正文:

  话不多说,直接上代码:

#include<Windows.h>
#include<GL/GL.h>
#pragma comment(lib,"opengl32.lib")
//注册win32窗口类
BOOL win32_regist_class(const char* class_name)
{WNDCLASSEXA cs ={sizeof(WNDCLASSEXA),CS_HREDRAW | CS_VREDRAW,[](HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)->LRESULT{switch (msg){case WM_NCCREATE:{SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)((LPCREATESTRUCTA)lparam)->lpCreateParams);break;};case WM_PAINT:{PAINTSTRUCT ps;BeginPaint(hwnd, &ps);EndPaint(hwnd, &ps);break;}case WM_ERASEBKGND://阻止窗口重绘,不然当窗口从边界移回来时会看到背景色{return TRUE;}case WM_DESTROY:{PostQuitMessage(0);break;}default:break;}return DefWindowProcA(hwnd, msg, wparam, lparam);},0,0,(HINSTANCE)GetModuleHandleA(nullptr),nullptr,LoadCursorA(nullptr,IDC_ARROW),(HBRUSH)COLOR_WINDOW,nullptr,class_name,nullptr};return RegisterClassExA(&cs);
}
//创建win32窗口
HWND win32_create(const char*class_name,const char*window_name,int x, int y, int width, int height)
{return CreateWindowExA(0, class_name,window_name, WS_OVERLAPPEDWINDOW | WS_VISIBLE,x, y, width, height,nullptr, nullptr, GetModuleHandle(nullptr), nullptr);
}
//获取可用于OpenGL绘制的DC
HDC win32_get_gl_dc(HWND hwnd)
{PIXELFORMATDESCRIPTOR pfd = {};pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);pfd.nVersion = 1;pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;auto hdc = GetDC(hwnd);auto pixelFormat = ChoosePixelFormat(hdc, &pfd);if (!pixelFormat){ReleaseDC(hwnd, hdc);return nullptr;}if (!SetPixelFormat(hdc, pixelFormat, &pfd)){ReleaseDC(hwnd, hdc);return nullptr;}return hdc;
}
//处理win32消息
BOOL win32_peek_message(HWND hwnd)
{MSG msg;if (PeekMessageA(&msg, hwnd, 0, 0, PM_REMOVE)){if (msg.message == WM_QUIT)return FALSE;TranslateMessage(&msg);DispatchMessageA(&msg);}return TRUE;
}
//创建OpenGL API
HGLRC gl_create(HDC hdc)
{auto hglrc = wglCreateContext(hdc);if (!hglrc)return nullptr;if (!wglMakeCurrent(hdc, hglrc))return nullptr;//******获取高版本API(glew的最主要功能就是这是一步)/*在这个里获取会用到的opengl api,这些API名称可以去opengl官网查询因为需要的功能不复杂,不需要使用着色器,GL1.0版本的API足够用了。所以这里并没有获取所有高版本的API,只获取了一个glCreateShader作为例子。*/auto glCreateShader=(GLuint(__stdcall*)(GLenum type))wglGetProcAddress("glCreateShader");//******获取高版本API结束return hglrc;
}
//渲染
void render(HWND hwnd, HDC hdc, HGLRC hglrc)
{RECT rc;GetClientRect(hwnd, &rc);wglMakeCurrent(hdc, hglrc);//关联gl的DC到窗口的hdc。如果是单DC,只需关联一次即可glViewport(0, 0, rc.right, rc.bottom);//设置视口glClearColor(0.4f, 0.5f, 0.4f, 0);//设置清屏时的颜色glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清屏。这里清掉颜色缓冲区与深度缓冲区//******以下内容为1.0版本绘制方法,高版本的不建议这样绘制了,尽量使用glDraw*系列函数以提高性能//设置点glBegin(GL_TRIANGLE_STRIP); //以画线方式绘制,glColor3f(1, 0, 0); glVertex2f(0.0f, 0.0f);//中心端点,为红色glColor3f(0, 1, 0); glVertex2f(0.5f, 0.5f);//到左上角中点端点,为绿色glColor3f(0, 0, 1); glVertex2f(0.0f, 0.5f);//到上方中点端点,为蓝色glEnd();//glDrawArrays(GL_LINES, 0, 2);//经过测试,1.0版本不需要调用此函数
}
int main(int argc, const char* argv[])
{win32_regist_class("test");auto hwnd = win32_create("test", "test", 100, 100, 500, 400);auto hdc = win32_get_gl_dc(hwnd);auto hglrc = gl_create(hdc);while (true){if(win32_peek_message(nullptr)==FALSE)break;render(hwnd, hdc, hglrc);SwapBuffers(wglGetCurrentDC());//翻转缓冲区(因为使用了双缓冲,必须要翻转才能看到绘制结果)}
}

  整个代码约140行,不算多。这是上次QQ群里一个人问我之后我改了之前的代码写出来的,逻辑比之前强很多,个人感觉优势在于不再需要乱七八糟的第三方库,可以作为学习用,在自己获取高版本GL的API后也可以简单取代glut。
  主要部分是win32_get_gl_dc(HWND hwnd)这个函数。这个函数执行成功了就可以继续后续的OpenGL操作,不然的话就会出现GL上下文创建失败的情况,导致后续的OpenGL操作无效。

附:gles32 API获取文件说明

  实现我已经放到我的资源里:_gles32.h,直接点击下载就行,只有一个头文件,是从GLES32官网上扒了gles32头文件下来改了实现的。
用法:

  1. 先调用上面的gl_create函数创建gl环境,不然会像gl_create代码里的注释说的一样接下来的操作失败(glew里包含有这步,所以可以直接用);
gl_load_api(wglGetProcAddress);

至于头文件包含

#include"_gles32.h"

这个不用我多说了吧。
  上面的wglGetProcAddress这个就是win32下用来获取高版本GL API的平台函数,之所以放到这里来作为参数传入而不写在_gles32.h里就是希望让_gles32.h平台独立化,所以gles32.h里是没有任何与win32相关的API的,唯一一个相关的已经被放到参数这来了。
  实现这个主要是因为原来用的glew还需要下载一个库,研究了下glew发现也没什么特别的,就去gles官网上扒了头文件下来自己改了下就完成实现了。这样下以后就可以不用再去包含一个第三方库。
  实际上我还实现了一个_gl_wrapper.h文件来对_gles32.h做包装,里面包含了着色器的操作封装及其他东西,但我觉得这不是OpenGL的核心东西,所以没放到资源里。
  完整的调用代码如下:

#include<Windows.h>
#include<GL/GL.h>
//包含头文件
#include"_gles32.h"
#pragma comment(lib,"opengl32.lib")int main(int argc, const char* argv[])
{win32_regist_class("test");auto hwnd = win32_create("test", "test", 100, 100, 500, 400);auto hdc = win32_get_gl_dc(hwnd);//哈哈,你没看错,这就是上面那个例子的main函数,就改了这里auto hglrc = wglCreateContext(hdc);wglMakeCurrent(hdc, hglrc);//加载高版本GL API(就一个函数)gl_load_api(wglGetProcAddress);//加载API结束,接下来就可以正常使用高版本的GLES API了,//例如glCreateShader、glCreateProgram之类的。while (true){if(win32_peek_message(nullptr)==FALSE)break;render(hwnd, hdc, hglrc);SwapBuffers(wglGetCurrentDC());//翻转缓冲区(因为使用了双缓冲,必须要翻转才能看到绘制结果)}
}

  (吐槽一下,CSDN的markdown排版有点难用啊,我用typora编辑的时候没这么蛋疼,而且typora和CSDN用的数学公式渲染器不是同一个,导致我在typora上编辑好的公式没法直接复制过来用)

win32原生API实现OpenGL例子(无glew,glut等第三方依赖库)相关推荐

  1. AngularJS2.0 hello world例子——引入这么多额外的依赖库真是很忧伤啊

    初识Angular2 写一个Angular2的Hello World应用相当简单,分三步走: 1. 引入Angular2预定义类型 import {Component,View,bootstrap} ...

  2. vue使用高德地图原生API实现省份添加背景色,文字标注;实现点聚合和点标记点击之后出现信息窗体的功能

    功能描述:初始状态下,可以看到所有数据在地图上的分布的省份及相应的分布数量,点击点标注可以弹出对应的详细信息. 该例子使用了高德地图原生API去实现上述功能,效果图如下: 下面附上实现步骤: 1. v ...

  3. Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1

    Elastic search入门到集群实战操作详解(原生API操作.springboot整合操作)-step2 https://blog.csdn.net/qq_45441466/article/de ...

  4. InternetOpen\InternetOpenUrl\InternetReadFile 等相关Win32 网络API 使用详细说明

    InternetOpen\InternetOpenUrl\InternetReadFile 等相关Win32 网络API 使用详细说明 摘要 这篇技术性文章讨论了如何利用Microsoft Win32 ...

  5. win32 debug api 原理

    在Win32中自带了一些API函数,它们提供了相当于一般调试器的大多数功能,这些函数统称为Win32调试API(Win32 Debug API).利用这些API可以做到加载一个程序或捆绑到一个正在运行 ...

  6. win32 调试 API 学习总结

    Win32调试API原理 来自<软件技术加密内幕>和chm版本不太一样 在Win32中自带了一些API函数,它们提供了相当于一般调试器的大多数功能,这些函数统称为Win32调试API(Wi ...

  7. IOS7使用原生API进行二维码和条形码的扫描

    使用IOS7原生API进行二维码条形码的扫描 IOS7之前,开发者进行扫码编程时,一般会借助第三方库.常用的是ZBarSDK,IOS7之后,系统的AVMetadataObject类中,为我们提供了解析 ...

  8. Zookeeper_原生API操作(一)

    讲了zookeeper的简单的介绍,以及环境搭建,还有zkClient的使用,基本上很简单,作为HelloWorld,今天继续往下走,既然已经把简介和环境搭建完了,然后一会来说说配置,配置也没有什么说 ...

  9. 使用JavaScript调用手机平台上的原生API

    我之前曾经写过一篇文章使用Cordova将您的前端JavaScript应用打包成手机原生应用,介绍了如何使用Cordova框架将您的用JavaScript和HTML开发的前端应用打包成某个手机平台(比 ...

最新文章

  1. 北大青鸟口碑好才真的好
  2. 从源码分析DEARGUI之add_input_float和4
  3. 如何:从 Windows 窗体 DataGridView 控件中移除自动生成的列
  4. 总结一些关于操作数据库是sql语句还是存储过程问题
  5. 通过Dapr实现一个简单的基于.net的微服务电商系统(九)——一步一步教你如何撸Dapr之OAuth2授权...
  6. ftl有三种映射地址_浅谈以太坊中的三种“树”
  7. 莫烦Tensorflow教程(1~14)(转)
  8. excel两个表格数据对比_教你如何使用excel快速对比多项数据
  9. 067 Pytohn文件的两种用途
  10. Monkey Test - 命令
  11. MDClub 轻量级网论坛源码
  12. 最直白的编译原理-基础知识(清华-王书3版)
  13. 导出excel 手动拼装复杂表头
  14. 智能化测试技术探索与实践——AAAS/IEEE Fellow、北京大学讲席教授谢涛阿里行
  15. 苹果7手机html5测试,测试开发之前端——No7.HTML5中的鼠标事件
  16. iOS开发笔记(IOS7回归)
  17. 10uF的电容能滤除什么频率的电源纹波?
  18. 雅虎非法监控邮件内容 在美国面临集体诉讼
  19. uniapp微信小程序富文本编辑器组件
  20. .NET开源工作流RoadFlow-快速入门

热门文章

  1. 【1945. 字符串转化后的各位数字之和】
  2. 推荐几个比较骚的技术公众号【文末福利】
  3. 不选主元的矩阵三角分解法
  4. 手机网站点击手机号码直接拨号
  5. 阴阳师辅助(基于按键精灵)
  6. 新增诊所19804家 | 私营诊所要如何主动?才能被患者选择
  7. css3新增属性sticky
  8. android9.0设置默认输入法
  9. 大数据破获网售假耐克案
  10. java学习之SpringBoot2