Archived

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

Sheep

several problems with my terrain generator

Recommended Posts

Hello everyone. I have recently been working on a terrain generator, and have finally gotten something up that somewhat resembles terrain ( not quite ). However, now I seem to be getting less than one frame per second (average: 0.014 fps). I cant seem to think why it would do this. The only thing the debugger gives is this: First-chance exception in Test.exe (GDI32.DLL): 0xC0000005: Access Violation. Could that be the cause? The debugger doesnt tell me what line its on, so I dont know whats causing it. Here is the relevant code:
    
HRESULT CTerrain::FillVB( LPDIRECT3DDEVICE8 pd3dDevice )
{
	if( pd3dDevice == NULL )
		return E_FAIL;
	
	// create the vertices

	DWORD count = 0L;
	
	for ( float x = 0; x < m_nWidth; x ++ )
	{
		for ( float z = 0; z < m_nHeight; z ++ )
		{
			m_pMapIndex[count].p.x = x*2;
			m_pMapIndex[count].p.y = GetCell( x, z );
			m_pMapIndex[count].p.z = z*2;
			m_pMapIndex[count].tu0 = ((x)/m_nWidth);
			m_pMapIndex[count].tv0 = 1.0f-((z)/m_nHeight);
			count++;

		}
	}

	if( FAILED( pd3dDevice->CreateVertexBuffer(m_dwNumVerts * sizeof(TERRAIN_VERT),
												  0, D3DFVF_TERRAIN,
												  D3DPOOL_DEFAULT, &m_pVB ) ) )
	{
		return E_FAIL;
	}
	
	// Fill vertex buffer

	VOID* pVertices;
	if( FAILED( m_pVB->Lock( 0, sizeof(TERRAIN_VERT) * m_dwNumVerts, (BYTE**)&pVertices, 0 ) ) )
	{
		return E_FAIL;
	}
	memcpy(pVertices, m_pMapIndex, sizeof(TERRAIN_VERT) * m_dwNumVerts);
	m_pVB->Unlock();

	return S_OK;

}

HRESULT CTerrain::FillIB( LPDIRECT3DDEVICE8 pd3dDevice )
{
	
	if( pd3dDevice == NULL )
		return E_FAIL;
	
	m_dwNumTris  = m_nWidth * m_nHeight;
	m_pdwIndices = new DWORD[m_dwNumTris * 6];

	DWORD count  =  0L;
	for ( int z = 0; z < m_nHeight; z ++ )
	{
		for (int x = 0; x < m_nWidth; x ++)
		{
			// create vertex index from co-ordinate

			WORD index= x + (z * m_nWidth );

			m_pdwIndices[count]=index;
			m_pdwIndices[count+1]=index+m_nWidth;
			m_pdwIndices[count+2]=index+1;

			count+=3;

			m_pdwIndices[count]=index+m_nWidth;
			m_pdwIndices[count+1]=index+m_nWidth+1;
			m_pdwIndices[count+2]=index+1;

			count+=3;

		}
	}

	// Triangle indexes

	if( FAILED( pd3dDevice->CreateIndexBuffer( m_dwNumTris*sizeof(DWORD)*3,
												  D3DUSAGE_WRITEONLY,
												  D3DFMT_INDEX16,
												  D3DPOOL_DEFAULT,
												  &m_pIB) ) )
	{
		return E_FAIL;
	}
	
	VOID *pIndices;
	if( FAILED( m_pIB->Lock( 0, m_dwNumTris*sizeof(WORD)*3, (BYTE**)&pIndices, 0 ) ) )
		return E_FAIL;
	memcpy(pIndices,m_pdwIndices,sizeof(WORD)*m_dwNumTris*3);
	m_pIB->Unlock();

	return S_OK;
}   

and for rendering:

      
pd3dDevice->SetTexture( 0, m_pTexture );
	
	pd3dDevice->SetStreamSource(0, m_pVB, sizeof(TERRAIN_VERT));
	pd3dDevice->SetVertexShader(D3DFVF_TERRAIN);
	pd3dDevice->SetIndices(m_pIB, 0 );


	pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 
		                               0, m_dwNumVerts, 0, 
									   m_dwNumTris );     
Any ideas? Thanks. [edited by - Sheep on May 5, 2002 12:54:57 PM]

Share this post


Link to post
Share on other sites
1024x1024 vertices along with an index buffer...I have a pentium4 @ 1.3ghz + geforceMx 400 + 128mb RAM.

Share this post


Link to post
Share on other sites
You''re right, there must be something wrong there! I will have to check over it a little more in depth when I have some time.

Moe''s site

Share this post


Link to post
Share on other sites
1024 x 1024 vertices at 32 bytes each is 32 MB. That''s a whole lot of vertices. Coupled with a large index buffer to index them all 3 times, that''s fairly punishing the card.

A good idea would be to split the terrain up into smaller chunks (a couple of MB per chunk) and draw the chunks induvidually. That way you could implement some kind of frustum culling too.


Helpful links:
How To Ask Questions The Smart Way | Google can help with your question | Search MSDN for help with standard C or Windows functions

Share this post


Link to post
Share on other sites
Hmmm...32mb? Thats all the memory my vid-card has Is there a simple way of implementing the drawing in chunks? I tried doing that once (fine, it was only a couple of hours ago) but it was far too confusing for me...Thanks.

Share this post


