c++ - 为什么我的三角形在镶嵌后不显示? OpenGL

标签 c++ opengl glsl shader

我开始学习opengl,我正处于镶嵌阶段,我有问题,当我将镶嵌着色器附加到程序时,我的三角形不会显示。着色器编译正确,没有链接错误。从代码方面来看,一切似乎都很好。当我只使用顶点着色器和片段着色器时,一切都很好。可能是什么原因?

Shaders::Shaders(const char* vertexPath, const char* fragmentPath, const char* tessControlPath, const char* tessEvaluationPath)
{
    std::string vs_str = load_file(vertexPath);
    std::string fs_str = load_file(fragmentPath);
    std::string tc_str = load_file(tessControlPath);
    std::string te_str = load_file(tessEvaluationPath);
    const char* vs_src = vs_str.c_str();
    const char* fs_src = fs_str.c_str();
    const char* tc_src = tc_str.c_str();
    const char* te_src = te_str.c_str();

    create_shader(GL_VERTEX_SHADER, vertexShader, vs_src);
    create_shader(GL_FRAGMENT_SHADER, fragmentShader, fs_src);
    create_shader(GL_TESS_CONTROL_SHADER, tessControlShader, tc_src);
    create_shader(GL_TESS_EVALUATION_SHADER, tessEvaluationShader, te_src);

    program = glCreateProgram();
    glAttachShader(program, vertexShader);
    glAttachShader(program, fragmentShader);
    glAttachShader(program, tessControlShader);
    glAttachShader(program, tessEvaluationShader);
    glLinkProgram(program);

    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    glDeleteShader(tessControlShader);
    glDeleteShader(tessEvaluationShader);

    glCreateVertexArrays(1, &vertexArrayObject);
    glBindVertexArray(vertexArrayObject);
}
void Shaders::create_shader(GLenum type, GLuint& shader, const char* src)
{
    GLint isCompiled = 0;
    shader = glCreateShader(type);
    glShaderSource(shader, 1, &src, nullptr);
    glCompileShader(shader);
    glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);
    if (isCompiled == GL_FALSE)
    {
        GLint maxLength = 0;
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);
        std::vector<GLchar> errorLog(maxLength);
        glGetShaderInfoLog(shader, maxLength, &maxLength, &errorLog[0]);
        for (int i = 0; i < errorLog.size(); i++)
        {
            std::cerr << errorLog[i];
        }
        glDeleteShader(shader);
    }
}

int main()
{
    Window* window = new Window(1200, 1000);
    Shaders* shader = new Shaders("shaders/vertex.glsl", "shaders/fragment.glsl", "shaders/tess_control.glsl", "shaders/tess_evaluation.glsl");

    while (glfwWindowShouldClose(window->get_window()) == false)
    {
        window->loop();
        const GLfloat color[]{1.0f, 0.5f, 0.5f, 1.0f};
        glClearBufferfv(GL_COLOR, 0, color);

        const GLfloat attrib[]{0.0f, 0.0f, 1.0f, 1.0f};

        glUseProgram(shader->get_program());
        glVertexAttrib4fv(0, attrib);

        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        glDrawArrays(GL_PATCHES, 0, 3);
    }

    delete window;
    delete shader;
    glfwTerminate();
}

顶点.glsl
#version 450 core

layout (location = 0) in vec4 color;

out VS_OUT
{ 
    vec4 color;
} vs_out;

void main(void)
{
    const vec4 vertices[3] = vec4[3](vec4( 0.25, -0.25, 0.5, 1.0), vec4(-0.25, -0.25, 0.5, 1.0), vec4(0.25, 0.25, 0.5, 1.0));

    gl_Position = vertices[gl_VertexID];
    vs_out.color = color;
}

片段.glsl
#version 450 core

in VS_OUT
{
    vec4 color;
} fs_in;

out vec4 color;

void main(void)
{
    color = fs_in.color;
}

tess_control.glsl
#version 450 core

layout (vertices = 3) out;

void main(void)
{
    if (gl_InvocationID = 0)
    {
        gl_TessLevelInner[0] = 5.0;
        gl_TessLevelOuter[0] = 5.0;
        gl_TessLevelOuter[1] = 5.0;
        gl_TessLevelOuter[2] = 5.0;
    }
    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
}

tess_evaluation.glsl
#version 450 core

layout (triangles, equal_spacing, ccw) in;

void main(void)
{
    gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position + gl_TessCoord.y * gl_in[1].gl_Position + gl_TessCoord.z * gl_in[2].gl_Position);
}

最佳答案

您已通过 glPatchParameteri 指定将用于构成单个面片图元的顶点数。 :

glPatchParameteri(GL_PATCH_VERTICES, 3);
glDrawArrays(GL_PATCHES, 0, 3);

此外,您还必须通过所有着色器阶段,从顶点着色器到片段着色器一直传递颜色:

Tessellation Control Shader 的输入是一个补丁,输出也是补丁。但是输入补丁大小可以与输出补丁大小不同。虽然输入补丁大小由 GL_PATCH_VERTICES 定义,输出补丁大小由 layout (vertices = 3) out 定义.因此,您必须在着色器程序中指定输入补丁的属性如何映射到输出补丁的属性。

#version 450 core

layout (vertices = 3) out;

in VS_OUT
{ 
    vec4 color;
} in_data[];

out VS_OUT
{ 
    vec4 color;
} out_data[];

void main(void)
{
    out_data[gl_InvocationID].color = in_data[gl_InvocationID].color;
    if (gl_InvocationID = 0)
    {
        gl_TessLevelInner[0] = 5.0;
        gl_TessLevelOuter[0] = 5.0;
        gl_TessLevelOuter[1] = 5.0;
        gl_TessLevelOuter[2] = 5.0;
    }
    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
}

Tessellation Evaluation Shader执行插值。镶嵌控制着色器的输出补丁的属性根据 gl_TessCoord 进行插值。 .
您必须实现在着色器程序中插入属性的算法。

#version 450 core

layout (triangles, equal_spacing, ccw) in;

in VS_OUT
{ 
    vec4 color;
} in_data[];

out VS_OUT
{ 
    vec4 color;
} out_data;

void main(void)
{
    out_data.color = in_data[0].color * gl_TessCoord.x + in_data[1].color * gl_TessCoord.y + in_data[2].color * gl_TessCoord.z;
    gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position + gl_TessCoord.y * gl_in[1].gl_Position + gl_TessCoord.z * gl_in[2].gl_Position);
}

关于c++ - 为什么我的三角形在镶嵌后不显示? OpenGL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60917254/

相关文章:

c++ - 条件 constexpr 函数

opengl - 警告 LNK4098 : defaultlib 'LIBCMT' conflicts with use of other libs; use/NODEFAULTLIB:library

algorithm - 在 GLSL 中将 float 转换为十进制数字

opengl - 片段着色器 : output variables

c++ - 替换 VC++ 8 中的 auto_ptr

c++ - 这张图说明了时间复杂度是多少?

c++ - 使用 CUDA 在 GPU 之间复制大数据

OpenGL重叠丑陋的渲染

c++ - 为什么 glDrawElments() 可以在不使用任何着色器的情况下工作?

javascript - 使用 webgl 在鼠标移动上创建一个连续动画回到原始状态的涂抹/液化效果