Does someone undersatnd the code

Started by
6 comments, last by Evil Steve 12 years, 11 months ago
Does someone understand the code as below,this is expert from book<Programming An Rts Game With Directx>
void TERRAIN::GenerateRandomTerrain(int numPatches)
{
try
{
Release();

//Create two heightmaps and multiply them
m_pHeightMap = new HEIGHTMAP(m_size, 20.0f);
HEIGHTMAP hm2(m_size, 2.0f);

m_pHeightMap->CreateRandomHeightMap(rand()%2000, 2.0f, 0.5f, 8);
hm2.CreateRandomHeightMap(rand()%2000, 2.5f, 0.8f, 3);

hm2.Cap(hm2.m_maxHeight * 0.4f);

*m_pHeightMap *= hm2;
hm2.Release();

CreatePatches(numPatches);
CalculateAlphaMaps();

//Add m_objects
HEIGHTMAP hm3(m_size, 1.0f);
hm3.CreateRandomHeightMap(rand()%1000, 5.5f, 0.9f, 7);

for(int y=0;y<m_size.y;y++)
for(int x=0;x<m_size.x;x++)
{
if(m_pHeightMap->GetHeight(x, y) == 0.0f && hm3.GetHeight(x, y) > 0.7f && rand()%6 == 0)
AddObject(0, INTPOINT(x, y)); //Tree
else if(m_pHeightMap->GetHeight(x, y) >= 1.0f && hm3.GetHeight(x, y) > 0.9f && rand()%20 == 0)
AddObject(1, INTPOINT(x, y)); //Stone
}

hm3.Release();
}
catch(...)
{
debug.Print("Error in TERRAIN::GenerateRandomTerrain()");
}
}
what is an alphaUV color UV?

Advertisement
Hi.

Get the book Introduction to 3d Game Programming with Directx 10 by Frank D. Luna And the DX 9 version of the books.

isbn-13:978-1-59822-053-7
isbn-10: 1-59822-053-5




The dx 9book a shaders approach will show you how to set up your own windows class then you can get into DX from there

what is an alphaUV color UV?
It's presumably a UV coordinate for an alpha or colour map. But since the code you posted doesn't mention "alpha UV" or "colour UV", it's impossible to say.
the code has a FVF define as:const DWORD TERRAINVertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;the book says have two UV coordinate first alpha
second color,but I don't really understand the all code as here!
const DWORD TERRAINVertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;

//////////////////////////////////////////////////////////////////////////////////////////
// PATCH //
//////////////////////////////////////////////////////////////////////////////////////////

PATCH::PATCH()
{
m_pDevice = NULL;
m_pMesh = NULL;
}
PATCH::~PATCH()
{
Release();
}

void PATCH::Release()
{
if(m_pMesh != NULL)
m_pMesh->Release();
m_pMesh = NULL;
}

