4

Is there a way to run a shader on Buffer Object and modifying it with some other data with shader?

In other words: Is there a way to create uniform global variable in shader and modifiable?

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
User is deleted
  • 157
  • 2
  • 11

2 Answers2

8

Yes, though it depends on your hardware. All of these mechanisms require hardware capable of GL 3.x or above.

Transform Feedback

This allows you to capture the results of vertex processing in one or more buffer objects.

This is the most crude mechanism, because each vertex shader can only access the vertex data it is given as input, and can only write to the output vertex. So the shader can't access the vertex before or after it. Also, the amount of outputting is quite limited, usually only 4 output values from GL 3.x-class hardware.

You could use a geometry shader to increase some of your reading and writing abilities; feedback happens after the VS or GS.

Render to Buffer Object

Buffer textures are textures that use a buffer object for storage. They're like really big 1D textures.

Being a texture, you can freely attach them to a Framebuffer Object and render to it.

The downside of this technique, beyond the difficulty of rendering to an image with 1 pixel of height, is that you're dealing with the rasterizer. It's not perfectly exact. You can use gl_FragCoord to know where you are in the fragment, but if you want to write significantly different data to different areas of the image, there may be difficulties.

The other problem is that FBO sizes are limited by the viewport dimensions, usually around 8192 to 16384. That's not a lot of room to write; at best, you can write 65536 individual floats (if the buffer texture uses the GL_RGBA32F format). So you're very restricted in how much data you can actually write.

Image Load/Store

ARB_shader_image_load_store, core in GL 4.2, represents the ability of a shader to arbitrarily read from and write to image data. Combined with buffer textures (textures that use buffer objects as storage), you can arbitrarily read from and write to buffer objects.

The big downside, besides the hardware requirements, is that there's no free lunch. By using Image Load Store, you effectively give up on all of OpenGL's automatic memory synchronization systems. So you have to do all synchronizations manually for writes and reads. This is a big pain and you can very easily screw it up and get undefined behavior without having a clue as to why. It might work on one platform, but not out on a user's machine.

You have to be very careful with this stuff.

Shader Storage Buffer Object

Shader storage buffer objects are really just Image Load/Store from buffer textures, only with a much nicer interface. It's like defining structs and just accessing them.

The same downsides as for Image Load/Store apply. Also, SSBO is really new; only NVIDIA implements it yet, and even then, only in beta drivers.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
1

I'm not too knowledgeable about exactly how it's done, but I know that modifying a VBO from a shader is called Transform Feedback. You'll need OpenGL >=3.0, or OpenGL >= 2.0 with the NV_transform_feedback or EXT_transform_feedback extension.

If you need more general computation power, you could try doing some OpenCL/OpenGL interop...

Robert Rouhani
  • 14,512
  • 6
  • 44
  • 59
  • Transform Feedback was originally written against 2.0 as an extension [LINK](http://www.opengl.org/registry/specs/EXT/transform_feedback.txt) – Bartek Banachewicz Dec 01 '12 at 17:55
  • My computer is too old (OpenGL 2.1) I'll try the OpenCL one... – User is deleted Dec 01 '12 at 17:58
  • ^^ ah, I was looking at when it became part of the core profile... I'll be more specific – Robert Rouhani Dec 01 '12 at 17:58
  • @FijiWiji: If your GPU can't handle OpenGL 3.x, then it *certainly* can't handle OpenCL. You need a minimum of a 3.x-class GPU to get compute functionality out of OpenCL. – Nicol Bolas Dec 01 '12 at 18:46
  • @RobertRouhani Can you make an example with `NV_transform_feedback` or `EXT_transform_feedback` I just can't find any tutorials no it... – User is deleted Dec 01 '12 at 19:29
  • It's basically the same API with `NV` or `EXT` at the end of everything (i.e. `glBeginTransformFeedbackNV`) – Robert Rouhani Dec 01 '12 at 19:37
  • @RobertRouhani When I try to call it I get an exception. When I tried `printf("glBeginTransformFeedbackNV is %s.\n",wglGetProcAddress("glBeginTransformFeedbackNV")?"supported":"not supported");` I got `glBeginTransformFeedbackNV` weird... This GPU isn't support anything or what XD? – User is deleted Dec 01 '12 at 20:48
  • That just means your GPU is too old to support transform feedback. You can double check this by seeing if either extension appears in [OpenGL Extension Viewer](http://www.realtech-vr.com/glview/download.php). Try the "Render to Buffer Object" method in @NicolBolas's answer. If you don't have `ARB_texture_buffer_object` or `EXT_texture_buffer_object`, then you basically can't do what you want to do and should consider redesigning and finding workarounds. – Robert Rouhani Dec 01 '12 at 21:06
  • 1
    @FijiWiji: If your GPU does not support OpenGL 3.x, then it doesn't support transform feedback or buffer textures. Your GPU is too old to do what you want. And any GPU that old won't be able to use OpenCL. – Nicol Bolas Dec 01 '12 at 21:19