Link to post
Share on other sites
Ahh, so the vertices are being stored in system memory instead of video card memory.

For splitting things into chunks you may want to check out Octrees or something similar. There''s a fair bit of sample code at gametutorials.com (shame there''s not actually a tutorial) but I''m sure a google search will find Octree tutorials. I think there''s one on either here or flipcode too.

Whatever way you do it, these vertices aren''t all going to fit into video memory, so if you must have that resolution you''re going to have to put up with bad frame rates. You could also look into some form of mesh optimisation, like replacing low-detail parts of the terrain with larger polygons.


Helpful links:
How To Ask Questions The Smart Way | Google can help with your question | Search MSDN for help with standard C or Windows functions

Share this post


Link to post
Share on other sites
Thanks...Ill check that out. However, now I have some more problems. I am loading in a .tga (targa) image for my heightmap, and it seems that instead of making the terrain a square, it elongates it and makes it a rectangle. Do any of you know why this might happen? Also, when I render the terrain as a point list, everything looks fine except that it is stretched, but when I draw it as a triangle list, there is like a big triangle jutting downward out of the middle. And of course, one more problem. I currently also have a mesh in my world, and so I never bothered setting the mesh''s own world matrix, but when I did it dissapeared without a trace! thanks.

Share this post


Link to post
Share on other sites
Usually when I see a big triangle jetting off from a side of the terrain, that usaully means one of the vertices is out of bounds.

MY biggest problem when creating terrain was using arrays, I would often confuse myself on where the array begins and ends.

Share this post


Link to post
Share on other sites
Does anyone know why the terrain might be stretched? Instead of 1024 verts by 1024 verts, its turns out to be 22xSomeNumber effectively making it a rectangle! Any ideas? this is getting really annoying. Also, the other two problems described have not yet been fixed Should I start a new thread because people think that this one is about a slow terrain generator?

Share this post


Link to post
Share on other sites
well I think the reason the terrain seems to be a triangle is that your rendering only half or a part of your triangles.

This is probably again related to your use of the array to keep the vertices. It may be related to the way your accessing the arrays that would be causing the stretched triangle and only part of the terrain being render (the "rectangluar" effect)

I would look over and make sure your parsing through the array of vertices correctly, and also make sure your using the correct size for each vertex structure(x,y,z, normal, extra info) .

Share this post


Link to post
Share on other sites
Looking over your code....it seems correct
Except I notice your doubling the size of the terrain by putting x*2 and z*2 for the x and z locations. BUT on your texture coordinates, your only using z and x as in :

m_pMapIndex[count].tu0 = ((x)/m_nWidth);
m_pMapIndex[count].tv0 = 1.0f-((z)/m_nHeight);

you need to double those values too. But that shouldn''t make a big difference in the look


also in FillIB(), the line:
m_dwNumTris = m_nWidth * m_nHeight;

is not correct...if you have a 3x3 grid of points you will have 8 triangles not 9 (using your formula). The acutal number of triangles is:

m_dwNumTris = (m_nWidth-1) * (m_nHeight-1) * 2

That would probably be way your only rendering half the terrain.

Hope that helps.

Share this post


Link to post
Share on other sites
Sorry if I wasnt clear about that Pactuul...I emailed you some screenshots of whats going on...

EDIT: Pactuul you posted before i sent the email...i'll try that.

[edited by - Sheep on May 5, 2002 2:51:27 PM]

Share this post


Link to post
Share on other sites
hahaha! thanks alot! the triangle is still sticking out, but now the terrain is sized correctly....somewhat...when I do the number of tri''s * 2, it wider, but still longer...if I multiply by 6 its even more square like...any ideas why this happens?

Share this post


Link to post
Share on other sites
that triangle sticking out is where I think GetCell(x,z) is returning an invalid number. Since the triangle looks like its at the end corner, it might be near the end of the array, so make sure your generating correct heights for ALL those points, cause I think you might accidently be leaving off the last one.

Share this post


Link to post
Share on other sites
Wow! You were right! It was in the GetCell(x,y) function! but now I still have my problem with this:

m_dwNumTris = ((m_nWidth-1) * (m_nHeight-1)) * 2;

That makes the terrain more square-like than before, but not quite. Then I tryed multiplying it by 6 instead of 2 and it became even more square like, but not quite. What do I have to do to make it a square??? Thanks for your help so far...

Share this post


Link to post
Share on other sites
hmmm well I think that algo isn't quite right either:

m_dwNumTris = ((m_nWidth-1) * (m_nHeight-1)) * 2;

thinking about it: try dropping the -1's on the equation.

Better YET: to definately make sure, in your FillIB() do this

      
for ( int z = 0; z < m_nHeight; z ++ )
{
for (int x = 0; x < m_nWidth; x ++)
{
// create vertex index from co-ordinate

WORD index= x + (z * m_nWidth );
m_pdwIndices[count]=index;
m_pdwIndices[count+1]=index+m_nWidth;
m_pdwIndices[count+2]=index+1;
count+=3;
m_pdwIndices[count]=index+m_nWidth;
m_pdwIndices[count+1]=index+m_nWidth+1;
m_pdwIndices[count+2]=index+1;
count+=3;
m_dwNumTris += 2;
//change!

}
}


And of course delete the other m_dwNumTris code that modifies it.



[edited by - Pactuul on May 6, 2002 11:32:27 AM]

Share this post


Link to post
Share on other sites