Jump to content
  • Advertisement
Sign in to follow this  
xxAnthonyxx

Create texture from raw

This topic is 4167 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Well I have an A8R8G8B8 DDS texture in a file without a header so its just the raw I would like to create a texture and then set the data as the raw, I know that I would use D3DXCreateTexture to create the texture then LockRect so I can get the bits to write to. Heres what I have //Create a buffer WORD* buffer = new WORD[0x2C790]; //Read the data DWORD numberOfBytesRead = 0; ReadFile(fileHandle, buffer, 0x2C790, &numberOfBytesRead, NULL) ; //Create the texture D3DXCreateTexture( g_pd3dDevice, 208, 220, D3DX_DEFAULT, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &previewTexture ); //Lock the data and write to it D3DLOCKED_RECT locked; previewTexture->LockRect(0, &locked, NULL, 0); memcpy(locked.pBits, buffer, 0x2C790); //Unlock the texture previewTexture->UnlockRect(0); The raw is 0x2C790 bytes and its 208x220 thanks

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Dave
Is there a problem?


yes there is

for some reason the texture is coming out like that when it looks nothing like that
http://img116.imageshack.us/img116/1643/1921680109image3sd7.png

here is what it should be
http://img255.imageshack.us/img255/691/containmentpreviewimagesj3.png

Share this post


Link to post
Share on other sites
Check that you are memcpy'ing the correct amount of data around. To me that looks like you're copying too little data into the texture because whatever was there before it is showing through.

Dave

Share this post


Link to post
Share on other sites
well there are 4 bytes per pixel

Alpha Red Green Blue
its 220x207 (just checked again)

so its (220 * 207 * 4)

which is
0x2C790 thats how much I read into the buffer and thats how much I copied so im pretty sure thats correct, did I create the texture correctly? maybe thats the problem. Also I think I may have to swizzle the image how would I go about doing that?

Share this post


Link to post
Share on other sites
Hi, I checked the size of the "wrong" image you posted, and it was 256 * 256. This makes me think when you load the picture it is being loaded into a texture memory area of the next pow 2 up, (this happens quite a lot and I think is is actually the normal way d3d does it). You could try extending your source picture to either 255 * 255 or 256 * 256 (can't remember which is right). Before you load it, call D3DXGetImageInfoFromFile, to get the image information. You could also try using LPDIRECT3DSURFACE9->GetSurfaceDesc(), on the surface once you've loaded it. (That might be easier as you are working with the surface).

..Ok, so you could try "memcopying" 256 * 256 *4 of data over and see if that works. (as long as you've made the source image bigger). If you are using a quad to show the picture, you can set the tu & tv values to compensate for the extra texture size. tu = 220.0f / 256.0f, tv = 208.0f / 256.0f. (They need to be floats).

I'd be interested in seeing if memcpy works as well, as I usually go through each pixel with the _LrBits pointer, memcopying the whole chunk might be quicker, although I am using a 1024 * 1024 * 4, so maybe its just a problem with the size. Incidently I wouldn't be sure that memcopy would work on any subrects of the surface (with out trying it).

Share this post


Link to post
Share on other sites
It looks like you may be running into a pitch/width mismatch.

Quote:
From MSDN
When you lock a surface using the IDirect3DSurface9::LockRect method, the method fills in a D3DLOCKED_RECT structure that contains the pitch of the surface and a pointer to the locked bits. The value in the Pitch member describes the surface's memory pitch, also called stride. Pitch is the distance, in bytes, between two memory addresses that represent the beginning of one bitmap line and the beginning of the next bitmap line. Because pitch is measured in bytes rather than pixels, a 640x480x8 surface has a very different pitch value than a surface with the same dimensions but a different pixel format. Additionally, the pitch value sometimes reflects bytes that Direct3D has reserved as a cache, so it is not safe to assume that pitch is just the width multiplied by the number of bytes per pixel ... When rendering directly into surface memory, always use the pitch returned by the IDirect3DSurface9::LockRect method. Do not assume a pitch based solely on the display mode.


So you'll need to know the source image's dimensions for defined behaviour. I haven't tested it, but it would look something like this, I'd imagine:

// Lock the data and write to it
D3DLOCKED_RECT locked;
previewTexture->LockRect(0, &locked, NULL, 0);

const int pixel_size = 4;
char* dest_buffer = reinterpret_cast<char*> (locked.pBits);
for (int i = 0; i < source_height; ++i) {
memcpy(dest_buffer + (i * locked.Pitch), buffer + (i * source_width * pixel_size), source_width * pixel_size);
}


Admiral

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!