gl*Pointer-function for texture-bindings - opengl

While I looked at the definitions in gl.h ang glext.h I found GL_TEXTURE_BINDING_ARRAY, I think it has to do with VBOs like GL_TEXTURE_COORD_ARRAY does, to enable the buffer set up with glTexCoordArray.
Is there a vbo-function to bind texture-objects in an VBO like you bind the coordinates of the texture with glTexCoordArray? And how to bind it to a triangle/quad and not a single vertex?

Is there a vbo-function to bind texture-objects in an VBO
No.
The most you could do is employ bindless textures and pass those as 64-bit integer values (which presumably you'll pass to the fragment shader). But that still only provides the value per-vertex, not per-primitive. So you'll still have to deal with provoking vertex issues.

Related

render to color attachment with DSA

I want to render into a framebuffer with DSA. However I only got it working when manually binding the framebuffer. Is there a way without bind it?
This is how I thought it would work:
glNamedFramebufferDrawBuffer(m_fbo, GL_COLOR_ATTACHMENT0);
drawCall();
This only works if I use glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); before. How do I do it correctly?
Also, what is the equivalent to glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); for framebuffers with DSA? Again, I can only clear if I previously bound the framebuffer.
The array of draw buffers is not a global state, but rather it is stored per-framebuffer. You are probably familiar with the mechanics of Vertex Array Objects, which maintain separate sets of vertex attribute pointers; draw buffers are analogous to attribute pointers in this situation.
When you make a call to glNamedFramebufferDrawBuffer (m_fbo, ...), you are modifying the state of m_fbo's array without first having to bind m_fbo. You are not actually telling OpenGL to source its color buffer from m_fbo's GL_COLOR_ATTACHMENT0 - that only happens when you bind m_fbo.
In fact, if you think about this critically, this is the only logical way it can work. If you could arbitrarily source buffers from different framebuffer objects, then that would violate validation (completeness). For instance, FBO0 might have a multi-sampled color attachment with 4 samples and FBO1 might have a single-sampled depth attachment. Those are two incompatible buffers, but the only time that is validated is when you try to attach those two images to the same FBO.

OpenGL rendering with multiple textures

Is there a way in OpenGL to render a vertex buffer using multiple independent textures in VRAM without manually binding them (i.e. returning control to the CPU) in between?
Edit: So I'm currently rendering objects with multiple textures by rendering with a single texture, binding a new texture, and repeating, until everything is done. This is slow and requires returning control to CPU and making syscalls for every texture. Is there a way to avoid this switching, and make multiple textures available to the shaders to choose based on vertex data?
As mentioned in the comments on the question, glActiveTexture is the key - samplers in GLSL bind to texture units (e.g. GL_TEXTURE0), not specific texture targets (e.g. GL_TEXTURE2D), so you can bind a GL_TEXTURE2D texture under glActiveTexture(GL_TEXTURE0), another under glActiveTexture(GL_TEXTURE1), and then bind your GLSL sampler2D values to be 0, 1, etc. (NB: do not make your sampler2D values GL_TEXTURE0, GL_TEXTURE1, etc. - they are offsets from GL_TEXTURE0).

OpenGL Order of VBO binding

If I'm trying to do some OpenGL 3.3+ style VBO graphics, is it alright for me to first, enable attribute arrays and set vertex attribute pointers, then in an often refreshing VBO, load fresh data and bind a GL_ARRAY_BUFFER and GL_ELEMENT_ARRAY_BUFFER then call drawELements? I have code that is crashing on drawElements, and I'm wondering if its because the order of my calls is messed up. I'll also mention that this is under the guise of Qt 5.
Whn you set your attribute pointers, it is crucial to have the correct GL_ARRAY_BUFFER bound. The current GL_ARRAY_BUFFER_BINDING at the time of the glVertexAttribPointer() call will become part of that attribute pointer state. It does not matter which GL_ARRAY_BUFFER is bound at draw time (in contrast to the GL_ELEMENT_ARRAY_BUFFER which is relevant for the glDrawElements() family of GL functions.

Find out if GL_TEXTURE_2D is active in shader

I would like to know if GL_TEXTURE_2D is active in the shader.
I am binding a color to the shader as well as the active texture (if GL_TEXTURE_2D is set) and need to combine these two.
So if texture is bound, mix the color and the texture (sampler2D * color) and if no texture is bound, use color.
Or should I go another way about this?
It is not quite clear what you mean by 'GL_TEXTURE_2D is active' or 'GL_TEXTURE_2D is set'.
Please note the following:
glEnable(GL_TEXTURE_2D) has no effect on your (fragment) shader. It parametrizes the fixed function part of your pipeline that you just replaced by using a fragment shader.
There is no 'direct'/'clean' way of telling from inside the GLSL shader whether there is a valid texture bound to the texture unit associated with your texture sampler (to my knowledge).
Starting with GLSL 1.3 you might have luck using textureSize(sampler, 0).x > 0 to detect the presence of a valid texture associated with sampler, but that might result in undefined behavior.
The ARB_texture_query_levels extension does indeed explicitly state that textureQueryLevels(gsampler2D sampler) returns 0 if there is no texture associated with sampler.
Should you go another way about this? I think so: Instead of making a decision inside the shader, simply bind a 1x1 pixel texture of 'white' and unconditionally sample that texture and multiply the result with color, which will obviously return 1.0 * color. That is going to be more portable and faster, too.

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

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.
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.
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
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
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).