Archived

This topic is now archived and is closed to further replies.

higherspeed

Terrain Rendering Problems

Recommended Posts

I''ve been having problems rendering my terrain. I''m using a binary tree, but have simplified it to just drawing a grid, to try to solve my problem. I''ve tried all sorts of things, but have had no luck. Ingame nothing shows up. However when looking towards the point (0,0,0), I get a significant slowdown. So what I think is happening is that all the vertices are getting stuck at (0,0,0). This code just generates the terrain and makes a vertex and index buffer.
  
int gw = 50;
NumVertices = (gw+1) * (gw+1);
TERRAINVERTEX *g_Vertices = new TERRAINVERTEX[NumVertices];
int i, j;
for(i = 0; i < (gw+1); i++)
{
	for(j = 0; j < (gw+1); j++)
	{
		g_Vertices[i*(gw+1) + j].x = i*100.0f;
		g_Vertices[i*(gw+1) + j].y = 100;
		g_Vertices[i*(gw+1) + j].z = j*100.0f;
		g_Vertices[i*(gw+1) + j].tu = ((float)i)/((float)gw);
		g_Vertices[i*(gw+1) + j].tv = ((float)j)/((float)gw);
	}
}

NumFaces = gw * gw * 2;
WORD *pIndices = new WORD[NumFaces*3];
for(i = 0; i < gw; i++)
{
	for(j = 0; j < gw; j++)
	{
		pIndices[i*6*gw + j*6 + 0] = (i+0) * (gw+1) + (j+0);
		pIndices[i*6*gw + j*6 + 1] = (i+1) * (gw+1) + (j+0);
		pIndices[i*6*gw + j*6 + 2] = (i+0) * (gw+1) + (j+1);
		pIndices[i*6*gw + j*6 + 3] = (i+0) * (gw+1) + (j+1);
		pIndices[i*6*gw + j*6 + 4] = (i+1) * (gw+1) + (j+0);
		pIndices[i*6*gw + j*6 + 5] = (i+1) * (gw+1) + (j+1);
	}
}
	
g_pD3DDevice->CreateVertexBuffer( NumVertices*sizeof(TERRAINVERTEX),
                                                  0, D3DFVF_TERRAINVERTEX,
                                                  D3DPOOL_DEFAULT, &terrainVB, NULL );

VOID* pVertices;
terrainVB->Lock( 0, sizeof(g_Vertices), (void**)&pVertices, 0 );
memcpy( pVertices, g_Vertices, sizeof(g_Vertices) );
terrainVB->Unlock();

WORD *pwIndices;
g_pD3DDevice->CreateIndexBuffer(NumFaces * 3 * sizeof(WORD), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &terrainIB, NULL);

terrainIB->Lock(0, NumFaces * 3 * sizeof(WORD), (void**) &pwIndices, D3DLOCK_DISCARD);	
memcpy( pwIndices, pIndices, sizeof(pIndices) );
terrainIB->Unlock();

delete [] pIndices;
delete [] g_Vertices;
  
Yes I know the terrain would be flat. Now this bit of code sends it to be rendered.
  
g_pD3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE );

g_pD3DDevice->SetTextureStageState(0,D3DTSS_COLOROP,   D3DTOP_SELECTARG1);
g_pD3DDevice->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_pD3DDevice->SetTextureStageState(0,D3DTSS_COLORARG2, D3DTA_DIFFUSE);
g_pD3DDevice->SetTextureStageState(0,D3DTSS_ALPHAOP,   D3DTOP_DISABLE);
	 
g_pD3DDevice->SetSamplerState(0,D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
g_pD3DDevice->SetSamplerState(0,D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
g_pD3DDevice->SetSamplerState(0,D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
g_pD3DDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR );
g_pD3DDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR );

g_pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
g_pD3DDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME );

g_pD3DDevice->SetStreamSource( 0, terrainVB, 0, sizeof(TERRAINVERTEX));
g_pD3DDevice->SetFVF( D3DFVF_TERRAINVERTEX );
g_pD3DDevice->SetTexture( 0, terrainTexture );
g_pD3DDevice->SetIndices(terrainIB);
g_pD3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, NumVertices, 0, NumFaces );

g_pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
g_pD3DDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
g_pD3DDevice->SetTexture(0,NULL);
g_pD3DDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
  
And finally here is the declaration of my vertex struct.
  
struct TERRAINVERTEX
{
	FLOAT x, y, z;
	FLOAT tu, tv;
};
#define D3DFVF_TERRAINVERTEX (D3DFVF_XYZ|D3DFVF_TEX1)
  
