首页 > 解决方案 > 可视化向量范数的问题(OpenGL C++)

问题描述

我正在用 C++ 制作模型查看器,并尝试使用顶点、片段和几何着色器在模型上可视化我的向量规范,但是它只在屏幕上显示几行而不是每个向量一个,这是我的着色器代码:

    //Create vertex shader for visNorm
    const GLchar* vertexShaderVN =
        "#version 410\n " \
        "attribute vec3 a_Position;            " \
        "attribute vec3 in_Normal;               " \
        "                                       " \
        "out VS_OUT {          " \
        "vec3 normal;            " \
        "} vs_out;            " \
        "uniform mat4 u_View;                  " \
        "uniform mat4 u_Model;                 " \
        "void main()               " \
        "{                " \
        "gl_Position = 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 * in_Normal, 0.0)));                                      " \
        "} " \
        "                                       ";
    //Create geometry shader for visNorm
    const GLchar* geometryShaderVN =
        "#version 410\n " \
        "layout (triangles) in;" \
        "layout (line_strip, max_vertices = 6) out;" \
        "in VS_OUT {" \
        "vec3 normal;" \
        "} gs_in[];" \
        "const float MAGNITUDE = 1.0; " \
        "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 410\n " \
        "out vec4 FragColor;" \
        "void main()" \
        "{   " \
        "FragColor = vec4(1.0, 1.0, 0.0, 1.0);" \
        "}                          " \
        "                          ";
    GLuint programIdVN = LoadShader(vertexShaderVN, geometryShaderVN, fragmentShaderSrcVN);

我的加载着色器的代码:

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, geometryShaderId);
    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)
    {
        GLint maxLength = 0;
        glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &maxLength);
        std::vector<GLchar> errorLog(maxLength);
        glGetProgramInfoLog(programId, maxLength, &maxLength, &errorLog.at(0));
        std::cout << &errorLog.at(0) << std::endl;
        //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, geometryShaderId);
    glDeleteShader(geometryShaderId);
    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;
}

如果有人对为什么这不能按预期工作有任何想法,那将非常感谢!

标签: c++openglfragment-shadervertex-shadergeometry-shader

解决方案


推荐阅读