AnsweredAssumed Answered

OpenGL Shader Queries:

Question asked by calioraged on Mar 19, 2019

*** Beginner question - some terminology may not be correct ***

I will relay my understanding of OpenGL shaders in this post in the hope that members can confirm the areas where I am correct and redress the areas where my understanding falls short.

Firstly, here is my shader:

#shader vertex#version 330 core layout(location = 0) in vec4 position;   layout(location = 1) in vec2 tex_coord;   out vec2 v_tex_coord;void main(){     gl_Position = position;        v_tex_coord = tex_coord; };#shader fragment#version 330 core layout(location = 0) out vec4 colour; in vec2 v_tex_coord; uniform sampler2D u_Texture;void main(){     vec4 tex_colour = texture(u_Texture,v_tex_coord);     colour = tex_colour;};

First Query:

I have been following a tutorial on shaders and have replicated the code used in the tutorial. My program renders a square, onto which a texture (image) is placed. I have bound the vertex position coordinates to the first attribute index of the vertex array, and the texture coordinates to the second attribute index of the vertex array *1*.  The program works without any issues, but there are some aspects which have me confused and I therefore seek clarification from forum members.

The vertex shader features the below lines:

layout(location = 0) in vec4 position;   layout(location = 1) in vec2 tex_coord;

 From my understanding, these lines are essentially saying: "take the layout of attribute 0 and place it in the 'position' variable" and "take the layout of attribute 1 and place in the 'tex_coord' variable". This makes sense to me since the vertex shader determines the position of each vertex on the screen. However, in the fragment shader, I am more dubious:

layout(location = 0) out vec4 colour;

If the lines in the previous snippet are saying "take the layout of attribute x and place it in the 'y' variable", then what exactly is the above line saying? Specifically, why is the layout from the position attribute (attribute 0) being used and not the texture attribute (attribute 1)? 

Second Query:

I understand that the input variable in the fragment shader (v_tex_coord) is supplied by the output variable from the vertex shader (which originally gathered its data from the layout of attribute 1). But how is the final colour for each pixel here actually set? In the main() function of the fragment shader, the texture() function is used. From what I have gathered this function samples the colour of each pixel in the texture.

Once a texture has been bound to a specific slot, we can set the uniform outside of the shader with glUniform() by returning the location of the uniform variable (location of "u_Texture" in this case) and then linking it to the previously bound slot. Presumably this is the step which links together the texture image and the uniform - meaning that 'u_Texture' now has access to the texture image via the slot to which it was bound (please correct me if I am wrong here).  The next assumption is that the texture() function will sample the corresponding colour value through its parameters ('u_Texture' - which now contains the texture image (or at least has access to the slot to which the texture image is bound) and 'v_tex_coord' which contains the coordinates to which the texture should be rendered). 

Here is the part that confuses me most:

The outcome of the texture() function is returned to the vec4 variable 'tex_colour' which then reassigns its value to the output vec4 variable 'colour'. What was the point in this last step? 'tex_colour' already contained the result of the texture() function so why does it then need to be reassigned to 'colour'? 'colour' is not predefined by OpenGL, I can change the name to 'the_colour', 'a_colour' or 'the_ice_cream_man' and the texture image is still rendered perfectly fine. Is it the case that the variable defined as the output in the fragment shader will be used to render the colour of each pixel regardless of its name? I suppose that the reason I ask this is because the 'gl_Position' variable in the vertex shader which sets the position appears to be a variable predefined by OpenGL whereas in the fragment shader this doesn't appear to be the case with the variable which sets the colour... some clarification of this would be greatly appreciated. 


*1* - terminology may be wrong here but essentially I have used glVertexAttribPointer() to set the below vertices position coordinates to attribute 0 and the below texture position coordinates to attribute 1. The full program consists of 16 files and it didn't want to include source code for each file because most of it is irrelevant to the questions I am asking.

float positions[]    =     {         // vertices     // texture  -0.5F,-0.5F,     0.0F,0.0F, // x and y coordinates   0.5F,-0.5F,     1.0F,0.0F,   0.5F, 0.5F,     1.0F,1.0F,  -0.5F, 0.5F,     0.0F,1.0F};