我正在使用什么:Qt 5.11.1,MinGW 5.3,Windows 10,C ++ 11,GPU:NVidia 820M(支持OpenGL 4.5)
我的任务:我有非实体(仅表面)对象,通过glDrawArrays渲染,并且需要按平面获取该对象的横截面。我已经找到了古老的openGL函数glClipPlane,但它与VAO和VBO的兼容性不强。我也发现可以通过几何着色器重写glClipPlane。
我的问题/问题:
您知道实现此任务的其他方法吗?
我真的不明白,如何在QtCreator中添加几何着色器,没有几何着色器的“图标”,我试图添加顶点着色器并将其重命名为.gsh或只是.glsl,尝试使用{ {1}}并在程序中编写着色器代码,但是每次添加几何着色器时,在字符串上出现“ QOpenGLShader:无法创建着色器”。
看起来要在程序中添加着色器
顶点着色器:
QOpenGLShaderProgram::addShaderFromSourceCode(QOpenGLShader::Geometry, QString &source)
几何着色器:
layout (triangles) in;
layout (triangles) out;
layout (max_vertices = 3) out;
void main()
{
int i;
for (i = 0; i < gl_in.length(); i++)
{
gl_Position = gl_in[i].gl_Position;
EmitVertex();
}
EndPrimitive();
}
片段着色器:
layout (triangles) in;
layout (triangles) out;
layout (max_vertices = 3) out;
void main()
{
int i;
for (i = 0; i < gl_in.length(); i++)
{
gl_Position = gl_in[i].gl_Position;
EmitVertex();
}
EndPrimitive();
}
答案 0 :(得分:3)
让我们先解决一些误解:
已经发现了古老的openGL函数
glClipPlane
,但它与VAO和VBO的兼容性不强。
那是不正确的。通过glClipPlane
定义的用户剪切平面在现代GL中确实已弃用,并已从核心轮廓中删除。但是,如果使用它们仍然存在的上下文,则可以将它们与VAO和VBO结合使用而没有任何问题。
我也发现可以通过几何着色器重写
glClipPlane
。
自定义裁剪平面不需要几何着色器。
用户定义的裁剪平面的现代方式是为每个顶点计算gl_ClipDistance
。您可以在几何着色器中修改此值,也可以在顶点着色器中直接生成该值。如果您不需要几何着色器,则完全没有理由仅将其添加到剪切平面。
我真的不明白,如何在QtCreator中添加几何着色器,没有几何着色器的“图标”,我试图添加顶点着色器并将其重命名为.gsh或只是.glsl,尝试使用{{1} }并在程序中编写着色器代码,但是每次添加几何着色器时,在字符串上出现“ QOpenGLShader:无法创建着色器”。
您首先需要确定您实际使用的OpenGL版本。使用Qt,您可以轻松获得OpenGL ES 2.0上下文(取决于创建上下文的方式以及Qt的编译方式)。您的着色器代码是桌面GL 2.x(GLSL 1.10 / 1.20)或GLES 2.0(GLSL 1.00ES),但在现代OpenGL核心配置文件中无效。
GLES2完全不支持几何着色器。它还不支持OpenGLShaderProgram::addShaderFromSourceCode(QOpenGLShader::Geometry, QString &source)
,因此,如果您确实需要使用GLES2,则可以尝试使用emulate the clipping in the fragment shader。但是更好的选择是切换到现代的核心配置文件GL环境。
答案 1 :(得分:1)
glClipPlane
在现代OpenGL中已被弃用,但裁剪平面的概念却没有。
在您的CPU代码中,开始绘制要修剪的几何图形之前,必须启用一个修剪平面。
glEnable(GL_CLIP_DISTANCE0);
完成绘制后,您将以类似的方式禁用它。
glDisable(GL_CLIP_DISTANCE0);
保证您至少可以启用8个剪切平面。
然后在顶点或几何着色器中,您必须告诉OpenGL顶点与平面的距离,以使其知道要裁剪的内容。需要明确的是,您不需要 用于剪切的几何着色器,但是可以根据需要在此处完成。着色器代码如下所示:
// vertex in world space
vec4 vert_pos_world = world_matrix * vec4(vert_pos_model, 1.0);
// a horizontal plane at a specified height with normal pointing up
// could be a uniform or hardcoded
vec4 plane = vec4(0, 1, 0, clip_height_world);
// 0 index since that's the clipping plane we enabled
gl_ClipDistance[0] = dot(vert_pos_world, plane);