Writing to a pbuffer

I need to create a texture bindable pbuffer. Then bind it and upload the texture data.

Im sort of stuck.

Here’s how we create the pbuffers(all this code courtesy a reply from Xmas in these forums):

EGLSurface pbuffer[NUM_PBUFFERS];
for (int i = 0; i < NUM_PBUFFERS; ++i)
pbuffer[i] = eglCreatePbufferSurface(eglDisplay, eglConfig, attribs);

And this is what I need to do while rendering(it should be equivalent to glTexSubImage2D+glDrawArrays+glSwapBuffers when using textures alone)

void renderScene()
{
eglMakeCurrent(eglDisplay, pbuffer[writeBuffer], pbuffer[readBuffer], eglContext);
<<<<DRAW to the writepbuffer>>>>
}

Is there anything wrong with the contents of renderScene?
How do I do the <<<<DRAW to the writepbuffer>>>> part?
Is it placed correctly in the function?
And should’nt there be an eglSwapBuffers someplace?

Thanks for your help.

The idea was to use the pbuffer as a texture, not as a render target. So you don’t need the eglMakeCurrent call.

// create pbuffer
EGLint attribs[] = {
  EGL_WIDTH, width,
  EGL_HEIGHT, height,
  EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB,
  EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
  EGL_NONE
};
pbuffer = eglCreatePbufferSurface(eglDisplay, eglConfig, attribs);

// upload data to pbuffer
glBindTexture(GL_TEXTURE_2D, 0);
eglBindTexImage(eglDisplay, pbuffer, EGL_BACK_BUFFER);
glTexImage2D(...); 

// render using pbuffer as texture
// upload data to pbuffer 
glBindTexture(GL_TEXTURE_2D, 0); 
eglBindTexImage(eglDisplay, pbuffer, EGL_BACK_BUFFER); 
glTexImage2D(...); 

If I want to draw some rendering scene to PBuffer,
And I use this PBuffer scene as a texture.

How can I move PBuffer Scene to glTexImage2D(…)?

For drawing some rendering scene to PBuffer,
I guess eglMakeCurrent() be requested… right??

Yes, if you want to render to a pbuffer, you need to make it the current draw surface.

However, akhil is looking for a solution to another problem (see other treads in this forum) where using a pbuffer solely as a texture without ever rendering to it could help.

// create pbuffer

// upload data to pbuffer

glTexImage2D(…);
// render using pbuffer as texture

Just to make sure I am clear as to whats going on here…

A pbuffer resides in video memory like a texture, the difference being pbuffer is expected to be dynamic, whereas texture, static.

So I initialize the pbuffer like so:

pbuffer = eglCreatePbufferSurface(...)
glBindTexture(GL_TEXTURE_2D, 0); // why 0?
eglBindTexImage(eglDisplay, pbuffer, EGL_BACK_BUFFER); 
glTexImage2D(...,0); 

In my “regular update” function, which keeps drawing the scren quad to screen I do this(??):

glBindTexture(GL_TEXTURE_2D, 0); //does this automatically link to the pbuffer or something?
glTexSubImage2D(....,screenbuffer)
glDrawArrays(...);//to draw a quad
eglSwapBuffers(...);

Here is how my app is structured:
in loop:
ul Draw modified objects(not textures) to ScreenBuffer(memcpy’s)
(2) Draw opengles texture objects to screen (glDrawarrays for different textures)
(3) RegularUpdate: Draw the ScreenBuffer (prepared in (1) ) to screen (A glDrawArrays to draw the screenbuffer quad(until know, via a texture, but hopefully soon, using a pbuffer), followed by an eglSwapBuffers)
Then back to (1)[/ul]

First you want to create a pbuffer, bind it to a texture name and set the filter and wrap modes. You only do this once:

pbuffer = eglCreatePbufferSurface(...);
GLuint pbufferTex;
glGenTextures(1, &pbufferTex);
glBindTexture(GL_TEXTURE_2D, pbufferTex);
eglBindTexImage(eglDisplay, pbuffer, EGL_BACK_BUFFER);

// set filter and wrap modes
glTexParameter(...);
...

Note that you need a new/unused texture name because eglBindTexImage deletes the contents of the currently bound texture. I used 0 above simply because it’s the name of the default texture, which is rarely used.

Whenever you want to update the pbuffer, use this:

glBindTexture(GL_TEXTURE_2D, pbufferTex);
glTexSubImage2D(...);

Note that you must use glTexSubImage2D, otherwise the pbuffer binding would be released. So the example in my post above is wrong.
Of course you only need to call glBindTexture if the texture isn’t bound already.

And when you want to render something with that texture:

glBindTexture(GL_TEXTURE_2D, pbufferTex);
// set up render states, texenv, vertex arrays, etc.
glEnable(GL_TEXTURE_2D);
...

glDrawArrays(...);

If you want to clean up nicely:

eglReleaseTexImage(eglDisplay, pbuffer, EGL_BACK_BUFFER);
eglDestroySurface(eglDisplay, pbuffer);
glDeleteTextures(1, &pbufferTex);

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.