遗留OpenGL - 渲染立方体贴图布局,理解glTexCoord3f参数

3
我希望能够呈现一个立方体贴图布局(正交投影)- 就像这个。 让我们专注于+X面(图片中的右侧)。 渲染+X面的代码如下:
glBegin(GL_QUADS);

glTexCoord3f(1, 1, -1);
glVertex2i(0,0);

glTexCoord3f(1, 1, 1);
glVertex2i(256,0);

glTexCoord3f(1, -1, 1);
glVertex2i(256, 256);

glTexCoord3f(1, -1, -1);
glVertex2i(0, 256);

glEnd();

看起来glTexCoord3f使用了NDC值,但我不明白为什么前两个顶点的y值是正的,而最后一个顶点的y值是负的,根据我的理解应该相反(我想象自己从立方体中心观察立方体的面)。

1个回答

3

glTexCoord3D不使用NDC !!! 它是一个方向向量。

过去我也曾经苦恼于同样的问题... GL_TEXTURE_CUBE_MAP 难以入手...

为了让事情变得更加简单,这里是我在旧API中的渲染代码(从我的引擎中提取):

void OpenGL_TXR::cube_draw_CW(double size,int unit)
    {
    int i,j;
    double  a=size;
    double  pnt[8][3]=
        {
        +a,-a,+a,
        +a,+a,+a,
        -a,+a,+a,
        -a,-a,+a,
        +a,-a,-a,
        +a,+a,-a,
        -a,+a,-a,
        -a,-a,-a
        };
    int     tab[24]=
        {
        0,1,2,3,
        7,6,5,4,
        4,5,1,0,
        5,6,2,1,
        6,7,3,2,
        7,4,0,3
        };
    glColor3f(1,1,1);
    glBegin(GL_QUADS);
    for (i=23;i>=0;i--)
        {
        j=tab[i];
        glMultiTexCoord3dv(GL_TEXTURE0+unit,pnt[j]);
        glVertex3dv(pnt[j]);
        }
    glEnd();
    }

size 是立方体的一半尺寸,unit 是贴图单元,用于绑定你的立方体贴图。 但它会渲染一个带纹理的立方体。如果您想要呈现布局,则只需使用不同的顶点,但使用相同的纹理坐标。类似这样:

void cube_draw2D_CW(double size,int unit)
    {
    int i,j;
    //   U
    // W N E S
    //   D
    const double a=size,a0=-3.0*a,a1=a0+a+a,a2=a1+a+a,a3=a2+a+a;
    const double b=1.7320508075688772935274463415059; // sqrt(3.0)
    double  pnttxr[8][3]=
        {
        +b,-b,+b,
        +b,+b,+b,
        -b,+b,+b,
        -b,-b,+b,
        +b,-b,-b,
        +b,+b,-b,
        -b,+b,-b,
        -b,-b,-b
        };
    double  pntver[24][3]=
        {
        a1+a,a0+a-a,+0.0,
        a1+a,a0+a+a,+0.0,
        a1-a,a0+a+a,+0.0,
        a1-a,a0+a-a,+0.0,

        a1+a,a2+a-a,+0.0,
        a1+a,a2+a+a,+0.0,
        a1-a,a2+a+a,+0.0,
        a1-a,a2+a-a,+0.0,

        a0+a,a1+a-a,+0.0,
        a0+a,a1+a+a,+0.0,
        a0-a,a1+a+a,+0.0,
        a0-a,a1+a-a,+0.0,

        a1+a,a1+a-a,+0.0,
        a1+a,a1+a+a,+0.0,
        a1-a,a1+a+a,+0.0,
        a1-a,a1+a-a,+0.0,

        a2+a,a1+a-a,+0.0,
        a2+a,a1+a+a,+0.0,
        a2-a,a1+a+a,+0.0,
        a2-a,a1+a-a,+0.0,

        a3+a,a1+a-a,+0.0,
        a3+a,a1+a+a,+0.0,
        a3-a,a1+a+a,+0.0,
        a3-a,a1+a-a,+0.0,
        };
    int     tabtxr[24]=
        {
        4,0,3,7,    // D
        1,5,6,2,    // U
        3,2,6,7,    // W
        0,1,2,3,    // N
        4,5,1,0,    // E
        7,6,5,4,    // S
        };
    int     tabver[24]=
        {
        0,1,2,3,
        4,5,6,7,
        8,9,10,11,
        12,13,14,15,
        16,17,18,19,
        20,21,22,23,
        };
    glColor3f(1,1,1);
    glBegin(GL_QUADS);
    for (i=23;i>=0;i--)
        {
        j=tabtxr[i];
        glMultiTexCoord3dv(GL_TEXTURE0+unit,pnttxr[j]);
        j=tabver[i];
        glVertex3dv(pntver[j]);
        }
    glEnd();
    }

这是预览图:

preview


为什么在pnttxr中使用sqrt(3)?glMultiTexCoord3dv是否会对该向量进行归一化? - Irbis
@Irbis 是的,立方体贴图会自行归一化向量,因此您可以使用1.0。我只在其中放入sqrt(3.0)是因为它只是常数,不需要额外的计算,当我几年后查看其中的内容时,它会让我知道这是一个向量而不是位置... - Spektre
当我使用你的示例中的坐标时,每个面的y视图都会翻转。我使用freeimage库加载纹理。以下教程也使用与你的示例相同的坐标:https://learnopengl.com/Advanced-OpenGL/Cubemaps 当我在教程代码中使用freeimage而不是stb image时,我也得到了翻转的y视图。发生了什么? - Irbis
@Irbis,你很可能有不同的投影或模型视图矩阵... 你可以在顶点坐标中反转y轴(将y轴的最后一个+/-a改为-/+a)以匹配你的矩阵,或者通过在模型视图中缩放y轴来实现-1。也可能是你的纹理与我的相比被加载反转了... - Spektre
请看这个链接:https://dev59.com/7mgt5IYBdhLWcg3w-SBM 现在我比以前更困惑了,看起来你的例子翻转了y坐标。 - Irbis
@Irbis 哦,现在我明白了,我正在使用自己的纹理加载器,而且立方体贴图的处理方式与其他纹理略有不同,所以我很可能没有在我的引擎中翻转y轴...(你知道对于图像来说,(0,0)是左上角是标准的,但在GL中不是...)不要紧,你仍然可以翻转以匹配你需要的内容,无论是在加载还是渲染时都可以...我认为你甚至可以翻转GL_TEXTURE矩阵,但不确定这是否适用于立方体贴图... - Spektre

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接