Sign in to follow this  
binpersonal

lockedRect.Pitch problem

Recommended Posts

binpersonal    122
Dear all, I created a 128*128 texture, then use LockRect to lock and change the data. Then use a square vertex to display the texture. However, I found the LockRect result is not a square; It seems x axis is 512 pixel, y axis is 128 pixel. When I use memcpy to set the destination position ( such as draw a line), I found x position can change from 0 to 511, while y position can only change 0 to 127. Anyone can give me some advices and ideas? Do it relates to the vertex? Thank you very much! struct Vertex { float x, y, z; float tu, tv; }; Vertex g_quadVertices[] = { {-1.0f, 1.0f, 0.0f, 0.0f,0.0f }, { 1.0f, 1.0f, 0.0f, 1.0f,0.0f }, {-1.0f,-1.0f, 0.0f, 0.0f,1.0f }, {1.0f,-1.0f, 0.0f, 1.0f,1.0f } }; D3DXCreateTexture( pd3dDevice, 128, 128, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_pDonutTexture ); V_RETURN(pd3dDevice->CreateVertexBuffer( 4*sizeof(Vertex), D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVertexBuffer, NULL )); void *pVertices = NULL; g_pVertexBuffer->Lock( 0, sizeof(g_quadVertices), (void**)&pVertices, 0 ); memcpy( pVertices, g_quadVertices, sizeof(g_quadVertices) ); g_pVertexBuffer->Unlock(); When I draw a line in the texture: D3DLOCKED_RECT lockedRect; g_pDonutTexture->LockRect(0, &lockedRect, NULL, D3DLOCK_DISCARD); BYTE* pData = (BYTE*)lockedRect.pBits; CData = D3DCOLOR_ARGB(0, 0, 0, 0); for (int yposition = 0; ypositon< 64; yposition++) { memcpy(pData + lockedRect.Pitch+xposition, cData, sizeof(cData[0])); } g_pDonutTexture->UnlockRect(0); D3DXMATRIX matTrans; D3DXMatrixTranslation( &matTrans, -1.0f, 0.0f, 4.0f ); pd3dDevice->SetTransform( D3DTS_WORLD, &matTrans); pd3dDevice->SetTexture( 0, g_pDonutTexture ); pd3dDevice->SetStreamSource( 0, g_pVertexBuffer, 0, sizeof(Vertex) ); pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX ); pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 ); xposition can vary from 0-512, while yposition can only vary from 0-127

Share this post


Link to post
Share on other sites
> memcpy(pData + lockedRect.Pitch+xposition, cData, sizeof(cData[0]));

should, at the very least have a "* y" in there.

pData + (y * lockedRect.Pitch) + xposition

But that's not right. The address doesn't increase by 1 per pixel, it increases by whatever the pixel pitch of the format is. In your case, A8R8G8B8 has a pixel pitch of 4.

pData + (y * lockedRect.Pitch) + (xposition * 4)

When you're specifying specific formats, you can hardcode a pixel pitch like this (never hardcode the line pitch, use what D3D returns to you). There is no generic way to handle pixel pitch without having a table describing each format.

You'll notice that when taking into account that a pixel is 4 bytes wide, your x range is the expected 0..127

Share this post


Link to post
Share on other sites
binpersonal    122
Thank you,Namethatnobodyelsetook, it is a bit helpful, but still puzzled. since the address increase by pixel pitch, why there is no pixel pitch in y axis?

Also, put one line in xposition*4 ,and another on (xposition+1)*4, Isn't there gaps between those two lines? It seems the x position is a discreet number now,
only happens at 1, 4, 8, 12 etc...

Thank you very much!

Quote:
Original post by Namethatnobodyelsetook
> memcpy(pData + lockedRect.Pitch+xposition, cData, sizeof(cData[0]));

should, at the very least have a "* y" in there.

pData + (y * lockedRect.Pitch) + xposition

But that's not right. The address doesn't increase by 1 per pixel, it increases by whatever the pixel pitch of the format is. In your case, A8R8G8B8 has a pixel pitch of 4.

pData + (y * lockedRect.Pitch) + (xposition * 4)

When you're specifying specific formats, you can hardcode a pixel pitch like this (never hardcode the line pitch, use what D3D returns to you). There is no generic way to handle pixel pitch without having a table describing each format.

You'll notice that when taking into account that a pixel is 4 bytes wide, your x range is the expected 0..127


Share this post


Link to post
Share on other sites
Sc4Freak    643
Quote:
Original post by binpersonal
Thank you,Namethatnobodyelsetook, it is a bit helpful, but still puzzled. since the address increase by pixel pitch, why there is no pixel pitch in y axis?

Think about this for a minute. How would this work?

Memory is linear. Your image is being stored as a single linear block of memory. For example, this is what a 4x4 pixel ARGB image would be laid out in memory:

ARGBARGBARGBARGBARGBARGBARGBARGBARGBARGBARGBARGBARGBARGBARGBARGB

It's just 64 bytes in a clump. If you want to access the second pixel, you need to begin reading 4 bytes in from the start of the buffer (since the first pixel occupied 4 bytes).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this