How change LOD in geometry?
Posted
by
ChaosDev
on Game Development
See other posts from Game Development
or by ChaosDev
Published on 2012-07-08T14:24:33Z
Indexed on
2012/07/08
15:23 UTC
Read the original article
Hit count: 276
c++
|level-of-detail
Im looking for simple algorithm of LOD, for change geometry vertexes and decrease frame time. Im created octree, but now I want model or terrain vertex modify algorithm,not for increase(looking on tessellation later) but for decrease.
I want something like this
Questions:
- Is same algorithm can apply either to model and terrain correctly?
- Indexes need to be modified ?
- I must use octree or simple check distance between camera and object for desired effect ?
- New value of indexcount for DrawIndexed function needed ?
Code:
//m_LOD == 10 in the beginning
//m_RawVerts - array of 3d Vector filled with values from vertex buffer.
void DecreaseLOD()
{
m_LOD--;
if(m_LOD<1)m_LOD=1;
RebuildGeometry();
}
void IncreaseLOD()
{
m_LOD++;
if(m_LOD>10)m_LOD=10;
RebuildGeometry();
}
void RebuildGeometry()
{
void* vertexRawData = new byte[m_VertexBufferSize];
void* indexRawData = new DWORD[m_IndexCount];
auto context = mp_D3D->mp_Context;
D3D11_MAPPED_SUBRESOURCE data;
ZeroMemory(&data,sizeof(D3D11_MAPPED_SUBRESOURCE));
context->Map(mp_VertexBuffer->mp_buffer,0,D3D11_MAP_READ,0,&data);
memcpy(vertexRawData,data.pData,m_VertexBufferSize);
context->Unmap(mp_VertexBuffer->mp_buffer,0);
context->Map(mp_IndexBuffer->mp_buffer,0,D3D11_MAP_READ,0,&data);
memcpy(indexRawData,data.pData,m_IndexBufferSize);
context->Unmap(mp_IndexBuffer->mp_buffer,0);
DWORD* dwI = (DWORD*)indexRawData;
int sz = (m_VertexStride/sizeof(float));//size of vertex element
//algorithm must be here.
std::vector<Vector3d> vertices;
int i = 0;
for(int j = 0; j < m_VertexCount; j++)
{
float x1 = (((float*)vertexRawData)[0+i]);
float y1 = (((float*)vertexRawData)[1+i]);
float z1 = (((float*)vertexRawData)[2+i]);
Vector3d lv = Vector3d(x1,y1,z1);
//my useless attempts
if(j+m_LOD+1<m_RawVerts.size())
{
float v1 = VECTORHELPER::Distance(m_RawVerts[dwI[j]],m_RawVerts[dwI[j+m_LOD]]);
float v2 = VECTORHELPER::Distance(m_RawVerts[dwI[j]],m_RawVerts[dwI[j+m_LOD+1]]);
if(v1>v2)
lv = m_RawVerts[dwI[j+1]];
else
if(v2<v1)
lv = m_RawVerts[dwI[j+2]];
}
(((float*)vertexRawData)[0+i]) = lv.x;
(((float*)vertexRawData)[1+i]) = lv.y;
(((float*)vertexRawData)[2+i]) = lv.z;
i+=sz;//pass others vertex format values without change
}
for(int j = 0; j < m_IndexCount; j++)
{
//indices ?
}
//set vertexes to device
UpdateVertexes(vertexRawData,mp_VertexBuffer->getSize());
delete[] vertexRawData;
delete[] indexRawData;
}
© Game Development or respective owner