说明

最近做图像算法,需要用到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

版权声明:本文为博主原创文章,未经博主允许不得转载。

更多相关文章

  1. 第七章 使用Intents与Phone Dialer——上
  2. Android(安卓)Studio使用Google Flutter完整教程
  3. 开发Android第三步,签名证书,真机安装编译程序
  4. Android(安卓)WebView优化
  5. Android工具HierarchyViewer 代码导读
  6. 《第一行代码》-第一次学习笔记(第一章).md
  7. android中如何通过代码来开启和关闭移动网络
  8. 为NetBeans添加Andriod平台 .
  9. android 垂直 SeekBar 源代码(VerticalSeekBar)

随机推荐

  1. Android字体简介
  2. android : 控件在代码中设置属性-setWidt
  3. 反编译Android 语法
  4. Android 判断两个图片相等
  5. android关于蓝牙不能传送APK文件
  6. Android ACodec学习
  7. 百度地图 android 线路
  8. 新手安卓socket 连接 内网穿透问题
  9. android 崩溃 重启 捕获异常 并重启应用
  10. Android Studio 3.0 正式版 踩坑记录