Каковы координаты текстуры для куба в OpenGL? - PullRequest
4 голосов
/ 13 февраля 2011

У меня есть куб, определенный как:

float vertices[] = { -width, -height, -depth, // 0
                              width, -height, -depth, // 1
                              width,  height, -depth, // 2
                             -width,  height, -depth, // 3
                             -width, -height,  depth, // 4
                              width, -height,  depth, // 5
                              width,  height,  depth, // 6
                             -width,  height,  depth // 7
        };  

и у меня есть изображение 128x128, которое я просто хочу нарисовать на каждой из 6 граней куба и ничего больше. Так что же такое текстура, координированная? Мне нужны реальные значения.

Это код чертежа:

// Counter-clockwise winding.
        gl.glFrontFace(GL10.GL_CCW);
        // Enable face culling.
        gl.glEnable(GL10.GL_CULL_FACE);
        // What faces to remove with the face culling.
        gl.glCullFace(GL10.GL_BACK);
        // Enabled the vertices buffer for writing and to be used during
        // rendering.
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

        // Specifies the location and data format of an array of vertex
        // coordinates to use when rendering.
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVerticesBuffer);


            // Bind the texture according to the set texture filter
            gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[filter]);
            gl.glEnable(GL10.GL_TEXTURE_2D);



            // Enable the texture state
            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

            // Point to our buffers
            gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTextureBuffer);



        // Set flat color
        gl.glColor4f(red, green, blue, alpha);


        gl.glDrawElements(GL10.GL_TRIANGLES, mNumOfIndices,
                GL10.GL_UNSIGNED_SHORT, mIndicesBuffer);

        // ALL the DRAWING IS DONE NOW

        // Disable the vertices buffer.
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);


            gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);


        // Disable face culling.
        gl.glDisable(GL10.GL_CULL_FACE);

Это индексный массив:

short indices[] = { 0, 2, 1,
                0, 3, 2,

                1,2,6,
                6,5,1,

                4,5,6,
                6,7,4,

                2,3,6,
                6,3,7,

                0,7,3,
                0,4,7,

                0,1,5,
                0,5,4


               };  

Я не уверен, нужен ли индексный массив для поиска текстовых координат. Обратите внимание, что массив вершин куба, который я дал, является наиболее эффективным представлением куба с использованием массива индекса. Куб рисует отлично, но не текстуры. Только одна сторона показывает правильную картину, но другие перепутаны. Я использовал методы, описанные в различных онлайн-учебниках по текстурам, но это не работает.

Ответы [ 5 ]

7 голосов
/ 13 февраля 2011

То, что вы ищете, это карта куба . В OpenGL вы можете определить шесть текстур одновременно (представляющих стороны размера куба) и отобразить их, используя координаты 3D-текстуры вместо общих координат 2D-текстуры. Для простого куба координаты текстуры будут такими же, как и соответствующие нормали вершин. (Если вы будете таким образом текстурировать только плоские кубы, вы также можете консолидировать нормали и координаты текстуры в своем вершинном шейдере!) Карты кубов намного проще, чем пытаться применять одну и ту же текстуру к повторяющимся квадрам (дополнительные ненужные шаги рисования).

GLuint mHandle;
glGenTextures(1, &mHandle); // create your texture normally

// Note the target being used instead of GL_TEXTURE_2D!
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glBindTexture(GL_TEXTURE_CUBE_MAP, mHandle);

// Now, load in your six distinct images. They need to be the same dimensions!
// Notice the targets being specified: the six sides of the cube map.
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, width, height, 0,
    format, GL_UNSIGNED_BYTE, data1);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, width, height, 0,
    format, GL_UNSIGNED_BYTE, data2);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, width, height, 0,
    format, GL_UNSIGNED_BYTE, data3);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, width, height, 0,
    format, GL_UNSIGNED_BYTE, data4);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, width, height, 0,
    format, GL_UNSIGNED_BYTE, data5);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, width, height, 0,
    format, GL_UNSIGNED_BYTE, data6);

glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

// And of course, after you are all done using the textures...
glDeleteTextures(1, &mHandle);

При указании координат текстуры вы будете использовать наборы из 3 координат вместо наборов из 2. В простом кубе вы указываете на 8 углов, используя нормализованные векторы. Если N = 1,0 / sqrt (3,0), то одним углом будет N, N, N; другой будет N, N, -N; и т.д.

4 голосов
/ 13 февраля 2011
  1. Вам нужно определить, какую ориентацию вы хотите на каждой грани (и это изменит то, какие координаты текстуры будут наложены на каждую вершину)
  2. Вам нужно продублировать позиции вершин, как тот же угол кубаиметь разные текстурные координаты в зависимости от того, какая грань является частью
  3. , если вам нужна полная текстура на каждой грани, то текстурные координаты равны (0, 0) (0, 1) (1, 1) (10).То, как вы сопоставите их с конкретными вершинами (24 из них, 4 на грани), зависит от желаемой ориентации.
3 голосов
/ 13 февраля 2011

Для меня проще рассмотреть ваши вершины как ширина = х, высота = у и глубина = z.Тогда просто получить 6 граней.

float vertices[] = { -x, -y, -z, // 0
                              x, -y, -z, // 1
                              x,  y, -z, // 2
                             -x,  y, -z, // 3
                             -x, -y,  z, // 4
                              x, -y,  z, // 5
                              x,  y,  z, // 6
                             -x,  y,  z// 7
        };  

Например, передняя грань вашего куба будет иметь положительную глубину (центр этого куба находится в 0,0,0 от вершин, которые выкак указано выше), теперь, поскольку имеется 8 точек с 4 положительными глубинами, ваша передняя грань равна 4,5,6,7, это происходит от -x, -y против часовой стрелки до -x, y.

Итак, все ваше заднее лицо имеет отрицательную глубину или -z, так что это просто 0,1,2,3.

Видите картинку?Ваше левое лицо имеет всю отрицательную ширину или -х, так что 0,3,4,7, а ваше правое лицо - положительное х, так что 1,2,5,6.

Я дам вам понять верх идно куба.

2 голосов
/ 13 февраля 2011

Ваш массив вершин описывает только 2 стороны куба, но для аргументов, скажем, вершины [0] - вершины [3] описывают 1 сторону, тогда ваши координаты текстуры могут быть:

float texCoords[] = { 0.0, 0.0,  //bottom left of texture
                      1.0, 0.0,  //bottom right "    "
                      1.0, 1.0,  //top right    "    "
                      0.0, 1.0   //top left     "    "
                    };

Вы можете использовать эти координаты для текстурирования каждой последующей стороны всей текстурой.

0 голосов
/ 18 декабря 2014

Для рендеринга скайбокса (cubemap) у меня работает следующий шейдер:

Cubemap vertexshader::
        attribute vec4 a_position;             
        varying vec3 v_cubemapTexture;          
        vec3 texture_pos;                           
        uniform vec3 u_cubeCenterPt;            
        uniform mat4 mvp;                       
        void main(void)                     
        {                                       
         gl_Position = mvp * a_position;        
         texture_pos = vec3(a_position.x - u_cubeCenterPt.x, a_position.y - u_cubeCenterPt.y, a_position.z - u_cubeCenterPt.z);
         v_cubemapTexture = normalize(texture_pos.xyz); 
        }                                       

Cubemap fragmentshader::
        precision highp float;                                              
        varying vec3 v_cubemapTexture;                                      
        uniform samplerCube cubeMapTextureSample;                           
        void main(void)                                                 
        {                                                                   
          gl_FragColor = textureCube(cubeMapTextureSample, v_cubemapTexture);  
        }

Надеюсь, это полезно ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...