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

时间:2017-01-17 05:35:08

标签: c++ opengl graphics game-engine

我正在尝试编写一个采用单个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;
}

1 个答案:

答案 0 :(得分: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;
}