openGL学习笔记二: MFC 下搭建开发环境(不借助界面库)

  在win mfc环境下,不借助任何界面库搭建opengl开发环境。

VS环境设置:

      项目属性----链接器----附加依赖项----添加库文件OpenGL32.lib

1. 新建MFC项目:

创建MFC单文档项目 02exampleOpenGLMFC,选择默认设置。(对话框、多文档类似)

在这里插入图片描述

2. 引入自己封装的opengl初始化类文件GLContext.hpp、GLContext.cpp。

3. MFC中负责显示的是View类,所以修改02exampleOpenGLMFCView.h .cpp文件。

  a. 在02exampleOpenGLMFCView.h 中定义GLContext 变量:

	GLContext _context;

   b. 重写OnInitialUpdate函数: 类视图----选择类:CMy02exampleOpenGLMFCView -----属性-----选择:重写OnInitialUpdate,在OnInitialUpdate函数中初始化opengl:

//初始化
void CMy02exampleOpenGLMFCView::OnInitialUpdate() {
	CView::OnInitialUpdate();

	_context.setup(m_hWnd, ::GetDC(m_hWnd));
}

  c. 重写OnDestroy函数(销毁):类视图----选择类:CMy02exampleOpenGLMFCView -----属性-----选择:消息 WM_DESTROY 重写OnDestroy,在OnDestroy函数中进行opengl销毁操作:

//销毁
void CMy02exampleOpenGLMFCView::OnDestroy() {
	CView::OnDestroy();

	_context.shutdown();
}

  d.opengl绘制在OnDraw函数中:

// CMy02exampleOpenGLMFCView 绘制

void CMy02exampleOpenGLMFCView::OnDraw(CDC* /*pDC*/)
{
	CMy02exampleOpenGLMFCDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;
    //opengl 绘制
	glClearColor(0,1,0,1);
	glClear(GL_COLOR_BUFFER_BIT);
	_context.swapBuffer();
}

  e.为了解决窗口大小改变时出现闪烁问题 需要重写OnEraseBkgnd函数:类视图----选择类:CMy02exampleOpenGLMFCView -----属性-----选择:消息 WM_ENTERSIZEMOVE 重写OnEraseBkgnd函数:

//重写删除背景 解决改动显示区域 屏幕闪烁问题
//因为改动窗口大小时, window会重绘窗口  这里改成不重绘 就不会闪烁
BOOL CMy02exampleOpenGLMFCView::OnEraseBkgnd(CDC* pDC) {
	// TODO:  在此添加消息处理程序代码和/或调用默认值
	return TRUE; //return CView::OnEraseBkgnd(pDC);
}

4. 详细代码:

02exampleOpenGLMFCView.h


// 02exampleOpenGLMFCView.h : CMy02exampleOpenGLMFCView 类的接口
//
#pragma once

#include "GLContext.hpp"

class CMy02exampleOpenGLMFCView : public CView
{
protected: // 仅从序列化创建
	CMy02exampleOpenGLMFCView();
	DECLARE_DYNCREATE(CMy02exampleOpenGLMFCView)

protected:
	GLContext _context;
// 特性
public:
	CMy02exampleOpenGLMFCDoc* GetDocument() const;

// 操作
public:

// 重写
public:
	virtual void OnDraw(CDC* pDC);  // 重写以绘制该视图
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
	virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
	virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
	virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);

// 实现
public:
	virtual ~CMy02exampleOpenGLMFCView();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// 生成的消息映射函数
protected:
	afx_msg void OnFilePrintPreview();
	afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
	DECLARE_MESSAGE_MAP()
public:
	virtual void OnInitialUpdate();
	afx_msg void OnDestroy();
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
};

#ifndef _DEBUG  // 02exampleOpenGLMFCView.cpp 中的调试版本
inline CMy02exampleOpenGLMFCDoc* CMy02exampleOpenGLMFCView::GetDocument() const
   { return reinterpret_cast<CMy02exampleOpenGLMFCDoc*>(m_pDocument); }
