适用于OpenGL离屏渲染上下文的初始化代码

说明

最近做图像算法,需要用到shader对图像进行处理,用glut会有窗口,不适合写成UT测试用例,需要创建一个无窗口的OpenGL上下文。

代码

这部分代码其实是参考 Android的Skia 模块相关代码写的,适用于 Mac、EGL(Android)、X11(Ubuntu等Linux系统)平台。

h文件

class GLContext
{
public:
    class nativeContext;
    static nativeContext* init(int version=2);
    static void destroy(nativeContext* context);
};

class GLAutoContext
{
    public:
        GLAutoContext()
        {
            mContext = GLContext::init();
        }
        ~GLAutoContext()
        {
            GLContext::destroy(mContext);
        }
    private:
        GLContext::nativeContext* mContext;
};

cpp文件

#include "GL/GLContext.h"
#include <assert.h>

#ifdef GL_BUILD_FOR_ANDROID
#include <EGL/egl.h>
class GLContext::nativeContext
{
    public:
        nativeContext()
        {
            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, 2,
                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);
        }
    ~nativeContext()
    {
        eglMakeCurrent(gDisplay, EGL_NO_SURFACE , EGL_NO_SURFACE , EGL_NO_CONTEXT);
        eglDestroyContext(gDisplay, gContext);
        eglDestroySurface(gDisplay, gSurface);
        eglTerminate(gDisplay);
        gDisplay = EGL_NO_DISPLAY;
    }

    private:
        EGLContext gContext;
        EGLDisplay gDisplay;
        EGLSurface gSurface;
};
#else
#ifdef __APPLE__
#include <OpenGL/OpenGL.h>
class GLContext::nativeContext
{
    public:
        nativeContext()
        {
            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);
        }
        ~nativeContext()
        {
            CGLReleaseContext(gContext);
        }
    private:
        CGLContextObj gContext;
};
#else
#include <GL/glew.h>
#include <GL/glut.h>
#include <X11/Xlib.h>
#include <GL/glx.h>
class GLContext::nativeContext
{
    public:
        nativeContext()
        {
            gDisplay = XOpenDisplay(0);
            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();
        }
        ~nativeContext()
        {
            glXMakeCurrent(gDisplay, 0,0);
            glXDestroyContext(gDisplay, gContext);
            glXDestroyGLXPixmap(gDisplay, gGlxPixmap);
            XFreePixmap(gDisplay, gPixmap);
            XCloseDisplay(gDisplay);
            gDisplay = NULL;
        }
    private:
        GLXContext gContext;
        Pixmap gPixmap;
        GLXPixmap gGlxPixmap;
        Display* gDisplay;
};
#endif
#endif

GLContext::nativeContext* GLContext::init(int version)
{
    return new nativeContext;
}

void GLContext::destroy(nativeContext* context)
{
    delete context;
}
时间: 2024-10-28 20:25:36

适用于OpenGL离屏渲染上下文的初始化代码的相关文章

opengl中如何进行离屏渲染?如何创建比屏幕大的帧缓冲区?

问题描述 opengl中如何进行离屏渲染?如何创建比屏幕大的帧缓冲区? 我现在需要要创建一个9倍于屏幕大小的缓冲区,一次性渲染一个九倍当前屏幕大小的场景然后使用glReadPixel读取这个场景截图的数据(如果我创建的帧缓冲区没有屏幕大,我就没法从缓冲区中使用glReadPixel函数读取到面积足够大的图片,即使我读取的宽度和高度设置为屏幕的3倍,但是读取出来的超出屏幕的范围都是glClear清除出来的颜色,实际的场景没法被渲染到超高屏幕的范围) 首先,这个问题是我在负责一个老项目时候遇到的,这

opengl es离屏渲染问题

问题描述 opengl es离屏渲染问题 我需要创建一个比屏幕打的缓存,我查资料发现有FBO和PBUFFER两种方式,请问离屏渲染时如何将缓存的某一块放到屏幕中显示?我自己找的例子都是将缓存全部放到屏幕里. 另外问一下现在手机都支持FBO吗 解决方案 1.每次draw 都应该在最后eglSwapBuffers(m_pOgles->m_EGLDisplay, m_pOgles->m_EGLSurface);?2.opengl es 1.x 与 2.x的LIB 不应该共用,因为两个lib里面有相同

IOS 性能优化中离屏渲染_IOS

GPU屏幕渲染有以下两种方式: On-Screen Rendering 意为当前屏幕渲染,指的是GPU的渲染操作是在当前用于显示的屏幕缓冲区中进行. Off-Screen Rendering 意为离屏渲染,指的是GPU在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作. 特殊的离屏渲染: 如果将不在GPU的当前屏幕缓冲区中进行的渲染都称为离屏渲染,那么就还有另一种特殊的"离屏渲染"方式: CPU渲染. 如果我们重写了drawRect方法,并且使用任何Core Graphics的技术进行了

java基于OpenGL ES实现渲染实例_java

本文实例讲述了java基于OpenGL ES实现渲染的方法.分享给大家供大家参考.具体如下: 1. Run.java文件: package net.obviam.opengl; import android.app.Activity; import android.opengl.GLSurfaceView; import android.os.Bundle; import android.view.Window; import android.view.WindowManager; public

液晶屏初始化代码怎么用

问题描述 液晶屏初始化代码怎么用 大神们,液晶屏供应商只给了我一份初始化的代码,要怎么做才能使液晶屏工作啊,液晶屏是SPI接口的 解决方案

android4.0之后怎么实现锁屏功能(不改底层代码的情况下)???,请高手指点!!

问题描述 android4.0之后怎么实现锁屏功能(不改底层代码的情况下)???,请高手指点!! android4.0之后怎么实现锁屏功能(不改底层代码的情况下)???,请高手指点!! 解决方案 看一下Android获取系统隐藏服务实现锁屏能够否满足你的需求. 解决方案二: 这个只对4.0以下的版本适用,我的问题还是不能解决,不过还是得谢谢你啦

c++-OpenGL初学,请问我这段代码有错吗?为什么在窗口显示不出来

问题描述 OpenGL初学,请问我这段代码有错吗?为什么在窗口显示不出来 #include #include #include #include #include const GLint screenWidth = 640; const GLint screenHeight = 480; void myInit(void) { glClearColor(1.0, 1.0, 1.0, 0.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluO

ios-didFinishLunchingWithOptions里面为什么没有初始化代码了?

问题描述 didFinishLunchingWithOptions里面为什么没有初始化代码了? 我记得老版本的好像有的 现在新创建怎么没有了.是引入了什么机制导致了不用在这里写初始化代码了? 解决方案 是打发噶嘎多撒阿萨德发士大夫撒饭 解决方案二: 关于C++里面折叠代码的两招 解决方案三: 你曾经创建了Swift文件导致,重新打开xcode试下 解决方案四: 新版本没有了,不过也可以自己添加修改.

c语言-让电脑锁屏并提示密码解屏,这个c程序代码是什么?

问题描述 让电脑锁屏并提示密码解屏,这个c程序代码是什么? 求锁屏代码和解屏代码!解屏的密码自己设置,,在没有输入正确的密码之前,屏幕一直处于锁屏状态! 解决方案 创建一个和屏幕一般大小的窗口,添加ws_ex_topmost属性让窗口一直在最前面 解决方案二: #include <Windows.h> #include <Winuser.h> void main() { LockWorkStation(); } 解决方案三: #include <Windows.h> #