目标
(1) 绘制三个立方体,位置如图所示。要求绘制出坐标系的
3 个坐标轴。
(2)三个立方体一起沿着坐标轴(x 或 y 或 z)旋转起来。说
明:旋转可以通过设置时钟事件来实现,提供的程序里
已经实现旋转的功能。打开菜单: 编辑-rotate about x
等即可旋转,可以参考其实现。
(3) 三个立方体分别沿 X 轴,Y 轴和 Z 轴旋转。
预备知识
1)MFC编程相关知识
2)了解OpenGL编程相关知识
过程描述
1)先实现要求一。要求一相对简单,只需要根据老师给出的图片,找到矩形的坐标即可。
2)实现要求二。实现旋转,需要有一个记录角度变换的量,m_angle。该变量在Ontime()函数中中期性的变化,用于在渲染函数中更新正方体的角度。在渲染函数中当m_rotate_aix==整体旋转的ID时,实现旋转。具体思路。1,先设置一个堆栈,里面进行两次旋转,用于将角度调制老师给定图片的角度2,该堆栈中再设置一个堆栈,用于实现图形的旋转。
3)实现要求三。在实现要求二的基础上,m_angle不变,只需要在渲染函数里对不同的ID分类讨论即可。对于每种情况同样是设置两个堆栈,外面的用于实现视角的变换,里面的实现旋转。
这里出现的绿屏是截图软件出现了问题,实际的效果是正常的。
遇到的问题
1、每次重新绘制时,不能做到接着上一次的角度继续旋转,而是从零开始。解决方法,设置m_angle记录每次的旋转角度,在每一次换图形的时候,都在堆栈里解决,每一次与每一次之间不相互影响,但又因为m_angle的帮助下,每一次的角度又可以接着上一次的角度。
代码
// OpenglExampleView.cpp : COpenglExampleView 类的实现
//
#include "stdafx.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "OpenglExample.h"
#endif
#include "OpenglExampleDoc.h"
#include "OpenglExampleView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#include <vector>
using namespace std;
// COpenglExampleView
IMPLEMENT_DYNCREATE(COpenglExampleView, CView)
BEGIN_MESSAGE_MAP(COpenglExampleView, CView)
ON_WM_CONTEXTMENU()
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_SIZE()
ON_WM_ERASEBKGND()
ON_COMMAND(ID_ROTATE, &COpenglExampleView::OnRotate)
ON_WM_TIMER()
ON_COMMAND(ID_Stop, &COpenglExampleView::OnStop)
ON_COMMAND(ID_ROTATE_X, &COpenglExampleView::OnRotateX)
ON_COMMAND(ID_ROTATE_Z, &COpenglExampleView::OnRotateZ)
ON_COMMAND(ID_32780, &COpenglExampleView::On32780)
END_MESSAGE_MAP()
// COpenglExampleView 构造/析构
COpenglExampleView::COpenglExampleView()
{
// TODO: 在此处添加构造代码
m_angle = 0;
m_rotate_axis = NOROTATE;
}
COpenglExampleView::~COpenglExampleView()
{
}
BOOL COpenglExampleView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: 在此处通过修改
// CREATESTRUCT cs 来修改窗口类或样式
return CView::PreCreateWindow(cs);
}
// COpenglExampleView 绘制
void COpenglExampleView::OnDraw(CDC* /*pDC*/)
{
COpenglExampleDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
//wglMakeCurrent(m_hDC, m_hRC);
RenderScene();
SwapBuffers(m_hDC);
}
//void COpenglExampleView::OnRButtonUp(UINT /* nFlags */, CPoint point)
//{
// ClientToScreen(&point);
// OnContextMenu(this, point);
//}
void COpenglExampleView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}
// COpenglExampleView 诊断
#ifdef _DEBUG
void COpenglExampleView::AssertValid() const
{
CView::AssertValid();
}
void COpenglExampleView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
COpenglExampleDoc* COpenglExampleView::GetDocument() const // 非调试版本是内联的
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(COpenglExampleDoc)));
return (COpenglExampleDoc*)m_pDocument;
}
#endif //_DEBUG
void COpenglExampleView::RenderScene2()
{
// clear color buffer and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(30, 0, 1, 0); //glRotatef(angle, rx, ry, rz);
glRotatef(30, 1, 0, 0);
glRotatef(30, 0, 0, 1);
glBegin(GL_QUADS);
// front
glNormal3f(0, 0, -1);
glVertex3f(0, 0, 0);
glVertex3f(1, 0, 0);
glVertex3f(1, 1, 0);
glVertex3f(0, 1, 0);
// bottom
glNormal3f(0, -1, 0);
glVertex3f(0, 0, 0);
glVertex3f(0, 0, 1);
glVertex3f(1, 0, 1);
glVertex3f(1, 0, 0);
//right
glNormal3f(1, 0, 0);
glVertex3f(1, 0, 0);
glVertex3f(1, 0, 1);
glVertex3f(1, 1, 1);
glVertex3f(1, 1, 0);
//left
glNormal3f(-1, 0, 0);
glVertex3f(0, 0, 0);
glVertex3f(0, 1, 0);
glVertex3f(0, 1, 1);
glVertex3f(0, 0, 1);
//top
glNormal3f(0, 1, 0);
glVertex3f(0, 1, 0);
glVertex3f(1, 1, 0);
glVertex3f(1, 1, 1);
glVertex3f(0, 1, 1);
//back
glNormal3f(0, 0, 1);
glVertex3f(0, 0, 1);
glVertex3f(0, 1, 1);
glVertex3f(1, 1, 1);
glVertex3f(1, 0, 1);
glEnd();
glPopMatrix();
glFlush(); //强制执行opengl语句
}
void COpenglExampleView::draw_car()
{
//x
glBegin(GL_QUADS);
// back
glNormal3f(0, 0, -1);
glVertex3f(-1, 0, -1);
glVertex3f(-1, 0, 0);
glVertex3f(-1, 1, 0);
glVertex3f(-1, 1, -1);
// bottom
glNormal3f(0, -1, 0);
glVertex3f(-2, 0, 0);
glVertex3f(-1, 0, 0);
glVertex3f(-1, 0, -1);
glVertex3f(-2, 0, -1);
//right
glNormal3f(1, 0, 0);
glVertex3f(-2, 0, 0);
glVertex3f(-1, 0, 0);
glVertex3f(-1, 1, 0);
glVertex3f(-2, 1, 0);
//left
glNormal3f(-1, 0, 0);
glVertex3f(-2, 0, -1);
glVertex3f(-1, 0, -1);
glVertex3f(-1, 1, -1);
glVertex3f(-2, 1, -1);
//top
glNormal3f(0, 1, 0);
glVertex3f(-2, 1, 0);
glVertex3f(-1, 1, 0);
glVertex3f(-1, 1, -1);
glVertex3f(-2, 1, -1);
//front
glNormal3f(0, 0, 1);
glVertex3f(-2, 0, -1);
glVertex3f(-2, 0, 0);
glVertex3f(-2, 1, 0);
glVertex3f(-2, 1, -1);
glEnd();
glBegin(GL_LINES);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(-1.0, 0.0, 0.0);
glEnd();
}
void draw_sphere(GLfloat x, GLfloat y, GLfloat z, GLfloat r)
{
}
void COpenglExampleView::