HRESULT PATCH::CreateMesh(HEIGHTMAP &hm, RECT source, IDirect3DDevice9* Dev)
{
if(m_pMesh != NULL)
{
m_pMesh->Release();
m_pMesh = NULL;
}

try
{
m_pDevice = Dev;

int width = source.right - source.left;
int height = source.bottom - source.top;
int nrVert = (width + 1) * (height + 1);
int nrTri = width * height * 2;

if(FAILED(D3DXCreateMeshFVF(nrTri, nrVert, D3DXMESH_MANAGED, TERRAINVertex::FVF, m_pDevice, &m_pMesh)))
{
debug.Print("Couldn't create mesh for PATCH");
return E_FAIL;
}

//Create vertices
TERRAINVertex* ver = 0;
m_pMesh->LockVertexBuffer(0,(void**)&ver);
for(int z=source.top, z0 = 0;z<=source.bottom;z++, z0++)
for(int x=source.left, x0 = 0;x<=source.right;x++, x0++)
{
D3DXVECTOR3 pos = D3DXVECTOR3(x, hm.m_pHeightMap[x + z * hm.m_size.x], -z);
D3DXVECTOR2 uv = D3DXVECTOR2(x * 0.2f, z * 0.2f);
ver[z0 * (width + 1) + x0] = TERRAINVertex(pos, uv);
}
m_pMesh->UnlockVertexBuffer();

//Calculate Indices
WORD* ind = 0;
m_pMesh->LockIndexBuffer(0,(void**)&ind);
int index = 0;

for( z=source.top, z0 = 0;z<source.bottom;z++, z0++)
for(int x=source.left, x0 = 0;x<source.right;x++, x0++)
{
//Triangle 1
ind[index++] = z0 * (width + 1) + x0;
ind[index++] = z0 * (width + 1) + x0 + 1;
ind[index++] = (z0+1) * (width + 1) + x0;

//Triangle 2
ind[index++] = (z0+1) * (width + 1) + x0;
ind[index++] = z0 * (width + 1) + x0 + 1;
ind[index++] = (z0+1) * (width + 1) + x0 + 1;
}

m_pMesh->UnlockIndexBuffer();

//Set Attributes
DWORD *att = 0, a = 0;
m_pMesh->LockAttributeBuffer(0,&att);

for( z=source.top;z<source.bottom;z++)
for(int x=source.left;x<source.right;x++)
{
//Calculate quad subsets depending on height
int subset;
if(hm.m_pHeightMap[x + z * hm.m_size.x] == 0.0f)
subset = 0;
else if(hm.m_pHeightMap[x + z * hm.m_size.x] <= hm.m_maxHeight * 0.6f)
subset = 1;
else subset = 2;

att[a++] = subset;
att[a++] = subset;
}

m_pMesh->UnlockAttributeBuffer();

//Compute normals
D3DXComputeNormals(m_pMesh, NULL);
}
catch(...)
{
debug.Print("Error in PATCH::CreateMesh()");
return E_FAIL;
}

return S_OK;
}

void PATCH::Render(int texture)
{
//Draw mesh
if(m_pMesh != NULL)
m_pMesh->DrawSubset(texture);
}
Did you can tell me how to understand D3DCreateMeshFVF?

D3DFVF: http://msdn.microsof...v=vs.85%29.aspx

D3DXCreateMeshFVF: http://msdn.microsof...v=vs.85%29.aspx

Basically D3DXCreateMeshFVF creates a mesh object based on the vertex format specified by the FVF

m_pMesh->LockVertexBuffer(0,(void**)&ver); locks the vertexbuffer and sets the pointer (&ver) so that the buffer can be modified.

for(int z=source.top, z0 = 0;z<=source.bottom;z++, z0++)
for(int x=source.left, x0 = 0;x<=source.right;x++, x0++)
{
D3DXVECTOR3 pos = D3DXVECTOR3(x, hm.m_pHeightMap[x + z * hm.m_size.x], -z);
D3DXVECTOR2 uv = D3DXVECTOR2(x * 0.2f, z * 0.2f);
ver[z0 * (width + 1) + x0] = TERRAINVertex(pos, uv);
}
m_pMesh->UnlockVertexBuffer();

This section basically sets all the vertices in the buffer to the appropriate positions and assigns texture coordinates to them based on the heightmap.

the z0*(width+1) +x0 (and x + z*hm.m_size.x) are the basic formula for accessing a linear buffer as if it was a 2 dimensional one. (For heightmaps it makes sense to treat the mesh as a 2D grid of vertices)

if we have for example an 8x8 grid where z0 is the column and x0 the row we can either store it as
int grid2D[8][8]
or as int grid1D[64]

grid2D[2][6] is then effectivly the same as grid1D[6*8+2].

Further down in the code the indices are assigned
each triangle has 3 vertex indices, the index is the position of the vertex in the vertexbuffer, and after that attributes and normals are assigned aswell.

