[FIXED]Terrain not drawing after building VB and IB from RAW file

Started by
4 comments, last by JonConley 14 years, 11 months ago
I am in the process of trying to get a heightmap to work correctly in a quick D3D app. It seems the vertex data (me pulling the byte from the 512/512 RAW file) is fine. Then it gets a little hairy after that. It seems to be screwing up in creating the VB and IB somewhere. [EDIT] Ok I have narrowed it to the VB and IB by rendering it as a User Primitive and just passing vertices, and indices to it which then rendered it correctly. If I use:

Render::d3dManager::Instance()->GetDevice()->SetStreamSource(0, vBuffer, 0,    sizeof(StaticVertex));
Render::d3dManager::Instance()->GetDevice()->SetFVF(StaticMesh_FVF);
Render::d3dManager::Instance()->GetDevice()->SetIndices(iBuffer);
 
Render::d3dManager::Instance()->GetDevice()->DrawIndexedPrimitive(
		D3DPT_TRIANGLELIST, 
		0, 
		0, 
		VertexCount, 
		0, 
		IndexCount / 3);


it doesn't draw anything at all. I've also tried putting if(FAILED() around where I create the VB and IBs and toss a breakpoint in between and it seems to be creating it. vertices is an array of my vertex struct (and I have created the FVF for it) indices is just an int array

Render::d3dManager::Instance()->GetDevice()->CreateVertexBuffer(
		VertexCount * sizeof(StaticVertex), //Size of Buffer
		D3DUSAGE_WRITEONLY, //Usage
		StaticMesh_FVF, //the FVF for this VB
		D3DPOOL_MANAGED, //The Pool in which it is stored
		&vBuffer,
		NULL);

	VOID* pVoid;

	vBuffer->Lock(0,sizeof(vertices), (void**)&pVoid, 0);
	memcpy(pVoid, vertices, sizeof(vertices));
	vBuffer->Unlock();

	//Create The Index Buffer
	Render::d3dManager::Instance()->GetDevice()->CreateIndexBuffer(
		IndexCount* sizeof(int), //Size of the Index Buffer
		D3DUSAGE_WRITEONLY, //Usage of the Index Buffer
		D3DFMT_INDEX32, //Format of the buffer
		D3DPOOL_MANAGED, //Pool to put in mem
		&iBuffer,
		NULL);

	VOID* iVOID;
	iBuffer->Lock(0, sizeof(indices), (void**)indices, 0);
	memcpy(pVoid, iBuffer, sizeof(iBuffer));
	iBuffer->Unlock();




[Edited by - JonConley on April 29, 2009 3:43:04 PM]
Advertisement
Just a couple of stabs in the dark

Did you enable the debug runtime?

Did you try setting the cullmode to none?

What is PIX telling you?

I can't verify this right now, but does sizeof(iBuffer) do what you expect it to do?
The sizeof operator will only return the size of the pointer, not the total size of the array. So your calls to sizeof(vertices) and sizeof(indices), unless they were declared as: vertices[100], will only return the size of these pointers (probably 4 if you're in 32-bit windows environment).

You'll want to do something like: sizeof(StaticVertex) * numVertices, to get the total number of bytes in the vertices array.

Also, if you want to lock the entire vertex/index buffer, you can pass zero in for the SizeToLock parameter. IDirect3DVertexBuffer9::Lock

[Edited by - glaeken on April 29, 2009 2:59:57 PM]
PIX isn't really telling me anything.

I have cullmode set to none and I also have it set to draw wireframe.

Drawing the User Primitive is fine



and yet my vertex and index buffer doesn't seem to work.

Here is the entire height map class as of now

#include "HeightMap.h"HeightMap::HeightMap(std::string FileName, float Scale, int MaxHeight, int MinHeight){	//Binary Reader to read in data from a binary file	BinaryReader* bReader = new BinaryReader(FileName);	//Make an Identity Matrix used for World	D3DXMatrixIdentity(&Transforms);	//Number of vertices = the number of bytes in the file	vertices = new StaticVertex[bReader->FileSize()];		//Set width and the height (its the same since its a square map)	Width = Height = sqrt(static_cast<double>(bReader->FileSize()));	//Number of indices	indices = new int[(Width-1) * (Height - 1) * 6];		//Read the file byte by byte	for(int i = 0; i < bReader->FileSize(); i++)	{		byte readByte = bReader->ReadByte();		float fPercent = static_cast<int>(readByte) / 255.0f;		float height = (MaxHeight - MinHeight) * fPercent + MinHeight;		StaticVertex newVec;		newVec.X = i % Width * Scale - Width* Scale / 2;		newVec.Y = height;		newVec.Z = (int)(i / Width) * Scale - Height * Scale / 2;		newVec.Color = D3DCOLOR_ARGB(255, readByte, readByte, readByte);		vertices = newVec;	}		int counter = 0;	for (int x = 0; x < Width - 1; x++)	{		for (int y = 0; y < Height - 1; y++)		{			int lowerLeft = x + (y+1) * Width;			int lowerRight = (x + 1) + (y +1) * Width;			int topLeft = x + y * Width;			int topRight = (x + 1) + y * Width;			indices[counter++] = topLeft;			indices[counter++] = lowerRight;			indices[counter++] = lowerLeft;			indices[counter++] = topLeft;			indices[counter++] = topRight;			indices[counter++] = lowerRight;		}	}	IndexCount = counter -1;	VertexCount = bReader->FileSize();		Render::d3dManager::Instance()->GetDevice()->CreateVertexBuffer(		VertexCount * sizeof(StaticVertex), //Size of Buffer		D3DUSAGE_WRITEONLY, //Usage		StaticMesh_FVF, //the FVF for this VB		D3DPOOL_MANAGED, //The Pool in which it is stored		&vBuffer,		NULL);	VOID* pVoid;	vBuffer->Lock(0,0, (void**)&pVoid, 0);	memcpy(pVoid, vertices, sizeof(vertices));	vBuffer->Unlock();	//Create The Index Buffer	Render::d3dManager::Instance()->GetDevice()->CreateIndexBuffer(		IndexCount* sizeof(int), //Size of the Index Buffer		D3DUSAGE_WRITEONLY, //Usage of the Index Buffer		D3DFMT_INDEX32, //Format of the buffer		D3DPOOL_MANAGED, //Pool to put in mem		&iBuffer,		NULL);	VOID* iVOID;	iBuffer->Lock(0, 0, (void**)indices, 0);	memcpy(pVoid, iBuffer, sizeof(iBuffer));	iBuffer->Unlock();	bReader->Close();	delete bReader;}void HeightMap::Draw(){	Render::d3dManager::Instance()->GetDevice()->SetStreamSource(0, vBuffer, 0, sizeof(StaticVertex));	Render::d3dManager::Instance()->GetDevice()->SetFVF(StaticMesh_FVF);	Render::d3dManager::Instance()->GetDevice()->SetIndices(iBuffer);	//do translations here	//Render::d3dManager::Instance()->GetDevice()->SetTransform(D3DTS_WORLD, &Transforms);	//Render::d3dManager::Instance()->GetDevice()->DrawIndexedPrimitive(	//	D3DPT_TRIANGLELIST, 	//	0, 	//	0, 	//	VertexCount, 	//	0, 	//	IndexCount / 3);	Render::d3dManager::Instance()->GetDevice()->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, VertexCount, IndexCount/3, indices, D3DFMT_INDEX32, vertices, sizeof(StaticVertex));	//Render::d3dManager::Instance()->GetDevice()->DrawPrimitiveUP(D3DPT_TRIANGLELIST, VertexCount / 3, vertices, sizeof(StaticVertex));}
In your memcpy calls, you're still using the sizeof operator on the vertices/indices pointers for the number of bytes to copy. You need to use sizeof(StaticVertex) * numVertices and likewise for the indices to correctly copy all of the data.
Thanks for helping me fix this, among those things I also made a couple silly copy and past errors that didn't work out so well. I slowly narrowed it down to my index buffer being wrong, the mem copy I was trying to copy my index buffer to the void pointer, fixed that and also changed all indices to shorts to save a little mem.

Thanks again all.

I would like to ask what people think about the code also, I've never really written code for anyone and am in the process of getting a software engineering degree but never really had many professional programmers see any of mine. Just a little feedback on the clarity and structure if you can spare a moment.

This topic is closed to new replies.

Advertisement