Sign in to follow this  
Juliean

questions about/problems with meshes

Recommended Posts

Hi,

I'm trying to convert my heightmap generated terrain into a D3DXMesh. This is the currenct code which I use to read the heightmap & load the terrain:

[code]
int i, j, k;

m_lpDevice = lpDevice;

LPDIRECT3DSURFACE9 lpSurface = NULL;

D3DXIMAGE_INFO ImgInfo;

D3DXGetImageInfoFromFile(lpHeightmap, &ImgInfo);

m_Width = ImgInfo.Width;
m_Length = ImgInfo.Height;

m_lpDevice->CreateOffscreenPlainSurface(m_Width,
m_Length,
D3DFMT_L8,
D3DPOOL_SCRATCH,
&lpSurface, 0);

D3DXLoadSurfaceFromFile(lpSurface, 0, 0, lpHeightmap, 0, D3DX_DEFAULT, 0, 0);

int SizeVertices = m_Width * m_Length;
int SizeIndices = (m_Width-1)*(m_Length-1)*2*3;

D3DLOCKED_RECT LockedRect;

lpSurface->LockRect(&LockedRect, 0, 0);

BYTE* lpHeights = (BYTE*) LockedRect.pBits;

int nPitch = LockedRect.Pitch;

TERRAIN_VERTEX* Vertices = new TERRAIN_VERTEX[SizeVertices];

// und mit Werten belegen
for(i=0;i<m_Length;i++)
{
// der Farbwert des Pixels bestimmt die Hoehe
for(j=0;j<m_Width;j++)
{
Vertices[i*m_Width+j].x = static_cast<float>(j);

Vertices[i*m_Width+j].y = static_cast<float>(lpHeights[i*nPitch+j])/2;

Vertices[i*m_Width+j].z = static_cast<float>(m_Length - i);

// je hoeher der Vertex, umso heller die Farbe
Vertices[i*m_Width+j].Color = D3DCOLOR_XRGB(lpHeights[i*nPitch+j],
lpHeights[i*nPitch+j],
lpHeights[i*nPitch+j]);

//Vertices[i*m_Width+j].tu1 = static_cast<float>(j) / m_Width;
//Vertices[i*m_Width+j].tv1 = static_cast<float>(i) / m_Length;

Vertices[i*m_Width+j].tu2 = static_cast<float>(j) / m_Width * 32;
Vertices[i*m_Width+j].tv2 = static_cast<float>(i) / m_Length * 32;

}
}

unsigned int* Indices = new unsigned int[SizeIndices];

k = 0;

for(i=0;i<m_Length-1;i++)
{
for(j=0;j<m_Width-1;j++)
{
Indices[k++] = m_Width * (i + 1) + j;
Indices[k++] = m_Width * i + j;
Indices[k++] = m_Width * (i + 1) + j + 1;
Indices[k++] = m_Width * i + j;
Indices[k++] = m_Width * i + j + 1;
Indices[k++] = m_Width * (i + 1) + j + 1;
}
}

DWORD* pVertices;

LPD3DXMESH Mesh;

HRESULT hr = D3DXCreateMeshFVF(SizeIndices/3, SizeVertices, D3DXMESH_32BIT, D3DFVF_TERRAINVERTEX, m_lpDevice, &Mesh);

int nNumFaces = Mesh->GetNumFaces();

DWORD* att = NULL;
Mesh->LockAttributeBuffer(0,&att);
memset((void*)att, 0, sizeof(int)*nNumFaces);
Mesh->UnlockAttributeBuffer();

int l = Mesh->GetNumVertices();

Mesh->LockVertexBuffer(0,(LPVOID*)&pVertices);

memcpy(pVertices, Vertices, sizeof(Vertices)*sizeof(TERRAIN_VERTEX));

Mesh->UnlockVertexBuffer();

DWORD* pIndices;

hr = Mesh->LockIndexBuffer(0, (void**)&pIndices);
//m_IBuffer->Lock(0, SizeIndices * sizeof(unsigned int), &pIndices, 0);

memcpy(pIndices, Indices, sizeof(Indices)*sizeof(unsigned int));

Mesh->UnlockIndexBuffer();
// Speicher freigeben
delete[] Vertices;
delete[] Indices;

LPD3DXBUFFER pBuffer = NULL;
LPD3DXMESH pMeshTemp = NULL;

DWORD *pAdjacency1 = new DWORD[nNumFaces * 3];
DWORD *pAdjacency2 = new DWORD[nNumFaces * 3];
DWORD *pAdjacency3 = new DWORD[nNumFaces * 3];

Mesh->GenerateAdjacency(0.0f, pAdjacency1);

// Zusammenfassen von Vertices. Diese Funktion muss aufgerufen werden

hr = D3DXCleanMesh(D3DXCLEAN_SIMPLIFICATION, Mesh, pAdjacency1, &pMeshTemp, pAdjacency2, &pBuffer);

D3DXValidMesh(pMeshTemp, pAdjacency2, &pBuffer);

Mesh->Release();
Mesh = pMeshTemp;

D3DXComputeNormals(Mesh, NULL);
D3DXComputeTangent(Mesh, 0, 0, 0, 0, NULL);

D3DXGeneratePMesh(Mesh, pAdjacency2, NULL, NULL, 300, D3DXMESHSIMP_FACE, &m_lpMesh);

lpSurface->Release();

delete[] pAdjacency1;
delete[] pAdjacency2;
delete[] pAdjacency3;[/code]

After a lot of errors with the filling of the vertex and index buffer I managed to at least make it work, but on my call of D3DXCleanMesh() the HR says that the mesh is invalid, so it wont create the PMesh, and I get an error on rendering (because m_lpMesh points to 0xccccccccc).
If I don't use the cleaned pmesh, just the one I created, I get messed up graphics. I can barely see anything because there are so many triangles on the screen with random coordinates, all pointing to the center of the camera, whereever I move it.
Does anyone know whats wrong here? The code worked as long as I filled a seperate vertex/index-buffer. I tried many different ways like a for() loop instead of memcpy but everything failed. Does someone know what I'm doing wrong?

Second question, I want to calculate the normals, tangents and binormals of my mesh. I know this functions:
D3DXComputeNormals(Mesh, NULL);
D3DXComputeTangent(Mesh, 0, 0, 0, 0, NULL);
Does D3DXComputeTangent also calculate binormals or do I need another function (didn't found one so far)? Is my call of D3DXComputeTangent even valid? I looked up msdn but the explanations of what for example parameter 2 and 3 does make no sense to me. What should I do?

Share this post


Link to post
Share on other sites
*Bump*
Anybody? I'm desperatly trying to get it to work, played with the size-paramenter in memcpy, with the parameters of D3DXCreateMeshFVF, nothing works. At least some general suggestions what can go wrong pls, or some answer to my second question (can't tell me nobody used D3DXComputeTangent() before) :(

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