OpenGL 几何着色器三角形不会绘制而没有错误

OpenGL Geomentry Shader triangle wont draw with no errors

本文关键字:绘制 有错误 何着色 三角形 OpenGL      更新时间:2023-10-16

我正在尝试编写一个采用单个 vec4 位置并创建一个三角形的几何着色器。程序链接正确,但是当绘制调用发生时,屏幕上不会显示任何内容。

我有一个工作版本,在我自己计算三角形后,我将顶点交给 OpenGL,但我希望让着色器工作,以便可以在 GPU 上创建三角形(以及最终的其他形状)。这是我的代码:

void TriSprite::v_InitShader(void)
{
    if(_shaderProgram != NULL) return;
    //=====Vertex Shaders=====
    //This is used when only colors, not textures are used to render
    //a pirmitive
    static const GLchar* _vertexShaderSource[] = 
    {
        "#version 430 core                                                              n"
        "                                                                               n"
        "layout (location = 0) in vec4 position;                                        n"
        "layout (location = 1) in vec4 color;                                           n"
        "layout (location = 2) in float width;                                          n"
        "layout (location = 3) in float height;                                         n"                 
        "uniform mat4 transform_mat;                                                    n"
        "                                                                               n"
        "out vec4 vs_color;                                                             n"
        "out vec4 vs_dimnsions;                                                         n"
        "                                                                               n"
        "void main(void)                                                                n"
        "{                                                                              n"
        //=====Top=====
        "   gl_Position = transform_mat * position;                                     n"
        "   vs_color = color;                                                           n"
        "   vs_dimnsions = vec4(width, height, 0.0, 0.0);                               n"
        "}                                                                              n"
    };
    //=====Geomtry Shader=====
    static const GLchar* _geometryShaderSource[] =
    {
        "#version 430 core                                                              n"
        "                                                                               n"
        "layout(points) in;                                                             n"
        "layout(triangle_strip, max_vertices = 2) out;                                  n"
        "                                                                               n"
        "in vec4 vs_color[1];                                                           n"
        "in vec4 vs_dimnsions[1];                                                       n"
        "                                                                               n"
        "out vec4 gs_color;                                                             n"
        "                                                                               n"
        "void main()                                                                    n"
        "{                                                                              n"
        //Bottom Right
        "   gl_Position = gl_in[0].gl_Position + vec4(vs_dimnsions[0].x, -vs_dimnsions[0].y, 0, 0);         n"
        "   EmitVertex();                                                                                   n"
        //Top
        "   gl_Position = gl_in[0].gl_Position + vec4(0.0, vs_dimnsions[0].y, 0.0, 0.0);                    n"
        "   EmitVertex();                                                                                   n"
        //Bottom Left
        "   gl_Position = gl_in[0].gl_Position + vec4(-vs_dimnsions[0].x, -vs_dimnsions[0].y, 0.0, 0.0);    n"
        "   EmitVertex();                                                                                   n"
        "                                                                               n"
        "   EndPrimitive();                                                             n"
        "   gs_color = vs_color[0];                                                     n"
        "}                                                                              n"
    };

    //=====Fragment Shaders=====
    //This is used when only colors, not textures are used to render
    //a pirmitive
    static const GLchar* _fragmentShaderSource[] = 
    {
        "#version 430 core                                                              n"
        "                                                                               n"
        "in vec4 gs_color;                                                              n"
        "out vec4 color;                                                                n"
        "                                                                               n"
        "void main(void)                                                                n"
        "{                                                                              n"
        "   color = gs_color;                                                           n"
        "}                                                                              n"
    };
    //=====Compile Shaders=====
    GLuint vertextShaderProgram;
    GLuint geometryShaderProgram;
    GLuint fragmentShaderProgram;
    vertextShaderProgram = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertextShaderProgram, 1, _vertexShaderSource, NULL);
    glCompileShader(vertextShaderProgram);
    geometryShaderProgram = glCreateShader(GL_GEOMETRY_SHADER);
    glShaderSource(geometryShaderProgram, 1, _geometryShaderSource, NULL);
    glCompileShader(geometryShaderProgram);
    fragmentShaderProgram = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShaderProgram, 1, _fragmentShaderSource, NULL);
    glCompileShader(fragmentShaderProgram);
    _shaderProgram = glCreateProgram();
    glAttachShader(_shaderProgram, vertextShaderProgram);
    glAttachShader(_shaderProgram, geometryShaderProgram);
    glAttachShader(_shaderProgram, fragmentShaderProgram);
    glLinkProgram(_shaderProgram);
    GLint isLinked = 0;
    glGetProgramiv(_shaderProgram, GL_LINK_STATUS, &isLinked);
    //=====Error Checking=====
    if(isLinked == GL_FALSE)
    {
        GLint maxLength = 0;
        glGetProgramiv(_shaderProgram, GL_INFO_LOG_LENGTH, &maxLength);
        //The maxLength includes the NULL character
        std::vector<GLchar> infoLog(maxLength);
        glGetProgramInfoLog(_shaderProgram, maxLength, &maxLength, &infoLog[0]);
        for(auto i = infoLog.begin(); i != infoLog.end(); ++i)
        {
            std::cout << *i ;
        }
        std::cout << "n";
        //The program is useless now. So delete it.
        glDeleteProgram(_shaderProgram);
    }
    //=====Clean up=====
    glDeleteShader(vertextShaderProgram);
    glDeleteShader(geometryShaderProgram);
    glDeleteShader(vertextShaderProgram);
}

