【问题标题】:Confused About Triangle Winding And Transformations对三角绕组和变换感到困惑
【发布时间】:2011-11-06 02:33:53
【问题描述】:

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

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

    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
};

正如您从 cmets 中看到的,我使用了上、下、左、右等术语。如果我们假设我们正在从某个位置(例如 (0, 0, -3a) in世界坐标。现在,据我了解,我的立方体的正面是逆时针缠绕的(也就是说,如果我们从立方体外部的任何位置查看立方体,并枚举我们看到的三角形中的顶点,我们将得到逆时针缠绕) .

所以,我需要 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;
}

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

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

如果我将glFrontFace(GL_CCW); 更改为glFrontFace(GL_CW);,或者将glCullFace(GL_BACK) 更改为glCullFace(GL_FRONT),我会得到预期的(至少比前一个更预期,请参阅第二个和第三个问题)呈现:

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

实际问题:

Q1:为什么曲折与我的意图相反?我没有为正面的顶点逆时针缠绕顶点吗?
Q2为什么我的“左”面和“右”面交换了位置?左脸应该是黄色的,右脸应该是绿色的,反之亦然!我的转换有什么问题?
Q3我的转换有问题因为我的眼睛矢量的 x 坐标是正的,这意味着我应该实际看到一点右边一点,左边一点!

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

【问题讨论】:

    标签: c++ opengl culling coordinate-transformation


    【解决方案1】:

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

    【讨论】:

    • 我还是一头雾水。我不能随意定义我的“世界”坐标系吗? LookAt 函数采用世界坐标中的向量,不是吗?那么它与默认的Z轴方向有什么区别呢?
    • 啊……我想我现在开始明白了……我无法改变三个人的 relative 性格轴甚至在世界坐标系中。对吗?
    • @Armen 是的,就是这样。您可以按 (1,1,-1) 缩放您的模型视图矩阵,因此镜像 z 轴以假设您想要的左手系统,但我不建议这样做,因为这就像围绕 de-右手系统的事实标准。
    • 谢谢,Datenwolf 和@Christian。我现在明白了:)
    • @Armen Tsirunyan:gluLookAt 不是这样工作的。 gluLookAt 设置全局世界转换,类似于相机。就像相机不仅有位置和目标一样,向上的方向也很重要,这就是 gluLookAt 定义的。但不是坐标系。
    猜你喜欢
    • 2021-11-28
    • 2013-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多