创建一个eglpbuffersurface并将其绑定到eglwindowsurface

时间:2013-12-30 06:16:30

标签: c opengl

/*
This Code draws a rectangle on eglwindowsurface , however intention is to draw on         pbuffersurface  which would be binded to eglwindowsurface 
*/

static void _subset_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2,
    GLfloat r, GLfloat g, GLfloat b)
{
    GLfloat v[4][2], c[4][4];
    int i;

    v[0][0] = x1;   v[0][1] = y1;
    v[1][0] = x2;   v[1][1] = y1;
    v[2][0] = x2;   v[2][1] = y2;
    v[3][0] = x1;   v[3][1] = y2;

    for (i = 0; i < 4; i++) {
        c[i][0] = r;
        c[i][1] = g;
        c[i][2] = b;
        c[i][3] = 1.0;
    }

    glVertexPointer(2, GL_FLOAT, 0, v);
    glColorPointer(4, GL_FLOAT, 0, v);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);

    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
}

/*
redraw call swaps the buffers and calls draw rectangle
*/
static void redraw(EGLDisplay dpy, EGLSurface surf, int rot)
{
    GLfloat r, g, b;

    glClearColor(rand()/(float)RAND_MAX,
        rand()/(float)RAND_MAX,
        rand()/(float)RAND_MAX,
        1);

    glClear( GL_COLOR_BUFFER_BIT );

    r = rand()/(float)RAND_MAX;
    g = rand()/(float)RAND_MAX;
    b = rand()/(float)RAND_MAX;

    glPushMatrix();
    glRotatef(rot, 0, 0, 1);
    glScalef(.5, .5, .5);
    _subset_Rectf( -1, -1, 1, 1, r, g, b );
    glPopMatrix();
    eglSwapBuffers( dpy, surf );
    glFinish();
}

/*main functtion*/ 
int main(int argc, char *argv[])
{
    int maj, min;
    EGLContext ctx;
    EGLSurface pbuffer, screen_surf;
    EGLConfig configs[10];
    EGLint numConfigs, i;
    EGLBoolean b;
    const EGLint pbufAttribs[] = {
        EGL_WIDTH, 500,
        EGL_HEIGHT, 500,
        EGL_NONE
    };
    const EGLint screenAttribs[] = {
        EGL_WIDTH, 1024,
        EGL_HEIGHT, 768,
        EGL_NONE
    };

    Window window;
    Display *display;

    if(!(display=XOpenDisplay(NULL))) {
        fprintf(stderr, "rsadhu::ERROR: Could not open display\n");
        exit(1);
    }

    Colormap colormap;
    XVisualInfo *pVisual;

    EGLint count;

    EGLDisplay d = eglGetDisplay(display);

    assert(d);

    if (!eglInitialize(d, &maj, &min)) {
        printf("rsadhu:: demo: eglInitialize failed\n");
        exit(1);
    }

    eglGetConfigs(d, configs, 10, &numConfigs);
    for (i = 0; i < numConfigs; i++) {
        EGLint id, red, depth;
        eglGetConfigAttrib(d, configs[i], EGL_CONFIG_ID, &id);
        eglGetConfigAttrib(d, configs[i], EGL_RED_SIZE, &red);
        eglGetConfigAttrib(d, configs[i], EGL_DEPTH_SIZE, &depth);
        printf("rsadhu:: %2d:  Red Size = %d  Depth Size = %d\n", id, red, depth);
    }

    ctx = eglCreateContext(d, configs[0], EGL_NO_CONTEXT, NULL);
    if (ctx == EGL_NO_CONTEXT) {
        return 0;
    }

    window = CreateWindow("OpenGL ES 2.0 DRI", SIZEX, SIZEY, display, d,configs[0], &colormap, &pVisual); // creates an X Window 

    pbuffer = eglCreatePbufferSurface(d, configs[0], pbufAttribs);

    if (pbuffer == EGL_NO_SURFACE) {
        printf("rsadhu:: failed to create pbuffer\n");
        return 0;
    }
    b = eglMakeCurrent(d, pbuffer, pbuffer, ctx);
    if (!b) {
        printf("rsadhu::make current failed\n");
        return 0;
    }

    b = eglMakeCurrent(d, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);

    screen_surf = eglCreateWindowSurface(d,configs[0],(NativeWindowType)window,NULL);;
    if (screen_surf == EGL_NO_SURFACE) {
        printf("rsadhu::failed to create screen surface\n");
        return 0;
    }

    b = eglMakeCurrent(d, screen_surf, screen_surf, ctx);
    if (!b) {
        printf("rsadhu::make current failed\n");
        return 0;
    }

    glViewport(0, 0, 1024, 768);

    glClearColor(0, 1.0, 0, 1);

    glClear( GL_COLOR_BUFFER_BIT );

    glShadeModel( GL_FLAT );

    while(1)
    {
        static int frames = 0;
        static double timeLast = GetCurrentTimeInSeconds();
        double timeCurrent = GetCurrentTimeInSeconds();

        redraw(d, screen_surf,  i*10 ); // MAIN CAL ....

        frames++;
        if (timeCurrent - timeLast >= 1.0) {
            GLfloat seconds = timeCurrent - timeLast;
            GLfloat fps = frames / seconds;
            printf("rsadhu :: %d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds,fps);
            timeLast = timeCurrent;
            frames = 0;
        }

    }

    eglDestroySurface(d, pbuffer);
    eglDestroyContext(d, ctx);
    eglTerminate(d);

    return 0;
}

1 个答案:

答案 0 :(得分:1)

你还有什么理由想要使用pbuffers吗?如果您的目标是渲染到屏幕外缓冲区,并将其绑定为纹理以进行渲染显示,则可以使用帧缓冲区对象(FBO)来提高效率。您可以参考discussion in opengl forum here。您可以从这里sgxperf code gist

以简单的方式参考设置FBO的代码

顺便说一句,您的代码只会渲染到显示缓冲区,因为您已将screen_surf设为 eglMakeCurrent 调用中的最新当前曲面。