遗留 opengl - 渲染立方体地图布局,了解 glTexCoord3f 参数

Posted

技术标签:

【中文标题】遗留 opengl - 渲染立方体地图布局,了解 glTexCoord3f 参数【英文标题】:legacy opengl - rendering cube map layout, understanding glTexCoord3f parameters 【发布时间】:2019-09-26 22:36:52 【问题描述】:

我想渲染一个立方体地图布局(正交投影) - 类似于 this。让我们关注+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 值对于前两个顶点为正,而对于下一个顶点为负,根据我的理解它应该是相反的(我想我观察立方体面来自立方体中心)。

【问题讨论】:

【参考方案1】:

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

我过去也有同样的困难...GL_TEXTURE_CUBE_MAP很难开始...

为了让事情变得更简单,我在旧 API(来自我的引擎的 C++ 成员)中为这些人渲染:

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();
    

这里预览:

【讨论】:

为什么要使用 sqrt(3) 来处理 pnttxr ? glMultiTexCoord3dv 是否规范化该向量? @Irbis 是的,立方体贴图会自行对矢量进行归一化,因此您可以改用 1.0。我把sqrt(3.0) 放在那里只是因为它只是常数,所以没有进行额外的计算,而且当我在几年后查看这些东西时,它会打到我它的向量而不是位置...... 当我从你的例子中应用坐标时,我得到了每张脸的倒置 y 视图。我使用freeimage lib加载纹理。以下教程也使用与您的示例相同的坐标:learnopengl.com/Advanced-OpenGL/Cubemaps 当我在教程代码中使用 freeimage 而不是 stb 图像时,我也会得到倒置的 y 视图。这是怎么回事? @Irbis 您很可能有不同的投影或模型视图矩阵...您可以在顶点坐标中反转 y 轴(在 y 轴上将最后一个 +/-a 更改为 -/+a)以匹配您的或缩放 y在-1 的模型视图中。与我的相比,也可能是您的纹理被倒置加载... 请看一下:***.com/questions/11685608/… 知道我比以前更困惑了,看起来你的示例已经填充了 y 坐标。

以上是关于遗留 opengl - 渲染立方体地图布局,了解 glTexCoord3f 参数的主要内容,如果未能解决你的问题,请参考以下文章

VBO 最佳方法 OpenGL

Opengl:渲染到立方体贴图?

为啥正面剔除用 OpenGL 渲染立方体?

Opengl 3d立方体不渲染

渲染动态立方体贴图 (OpenGL)

OpenGL:渲染天空盒立方体贴图问题