📄 scene.cpp
字号:
//Version 1.1c
//Code by Phil.Z
//Date 2007-12-28
#include "stdafx.h"
#include "Scene.h"
#include "Figure.h"
#include <cmath>
const double PI = 3.1415926;
Scene::Scene(CWnd *pWnd)
:m_pWnd(pWnd),
m_fXRot(0),m_fYRot(0),
m_bLight(false),
m_pFigure(0),
m_pCurFigure(0),
m_fWalkDistance(0.5f),
m_fXPos(0.0f),
m_fZPos(0.0f)
{
m_afBkColor[0] = 0.0f;
m_afBkColor[1] = 0.0f;
m_afBkColor[2] = 0.0f;
m_afBkColor[3] = 0.0f;
}
Scene::~Scene()
{
while (m_pFigure)
{
FigureNode *p = m_pFigure;
m_pFigure = m_pFigure->next;
delete p->figure;
delete p;
}
}
void Scene::SetParam(float *initList)
{
m_fXRot = initList[0];
m_fYRot = initList[1];
m_bLight = initList[2];
for (int i = 0;i < 4;i++)
m_afBkColor[i] = initList[i + 3];
for (i = 0;i < 8;i++)
m_afLightColor[i] = initList[i + 7];
UpdateLightState();
}
void Scene::InitGLScene()
{
glClearColor(m_afBkColor[0],m_afBkColor[1],m_afBkColor[2],m_afBkColor[3]);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_POLYGON_SMOOTH);
UpdateLightState();
}
void Scene::ResizeGLScene(float width,float height)
{
float aspect;
if (height == 0)
aspect = 1;
else
aspect = width / height;
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,aspect,0.1,400);
glMatrixMode(GL_MODELVIEW);
}
void Scene::DrawGLScene()
{
//初始化场景为当前的视角和位置
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glTranslatef(0,0,-30);
glTranslatef(m_fXPos,0,m_fZPos);
glRotatef(m_fXRot,1,0,0);
glRotatef(m_fYRot,0,1,0);
if (m_bLight)
glLightfv(GL_LIGHT0,GL_POSITION,m_afLightPos);
//绘制链表当中的各个图形
FigureNode *p = m_pFigure;
while (p)
{
p->figure->Display();
p = p->next;
}
glFinish();
}
bool Scene::NewFigure(int FigureClass,float *initList)
{
FigureNode *p = new FigureNode;
if (!p)
return false;
switch (FigureClass)
{
case F2D_POINT:
p->figure = new Point(initList);
break;
case F2D_LINE:
p->figure = new Line(initList);
break;
case F2D_RECT:
p->figure = new Rect(initList);
break;
case F2D_CIRCLE:
p->figure = new Circle(initList);
break;
case F3D_CUBE:
p->figure = new Cube(initList);
break;
case F3D_SPHERE:
p->figure = new Sphere(initList);
break;
case F3D_CYLINDER:
p->figure = new Cylinder(initList);
break;
case F3D_DISK:
p->figure = new Disk(initList);
break;
}
if (!p->figure)
return false;
p->prior = NULL;
if (!m_pFigure) //新节点插入到链表头部
{
p->next = 0;
m_pFigure = p;
}
else
{
p->next = m_pFigure;
m_pFigure->prior = p;
m_pFigure = p;
}
return true;
}
bool Scene::DeleteSelFigure()
{
if (!IsCurSelected())
return false;
if (m_pCurFigure == m_pFigure)
{
m_pFigure = m_pFigure->next;
if (m_pFigure)
m_pFigure->prior = NULL;
}
else
{
if (m_pCurFigure->prior)
m_pCurFigure->prior->next = m_pCurFigure->next;
if (m_pCurFigure->next)
m_pCurFigure->next->prior = m_pCurFigure->prior;
}
delete m_pCurFigure->figure;
delete m_pCurFigure;
m_pCurFigure = 0;
m_pWnd->Invalidate();
return true;
}
void Scene::SetSceneLight(bool bLight)
{
m_bLight = bLight;
UpdateLightState();
}
void Scene::SetSceneLight(int LightParam,float * value)
{
int i;
switch (LightParam)
{
case LP_AMBIENT:
for (i = 0;i < 4;i++)
m_afLightColor[i] = value[i];
break;
case LP_DIFFUSE:
for (i = 0;i < 4;i++)
m_afLightColor[i + 4] = value[i];
break;
case LP_POSITION:
for (i = 0;i < 4;i++)
m_afLightPos[i] = value[i];
break;
}
UpdateLightState();
}
void Scene::SetSceneBkColor(float *value)
{
for (int i = 0;i < 4;i++)
m_afBkColor[i] = value[i];
glClearColor(m_afBkColor[0],m_afBkColor[1],m_afBkColor[2],m_afBkColor[3]);
m_pWnd->Invalidate();
}
void Scene::SetSceneRot(int RotCrood,float *value)
{
switch (RotCrood)
{
case RC_XROT:
m_fXRot = *value;
break;
case RC_YROT:
m_fYRot = *value;
break;
case RC_XANDY:
m_fXRot = value[0];
m_fYRot = value[1];
break;
}
m_pWnd->Invalidate();
}
void Scene::UpdateLightState()
{
if (m_bLight)
{
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,m_afLightColor);
glLightfv(GL_LIGHT0,GL_DIFFUSE,&m_afLightColor[4]);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
}
else
{
glDisable(GL_LIGHT0);
glDisable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);
}
}
void Scene::SetDistance(float StepDistance)
{
//限制步长在0.5到5之间
m_fWalkDistance = StepDistance;
if (m_fWalkDistance < 0.05f)
m_fWalkDistance = 0.05f;
if (m_fWalkDistance > 5.0f)
m_fWalkDistance = 5.0f;
}
float Scene::GetDistance() const
{
return m_fWalkDistance;
}
void Scene::Move(unsigned int Direction)
{
//算法是将移动的距离分解到X/Z两个方向上
switch (Direction)
{
case MV_FORWARD:
m_fXPos += (float)sin(m_fYRot * PI / 180.0) * m_fWalkDistance;
m_fZPos += (float)cos(m_fYRot * PI / 180.0) * m_fWalkDistance;
break;
case MV_BACK:
m_fXPos -= (float)sin(m_fYRot * PI / 180.0) * m_fWalkDistance;
m_fZPos -= (float)cos(m_fYRot * PI / 180.0) * m_fWalkDistance;
break;
case MV_LEFT:
m_fXPos += (float)cos(m_fYRot * PI / 180) * m_fWalkDistance;
m_fZPos -= (float)sin(m_fYRot * PI / 180) * m_fWalkDistance;
break;
case MV_RIGHT:
m_fXPos -= (float)cos(m_fYRot * PI / 180) * m_fWalkDistance;
m_fZPos += (float)sin(m_fYRot * PI / 180) * m_fWalkDistance;
break;
default:
return;
}
m_pWnd->Invalidate();
}
void Scene::SetPick(int xMousePos,int yMousePos)
{
GLint viewport[4];
const int BUFFERSIZE = 128;
GLuint selbuffer[BUFFERSIZE];
glGetIntegerv(GL_VIEWPORT,viewport);
glSelectBuffer(BUFFERSIZE,selbuffer);
glRenderMode(GL_SELECT);
glInitNames();
glPushName(0);
float aspect = 1;
if (viewport[2])
aspect = (float)viewport[2] / (float)viewport[3];
if (m_pCurFigure)
m_pCurFigure = 0;
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPickMatrix((GLdouble)xMousePos,(GLdouble)viewport[3] - yMousePos,1,1,viewport);
gluPerspective(45,aspect,1,400);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0,0,-30);
glTranslatef(m_fXPos,0,m_fZPos);
glRotatef(m_fXRot,1,0,0);
glRotatef(m_fYRot,0,1,0);
FigureNode *p = m_pFigure;
int nName = 1;
while (p)
{
glLoadName(nName);
p->figure->Display();
p->figure->SetName(nName);
p->figure->SetCurStatue(false);
p = p->next;
nName++;
}
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glFinish();
GLuint nSel = glRenderMode(GL_RENDER);
p = m_pFigure;
if (nSel)
{
while (p)
{
if ((p->figure->GetName()) == selbuffer[3])
{
p->figure->SetCurStatue(true);
m_pCurFigure = p;
}
p = p->next;
}
}
m_pWnd->Invalidate();
}
bool Scene::IsCurSelected()
{
return m_pCurFigure;
}
void Scene::MoveCurFigure(int Coord,int OP,int value)
{
if (!IsCurSelected())
return;
float FigurePos[3];
m_pCurFigure->figure->GetPos(FigurePos);
if (OP == OP_MINUS)
value = -value;
switch (Coord)
{
case FP_XPOS:
FigurePos[0] += value;
break;
case FP_YPOS:
FigurePos[1] += value;
break;
case FP_ZPOS:
FigurePos[2] += value;
break;
}
m_pCurFigure->figure->SetPos(FigurePos);
m_pWnd->Invalidate();
}
void Scene::RotateCurFigure(int Coord,int OP,int value)
{
if (!IsCurSelected())
return;
float FigureRot[3];
m_pCurFigure->figure->GetRot(FigureRot);
if (OP == OP_MINUS)
value = -value;
switch (Coord)
{
case FR_XROT:
FigureRot[0] += value;
break;
case FR_YROT:
FigureRot[1] += value;
break;
case FR_ZROT:
FigureRot[2] += value;
break;
}
m_pCurFigure->figure->SetRot(FigureRot);
m_pWnd->Invalidate();
}
void Scene::SetInsertMode()
{
m_fXPos = 0;
m_fZPos = 0;
m_fXRot = 0;
m_fYRot = 0;
m_pWnd->Invalidate();
}
void Scene::WinPosToGLPos(float GLPos[],CPoint WinPos)
{
const double PI = 3.1415926;
int viewport[4];
glGetIntegerv(GL_VIEWPORT,viewport);
int xPos = WinPos.x;
int yPos = viewport[3] - WinPos.y;
float yRange = (double)30 * (double)tan((double)(22.5 / 180.0 * PI));
float xRange = yRange * ((double)viewport[2] / (double)viewport[3]);
GLPos[0] = 2 * (double) xPos * xRange / (double) viewport[2] - xRange;
GLPos[1] = 2 * (double) yPos * yRange / (double) viewport[3] - yRange;
GLPos[2] = 0;
/*GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
GLfloat winX, winY, winZ;
GLdouble posX, posY, posZ;
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
winX =(float) WinPos.x;
winY =(float) WinPos.y;
winX = (float)WinPos.x;
winY = viewport[3] - (float)WinPos.y;
glReadPixels((int)winX, (int)winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);
gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
GLPos[0] = posX;
GLPos[1] = posY;
GLPos[2] = posZ;*/
}
void Scene::Display()
{
FigureNode *p = m_pFigure;
while (p)
{
p->figure->Display();
p = p->next;
}
glFinish();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -