LOD 地形渲染问题

啊福 2012-06-04 11:27:53
LOD学习有一周了,有一些突破,还是有BUG,不知道怎么解决,下面是效果图:


这里只是先修补上方点,加了俩条边!


这里多了很多莫名的边,不知道原因.

下面给出顶点添加的代码:
void GameLodTerrain::SetNodeVertex(QuadTreeNode *pNode)
{

if(pNode->m_Size<2||pNode==NULL) return;
if (FALSE == pNode->m_bIsVisible||FALSE==pNode->m_bIsTouched)
return;
if (TRUE == pNode->m_bIsReached)
{
// fill vertex buffer
static INT nSizeDivide2 = m_row >> 1;
INT L = pNode->m_CenterX - (pNode->m_Size >> 1); // left
INT R = pNode->m_CenterX + (pNode->m_Size >> 1); // right
INT X = pNode->m_CenterX; // center X
INT Y = pNode->m_CenterY; // center Y
INT T = pNode->m_CenterY - (pNode->m_Size >> 1); // top
INT B = pNode->m_CenterY + (pNode->m_Size >> 1); // bottom

INT L1=0;INT R1=0;INT T1=0;INT B1=0;
if(!pNode->m_bIsLeaf&&pNode->m_Size<=4)
{
L1 = pNode->m_CenterX - (pNode->m_Size >> 2); // left
R1 = pNode->m_CenterX + (pNode->m_Size >> 2); // right
T1 = pNode->m_CenterY - (pNode->m_Size >> 2); // top
B1 = pNode->m_CenterY + (pNode->m_Size >> 2); // bottom
}

// 1 2 3 TL Top TR
// 8 0 4 -> Left Center Right
// 7 6 5 BL Bottom BR
int i=0;
// CENTER
m_pVerticesPtr[m_vbIndex + i]._x = (X - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._z = (Y - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._y = m_heightmap[Y][X];
m_pVerticesPtr[m_vbIndex + i]._u = m_tuArray[X];
m_pVerticesPtr[m_vbIndex + i]._v = m_tvArray[Y];
i++;
// TL
m_pVerticesPtr[m_vbIndex + i]._x = (L - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._z = (T - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._y = m_heightmap[T][L];
m_pVerticesPtr[m_vbIndex + i]._u = m_tuArray[L];
m_pVerticesPtr[m_vbIndex + i]._v = m_tvArray[T];
i++;
// TOP,上方要进行修补处理
QuadTreeNode *n=FindNode(X,Y-pNode->m_Size);
if(pNode->m_bIsLeaf||n==NULL)
{
m_pVerticesPtr[m_vbIndex + i]._x = (X - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._z = (T - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._u = m_tuArray[X];
m_pVerticesPtr[m_vbIndex + i]._v = m_tvArray[T];
m_pVerticesPtr[m_vbIndex + i]._y = m_heightmap[T][X];
i++;
}
else if(n->m_Size>4||n->m_bIsReached||!n->m_bIsTouched)
{

m_pVerticesPtr[m_vbIndex + i]._x = (X - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._z = (T - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._u = m_tuArray[X];
m_pVerticesPtr[m_vbIndex + i]._v = m_tvArray[T];
m_pVerticesPtr[m_vbIndex + i]._y = m_heightmap[T][X];
i++;
}
else if(!n->m_bIsReached&&n->m_Size<=4)
{
m_pVerticesPtr[m_vbIndex + i]._x = (L1 - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._z = (T - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._u = m_tuArray[L1];
m_pVerticesPtr[m_vbIndex + i]._v = m_tvArray[T];
m_pVerticesPtr[m_vbIndex + i]._y = m_heightmap[T][L1];
i++;
m_pVerticesPtr[m_vbIndex + i]._x = (X - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._z = (T - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._u = m_tuArray[X];
m_pVerticesPtr[m_vbIndex + i]._v = m_tvArray[T];
m_pVerticesPtr[m_vbIndex + i]._y = m_heightmap[T][X];
i++;
m_pVerticesPtr[m_vbIndex + i]._x = (R1 - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._z = (T - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._u = m_tuArray[R1];
m_pVerticesPtr[m_vbIndex + i]._v = m_tvArray[T];
m_pVerticesPtr[m_vbIndex + i]._y = m_heightmap[T][R1];
i++;
}
// TR
m_pVerticesPtr[m_vbIndex + i]._x = (R - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._z = (T - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._y = m_heightmap[T][R];
m_pVerticesPtr[m_vbIndex + i]._u = m_tuArray[R];
m_pVerticesPtr[m_vbIndex + i]._v = m_tvArray[T];
i++;
// RIGHT
m_pVerticesPtr[m_vbIndex + i]._x = (R - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._z = (Y - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._u = m_tuArray[R];
m_pVerticesPtr[m_vbIndex + i]._v = m_tvArray[Y];
m_pVerticesPtr[m_vbIndex + i]._y = m_heightmap[Y][R];
i++;
// BR
m_pVerticesPtr[m_vbIndex + i]._x = (R - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._z = (B - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._y = m_heightmap[B][R];
m_pVerticesPtr[m_vbIndex + i]._u = m_tuArray[R];
m_pVerticesPtr[m_vbIndex + i]._v = m_tvArray[B];
i++;
//BOTTOM
m_pVerticesPtr[m_vbIndex + i]._x = (X - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._z = (B - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._u = m_tuArray[X];;
m_pVerticesPtr[m_vbIndex + i]._v = m_tvArray[B];
m_pVerticesPtr[m_vbIndex + i]._y = m_heightmap[B][X];
i++;
// BL
m_pVerticesPtr[m_vbIndex + i]._x = (L - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._z = (B - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._y = m_heightmap[B][L];
m_pVerticesPtr[m_vbIndex + i]._u = m_tuArray[L];
m_pVerticesPtr[m_vbIndex + i]._v = m_tvArray[B];
i++;
// LEFT
m_pVerticesPtr[m_vbIndex + i]._x = (L - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._z = (Y - nSizeDivide2) * m_wScale;
m_pVerticesPtr[m_vbIndex + i]._u = m_tuArray[L];
m_pVerticesPtr[m_vbIndex + i]._v = m_tvArray[Y];
m_pVerticesPtr[m_vbIndex + i]._y = m_heightmap[Y][L];
i++;


// fill index buffer
// 1 2 3
// 8 0 4
// 7 6 5
int j=0;
for(int k=1;k<i-1;k++)
{
m_pIndicesPtr[m_ibIndex+ j] = (WORD)m_vbIndex + k;
j++;
m_pIndicesPtr[m_ibIndex+ j] = (WORD)m_vbIndex + k+1;
j++;
m_pIndicesPtr[m_ibIndex+ j] = (WORD)m_vbIndex + 0;
j++;
}
m_pIndicesPtr[m_ibIndex+ j] = (WORD)m_vbIndex + i-1;
j++;
m_pIndicesPtr[m_ibIndex+ j] = (WORD)m_vbIndex + 1;
j++;
m_pIndicesPtr[m_ibIndex+ j] = (WORD)m_vbIndex + 0;
j++;

m_vbIndex += i;
m_ibIndex += j;

}
else if (!pNode->m_bIsLeaf)
{
SetNodeVertex(pNode->m_pTLChildNode);
SetNodeVertex(pNode->m_pTRChildNode);
SetNodeVertex(pNode->m_pBLChildNode);
SetNodeVertex(pNode->m_pBRChildNode);
}
}
希望有高手指点下迷津。


...全文
315 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
tl_ 2013-03-28
  • 打赏
  • 举报
回复
我也为此问题烦恼,终于知道了
啊福 2012-06-30
  • 打赏
  • 举报
回复
当然大型地形不止一张纹理:

1:纹理混合
2:采用分块的地形,实现无缝连接
一开始的回忆 2012-06-28
  • 打赏
  • 举报
回复
那么我想问,那么大型的地形 也是用一张贴图么?比如 大型3d网游的?
啊福 2012-06-21
  • 打赏
  • 举报
回复
用一张就好,用 D3DTADDRESS_WRAP:

纹理地址模式具有包装模式(Wrap),镜像模式(Mirror),夹子模式(Clamp),边界模式(Border)和一次镜像模式(MirrorOnce)等多种寻址控制方式
一开始的回忆 2012-06-20
  • 打赏
  • 举报
回复
问你个问题,你这样 的 地形 ,做了lod,那么贴图 怎么帖?用1张贴图?还是多个 平铺?
啊福 2012-06-09
  • 打赏
  • 举报
回复
问题已经解决了,问题出在DrawIndexedPrimitive:

HRESULT DrawIndexedPrimitive(
D3DPRIMITIVETYPE Type,
INT BaseVertexIndex,
UINT MinIndex,
UINT NumVertices,
UINT StartIndex,
UINT PrimitiveCount
);

Type——不用过多解释的参数,就是图元类型,像是线段、三角形等等。

BaseVertexIndex——这个用作偏移量,比如我们在索引缓冲中的顶点是Vx=10(Vx表示顶点在顶点数组中的下标,下同),那么Vx实际上传递到显卡是Vx+BaseVertexIndex,为什么要加上这个参数呢?他的好处在于,如果我一次性在一个顶点缓冲中加上了别的几个顶点缓冲,那么我再用一个索引缓冲去定位顶点的话就会有问题,比如原先有个缓冲A,其中某个顶点Vx=10,那么现在我把这个缓冲附到了某个缓冲B后面,这个时候顶点的索引依旧是Vx=10,但是下标为10的这个顶点已经不是原来那个了,因为前面加上了缓冲B。对于老版的DX8,我们可以通过修改索引缓冲达到相应的效果,然而这项操作的时间复杂度是O(n),现在我们就用不到了,只要交给DX自己处理。

MinIndex——下标最小的顶点,顾名思义,就是在本次绘图过程中用到的下标最小的顶点。(估计给D3D做优化用,参考下一个参数的说明)

NumVertices——这恐怕是最坑爹的参数,网上给出的说法都是:用到的顶点数,但实际上呢?如果尝试用用到的顶点数去做参数的话,在PIX中调试程序,会出现各种错误,像是Index Out Of Range(索引超越边界),严重的导致PIX崩溃。在查阅了大量资料后,终于知道了这个参数的含义:一次绘图中顶点索引的跨度(即Vmax-Vmin+1),只是跨度而不一定是顶点数目,也就是说可以包含一些没有用到的顶点……这么说来,用作优化还真是很有道理的,因为在知道MinIndex以后,D3D就可以把MinIndex~MinIndex+NumVertices这段的数据提取出来用于渲染,省去了不必要的内存开销……

StartIndex——这个函数很简单,表示索引缓冲中开始的那个下标

PrimitiveCount——绘制的图元个数,配合StartIndex来定位索引缓冲

解决后的效果:


也就是 SetNodeVertex(QuadTreeNode *pNode) 这段代码是正确的,以上大家可以共享下!!!
啊福 2012-06-06
  • 打赏
  • 举报
回复
自己顶一下~~~

8,303

社区成员

发帖
与我相关
我的任务
社区描述
游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