【问题标题】:Texturing an opengl cube纹理一个opengl立方体
【发布时间】:2020-08-19 13:57:41
【问题描述】:

我有一个 opengl 立方体,我想为所有 6 个面设置纹理。

我需要多个纹理吗?

这是当前立方体的截图:

基本上我不知道如何将纹理包裹在整个立方体周围...

这是我定义 IBO 和 VBO 的 cube.h 头文件

#pragma once
#include <GL\glew.h>

class cube {
public:
    cube() {
        x = 0;
        y = 0;
        z = 0;
        width = 0;
        vertices = 0;
        indices = 0;
    }
    cube(GLfloat X, GLfloat Y, GLfloat Z, float w) {
        x = X;
        y = Y;
        z = Z;
        width = w;

        vertices = new GLfloat[40];

        //1
        vertices[0] = x;     //x pos
        vertices[1] = y;     //y pos
        vertices[2] = z;     //z pos

        vertices[3] = 0;     //x pos in texture
        vertices[4] = 1;     //y pos in texture
        //2
        vertices[5] = x + width;
        vertices[6] = y;
        vertices[7] = z;

        vertices[8] = 1;
        vertices[9] = 1;
        //3
        vertices[10] = x;
        vertices[11] = y - width;
        vertices[12] = z;

        vertices[13] = 0;
        vertices[14] = 0;
        //4
        vertices[15] = x + width;
        vertices[16] = y - width;
        vertices[17] = z;

        vertices[18] = 1;
        vertices[19] = 0;
        //5
        vertices[20] = x;
        vertices[21] = y;
        vertices[22] = z - width;

        vertices[23] = 0;
        vertices[24] = 1;
        //6
        vertices[25] = x + width;
        vertices[26] = y;
        vertices[27] = z - width;

        vertices[28] = 1;
        vertices[29] = 1;
        //7
        vertices[30] = x;
        vertices[31] = y - width;
        vertices[32] = z - width;

        vertices[33] = 0;
        vertices[34] = 0;
        //8
        vertices[35] = x + width;
        vertices[36] = y - width;
        vertices[37] = z - width;

        vertices[38] = 1;
        vertices[39] = 0;

        //indices
        indices = new unsigned int[36];
        //0
        indices[0] = 0;
        indices[1] = 1;
        indices[2] = 2;
        //1
        indices[3] = 1;
        indices[4] = 2;
        indices[5] = 3;
        //2
        indices[6] = 4;
        indices[7] = 5;
        indices[8] = 6;
        //3
        indices[9] = 5;
        indices[10] = 6;
        indices[11] = 7;
        //4
        indices[12] = 4;
        indices[13] = 0;
        indices[14] = 1;
        //5
        indices[15] = 4;
        indices[16] = 5;
        indices[17] = 1;
        //6
        indices[18] = 6;
        indices[19] = 2;
        indices[20] = 3;
        //7
        indices[21] = 6;
        indices[22] = 7;
        indices[23] = 3;
        //8
        indices[24] = 1;
        indices[25] = 5;
        indices[26] = 3;
        //9
        indices[27] = 5;
        indices[28] = 7;
        indices[29] = 3;
        //10
        indices[30] = 4;
        indices[31] = 0;
        indices[32] = 2;
        //11
        indices[33] = 4;
        indices[34] = 6;
        indices[35] = 2;
    }

    GLfloat* vertices;
    unsigned int* indices;
private:
    GLfloat x;
    GLfloat y;
    GLfloat z;
    float width;
};

这段代码所做的只是为以后使用的多维数据集对象设置一个简单的 VBO 和 IBO/EBO。

【问题讨论】:

  • 最简单的方法是复制顶点,因为同一个顶点的每一侧都有不同的纹理坐标......所以你的缓冲区中应该有6*4*5=120而不是8*5=40。如果您使用所有 6 个面的单一纹理(如剪纸模型)或单面的完整纹理,那么您只需复制纹理坐标在面之间不同的点,从而降低 120 很多。欲了解更多信息,请参阅How do I sort the texture positions based on the texture indices given in a Wavefront (.obj) file?
  • 另一种选择是使用 2 个索引,一个用于顶点,一个用于 TexCoord,点只有 8*3,纹理只有 4*2 或 6*4*2,但这需要着色器才能工作。
  • @Spektre 你能写出实施中的内容吗?我对你的意思有点困惑......
  • @Jcsq6 您必须为立方体的每一侧指定单独的顶点元组和关联的纹理坐标。你不能使用索引。立方体的 6 个面中的每一个都由 4 个元组和 5 个分量(x、y、z、u、v)组成。另请参阅How do I wrap a sprite around a cube without GL_REPEAT?
  • @Rabbid76 很抱歉,但我似乎还是不明白。我使用的是 (x, y, z u, v) 格式。你是说我不应该使用 IBO?

标签: c++ opengl sdl-2 glew


【解决方案1】:

问题在于每个立方体顶点在其纹理坐标可能不同的 3 个面之间共享。因此,您要么复制此类顶点(每个顶点具有不同的纹理坐标),要么使用 2 个单独的索引(一个用于顶点,一个用于纹理)。

复制可能如下所示(使用GL_QUADS 原语):

double cube[]=
    {
    // x,   y,   z,  s,  t,
    +1.0,-1.0,-1.0,0.0,1.0,
    -1.0,-1.0,-1.0,1.0,1.0,
    -1.0,+1.0,-1.0,1.0,0.0,
    +1.0,+1.0,-1.0,0.0,0.0,

    -1.0,+1.0,-1.0,0.0,0.0,
    -1.0,-1.0,-1.0,0.0,1.0,
    -1.0,-1.0,+1.0,1.0,1.0,
    -1.0,+1.0,+1.0,1.0,0.0,

    -1.0,-1.0,+1.0,0.0,1.0,
    +1.0,-1.0,+1.0,1.0,1.0,
    +1.0,+1.0,+1.0,1.0,0.0,
    -1.0,+1.0,+1.0,0.0,0.0,

    +1.0,-1.0,-1.0,1.0,1.0,
    +1.0,+1.0,-1.0,1.0,0.0,
    +1.0,+1.0,+1.0,0.0,0.0,
    +1.0,-1.0,+1.0,0.0,1.0,

    +1.0,+1.0,-1.0,0.0,1.0,
    -1.0,+1.0,-1.0,1.0,1.0,
    -1.0,+1.0,+1.0,1.0,0.0,
    +1.0,+1.0,+1.0,0.0,0.0,

    +1.0,-1.0,+1.0,0.0,0.0,
    -1.0,-1.0,+1.0,1.0,0.0,
    -1.0,-1.0,-1.0,1.0,1.0,
    +1.0,-1.0,-1.0,0.0,1.0,
    };

使用这种纹理:

还有这个(对不起,旧的 GL api,但更容易测试):

int i,n=sizeof(cube)/(sizeof(cube[0]));
glColor3f(1.0,1.0,1.0);
scr.txrs.bind(txr);
glBegin(GL_QUADS);
for (i=0;i<n;i+=5)
    {
    glTexCoord2dv(cube+i+3);
    glVertex3dv(cube+i+0);
    }
glEnd();
scr.txrs.unbind();

我得到了这个结果:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-08
    相关资源
    最近更新 更多