首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >glPolygonMode没有以正确的模式呈现

glPolygonMode没有以正确的模式呈现
EN

Stack Overflow用户
提问于 2018-07-20 14:15:36
回答 2查看 830关注 0票数 1

我最近开始学习镶嵌,今天我试着画一个又一个三角形,这样我就可以用glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)看到所有的三角形。但出于某种原因,输出只是一个没有任何三角形的彩色背景。对于这个结构,我做了一个control shaderevaluation shader,然后将它们链接到program

代码语言:javascript
复制
// Source code for Tesselation Control Shader
static const GLchar * tesselation_control_shader[] = 
{
    "#version 450 core                                  \n"
    "                                                   \n"
    "layout(vertices = 3) out;                          \n"
    "                                                   \n"
    "void main(void)                                    \n"
    "{                                                  \n"
    "   //Only if I am invocation 0                     \n"
    "   if (gl_InvocationID == 0)                       \n"
    "   {                                               \n"
    "       gl_TessLevelInner[0] = 5.0;                 \n"
    "       gl_TessLevelOuter[0] = 5.0;                 \n"
    "       gl_TessLevelOuter[1] = 5.0;                 \n"
    "       gl_TessLevelOuter[2] = 5.0;                 \n"
    "   }                                               \n"
    "                                                   \n"
    "   // Everybody copies their input to their input  \n"
    "   gl_out[gl_InvocationID].gl_Position =           \n"
    "       gl_in[gl_InvocationID].gl_Position;         \n"
    "}                                                  \n"
};

// Source code for tesselation evaluation shader
static const GLchar * tesselation_evaluation_shader[] =
{
    "#version 450 core                                          \n"
    "                                                           \n"
    "layout(triangles, equal_spacing, cw) in;                   \n"
    "                                                           \n"
    "void main(void)                                            \n"
    "{                                                          \n"
    "   gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position +  \n"
    "       gl_TessCoord.y * gl_in[1].gl_Position +             \n"
    "       gl_TessCoord.z * gl_in[2].gl_Position);             \n"
    "}                                                          \n"
};

然后,在使用glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)绘制三角形之前,在render函数中调用glDrawArrays(GL_TRIANGLE, 0, 3)。我最初以为glPolygonMode默认为GL_FILL,但我不认为这是问题所在,因为我只是在遵循一本书(OpenGL Superbible第7版)。我怎么才能解决这个问题?

编辑:

我在下面添加了我的整个程序的代码:

代码语言:javascript
复制
GLuint compile_shaders(void)
{
    GLuint vertex_shader;
    GLuint fragment_shader;
    GLuint control_shader;
    GLuint evaluation_shader;
    GLuint program;

    // Source code for Vertex Shader
    static const GLchar * vertex_shader_source[] =
    {
        "#version 450 core                                                      \n"
        "                                                                       \n"
        "// offset and color are input vertex attribute                         \n"
        "layout (location = 0) in vec4 offset;                                  \n"
        "layout (location = 1) in vec4 color;                                   \n"
        "                                                                       \n"
        "//Declare VS_OUT as an output interface block                          \n"
        "out VS_OUT                                                             \n"
        "{                                                                      \n"
        "   vec4 color; //Send color to next stage                              \n"
        "}vs_out;                                                               \n"
        "                                                                       \n"
        "void main(void)                                                        \n"
        "{                                                                      \n"
        "   //Decalre a hardcoded array of positions                            \n"
        "   const vec4 vertices[3] = vec4[3](vec4(0.25, -0.25, 0.5, 1.0),       \n"
        "                                    vec4(-0.25, -0.25, 0.5, 1.0),      \n"
        "                                    vec4(0.25, 0.25, 0.5, 1.0));       \n"
        "                                                                       \n"
        "   //Index into our array using gl_VertexID                            \n"
        "   gl_Position = vertices[gl_VertexID] + offset;                       \n"
        "                                                                       \n"
        "//color = vec4(1.0, 0.0, 0.0, 1.0);                                    \n"
        "//Output fixed value for vs_color                                      \n"
        "vs_out.color = color;                                                  \n"
        "}                                                                      \n"
    };

    // Source code for Fragment Shader
    static const GLchar * fragment_shader_source[] =
    {
        "#version 450 core                                                              \n"
        "                                                                               \n"
        "//Declare VS_OUT as an input interface block                                   \n"
        "in VS_OUT                                                                      \n"
        "{                                                                              \n"
        "   vec4 color; //Send color to next stage                                      \n"
        "}fs_in;                                                                        \n"
        "                                                                               \n"
        "//Ouput to the framebuffer                                                     \n"
        "out vec4 color;                                                                \n"
        "                                                                               \n"
        "void main(void)                                                                \n"
        "{                                                                              \n"
        "// Simply assign the color we were given by the vertex shader to our output    \n"
        "   color = fs_in.color;                                                        \n"
        "}                                                                              \n"
    };

    // Source code for Tesselation Control Shader
    static const GLchar * tesselation_control_shader[] = 
    {
        "#version 450 core                                  \n"
        "                                                   \n"
        "layout(vertices = 3) out;                          \n"
        "                                                   \n"
        "void main(void)                                    \n"
        "{                                                  \n"
        "   //Only if I am invocation 0                     \n"
        "   if (gl_InvocationID == 0)                       \n"
        "   {                                               \n"
        "       gl_TessLevelInner[0] = 5.0;                 \n"
        "       gl_TessLevelOuter[0] = 5.0;                 \n"
        "       gl_TessLevelOuter[1] = 5.0;                 \n"
        "       gl_TessLevelOuter[2] = 5.0;                 \n"
        "   }                                               \n"
        "                                                   \n"
        "   // Everybody copies their input to their input  \n"
        "   gl_out[gl_InvocationID].gl_Position =           \n"
        "       gl_in[gl_InvocationID].gl_Position;         \n"
        "}                                                  \n"
    };

    // Source code for tesselation evaluation shader
    static const GLchar * tesselation_evaluation_shader[] =
    {
        "#version 450 core                                          \n"
        "                                                           \n"
        "layout(triangles, equal_spacing, cw) in;                   \n"
        "                                                           \n"
        "void main(void)                                            \n"
        "{                                                          \n"
        "   gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position +  \n"
        "       gl_TessCoord.y * gl_in[1].gl_Position +             \n"
        "       gl_TessCoord.z * gl_in[2].gl_Position);             \n"
        "}                                                          \n"
    };

    // Create and compiler Vertex Shader
    vertex_shader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex_shader, 1, vertex_shader_source, NULL);
    glCompileShader(vertex_shader);

    // Create and compiler Fragment Shader
    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragment_shader, 1, fragment_shader_source, NULL);
    glCompileShader(fragment_shader);


    // Create and compile tesselation control shader
    control_shader = glCreateShader(GL_TESS_CONTROL_SHADER);
    glShaderSource(control_shader, 1, tesselation_control_shader, NULL);
    glCompileShader(control_shader);

    // Create and compile tesselation evaluation shader
    evaluation_shader = glCreateShader(GL_TESS_CONTROL_SHADER);
    glShaderSource(evaluation_shader, 1, tesselation_control_shader, NULL);
    glCompileShader(evaluation_shader);

    // Create program, attach shaders to it, and link it
    program = glCreateProgram();
    glAttachShader(program, vertex_shader);
    glAttachShader(program, fragment_shader);
    glAttachShader(program, control_shader);
    glAttachShader(program, evaluation_shader);
    glLinkProgram(program);

    // Delete shaders as program has them now
    glDeleteShader(vertex_shader);
    glDeleteShader(fragment_shader);
    glDeleteShader(control_shader);
    glDeleteShader(evaluation_shader);

    return program;
};

class TesselationCSOne : public sb7::application
{
public:

    void startup()
    {
        rendering_program = compile_shaders();
        glCreateVertexArrays(1, &vertex_array_object);
        glBindVertexArray(vertex_array_object);
    }

    void shutdown()
    {
        glDeleteVertexArrays(1, &vertex_array_object);
        glDeleteProgram(rendering_program);
        glDeleteVertexArrays(1, &vertex_array_object);
    }

    // Our rendering function
    void render(double currentTime)
    {
        // Sets colour
        static const GLfloat color[] = { (float)sin(currentTime) * 0.5f + 0.5f, (float)sin(currentTime) * 0.5f + 0.5f, 0.0f, 1.0f };

        glClearBufferfv(GL_COLOR, 0, color);

        //Tell OpenGL to draw only the outlines of the resulting triangle
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

        // Use program object we created for rendering
        glUseProgram(rendering_program);

        GLfloat attrib[] = { 1.0, 0.0, 0.0, 0.0 };/*{ (float)sin(currentTime) * 0.5f, (float)sin(currentTime) * 0.6f, 0.0f, 0.0f };*/

        // Update value of input attribute 0
        glVertexAttrib4fv(0, attrib);

        // Draw pathes for tesselation shaders
        glPatchParameteri(GL_PATCH_VERTICES, 3);
        // Draw one triangle
        glDrawArrays(GL_PATCHES, 0, 3);
    }

private:

    GLuint rendering_program;
    GLuint vertex_array_object;
};

// Only instance of DECLARE_MAIN to state entry point
DECLARE_MAIN(TesselationCSOne);
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-07-27 13:49:25

因此,在检查了许多源代码和Superbible的代码存储库之后,我意识到我有很多不必要的代码(例如,着色器中的interface blocks ),甚至还有很多错误(例如,我有两个program变量)。

但是,在修复所有这些之后,生成所需输出的代码( tessellated三角形)是:

代码语言:javascript
复制
/**
        Program to draw a triangle with tesselation.
**/
#include <sb7.h>

class TesselatedTriangle : public sb7::application
{
    void init()
    {
        static const char title[] = "Tessellated Triangle";

        sb7::application::init();

        memcpy(info.title, title, sizeof(title));
    }

    virtual void startup()
    {
        static const char * vertex_shader_source[] =
        {
            "#version 450 core                                                 \n"
            "                                                                  \n"
            "void main(void)                                                   \n"
            "{                                                                 \n"
            "    const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0),  \n"
            "                                   vec4(-0.25, -0.25, 0.5, 1.0),  \n"
            "                                   vec4( 0.25,  0.25, 0.5, 1.0)); \n"
            "                                                                  \n"
            "    gl_Position = vertices[gl_VertexID];                          \n"
            "}                                                                 \n"
        };

        static const char * tesselation_control_shader_source[] =
        {
            "#version 450 core                                                                 \n"
            "                                                                                  \n"
            "layout (vertices = 3) out;                                                        \n"
            "                                                                                  \n"
            "void main(void)                                                                   \n"
            "{                                                                                 \n"
            "    if (gl_InvocationID == 0)                                                     \n"
            "    {                                                                             \n"
            "        gl_TessLevelInner[0] = 5.0;                                               \n"
            "        gl_TessLevelOuter[0] = 5.0;                                               \n"
            "        gl_TessLevelOuter[1] = 5.0;                                               \n"
            "        gl_TessLevelOuter[2] = 5.0;                                               \n"
            "    }                                                                             \n"
            "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;     \n"
            "}                                                                                 \n"
        };

        static const char * tesselation_evaluation_shader_source[] =
        {
            "#version 450 core                                                                 \n"
            "                                                                                  \n"
            "layout (triangles, equal_spacing, cw) in;                                         \n"
            "                                                                                  \n"
            "void main(void)                                                                   \n"
            "{                                                                                 \n"
            "    gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position) +                       \n"
            "                  (gl_TessCoord.y * gl_in[1].gl_Position) +                       \n"
            "                  (gl_TessCoord.z * gl_in[2].gl_Position);                        \n"
            "}                                                                                 \n"
        };

        static const char * fragment_shader_source[] =
        {
            "#version 450 core                                                 \n"
            "                                                                  \n"
            "out vec4 color;                                                   \n"
            "                                                                  \n"
            "void main(void)                                                   \n"
            "{                                                                 \n"
            "    color = vec4(0.0, 0.8, 1.0, 1.0);                             \n"
            "}                                                                 \n"
        };

        rendering_program = glCreateProgram();

        // Compile shaders
        GLuint vs = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vs, 1, vertex_shader_source, NULL);
        glCompileShader(vs);

        GLuint tcs = glCreateShader(GL_TESS_CONTROL_SHADER);
        glShaderSource(tcs, 1, tesselation_control_shader_source, NULL);
        glCompileShader(tcs);

        GLuint tes = glCreateShader(GL_TESS_EVALUATION_SHADER);
        glShaderSource(tes, 1, tesselation_evaluation_shader_source, NULL);
        glCompileShader(tes);

        GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fs, 1, fragment_shader_source, NULL);
        glCompileShader(fs);

        // Attach shaders to the program
        glAttachShader(rendering_program, vs);
        glAttachShader(rendering_program, tcs);
        glAttachShader(rendering_program, tes);
        glAttachShader(rendering_program, fs);

        // Link the program
        glLinkProgram(rendering_program);

        // Generate vertex arrays
        glGenVertexArrays(1, &vertex_array_object);
        glBindVertexArray(vertex_array_object);

        // Declare the drawing mode for the polygons
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    }

    virtual void render(double currentTime)
    {
        static const GLfloat green[] = { 0.0f, 0.25f, 0.0f, 1.0f };

        glClearBufferfv(GL_COLOR, 0, green);

        glUseProgram(rendering_program);

        glDrawArrays(GL_PATCHES, 0, 3);
    }

    virtual void shutdown()
    {
        glDeleteVertexArrays(1, &vertex_array_object);

        glDeleteProgram(rendering_program);
    }


private:

    GLuint          rendering_program;
    GLuint          vertex_array_object;

};

// One and only instance of DECLARE_MAIN
DECLARE_MAIN(TesselatedTriangle)

希望这能帮助其他人解决同样的问题。

票数 1
EN

Stack Overflow用户

发布于 2018-07-20 17:29:48

如果你使用镶嵌着色器,那么你必须画补丁。您必须通过glPatchParameteri( GL_PATCH_VERTICES, ...)来设置补丁的大小,并且基本类型必须是GL_PATCHES

如果一个补丁中的顶点数是3个,那么您必须这样做:

代码语言:javascript
复制
glPatchParameteri(GL_PATCH_VERTICES, 3); 
glDrawArrays(GL_PATCHES, 0, 3)

请参阅OpenGL 4.6API核心配置文件规范;10.1.15单独补丁;第342页

使用模式PATCHES指定单独的修补程序。补丁是用于原始镶嵌的顶点的有序集合(第11.2节)。包括补片的顶点没有隐含的几何顺序。贴片的顶点由镶嵌着色器和固定函数拼接器用来生成新的点、线或三角形primitives.void PatchParameteri( enum,int值); 将名称设置为PATCH_VERTICES

您的着色器程序甚至没有链接,因为片段着色器试图从输入接口块中读取,而输入接口块没有被声明为来自上一个着色器阶段的输出。

您必须将顶点属性通过镶嵌控件和评估着色器传递给片段着色器:

镶嵌控制着色器:

代码语言:javascript
复制
#version 450 core                                 

layout(vertices = 3) out;

in VS_OUT                                                                    
{                                                                            
   vec4 color;                                   
} tesc_in[];

out TESC_OUT                                                                    
{                                                                            
   vec4 color;                                   
} tesc_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;                
   }                                              

   tesc_out[gl_InvocationID].color     = tesc_in[gl_InvocationID].color;                    
   gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;        
} 

镶嵌评价着色器:

代码语言:javascript
复制
#version 450 core                                         

layout(triangles, equal_spacing, cw) in; 

in TESC_OUT                                                                    
{                                                                            
   vec4 color;                                   
} tese_in[];

out TESE_OUT                                                                    
{                                                                            
   vec4 color;                                   
} tese_out;                  

void main(void)                                           
{                               
   tese_out.color = ( gl_TessCoord.x * tese_in[0].color + 
                      gl_TessCoord.y * tese_in[1].color +            
                      gl_TessCoord.z * tese_in[2].color ) / 3.0;

   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 ) / 3.0;            
}                                                         

碎片着色器:

代码语言:javascript
复制
#version 450 core                                                            

in TESE_OUT                                                                    
{                                                                            
   vec4 color;                                  
} fs_in;                                                                      

out vec4 color;                                                              

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

此外,我建议检查着色器对象是否已成功编译:

代码语言:javascript
复制
GLuint shaderObj = .... ;
glCompileShader( shaderObj );

GLint status = GL_TRUE;
glGetShaderiv( shaderObj, GL_COMPILE_STATUS, &status );
if ( status == GL_FALSE )
{
    GLint logLen;
    glGetShaderiv( shaderObj, GL_INFO_LOG_LENGTH, &logLen );
    std::vector< char >log( logLen );
    GLsizei written;
    glGetShaderInfoLog( shaderObj, logLen, &written, log.data() );
    std::cout << "compile error:" << std::endl << log.data() << std::endl;
}

并成功地链接了一个着色器程序对象:

代码语言:javascript
复制
GLuint progObj = ....;
glLinkProgram( progObj );

GLint status = GL_TRUE;
glGetProgramiv( progObj, GL_LINK_STATUS, &status );
if ( status == GL_FALSE )
{
    GLint logLen;
    glGetProgramiv( progObj, GL_INFO_LOG_LENGTH, &logLen );
    std::vector< char >log( logLen );
    GLsizei written;
    glGetProgramInfoLog( progObj, logLen, &written, log.data() );
    std::cout  << "link error:" << std::endl << log.data() << std::endl;
}

顺便说一下,请阅读原始字符串文字,它简化了着色器源代码字符串的声明:

例如:

代码语言:javascript
复制
std::string fragment_shader_source = R"(
#version 450 core                                                            

in TESE_OUT                                                                    
{                                                                            
    vec4 color;                                  
} fs_in;                                                                      

out vec4 color;                                                              

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

进一步注意,offset可能会将三角形移出视口。要么在属性初始化中更改offset的值:

代码语言:javascript
复制
GLfloat attrib[] = { 0.0, 0.0, 0.0, 0.0 };

或删除顶点着色器中的offest,因为调试原因。

代码语言:javascript
复制
gl_Position = vertices[gl_VertexID]; 

您必须确保颜色属性也已设置:

代码语言:javascript
复制
GLfloat attrib1[] = { 1.0, 1.0, 0.0, 1.0 };
glVertexAttrib4fv(1, attrib1);

结果可能如下:

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51444536

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档