I''m sure it must be a very simple mistake I''ve made, that I''ll only ever make this once. I''m sorry to post so much code, but this has been bugging me for the past few days.

Share this post


Link to post
Share on other sites
Unless I''m missing something, this looks very wrong:

int gw = 50;
g_Vertices[i*(gw+1) + j].x = i*100.0f;
g_Vertices[i*(gw+1) + j].y = 100;
g_Vertices[i*(gw+1) + j].z = j*100.0f;

I can''t believe you''re not getting overflow crashes. The way I''m reading this, when i=0 and j=0, your index into the g_Vertices array would be 0. Fair enough, but when i increments to 1, your index would be 51 (1*(50+1)+0) which is skipping 1 through 50. I''m pretty sure this isn''t what you want because your DrawPrimitive statement expects these elements to be sequential.

Instead of what you have, just increment an iVertexCount variable and use that as your index:

g_Vertices[iVertexCount].x = i*100.0f;
g_Vertices[iVertexCount].y = 100;
g_Vertices[iVertexCount].z = j*100.0f;
iVertexCount++

There could be other problems, but that''s the first thing that jumps out at me.

bpopp (bpopp.net)

Share this post


Link to post
Share on other sites
I''m not saying that I''m not mistaken, but I think it is sequential, due to the for loop, increasing j. When i increments to 1, j is 50. So it goes from 50 to 51. Thanks for the idea, I''ll check over the code once again.

Share this post


Link to post
Share on other sites
Yeah, you're right. I know this doesn't answer your question, but you might try simplifying your code a little bit and the problem may jump out at you. Here's how I do my vertex/index buffer initialization.


    
int iNW, iNE, iSW, iSE;

iNE = AddVertex (x+width, GetHeight(x+width, y ), y );
iNW = AddVertex (x, GetHeight(x, y ), y );
iSW = AddVertex (x, GetHeight ( x, y + width ), y );
iSE = AddVertex (x+width, GetHeight ( x+width, y+width ), y );

m_Indices[m_IndexCount++] = nSW;
m_Indices[m_IndexCount++] = nSE; m_Indices[m_IndexCount++] = nNW;
m_Indices[m_IndexCount++] = nNW;
m_Indices[m_IndexCount++] = nSE;
m_Indices[m_IndexCount++] = nNE;

float CTerrain::AddVertex ( float x, float y, float z )
{
InitVertex ( &m_Vertexes[m_VertexCount], x, y, z );
return m_VertexCount++;
}

float CTerrain::InitVertex ( D3DVERTEX *vertex, float x, float y, float z )
{
vertex->x = x;
vertex->y = y/(m_Heightscale);
vertex->z = z;
vertex->tu = x/(m_mapSize);
vertex->tv = y/(m_mapSize);
}


bpopp (bpopp.net)

[edited by - bpopp on May 28, 2003 3:56:15 PM]

Share this post


Link to post
Share on other sites
I know my code is disgusting, but I think it''s more something to do with the DirectX side of things. I''m not going to use a grid anyway. I''ve got all my binary tree creation done, just commented out, I''m only using the grid, to simplify things so I can sort out this one problem.

I don''t think the geometry is the problem. I think it''s something else, either in the creation of the buffers, or in the rendering part.

Share this post


Link to post
Share on other sites
I don''t see anything wrong with your rendering code. What''s your view setup look like?

If you think it would help, you can look at my quadtree terrain here if you want to see how I do my rendering. It''s pretty messy since I''ve pieced it together bit by bit over time, but it works. Unfortunately, my view projection is done in a separate camera class, but the old manual method is still there (commented out) in the SetEnvironment function.

bpopp (bpopp.net)

Share this post


Link to post
Share on other sites
The view system isn''t the problem. I know exactly where the tris are being rendered, and that''s in a spot at the origin. It''s very frustrating. Also it uses the same system as everything else and my meshes render fine. The reason I didn''t post it, is that it''s also in my camera class. I''ll take a look at your code. Thanks.

Share this post


Link to post
Share on other sites
Well thanks a lot bpopp. It was just in the memcpy lines. I was using sizeof(g_Vertices), which isn''t the same as NumVertices * sizeof(TERRAINVERTEX). Which is always a problem. Thanks all the same for your suggestions. I noticed it while reading through your code.

Well that was many hours wasted. I''ve never been good with the programming aspect. I''ve always been better with the maths.

Share this post


Link to post
Share on other sites