Visualising normal vectors only colouring model, OpenGL

  c++, geometry-shader, opengl, shader

I am currently trying to use a geometry shader to visualize the normal vectors of a 3D model in OpenGL but instead of doing this, it is just changing the color of my model to be a flat yellow color. I’ll post the code for my shaders below as well as some other code for loading my shaders and displaying my models too. Any help would be greatly appreciated thank you!

Shaders code:

    //Create vertex shader for visNorm
    const GLchar* vertexShaderVN =
        "#version 410n " 
        "uniform mat4 u_Projection;            " 
        "attribute vec3 a_Position;            " 
        "attribute vec2 a_Texcord;               " 
        "attribute vec3 in_Normal;               " 
        "                                       " 
        "varying vec2 v_Texcord;                 " 
        "varying vec3 v_FragPos;                 " 
        "varying vec3 v_Normal;                 " 
        "out VS_OUT {          " 
        "vec3 normal;            " 
        "} vs_out;            " 
        "uniform mat4 u_View;                  " 
        "uniform mat4 u_Model;                 " 
        "void main()               " 
        "{                " 
        "v_FragPos = vec3(u_Model * vec4(a_Position, 1.0)); " 
        "gl_Position = u_Projection * u_View * u_Model * vec4(a_Position, 1.0); " 

        "mat3 normalMatrix = mat3(transpose(inverse(u_View * u_Model)));                          " 
        "vs_out.normal = normalize(vec3(vec4(normalMatrix * v_Normal, 0.0)));                                      " 
        "} " 
        "                                       ";
    //Create geometry shader for visNorm
    const GLchar* geometryShaderVN =
        "#version 410n " 
        "layout (triangles) in;" 
        "layout (line_strip, max_vertices = 6) out;" 
        "in VS_OUT {" 
        "vec3 normal;" 
        "} gs_in[];" 
        "const float MAGNITUDE = 0.4; " 
        "uniform mat4 u_Projection;            " 
        "void GenerateLine(int index)" 
        "{" 
        "gl_Position = u_Projection * gl_in[index].gl_Position;" 
        "EmitVertex();" 
        "gl_Position = u_Projection * (gl_in[index].gl_Position + vec4(gs_in[index].normal, 0.0) * MAGNITUDE); " 
        "EmitVertex();" 
        "EndPrimitive();" 
        "}" 
        "void main()" 
        "{" 
        "GenerateLine(0);" 
        "GenerateLine(1);" 
        "GenerateLine(2);" 
        "}" 
        "";
    //Create fragment shader for no visNorm
    const GLchar* fragmentShaderSrcVN =
        "#version 410n " 
        "out vec4 FragColor;" 
        "void main()" 
        "{   " 
        "FragColor = vec4(1.0, 1.0, 0.0, 1.0);" 
        "}                          " 
        "                          ";
    GLuint programIdVN = LoadShader(vertexShaderVN, geometryShaderVN, fragmentShaderSrcVN);

Shader loading function code:

GLuint LoadShader(const GLchar* vert, const GLchar* geo, const GLchar* frag)
{
    //Create a new vertex shader, attach source code, compile it and check for errors
    GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShaderId, 1, &vert, NULL);
    glCompileShader(vertexShaderId);
    GLint success = 0;
    glGetShaderiv(vertexShaderId, GL_COMPILE_STATUS, &success);
    //Display any errors that occur in the vertex shader
    if (!success)
    {
        GLint maxLength = 0;
        glGetShaderiv(vertexShaderId, GL_INFO_LOG_LENGTH, &maxLength);
        std::vector<GLchar> errorLog(maxLength);
        glGetShaderInfoLog(vertexShaderId, maxLength, &maxLength, &errorLog.at(0));
        std::cout << &errorLog.at(0) << std::endl;
        throw std::exception();
    }
    //Create a new geometry shader, attach source code, compile it and check for errors
    GLuint geometryShaderId = glCreateShader(GL_GEOMETRY_SHADER);
    glShaderSource(geometryShaderId, 1, &geo, NULL);
    glCompileShader(geometryShaderId);
    glGetShaderiv(geometryShaderId, GL_COMPILE_STATUS, &success);
    //Display any errors that occur in the vertex shader
    if (!success)
    {
        GLint maxLength = 0;
        glGetShaderiv(geometryShaderId, GL_INFO_LOG_LENGTH, &maxLength);
        std::vector<GLchar> errorLog(maxLength);
        glGetShaderInfoLog(geometryShaderId, maxLength, &maxLength, &errorLog.at(0));
        std::cout << &errorLog.at(0) << std::endl;
        throw std::exception();
    }
    //Create a new fragment shader, attach source code, compile it and check for errors
    GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShaderId, 1, &frag, NULL);
    glCompileShader(fragmentShaderId);
    glGetShaderiv(fragmentShaderId, GL_COMPILE_STATUS, &success);
    //Display any errors that occur in the fragment shader
    if (!success)
    {
        GLint maxLength = 0;
        glGetShaderiv(fragmentShaderId, GL_INFO_LOG_LENGTH, &maxLength);
        std::vector<GLchar> errorLog(maxLength);
        glGetShaderInfoLog(fragmentShaderId, maxLength, &maxLength, &errorLog.at(0));
        std::cout << &errorLog.at(0) << std::endl;
        throw std::exception();
    }
    //Create new shader program and attach our shader objects
    GLuint programId = glCreateProgram();
    glAttachShader(programId, vertexShaderId);
    glAttachShader(programId, fragmentShaderId);
    //Ensure the VAO "position" attribute stream gets set as the first position during the link.
    glBindAttribLocation(programId, 0, "a_Position");
    glBindAttribLocation(programId, 1, "a_Texcord");
    glBindAttribLocation(programId, 2, "in_Normal");
    //Perform the link and check for failure
    glLinkProgram(programId);
    glGetProgramiv(programId, GL_LINK_STATUS, &success);
    if (!success)
    {
        throw std::exception();
    }
    //Detach and destroy the shader objects. These are no longer needed because we now have a complete shader program
    glDetachShader(programId, vertexShaderId);
    glDeleteShader(vertexShaderId);
    glDetachShader(programId, fragmentShaderId);
    glDeleteShader(fragmentShaderId);
    //Find uniform locations
    GLint colorloc = glGetUniformLocation(programId, "u_Texcord");
    GLint modelLoc = glGetUniformLocation(programId, "u_Model");
    GLint viewLoc = glGetUniformLocation(programId, "u_View");
    GLint projectionLoc = glGetUniformLocation(programId, "u_Projection");
    if (modelLoc == -1)
    {
        throw std::exception();
    }
    if (projectionLoc == -1)
    {
        throw std::exception();
    }
    return programId;
}

And the model loading code:

LoadModel(programIdNO, cat, textureId1, modelLoc, viewLoc, projectionLoc, colorloc, winWidth, winHeight, xPos3D + 0 * (winWidth / 50.0f), yPos3D - 0.6, zPos3D - 4.5f, angle, deltaTime);

void LoadModel(GLuint programID, std::shared_ptr<VertexArray> object, GLuint texture, GLuint modelLoc, GLuint viewLoc, GLuint projectionLoc, GLuint colorloc, float winWidth, float winHeight, float xPos, float yPos, float zPos, float angle, float deltaTime)
{
    glUseProgram(programID);
    glBindVertexArray(object->getId());
    glBindTexture(GL_TEXTURE_2D, texture);
    //Prepare the perspective projection matrix
    glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)winWidth / (float)winHeight, 0.1f, 100.f); //!!!
    //Prepare the model matrix
    glm::mat4 model(1.0f);
    model = glm::translate(model, glm::vec3(xPos, yPos, zPos));
    model = glm::rotate(model, glm::radians(angle), glm::vec3(0, 1, 0));
    glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
    glm::mat4 view(1.0f);
    view = glm::translate(view, glm::vec3(0, 0, 5));
    glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(glm::inverse(view)));
    //Make sure the current program is bound
    //Upload the model matrix
    //Upload the projection matrix
    glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));
    glUniform4f(colorloc, 1, 1, 1, 1);
    //Draw 3 vertices (a triangle)
    glDrawArrays(GL_TRIANGLES, 0, object->getVertCount());
}

I’m sure not all this code is necessary but I’m honestly not sure where the issue lies. Thanks in advance and apologies if the solution is painfully simple.

Source: Windows Questions C++

LEAVE A COMMENT