Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the reasoning behind OpenGL texture units as opposed to regular buffers and uniforms?

Tags:

c++

opengl

I am very new to the OpenGL API and just discovered textures and how to use them. The generated texture buffers are not bound in the same way as regular uniforms are bound and instead use glActiveTexture, followed by a bind rather than just supplying the texture to the shaders via glUniform as we do with other constants.

What is the reasoning behind this convention?

The only reason I can think of is to utilize the graphics card's full potential and texture processing capabilities instead of just binding buffers directly. Is this correct reasoning, or is it simply the way the API was implemented?

No reasoning is given on the official wiki, just says that it's weird: "Binding textures for use in OpenGL is a little weird" https://www.khronos.org/opengl/wiki/Texture

like image 340
Timothy Avatar asked Aug 27 '17 15:08

Timothy


People also ask

What is texture unit OpenGL?

A texture is an OpenGL Object that contains one or more images that all have the same image format. A texture can be used in two ways: it can be the source of a texture access from a Shader, or it can be used as a render target.

What is texture buffering?

A Buffer Texture is a one-dimensional Texture whose storage comes from a Buffer Object. They are used to allow a shader to access a large table of memory that is managed by a buffer object.

What are uniform buffers?

A Buffer Object that is used to store uniform data for a shader program is called a Uniform Buffer Object. They can be used to share uniforms between different programs, as well as quickly change between sets of uniforms for the same program object.

Why are OpenGL textures upside down?

You probably noticed that the texture is flipped upside-down! This happens because OpenGL expects the 0.0 coordinate on the y-axis to be on the bottom side of the image, but images usually have 0.0 at the top of the y-axis.


1 Answers

Your question can be interpreted in two ways.

"Why do we bind textures to the context rather than to the shader?"

Because that would make it needlessly difficult to have multiple shaders use the same textures. Note that pretty much no graphics API directly attaches the texture to the program. Not D3D of any version, not Metal, nor even Vulkan.

Textures are resources used by shaders. But they are not part of the shader.

"Why do we treat textures differently from a general array of values?"

In modern OpenGL, shaders have access to several different kinds of resources: UBOs, SSBOs, textures, and images. Each of these kinds of resources ultimately represents a potentially distinct part of the graphics hardware.

A storage block is not just a uniform block that can be bigger. Storage buffers represent the shader doing global memory accesses, while uniform blocks are often copied directly into the shader execution units. In the latter case, accessing their data is much faster, but that also means that you're limited by how much storage those execution units can have.

Now, this is not true for all hardware (AMD's GCN hardware treats the two almost identically, which is why their UBO limits are so large). But it is true of much hardware.

Textures are even more complicated, because implementations need to be able to store their data in an optimal way for performance reasons. As such, texture storage formats are opaque. They're even opaque in ostensibly low-level APIs like Vulkan. Oh sure, linear formats exist, but implementations aren't required to let you read from them at all.

So textures are not just constant arrays.

like image 75
Nicol Bolas Avatar answered Sep 20 '22 10:09

Nicol Bolas