Windows 上使用 glad 加载浏览器的 LibEGL.dll 和 LibGLESV2.dll,测试 EGL 在 Windows 上的实现,代码:

复制代码
  1 #include <stdio.h>
  2 
  3 #include "include/glad/egl.h"
  4 #include "include/glad/gles3.2.h"
  5 
  6 #define STB_IMAGE_WRITE_IMPLEMENTATION
  7 #include "include/stb_image_write.h"
  8 
  9 #ifdef GLAD_GLES2
 10 #include "src/egl.c"
 11 #include "src/gles3.2.c"
 12 #endif
 13 
 14 /* 这个例子是 Windows 平台测试谷歌的 Angle 库,PBuffer 的创建。用到了 GLAD 的 EGL 和 GLES 2.x、GLES 3.x 模块。
 15  *
 16  * 用到的 Angle 的动态链接库是:
 17  *
 18  *   d3dcompiler_47.dll
 19  *   libEGL.dll
 20  *   libGLESv2.dll
 21  *
 22  * 这三个 dll 很多软件带了,比如 vscode(64位),很多浏览器的目录,也可以自己下载 Angle 的源码编译。 
 23  */
 24 
 25 /* HDC      可以是任意窗口的 HDC,相当于 Windows 平台的 display,这里可以设置成 NULL(无窗口依赖)
 26  *
 27  */
 28 int test_pbuffer(HDC hdc)
 29 {
 30     int n;
 31 
 32     #if defined(GLAD_EGL_H_) || defined(GLAD_EGL)
 33 
 34     // 先用 GLAD 加载 EGL 的函数
 35     n = gladLoaderLoadEGL(0);
 36     if (n == 0) {
 37         printf("egl> gladLoaderLoadEGL() = %d\n", n);
 38         return -1;
 39     }
 40     else {
 41         printf("egl> gladLoaderLoadEGL() = %d\n", n);
 42     }
 43     #endif
 44 
 45     // EGL 版本参数
 46     EGLint ai32ContextAttribs[] = {
 47         EGL_CONTEXT_CLIENT_VERSION, 2,
 48         EGL_NONE, EGL_NONE
 49     };
 50 
 51     // 获取 EGL display
 52     EGLDisplay eglDisplay = eglGetDisplay((EGLNativeDisplayType) hdc);
 53 
 54     // 初始化 EGL
 55     eglInitialize(eglDisplay, 0, 0);
 56 
 57     // 绑定 OpenGL ES API。这个函数在 Windows 平台是空,OpenGL ES 的函数稍后我们用 GLAD 加载
 58     if (eglBindAPI) {
 59         eglBindAPI(EGL_OPENGL_ES_API);
 60     }
 61 
 62     // 设置 OpenGL ES 初始化参数
 63     EGLint pi32ConfigAttribs[] = {
 64         //EGL_SURFACE_TYPE, EGL_WINDOW_BIT,         // 绘制到窗口,配合上面的 HDC 句柄
 65         EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,          // 使用 PBuffer
 66         EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,    // OpenGL ES 版本
 67         EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,      // 颜色缓冲格式
 68         EGL_BLUE_SIZE, 8,
 69         EGL_GREEN_SIZE, 8,
 70         EGL_RED_SIZE, 8,
 71         EGL_ALPHA_SIZE, 8,
 72         EGL_DEPTH_SIZE, 24,
 73         EGL_STENCIL_SIZE, 8,
 74         EGL_NONE, EGL_NONE
 75     };
 76 
 77     // 选择 display 设置属性
 78     int iConfigs;
 79     EGLConfig eglConfig;
 80     eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &iConfigs);
 81 
 82     if (iConfigs != EGL_TRUE) {
 83         printf("egl> Error: eglChooseConfig(): config not found.\n");
 84         return -1;
 85     }
 86 
 87     // 创建 PBuffer 表面
 88     EGLint pBufferAttribs[] = {
 89         EGL_WIDTH, 800,
 90         EGL_HEIGHT, 600,
 91         EGL_LARGEST_PBUFFER, EGL_TRUE,
 92         EGL_NONE, EGL_NONE
 93     };
 94     EGLSurface eglSurface = eglCreatePbufferSurface(eglDisplay, eglConfig, pBufferAttribs);
 95 
 96     if (!eglSurface) {
 97         printf("egl> pbuffer surface create failed.\n");
 98         return -1;
 99     }
100 
101     // 创建 OpenGL ES 上下文
102     EGLContext eglContext;
103     eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, ai32ContextAttribs);
104 
105     // 绑定 OpenGL ES 上下文
106     eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
107 
108     // 使用 GLAD 加载 GLES 的函数
109     #if defined(GLAD_GLES2_H_) || defined(GLAD_GLES2)
110     n = gladLoaderLoadGLES2();
111     if (n == 0) {
112         printf("egl> gladLoaderLoadGLES2() = %d\n", n);
113         return -1;
114     }
115     else {
116         printf("egl> gladLoaderLoadGLES2() = %d\n", n);
117     }
118     #endif
119 
120     //
121     // 从这里开始,可以使用普通的 OpenGL (ES) 函数
122     //
123 
124     // 清屏
125     glClearColor(0.0, 0.5, 1.0, 1.0);
126     glClear(GL_COLOR_BUFFER_BIT);
127 
128     // 读取颜色缓冲区
129     uint8_t* buf = (uint8_t*) malloc(800 * 600 * 4);
130     glReadPixels(0, 0, 800, 600, GL_RGBA, GL_UNSIGNED_BYTE, buf);
131 
132     // 使用 stb_image_write 保存图片,如果程序目录看到一张蓝色背景的图片,说明测试成功。
133     stbi_write_png("test.png", 800, 600, 4, buf, 0);
134     printf("gles> save test.png ok.\n");
135 
136     delete buf;
137 
138     // EGL 的反转缓冲区
139     eglSwapBuffers(eglDisplay, eglSurface);
140 
141     // 取消绑定上下文
142     eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
143 
144     // 释放 EGL 环境
145     eglDestroyContext(eglDisplay, eglContext);
146     eglDestroySurface(eglDisplay, eglSurface);
147     eglTerminate(eglDisplay);
148 
149     printf("egl> test ok.\n");
150 }
151 
152 int main(int argc, char* argv[])
153 {
154     test_pbuffer(NULL);
155 
156     system("pause");
157 
158     return 0;
159 }
复制代码