3

I am compiling this shader with glslangValidator, and am using OpenGL 4.3 Core Profile with the extension GL_ARB_gl_spirv, and using the GLAD webservice to generate function pointers to access the Core OpenGL API, and SDL2 to create the context, if that is of any use.

If I have a fragment shader like so:

#version 430 core

//output Fragment Color
layout (location = 0) out vec4 outFragColor;

//Texture coordinates passed from the vertex shader
layout (location = 0) in vec2 inTexCoord;

uniform sampler2D inTexture;

void main()
{
    outFragColor = texture(inTexture, inTexCoord);
}

How would I be able to set which texture unit inTexture uses?

From what I have read online through documents, I cannot use glGetUniformLocation to get the location of this uniform to use in glUniform1i, because of the fact I am using SPIR-V, instead of GLSL directly.

What would I need to do to set it in a fashion like glUniform1i? Do I need to set the location in the layout modifier? The binding? I've tried to use Uniform Buffer Objects, but apparently sampler2D can only be a uniform.

KapowCabbage
  • 65
  • 1
  • 8
  • 1
    You need a layout and binding for the uniform. For example `layout(binding = 1) uniform sampler2D inTexture;` – D-RAJ Jan 03 '21 at 07:00
  • @DhirajWishal After that, how would I edit the ```sampler2D``` from my main program? – KapowCabbage Jan 03 '21 at 07:02
  • @DhirajWishal Would I just enter ```1``` into ```glUniform```? – KapowCabbage Jan 03 '21 at 07:05
  • I personally don't have much experience with OpenGL but in Vulkan. So I guess you can get it to work with `glUniform1i` even though i'm not 100% sure about it. From what i do know, its not an easy task to use SPIR-V to work with OpenGL. – D-RAJ Jan 03 '21 at 07:06
  • 1
    @DhirajWishal It appears to work so far with ```glUniform1i```. Thanks for your help. – KapowCabbage Jan 03 '21 at 07:09

1 Answers1

5

Since GLSL 4.20, you have the ability to set the binding point for any opaque type like samplers from GLSL code directly. This is done through the binding layout qualifier:

layout(binding = #) uniform sampler2D inTexture;

The # here is whatever binding index you want to use. This is the index you use when binding the texture: glActiveTexture(GL_TEXTURE0 + #). That is, you don't need to use glProgramUniform to set the uniform's value anymore; you already set it in the shader.

If you want to modify the binding dynamically (and you shouldn't), GLSL 4.30 offers the ability to set the location for any non-block uniform value via the location layout qualifier:

layout(location = #) uniform sampler2D inTexture;

This makes # the uniform's location, which you can pass to any glProgramUniform call.

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