和渲染调用:

    void Renderer::AddToBatch(GLuint shader, Vec2& pos, U32 w, U32 h, Col& c)
{
    if(_currentShader != shader)
    {
        Draw();
        _currentShader = shader;
        glUseProgram(_currentShader);
    }
    if(_currentBatchSize + 1 >= _maxBatchSize) { Draw(); }
    _vertices.push_back(pos.GetX());
    _vertices.push_back(pos.GetY());
    _vertices.push_back(pos.GetZ());
    _vertices.push_back(pos.GetW());
    _xDimensions.push_back((F32)w);
    _yDimensions.push_back((F32)h);

    _colors.push_back(c.GetRed());
    _colors.push_back(c.GetGreen());
    _colors.push_back(c.GetBlue());
    _colors.push_back(c.GetAlpha());
    ++_currentBatchSize;
}
    void Renderer::Draw(void)
{
    if(_currentBatchSize == 0) return;
    GLuint buffers[4];
    glGenBuffers(4, buffers);
    glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
    glBufferData(GL_ARRAY_BUFFER, (sizeof(F32) * _vertices.size()), &_vertices[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
    glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
    glBufferData(GL_ARRAY_BUFFER, (sizeof(F32) * _colors.size()), &_colors[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, NULL);

    glBindBuffer(GL_ARRAY_BUFFER, buffers[2]);
    glBufferData(GL_ARRAY_BUFFER, (sizeof(U32) * _xDimensions.size()), &_xDimensions[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 0, NULL);

    glBindBuffer(GL_ARRAY_BUFFER, buffers[3]);
    glBufferData(GL_ARRAY_BUFFER, (sizeof(U32) * _yDimensions.size()), &_yDimensions[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(3);
    glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, 0, NULL);

    glDrawArrays(GL_TRIANGLES, 0, _currentBatchSize);
    _currentBatchSize = 0;
}

任何见解或帮助将不胜感激。

static const GLchar* _vertexShaderSource[] = 
    {
        "#version 430 core                                                              n"
        "                                                                               n"
        "layout (location = 0) in vec4 position;                                        n"
        "layout (location = 1) in vec4 color;                                           n"                 
        "uniform mat4 transform_mat;                                                    n"
        "                                                                               n"
        "out vec4 vs_color;                                                             n"
        "                                                                               n"
        "void main(void)                                                                n"
        "{                                                                              n"
        "   gl_Position = transform_mat * position;                                     n"
        "   vs_color = color;                                                           n"
        "}                                                                              n"
    };
static const GLchar* _fragmentShaderSource[] = 
    {
        "#version 430 core                                                              n"
        "                                                                               n"
        "in vec4 vs_color;                                                              n"
        "out vec4 color;                                                                n"
        "                                                                               n"
        "void main(void)                                                                n"
        "{                                                                              n"
        "   color = vs_color;                                                           n"
        "}                                                                              n"
    };

您会注意到,在此示例中,我直接向着色器提供顶点,基本上只是转换它们。此版本有效。这是基于评论的更新版本。这仍然不起作用:

static const GLchar* _vertexShaderSource[] = 
    {
        "#version 430 core                                                              n"
        "                                                                               n"
        "layout (location = 0) in vec4 position;                                        n"
        "layout (location = 1) in vec4 color;                                           n"
        "layout (location = 2) in float width;                                          n"
        "layout (location = 3) in float height;                                         n"                 
        "uniform mat4 transform_mat;                                                    n"
        "                                                                               n"
        "out vec4 vs_color;                                                             n"
        "out vec4 vs_dimensions;                                                        n"
        "                                                                               n"
        "void main(void)                                                                n"
        "{                                                                              n"
        "   gl_Position = transform_mat * position;                                     n"
        "   vs_color = color;                                                           n"
        "   vs_dimensions = transform_mat * vec4(width, height, 0.0, 0.0);              n"
        "}                                                                              n"
    };
static const GLchar* _geometryShaderSource[] =
    {
        "#version 430 core                                                              n"
        "                                                                               n"
        "layout(points) in;                                                             n"
        "layout(triangle_strip, max_vertices = 3) out;                                  n"
        "                                                                               n"
        "in vec4 vs_color[1];                                                           n"
        "in vec4 vs_dimensions[1];                                                      n"
        "                                                                               n"
        "out vec4 gs_color;                                                             n"
        "                                                                               n"
        "void main()                                                                    n"
        "{                                                                              n"
        "   gs_color = vs_color[0];                                                     n"
        //Top
        "   gl_Position = gl_in[0].gl_Position + vec4(0.0, vs_dimensions[0].y, 0.0, 0.0);                   n"
        "   EmitVertex();                                                                                   n"
        //Bottom Right
        "   gl_Position = gl_in[0].gl_Position + vec4(vs_dimensions[0].x, -vs_dimensions[0].y, 0, 0);       n"
        "   EmitVertex();                                                                                   n"
        //Bottom Left
        "   gl_Position = gl_in[0].gl_Position + vec4(-vs_dimensions[0].x, -vs_dimensions[0].y, 0.0, 0.0);  n"
        "   EmitVertex();                                                                                   n"
        "                                                                               n"
        "   EndPrimitive();                                                             n"
        "}
static const GLchar* _fragmentShaderSource[] = 
    {
        "#version 430 core                                                              n"
        "                                                                               n"
        "in vec4 gs_color;                                                              n"
        "out vec4 color;                                                                n"
        "                                                                               n"
        "void main(void)                                                                n"
        "{                                                                              n"
        "   color = gs_color;                                                           n"
        "}                                                                              n"
    };

void Renderer::Draw(void)
{
    if(_currentBatchSize == 0) return;
    GLuint buffers[4];
    glGenBuffers(4, buffers);
    glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
    glBufferData(GL_ARRAY_BUFFER, (sizeof(F32) * _vertices.size()), &_vertices[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
    glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
    glBufferData(GL_ARRAY_BUFFER, (sizeof(F32) * _colors.size()), &_colors[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, NULL);

    glBindBuffer(GL_ARRAY_BUFFER, buffers[2]);
    glBufferData(GL_ARRAY_BUFFER, (sizeof(U32) * _xDimensions.size()), &_xDimensions[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 0, NULL);

    glBindBuffer(GL_ARRAY_BUFFER, buffers[3]);
    glBufferData(GL_ARRAY_BUFFER, (sizeof(U32) * _yDimensions.size()), &_yDimensions[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(3);
    glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, 0, NULL);

    glDrawArrays(GL_TRIANGLES, 0, _currentBatchSize);
    _currentBatchSize = 0;
}

在逐步完成代码并花一些时间查看几何着色器的进出内容后,我发现了我的问题。这是语法错误、普遍缺乏理解和一些逻辑错误的结合。以下是所有有效的最终代码:

static const GLchar* _vertexShaderSource[] = 
    {
        "#version 430 core                                                              n"
        "layout (location = 0) in vec4 position;                                        n"
        "layout (location = 1) in vec4 color;                                           n"
        "layout (location = 2) in vec2 dimensions;                                      n"
        "uniform mat4 transform_mat;                                                    n"
        "out vec4 gs_color;                                                             n"
        "out vec4 gs_dimensions;                                                        n"
        "void main(void)                                                                n"
        "{                                                                              n"
        "   gl_Position = transform_mat * position;                                     n"
        "   gs_color = color;                                                           n"
        "   gs_dimensions = transform_mat * vec4(dimensions.x, dimensions.y, 0.0, 0.0);                                 n"
        "}                                                                              n"
    };
//=====Geomtry Shader=====
    static const GLchar* _geometryShaderSource[] =
    {
        "#version 430 core                                                              n"
        "layout(points) in;                                                             n"
        "layout(triangle_strip, max_vertices = 3) out;                                  n"
        "in vec4 gs_color[];                                                            n"
        "in vec4 gs_dimensions[];                                                       n"
        "out vec4 fs_color;                                                             n"
        "void main()                                                                    n"
        "{                                                                              n"
        "   fs_color = gs_color[0];                                                     n"
        //Top
        "   gl_Position = gl_in[0].gl_Position + vec4(0.0, gs_dimensions[0].y, 0.0, 0.0);                   n"
        "   EmitVertex();                                                                                   n"
        //Bottom Right
        "   gl_Position = gl_in[0].gl_Position + vec4(-gs_dimensions[0].x, -gs_dimensions[0].y, 0, 0);      n"
        "   EmitVertex();                                                                                   n"
        //Bottom Left
        "   gl_Position = gl_in[0].gl_Position + vec4(gs_dimensions[0].x, -gs_dimensions[0].y, 0.0, 0.0);   n"
        "   EmitVertex();                                                                                   n"
        "   EndPrimitive();                                                             n"
        "}                                                                              n"
    };

    //=====Fragment Shaders=====
    //This is used when only colors, not textures are used to render
    //a pirmitive
    static const GLchar* _fragmentShaderSource[] = 
    {
        "#version 430 core                                                              n"
        "in vec4 fs_color;                                                              n"
        "out vec4 color;                                                                n"
        "void main(void)                                                                n"
        "{                                                                              n"
        "   color = fs_color;                                                           n"
        "}                                                                              n"
    };

以下是 draw 和 AddToBatch 函数的外观:

void Renderer::AddToBatch(GLuint shader, Vec2& pos, U32 w, U32 h, Col& c)
{
    if(_currentShader != shader)
    {
        Draw();
        _currentShader = shader;
        glUseProgram(_currentShader);
        _SetOrthoProjection();
    }
    if(_currentBatchSize + 1 >= _maxBatchSize) { Draw(); }
    _vertices.push_back(pos.GetX());
    _vertices.push_back(pos.GetY());
    _vertices.push_back(pos.GetZ());
    _vertices.push_back(pos.GetW());
    _dimensions.push_back((F32)w);
    _dimensions.push_back((F32)h);
    _colors.push_back(c.GetRed());
    _colors.push_back(c.GetGreen());
    _colors.push_back(c.GetBlue());
    _colors.push_back(c.GetAlpha());
    ++_currentBatchSize;
}

void Renderer::Draw(void)
{
    if(_currentBatchSize == 0) return;
    GLuint buffers[4];
    glGenBuffers(4, buffers);
    glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
    glBufferData(GL_ARRAY_BUFFER, (sizeof(F32) * _vertices.size()), &_vertices[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
    glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
    glBufferData(GL_ARRAY_BUFFER, (sizeof(F32) * _colors.size()), &_colors[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, NULL);

    glBindBuffer(GL_ARRAY_BUFFER, buffers[2]);
    glBufferData(GL_ARRAY_BUFFER, (sizeof(F32) * _dimensions.size()), &_dimensions[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    glDrawArrays(GL_POINTS, 0, _currentBatchSize);
    //=====Reset All Containers and Counters=====
    _vertices.clear();
    _dimensions.clear();
    _colors.clear();
    _uvs.clear();
    _currentBatchSize = 0;
}