C++ glPolygonMode未在正确模式下渲染
我最近开始学习细分,今天我尝试在细分之后绘制一个三角形,这样我就可以使用GLPolygonModelGL_FRONT_和_BACK,GL_LINE查看所有细分的较小三角形。但由于某些原因,输出只是一个彩色背景,没有任何三角形。 对于细分,我制作了一个控制着色器和求值着色器,然后将它们链接到程序C++ glPolygonMode未在正确模式下渲染,c++,opengl,glsl,shader,tesselation,C++,Opengl,Glsl,Shader,Tesselation,我最近开始学习细分,今天我尝试在细分之后绘制一个三角形,这样我就可以使用GLPolygonModelGL_FRONT_和_BACK,GL_LINE查看所有细分的较小三角形。但由于某些原因,输出只是一个彩色背景,没有任何三角形。 对于细分,我制作了一个控制着色器和求值着色器,然后将它们链接到程序 // Source code for Tesselation Control Shader static const GLchar * tesselation_control_shader[] = {
// 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"
};
然后在使用glDrawArraysGL_三角形0,3绘制三角形之前,我在渲染函数中调用GLPolygonModelGL_FRONT_和GLu BACK,GL_线。
我最初认为glPolygonMode默认为GL_FILL,但我不认为这是问题所在,因为我只是在看一本OpenGL Superbible第7版的书。
我怎样才能解决这个问题
编辑:
我在下面添加了整个程序的代码:
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);
如果使用细分着色器,则必须绘制面片。您必须按设置面片的大小,并且基本体类型必须是GL_面片 如果面片中的顶点数为3,则必须按如下方式执行:
glPatchParameteri(GL_PATCH_VERTICES, 3);
glDrawArrays(GL_PATCHES, 0, 3)
见:
使用模式面片指定单独的面片。面片是用于第11.2节基本体细分的有序顶点集合。构成面片的顶点没有隐含的几何顺序。细分着色器和固定函数细分器使用面片的顶点生成新的点、线或三角形基本体。
void PatchParameteri( enum pname, int value );
将pname设置为面片顶点
着色器程序甚至不链接,因为片段着色器尝试从输入接口块读取,
未声明为前一着色器阶段的输出。
必须将顶点属性通过细分控制和求值着色器传递到片段着色器:
#version 450 core
in TESE_OUT
{
vec4 color;
} fs_in;
out vec4 color;
void main(void)
{
color = fs_in.color;
}
细分控制着色器:
#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;
}
细分求值着色器:
#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;
}
片段着色器:
#version 450 core
in TESE_OUT
{
vec4 color;
} fs_in;
out vec4 color;
void main(void)
{
color = fs_in.color;
}
此外,我建议检查着色器对象是否已成功编译:
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;
}
进一步注意,偏移可能会将三角形移出视口。更改属性初始化中偏移量的值:
GLfloat attrib[] = { 0.0, 0.0, 0.0, 0.0 };
或者出于调试原因,去掉顶点着色器中的offest
gl_Position = vertices[gl_VertexID];
您必须确保颜色属性也已设置:
GLfloat attrib1[] = { 1.0, 1.0, 0.0, 1.0 };
glVertexAttrib4fv(1, attrib1);
结果可能如下所示:
glPatchParameteri(GL_PATCH_VERTICES, 3);
glDrawArrays(GL_PATCHES, 0, 3)
如果使用细分着色器,则必须绘制面片。您必须按设置面片的大小,并且基本体类型必须是GL_面片 如果面片中的顶点数为3,则必须按如下方式执行:
glPatchParameteri(GL_PATCH_VERTICES, 3);
glDrawArrays(GL_PATCHES, 0, 3)
见:
使用模式面片指定单独的面片。面片是用于第11.2节基本体细分的有序顶点集合。构成面片的顶点没有隐含的几何顺序。细分着色器和固定函数细分器使用面片的顶点生成新的点、线或三角形基本体。
void PatchParameteri( enum pname, int value );
将pname设置为面片顶点
着色器程序甚至不链接,因为片段着色器尝试从输入接口块读取,
未声明为前一着色器阶段的输出。
必须将顶点属性通过细分控制和求值着色器传递到片段着色器:
#version 450 core
in TESE_OUT
{
vec4 color;
} fs_in;
out vec4 color;
void main(void)
{
color = fs_in.color;
}
细分控制着色器:
#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;
}
细分求值着色器:
#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;
}
片段着色器:
#version 450 core
in TESE_OUT
{
vec4 color;
} fs_in;
out vec4 color;
void main(void)
{
color = fs_in.color;
}
此外,我建议检查着色器对象是否已成功编译:
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;
}
进一步注意,偏移可能会将三角形移出视口。更改属性初始化中偏移量的值:
GLfloat attrib[] = { 0.0, 0.0, 0.0, 0.0 };
或者出于调试原因,去掉顶点着色器中的offest
gl_Position = vertices[gl_VertexID];
您必须确保颜色属性也已设置:
GLfloat attrib1[] = { 1.0, 1.0, 0.0, 1.0 };
glVertexAttrib4fv(1, attrib1);
结果可能如下所示:
glPatchParameteri(GL_PATCH_VERTICES, 3);
glDrawArrays(GL_PATCHES, 0, 3)
因此,在检查了大量源代码和Superbible的代码库后,我意识到我有很多不必要的代码,例如,着色器中的接口块,甚至有相当多的错误,例如,我有两个程序变量。 但是,在修复所有生成所需输出的代码后,细分三角形是:
希望这能帮助其他人解决同样的问题。因此,在检查了大量源代码和Superbible的代码库后,我意识到我有很多不必要的代码,例如,着色器中的接口块,甚至有很多错误,例如,我有两个程序变量。 但是,在修复所有生成所需输出的代码后,细分三角形是:
希望这能帮助其他人解决同样的问题。如果你使用镶嵌着色器,那么你必须绘制GL_补丁。与你的问题无关,但这可能值得研究,而不是将GLSL源的每一行都用引号括起来。@rabbi76如果你使用细分着色器?我需要的每个补丁的控制点数量是3。不是吗
默认值是多少?如果它是默认值,那么我就不必称它为正确的吗?@Fibbles我将对此进行研究,谢谢你的邀请advice@Varun.R您必须根据设置面片的大小,并且基本类型必须为GL_面片。如果您使用细分着色器,则必须绘制GL_面片。与您的问题无关,但可能值得研究,而不是将GLSL源的每一行都用引号括起来。@rabbi76我认为面片如果使用细分着色器,是否自动隐式完成?我需要的每个补丁的控制点数量是3。这不是默认值吗?如果它是默认值,那么我就不必说它是对的?@Fibbles我会研究一下,谢谢你的帮助advice@Varun.R您必须通过设置面片的大小,并且基本类型必须是GL_patches我在哪里调用glpatchParameteri和glDrawArray?在渲染中绘制三角形之前,我会调用它,但输出是相同的,细分仍然不是there@Varun.R在您的问题中,您只发布了细分着色器。因此,不可能找到问题所在。你问题中的代码不是我编辑的问题,并添加了整个程序的代码。这有帮助吗?我修复了错误并链接了着色器程序,就像您在放入的代码片段中所做的那样,但输出仍然是黄色屏幕,没有显示triangle@Varun.R我扩展了答案。我在哪里调用glPatchParametri和glDrawArrays?在渲染中绘制三角形之前,我会调用它,但输出是相同的,细分仍然不是there@Varun.R在您的问题中,您只发布了细分着色器。因此,不可能找到问题所在。你问题中的代码不是我编辑的问题,并添加了整个程序的代码。这有帮助吗?我修复了错误并链接了着色器程序,就像您在放入的代码片段中所做的那样,但输出仍然是黄色屏幕,没有显示triangle@Varun.R我扩展了答案。