It might just be me but i have a very hard time deciding what level i can put my answers on, The question suggest that you are a complete beginner just copy&pasting code he doesn't understand while the subject (Hightmaps in this case) suggest that you allready have a solid understanding of the Direct3D API (Which makes the questions about D3DXCreateMeshFVF very confusing)

It would probably help alot if you asked more detailed questions instead of just doing a big code dump and adding "please explain" to it.
[size="1"]I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!
From my reply to the PM you sent me (P.s. please don't send me PMs when you're posting the same thing in the thread - I don't mind you PMing me to direct me to the thread though):

D3DXCreateMeshFVF creates an ID3DXMesh from a given FVF code. The FVF code specified means that each vertex has an XYZ position, a normal, and one set of 2D texture coordinates. So the vertex struct is expected to look like:
struct TerrainVertex
{
D3DXVECTOR3 pos;
D3DXVECTOR3 normal
D3DXVECTOR2 uv;
};The code creates a mesh with nrTri faces, and nrVertvertices, and then fills in the vertex positions and indices required to make triangles from them. It then calls D3DXComputeNormals to automatically generate the normals for the faces in the mesh.
Don't understand why the ind[index++] = z0 * (width + 1) + x0;
and for you reply why you says gird[2][6] = gird1D(6*8+2) ok
the code from here I don't understand :
for( z=source.top, z0 = 0;z<source.bottom;z++, z0++)
for(int x=source.left, x0 = 0;x<source.right;x++, x0++)
{
//Triangle 1
ind[index++] = z0 * (width + 1) + x0;
ind[index++] = z0 * (width + 1) + x0 + 1;
ind[index++] = (z0+1) * (width + 1) + x0;

//Triangle 2
ind[index++] = (z0+1) * (width + 1) + x0;
ind[index++] = z0 * (width + 1) + x0 + 1;
ind[index++] = (z0+1) * (width + 1) + x0 + 1;
}

m_pMesh->UnlockIndexBuffer();

//Set Attributes
DWORD *att = 0, a = 0;
m_pMesh->LockAttributeBuffer(0,&att);
memset(att, 0, sizeof(DWORD)*nrTri);
m_pMesh->UnlockAttributeBuffer();
it's so hard to understand the concept of save the vertices into
traingles,and another things please explain D3DXCreateMeshFVF function!and what that mean attributes?


Don't understand why the ind[index++] = z0 * (width + 1) + x0;
and for you reply why you says gird[2][6] = gird1D(6*8+2) ok
the code from here I don't understand :
for( z=source.top, z0 = 0;z<source.bottom;z++, z0++)
for(int x=source.left, x0 = 0;x<source.right;x++, x0++)
{
//Triangle 1
ind[index++] = z0 * (width + 1) + x0;
ind[index++] = z0 * (width + 1) + x0 + 1;
ind[index++] = (z0+1) * (width + 1) + x0;

//Triangle 2
ind[index++] = (z0+1) * (width + 1) + x0;
ind[index++] = z0 * (width + 1) + x0 + 1;
ind[index++] = (z0+1) * (width + 1) + x0 + 1;
}

m_pMesh->UnlockIndexBuffer();

//Set Attributes
DWORD *att = 0, a = 0;
m_pMesh->LockAttributeBuffer(0,&att);
memset(att, 0, sizeof(DWORD)*nrTri);
m_pMesh->UnlockAttributeBuffer();
it's so hard to understand the concept of save the vertices into
traingles,and another things please explain D3DXCreateMeshFVF function!and what that mean attributes?



Try drawing the order and position of the vertices, and you'll see why it's using that formula. That's just the formula you need to make triangles out of the correct vertices.

Vertices are just points (+ some extra data like normal, UV, etc), so if you have 10 vertices, you don't have any idea how they combine into triangles. For that, you need the index buffer, which specifies which 3 vertices are used to make each triangle.

As for the attribute buffer and D3DXCreateMeshFVF, Google is your friend.

This topic is closed to new replies.

Advertisement