Archived

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

Heightmap: Formula for the 1D Array (that represents 2D)?

This topic is 5014 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to figure out the formula for the 1D array that 'mimics a 2D array', so that you can access values and get values through a 1D array as if it were 2D. This is helpful to keep your data aligned with a vertex buffer, etc. But I'm struggling, heres what I've got: [code removed, this part of the problem is solved, please look below] [edited by - Estauns on March 25, 2004 1:28:10 AM] [edited by - Estauns on March 25, 2004 2:00:39 PM]

Share this post


Link to post
Share on other sites
index2D[x][z] = index[(z * uiXSize)+x] for a row major array
Because remember, you should be multiplying the row index by the number of COLUMNS, not the number of rows.

[edited by - psamty10 on March 25, 2004 1:36:46 AM]

Share this post


Link to post
Share on other sites
Okay that works fine in the DOS console test app, thanks a lot for that.

But now I''m having problems with my terrain, I''m not too sure whats wrong exactly, I think its an index buffer issue but maybe not?

Heres a picture:


As you can see, the lines are shooting out in every which way.

Heres the code:

CHeightmap :: CHeightmap(IDirect3DDevice9 *pD3DDevice, unsigned int uiXSize, unsigned int uiZSize, float fScale)
{
m_pVertexBuffer = 0x00;
m_pIndexBuffer = 0x00;
m_pTexture = 0x00;

m_uiXSize = uiXSize;
m_uiZSize = uiZSize;
m_fScale = fScale;

// + 1 for the ''ending vertex'' right?

m_dwTerrainVertices = (m_uiXSize + 1) * (m_uiZSize + 1);
// * 2 as we''re making quads out of triangles.

m_dwTerrainPrimitives = (m_uiXSize * m_uiZSize * 2);

// This should be the same number of vertices as the mesh will have, right?

m_pucTerrainInfo = new unsigned char[m_dwTerrainVertices];

// Setup our information, just give it random values for now.

for(int iLoop = 0; iLoop < m_dwTerrainVertices; ++iLoop)
m_pucTerrainInfo[iLoop] = rand() % 256;

// For some reason I seem to have to declare them then assign them.

// D3DCOLOR_RGBA and D3DCOLOR_COLORVALUE macros don''t seem to work =/

D3DCOLORVALUE rgbaDiffuse = {1.0f, 1.0f, 1.0f, 0.0f};
D3DCOLORVALUE rgbaAmbient = {1.0f, 1.0f, 1.0f, 0.0f};
D3DCOLORVALUE rgbaSpecular = {0.0f, 0.0f, 0.0f, 0.0f};
D3DCOLORVALUE rgbaEmissive = {0.0f, 0.0f, 0.0f, 0.0f};

m_matMaterial.Diffuse = rgbaDiffuse;
m_matMaterial.Ambient = rgbaAmbient;
m_matMaterial.Specular = rgbaSpecular;
m_matMaterial.Power = 0.0f;
m_matMaterial.Emissive = rgbaEmissive;

Create(pD3DDevice);
}

CHeightmap :: ~CHeightmap(void)
{
SAFE_DELETE_ARRAY(m_pucTerrainInfo);

SAFE_RELEASE(m_pTexture);
SAFE_RELEASE(m_pIndexBuffer);
SAFE_RELEASE(m_pVertexBuffer);
}

void CHeightmap :: Render(IDirect3DDevice9 *pD3DDevice)
{
pD3DDevice->SetStreamSource(0, m_pVertexBuffer, 0, sizeof(HEIGHTMAP_VERTEX));
pD3DDevice->SetFVF(D3DFVF_HEIGHTMAP);

pD3DDevice->SetMaterial(&m_matMaterial);

pD3DDevice->SetIndices(m_pIndexBuffer);

pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, m_dwTerrainVertices, 0, m_dwTerrainPrimitives);

return;
}

