4

I have an opengl cube and I want to texture all 6 faces.

Do I need multiple textures?

Here's a screenshot of the current cube:

img

basically I don't know how to wrap the texture around the entire cube...

here's my cube.h header file where the IBO's and VBO's are defined

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

all this code does is set up a simple VBO and IBO/EBO for a cube object to later be used.

genpfault
  • 51,148
  • 11
  • 85
  • 139
Jcsq6
  • 474
  • 1
  • 4
  • 15
  • 2
    simplest it to duplicate vertexes as the same vertex have different texture coordinates for each side ... so instead of `8*5=40` you should have `6*4*5=120` items in your buffer. If you use single texture with all 6 sides (like paper cutout models) or full texture for single side then you need to duplicate just the points where the texture coordinate is different among faces lowering the 120 a lot. For more info see [How do I sort the texture positions based on the texture indices given in a Wavefront (.obj) file?](https://stackoverflow.com/a/51722009/2521214) – Spektre May 05 '20 at 10:31
  • Another option is to use 2 indices one for Vertex and one for TexCoord and having just 8*3 for points and 4*2 or 6*4*2 for textures but that needs shaders to work. – Spektre May 05 '20 at 10:32
  • @Spektre could you write up what that would be in implementation? I'm a little confused on exactly what you mean... – Jcsq6 May 05 '20 at 15:50
  • @Jcsq6 You have to specify separate tuples of vertices and associated texture coordinates for each side of the cube. You can't use indices. Each of the 6 sides of the cube consists of 4 tuples with 5 components (x, y, z, u, v). See also [How do I wrap a sprite around a cube without GL_REPEAT?](https://stackoverflow.com/questions/47977887/how-do-i-wrap-a-sprite-around-a-cube-without-gl-repeat/47983294#47983294) – Rabbid76 May 05 '20 at 16:56
  • @Rabbid76 I'm sorry but I still don't seem to understand. I'm using the (x, y, z u, v) format. are you saying I shouldn't be using an IBO? – Jcsq6 May 05 '20 at 17:12
  • @Rabbid76 if you don't mind, could you write an answer of the desired code? While I understand what is being said about needing to have multiple vertices, I don't know how to implement it without an IBO... and I also don't know how to render it without the IBO. would you still call this function-glDrawElements(GL_TRIANGLES, indicesCount, GL_UNSIGNED_INT, 0); or not... I'm sorry for the trouble, I'm just now learning opengl – Jcsq6 May 05 '20 at 17:22
  • @Rabbid76 Do I need to have GL_TRIANGLES still? or would i put it as something else. and without the ibo do i need to format it as triangles still in the vbo? – Jcsq6 May 05 '20 at 17:27

1 Answers1

2

the problem is that each cube vertex is shared among 3 faces in which its texture coordinate might not be the same. So you either duplicate such vertexes (each with different texture coordinate) or use 2 separate indices (one for vertex and one for texture).

The duplication might look like this (using GL_QUADS primitive):

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

With this texture:

texture

And this (sory for old GL api but its easier to test with):

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

I got this result:

preview

Spektre
  • 49,595
  • 11
  • 110
  • 380