mfc 下的OpenGL

建立一个SDI 的MFC工程,然后按freeglut 在mfc 下的编译_leon_zeng0的博客-CSDN博客​​​​​​

一文设置好include lib 路径

在view 中建立这2个函数:

复制代码
// Standard OpenGL Init Stuff

BOOL CmfcOpenglDemoView::SetupPixelFormat()
{
	static PIXELFORMATDESCRIPTOR pfd =
	{
		sizeof(PIXELFORMATDESCRIPTOR),    // size of this pfd
		1,                                // version number
		PFD_DRAW_TO_WINDOW |              // support window
		PFD_SUPPORT_OPENGL |              // support OpenGL
		PFD_DOUBLEBUFFER,                 // double buffered
		PFD_TYPE_RGBA,                    // RGBA type
		24,                               // 24-bit color depth
		0, 0, 0, 0, 0, 0,                 // color bits ignored
		0,                                // no alpha buffer
		0,                                // shift bit ignored
		0,                                // no accumulation buffer
		0, 0, 0, 0,                       // accumulation bits ignored
		16,                               // 16-bit z-buffer
		0,                                // no stencil buffer
		0,                                // no auxiliary buffer
		PFD_MAIN_PLANE,                   // main layer
		0,                                // reserved
		0, 0, 0                           // layer masks ignored
	};

	int m_nPixelFormat = ::ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd);

	if (m_nPixelFormat == 0)
		return FALSE;

	return ::SetPixelFormat(m_pDC->GetSafeHdc(), m_nPixelFormat, &pfd);
}

BOOL CmfcOpenglDemoView::InitOpenGL()
{
	TRACE(L"InitOpenGL()\n");
	//Get a DC for the Client Area
	m_pDC = new CClientDC(this);

	//Failure to Get DC
	if (m_pDC == NULL)
		return FALSE;

	if (!SetupPixelFormat())
		return FALSE;

	//Create Rendering Context
	m_hRC = ::wglCreateContext(m_pDC->GetSafeHdc());

	//Failure to Create Rendering Context
	if (m_hRC == 0)
		return FALSE;

	//Make the RC Current
	if (::wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC) == FALSE)
		return FALSE;

	// Usual OpenGL stuff

	glClearColor(0.0f, 0.0f, 0.3f, 0.0f);
	glClearDepth(1.0f);
	glEnable(GL_DEPTH_TEST);
	//glDisable( GL_DEPTH_TEST );
	//glEnable( GL_TEXTURE_2D );
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	//	glDepthMask(GL_FALSE); 

	glLineWidth(1.0f);
	glPointSize(1.0f);

	// for test
	
	m_RenderScene = render;

	return TRUE;
}

void CmfcOpenglDemoView::RenderScene()
{
	if (m_RenderScene != NULL)
		m_RenderScene((CmfcOpenglDemoDoc*)(GetDocument()));
	else
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

利用class wizard 建立几个message:

OnCreate(LPCREATESTRUCT lpCreateStruct)

OnDestroy()

OnSize(UINT nType, int cx, int cy)

OnEraseBkgnd(CDC* pDC)

复制代码
int CmfcOpenglDemoView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  Add your specialized creation code here
	if (!InitOpenGL())
	{
		MessageBox(L"Error setting up OpenGL!", L"Init Error!",
			MB_OK | MB_ICONERROR);
		return -1;
	}

	COLORREF color = ::GetSysColor(COLOR_3DFACE);
	glClearColor(0.0, 0, 0.25, 1.0);
	glPolygonMode(GL_FRONT, GL_FILL);
	glPolygonMode(GL_BACK, GL_FILL);
	glEnable(GL_DEPTH_TEST);
	// Antialiasing
	glEnable(GL_LINE_SMOOTH);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
	glLineWidth(1.0);

	return 0;
}


void CmfcOpenglDemoView::OnDestroy()
{
	CView::OnDestroy();

	// TODO: Add your message handler code here
	wglMakeCurrent(0, 0);
	wglDeleteContext(m_hRC);
	if (m_pDC)
	{
		delete m_pDC;
	}
	m_pDC = NULL;
}


void CmfcOpenglDemoView::OnSize(UINT nType, int cx, int cy)
{
	CView::OnSize(nType, cx, cy);

	// TODO: Add your message handler code here
	Resize(cx,cy);

	RenderScene();//	OnPaint();
}


BOOL CmfcOpenglDemoView::OnEraseBkgnd(CDC* pDC)
{
	// TODO: Add your message handler code here and/or call default
	TRACE("COpem:OnEraseBkgnd--\n");

	return CView::OnEraseBkgnd(pDC);
}


void CmfcOpenglDemoView::Resize(int cx,int cy)
{
	// TODO: Add your implementation code here.
	GLsizei width, height;
	GLdouble aspect;

	width = cx;
	height = cy;

	if (cy == 0)
		aspect = (GLdouble)width;
	else
		aspect = (GLdouble)width / (GLdouble)height;

	glViewport(0, 0, width, height);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	gluOrtho2D(-1.0f,1.0,-1.0f,1.0f);
		//glOrtho(-4.0 * aspect - pDoc->m_transX, 4.0 * aspect - pDoc->m_transX, -4 - pDoc->m_transY, 4 - pDoc->m_transY, -10, 10);//aspect=cx/cy
	glMatrixMode(GL_MODELVIEW);

	//glMatrixMode( GL_PROJECTION );

}

Resize 可以参考下面代码,设置立体图,上面代码只是正面的平面图。

