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

原创 2016年01月22日 00:39:11

说明

最近做图像算法,需要用到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;
}
版权声明:本文为博主原创文章,转载请注明出处:http://blog.csdn.net/jxt1234and2010

opengl微开发之1-从零开始

对OpenGL有一点了解之后,现在开始真正编写代码。 今天的内容:         使用FreeGLUT创建OpenGL的上下文环境         初始化GLEW         创建一个O...
  • xiebaochun
  • xiebaochun
  • 2014年06月07日 09:41
  • 2106

opengl离屏渲染(不需要和窗口绑定,仅当作一个可以渲染一张图片的API使用)+ opencv显示

【原文:http://www.csdn123.com/html/itweb/20130919/127140_127126_127133.htm】 具体过程参考的是这篇BLOG: http://...
  • zhazhiqiang2010
  • zhazhiqiang2010
  • 2015年05月22日 15:29
  • 1501

【菜鸟也能玩转OpenGL】最简单的OpenGL窗口

笔记一中我们介绍了如何用代码创建空的win32窗口,然而创建空的win32窗口只完成了一半的工作,接下来要做的工作是设置Direct3D,从而可以在屏幕上渲染图形。...
  • mni2005
  • mni2005
  • 2014年05月27日 18:59
  • 1828

OpenGL技术之摆脱GLUT的束缚

详细讲解如何使用自己创建的窗口来让OpenGL进行绘制
  • i_dovelemon
  • i_dovelemon
  • 2017年03月12日 13:19
  • 1600

NeHe OpenGL教程第一课 创建一个OpenGL窗口(Wiin32)

(以下内容为我个人按照NeHe英文教程原文,以及一些中文资料做的翻译,由于自己的英语水平有限,可能有些地方翻译的不是很正确,欢迎指正,共同提高,希望以下文档能够给你一些帮助。 注:以下代码均是在Vi...
  • ygc87
  • ygc87
  • 2011年08月31日 01:06
  • 6386

android jni 用c++使用opengles和egl实现离屏渲染

最近在做视频有关的东西,用开源的ffmpeg解码视频,在通过opengl渲染出来,因为有使用到egl就试了试离屏渲染 EGLConfig eglConf; EGLSurface eglSurface...
  • u010302327
  • u010302327
  • 2017年08月04日 20:20
  • 515

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

说明最近做图像算法,需要用到shader对图像进行处理,用glut会有窗口,不适合写成UT测试用例,需要创建一个无窗口的OpenGL上下文。代码这部分代码其实是参考 Android的Skia 模块相关...
  • jxt1234and2010
  • jxt1234and2010
  • 2016年01月22日 00:39
  • 1969

OpenGL系列教程之十二:OpenGL Windows图形界面应用程序

这篇文章是关于使用MVC(Model-View-Controller,模型-视图-控制)框架在windows平台下创建OpenGL图形界面应用程序。MVC框架在GUI(Graphic User Int...
  • wozhengtao
  • wozhengtao
  • 2016年09月26日 17:17
  • 2261

opengl在linux上进行离屏渲染

opengl往往初始化需要使用glutinit之类创建窗口的函数,而对于某些开发,比如ffmpeg中间的滤镜,我们是不希望创建这种窗口的。这时候需要使用离屏渲染的方法在代码中对opengl进行初始化。...
  • defence006
  • defence006
  • 2017年05月24日 11:16
  • 509

Chromium硬件加速渲染的OpenGL上下文绘图表面创建过程分析

GPU命令需要在OpenGL上下文中执行。每一个OpenGL上下文都关联有一个绘图表面,GPU命令就是作用在绘图表面上的。不同用途的OpenGL上下文关联的绘图表面不一样,例如用于离屏渲染的OpenG...
  • Luoshengyang
  • Luoshengyang
  • 2015年10月19日 01:00
  • 12631
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:适用于OpenGL离屏渲染上下文的初始化代码
举报原因:
原因补充:

(最多只允许输入30个字)