c++ - 对三角形缠绕和变换感到困惑

标签 c++ opengl culling coordinate-transformation

首先,我想为这么长的问题道歉。你不必阅读它。您可以直接跳到问题部分,然后在需要时查找详细信息(我已尝试提供尽可能多的信息,因为根据我的经验,代码太多总比代码太少好)。所以,...

我对三角形缠绕和变换有点困惑,我以为我理解了。我正在尝试绘制一个定义如下的立方体:

    const float a = 0.5f; //half of the cube side length
    float positions[nComponents] =
    {
        //front face
        -a, -a, -a,
         a, -a, -a,
         a,  a, -a,

        -a, -a, -a,
         a,  a, -a,
        -a,  a, -a,

        //back face
        -a, -a,  a,
         a,  a,  a,
         a, -a,  a,

        -a, -a,  a,
        -a,  a,  a,
         a,  a,  a,

        //up face
        -a,  a, -a,
         a,  a, -a,
         a,  a,  a,

        -a,  a, -a,
         a,  a,  a,
        -a,  a,  a,

        //down face
        -a, -a, -a,
         a, -a,  a,
         a, -a, -a,

        -a, -a, -a,
        -a, -a,  a,
         a, -a,  a,

         //right face
         a, -a, -a,
         a, -a,  a,
         a,  a,  a,

         a, -a, -a,
         a,  a,  a,
         a,  a, -a,

         //left face
         -a, -a, -a,
         -a,  a,  a,
         -a, -a,  a,

         -a, -a, -a,
         -a,  a, -a,
         -a,  a,  a,
    };

这些是我脸上的假定颜色:

float face_colors[nFaces * dim] =
{
    1,0,0, //front RED
    1,1,1, //back  WHITE
    0,0,1, //up    BLUE
    0,1,1, //down  SKY BLUE
    0,1,0, //right GREEN
    1,1,0, //left  YELLOW
};

正如您从评论中看到的那样,我使用了上、下、左、右等术语。如果我们假设我们从某个位置看立方体,那么这些词就可以理解它们的含义,比如说,( 0, 0, -3a) 在世界坐标中。现在,据我所知,我的立方体的正面是逆时针缠绕的(也就是说,如果我们从立方体外部的任何位置看它,并枚举我们看到的三角形中的顶点,我们将逆时针缠绕) .

所以,我需要 1. 启用剔除。 2.说逆时针是正面 3.剔除背面。这是相关代码:

glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
glCullFace(GL_BACK);

我的投影矩阵是一个透视投影矩阵,modelView矩阵只是一个LookAt矩阵。它们作为制服提供给顶点着色器。

ProjectionMatrix = glm::perspective(45.0f, (float)w/h, 0.1f, 100.0f);
glm::vec3 center(0.0f, 0.0f, 0.0f);
glm::vec3 eye(1.0f, 2.0f, -3.0f);
glm::vec3 up(0.0f, 1.0f, 0.0f);
ModelViewMatrix = glm::lookAt(eye, center, up);
glUniformMatrix4fv(locP, 1, false, glm::value_ptr(ProjectionMatrix));
glUniformMatrix4fv(locMV, 1, false, glm::value_ptr(ModelViewMatrix));

我的顶点着色器定义如下:

#version 400
layout(location = 0) in vec4 vVertex;
layout(location = 1) in vec4 vColor;
uniform mat4 P;
uniform mat4 MV;
out vec4 vFragColor;
void main(void)
{
   vFragColor = vColor;
   gl_Position = P * MV * vVertex;
}

我的片段着色器很简单——它只输出插值颜色。

现在...这是我得到的输出:

enter image description here

如果我将 glFrontFace(GL_CCW); 更改为 glFrontFace(GL_CW);,或者将 glCullFace(GL_BACK) 更改为 glCullFace(GL_FRONT),我得到了预期的(至少比前一个更预期,见第二和第三个问题)渲染:

enter image description here

我在这里看到三个问题,每个问题都在一个问题中进行了描述:

实际问题:

问题 1: 为什么缠绕与我预期的相反?前面的顶点不是逆时针旋转的吗?
Q2 为什么我的“左”脸和“右”脸调换了位置?左脸应该是黄色的,右脸应该是绿色的,而不是相反!我的转型有什么问题?
Q3 我的转换有问题,因为我的眼睛 vector 的 x 坐标是正的,这意味着我实际上应该看到右边的一点点,而不是右边的一点点左边!

我一起问了这些问题,因为我认为它们都是相互关联的,并且可能与我遗漏的一些非常基本的问题有关。非常感谢您花时间澄清这些事情。

最佳答案

默认情况下,OpenGL 采用右手坐标系,即正 Z 轴指向屏幕外。您的立方体顶点位置表明您假设是左手坐标系。但是,如果您将这些值放入 RHS,那么您的 LHS 逆时针坐标变为顺时针 (1),一个轴上的面交换位置 (2),并且您假设的眼睛变换将进入相反的方向 (3)。

关于c++ - 对三角形缠绕和变换感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7231848/

相关文章:

opengl - 延迟渲染与基于图 block 的剔除概念问题

c++ - 多重映射如何在内部处理重复键?

c++ - Qt - 在工作线程崩溃时将 cv::Mat 转换为 QImage

arrays - glsl multi light,传递数据的最佳实践(结构数组?)

c++ - OpenGL 如何渲染它的三角形?

opengl - 在 OpenGL 中绘制对象 X 秒

c++ - OpenGL:四边形似乎没有正确剔除

c# - 编码 SIZE_T* 的正确方法?

c++ - 函数返回值的自动类型推导

javascript - 体素世界中的“剔除”