C++/DX9 - Terrain Culling Problem

I can see terrain behind terrain from some angles.

Page 1 of 1

2 Replies - 1922 Views - Last Post: 12 October 2009 - 04:22 PM Rate Topic: -----

#1 Zapron  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 12-October 09

C++/DX9 - Terrain Culling Problem

Posted 12 October 2009 - 03:37 PM

I've been working on my first app and learning C++ and DirectX as I go. So far by incorporating concepts from various tutorials I've done the following:
  • Set up visual studio 2008 with direct x 9
  • Created a windows application with a main loop which is used as the game loop.
  • Begun utilizing header files and created custom classes/structures/functions.
  • Initialized DirectX and included the proper directx9 libraries in my project.
  • Generated a terrain using an imported RAW file as the heightmap.
  • Read input from the user's keyboard/mouse and processed the input to perform some functions.
  • Implemented a camera that is controlled by the user's WASD and up,down,left,right arrows.
  • Added color to the vertices of my terrain.
  • Added a basic directional light to the scene (this is where I stopped)

The Problem

Prior to adding color and lights to my scene I had the fillmode set to wireframe (since that's what it was set to in one of the tutorials I had followed). I wanted to see what the scene looked like with color/light, so I turned off wireframe and what I found was that from some angles I could see through terrain in the foreground to the terrain behind it.

With culling off:

From some angles it looks fine.
Posted Image

From the other angles it's as if my terrain is transparent and I can see through to the terrain behind it.
Posted Image

With culling on (set to CCW):
A lot of the terrain is culled.
Posted Image
Posted Image

This is what I have done to attempt to find a solution:

My first thought was that maybe the indices for the terrain were being set in a Counter Clockwise order, so I checked both the verticies and indicies:

LPDIRECT3DVERTEXBUFFER9 FillVertices(HWND han_Window, LPDIRECT3DDEVICE9 p_dx_Device)
 {
	 LPDIRECT3DVERTEXBUFFER9 p_dx_VertexBuffer;
	 OURCUSTOMVERTEX *cv_Vertices = new OURCUSTOMVERTEX[WIDTH*HEIGHT];
	 std::ifstream f_DataFile;
 
	 f_DataFile.open("heightdata.raw", std::ios::binary);
 
	 if (f_DataFile.is_open())
	 {

		for (int x=0;x< WIDTH;x++)		{

			for (int y=0; y< HEIGHT;y++)			{
				cv_Vertices[y*WIDTH + x].x = -x;
				cv_Vertices[y*WIDTH + x].y = y;
				cv_Vertices[y*WIDTH + x].z = f_DataFile.get()/2;

				int int_curZ = cv_Vertices[y*WIDTH + x].z;
				if(int_curZ < SEALEVEL)
				{
					cv_Vertices[y*WIDTH + x].color = 0xff0000ff;
				}
				if(int_curZ > SEALEVEL && int_curZ <= TREELEVEL)
				{
					cv_Vertices[y*WIDTH + x].color = 0xff00ff00;
				}
				else
				{
					cv_Vertices[y*WIDTH + x].color = 0xff804000;
				}

				cv_Vertices[y*WIDTH + x].normal.x = 1;
				cv_Vertices[y*WIDTH + x].normal.y = 0;
				cv_Vertices[y*WIDTH + x].normal.z = 1;
			}
		}
	}else{
		MessageBox(han_Window,"HeighData file not found!","FillVertices()",MB_OK);
	}

	f_DataFile.close();

	if (FAILED(p_dx_Device->CreateVertexBuffer(WIDTH*HEIGHT*sizeof(OURCUSTOMVERTEX), 0, D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE, D3DPOOL_DEFAULT, &p_dx_VertexBuffer, NULL)))
	{		MessageBox(han_Window,"Error while creating VertexBuffer","FillVertices()",MB_OK);
	}

	VOID* p_Vertices;
	if (FAILED(p_dx_VertexBuffer->Lock(0, WIDTH*HEIGHT*sizeof(OURCUSTOMVERTEX), (void**)&p_Vertices, 0)))
	{
		MessageBox(han_Window,"Error trying to lock","FillVertices()",MB_OK);
	}else{
		memcpy(p_Vertices, cv_Vertices, WIDTH*HEIGHT*sizeof(OURCUSTOMVERTEX));
		p_dx_VertexBuffer->Unlock();
	}

	delete [] cv_Vertices;
	return p_dx_VertexBuffer;
}



LPDIRECT3DINDEXBUFFER9 FillIndices(HWND han_Window, LPDIRECT3DDEVICE9 p_dx_Device)
{
	LPDIRECT3DINDEXBUFFER9 p_dx_IndexBuffer;
	short *s_Indices = new short[(WIDTH-1)*(HEIGHT-1)*6];


	for (int x=0;x< WIDTH-1;x++)	{

		for (int y=0; y< HEIGHT-1;y++)
		{

			s_Indices[(x+y*(WIDTH-1))*6] = (x+1)+(y+1)*WIDTH;
			s_Indices[(x+y*(WIDTH-1))*6+1] = (x+1)+y*WIDTH;
						s_Indices[(x+y*(WIDTH-1))*6+2] = x+y*WIDTH;
			
						s_Indices[(x+y*(WIDTH-1))*6+3] = (x+1)+(y+1)*WIDTH;
						s_Indices[(x+y*(WIDTH-1))*6+4] = x+y*WIDTH;
						s_Indices[(x+y*(WIDTH-1))*6+5] = x+(y+1)*WIDTH;

		}
	}

	if (FAILED(p_dx_Device->CreateIndexBuffer((WIDTH-1)*(HEIGHT-1)*6*sizeof(short),D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,D3DPOOL_MANAGED,&p_dx_IndexBuffer,NULL)))
	{
		MessageBox(han_Window,"Error while creating IndexBuffer","FillIndices()",MB_OK);
	}

	VOID* p_Indices;
	if (FAILED(p_dx_IndexBuffer->Lock(0, (WIDTH-1)*(HEIGHT-1)*6*sizeof(short), (void**)&p_Indices, 0)))
	{
		MessageBox(han_Window,"Error trying to lock","FillIndices()",MB_OK);
	}else{
		memcpy(p_Indices, s_Indices, (WIDTH-1)*(HEIGHT-1)*6*sizeof(short));
		p_dx_IndexBuffer->Unlock();
	}

	delete [] s_Indices;
	return p_dx_IndexBuffer;
}


The WIDTH and HEIGHT of my terrain is 256 by 256. I double checked the population of the cv_Vertices array in FillVertices() and it should produce verticies like:
511......512......513...................765
256......257......258...................510
0..........1..........2......................255

I checked the s_Indices array in FillIndices() and they should be populated like:
s_Indices[0] = 257;
s_Indices[1] = 1;
s_Indices[2] = 0;

s_Indices[3] = 257;
s_Indices[4] = 0;
s_Indices[5] = 256;

Those indices with the vertices described above should produce something like:
Posted Image
If all of that is correct then the indices do refer to vertices in a Clockwise order which from what I understand is correct and should work properly with culling set to CCW.




The full project can be downloaded below. If anyone has a clue what's going on I would greatly appreciate the help. Thanks for reading.
http://thegamerguide...iles/Ataxia.zip

Is This A Good Question/Topic? 0
  • +

Replies To: C++/DX9 - Terrain Culling Problem

#2 Tom9729  Icon User is offline

  • Segmentation fault
  • member icon

Reputation: 180
  • View blog
  • Posts: 2,641
  • Joined: 30-December 07

Re: C++/DX9 - Terrain Culling Problem

Posted 12 October 2009 - 04:15 PM

Unfamiliar with DX but do you have your normals set properly?

What does your scene look like with lighting disabled?

Edit: If this was OpenGL I would say to check whether GL_DEPTH_TEST is enabled, because the screenshots without culling look like depth testing isn't happening. :)

This post has been edited by Tom9729: 12 October 2009 - 04:18 PM

Was This Post Helpful? 0
  • +
  • -

#3 Zapron  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 12-October 09

Re: C++/DX9 - Terrain Culling Problem

Posted 12 October 2009 - 04:22 PM

View PostTom9729, on 12 Oct, 2009 - 03:15 PM, said:

Unfamiliar with DX but do you have your normals set properly?

What does your scene look like with lighting disabled?


My normals are not set properly yet, however, the screenshots in my original post were taken with lighting disabled.

Just to be sure, I removed the lighting code and compiled it again and the problem still existed.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1