复制代码
	width = m_sizeCx;
	height = m_sizeCy;

	if(m_sizeCy==0)
		aspect = (GLdouble)width;
	else
		aspect = (GLdouble)width/(GLdouble)height;

	glViewport(0,0,width,height);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	if(pDoc->m_ViewSelect==0)
		gluPerspective(45,aspect,1,100.0);
	else
		//gluOrtho2D(0.0f,aspect,0.0f,1.0f);
		glOrtho(-4.0*aspect-pDoc->m_transX, 4.0*aspect-pDoc->m_transX, -4-pDoc->m_transY,4-pDoc->m_transY, -10, 10);//aspect=cx/cy
	glMatrixMode(GL_MODELVIEW);

glOtho2D 参看

https://registry.khronos.org/OpenGL-Refpages/gl2.1/xhtml/glOrtho.xml

C Specification

|-----------------------|---------------------|
| void glOrtho( | GLdouble left, |
| | GLdouble right, |
| | GLdouble bottom, |
| | GLdouble top, |
| | GLdouble nearVal, |
| | GLdouble farVal); |

Parameters

left , right

Specify the coordinates for the left and right vertical clipping planes.

bottom , top

Specify the coordinates for the bottom and top horizontal clipping planes.

nearVal , farVal

Specify the distances to the nearer and farther depth clipping planes. These values are negative if the plane is to be behind the viewer.

Description

glOrtho describes a transformation that produces a parallel projection. The current matrix (see glMatrixMode) is multiplied by this matrix and the result replaces the current matrix, as if glMultMatrix were called with the following matrix as its argument:

2right-left00��02top-bottom0��00-2farVal-nearVal��0001

where

��=-right+leftright-left

��=-top+bottomtop-bottom

��=-farVal+nearValfarVal-nearVal

Typically, the matrix mode is GL_PROJECTION, and leftbottom-nearVal and righttop-nearVal specify the points on the near clipping plane that are mapped to the lower left and upper right corners of the window, respectively, assuming that the eye is located at (0, 0, 0). -farVal specifies the location of the far clipping plane. Both nearVal and farVal can be either positive or negative.

Use glPushMatrix and glPopMatrix to save and restore the current matrix stack.

Errors

GL_INVALID_VALUE is generated if left = right , or bottom = top , or near = far.

GL_INVALID_OPERATION is generated if glOrtho is executed between the execution of glBegin and the corresponding execution of glEnd.

在.h 文件中加这几个函数

复制代码
	void SetRenderFunc(void (*func) (CmfcOpenglDemoDoc*)) { m_RenderScene = func; }
	void RenderScene();
	// Each viewport uses its own context
	// so we need to make sure the correct
	// context is set whenever we make an
	// OpenGL command.
	void SetContext() { wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC); }
	void SwapGLBuffers() { SwapBuffers(m_pDC->GetSafeHdc()); }

添加一个画图函数,不是类里的,独立的

复制代码
void render(CmfcOpenglDemoDoc* pdoc)
{

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glBegin(GL_TRIANGLE_STRIP);
	glColor3f(0.0f, 0.5f, 0.0f);
	glVertex2f(0.0f, -0.0f);
	glVertex2f(0.0f, 0.3f);
	glVertex2f(0.4f, 0.0f);
	glEnd();

}

在init里有这一句:

cpp 复制代码
m_RenderScene = render;

在.h 文件中有:

cpp 复制代码
// Attributes
public:
	CmfcOpenglDemoDoc* GetDocument() const;

	//------------------
	void (*m_RenderScene) (CmfcOpenglDemoDoc* doc);	// void function pointer to the rendering
												// function. Used to change to easily
												// change what a viewport displays.
protected:
	HGLRC m_hRC; //Rendering Context
	CDC* m_pDC;  //Device Context

// Operations
public:
	// OpenGL init stuff
	BOOL SetupPixelFormat();
	BOOL InitOpenGL();

这样就构造了一个基本的mfc 下的opengl 工程

相关推荐
智者知已应修善业8 分钟前
【51单片机1,左边4个LED灯先闪烁2次后,右边4个LED灯再闪烁2次:2,接着所用灯一起闪烁3次,接着重复步骤1,如此循环。】2023-5-19
c++·经验分享·笔记·算法·51单片机
xiaoye-duck14 分钟前
《算法题讲解指南:优选算法-队列+宽搜》--70.N叉树的层序遍历,71.二叉树的锯齿形层序遍历,72.二叉树的最大宽度,73.在每个树行中找最大值
数据结构·c++·算法·队列
代码改善世界15 分钟前
【C++初阶】双向循环链表:List底层结构的完整实现剖析
c++·链表·list
REDcker19 分钟前
C++ 包管理工具概览
开发语言·c++
努力努力再努力wz22 分钟前
【C++高阶系列】告别内查找局限:基于磁盘 I/O 视角的 B 树深度剖析与 C++ 泛型实现!(附B树实现源码)
java·linux·开发语言·数据结构·c++·b树·算法
承渊政道23 分钟前
【优选算法】(实战攻坚BFS之FloodFill、最短路径问题、多源BFS以及解决拓扑排序)
数据结构·c++·笔记·学习·算法·leetcode·宽度优先
lcj251139 分钟前
字符函数,字符串函数,内存函数
c语言·开发语言·c++·windows
吃着火锅x唱着歌44 分钟前
深度探索C++对象模型 学习笔记 第三章 Data语意学(2)
c++·笔记·学习
Imxyk1 小时前
P9242 [蓝桥杯 2023 省 B] 接龙数列
c++·算法·图论
郝学胜-神的一滴1 小时前
二叉树后序遍历:从递归到非递归的优雅实现
数据结构·c++·程序人生·算法·