Sign in to follow this  
JonConley

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

Recommended Posts

JonConley    215
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]

Share this post


Link to post
Share on other sites
harveypekar    219
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?

Share this post


Link to post
Share on other sites
glaeken    294
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]

Share this post


Link to post
Share on other sites
JonConley    215
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[i] = 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));
}



Share this post


Link to post
Share on other sites
glaeken    294
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.

Share this post


Link to post
Share on other sites
JonConley    215
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.

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