基本设计思想:
主要有以下几个类,
CTerrainBlock,地形一个block,每个对象拥有自己的顶点缓冲和相对应的LOD值。
HeightMap类,读入高度图,并根据策略创建一定数量的CTerrainBlock。例如1024x1024的地形,我把每个block大小设置为64x64,那么这个HeightMap有16 x 16个block。
CQuadTree类,四叉树类,根据block的大小划分四叉树。
基本流程:当场景渲染时,在场景UpdateScene的时候,首先Update了Camera数据,然后从新计算Frustum,然后调用m_quadTree.GetRenderObject(list& renderList)函数,以递归形式把quadTree中的在可视区内的渲染对象加到渲染队列,加入队列前并计算出CTerrainBlock的LOD值。到渲染时,首先根据地形的LOD值与相邻四个作判断,然后修补裂缝,具体做法是动态改变IB的值,有些LOD算法是一开始就根据不同的LOD和四边的情况生成N个公共的IB,到渲染时可根据当前情况选择合适的IB以解决裂缝问题。这样可省去计算IB的时间,不过IB的数量会增多,就是以内存换时间。我现在的做法是以时间换内存。
下面是UpdateScene的代码:
void
CTerrainSceneManager::UpdateScene()
{
//在这里应该把所有object更新一次,然后更新渲染队列
CAMERAINST->Update();
FRUSTUM->CalculateFrustum();
m_listRender.clear();
m_quadTree.GetRenderableObject(m_listRender);
//下面的代码也可以在每个Object的Render时调用Update,这里我还没体会到底放在哪里好。当时考虑到shader的调用,所以放到Render里,把这里注释了。
//for (list<CTerrainBlock*>::iterator it = m_listRender.begin(); it != m_listRender.end(); it++)
//{
// (*it)->Update();
//}
}
{
//在这里应该把所有object更新一次,然后更新渲染队列
CAMERAINST->Update();
FRUSTUM->CalculateFrustum();
m_listRender.clear();
m_quadTree.GetRenderableObject(m_listRender);
//下面的代码也可以在每个Object的Render时调用Update,这里我还没体会到底放在哪里好。当时考虑到shader的调用,所以放到Render里,把这里注释了。
//for (list<CTerrainBlock*>::iterator it = m_listRender.begin(); it != m_listRender.end(); it++)
//{
// (*it)->Update();
//}
}
下面是CTerrainBlock的部分代码
1
void
CTerrainBlock::Update()
2 {
3
4 FixCrack(TERRAINSCENE->GetTerrain()); //候补裂缝
5 m_dwTotalIndex = ComputeIndics(); //计算索引并填充IB
6 //UpdateShader();
7 UpdateEffect(); //更新Shader
8}
9
10 void CTerrainBlock::FixCrack(CHeightMap * pTerrain)
11 {
12 m_nLeftIndexCount = 0;
13 m_nRightIndexCount = 0;
14 m_nBottomIndexCount = 0;
15 m_nTopIndexCount = 0;
16
17 //上方
18 CTerrainBlock* pBlock = pTerrain->GetBlock(m_nNeighbor[0]);
19
20 if (pBlock)
21 {
22 FixCrackEdge(pBlock->GetLODLevel(), BLOCK_TOP);
23 }
24
25 //右方
26 pBlock = pTerrain->GetBlock(m_nNeighbor[1]);
27
28 if (pBlock)
29 {
30 FixCrackEdge(pBlock->GetLODLevel(), BLOCK_RIGHT);
31 }
32
33 //下方
34 pBlock = pTerrain->GetBlock(m_nNeighbor[2]);
35
36 if (pBlock)
37 {
38 FixCrackEdge(pBlock->GetLODLevel(), BLOCK_BOTTOM);
39 }
40
41 //左方
42 pBlock = pTerrain->GetBlock(m_nNeighbor[3]);
43
44 if (pBlock)
45 {
46 FixCrackEdge(pBlock->GetLODLevel(), BLOCK_LEFT);
47 }
48}
49
50 void CTerrainBlock::FixCrackEdge( int nNeighborLevel, BLOCKEDGE edge)
51 {
52 if (m_nLODLevel == 3 || nNeighborLevel == m_nLODLevel)
53 {
54 return;
55 }
56 if ((nNeighborLevel - m_nLODLevel) == 1)
57 {
58 switch(edge)
59 {
60 case BLOCK_TOP:
61 //m_vtTopEdge.clear();
62 m_nTopIndexCount = 1;
63
64 break;
65 case BLOCK_RIGHT:
66 m_nRightIndexCount = 1;
67
68 break;
69 case BLOCK_BOTTOM:
70 m_nBottomIndexCount = 1;
71
72 break;
73 case BLOCK_LEFT:
74 m_nLeftIndexCount = 1;
75
76 break;
77 }
78 }
79 else if ((nNeighborLevel - m_nLODLevel) == 2)
80 {
81 switch(edge)
82 {
83 case BLOCK_TOP:
84 m_nTopIndexCount = 3;
85
86 break;
87 case BLOCK_RIGHT:
88 m_nRightIndexCount = 3;
89
90 break;
91 case BLOCK_BOTTOM:
92 m_nBottomIndexCount = 3;
93
94 break;
95 case BLOCK_LEFT:
96 m_nLeftIndexCount = 3;
97
98 break;
99 }
100 }
101}
102
103 void CTerrainBlock::ComputeNeighbor()
104 {
105 m_nNeighbor[0] = m_nTopLeftX + (m_nTopLeftY - m_wGridsPerRow) * m_dwTerrainSize; //上方
106 m_nNeighbor[1] = m_nTopLeftX + m_wGridsPerRow + m_nTopLeftY * m_dwTerrainSize; //右方 //右方
107 m_nNeighbor[2] = m_nTopLeftX + (m_nTopLeftY + m_wGridsPerRow) * m_dwTerrainSize; //下方 //下方
108 m_nNeighbor[3] = m_nTopLeftX - m_wGridsPerRow + m_nTopLeftY * m_dwTerrainSize; //左方 //左方
109}
110
111 DWORD CTerrainBlock::ComputeIndics()
112 {
113 WORD* pIndices = NULL;
114
115 m_pIndexBuffer->Lock(0, 0, (void**)&pIndices, NULL);
116
117 DWORD dwIndex = 0;
118
119 DWORD dwTopLeft = 0;//m_data.dwTopLeft; //声明,topleft是要在block里的topleft,而不是在整个地形的topleft
120 DWORD dwTopRight = m_wBlockSize - 1;
121 DWORD dwBottomRight = m_dwNumBlockVertices - 1;
122 DWORD dwBottomLeft = dwBottomRight - (m_wBlockSize - 1);
123 if (m_nLODLevel == 3) //最大层
124 {
125 for (DWORD nRow = 0; nRow < m_nRealCell; nRow++) //行
126 {
127 for (DWORD nCol = 0; nCol < m_nRealCell; nCol++)
128 {
129 *(pIndices + dwIndex++) = dwTopLeft + nCol * m_wIndexStride + nRow * m_wIndexStride * m_wBlockSize;
130 *(pIndices + dwIndex++) = dwTopLeft + (nCol + 1) * m_wIndexStride + nRow * m_wIndexStride * m_wBlockSize;
131 *(pIndices + dwIndex++) = dwTopLeft + (nCol + 1) * m_wIndexStride + (nRow + 1) * m_wIndexStride * m_wBlockSize;
132
133 *(pIndices + dwIndex++) = dwTopLeft + nCol * m_wIndexStride + nRow * m_wIndexStride * m_wBlockSize;
134 *(pIndices + dwIndex++) = dwTopLeft + (nCol + 1) * m_wIndexStride + (nRow + 1) * m_wIndexStride * m_wBlockSize;
135 *(pIndices + dwIndex++) = dwTopLeft + nCol * m_wIndexStride + (nRow + 1) * m_wIndexStride * m_wBlockSize;
136 }
137 }
138
139 }
140
141 if (m_nLODLevel <= 2) //第二、第三层
142 {
143 //处理上边
144 if (m_nTopIndexCount == 1)
145 {
146 for (DWORD nCol = 0; nCol < m_nRealCell; nCol += 2)
147 {
148 DWORD dwBottom = dwTopLeft + (nCol + 1) * m_wIndexStride + m_wIndexStride * m_wBlockSize;//m_wIndexStride + m_wIndexStride * m_wBlockSize + nCol * m_wIndexStride * 2;
149
150 if (nCol == 0) //处理右边的三角形
151 {
152
153 *(pIndices + dwIndex++) = dwBottom;
154 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride - m_wIndexStride * m_wBlockSize;
155 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride;
156 }
157 else if (nCol == m_nRealCell - 2)
158 {
159 //左下边三角形
160 *(pIndices + dwIndex++) = dwBottom;
161 *(pIndices + dwIndex++) = dwBottom - m_wIndexStride;
162 *(pIndices + dwIndex++) = dwBottom - m_wIndexStride - m_wIndexStride * m_wBlockSize;
163 }
164 else
165 {
166 //左下边三角形
167 *(pIndices + dwIndex++) = dwBottom;
168 *(pIndices + dwIndex++) = dwBottom - m_wIndexStride;
169 *(pIndices + dwIndex++) = dwBottom - m_wIndexStride - m_wIndexStride * m_wBlockSize;
170
171 //右下边三角形
172 *(pIndices + dwIndex++) = dwBottom;
173 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride - m_wIndexStride * m_wBlockSize;
174 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride;
175 }
176
177 //处理上边的三角形
178 *(pIndices + dwIndex++) = dwBottom;
179 *(pIndices + dwIndex++) = dwBottom - m_wIndexStride - m_wIndexStride * m_wBlockSize;
180 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride - m_wIndexStride * m_wBlockSize;
181
182 }
183 }
184 else if (m_nTopIndexCount == 3)
185 {
186 for (DWORD nCol = 0; nCol < m_nRealCell; nCol += 4)
187 {
188 DWORD dwBottom = dwTopLeft + (nCol + 2) * m_wIndexStride + m_wIndexStride * m_wBlockSize;
189
190 if (nCol == 0) //处理右边的三角形
191 {
192 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride;
193 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride * 2 - m_wIndexStride * m_wBlockSize;
194 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride * 2;
195 }
196 else if (nCol == m_nRealCell - 4)
197 {
198 //左下边三角形
199 *(pIndices + dwIndex++) = dwBottom - m_wIndexStride;
200 *(pIndices + dwIndex++) = dwBottom - 2 * m_wIndexStride;
201 *(pIndices + dwIndex++) = dwBottom - 2 * m_wIndexStride - m_wIndexStride * m_wBlockSize;
202 }
203 else
204 {
205 //左下边三角形
206 *(pIndices + dwIndex++) = dwBottom - m_wIndexStride;
207 *(pIndices + dwIndex++) = dwBottom - 2 * m_wIndexStride;
208 *(pIndices + dwIndex++) = dwBottom - 2 * m_wIndexStride - m_wIndexStride * m_wBlockSize;
209
210 //右下边三角形
211 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride;
212 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride * 2 - m_wIndexStride * m_wBlockSize;
213 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride * 2;
214 }
215
216 //处理上边的3个三角形
217 *(pIndices + dwIndex++) = dwBottom;
218 *(pIndices + dwIndex++) = dwBottom - m_wIndexStride;
219 *(pIndices + dwIndex++) = dwBottom - 2 * m_wIndexStride - m_wIndexStride * m_wBlockSize;
220
221 *(pIndices + dwIndex++) = dwBottom;
222 *(pIndices + dwIndex++) = dwBottom - 2 * m_wIndexStride - m_wIndexStride * m_wBlockSize;
223 *(pIndices + dwIndex++) = dwBottom + 2 * m_wIndexStride - m_wIndexStride * m_wBlockSize;
224
225 *(pIndices + dwIndex++) = dwBottom;
226 *(pIndices + dwIndex++) = dwBottom + 2 * m_wIndexStride - m_wIndexStride * m_wBlockSize;
227 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride;
228
229 }
230 }
231 else if (m_nTopIndexCount == 0) //不需要修补
232 {
233 for (DWORD i = 0; i < m_nRealCell; i++)
234 {
235 if (i == 0)
236 {
237 *(pIndices + dwIndex++) = dwTopLeft + m_wIndexStride + m_wIndexStride * m_wBlockSize;
238 *(pIndices + dwIndex++) = dwTopLeft;
239 *(pIndices + dwIndex++) = dwTopLeft + m_wIndexStride;
240
241 }
242 else if (i == m_nRealCell - 1)
243 {
244 *(pIndices + dwIndex++) = dwTopLeft + i * m_wIndexStride + m_wIndexStride * m_wBlockSize;
245 *(pIndices + dwIndex++) = dwTopLeft + i * m_wIndexStride;
246 *(pIndices + dwIndex++) = dwTopRight;
247 }
248 else
249 {
250 *(pIndices + dwIndex++) = dwTopLeft + (i + 1) * m_wIndexStride + m_wIndexStride * m_wBlockSize;
251 *(pIndices + dwIndex++) = dwTopLeft + i * m_wIndexStride + m_wIndexStride * m_wBlockSize;
252 *(pIndices + dwIndex++) = dwTopLeft + i * m_wIndexStride;
253
254 *(pIndices + dwIndex++) = dwTopLeft + i * m_wIndexStride;
255 *(pIndices + dwIndex++) = dwTopLeft + (i + 1) * m_wIndexStride;
256 *(pIndices + dwIndex++) = dwTopLeft + (i + 1) * m_wIndexStride + m_wIndexStride * m_wBlockSize;
257 }
258 }
259 }
260
261
262}
2 {
3
4 FixCrack(TERRAINSCENE->GetTerrain()); //候补裂缝
5 m_dwTotalIndex = ComputeIndics(); //计算索引并填充IB
6 //UpdateShader();
7 UpdateEffect(); //更新Shader
8}
9
10 void CTerrainBlock::FixCrack(CHeightMap * pTerrain)
11 {
12 m_nLeftIndexCount = 0;
13 m_nRightIndexCount = 0;
14 m_nBottomIndexCount = 0;
15 m_nTopIndexCount = 0;
16
17 //上方
18 CTerrainBlock* pBlock = pTerrain->GetBlock(m_nNeighbor[0]);
19
20 if (pBlock)
21 {
22 FixCrackEdge(pBlock->GetLODLevel(), BLOCK_TOP);
23 }
24
25 //右方
26 pBlock = pTerrain->GetBlock(m_nNeighbor[1]);
27
28 if (pBlock)
29 {
30 FixCrackEdge(pBlock->GetLODLevel(), BLOCK_RIGHT);
31 }
32
33 //下方
34 pBlock = pTerrain->GetBlock(m_nNeighbor[2]);
35
36 if (pBlock)
37 {
38 FixCrackEdge(pBlock->GetLODLevel(), BLOCK_BOTTOM);
39 }
40
41 //左方
42 pBlock = pTerrain->GetBlock(m_nNeighbor[3]);
43
44 if (pBlock)
45 {
46 FixCrackEdge(pBlock->GetLODLevel(), BLOCK_LEFT);
47 }
48}
49
50 void CTerrainBlock::FixCrackEdge( int nNeighborLevel, BLOCKEDGE edge)
51 {
52 if (m_nLODLevel == 3 || nNeighborLevel == m_nLODLevel)
53 {
54 return;
55 }
56 if ((nNeighborLevel - m_nLODLevel) == 1)
57 {
58 switch(edge)
59 {
60 case BLOCK_TOP:
61 //m_vtTopEdge.clear();
62 m_nTopIndexCount = 1;
63
64 break;
65 case BLOCK_RIGHT:
66 m_nRightIndexCount = 1;
67
68 break;
69 case BLOCK_BOTTOM:
70 m_nBottomIndexCount = 1;
71
72 break;
73 case BLOCK_LEFT:
74 m_nLeftIndexCount = 1;
75
76 break;
77 }
78 }
79 else if ((nNeighborLevel - m_nLODLevel) == 2)
80 {
81 switch(edge)
82 {
83 case BLOCK_TOP:
84 m_nTopIndexCount = 3;
85
86 break;
87 case BLOCK_RIGHT:
88 m_nRightIndexCount = 3;
89
90 break;
91 case BLOCK_BOTTOM:
92 m_nBottomIndexCount = 3;
93
94 break;
95 case BLOCK_LEFT:
96 m_nLeftIndexCount = 3;
97
98 break;
99 }
100 }
101}
102
103 void CTerrainBlock::ComputeNeighbor()
104 {
105 m_nNeighbor[0] = m_nTopLeftX + (m_nTopLeftY - m_wGridsPerRow) * m_dwTerrainSize; //上方
106 m_nNeighbor[1] = m_nTopLeftX + m_wGridsPerRow + m_nTopLeftY * m_dwTerrainSize; //右方 //右方
107 m_nNeighbor[2] = m_nTopLeftX + (m_nTopLeftY + m_wGridsPerRow) * m_dwTerrainSize; //下方 //下方
108 m_nNeighbor[3] = m_nTopLeftX - m_wGridsPerRow + m_nTopLeftY * m_dwTerrainSize; //左方 //左方
109}
110
111 DWORD CTerrainBlock::ComputeIndics()
112 {
113 WORD* pIndices = NULL;
114
115 m_pIndexBuffer->Lock(0, 0, (void**)&pIndices, NULL);
116
117 DWORD dwIndex = 0;
118
119 DWORD dwTopLeft = 0;//m_data.dwTopLeft; //声明,topleft是要在block里的topleft,而不是在整个地形的topleft
120 DWORD dwTopRight = m_wBlockSize - 1;
121 DWORD dwBottomRight = m_dwNumBlockVertices - 1;
122 DWORD dwBottomLeft = dwBottomRight - (m_wBlockSize - 1);
123 if (m_nLODLevel == 3) //最大层
124 {
125 for (DWORD nRow = 0; nRow < m_nRealCell; nRow++) //行
126 {
127 for (DWORD nCol = 0; nCol < m_nRealCell; nCol++)
128 {
129 *(pIndices + dwIndex++) = dwTopLeft + nCol * m_wIndexStride + nRow * m_wIndexStride * m_wBlockSize;
130 *(pIndices + dwIndex++) = dwTopLeft + (nCol + 1) * m_wIndexStride + nRow * m_wIndexStride * m_wBlockSize;
131 *(pIndices + dwIndex++) = dwTopLeft + (nCol + 1) * m_wIndexStride + (nRow + 1) * m_wIndexStride * m_wBlockSize;
132
133 *(pIndices + dwIndex++) = dwTopLeft + nCol * m_wIndexStride + nRow * m_wIndexStride * m_wBlockSize;
134 *(pIndices + dwIndex++) = dwTopLeft + (nCol + 1) * m_wIndexStride + (nRow + 1) * m_wIndexStride * m_wBlockSize;
135 *(pIndices + dwIndex++) = dwTopLeft + nCol * m_wIndexStride + (nRow + 1) * m_wIndexStride * m_wBlockSize;
136 }
137 }
138
139 }
140
141 if (m_nLODLevel <= 2) //第二、第三层
142 {
143 //处理上边
144 if (m_nTopIndexCount == 1)
145 {
146 for (DWORD nCol = 0; nCol < m_nRealCell; nCol += 2)
147 {
148 DWORD dwBottom = dwTopLeft + (nCol + 1) * m_wIndexStride + m_wIndexStride * m_wBlockSize;//m_wIndexStride + m_wIndexStride * m_wBlockSize + nCol * m_wIndexStride * 2;
149
150 if (nCol == 0) //处理右边的三角形
151 {
152
153 *(pIndices + dwIndex++) = dwBottom;
154 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride - m_wIndexStride * m_wBlockSize;
155 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride;
156 }
157 else if (nCol == m_nRealCell - 2)
158 {
159 //左下边三角形
160 *(pIndices + dwIndex++) = dwBottom;
161 *(pIndices + dwIndex++) = dwBottom - m_wIndexStride;
162 *(pIndices + dwIndex++) = dwBottom - m_wIndexStride - m_wIndexStride * m_wBlockSize;
163 }
164 else
165 {
166 //左下边三角形
167 *(pIndices + dwIndex++) = dwBottom;
168 *(pIndices + dwIndex++) = dwBottom - m_wIndexStride;
169 *(pIndices + dwIndex++) = dwBottom - m_wIndexStride - m_wIndexStride * m_wBlockSize;
170
171 //右下边三角形
172 *(pIndices + dwIndex++) = dwBottom;
173 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride - m_wIndexStride * m_wBlockSize;
174 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride;
175 }
176
177 //处理上边的三角形
178 *(pIndices + dwIndex++) = dwBottom;
179 *(pIndices + dwIndex++) = dwBottom - m_wIndexStride - m_wIndexStride * m_wBlockSize;
180 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride - m_wIndexStride * m_wBlockSize;
181
182 }
183 }
184 else if (m_nTopIndexCount == 3)
185 {
186 for (DWORD nCol = 0; nCol < m_nRealCell; nCol += 4)
187 {
188 DWORD dwBottom = dwTopLeft + (nCol + 2) * m_wIndexStride + m_wIndexStride * m_wBlockSize;
189
190 if (nCol == 0) //处理右边的三角形
191 {
192 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride;
193 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride * 2 - m_wIndexStride * m_wBlockSize;
194 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride * 2;
195 }
196 else if (nCol == m_nRealCell - 4)
197 {
198 //左下边三角形
199 *(pIndices + dwIndex++) = dwBottom - m_wIndexStride;
200 *(pIndices + dwIndex++) = dwBottom - 2 * m_wIndexStride;
201 *(pIndices + dwIndex++) = dwBottom - 2 * m_wIndexStride - m_wIndexStride * m_wBlockSize;
202 }
203 else
204 {
205 //左下边三角形
206 *(pIndices + dwIndex++) = dwBottom - m_wIndexStride;
207 *(pIndices + dwIndex++) = dwBottom - 2 * m_wIndexStride;
208 *(pIndices + dwIndex++) = dwBottom - 2 * m_wIndexStride - m_wIndexStride * m_wBlockSize;
209
210 //右下边三角形
211 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride;
212 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride * 2 - m_wIndexStride * m_wBlockSize;
213 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride * 2;
214 }
215
216 //处理上边的3个三角形
217 *(pIndices + dwIndex++) = dwBottom;
218 *(pIndices + dwIndex++) = dwBottom - m_wIndexStride;
219 *(pIndices + dwIndex++) = dwBottom - 2 * m_wIndexStride - m_wIndexStride * m_wBlockSize;
220
221 *(pIndices + dwIndex++) = dwBottom;
222 *(pIndices + dwIndex++) = dwBottom - 2 * m_wIndexStride - m_wIndexStride * m_wBlockSize;
223 *(pIndices + dwIndex++) = dwBottom + 2 * m_wIndexStride - m_wIndexStride * m_wBlockSize;
224
225 *(pIndices + dwIndex++) = dwBottom;
226 *(pIndices + dwIndex++) = dwBottom + 2 * m_wIndexStride - m_wIndexStride * m_wBlockSize;
227 *(pIndices + dwIndex++) = dwBottom + m_wIndexStride;
228
229 }
230 }
231 else if (m_nTopIndexCount == 0) //不需要修补
232 {
233 for (DWORD i = 0; i < m_nRealCell; i++)
234 {
235 if (i == 0)
236 {
237 *(pIndices + dwIndex++) = dwTopLeft + m_wIndexStride + m_wIndexStride * m_wBlockSize;
238 *(pIndices + dwIndex++) = dwTopLeft;
239 *(pIndices + dwIndex++) = dwTopLeft + m_wIndexStride;
240
241 }
242 else if (i == m_nRealCell - 1)
243 {
244 *(pIndices + dwIndex++) = dwTopLeft + i * m_wIndexStride + m_wIndexStride * m_wBlockSize;
245 *(pIndices + dwIndex++) = dwTopLeft + i * m_wIndexStride;
246 *(pIndices + dwIndex++) = dwTopRight;
247 }
248 else
249 {
250 *(pIndices + dwIndex++) = dwTopLeft + (i + 1) * m_wIndexStride + m_wIndexStride * m_wBlockSize;
251 *(pIndices + dwIndex++) = dwTopLeft + i * m_wIndexStride + m_wIndexStride * m_wBlockSize;
252 *(pIndices + dwIndex++) = dwTopLeft + i * m_wIndexStride;
253
254 *(pIndices + dwIndex++) = dwTopLeft + i * m_wIndexStride;
255 *(pIndices + dwIndex++) = dwTopLeft + (i + 1) * m_wIndexStride;
256 *(pIndices + dwIndex++) = dwTopLeft + (i + 1) * m_wIndexStride + m_wIndexStride * m_wBlockSize;
257 }
258 }
259 }
260
261
262}
这样LOD的地形大概完成,下面是DEBUG版本贴图:
1025 x1025 的地形:
WireFrame截图:
129x129截图:
因为129X129的顶点数较少,所以开了水面反射与折射帧数还是比较高。