/*
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;
}
答案 0 :(得分:1)
你还有什么理由想要使用pbuffers吗?如果您的目标是渲染到屏幕外缓冲区,并将其绑定为纹理以进行渲染显示,则可以使用帧缓冲区对象(FBO)来提高效率。您可以参考discussion in opengl forum here。您可以从这里sgxperf code gist
以简单的方式参考设置FBO的代码顺便说一句,您的代码只会渲染到显示缓冲区,因为您已将screen_surf设为 eglMakeCurrent 调用中的最新当前曲面。