Отображение квадратной текстуры в треугольник - PullRequest
1 голос
/ 30 ноября 2010

Я начал играть с OpenGL ES 1.0 и столкнулся с некоторой проблемой (для начинающих): я попытался сопоставить квадратную текстуру с кубом, описываемым треугольниками.

    // Turn necessary features on
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_SRC_COLOR);
    glEnable(GL_CULL_FACE);
    //glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);  

    // Bind the number of textures we need, in this case one.
    glGenTextures(1, &texture[0]);
    glBindTexture(GL_TEXTURE_2D, texture[0]);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

//Drawing code
static GLfloat rot = 0.0;

static const Vertex3D vertices[] = {
    -1.0f,-1.0f,-1.0f, //0  00  
     1.0f,-1.0f,-1.0f, //1  10
     1.0f, 1.0f,-1.0f, //2  11
    -1.0f, 1.0f,-1.0f, //3  01      
};


static const int vertexCnt = 3 * 2;

static const GLubyte cube[] = {
    3,0,2,
    1,2,0,
};

static const GLfloat texCoords[] = {
    0,1,
    0,0,
    1,1,
    1,0,
    1,1,
    0,0,
};


glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();

glTranslatef(0.0f, 0.0f, -3.0f);

glBindTexture(GL_TEXTURE_2D, texture[0]);

glEnableClientState(GL_VERTEX_ARRAY);
//glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_COLOR_MATERIAL);


glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glVertexPointer(3, GL_FLOAT, 0, vertices);

//glColorPointer(4, GL_FLOAT, 0, colors);
glNormalPointer(GL_FLOAT, 0, normals);



glDrawElements(GL_TRIANGLES, vertexCnt, GL_UNSIGNED_BYTE, cube);


glDisableClientState(GL_VERTEX_ARRAY);
//glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);

Теперь, после миллионной попытки, я просто не могу заставить ее работать на другие стороны ... Есть ли какое-то практическое правило для случая, когда квадратная текстура отображается на треугольники?

РЕДАКТИРОВАТЬ: Я думаю, я выясняю, как должно быть сделано сопоставление.Но это не работает для этого примера (одно лицо).Может кто-то просто проверить, правильно ли я сделал отображение (при условии, что остальная часть кода работает)?

Большое спасибо

Ответы [ 2 ]

1 голос
/ 07 декабря 2010

Точно так же, как и другие, я не думаю, что есть хитрость, чтобы отобразить ваши четырехугольные текстуры на треугольники.

Основная проблема, с которой вы сталкиваетесь, из-за разрывов в текстурных координатах для каждого угла. Если один угол равен некоторым UV-координатам {u, v} для одной грани, это не значит, что он будет иметь такое же значение для двух других граней, которые разделяют вершину. Можно найти отображение так, чтобы UV было уникальным в каждом углу куба (совместно используемом 3 гранями) и чтобы все 4 значения UV ({0,0}, {1,0}, {1,1} и {0,1}) присутствуют на каждой грани, но тогда некоторые текстуры будут полностью искажены. Попробуйте проверить это на листе бумаги: {1,1} не всегда противоположно {0,0}.

Проще всего начать с явного объявления 6 квадов, каждый из которых состоит из 2 треугольников. Это дает вам в общей сложности 24 вершины (24 позиции и 24 текс-координаты, с чередованием или нет) и 36 индексов (6 четырехугольников, состоящих из двух треугольников, 6 * 2 * 3 = 36).

Вот ваш код, обновленный для отображения куба (возможно, возникла некоторая проблема с намоткой, поэтому я, конечно, отключил выборку лица):

glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);

static const float vertices[] = {
        0.0f, 1.0f, 0.0f,
        1.0f, 1.0f, 0.0f,
        0.0f, 0.0f, 0.0f,
        1.0f, 0.0f, 0.0f,

        0.0f, 1.0f, 1.0f,
        0.0f, 0.0f, 1.0f,
        1.0f, 1.0f, 1.0f,
        1.0f, 0.0f, 1.0f,

        0.0f, 1.0f, 1.0f,
        1.0f, 1.0f, 1.0f,
        0.0f, 1.0f, 0.0f,
        1.0f, 1.0f, 0.0f,

        0.0f, 0.0f, 1.0f,
        0.0f, 0.0f, 0.0f,
        1.0f, 0.0f, 1.0f,
        1.0f, 0.0f, 0.0f,

        1.0f, 1.0f, 0.0f,
        1.0f, 1.0f, 1.0f,
        1.0f, 0.0f, 0.0f,
        1.0f, 0.0f, 1.0f,

        0.0f, 1.0f, 0.0f,
        0.0f, 0.0f, 0.0f,
        0.0f, 1.0f, 1.0f,
        0.0f, 0.0f, 1.0f
        };


static const int vertexCnt = 6 * 4;

static const GLubyte cube[] = {
     0,  1,  2,  1,  2,  3,
     4,  5,  6,  5,  6,  7,
     8,  9, 10,  9, 10, 11,
    12, 13, 14, 13, 14, 15,
    16, 17, 18, 17, 18, 19,
    20, 21, 22, 21, 22, 23 
};

static const GLfloat texCoords[] = {
    0.0f, 0.0f,
    1.0f, 0.0f,
    0.0f, 1.0f,
    1.0f, 1.0f,

    1.0f, 0.0f,
    1.0f, 1.0f,
    0.0f, 0.0f,
    0.0f, 1.0f,

    0.0f, 0.0f,
    1.0f, 0.0f,
    0.0f, 1.0f,
    1.0f, 1.0f,

    0.0f, 1.0f,
    0.0f, 0.0f,
    1.0f, 1.0f,
    1.0f, 0.0f,

    0.0f, 0.0f,
    1.0f, 0.0f,
    0.0f, 1.0f,
    1.0f, 1.0f,

    1.0f, 0.0f,
    1.0f, 1.0f,
    0.0f, 0.0f,
    0.0f, 1.0f
    };

glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//glLoadIdentity();

//glTranslatef(0.0f, 0.0f, -3.0f);
glRotatef(3.1415927f, 1.0f, 1.0f, 0.0f);

glBindTexture(GL_TEXTURE_2D, spriteTexture);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glVertexPointer(3, GL_FLOAT, 0, vertices);

glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, cube);
1 голос
/ 30 ноября 2010

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

Что касается самих координат текстуры, не должно быть хитрости с отображением треугольников по сравнению с квадратами.Вам просто нужно иметь 6 текстурных координат, где раньше у вас было бы четыре, поскольку есть 6 вершин (по две дубликата на грани).Вы можете избежать дублирования, используя индексный буфер, как это было с вашим кубом.

Что касается потенциальной проблемы отбраковки задней поверхности, вы должны каждый раз определять свои вершины в одном и том же порядке.Все по часовой стрелке относительно направления текстуры или все против часовой стрелки.

Какие команды вы используете для настройки конвейера OpenGL, и какие команды вы используете для рисования этих вершин?Пожалуйста, добавьте соответствующий код к вопросу.

...