MFC——OpenGL编程

本文档介绍了如何使用MFC结合OpenGL编程实现3D场景中三个立方体的绘制及旋转效果。首先,按照指定位置绘制立方体和坐标轴;然后,通过时钟事件动态旋转立方体;最后,详细描述了遇到的旋转角度连续性问题及解决方案。代码中包含关键的堆栈管理和旋转逻辑。
摘要由CSDN通过智能技术生成

目标

(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::
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值