Jump to content
  • Advertisement
Sign in to follow this  
VISQI

LockRect() in D3D10?

This topic is 2478 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

Hey people
So i had this old piece of code that creates a noise texture by using LockRect(). I was wondering how can i transfer it to D3D10 because i didn't find a LockRect() function in ID3D10Texture2D structure.

here is the code:


V(gd3dDev->CreateTexture(256, 256, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &mNoiseTexture, 0));
D3DLOCKED_RECT rect;

V(mNoiseTexture->LockRect(0, &rect, 0, 0));

for(int i = 0; i < 256; i++)
for(int j = 0; j < 256; j++)
{
int Random = GetRandomInt()&1000;

uint8_t* Pixels = (uint8_t*)rect.pBits;

uint32_t* CurrentPixel = (uint32_t*)&Pixels[rect.Pitch*i + 4*j];

uint8_t* Components = (uint8_t*)CurrentPixel;

Components[0] = 0;
Components[1] = Random;
Components[2] = 0;
Components[3] = 0;
}

V(mNoiseTexture->UnlockRect(0));


To be fair, i don't really quite understand the different types of uint and how to deal with them, So please be thorough.

Share this post


Link to post
Share on other sites
Advertisement
For equivalent functions in D3D10, see Map and Unmap.

The format of the texture here is A8R8G8B8; therefore, one texel can be represented as either one 32-bit integer (uint32_t) or four 8-bit integers (uint8_t). The pointer arithmetic in the code first establishes the address of the first texel on the texture; then, it finds the address of the current pixel given the i, j, pitch (number of bytes on a line, including cache and padding) and number of bytes per pixel; finally, the current pixel address is cast to a pointer of 8-bit integers to conveniently access the individual bytes (or color components) within as an array of bytes.

In this case, the red channel is filled with random noise and the rest of the channels are left to zero. Note that since the random integer is established with a modulus of 1000, the random value distribution is uneven (even though the random function would be even) because the maximum value of a byte (aka 8-bit integer in this context) is 255.

Share this post


Link to post
Share on other sites
You actually don't want to use Map or Unmap. In D3D10 you can create a texture as IMMUTABLE and pass a pointer containing texel data that you want that texture to be initialized with. This is more efficient than creating a texture, and then filling it afterwards.

Share this post


Link to post
Share on other sites
If you do fill the texture with dynamic data each frame (think video, for example), you still want to use Map/Unmap here (but allocate the texture once outside the frame loop) :)

Share this post


Link to post
Share on other sites

For equivalent functions in D3D10, see Map and Unmap.

The format of the texture here is A8R8G8B8; therefore, one texel can be represented as either one 32-bit integer (uint32_t) or four 8-bit integers (uint8_t). The pointer arithmetic in the code first establishes the address of the first texel on the texture; then, it finds the address of the current pixel given the i, j, pitch (number of bytes on a line, including cache and padding) and number of bytes per pixel; finally, the current pixel address is cast to a pointer of 8-bit integers to conveniently access the individual bytes (or color components) within as an array of bytes.

In this case, the red channel is filled with random noise and the rest of the channels are left to zero. Note that since the random integer is established with a modulus of 1000, the random value distribution is uneven (even though the random function would be even) because the maximum value of a byte (aka 8-bit integer in this context) is 255.


very nice, but since we are trying to access all the texels, why are accessing the texels using a uint8_t structure in the beginning. Meaning, why is it that "Pixels" is a uint8_t structure and not a uint32_t structure??

Share this post


Link to post
Share on other sites
[font=courier new,courier,monospace][color="#000000"]uint32_t[color="#666600"]* [color="#660066"]CurrentPixel [color="#666600"]= [color="#666600"]([color="#000000"]uint32_t[color="#666600"]*)&[color="#660066"]Pixels[color="#666600"][[color="#000000"]rect[color="#666600"].[color="#660066"]Pitch[color="#666600"]*[color="#000000"]i [color="#666600"]+ [color="#006666"]4[color="#666600"]*[color="#000000"]j[color="#666600"]];[/font]

This row finds the mapped virtual memory address of a ij[sup]th [/sup]byte (8-bit uint) of the texture data and casts it to a pointer to a 32-bit uint. Because the Pixels array is a pointer to 8-bit uints, the array elements are 8 bits apart. If it was a uint32_t* to begin with, the elements would be 32 bits apart and the pointer arithmetic would be slightly more complex. Consider that the pitch of the texture is expressed as bytes, not uint32:s - because the texel size can be other than uint32 if a different texture format is used.

[font=courier new,courier,monospace][color="#000000"]uint8_t[color="#666600"]* [color="#660066"]Components [color="#666600"]= [color="#666600"]([color="#000000"]uint8_t[color="#666600"]*)[color="#660066"]CurrentPixel[color="#666600"];[/font]

This is mainly for convenience, so you can use the array syntax to access the individual bytes found in the address. If you don't need to do that, you could just write the pixel value as a 32-bit uint to the address represented by CurrentPixel pointer.

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!