看了何咏的文章(http://www.graphixer.com.cn/ShowWorks.asp?Type=1&ID=28)后,再找到了最原始的那篇论文,也实现了一个,仅仅实现了动态地形优化部分,纹理等其它无关算法的内容没有加上去。使用OpenGL渲染,即以前做毕业设计时的框架,顺便也可以改进一下以前的游戏框架~
这里就不说算法了,读者可以找找何咏说到的那篇论文,个人觉得主要难点是理解消除裂缝的那部分
首先看效果图,没有优化的情况:
![](http://www.cppblog.com/images/cppblog_com/jedi-cy/image_no.jpg)
启用算法优化:
![](http://www.cppblog.com/images/cppblog_com/jedi-cy/image_y.jpg)
![](http://www.cppblog.com/images/cppblog_com/jedi-cy/image_y2.jpg)
不过之前毕业设计的游戏框架做得太烂,很多东西都太死,就不提供出来了,待以后有空好好改进。这里只贴LOD地形类的代码
.h文件:
1
#pragma once
2![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
3
#include "gmath.h"
4
#include "CY_Camera.h"
5![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
6![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
7
struct lodNode
8![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
9
Index2 Pos;//节点坐标(第x行y列;即对PointArray的索引)
10
int halfRange;//覆盖半径
11![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
12
float BoundRadius; //包围球半径
13
float DeltaH; //节点误差值
14![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
15
//四个子节点
16
lodNode* LeftUp;
17
lodNode* RightUp;
18
lodNode* LeftDown;
19
lodNode* RightDown;
20![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
21
//
22
lodNode()
23![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
24
LeftUp=0;
25
RightUp=0;
26
LeftDown=0;
27
RightDown=0;
28![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
29
halfRange=0;
30
BoundRadius=0;
31
}
32
~lodNode()
33![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
34
if(LeftUp)delete LeftUp;
35
if(RightUp)delete RightUp;
36
if(LeftDown)delete LeftDown;
37
if(RightDown)delete RightDown;
38
}
39
};
40
class LOD
41![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
42
float Xuint;//每个单位像素表示的 宽度
43
float Yuint;//每个单位像素表示的 高度
44
float Zuint;//每个单位alpha表示的深度
45
Vector3 *PointArray;//位置矩阵,x对应w,y对应h,z对应d;
46
bool *NeedSplitArray;
47
int Size;//地形图尺寸
48
int maxLevel;//树深度
49![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
50
51
lodNode *Root;
52
void CaculateRadius(lodNode *t);//处理该节点的包围球半径、子节点(初始化层次树中)
53
float CaculateDeltaH(lodNode *t);//处理该节点的误差值,返回子节点误差值
54![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
55
bool isDone;
56![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
57
Vector3 *GetPoint(int x,int y);//获取第y行,第x列
58
bool GetPointMark(int x,int y);
59
void SetPoint(int x,int y,float w,float h,float d);
60
void SetPointMark(int x,int y,bool ismark);
61![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
62
void RenderNode(lodNode *t,int &TrangleNum);//画该节点
63
void InitMark();//初始化是否细化的标记
64
bool IsNeedMark(lodNode *t);//节点的子节点是否可以标记细分
65
public:
66
LOD();
67
~LOD();
68
void InitPointArray(int size,BYTE *tgaData,float xuint,float yuint,float zuint);//1、初始化数组
69
void InitLOD(); //2、初始化层次树
70
void FreeData();
71![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
72
73
void RenderNoLOD();//无优化的渲染
74
void RenderLOD(CY_Camera *cam);
75![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
76
int trangleNum;//记录三角形数
77
};
.cpp文件:
1
#include "LOD.h"
2
#include "GLee.h"
3
#include "CY_Camera.h"
4
#include "Frustum.h"
5
#include "list"
6
using namespace std;
7![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
8
const float C_Distan=10.0f;
9
const float C_Noise=25.0f;
10![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
11
LOD::LOD()
12![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
13
Root=0;
14
PointArray=0;
15
NeedSplitArray=0;
16
isDone=false;
17
}
18
LOD::~LOD()
19![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
20
FreeData();
21
}
22
void LOD::FreeData()
23![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
24
if(isDone)
25
isDone=false;
26
if(PointArray)
27
delete []PointArray;
28
if(NeedSplitArray)
29
delete []NeedSplitArray;
30
NeedSplitArray=0;
31
PointArray=0;
32
if(Root)
33
delete Root;
34
Root=0;
35
}
36
//---------------------------------------------------------------------------------------
37
void LOD::InitPointArray(int size,BYTE *tgaData,float xuint,float yuint,float zuint)
38![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
39
Xuint=xuint;
40
Yuint=yuint;
41
Zuint=zuint;
42
Size=size;//地形图尺寸
43![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
44
PointArray=new Vector3[Size*Size];
45
for(int i=0;i<Size;++i)
46
for(int j=0;j<Size;++j)
47![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
48
SetPoint(i,j,Xuint*i,Yuint*j,Zuint*tgaData[3+4*(j*Size+i)]);
49
}
50
NeedSplitArray=new bool[Size*Size];
51
InitMark();
52
}
53
//----------------------------------------------------------------------------------------
54
void LOD::CaculateRadius(lodNode *t)//处理该节点的包围球半径、子节点(初始化层次树中)
55![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
56
int minX,maxX,minY,maxY;
57
float currentR,MaxR=0;
58
Vector3 *temp;
59
Vector3 *target=GetPoint(t->Pos.x,t->Pos.y);
60![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
61
//---------------计算包围球半径---
62
minX=t->Pos.x-t->halfRange;
63
maxX=t->Pos.x+t->halfRange;
64
minY=t->Pos.y-t->halfRange;
65
maxY=t->Pos.y+t->halfRange;
66
for(int i=minX;i<=maxX;++i)
67![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
68
for(int j=minY;j<=maxY;++j)
69![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
70
temp=GetPoint(i,j);
71
currentR=VectorLength(temp->x-target->x,temp->y-target->y,temp->z-target->z);
72
if(currentR>MaxR)
73
MaxR=currentR;
74
}
75
}
76
t->BoundRadius=MaxR;
77
//-------------------------------------
78
//---------------------------------计算子节点---------------
79
if(t->halfRange<=1)return;
80
lodNode *LU_sub,*LD_sub,*RU_sub,*RD_sub;
81
LU_sub=new lodNode();
82
LU_sub->halfRange=t->halfRange/2;
83
LU_sub->Pos.x=t->Pos.x-LU_sub->halfRange;
84
LU_sub->Pos.y=t->Pos.y-LU_sub->halfRange;
85![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
86
LD_sub=new lodNode();
87
LD_sub->halfRange=t->halfRange/2;
88
LD_sub->Pos.x=t->Pos.x-LD_sub->halfRange;
89
LD_sub->Pos.y=t->Pos.y+LD_sub->halfRange;
90![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
91
RU_sub=new lodNode();
92
RU_sub->halfRange=t->halfRange/2;
93
RU_sub->Pos.x=t->Pos.x+RU_sub->halfRange;
94
RU_sub->Pos.y=t->Pos.y-RU_sub->halfRange;
95![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
96
RD_sub=new lodNode();
97
RD_sub->halfRange=t->halfRange/2;
98
RD_sub->Pos.x=t->Pos.x+RD_sub->halfRange;
99
RD_sub->Pos.y=t->Pos.y+RD_sub->halfRange;
100
101
t->LeftUp=LU_sub;
102
t->LeftDown=LD_sub;
103
t->RightUp=RU_sub;
104
t->RightDown=RD_sub;
105![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
106
CaculateRadius(LU_sub);
107
CaculateRadius(LD_sub);
108
CaculateRadius(RU_sub);
109
CaculateRadius(RD_sub);
110
}
111
float LOD::CaculateDeltaH(lodNode *t)//处理该节点的误差值,子节点误差值
112![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
113
int halfRange=t->halfRange;
114
float nDelta1,nDelta2,nDelta3,nDelta4;//4个边上的误差值
115
float maxDelta;
116
Vector3 *node1,*node2,*node3,*node4;//点结点
117
Vector3 *edge1,*edge2,*edge3,*edge4;//边结点
118
Vector3 temp;//
119![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
120
node1=GetPoint(t->Pos.x-halfRange,t->Pos.y-halfRange);
121
node2=GetPoint(t->Pos.x+halfRange,t->Pos.y-halfRange);
122
node3=GetPoint(t->Pos.x+halfRange,t->Pos.y+halfRange);
123
node4=GetPoint(t->Pos.x-halfRange,t->Pos.y+halfRange);
124
edge1=GetPoint(t->Pos.x,t->Pos.y-halfRange);
125
edge2=GetPoint(t->Pos.x+halfRange,t->Pos.y);
126
edge3=GetPoint(t->Pos.x,t->Pos.y+halfRange);
127
edge4=GetPoint(t->Pos.x-halfRange,t->Pos.y);
128![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
129
temp=((*node1)+(*node2))*0.5f;
130
nDelta1=VectorLength(temp-(*edge1));
131
maxDelta=nDelta1;
132
temp=((*node3)+(*node2))*0.5f;
133
nDelta2=VectorLength(temp-(*edge2));
134
if(maxDelta<nDelta2)maxDelta=nDelta2;
135
temp=((*node3)+(*node4))*0.5f;
136
nDelta3=VectorLength(temp-(*edge3));
137
if(maxDelta<nDelta3)maxDelta=nDelta3;
138
temp=((*node1)+(*node4))*0.5f;
139
nDelta4=VectorLength(temp-(*edge4));
140
if(maxDelta<nDelta4)maxDelta=nDelta4;
141![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
142
if(t->halfRange<=1)
143![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
144
t->DeltaH=maxDelta;
145
return maxDelta;
146
}
147
else
148![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
149
float subMax=CaculateDeltaH(t->LeftUp);
150
if(subMax>maxDelta)
151
maxDelta=subMax;
152
subMax=CaculateDeltaH(t->LeftDown);
153
if(subMax>maxDelta)
154
maxDelta=subMax;
155
subMax=CaculateDeltaH(t->RightUp);
156
if(subMax>maxDelta)
157
maxDelta=subMax;
158
subMax=CaculateDeltaH(t->RightDown);
159
if(subMax>maxDelta)
160
maxDelta=subMax;
161![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
162
t->DeltaH=maxDelta;
163
return maxDelta;
164
}
165
}
166
void LOD::InitLOD()
167![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
168
Root=new lodNode();
169
Root->Pos.x=Size/2;
170
Root->Pos.y=Size/2;
171
Root->halfRange=Size/2;
172
CaculateRadius(Root);
173
CaculateDeltaH(Root);
174![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
175
maxLevel=0;
176
int i=Size-1;
177
while(i>1)
178![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
179
i/=2;
180
++maxLevel;
181
}
182
--maxLevel;
183
}
184
//--------------------------------------------------------------------------------------------
185
inline Vector3* LOD::GetPoint(int x,int y)
186![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
187
return &(PointArray[y*Size+x]);
188
}
189
inline void LOD::SetPoint(int x,int y,float w,float h,float d)
190![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
191
Vector3 *target=GetPoint(x,y);
192![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
193
target->x=w;
194
target->y=h;
195
target->z=d;
196
}
197
inline bool LOD::GetPointMark(int x,int y)
198![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
199
return NeedSplitArray[y*Size+x];
200
}
201
inline void LOD::SetPointMark(int x,int y,bool ismark)
202![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
203
NeedSplitArray[y*Size+x]=ismark;
204
}
205
//------------------------------------------------------------------------------------------
206
void LOD::RenderNoLOD()//无优化的渲染
207![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
208
if(!PointArray)return;
209
float co=0.004f/Zuint;
210![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
211
Vector3 *temp1,*temp2,*temp3,*temp4;
212
glDisable(GL_LIGHTING);
213
glBegin(GL_TRIANGLES);
214
for(int i=0;i<Size-1;++i)
215
for(int j=0;j<Size-1;++j)
216![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
217
temp1=GetPoint(i,j);
218
temp2=GetPoint(i+1,j+1);
219
temp3=GetPoint(i,j+1);
220
temp4=GetPoint(i+1,j);
221
glColor3f(1,temp1->z*co,0);
222
glVertex3fv(temp1->V_Array);
223
glColor3f(1,temp3->z*co,0);
224
glVertex3fv(temp3->V_Array);
225
glColor3f(1,temp2->z*co,0);
226
glVertex3fv(temp2->V_Array);
227![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
228
glColor3f(1,temp1->z*co,0);
229
glVertex3fv(temp1->V_Array);
230
glColor3f(1,temp2->z*co,0);
231
glVertex3fv(temp2->V_Array);
232
glColor3f(1,temp4->z*co,0);
233
glVertex3fv(temp4->V_Array);
234
}
235
glEnd();
236
}
237
inline bool LOD::IsNeedMark(lodNode *t)//节点的子节点是否可以标记细分
238![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
239
int uy,dy,lx,rx;
240
int range=t->halfRange*2;
241
uy=t->Pos.y-range;
242
dy=t->Pos.y+range;
243
lx=t->Pos.x-range;
244
rx=t->Pos.x+range;
245
if(uy>=0 && !GetPointMark(t->Pos.x,uy))
246
return false;
247
if(dy<Size && !GetPointMark(t->Pos.x,dy))
248
return false;
249
if(lx>=0 && !GetPointMark(lx,t->Pos.y))
250
return false;
251
if(rx<Size && !GetPointMark(rx,t->Pos.y))
252
return false;
253
return true;
254
}
255
inline void LOD::RenderNode(lodNode *t,int &TrangleNum)//画该节点
256![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
257
if(!t)return;
258
TrangleNum+=4;
259
float co=0.004f/Zuint;
260![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
261
glDisable(GL_LIGHTING);
262
Vector3 *temp;
263![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
264
int uy,dy,lx,rx;
265
int range=t->halfRange*2;
266
uy=t->Pos.y-range;
267
dy=t->Pos.y+range;
268
lx=t->Pos.x-range;
269
rx=t->Pos.x+range;
270
int itemp=0;
271![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
272
glBegin(GL_TRIANGLE_FAN);
273
temp=GetPoint(t->Pos.x,t->Pos.y);
274
glColor3f(1,temp->z*co,0);
275![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
glVertex3fv(temp->V_Array);/**////-----------------中点
276![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
277
temp=GetPoint(t->Pos.x-t->halfRange,t->Pos.y-t->halfRange);
278
glColor3f(1,temp->z*co,0);
279![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
glVertex3fv(temp->V_Array);/**////-----------------1
280![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
281
if(lx<0 || GetPointMark(lx,t->Pos.y))
282![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
283
temp=GetPoint(t->Pos.x-t->halfRange,t->Pos.y);
284
glColor3f(1,temp->z*co,0);
285![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
glVertex3fv(temp->V_Array);/**////------------2
286
++TrangleNum;
287
++itemp;
288
}
289![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
290
temp=GetPoint(t->Pos.x-t->halfRange,t->Pos.y+t->halfRange);
291
glColor3f(1,temp->z*co,0);
292![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
glVertex3fv(temp->V_Array);/**////--------------3
293![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
294
if(dy>=Size || GetPointMark(t->Pos.x,dy))
295![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
296
temp=GetPoint(t->Pos.x,t->Pos.y+t->halfRange);
297
glColor3f(1,temp->z*co,0);
298
glVertex3fv(temp->V_Array);//-------------4
299
++TrangleNum;
300
++itemp;
301
}
302![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
303
temp=GetPoint(t->Pos.x+t->halfRange,t->Pos.y+t->halfRange);
304
glColor3f(1,temp->z*co,0);
305
glVertex3fv(temp->V_Array);//------------------5
306![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
307
if(rx>=Size || GetPointMark(rx,t->Pos.y))
308![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
309
temp=GetPoint(t->Pos.x+t->halfRange,t->Pos.y);
310
glColor3f(1,temp->z*co,0);
311![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
glVertex3fv(temp->V_Array);/**////------------6
312
++TrangleNum;
313
++itemp;
314
}
315![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
316
temp=GetPoint(t->Pos.x+t->halfRange,t->Pos.y-t->halfRange);
317
glColor3f(1,temp->z*co,0);
318
glVertex3fv(temp->V_Array);//-----------------7
319![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
320
if(uy<0 || GetPointMark(t->Pos.x,uy))
321![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
322
temp=GetPoint(t->Pos.x,t->Pos.y-t->halfRange);
323
glColor3f(1,temp->z*co,0);
324![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
glVertex3fv(temp->V_Array);/**////------------8
325
++TrangleNum;
326
++itemp;
327
}
328
temp=GetPoint(t->Pos.x-t->halfRange,t->Pos.y-t->halfRange);
329
glColor3f(1,temp->z*co,0);
330![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
glVertex3fv(temp->V_Array);/**////-----------------1
331![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
332
glEnd();
333
}
334
void LOD::InitMark()
335![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
336
int n=Size*Size;
337
for(int i=0;i<n;++i)
338
NeedSplitArray[i]=false;
339
}
340
void LOD::RenderLOD(CY_Camera *cam)
341![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
342
if(!PointArray || !Root)
343
return;
344![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
345
float modelview[16],projection[16];
346
glGetFloatv(GL_PROJECTION_MATRIX, projection);
347
glGetFloatv(GL_MODELVIEW_MATRIX, modelview);
348
glPushMatrix();
349
glLoadMatrixf(projection);
350
glMultMatrixf(modelview);
351
glGetFloatv(GL_MODELVIEW_MATRIX, modelview);//利用OpenGL计算乘积
352
glPopMatrix();
353
CY_Frustum Frustum;
354
Frustum.Init(modelview,false);
355
//-------------------------------------------------------
356
list<lodNode*>Temp1,Temp2;
357
list<lodNode*> *Current=&Temp1,*Next=&Temp2,*swapTemp;
358
list<lodNode*>::iterator i;
359![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
360
int level=0;
361
int distance2;//距离
362
Vector3 *point;
363
lodNode* temp;
364![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
365
trangleNum=0;
366![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
367
Current->push_back(Root);
368
while(Current->size()>0)
369![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
370
for(i=Current->begin();i!=Current->end();i++)
371![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
372
point=GetPoint((*i)->Pos.x,(*i)->Pos.y);
373
if(!Frustum.SphereInFrustum(*point,(*i)->BoundRadius))
374![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
375
continue;
376
}
377
else if(level==maxLevel)
378![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
379
RenderNode((*i),trangleNum);
380
}
381
else
382![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
383
distance2=VectorLength(cam->GetPosition()-(*point));
384
SetPointMark((*i)->Pos.x,(*i)->Pos.y,true);
385
if(distance2<C_Distan*C_Noise*(*i)->DeltaH && IsNeedMark(*i))
386![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
387
temp=(*i)->LeftUp;
388
SetPointMark(temp->Pos.x,temp->Pos.y,true);
389
Next->push_back(temp);
390![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
391
temp=(*i)->LeftDown;
392
SetPointMark(temp->Pos.x,temp->Pos.y,true);
393
Next->push_back(temp);
394![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
395
temp=(*i)->RightUp;
396
SetPointMark(temp->Pos.x,temp->Pos.y,true);
397
Next->push_back(temp);
398![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
399
temp=(*i)->RightDown;
400
SetPointMark(temp->Pos.x,temp->Pos.y,true);
401
Next->push_back(temp);
402
}
403
else
404![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
405
RenderNode((*i),trangleNum);
406![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
407
temp=(*i)->LeftUp;
408
SetPointMark(temp->Pos.x,temp->Pos.y,false);
409
temp=(*i)->LeftDown;
410
SetPointMark(temp->Pos.x,temp->Pos.y,false);
411
temp=(*i)->RightUp;
412
SetPointMark(temp->Pos.x,temp->Pos.y,false);
413
temp=(*i)->RightDown;
414
SetPointMark(temp->Pos.x,temp->Pos.y,false);
415
}
416
}
417
}
418
swapTemp=Current;
419
Current=Next;
420
Next=swapTemp;
421
Next->clear();
422
++level;
423
}
424
}
posted on 2009-06-30 12:53
陈昱(CY) 阅读(3077)
评论(10) 编辑 收藏 引用 所属分类:
游戏编程 、
图形学