我刚刚开始学习OpenGL,并遇到了一个有趣的错误(可能是因为我的错误行为)
然而,我似乎无法弄清楚为什么我的脸在默认情况下被绘制在两边,而不是一面。以下是一些描述问题的屏幕截图
当我继续启用 GL_CULL_FACE时(因为它显然没有启用它,因为它应该是),我的四边形被渲染,但都是错误的一面。这是由于我计算法线的方式吗?
这是我计算正常
的代码public static Point3D calculateNormals(Point3D p1, Point3D p2, Point3D p3) {
Point3D v1 = new Point3D(p2.getX() - p1.getX(), p2.getY() - p1.getY(), p2.getZ() - p1.getZ());
Point3D v2 = new Point3D(p3.getX() - p1.getX(), p3.getY() - p1.getY(), p3.getZ() - p1.getZ());
Point3D normal = new Point3D();
normal.addX((v1.getY() * v2.getZ()) - (v1.getZ() - v2.getY()));
normal.addY((v2.getZ() * v1.getX()) - (v2.getX() * v1.getZ()));
normal.addZ((v1.getX() - v2.getY()) - (v1.getY() - v2.getX()));
return normal;
}
注意:创建一个没有参数的Point3D导致x,y和z都被设置为0,因此可以使用addX,andY和addZ。
我应该翻转我的正常计算吗?
答案 0 :(得分:4)
你是什么意思?默认情况下,当我继续并启用GL_CULL_FACE时(因为它显然没有默认启用,因为它应该是)
GL_CULL_FACE
处于禁用状态,具体取决于规范。
决定正面是什么,背面是什么,与你使用的法线完全无关,GL使用基元的缠绕顺序(由你指定的顶点的顺序定义)。默认情况下,如果面的顶点(在屏幕空间中)以逆时针方向定向,则该面被视为正面。
您可以通过翻转每个基元的缠绕来重新定位您的面部,或者您可以使用glFrontFace()
将GL的顺序规则从GL_CCW
更改为GL_CW
(顺时针),或者您可以甚至使用glCullFace()
告诉OpenGL您要剔除正面而不是背面。
无论您选择何种选项,我都会建议您确保确保场景中所有对象的绕线顺序一致。原则上可以为每次绘制调用切换oders,但如果不是绝对必要的话,你应该避免这样做。
答案 1 :(得分:1)
GL_CULL_FACE(GL_BACK)将剔除对象的背面。在此之前,请记住glEnable(GL_CULL_FACE)。您可以随时重新启用和禁用剔除。有时候重要的是渲染双方(例如船上的帆)。