📄 lod.cpp
字号:
glEnd();
}
void CLOD::DrawNode(int cx, int cy, int d)
{
float tcx = float(cx)/m_w;
float tcy = float(cy)/m_h;
float tcd = float(d)/m_h;
int d2 = d*2;
#ifdef _COUNT_TRIAN_COUNT
m_trian_count += 4;
#endif
glBegin(GL_TRIANGLE_FAN);
//Center
glColor3f(1.0,0,0);
if(d == 1)
glColor4f(0,0,1.0,0);
SetTexCoord(tcx,tcy);
glVertex3f(cx,cy,m_pTerrain->GetValue(cx,cy));
glColor3f(1.0,1,1);
//Left_up
SetTexCoord(tcx - tcd, tcy + tcd);
glVertex3f(cx - d,cy + d,m_pTerrain->GetValue(cx - d,cy + d));
//Left
//nx = cx - d2;ny=cy;
if(m_neighbor[NV_LEFT] == VS_ACTIVE)//nx < 0 || m_active.GetValue(nx,ny) != VS_DISABLE)
{
#ifdef _COUNT_TRIAN_COUNT
m_trian_count++;
#endif
SetTexCoord(tcx - tcd, tcy);
glVertex3f(cx - d,cy,m_pTerrain->GetValue(cx - d,cy));
}
//Left down
SetTexCoord(tcx - tcd, tcy - tcd);
glVertex3f(cx - d,cy - d,m_pTerrain->GetValue(cx - d,cy - d));
//down
//nx = cx; ny = cy - d2;
if(m_neighbor[NV_DOWN] == VS_ACTIVE)//ny < 0 || m_active.GetValue(nx,ny) != VS_DISABLE)
{
#ifdef _COUNT_TRIAN_COUNT
m_trian_count++;
#endif
SetTexCoord(tcx , tcy - tcd);
glVertex3f(cx,cy - d,m_pTerrain->GetValue(cx,cy - d));
}
//right down
SetTexCoord(tcx + tcd, tcy - tcd);
glVertex3f(cx + d,cy - d,m_pTerrain->GetValue(cx + d,cy - d));
//right
//nx = cx + d2; ny = cy;
if(m_neighbor[NV_RIGHT] == VS_ACTIVE)//ny >= m_w || m_active.GetValue(nx,ny) != VS_DISABLE)
{
#ifdef _COUNT_TRIAN_COUNT
m_trian_count++;
#endif
SetTexCoord(tcx + tcd, tcy);
glVertex3f(cx + d,cy,m_pTerrain->GetValue(cx + d,cy));
}
//Right up
SetTexCoord(tcx + tcd, tcy + tcd);
glVertex3f(cx + d,cy + d,m_pTerrain->GetValue(cx + d,cy + d));
//up
//nx = cx; ny = cy + d2;
if(m_neighbor[NV_UP] == VS_ACTIVE)//ny >= m_h || m_active.GetValue(nx,ny) != VS_DISABLE)
{
#ifdef _COUNT_TRIAN_COUNT
m_trian_count++;
#endif
SetTexCoord(tcx , tcy + tcd);
glVertex3f(cx,cy + d,m_pTerrain->GetValue(cx,cy + d));
}
//Left_up
SetTexCoord(tcx - tcd, tcy + tcd);
glVertex3f(cx - d,cy + d,m_pTerrain->GetValue(cx - d,cy + d));
glEnd();
}
void CLOD::RenderLOD2()
{
#ifdef _COUNT_TRIAN_COUNT
m_trian_count = 0;
#endif
vector<QNODE> v1;
vector<QNODE> v2;
vector<QNODE>* cur_Queue;
vector<QNODE>* next_Queue,*temp_v;
cur_Queue =&v1;next_Queue = &v2;
int level = 0,i=0;
int d = m_delta[0];
int d2;
int nx,ny;
int cx = (m_w - 1)/2.;
int cy = (m_h - 1)/2.;
QNODE node ={cx,cy};
cur_Queue->push_back(node);
while( d > 0)
{
d2 = d/2;
int vlen = cur_Queue->size();
for(i = 0 ; i < vlen;i++)
{
node = (*cur_Queue)[i];
cx = node._x;
cy = node._y;
CheckNeighbor(cx,cy,d);
if(m_cull->IsRectCulled(cx,cy,d*2))
{
DividNode(cx,cy,d);
continue;
}
if( d == 1)
{
DrawNode(cx,cy,1);
continue;
}
m_subnode[0] = m_subnode[1] = m_subnode[2] = m_subnode[3] = FALSE;
//Left up
nx = cx - d2;ny=cy + d2;
if(CanActive(nx,ny,d))
{
if(m_neighbor[NV_LEFT] && m_neighbor[NV_UP])
{
m_subnode[SN_LU]=TRUE;
m_active.GetValue(nx,ny) = VS_ACTIVE;
node._x = nx;node._y=ny;
next_Queue->push_back(node);
}
else
m_active.GetValue(nx,ny) = VS_DISABLE;
}
else
m_active.GetValue(nx,ny) = VS_DISABLE;
//Leftdown
nx = cx - d2;ny=cy - d2;
if(CanActive(nx,ny,d))
{
if(m_neighbor[NV_LEFT] && m_neighbor[NV_DOWN])
{
m_subnode[SN_LD]=TRUE;
m_active.GetValue(nx,ny) = VS_ACTIVE;
node._x = nx;node._y=ny;
next_Queue->push_back(node);
}
else
m_active.GetValue(nx,ny) = VS_DISABLE;
}
else
m_active.GetValue(nx,ny) = VS_DISABLE;
//right dwon
nx = cx + d2;ny=cy - d2;
if(CanActive(nx,ny,d))
{
if(m_neighbor[NV_RIGHT] && m_neighbor[NV_DOWN])
{
m_subnode[SN_RD]=TRUE;
m_active.GetValue(nx,ny) = VS_ACTIVE;
node._x = nx;node._y=ny;
next_Queue->push_back(node);
}
else
m_active.GetValue(nx,ny) = VS_DISABLE;
}
else
m_active.GetValue(nx,ny) = VS_DISABLE;
//right up
nx = cx + d2;ny=cy + d2;
if(CanActive(nx,ny,d))
{
if(m_neighbor[NV_RIGHT] && m_neighbor[NV_UP])
{
m_subnode[SN_RU]=TRUE;
m_active.GetValue(nx,ny) = VS_ACTIVE;
node._x = nx;node._y=ny;
next_Queue->push_back(node);
}
else
m_active.GetValue(nx,ny) = VS_DISABLE;
}
else
m_active.GetValue(nx,ny) = VS_DISABLE;
if(m_subnode[0]==FALSE && m_subnode[1]==FALSE&&
m_subnode[2]==FALSE && m_subnode[3]==FALSE)
{
DrawNode(cx,cy,d);
continue;
}
else if(m_subnode[0]==TRUE && m_subnode[1]==TRUE&&
m_subnode[2]==TRUE && m_subnode[3]==TRUE)
{
continue;
}
else
{
DrawHalfNode(cx,cy,d);
}
}//end for
cur_Queue->clear();
temp_v = cur_Queue;
cur_Queue = next_Queue;
next_Queue = temp_v;
level ++ ;
d = m_delta[level];
}//end while
}
void CLOD::DrawHalfNode(int cx, int cy, int d)
{
float tcx = float(cx)/m_w;
float tcy = float(cy)/m_h;
float tcd = float(d)/m_h;
int d2 = d*2;
//Left up
if(m_subnode[SN_LU]==FALSE)
{
glBegin(GL_TRIANGLE_FAN);
//Center
glColor3f(1.0,0,0);
SetTexCoord(tcx,tcy);
glVertex3f(cx,cy,m_pTerrain->GetValue(cx,cy));
glColor3f(1.0,1.0,1.0);
//up
if(m_neighbor[NV_UP] == VS_ACTIVE)
{
SetTexCoord(tcx,tcy + tcd);
glVertex3f(cx,cy + d ,m_pTerrain->GetValue(cx,cy + d));
#ifdef _COUNT_TRIAN_COUNT
m_trian_count ++;
#endif
}
//Left up
SetTexCoord(tcx - tcd,tcy + tcd );
glVertex3f(cx - d,cy + d ,m_pTerrain->GetValue(cx - d,cy + d));
//Left
if(m_neighbor[NV_LEFT] == VS_ACTIVE)
{
SetTexCoord(tcx - tcd,tcy);
glVertex3f(cx - d,cy ,m_pTerrain->GetValue(cx - d,cy));
}
else
{
SetTexCoord(tcx - tcd,tcy - tcd);
glVertex3f(cx - d,cy - d,m_pTerrain->GetValue(cx - d,cy - d));
}
#ifdef _COUNT_TRIAN_COUNT
m_trian_count ++;
#endif
glEnd();
}
//Left DOWN
if(m_subnode[SN_LD]==FALSE)
{
glBegin(GL_TRIANGLE_FAN);
//Center
glColor3f(1.0,0,0);
SetTexCoord(tcx,tcy);
glVertex3f(cx,cy,m_pTerrain->GetValue(cx,cy));
glColor3f(1.0,1.0,1.0);
//left
if(m_neighbor[NV_LEFT]==VS_ACTIVE)
{
SetTexCoord(tcx - tcd,tcy);
glVertex3f(cx - d,cy ,m_pTerrain->GetValue(cx - d,cy));
#ifdef _COUNT_TRIAN_COUNT
m_trian_count ++;
#endif
}
//left down
SetTexCoord(tcx - tcd,tcy - tcd );
glVertex3f(cx - d,cy - d ,m_pTerrain->GetValue(cx - d,cy - d));
//dwon
if(m_neighbor[NV_DOWN]==VS_ACTIVE)
{
SetTexCoord(tcx,tcy - tcd);
glVertex3f(cx,cy - d ,m_pTerrain->GetValue(cx,cy - d));
}
else
{
SetTexCoord(tcx + tcd,tcy - tcd);
glVertex3f(cx + d,cy - d,m_pTerrain->GetValue(cx + d,cy - d));
}
#ifdef _COUNT_TRIAN_COUNT
m_trian_count ++;
#endif
glEnd();
}
//RIGHT Down
if(m_subnode[SN_RD]==FALSE)
{
glBegin(GL_TRIANGLE_FAN);
//Center
glColor3f(1.0,0,0);
SetTexCoord(tcx,tcy);
glVertex3f(cx,cy,m_pTerrain->GetValue(cx,cy));
glColor3f(1.0,1.0,1.0);
//down
if(m_neighbor[NV_DOWN]==VS_ACTIVE)
{
SetTexCoord(tcx,tcy - tcd);
glVertex3f(cx,cy - d ,m_pTerrain->GetValue(cx,cy - d));
#ifdef _COUNT_TRIAN_COUNT
m_trian_count ++;
#endif
}
//right down
SetTexCoord(tcx + tcd,tcy - tcd );
glVertex3f(cx + d,cy - d ,m_pTerrain->GetValue(cx + d,cy - d));
//right
if(m_neighbor[NV_RIGHT]==VS_ACTIVE)
{
SetTexCoord(tcx + tcd,tcy);
glVertex3f(cx + d,cy ,m_pTerrain->GetValue(cx + d,cy));
}
else
{
SetTexCoord(tcx + tcd,tcy + tcd);
glVertex3f(cx + d,cy + d,m_pTerrain->GetValue(cx + d,cy + d));
}
#ifdef _COUNT_TRIAN_COUNT
m_trian_count ++;
#endif
glEnd();
}
//Right up
if(m_subnode[SN_RU]==FALSE)
{
glBegin(GL_TRIANGLE_FAN);
//Center
glColor3f(1.0,0,0);
SetTexCoord(tcx,tcy);
glVertex3f(cx,cy,m_pTerrain->GetValue(cx,cy));
glColor3f(1.0,1.0,1.0);
//rihgt
if(m_neighbor[NV_RIGHT]==VS_ACTIVE)
{
SetTexCoord(tcx + tcd,tcy);
glVertex3f(cx + d,cy ,m_pTerrain->GetValue(cx + d,cy));
#ifdef _COUNT_TRIAN_COUNT
m_trian_count ++;
#endif
}
//right up
SetTexCoord(tcx + tcd,tcy + tcd );
glVertex3f(cx + d,cy + d ,m_pTerrain->GetValue(cx + d,cy + d));
//Up
if(m_neighbor[NV_UP]==VS_ACTIVE)
{
SetTexCoord(tcx ,tcy + tcd);
glVertex3f(cx ,cy + d ,m_pTerrain->GetValue(cx,cy + d));
}
else
{
SetTexCoord(tcx - tcd,tcy + tcd);
glVertex3f(cx - d,cy + d,m_pTerrain->GetValue(cx - d,cy + d));
}
#ifdef _COUNT_TRIAN_COUNT
m_trian_count ++;
#endif
glEnd();
}
}
void CLOD::SetLodMethod(int method)
{
m_lodmethod = method;
}
int CLOD::GetLodMethod()
{
return m_lodmethod;
}
void CLOD::CullNode(int cx, int cy, int d)
{
int sx = cx - d;
int ex = cx + d;
int sy = cy - d;
int ey = cy + d;
m_active.SetValue(cx,cy, VS_ACTIVE);
d /= 2;
while(d>1)
{
for( int x = sx + d; x < ex ;x += 2*d)
{
m_active.GetValue(x,d)= VS_ACTIVE;
m_active.GetValue(x,ey - d) = VS_ACTIVE;
}
for( int y = sy + d; y < ey ;y += 2*d)
{
m_active.GetValue(d,y)=VS_ACTIVE;
m_active.GetValue(ex - d,y)=VS_ACTIVE;
}
d/=2;
}
}
void CLOD::EnableGridRender(BOOL eGr)
{
m_is_Grid = eGr;
}
void CLOD::CheckNeighbor(int cx, int cy, int d)
{
int nx,ny;
int d2= 2*d;
m_neighbor[NV_LEFT] = VS_ACTIVE;
m_neighbor[NV_UP] = VS_ACTIVE;
m_neighbor[NV_DOWN] = VS_ACTIVE;
m_neighbor[NV_RIGHT] = VS_ACTIVE;
//Test the four neighbor if they are all enabled/stoped
nx = cx;ny = cy - d2;
if(ny >0)
{
if(m_active.GetValue(nx,ny) == VS_DISABLE)
m_neighbor[NV_DOWN] = VS_DISABLE;
}
nx = cx;ny = cy + d2;
if(ny<m_h)
{
if(m_active.GetValue(nx,ny) == VS_DISABLE)
m_neighbor[NV_UP] = VS_DISABLE;
}
nx = cx + d2;ny = cy;
if(nx <m_w )
{
if(m_active.GetValue(nx,ny) == VS_DISABLE)
m_neighbor[NV_RIGHT] = VS_DISABLE;
}
nx = cx - d2;ny = cy;
if(nx > 0 )
{
if(m_active.GetValue(nx,ny) == VS_DISABLE)
m_neighbor[NV_LEFT] = VS_DISABLE;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -