Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a framebuffer as a vertex buffer without moving the data to the CPU

Tags:

opengl

In OpenGL, is there a way to use framebuffer data as vertex data without moving the data through the CPU? Ideally, a framebuffer object could be recast as a vertex buffer object directly on the GPU. I'd like to use the fragment shader to generate a mesh and then render that mesh.

like image 226
May Oakes Avatar asked Apr 03 '10 03:04

May Oakes


People also ask

What is vertex buffer method?

A vertex buffer object (VBO) is an OpenGL feature that provides methods for uploading vertex data (position, normal vector, color, etc.) to the video device for non-immediate-mode rendering.

What function creates a vertex buffer object?

Vertex buffer object (VBO) creates "buffer objects" for vertex attributes in high-performance memory on the server side and provides same access functions to reference the arrays, which are used in vertex arrays, such as glVertexPointer(), glNormalPointer(), glTexCoordPointer(), etc.

What is an OpenGL buffer?

Buffer Objects are OpenGL Objects that store an array of unformatted memory allocated by the OpenGL context (AKA the GPU). These can be used to store vertex data, pixel data retrieved from images or the framebuffer, and a variety of other things.

How do frame buffers work?

In a technique known generally as double buffering or more specifically as page flipping, the framebuffer uses half of its memory to display the current frame. While that memory is being displayed, the other half of memory is filled with data for the next frame.


4 Answers

There's a couple ways you could go about this, the first has already been mentioned by spudd86 (except you need to use GL_PIXEL_PACK_BUFFER, that's the one that's written to by glReadPixels).

The other is to use a framebuffer object and then read from its texture in your vertex shader, mapping from a vertex id (that you would have to manage) to a texture location. If this is a one-time operation though I'd go with copying it over to a PBO and then binding into GL_ARRAY_BUFFER and then just using it as a VBO.

like image 142
a stray cat Avatar answered Nov 01 '22 15:11

a stray cat


Just use the functions to do the copy and let the driver figure out how to do what you want, chances are as long as you copy directly into the vertex buffer it won't actually do a copy but will just make your VBO a reference to the data.

The main thing to be careful of is that some drivers may not like you using something you told it was for vertex data with an operation for pixel data...

Edit: probably something like the following may or may not work... (IIRC the spec says it should)

int vbo;
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, vbo);
// use appropriate pixel formats and size
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);

glEnableClientState(GL_VERTEX_ARRAY);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
// draw stuff

Edited to correct buffer bindings thanks Phineas

like image 37
Spudd86 Avatar answered Nov 01 '22 13:11

Spudd86


The specification for GL_pixel_buffer_object gives an example demonstrating how to render to a vertex array under "Usage Examples".

The following extensions are helpful for solving this problem:

GL_texture_float - floating point internal formats to use for the color buffer attachment GL_color_buffer_float - disable automatic clamping for fragment colors and glReadPixels GL_pixel_buffer_object - operations for transferring pixel data to buffer objects

like image 24
May Oakes Avatar answered Nov 01 '22 13:11

May Oakes


If you can do your work in a vertex/geometry shader, you can use transform feedback to write directly into a buffer object. This also has the option of skip the rasterizer and fragment shading.

Transform feedback is available as EXT_transform_feedback or core version since GL 3.0 (and the ARB equivalent).

like image 24
Dr. Snoopy Avatar answered Nov 01 '22 15:11

Dr. Snoopy