Sign in to follow this  

DWORD image data confusion

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

q)I am confused about how this variable works as it doesnt seem to allocate memory for the array to be used. DWORD* imageData = (DWORD*)lockedRect.pBits; //no new? imageData[i * lockedRect.Pitch / 4 + j] = (D3DCOLOR)c;//??
bool Terrain::genTexture(D3DXVECTOR3* directionToLight)
{
	// Method fills the top surface of a texture procedurally.  Then
	// lights the top surface.  Finally, it fills the other mipmap
	// surfaces based on the top surface data using D3DXFilterTexture.

	HRESULT hr = 0;

	// texel for each quad cell
	int texWidth  = _numCellsPerRow;
	int texHeight = _numCellsPerCol;

	// create an empty texture
	hr = D3DXCreateTexture(
		_device,
		texWidth, texHeight,
		0, // create a complete mipmap chain
		0, // usage
		D3DFMT_X8R8G8B8,// 32 bit XRGB format
		D3DPOOL_MANAGED, &_tex);

	if(FAILED(hr))
		return false;

	D3DSURFACE_DESC textureDesc; 
	_tex->GetLevelDesc(0 /*level*/, &textureDesc);

	// make sure we got the requested format because our code 
	// that fills the texture is hard coded to a 32 bit pixel depth.
	if( textureDesc.Format != D3DFMT_X8R8G8B8 )
		return false;
		
	D3DLOCKED_RECT lockedRect;
	_tex->LockRect(0/*lock top surface*/, &lockedRect, 
		0 /* lock entire tex*/, 0/*flags*/);         

	DWORD* imageData = (DWORD*)lockedRect.pBits; //confusion?// how come it works?
	for(int i = 0; i < texHeight; i++)
	{
		for(int j = 0; j < texWidth; j++)
		{
			D3DXCOLOR c;

			// get height of upper left vertex of quad.
			float height = (float)getHeightmapEntry(i, j) / _heightScale;

			if( (height) < 42.5f ) 		 c = d3d::BEACH_SAND;
			else if( (height) < 85.0f )	 c = d3d::LIGHT_YELLOW_GREEN;
			else if( (height) < 127.5f ) c = d3d::PUREGREEN;
			else if( (height) < 170.0f ) c = d3d::DARK_YELLOW_GREEN;
			else if( (height) < 212.5f ) c = d3d::DARKBROWN;
			else	                     c = d3d::WHITE;

			// fill locked data, note we divide the pitch by four because the
			// pitch is given in bytes and there are 4 bytes per DWORD.
			imageData[i * lockedRect.Pitch / 4 + j] = (D3DCOLOR)c;//????
//it assigns values but how does directx know about this as
// it doesnt seem to to be assigned to anything?
		}
	}

	_tex->UnlockRect(0);

	...

Share this post


Link to post
Share on other sites
That "pBits" member points to memory that's already been allocated. It could have been allocated when the texture was created or when you called the LockRect function, it doesn't really matter when. All you need to know is that there is memory at that location that you can read and manipulate. Then what you're doing is copying the pointer value to "imageData", and in the process typecasting the pointer from VOID* to DWORD*.

Share this post


Link to post
Share on other sites
q)how can i use imagedata without creating space for the pointer using new?
a) are you saying the pointer points to memory pBits which it uses?

q)How can i use an array imagedata with data and directx can use it , i am unsure still?

Share this post


Link to post
Share on other sites
Quote:
Original post by jagguy2
q)how can i use imagedata without creating space for the pointer using new?


Like I said, this memory has already been allocated for you by D3D. It's the equivalent of doing this:



BYTE* numArray = new BYTE [500];

...

BYTE* bytePtr = numArray;
BYTE num = bytePtr [49];


The steps here are as follows:
-A block of memory 500 bytes wide is allocated with new. The pointer "numArray" is initialized to point at the beginning of this block of memory.
-"bytePtr" is initialized to same value as "numArray", which means it now also points at the beginning of the block of memory
-num is set to the value of the 50th byte in the block of memory, or in other words the value at bytePtr + 49.

Quote:
Original post by jagguy2
q)How can i use an array imagedata with data and directx can use it , i am unsure still?


Why wouldn't your code and the D3D runtime both be able to access a block of memory? It's just memory, you're guaranteeing that your app has access to it when you call LockRect. It doesn't really matter who allocated the memory, as long as you can ensure that it was allocated.

Share this post


Link to post
Share on other sites
speaking of the code i started the thread with.

q)i can get this code to work but it draws a terrain raw file upside down why?


q)i have set no FPS limit at all will that matter with display?



bool Terrain::draw()
{
HRESULT hr = 0;
D3DXMATRIX I;
D3DXMatrixIdentity(&I);

if( l_device )
{
l_device->SetTransform(D3DTS_WORLD, &I);

l_device->SetStreamSource(0, l_vb, 0, sizeof(TerrainVertex));
l_device->SetFVF(TerrainVertex::FVF);
l_device->SetIndices(l_ib);


l_device->SetTexture(0, l_tex);



// turn off lighting since we're lighting it ourselves
// l_device->SetRenderState(D3DRS_LIGHTING, false);

hr =l_device->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST,
0,
0,
l_numVertices,
0,
l_numTriangles);


[Edited by - jagguy2 on January 9, 2008 4:55:15 AM]

Share this post


Link to post
Share on other sites
Define "raw file". What image is it? What image type are you loading? Why aren't you checking the return value of LockRect()? If it fails (Which it can for loads of reasons), you're reading / writing random memory.

Are you calling getTexture() every frame? That would certainly explain a slowdown. Are you using the Debug Runtimes? What debug output do you have from them?

Share this post


Link to post
Share on other sites
my raw file is a terragen map exported into that format and i didnt know about lockRect return? Yes i call every frame but i have solved slow problem as it is large map.

q) why is it upside down and invereted?

q)can a terragen file ( and converted to a raw) have textures as well? My map has colors but i want textures with this code. I would have to add a U,V coordinate where it loads vertices and change texture for color. what would i do ?


bool Terrain::genTexture(D3DXVECTOR3* directionToLight)

{
HRESULT hr = 0;
// texel for each quad cell
int texWidth = _numCellsPerRow;
int texHeight = _numCellsPerCol;

// create an empty texture

hr = D3DXCreateTexture(
_device,
texWidth, texHeight,
0, // create a complete mipmap chain
0, // usage
D3DFMT_X8R8G8B8,// 32 bit XRGB format
D3DPOOL_MANAGED, &_tex);



if(FAILED(hr))

return false;



D3DSURFACE_DESC textureDesc;

_tex->GetLevelDesc(0 /*level*/, &textureDesc);


if( textureDesc.Format != D3DFMT_X8R8G8B8 )

return false;

D3DLOCKED_RECT lockedRect;

_tex->LockRect(0/*lock top surface*/, &lockedRect,

0 /* lock entire tex*/, 0/*flags*/);


DWORD* imageData = (DWORD*)lockedRect.pBits; //confusion?// how come it works?

for(int i = 0; i < texHeight; i++)

{
for(int j = 0; j < texWidth; j++)

{

D3DXCOLOR c;


// get height of upper left vertex of quad.

float height = (float)getHeightmapEntry(i, j) / _heightScale;

//I want TEXTURES and not COLORS
if( (height) < 42.5f ) c = d3d::BEACH_SAND;

else if( (height) < 85.0f ) c = d3d::LIGHT_YELLOW_GREEN;

else if( (height) < 127.5f ) c = d3d::PUREGREEN;

else if( (height) < 170.0f ) c = d3d::DARK_YELLOW_GREEN;

else if( (height) < 212.5f ) c = d3d::DARKBROWN;

else c = d3d::WHITE;



// fill locked data, note we divide the pitch by four because the

// pitch is given in bytes and there are 4 bytes per DWORD.

imageData[i * lockedRect.Pitch / 4 + j] = (D3DCOLOR)c;//????

//it assigns values but how does directx know about this as

// it doesnt seem to to be assigned to anything?

}

}



_tex->UnlockRect(0);



Share this post


Link to post
Share on other sites
Quote:
Original post by jagguy2
my raw file is a terragen map exported into that format and i didnt know about lockRect return? Yes i call every frame but i have solved slow problem as it is large map.

q) why is it upside down and invereted?
Because that's how the raw file was created. The data in the file is top to bottom (Is it a bitmap by any chance?)

Quote:
Original post by jagguy2
q)can a terragen file ( and converted to a raw) have textures as well? My map has colors but i want textures with this code. I would have to add a U,V coordinate where it loads vertices and change texture for color. what would i do ?
Not sure. How are you loading the teragen file? Is it just a chunk of points, or are you loading it as a D3DX mesh or something? If you're in control of the vertex buffer and vertex format, adding a texture coordinate for each vertex would work fine. The exact value for the texture coordinate depends on how you want to appy the texture (E.g. tiled, stretched, every alternate tile flipped, etc).

Share this post


Link to post
Share on other sites
i seem to be using texture coordinates where U,V is just a line as it is a color.

const DWORD Terrain::TerrainVertex::FVF = D3DFVF_XYZ | D3DFVF_TEX1;

but the textures are colors and i have this to load vertices so i shoud be able to add in u,v to the map size but changing the color to a texture in the original post i need to work out.

for(int z = startZ; z >= endZ; z -= l_cellSpacing)
{
int j = 0;
for(int x = startX; x <= endX; x += l_cellSpacing)
{
// compute the correct index into the vertex buffer and heightmap
// based on where we are in the nested loop.
int index = i * l_numVertsPerRow + j;

v[index] = TerrainVertex(
(float)x,
(float)l_heightmap[index],
(float)z,
(float)j * uCoordIncrementSize,
(float)i * vCoordIncrementSize);

j++; // next column
}
i++; // next row


[Edited by - jagguy2 on January 9, 2008 5:53:33 PM]

Share this post


Link to post
Share on other sites

This topic is 3625 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.

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