适用于OpenGL离屏渲染上下文的初始化代码
2015-10-15 00:00
671 查看
说明
最近做图像算法,需要用到shader对图像进行处理,用glut会有窗口,不适合写成UT测试用例,需要创建一个无窗口的OpenGL上下文。代码
这部分代码其实是参考 Android的Skia 模块相关代码写的,适用于 Mac、EGL(Android)、X11(Ubuntu等Linux系统)平台。h文件
#ifndef GL_GLCONTEXT_H #define GL_GLCONTEXT_H class 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
版权声明:本文为博主原创文章,未经博主允许不得转载。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories