#define RAD (3.14159265358979 / 180)
void COpenGLShowMovieView::OnDraw(CDC* pDC)
{
COpenGLShowMovieDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
//指定在后台缓存中绘制
glDrawBuffer(GL_BACK);
//初始化变换矩阵
glLoadIdentity();
glClearColor(0.0,0.0,0.0,0.0f);//设置背景颜色为黑色
glClear(GL_COLOR_BUFFER_BIT );//清除背景颜色
GetEye(r, hDegree, vDegree, ex, ey, ez);
gluLookAt(ex, ey, ez, 0, 0, 0, 0, r, 0);
glColor3f(1.0f, 1.0f, 0.0f); // 设置绘图颜色
auxWireTeapot(3.5);//绘制茶壶网格
char buf[40];
sprintf(buf, "r = %.4g, hDegree = %d, vDegree = %d", r, hDegree, vDegree);
//交换前后缓存
SwapBuffers(wglGetCurrentDC());
//绘制前景
glDrawBuffer(GL_FRONT);
pDC->TextOut(10, 10, "通过使用上、下、左、右箭头和加减键,调整观察位置");
pDC->TextOut(10, 30, buf);
}
int COpenGLShowMovieView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
m_pDC = new CClientDC(this);
ASSERT(m_pDC != NULL);
// 初始化像素格式
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // 结构大小
1, // 版本
PFD_DRAW_TO_WINDOW | // 支持Windows
PFD_SUPPORT_OPENGL | // 支持 OpenGL
PFD_DOUBLEBUFFER, // 双缓冲
PFD_TYPE_RGBA, // 像素类型
24, // 24-bit颜色位数
0, 0, 0, 0, 0, 0, // 忽略R、G、B位数
0, // α值位数
0, // α值偏移
0, // 光栅缓存位数
0, 0, 0, 0, // 光栅各分量缓存位数
32, // 深度缓存位数
0, // 图案缓存位数
0, // 辅助缓存位数
PFD_MAIN_PLANE, // 层类型
0, // 保留
0, 0, 0 // 忽略掩码
};
// 选择像素格式
int pixelformat;
if ( (pixelformat = ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd)) == 0 )
{
AfxMessageBox("选择像素格式失败!");
return -1;
}
// 设置像素格式
if (SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd) == FALSE)
{
AfxMessageBox("设置像素格式失败!");
return -1;
}
// 创建绘制情景对象
m_hglrc = wglCreateContext(m_pDC->GetSafeHdc());
return 0;
}
void COpenGLShowMovieView::OnDestroy()
{
CView::OnDestroy();
// TODO: Add your message handler code here
::wglMakeCurrent(NULL, NULL);
// 删除当前绘图情景对象并释放所占内存
if (m_hglrc)
{
::wglDeleteContext(m_hglrc);
m_hglrc = NULL;
}
if (m_pDC)
delete m_pDC;
}
void COpenGLShowMovieView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
if(m_hglrc)
wglMakeCurrent(m_pDC->GetSafeHdc(), m_hglrc);//获取当前绘图场景
else
return;
glViewport(0,0,cx,cy);//设置视口大小
glMatrixMode(GL_PROJECTION);//设置变换模式为投影变换
glLoadIdentity();//初始化投影变换矩阵
//根据窗口大小设置调整正射投影矩阵
if(cx<=cy)
glOrtho(-5.0,5.0,-5.0*(GLfloat)cy/(GLfloat)cx,
5.0*(GLfloat)cy/(GLfloat)cx,-12.0,12.0);
else
glOrtho(-5.0*(GLfloat)cx/(GLfloat)cy,
5.0*(GLfloat)cx/(GLfloat)cy,-5.0,5.0,-12.0,12.0);
// 设置变换模式为模型变换
glMatrixMode(GL_MODELVIEW);
// 初始化模型变换矩阵为单位矩阵
glLoadIdentity();
}
void COpenGLShowMovieView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
int hDegree0 = hDegree, vDegree0 = vDegree, times;
double r0=r,dr=0.01;
if (ctrl)
times = 10;
else
times = 1;
switch (nChar) {
// change view degree and distance
case 187: // +
r += times * dr;
break;
case 189: // -
r -= times * dr;
break;
case VK_UP:
vDegree -= times;
break;
case VK_DOWN:
vDegree += times;
break;
case VK_LEFT:
hDegree += times;
break;
case VK_RIGHT:
hDegree -= times;
break;
case VK_CONTROL:
ctrl = TRUE;
break;
case VK_SHIFT:
ctrl = FALSE;
}
if (hDegree < 0)
hDegree += 360;
else if (hDegree > 360)
hDegree -= 360;
if (vDegree < -180)
vDegree += 360;
else if (vDegree > 180)
vDegree -= 360;
if (r != r0 || hDegree != hDegree0 || vDegree0 != vDegree)
Invalidate();//更新视图
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
void COpenGLShowMovieView::GetEye(double r, int hd, int vd, GLdouble &ex, GLdouble &ey, GLdouble &ez)
{
ex = r * sin(vd * RAD) * cos(hd * RAD);
ey = r * sin(vd * RAD) * sin(hd * RAD);
ez = r * cos(vd * RAD);
}