在前面的入门教程中,从最基本的窗口建立,到三维贴图的交互,但我们的程序构架是 glfw + glad 。我一直在寻找转移的路线。我终于明白glfw 的功能就是窗口,上下文,交互,但没有菜单,对话框。在mfc 中不需要glfw, 但需要glad。
本文是在visual studio 2017下实现完成的,然后做了简单修改,在visual studio 2010下也测试通过了。本文参考 https://zhuanlan.zhihu.com/p/48931461 学习而来。
1:简介和运行效果图
与前面现代opengl 设计入门 对照而言,或者转移,只需要3个函数。
CreateContextPtr m_CreateContextCall;
DeleteContextPtr m_DeleteContextCall;
MakeCurrentPtr m_MakeCurrentCall;
这3个函数就是建立上下文,删除上下文,设置当前调用。
m_CreateContextCall = (CreateContextPtr)::GetProcAddress(::libGL, "wglCreateContext");
m_DeleteContextCall = (DeleteContextPtr)::GetProcAddress(::libGL, "wglDeleteContext");
m_MakeCurrentCall = (MakeCurrentPtr)::GetProcAddress(::libGL, "wglMakeCurrent");
本文为简单例子,只是一个简单三角形,但我这也陈列其他转移比如纹理贴图,三维纹理贴图的运行效果图。理解了本文也就都能实现转移。
三维纹理贴图运行效果图。
本文实际的运行效果图:
2:获取glad.c和glad.h源码做准备
获取glad.c和glad.h源码,这个库的作用是做OpenGL的API管理。https://glad.dav1d.de/ 中根据你的需要裁剪你的glad文件,然后给你下载。
(1)Language,选C/C++或C/C++ Debug
(2)Specification,选OpenGL
(3)API,gl至少选3.3,可以更高
(4)Profile,选Core
(5)Extension,全选,ADD ALL
(6)Options,默认即可
(7)点击Generate,下载生成的文件
3:工程建立
先在visual studio 2017 下建立一个简单的mfc SDI 工程,取名为sample。然后修改sampleView.cpp 和sampleView.h 后面有全部代码。
在类中添加4个事件的响应函数,sampleView.h 中如下显示
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnDestroy();
afx_msg void OnSize(UINT nType, int cx, int cy);
在sampleView.cpp 中除了上面4个函数外,另要修改OnDraw
4: 代码执行步骤分析
第一步:导入glad源码
向sampleView.cpp文件导入glad.c的源码,源代码中已经给出导入方式。
第二步:修改OnCreate
这个函数主要完成5件事:
->调用glad.c中的open_gl(),加载运行环境中的opengl32.dll,glad.c中静态变量libGL就是opengl32.dll的句柄。Windows上的OpenGL32.dll包含了OpenGL1.1的实现和wgl工具,其中的wglGetProcAddress函数,可以用来访问其他库实现的高版本OpenGL。
->如果open_gl()执行成功,从opengl32.dll获取wglCreateContext、wglDeleteContext和wglMakeCurrent这三个函数。注意:不从opengl32.dll获取,这个三个函数(也包括上一段提到的wglGetProcAddress)也可以调用。如果不用opengl32.dll而是直接调用这三个函数,需要程序在编译时链接OpenGL32.Lib库,这样,当程序运行时,程序会从内部调用它们,而不是从实际运行程序的机器上动态调用。
->设置像素格式,用SetPixelFormat使设置生效。
->调用刚才加载的wglCreateContext、wglMakeCurrent,创建渲染上下文。
->调用glad.c中的gladLoadGL函数,加载OpenGL的API。实际就是调用opengl32.dll中的wglGetProcAddress来寻找其他dll中的高版本OpenGL实现。
这5件事做完后,就可以初始化OpenGL了。
第三步:渲染环境
给sampleView添加5个方法
void _InitGL(); // 窗口的OnCreate调用这个函数
void _InitGraphic(); // 窗口的OnCreate调用这个函数
void _MainGLPaint(); // 窗口的OnDraw调用这个函数
void _ResizeGL(int w, int h); // 窗口的OnSize调用这个函数
void _CleanupGL(); // OnDestroy调用这个函数
具体含义见代码。
第四步:环境清理
当窗口关闭时,销毁渲染上下文,清理OpenGL的API,卸载opengl32.dll,完成清理,这些步骤在窗口的OnDestroy中去做。工程自动生成的代码不包含OnDestroy,需要手动添加。(头文件中添加声明、源文件中添加实现和消息映射)
5:前面工程代码转移
在前面教程中只是一个main 函数,包含glad glfw,作为测试和学习是很好的。完成后怎么代码移植的呢?
mfc 中不要glfw 代之以3个函数,这些在OnCreate 中实现上下文建立, OnDestroy 删除上下文。_CleanupGL中内存清除。
基本代码在_InitGraphic 变量,着色等。循环代码在_MainGLPaint() --OnDraw()中调用,窗口控制在 _ResizeGL() --OnSize()中调用。沟通变量用了
unsigned int m_iVAO, m_iVBO;