我需要实现
1.创建1个基于MFC的单文档窗口。
2.窗口背景为黄色。
3.使用OpenGL函数绘制一个正方形,颜色为填充蓝色:
a)(-0.3,-0.3)
b)(-0.3,0.3)
c)(0.3,0.3)
d)(0.3,-0.3)
4.在鼠标左键单击时,开始绕原点逆时针连续动态旋转,旋转步长和速度自行定义;在鼠标左键再次单击时,旋转停止。
我的OpenGL代码以及MFCAppView代码
MyOpenGL:
#include "stdafx.h"
#include "MyOpenGL.h"
#include "WinsOpenGLAppView.h"
static GLfloat spin = 0.0;
MyOpenGL::MyOpenGL()
{
}
MyOpenGL::~MyOpenGL()
{
wglMakeCurrent(hDC, NULL);
wglDeleteContext(hRC);
}
bool MyOpenGL::SetupPixelFormat(HDC hdc)
{
hDC = hdc;
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // pfd结构的大小
1, // 版本号
PFD_DRAW_TO_WINDOW | // 支持在窗口中绘图
PFD_SUPPORT_OPENGL | // 支持OpenGL
PFD_DOUBLEBUFFER, // 双缓存模式
PFD_TYPE_RGBA, // RGBA 颜色模式
24, // 24 位颜色深度
0, 0, 0, 0, 0, 0, // 忽略颜色位
0, // 没有非透明度缓存
0, // 忽略移位位
0, // 无累加缓存
0, 0, 0, 0, // 忽略累加位
32, // 32 位深度缓存
0, // 无模板缓存
0, // 无辅助缓存
PFD_MAIN_PLANE, // 主层
0, // 保留
0, 0, 0 // 忽略层,可见性和损毁掩模
};
int nPixelFormat; // 像素点格式
if (!(nPixelFormat = ChoosePixelFormat(hDC, &pfd)))
{
MessageBox(NULL, L"can not find proper mode", L"Error", MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
SetPixelFormat(hDC, nPixelFormat, &pfd);
hRC = wglCreateContext(hDC); //利用GDI绘图所使用的HDC创建对应的HGLRC
wglMakeCurrent(hDC, hRC); //使OpenGL绘图所使用的HGLRC为当前绘图工具
return TRUE;
}
void MyOpenGL::Init(void)
{
glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
}
void MyOpenGL::Render(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//绘制操作:
glColor3ub(0, 0, 255);
glBegin(GL_POLYGON);//填充凸多边形
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.5f, 0.5f, 0.0f);
glVertex3f(0.5f, -0.5f, 0.0f);
glVertex3f(-0.5f, -0.5f, 0.0f);
glVertex3f(-0.5f, 0.5f, 0.0f);
glRotatef(spin, 0.0, 0.0, 1.0);//旋转方向,遵循右手原则
glPopMatrix();
glEnd();
SwapBuffers(hDC);
}
void spinDisplay(void)
{
spin = spin + 0.04;
if (spin > 360.0)
{
spin = spin - 360.0;
}
glutPostRedisplay();
}
void MyOpenGL::mouse(int button, int state,int x,int y)
{
switch (button)
{
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc(spinDisplay);//glutIdleFunc函数如果启用,这个idle function会被不断调用,直到有窗口事件发生
else if (state == GLUT_UP)
glutIdleFunc(NULL);
break;
case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc(spinDisplay);
else if (state == GLUT_UP)
glutIdleFunc(NULL);
break;
default:
break;
}
}
void MyOpenGL::Reshape(int width, int height)
{
glViewport(0, 0, width, height);
}
WinsOpenGLAppView:
// WinsOpenGLAppView.cpp : CWinsOpenGLAppView 类的实现
//
#include "stdafx.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "WinsOpenGLApp.h"
#endif
#include "WinsOpenGLAppDoc.h"
#include "WinsOpenGLAppView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CWinsOpenGLAppView
IMPLEMENT_DYNCREATE(CWinsOpenGLAppView, CView)
BEGIN_MESSAGE_MAP(CWinsOpenGLAppView, CView)
// 标准打印命令
ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CWinsOpenGLAppView::OnFilePrintPreview)
ON_WM_CONTEXTMENU()
ON_WM_RBUTTONUP()
ON_WM_CREATE()
ON_WM_SIZE()
ON_COMMAND(ID_32771, &CWinsOpenGLAppView::On32771)
ON_WM_LBUTTONDOWN()
ON_WM_TIMER()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_RBUTTONDOWN()
END_MESSAGE_MAP()
// CWinsOpenGLAppView 构造/析构
CWinsOpenGLAppView::CWinsOpenGLAppView()
{
// TODO: 在此处添加构造代码
}
CWinsOpenGLAppView::~CWinsOpenGLAppView()
{
}
BOOL CWinsOpenGLAppView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: 在此处通过修改
// CREATESTRUCT cs 来修改窗口类或样式
cs.style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
return CView::PreCreateWindow(cs);
}
// CWinsOpenGLAppView 绘制
void CWinsOpenGLAppView::OnDraw(CDC* /*pDC*/)
{
CWinsOpenGLAppDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
opengl.Render();
}
// CWinsOpenGLAppView 打印
void CWinsOpenGLAppView::OnFilePrintPreview()
{
#ifndef SHARED_HANDLERS
AFXPrintPreview(this);
#endif
}
BOOL CWinsOpenGLAppView::OnPreparePrinting(CPrintInfo* pInfo)
{
// 默认准备
return DoPreparePrinting(pInfo);
}
void CWinsOpenGLAppView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: 添加额外的打印前进行的初始化过程
}
void CWinsOpenGLAppView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: 添加打印后进行的清理过程
}
void CWinsOpenGLAppView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}
// CWinsOpenGLAppView 诊断
#ifdef _DEBUG
void CWinsOpenGLAppView::AssertValid() const
{
CView::AssertValid();
}
void CWinsOpenGLAppView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CWinsOpenGLAppDoc* CWinsOpenGLAppView::GetDocument() const // 非调试版本是内联的
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CWinsOpenGLAppDoc)));
return (CWinsOpenGLAppDoc*)m_pDocument;
}
#endif //_DEBUG
// CWinsOpenGLAppView 消息处理程序
int CWinsOpenGLAppView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 在此添加您专用的创建代码
opengl.SetupPixelFormat(::GetDC(GetSafeHwnd()));
opengl.Init();
SetTimer(1, 5000, NULL);
return 0;
}
void CWinsOpenGLAppView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
// TODO: 在此处添加消息处理程序代码
opengl.Reshape(cx, cy);
}
void CWinsOpenGLAppView::On32771()
{
// TODO: 在此添加命令处理程序代码
int i;
i = 10;
}
void CWinsOpenGLAppView::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (nIDEvent == 1)
{
Invalidate(FALSE);
}
CView::OnTimer(nIDEvent);
}
void CWinsOpenGLAppView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (nFlags == 1)
{
SetTimer(1, 100, NULL);
opengl.mouse(GLUT_LEFT_BUTTON, GLUT_DOWN, point.x, point.y);
}
else
{
KillTimer(1);
}
CView::OnLButtonDown(nFlags, point);
}
void CWinsOpenGLAppView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CView::OnLButtonUp(nFlags, point);
opengl.mouse(GLUT_LEFT_BUTTON, GLUT_UP, point.x, point.y);
}
void CWinsOpenGLAppView::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (nFlags == 1)
{
SetTimer(1, 100, NULL);
opengl.mouse(GLUT_RIGHT_BUTTON, GLUT_DOWN, point.x, point.y);
}
else
{
KillTimer(1);
}
CView::OnRButtonDown(nFlags, point);
}
void CWinsOpenGLAppView::OnRButtonUp(UINT nFlags , CPoint point)
{
CView::OnLButtonUp(nFlags, point);
opengl.mouse(GLUT_RIGHT_BUTTON, GLUT_UP, point.x, point.y);
}
运行完成可以生成背景和图像,但是鼠标消息事件可以触发,但是点击后不会旋转。
我现在想知道要如何修改可以让OnLButtonDown函数成功调用mouse函数。
在OnLButtonDown函数中调用你的OpenGL对象的mouse函数
如 gl.mouse(GLUT_LEFT_BUTTON,GLUT_DOWN,point.x,point.y);