0

I am having a propblem figuring out what is going on in my simplest of shaders. Here is my vertex shader:

#version 410 core

in vec3 position;
in vec2 textureCoords;
out vec2 color;

void main(void)
{

    gl_Position = vec4(position.x, position.y, position.z, 1.0);
    color = vec2(1.0,0.5);
}

And the fragment shader:

#version 410 core

in vec2 color;
out vec4 out_color;

void main(void)
{
    out_color = vec4(0.0, 1.0, 0.0, 1.0);
}

Note, the color variable being passed out from the VS to FS doesnt really do anything. These shaders give me the expected result which is the following image:

Render from the original shaders above

Now, if i merely pass the textureCoords from the VS to the FS using the color variable without any change to the FS it shifts my image to the right. So the modified VS (and the ONLY modification to shaders) is:

#version 410 core

in vec3 position;
in vec2 textureCoords;
out vec2 color;

void main(void)
{
    gl_Position = vec4(position.x, position.y, position.z, 1.0);
    color = textureCoords;
}

This gives the unexpected following render (triangle shifts to the top-right):

After the modification to the VS

I dont understand why this is happening since I am not even using the color var in the FS.

Why is this happening ? I am merely trying to pass a vec2 to the FS ! What am I not seeing here ?

Here is some additional info: GL Information: Supported GL version: 4.1 NVIDIA-10.16.34 355.10.05.35f05 Supported shading lang: 4.10

Complete code here: complete code Entry point is tests.cpp

Here are my current vertex arrays:

GLfloat PossibleVertices[] = {
    // Left bottom triangle
     0.0f,  0.5f, 0.0f, // v0
    -0.5f,  -0.5f, 0.0f, // v1
     0.5f,  -0.5f, 0.0f
};

GLuint Indices[] = {
    0, 1, 2
};

GLfloat TextureCoords[] = 
{
    0.5f, 1.0f, // v0
    0.0f, 0.0f, // v1
    1.0f, 0.0f
};

// Load data to VAO
LoadToVAO(PossibleVertices, 9, Indices, 3, TextureCoords, 6);

... 

LoadToVAO
(
    GLfloat Positions[], GLuint PosArrySize,
    GLuint Indices[], GLuint IndArrySize,
    GLfloat TexCoords[], GLuint TCArrySize
)
{
    GLuint VaoID = CreateVAO();
    BindIndicesBufferVBO(Indices, IndArrySize); // Buffer Index - optimization
    StoreDataInAttrList(0, 3, Positions, PosArrySize);
    StoreDataInAttrList(1, 2, TexCoords, TCArrySize);
    UnbindVAO();
    CGCore::RawModel* ret = new CGCore::RawModel(VaoID, IndArrySize);
    return ret;
}

Here is the function called for actually storing data to the VAO. Called for both Vertex arrays:

void CGCore::Loader::StoreDataInAttrList(GLuint AttrNumber, GLuint AttrSize, GLfloat Data[], GLuint DataSize)
{
    GLuint VboID; 
    glGenBuffers(1,&VboID);
    VBOContainer.push_back(VboID);
    glBindBuffer(GL_ARRAY_BUFFER, VboID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*DataSize, Data, GL_STATIC_DRAW);
    glVertexAttribPointer(AttrNumber, AttrSize, GL_FLOAT, GL_FALSE, 0, (void*) 0); // write to VAO
    glBindBuffer(GL_ARRAY_BUFFER, 0); // unbind current VBO
}

Here is the attr binding code:

void BindAttributes()
{
    BindAttribute(0, "position");
    BindAttribute(1, "textureCoords"); 
}

// and also ... 

void BindAttribute(int Attrib, const GLchar* VarName)
{
    glBindAttribLocation(ProgramID, Attrib, VarName);
}

And finally the rendering code:

void CGCore::Renderer::Render(CGCore::TexturedModel* TexturedModelObj)
{
    CGCore::RawModel* Model = TexturedModelObj->GetModel();
    glBindVertexArray(Model->GetVaoID());
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glActiveTexture(GL_TEXTURE0);
    glDrawElements( GL_TRIANGLES, Model->GetVertexCount(), GL_UNSIGNED_INT, (void*) 0);
    glBindTexture(GL_TEXTURE_2D, TexturedModelObj->GetTexture()->GetTextureID());
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glBindVertexArray(0);
}

Sorry for the long post. Thanx!

Taner Selim
  • 196
  • 1
  • 9
  • 1
    Please show the drawing code. My guess is that you screwed up the data or the attribute pointers. – BDL Apr 08 '17 at 18:36
  • I edited in a github link to the drawing code. But still, how does assigning an in vec2 to an out vec2 shift vertices if none of the vec2s are being used in any way? And why the downvote its a legit q? – Taner Selim Apr 08 '17 at 18:47
  • 1
    There can, for example, be a problem with the attribute locations. If you don't use `textureCoords` in the VS, then it is inactive and will be optimized away. Now when you use it, then it is active and will get a location assigned. If you do not handle these locations correctly in your code, you might draw something else. – BDL Apr 08 '17 at 19:06
  • I added code from actuall passing of the arrays! I hope this is more helpful now – Taner Selim Apr 08 '17 at 19:38
  • Now it exactly looks as what I have said before: You are drawing the `TextureCoords` instead of the `PossibleVertices`. Most probably `position` has location 0 in your first program and location 1 when texture coordinates are used. Since you nowhere ask which variable is associated with each location or define them by a location qualifier, that can happen. – BDL Apr 08 '17 at 19:42
  • Can you be a little bit more specific plz? If you are talking about binding, I do have them: BindAttribute(0, "position"); BindAttribute(1, "textureCoords"); – Taner Selim Apr 08 '17 at 19:47
  • 2
    You are calling that **AFTER** linking. This calls only influence locations when called **BEFORE** linking. And please post *all the relevant code* here. I'm not going to look something up in your repo again. – BDL Apr 08 '17 at 19:50
  • I have added i think everything relevant regarding the drawing. Its scattered across different files thats why i gave a link. But its OK man, thank you for trying! You don't have to if its frustrating. I appretiate the effort. – Taner Selim Apr 08 '17 at 20:16

1 Answers1

-1

After experimenting, going through tons of OpenGL documentation and so on I finally solved my issue. Contrary to some comments, the problem was in the vertex shader. I.e. the declaration of the in variables. The following change in the VS gives me the expected output:

#version 410 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 textureCoords;

out vec2 TexCoord;

void main()
{
    gl_Position = vec4(position, 1.0f);
    TexCoord = textureCoords;
}

So what I am doing is explicitly specifying the location of the in params in the VOA when declaring the in params. I guess it has to do with the version of the vertex shader (v4.10) but im not sure. In any case specify the attr locations by declaring the in vars like this layout (location = X) in type var_name

Taner Selim
  • 196
  • 1
  • 9
  • You are drawing the wrong conclusions. @BDL's comments were spot-on. The fact that you can work around your wrong usage of `glBindAttribLocation` by using an alternative way to specify these locations does not imply that using `glBindAttribLocation` is wrong, or that GLSL 4.10 is behaving differently in that regard. – derhass Apr 09 '17 at 16:51