#endif

02exampleOpenGLMFCView.cpp


// 02exampleOpenGLMFCView.cpp : CMy02exampleOpenGLMFCView 类的实现
//
#include "stdafx.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "02exampleOpenGLMFC.h"
#endif

#include "02exampleOpenGLMFCDoc.h"
#include "02exampleOpenGLMFCView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CMy02exampleOpenGLMFCView
IMPLEMENT_DYNCREATE(CMy02exampleOpenGLMFCView, CView)

BEGIN_MESSAGE_MAP(CMy02exampleOpenGLMFCView, CView)
	// 标准打印命令
	ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CMy02exampleOpenGLMFCView::OnFilePrintPreview)
	ON_WM_CONTEXTMENU()
	ON_WM_RBUTTONUP()
	ON_WM_DESTROY()
	ON_WM_ERASEBKGND()
END_MESSAGE_MAP()

// CMy02exampleOpenGLMFCView 构造/析构

CMy02exampleOpenGLMFCView::CMy02exampleOpenGLMFCView()
{
	// TODO:  在此处添加构造代码

}

CMy02exampleOpenGLMFCView::~CMy02exampleOpenGLMFCView()
{
}

BOOL CMy02exampleOpenGLMFCView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO:  在此处通过修改
	//  CREATESTRUCT cs 来修改窗口类或样式

	return CView::PreCreateWindow(cs);
}

// CMy02exampleOpenGLMFCView 绘制

void CMy02exampleOpenGLMFCView::OnDraw(CDC* /*pDC*/)
{
	CMy02exampleOpenGLMFCDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;
    //opengl 绘制
	glClearColor(0,1,0,1);
	glClear(GL_COLOR_BUFFER_BIT);
	_context.swapBuffer();
}

// CMy02exampleOpenGLMFCView 打印

void CMy02exampleOpenGLMFCView::OnFilePrintPreview()
{
#ifndef SHARED_HANDLERS
	AFXPrintPreview(this);
#endif
}

BOOL CMy02exampleOpenGLMFCView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// 默认准备
	return DoPreparePrinting(pInfo);
}

void CMy02exampleOpenGLMFCView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO:  添加额外的打印前进行的初始化过程
}

void CMy02exampleOpenGLMFCView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO:  添加打印后进行的清理过程
}

void CMy02exampleOpenGLMFCView::OnRButtonUp(UINT /* nFlags */, CPoint point)
{
	ClientToScreen(&point);
	OnContextMenu(this, point);
}

void CMy02exampleOpenGLMFCView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
	theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}


// CMy02exampleOpenGLMFCView 诊断

#ifdef _DEBUG
void CMy02exampleOpenGLMFCView::AssertValid() const
{
	CView::AssertValid();
}

void CMy02exampleOpenGLMFCView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CMy02exampleOpenGLMFCDoc* CMy02exampleOpenGLMFCView::GetDocument() const // 非调试版本是内联的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMy02exampleOpenGLMFCDoc)));
	return (CMy02exampleOpenGLMFCDoc*)m_pDocument;
}
#endif //_DEBUG


// CMy02exampleOpenGLMFCView 消息处理程序

//初始化
void CMy02exampleOpenGLMFCView::OnInitialUpdate() {
	CView::OnInitialUpdate();

	_context.setup(m_hWnd, ::GetDC(m_hWnd));
}

//销毁
void CMy02exampleOpenGLMFCView::OnDestroy() {
	CView::OnDestroy();

	_context.shutdown();
}


//重写删除背景 解决改动显示区域 屏幕闪烁问题
//因为改动窗口大小时, window会重绘窗口  这里改成不重绘 就不会闪烁
BOOL CMy02exampleOpenGLMFCView::OnEraseBkgnd(CDC* pDC) {
	// TODO:  在此添加消息处理程序代码和/或调用默认值
	return TRUE; //return CView::OnEraseBkgnd(pDC);
}

5. 运行结果:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值