适用于OpenGL离屏渲染上下文的初始化代码
16lz
2021-01-24
说明
最近做图像算法,需要用到shader对图像进行处理,用glut会有窗口,不适合写成UT测试用例,需要创建一个无窗口的OpenGL上下文。
代码
这部分代码其实是参考 Android的Skia 模块相关代码写的,适用于 Mac、EGL(Android)、X11(Ubuntu等Linux系统)平台。
h文件
#ifndef GL_GLCONTEXT_H#define GL_GLCONTEXT_Hclass GLContext {public: static bool init(int version=2); static void destroy();};#endif
cpp文件
#include "GL/GLContext.h"#include <assert.h>#ifdef GL_BUILD_FOR_ANDROID//适用于 Android 和其他使用 EGL 标准的平台#include <EGL/egl.h>static EGLContext gContext;static EGLDisplay gDisplay;static EGLSurface gSurface;bool GLContext::init(int version){ gDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); EGLint majorVersion; EGLint minorVersion; eglInitialize(gDisplay, &majorVersion, &minorVersion); EGLint numConfigs; static const EGLint configAttribs[] = { EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_NONE }; EGLConfig surfaceConfig; eglChooseConfig(gDisplay, configAttribs, &surfaceConfig, 1, &numConfigs); static const EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, version, EGL_NONE }; gContext = eglCreateContext(gDisplay, surfaceConfig, NULL, contextAttribs); static const EGLint surfaceAttribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE }; gSurface = eglCreatePbufferSurface(gDisplay, surfaceConfig, surfaceAttribs); eglMakeCurrent(gDisplay, gSurface, gSurface, gContext); return true;}void GLContext::destroy(){ eglMakeCurrent(gDisplay, EGL_NO_SURFACE , EGL_NO_SURFACE , EGL_NO_CONTEXT); eglDestroyContext(gDisplay, gContext); eglDestroySurface(gDisplay, gSurface); eglTerminate(gDisplay); gDisplay = EGL_NO_DISPLAY;}#else/*适用于Mac平台*/#ifdef __APPLE__#include <OpenGL/OpenGL.h>CGLContextObj gContext;bool GLContext::init(int version){ CGLPixelFormatAttribute attributes[] = { kCGLPFADoubleBuffer, (CGLPixelFormatAttribute)0 }; CGLPixelFormatObj pixFormat; GLint npix; CGLChoosePixelFormat(attributes, &pixFormat, &npix); assert(NULL!=pixFormat); CGLCreateContext(pixFormat, NULL, &gContext); CGLReleasePixelFormat(pixFormat); assert(NULL!=gContext); CGLSetCurrentContext(gContext); return true;}void GLContext::destroy(){ CGLReleaseContext(gContext);}#else/*这个是以前用在Ubuntu系统中的,使用了glew以打开shader功能,适用于 XDisplay*/#include <GL/glew.h>#include <GL/glut.h>#include <X11/Xlib.h>#include <GL/glx.h>static GLXContext gContext;static Pixmap gPixmap;static GLXPixmap gGlxPixmap;static Display* gDisplay = XOpenDisplay(0);bool GLContext::init(int version){ int fbcount; static int visual_attribs[] = { GLX_X_RENDERABLE , True, GLX_DRAWABLE_TYPE , GLX_PIXMAP_BIT, None }; GLXFBConfig *fbc = glXChooseFBConfig(gDisplay, DefaultScreen(gDisplay), visual_attribs, &fbcount); int best_fbc = -1, best_num_samp = -1; int i; for (i = 0; i < fbcount; ++i) { XVisualInfo *vi = glXGetVisualFromFBConfig(gDisplay, fbc[i]); if (vi) { int samp_buf, samples; glXGetFBConfigAttrib(gDisplay, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf); glXGetFBConfigAttrib(gDisplay, fbc[i], GLX_SAMPLES, &samples); if (best_fbc < 0 || (samp_buf && samples > best_num_samp)) best_fbc = i, best_num_samp = samples; } XFree(vi); } GLXFBConfig bestFbc = fbc[best_fbc]; XFree(fbc); XVisualInfo *vi = glXGetVisualFromFBConfig(gDisplay, bestFbc); gPixmap = XCreatePixmap(gDisplay, RootWindow(gDisplay, vi->screen), 10, 10, vi->depth); gGlxPixmap = glXCreateGLXPixmap(gDisplay, vi, gPixmap); XFree(vi); gContext = glXCreateNewContext(gDisplay, bestFbc, GLX_RGBA_TYPE, 0, True); glXMakeCurrent(gDisplay, gGlxPixmap, gContext); glewInit(); return true;}void GLContext::destroy(){ glXMakeCurrent(gDisplay, 0,0); glXDestroyContext(gDisplay, gContext); glXDestroyGLXPixmap(gDisplay, gGlxPixmap); XFreePixmap(gDisplay, gPixmap); gDisplay = NULL; XCloseDisplay(gDisplay);}#endif#endif
版权声明:本文为博主原创文章,未经博主允许不得转载。
更多相关文章
- 第七章 使用Intents与Phone Dialer——上
- Android(安卓)Studio使用Google Flutter完整教程
- 开发Android第三步,签名证书,真机安装编译程序
- Android(安卓)WebView优化
- Android工具HierarchyViewer 代码导读
- 《第一行代码》-第一次学习笔记(第一章).md
- android中如何通过代码来开启和关闭移动网络
- 为NetBeans添加Andriod平台 .
- android 垂直 SeekBar 源代码(VerticalSeekBar)