OpenGLES pBuffer的用法

使用opengles做项目,在进行2D的游戏中出现了问题,因为之前大部分的2D游戏都使用了缓冲,但opengles 1.x中对于缓冲图像的支持不强,从网上查找了下资料,基本上使用下面两种解决办法(1.x,无FBO):
1、使用PBuffer
2、使用Pixmap
再网上找到的PBuffer代码,试了很多,在我的测试平台上总画不上去。下面是完整的解决办法(对我来讲解决了):
声明部分:

       EGLConfig eglConfigPbuffer = 0;
EGLSurface eglSurfacePbuffer = 0;
GLuint pBufferTexture = 0;
EGLContext eglContextPbuffer = 0;
       


初始化部分,我将这部分放在opengles主要的Surface初始化完整之后进行的:

       static int InitializePBuffer()
{
        EGLint attribListPbuffer[] = {
                EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
                EGL_RED_SIZE, 4,
                EGL_GREEN_SIZE, 4,
                EGL_BLUE_SIZE, 4,
                EGL_DEPTH_SIZE, 16,
                EGL_NONE
        };
 
        EGLint pBufferAttribs[] = {
                        // First we specify the width of the surface...
                EGL_WIDTH, 256,
                // ...then the height of the surface...
                EGL_HEIGHT, 256,
                /* ... then we specifiy the target for the texture
                   that will be created when the pbuffer is created...*/
                EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
                /*..then the format of the texture that will be created
                  when the pBuffer is bound to a texture...*/
               EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
                // The final thing is EGL_NONE which signifies the end.
                EGL_NONE
        };
        EGLint iConfigs = 0; 
        if (!eglChooseConfig(eglDisplay, attribListPbuffer,             \
                             &eglConfigPbuffer, 1, &iConfigs)) {
                return 1;
        }

        eglSurfacePbuffer = eglCreatePbufferSurface(eglDisplay,         \
                                                    eglConfigPbuffer,   \
                                                    pBufferAttribs);
        if (!eglSurfacePbuffer) {
                return 1;
        }
        eglContextPbuffer = eglCreateContext(eglDisplay, eglConfigPbuffer, \
                                             eglContextOpenGLES, KD_NULL);
        eglMakeCurrent(eglDisplay, eglSurfacePbuffer, eglSurfacePbuffer, \
                       eglConfigPbuffer);
        EGLint glConfigID;
        EGLint iWidth, iHeight;
        eglGetConfigAttrib(eglDisplay, eglConfig, EGL_CONFIG_ID, &glConfigID);
        eglQuerySurface(eglDisplay, eglSurfacePbuffer, EGL_WIDTH, &iWidth);
        eglQuerySurface(eglDisplay, eglSurfacePbuffer, EGL_HEIGHT, &iHeight);
        glGenTextures(1, &pBufferTexture);
        glBindTexture(GL_TEXTURE_2D, pBufferTexture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        return 0;
}
       

描绘的方法:

               eglMakeCurrent(eglDisplay, eglSurfacePbuffer,           \
                       eglSurfacePbuffer, eglContextPbuffer);
                               glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        //....other draw
                eglMakeCurrent(eglDisplay, eglWindowSurface,            \
                       eglWindowSurface, eglContextOpenGLES);
                               glBindTexture(GL_TEXTURE_2D, pBufferTexture);
        eglBindTexImage(eglDisplay, eglSurfacePbuffer, EGL_BACK_BUFFER);
                                       glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
                {
                GLfloat x1 = 0.0f;
                GLfloat y1 = 0.0f;
                GLfloat x2 = 1.0f;
                GLfloat y2 = 1.0f;
                GLfloat coord[] = {
                        x1, y1,
                        x2, y1,
                        x1, y2,
                        x2, y2
                };
                GLfloat x_1 = 256.0f;
                GLfloat y_1 = 256.0f;
                GLfloat x_2 = 512.0f;
                GLfloat y_2 = 512.0f;
                GLfloat vertices[] = {
                        x_1, y_1, 0.0f, 
                        x_2, y_1, 0.0f,
                        x_1, y_2, 0.0f,
                        x_2, y_2, 0.0f,
                };
                glBindTexture(GL_TEXTURE_2D, pBufferTexture);
                glVertexPointer(3, GL_FLOAT, 0, vertices);
                glTexCoordPointer(2, GL_FLOAT, 0, coord);
                glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
        }
                eglReleaseTexImage(eglDisplay, eglSurfacePbuffer, EGL_BACK_BUFFER);
       

释放资源:

               eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,      \
                       EGL_NO_CONTEXT);
        eglDestroyContext(eglDisplay, eglContextPbuffer);
        eglDestroySurface(eglDisplay, eglSurfacePbuffer);
        glDeleteTextures(1, &pBufferTexture);
       

现在可以随心所遇的使用缓冲了,只是不知道效率怎样。

发布者

rix

如果连自己都不爱自己,哪还有谁来爱你

  • :-),你是做游戏的么?开发单机游戏还是网游啊~

    • admin

      是啊。目前负责手机游戏。基本上都是单机游戏,虽然我超想跳到网络组去让那帮家伙知道网络游戏应该怎么做。