游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2898|回复: 5

LOD 地形渲染问题

[复制链接]

1

主题

8

帖子

11

积分

新手上路

Rank: 1

积分
11
发表于 2012-6-3 14:24:00 | 显示全部楼层 |阅读模式
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++;

                //MessageInt("i",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);
    }
}
希望有高手指点下迷津。

1

主题

8

帖子

11

积分

新手上路

Rank: 1

积分
11
 楼主| 发表于 2012-6-5 00:09:00 | 显示全部楼层

Re:LOD 地形渲染问题

自己顶~~·

1

主题

8

帖子

11

积分

新手上路

Rank: 1

积分
11
 楼主| 发表于 2012-6-6 11:35:00 | 显示全部楼层

Re:LOD 地形渲染问题

自己顶~~

1

主题

8

帖子

11

积分

新手上路

Rank: 1

积分
11
 楼主| 发表于 2012-6-9 00:22:00 | 显示全部楼层

Re:LOD 地形渲染问题

问题已经解决了,问题出在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来定位索引缓冲

1

主题

19

帖子

19

积分

新手上路

Rank: 1

积分
19
发表于 2012-6-9 10:42:00 | 显示全部楼层

Re:LOD 地形渲染问题

lz加油

1

主题

8

帖子

11

积分

新手上路

Rank: 1

积分
11
 楼主| 发表于 2012-6-9 10:47:00 | 显示全部楼层

Re: Re:LOD 地形渲染问题

494588416: ReOD 地形渲染问题

lz加油

谢谢,会的~~· [em19]
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-9 22:59

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表