Skip to main content
gamedev.net
🔒 Locked

96bpp texture

Started by evilgenius Oct 1, 2003 at 10:21 AM 10 replies 850+ views
Original Post
evilgenius
evilgenius
i'm looking for a way to create a texture out of a video-frame that has got 96bpp. there is no need to display the texture, i do only want to load it onto a triangle strip as a texture, so i can do some calculations with it. i've tried to solve this problem using CreateDibSection() and D3DXCreateTextureFromFileInMemory() but this fails. I also havent found an image format which supports 96bpp, so i "said" CreateDibSection() that it is 32bpp and it should create the dib as if it were three times larger. Thats no prob as i know how to do the calcs. (i guess :-) But as said before CreateTexture... fails (no debug message). I really don't know what else i could try to make it work, so i'm asking people here (who are much more into DX9 than me): Does anybody know how to solve this problem?? Every suggestion is welcome. [edited by - evilgenius on October 1, 2003 11:25:51 AM]
neneboricua19
neneboricua19
It depends in what format your original video-frame data is in. D3DXCreateTextureFromFileInMemory handles .bmp, .dds, .dib, .hdr, .jpg, .pfm, .png, .ppm, and .tga

If your video frame is in one of these formats, then it should work fine. If not, then you might end up having to create a blank texture surface and filling in the colors manually. DX9 supportsa 128bpp format. It''s called D3DFMT_A32B32G32R32F. This format uses a 32 bit float for the four components of a color, RGBA.

Since you mentioned that this info is coming from a video-frame, maybe I can guess that you''re using DirectShow??? If so, in DX9 there is a way to have DirectShow convert a video-frame into a texture that D3D can handle. It''s been a while since I dealt with DirectShow but I''m sure if you look through the docs and on MSDN you''ll find what I''m talking about.

neneboricua
Namethatnobodyelsetook
Namethatnobodyelsetook
DX9 will support 128bpp only if your card does, OR you use the reference rasterizer. Since you''re not trying to display anything, just process it, the reference rasterizer may be the best option.

But... if you''re not displaying it, what do you mean by "load it onto a triangle strip"?!?
neneboricua19
neneboricua19
Maybe evilgenius can correct me if I''m wrong but I suspect he''s trying to do some kind of image analysis. He might be trying to draw a screen-aligned quad as a triangle strip and texture that quad with info from his video-frame. That way he can write a bunch of pixel shaders to do different operations on the image like you would in Computer Vision. You can do things like edge detection, motion analysis, object recognition, etc...

Maybe he''s not displaying the output directly but will analyze the final image inside the app and output some kind of statistics or something else.

Since the GPU has gotten so fast, it''s starting to make sense to use pixel shaders to implement some of these image analysis algorithms instead of relying on the CPU.

neneboricua
evilgenius
evilgenius
neneboricua ist perfectly right. i want to use the GPU for a quite slow video filter. and i want to calculate in the backbuffer and write it right back to my main app for display. thats why i said i dont want to display / present anything.
i guess i''ll try using D3DFMT_A32B32G32R32F now. never used D3DXCreateTexture() before, hope it works. so thnx for all ur suggestions.
neneboricua19
neneboricua19
No problem. What you need to do is create a texture and then get a pointer (really an IDirect3dSurface9 interface) to its surface so you can set the texture as a render target. It would look like this:

D3DXCreateTexture( m_pd3dDevice, width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A32B32G32R32F, D3DPOOL_DEFAULT, &m_pScreenTexture );

m_pScreenTexture->GetSurfaceLevel( 0, &m_pScreenTextureSurface );

Then you can render to this texture/surface by doing:
m_pd3dDevice->SetRenderTarget( 0, m_pScreenTextureSurface );
m_pd3dDevice->DrawIndexedPrimitive(.....)

Good luck,
neneboricua
evilgenius
evilgenius
ok, thanks, but how do i copy the image-data "in"?
i thought i would have to ->LockRect(), but this doesnt work with D3DPOOL_DEFAULT. and D3DPOOL_MANAGED doesnt work D3DUSAGE_RENDERTARGET. i ve tried using NULL as D3DUSAGE and LockRect() and it seems to work, but the colors really arent right.
i can post my code too, if u need it.
neneboricua19
neneboricua19
quote:
Original post by evilgenius
ok, thanks, but how do i copy the image-data "in"?
i thought i would have to ->LockRect(), but this doesnt work with D3DPOOL_DEFAULT. and D3DPOOL_MANAGED doesnt work D3DUSAGE_RENDERTARGET. i ve tried using NULL as D3DUSAGE and LockRect() and it seems to work, but the colors really arent right.
i can post my code too, if u need it.

If you''re using DirectShow, you can get the current video frame directly as a D3D texture. If you''re NOT using DirectShow, then you have to do a couple of other things:

First, you have to create a system memory surface (or texture, either will work). Then you Lock() this surface and copy the pixels from your video frame to the system memory surface. Then you need to call UpdateSurface (or UpdateTexture depending on which one you''re using) to copy the data from the system memory surface to a video memory surface. This method is similar to calling CopyRects in DX8.

neneboricua
evilgenius
evilgenius
ok, this works fine except that it doesn''t show the whole texture.
my texture is 1526x1024 an it shows only about 1/4 of it. the rest of the window is black. but the window background should be blue so i think it does something. there isn''t any failure message printed, too. do i reach some sort of limit, which i don''t know?
i have got a radeon 9700pro which can do 2048x2048 for a texture, according to caps(). any ideas what could go wrong??
neneboricua19
neneboricua19
Maybe your loop didn''t copy all the pixels from your video-frame to the system memory texture? One thing you can do is use D3DXSaveSurfaceToFile (or D3DXSaveTextureToFile) on the system memory surface. You can save the image as a .bmp file and take a look at it offline so you can at least verify that your entire video-frame is being copied onto the system memory surface.

If you see the same problem offline as well, then that means there''s some kind of problem in the code to copy the pixels from your video-frame.

If you do not see the same problem (the .bmp file contains the whole image, as expected) then make sure that your system memory and video memory surfaces are the same size and you''re transfering the whole image when you use UpdateSurface.

Also make sure that your screen-aligned quad has the proper texture coordinates. You can check that by just loading a .bmp off the harddrive and using that instead of your video-frame, although I doubt that this is the problem.

neneboricua
evilgenius
evilgenius
it works now. i changed the code to copy a whole pixel at once. but it should have also worked when i copied one color channel after the other.

i figured the strange color thing out too. it seems, that most of the colorvalues are greater than 255 an so most of the texture is white. does anybody have the specs of D3DFMT_A32B32G32R32F? should be IEEE s23e8. i think the clipping is because of certain specs of this format.
evilgenius
evilgenius
well i got it. seems to be a float rgb format and seems that u have to divide through 255 if u get data in standard rgb. i didn''t know that. never mind :-)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.