在win32上用wgl折腾OpenGL 3.3等高版本OpenGL
用GLFW+GLAD库已经好一段时间了。但是我还是觉得GLFW不如原生的win32窗口用着顺手,毕竟win32窗口可以自绘加控件等等,可玩性可谓是很高的。
微软给OpenGL留了套东西,不过可惜,哪怕到了Windows 10,这套API都停留在OpenGL 1.x时代。甚至还是用的CPU渲染。新版本的API藏在显卡开发商提供的程序中,我们需要拿到这些API。
说到这里应该你就熟悉了,这些API有一个库可以帮忙——GLAD。而GLAD通过一个回调来拿到这些函数的地址,这个函数类型(我还是愿意给函数一个类型,正如大部分编译器的类型系统实现那样,因此不纠结细节了~)是GLADloadproc,是gladLoadGLLoader函数唯一的参数(截止至今天,2020-07-13)。了解这些之后,我们需要做的问题就是两个:一是实现这个函数,一个是初始化wgl一系列相关的。我们分步来,下面,假如你已经准备好了一个空窗口,现在我们开始干活吧!
step1. 拿到HDC,准备dll模块句柄
WGL是建立在HDC上的,因此,第一步我们需要拿到HDC。而dll其实是为了方便glad,这个一会会说。
hDC = GetDC(hWnd);
glInst = LoadLibraryA("opengl32.dll");
if (glInst == NULL)
{return false;
}
一般而言这个调用是成功的,只要窗口有效就可以了,加载的dll和动态调用dll的操作是一样的。
step2. 设置像素格式
如大多数教程,我们需要设置一下HDC希望匹配的像素格式。现在的OpenGL已经不需要拘于太多细节,因此直接这样就可以做到:
bool selectHDCFormat(HDC hdc) noexcept
{PIXELFORMATDESCRIPTOR pfd = { 0 };pfd.nSize = sizeof(pfd);pfd.nVersion = 1;pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;pfd.iPixelType = PFD_TYPE_RGBA;pfd.cColorBits = 24;auto pxfmt = ChoosePixelFormat(hdc, &pfd);if (pxfmt == 0) // 不支持的像素格式{return false;}auto _ = SetPixelFormat(hdc, pxfmt, &pfd);assert(_);return true;
}
调用这个函数,如果返回false则表示失败。我们打开了双缓冲,这是因为双缓冲能有效减少绘制过程带来的闪烁。
step3. 初始化WGL上下文
HDC准备好后,我们需要创建一个HGLRC,然后把这个HGLRC绑定给HDC:
hRC = wglCreateContext(hDC);
if (wglMakeCurrent(hDC, hRC) == FALSE)
{return false;
}
step4. 初始化glad
这一步弄完就可以了。查一下GLADloadproc长什么样,它在glad.h里面可以看到:
typedef void* (* GLADloadproc)(const char *name);
很显然,它将一个函数名作为输入,返回这个函数的地址。而注意,这个不单单是只取得OpenGL拓展,还包括OpenGL基本的API,如glGetString。在OpenGL 1.x时代还没有拓展的概念,因此我们需要去dll里面动态加载它,得到这个函数的地址。这就是之前使用LoadLibrary的原因。好了,所以这个函数应该先调用wglGetProcAddress,如果失败则调用GetProcAddress:
static void* cWGLGetProcAddr(const char *name)
{auto ret = wglGetProcAddress(name);if (ret == NULL){ret = GetProcAddress(glModleInst, name);}return ret;
}
接着,在你初始化glad的地方这样写:
bool initgladFuncAddr() noexcept
{assert(wglGetCurrentContext() != NULL); // 保证wgl有合适的上下文glModleInst = glInst;if (gladLoadGLLoader(cWGLGetProcAddr) == 0){return false;}return true;
}
这样就大功告成了!运行一下程序,试试glGetString(GL_VERSION)的结果是什么呢?
step5. 垂直同步
我们现在可以使用glEnable();操作一些东西,例如glEnable(GL_DEPTH_TEST);。但是有个地方没实现:垂直同步。
垂直同步是OpenGL的拓展,所以可以这样折腾:
typedef BOOL (APIENTRY *PFNWGLSWAPINTERVALFARPROC)(int);
PFNWGLSWAPINTERVALFARPROC wglSwapIntervalEXT = 0;
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALFARPROC)wglGetProcAddress("wglSwapIntervalEXT");
assert(wglSwapIntervalEXT != NULL);
这样的话,就可以用wglSwapIntervalEXT(1);来打开垂直同步,用wglSwapIntervalEXT(0);来关闭它。到这里是确实结束了,上一下我自己做出来的效果。注意窗口,很明显这个窗口和GLFW的( WS_OVERLAPPEDWINDOW那样的 )有差异:
step6. 删除资源
最后不要忘记用ReleaseDC、FreeLibrary、wglDeleteContext释放掉我们的资源
在win32上用wgl折腾OpenGL 3.3等高版本OpenGL相关推荐
- 【OpenGL相关】用高版本visual studio打开老版本的OpenGL工程文件可能会遇到的问题
内容 OpenGL库资源 测试代码 操作流程 解决方法 更多的问题 2022/10/21补充 参考文章 在3D图形程序设计课程进行学习的过程中,老师为我们提供了一些课本上的工程案例,但是这些工程案例过 ...
- [网络安全自学篇] 三十.文件上传漏洞、编辑器漏洞和IIS高版本漏洞及防御(三)
这是作者的系列网络安全自学教程,主要是关于安全工具和实践操作的在线笔记,特分享出来与博友共勉,希望您们喜欢,一起进步.前文分享了文件上传漏洞和IIS6.0解析漏洞,包括PHP345文件绕过上传.Win ...
- fckeditor漏洞_三十,文件上传漏洞、编辑器漏洞和IIS高版本漏洞及防御
一.编辑器漏洞 1.编辑器 编辑器属于第三方软件,它的作用是方便网站管理员上传或编辑网站上的内容,类似我们电脑上的Word文档. 编辑器通常分为两种情况: (1) 不需要后台验证,可以直接在前台访问且 ...
- glew java_使用GLEW在win环境下创建支持高版本OpenGL 上下文
BOOL Cgl::CreateMultiSample(HWND hwnd, BOOL bCreateZBuffer)/*by ZhouZhuo 2014.06.23 凹凸纹理 启动多采样抗锯齿 */ ...
- 【OpenGL游戏开发之二】OpenGL常用API
OpenGL常用API 开发基于OpenGL的应用程序,必须先了解OpenGL的库函数.它采用C语言风格,提供大量的函数来进行图形的处理和显示.OpenGL库函数的命名方式非常有规律.所有OpenGL ...
- OpenGL教程 用2D图形介绍OpenGL
OpenGL教程 用2D图形介绍OpenGL 1.设置OpenGL 要设置OpenGL,取决于您的编程平台,请阅读: 如何在C / C ++中编写OpenGL程序. 如何在Java中编写OpenGL程 ...
- 【OpenGL】八、初始化 OpenGL 渲染环境 ( 导入 OpenGL 头文件 | 链接 OpenGL 库 | 将窗口设置为 OpenGL 窗口 | 设置像素格式描述符 | 渲染绘制 ) ★
文章目录 一.导入 OpenGL 的两个头文件 二.链接 OpenGL 库 三.将 Windows 桌面窗口改成 OpenGL 窗口 四.获取窗口设备 五.设置像素格式描述符 六.设置像素格式 七.创 ...
- opengl java_android graphic(20)—java层OpenGL相关类
在https://zhuanlan.zhihu.com/p/68782491中已经介绍了如何加载EGL和OpenGL具体软硬件实现,其中system\lib\libEGL.so是加载具体实现的桥梁. ...
- OpenGL ES的性能范围(OpenGL ES2.0官方文档)
http://blog.csdn.net/mengtnt/article/details/7773304 OpenGL ES 1.1和OpengGL ES2.0的规范中,都定义了每种实现必须支持的最低 ...
- opengl png图片 qt_QT中使用OpenGL绘图
在之前说道过VS2010中配合OpenGL绘图的问题,这回是想要说说在QT中使用OpenGL,其实两者并无太大区别,因为都是基于C++语言的. 主要是想简要介绍下OpenGL在QT中的使用方法跟一些错 ...
最新文章
- c语言整形数组相加,[c语言]将两个整形升序数组合并为一个升序数组
- Android 三方库lottie、mmkv的使用
- JAVASCRIPT发展历程
- 字符串哈希-BKDRHash
- java数组代表unicode值么,02-Java的数组
- SQL中Case的使用方法(上篇)
- 用友u8怎么导出凭证_老师,用友U8里的凭证如何导出(导出有借贷方向的)?...
- HTC G14解锁S-OFF、刷机、获取ROOT权限
- 小案例:利用Python实现图片上下、左右翻转
- CycleGAN的测试
- JWTUtil工具类使用
- RT-Thread Nano入门学习笔记(2)
- oracle做分页式报表,报表性能优化方案之单数据集分页SQL实现层式报表
- mysql统计没有参加考试的学生名单_sQL SERVER,帮我编写一个存储过程,查询没有参加考试的学生名单,要求显示姓名、学号,具体请补充:...
- 记腾讯的暑期实习面试
- 重命名技巧,支持多个文件夹快速重命名
- linux-tomcat日志清理方案
- 小程序蓝牙开发官方demo--不能发送字符串命令或发送失败10004问题
- 令我“细思极恐”的Faster-R-CNN
- 适合大一大二学生的深度学习实践项目汇总:涵盖图像处理、语音识别、自然语言处理等领域