void CHeightmap :: Create(IDirect3DDevice9 *pD3DDevice)
{
short *pIndexData;
unsigned int x = 0, z = 0;

// Create Our Vertex Buffer!

pD3DDevice->CreateVertexBuffer(sizeof(HEIGHTMAP_VERTEX) * m_dwTerrainVertices, D3DUSAGE_WRITEONLY, D3DFVF_HEIGHTMAP, D3DPOOL_MANAGED, &m_pVertexBuffer, 0x00);
UpdateVertexBuffer();

// Index Buffer Here We Come!

pD3DDevice->CreateIndexBuffer(sizeof(short) * m_dwTerrainPrimitives * 3, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_pIndexBuffer, 0x00);
m_pIndexBuffer->Lock(0, 0, (void **)&pIndexData, 0);
for(z = 0; z < (m_uiZSize); ++z)
{
for(x = 0; x < (m_uiXSize); ++x)
{
*pIndexData++ = x + z * (m_uiXSize + 1);
*pIndexData++ = x + 1 + z * (m_uiXSize + 1);
*pIndexData++ = x + 1 + (z + 1) * (m_uiXSize + 1);

*pIndexData++ = x + z * (m_uiXSize + 1);
*pIndexData++ = x + 1 + (z + 1) * (m_uiXSize + 1);
*pIndexData++ = x + (z + 1) * (m_uiXSize + 1);
}
}
m_pIndexBuffer->Unlock();

return;
}

void CHeightmap :: UpdateVertexBuffer(void)
{
unsigned int x = 0, z = 0;
HEIGHTMAP_VERTEX *pVertexData;

m_pVertexBuffer->Lock(0, 0, (void **)&pVertexData, 0);
for(z = 0; z < (m_uiZSize + 1); ++z)
{
for(x = 0; x < (m_uiXSize + 1); ++x)
{
pVertexData[(z * m_uiXSize) + x].m_vPosition = D3DXVECTOR3(x * m_fScale, m_pucTerrainInfo[(z * m_uiXSize) + x], z * m_fScale);
pVertexData[(z * m_uiXSize) + x].m_vNormal = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
pVertexData[(z * m_uiXSize) + x].tu = 0.0f;
pVertexData[(z * m_uiXSize) + x].tv = 0.0f;
}
}
m_pVertexBuffer->Unlock();

return;
}


Its put together from some tutorials and like the TwoKings.de and AndyPike.com and some code I''ve found in searching the forums, so hopefully its not too hard to read for you guys.

Any ideas? I think its the index buffer that''d be causing an effect like the one above, but I dunno =(

Share this post


Link to post
Share on other sites
It looks like you are continuing the triangles form the end of one row to the beginning of the next row. I used a 1D array in my brute force renderring and just used a nested for loop that would up its index by the width of my image for the outer one and by the row for the inner one. Make sure you stop at the end of each row and not going one more. That''s what solved my problem

Share this post


Link to post
Share on other sites
Are you talking about for my index buffer or my vertex buffer? I''m not sure what you mean.

I''ve tried tinkering with it, changing the loop for my index buffers to m_uiXSize + 1 and m_uiZSize + 1, but that ended up with it crashing, heh.

I''m trying to think it through hypothetically, and the math seems alright to me.

To create a 2x2 patch, you need 9 vertices right? So if you do (m_uiXSize + 1) * (m_uiZSize + 1) thats 9 vertices.

So the VB should be alright, leaving me to think the fault is somewhere in the IB, which I''m not too keen on. If anyone can maybe look that code through for me? From what I''ve gathered from the sites like AndyPike and TwoKings, it seems alright.

If anyone knows, it''d be a really, really big help if you could help me out.

Thanks guys!

Share this post


Link to post
Share on other sites
Guest Anonymous Poster

test = new thing[uiXSize * uiZSize];
test[x + (z * uiZSize)]

will only work if uiZSize and uiXSize are equal - ie its square not rectangular

Share this post


Link to post
Share on other sites
Already fixed the code at the top, thanks to psamty10 who posted the solution: index2D[x][z] = index[(z * uiXSize)+x]

It worked fine with irregular sized in the DOS app.

----

Heres what 2x2 looks like:


The problem has to be in the index buffer, theres no way that thats correct. Unless I''m completely overlooking something.

Heres what my values are (I added some message boxes):

m_uiXSize = 2
m_uiZSize = 2
m_fScale = 10.0

m_dwTerrainVertices = 9
m_dwTerrainPrimitives = 8

Then I create my vertex buffer of 9 vertices and put all the values in with increasing x and z.
This line specifically, within the loop:
pVertexData[(z * m_uiXSize) + x].m_vPosition = D3DXVECTOR3(x * m_fScale, m_pucTerrainInfo[(z * m_uiXSize) + x], z * m_fScale);

Then I create my index buffer of 24 indices (m_dwTerrainPrimitives(8) x 3). I believe thats right, as a quad requires 6 indices and I''m drawing 4 quads.

All the numbers look right and I''ve checked and double checked tutorials from AndyPike.com and TwoKings.de, but I still end up with the messed up triangles pictured above =(

Any ideas?

Share this post


Link to post
Share on other sites