Текстурирование каждого полигона в массиве вершин - OpenGL

Я пытаюсь заставить мою функцию рендеринга работать. Я использую массивы вершин. Вот моя структура вершин.

struct Vertex 
{
    float x, y, z;              // The x, y and z floating point values     
    float u, v;                 // The u - v texture coordinates
    float padding[3];   // needs to be multiple of 32
};

Вот мой код рендеринга:

// Render the mesh
void WLD::render(GLuint* textures, long curRegion, CFrustum cfrustum)
{

    int num = 0;

    // Set up my indices
    GLuint indicies[3];

    // Cycle through the PVS
    while(num < regions[curRegion].visibility.size())
    {
        int i = regions[curRegion].visibility[num];

        if(!regions[i].dead && regions[i].meshptr != NULL)
        {
            if(cfrustum.BoxInFrustum(regions[i].meshptr->min[0], regions[i].meshptr->min[2], regions[i].meshptr->min[1], regions[i].meshptr->max[0], regions[i].meshptr->max[2], regions[i].meshptr->max[1]))
            {
                // Cycle through every polygon in the mesh and render it
                for(int j = 0; j < regions[i].meshptr->polygonCount; j++)
                {   
                    // Assign the index for the polygon to the index in the huge vertex array
                    indicies[0] = regions[i].meshptr->poly[j].vertIndex[0];
                    indicies[1] = regions[i].meshptr->poly[j].vertIndex[1];
                    indicies[2] = regions[i].meshptr->poly[j].vertIndex[2];

                    glEnableClientState(GL_VERTEX_ARRAY);
                    glVertexPointer(3, GL_FLOAT, sizeof(Vertex), &verticies[0].x);

                    // Texture index
                    int tex = regions[i].meshptr->poly[j].tex;
                    // Need to bind this to the polygon I render.

                    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
                    glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &verticies[0].u);
                    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, indicies);

                    glDisableClientState(GL_VERTEX_ARRAY);
                    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
                }
            }
        }
    num++;
    }
}

Один из аргументов, текстуры GLuint*, содержит все загруженные текстуры. Таким образом, значение, возвращаемое строкой int tex = region [i].meshptr->poly[j].tex; это индекс в текстурах для этого конкретного многоугольника. Как мне привязать это к каждому многоугольнику, когда я это отрисовываю? Дайте знать, если у вас появятся вопросы.

Я знаю, что мне нужно использовать glClientActiveTexture(), но во-первых, он говорит, что он не определен, и я не могу найти правильный заголовок, и во-вторых, я понятия не имею, как он используется. Я не смог найти хороших примеров. Итак, как мне, если, скажем, полигон ссылается на индекс текстуры 4, привязать его к полигону при рендеринге с помощью glClientActiveTexture.

2 ответа

То, что вы пытаетесь сделать, не всегда возможно. Вы обычно не пытаетесь визуализировать один поток треугольников (glDraw* вызов) с несколькими текстурами. Ну, не так, как вы имеете в виду, во всяком случае.

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

Общее решение состоит в том, чтобы объединить изображения в одну текстуру. Это обычно называют "текстурным атласом". В этом случае координаты текстуры на вершинах описывают, откуда в текстурном атласе (который является единственной текстурой) извлекать данные изображения.

Если вы используете аппаратное обеспечение с поддержкой GL 4.0 (D3D11) и GLSL, есть некоторые приемы, которые вы можете использовать для динамического выбора между 16 текстурами на основе произвольных вычислений. А для более раннего оборудования вы можете использовать шейдеры для выбора между текстурами. Но оба случая будут медленнее, чем просто массировать данные должным образом.

Вы можете сделать это с помощью вашего правильного подхода. Вам не нужно glClientActiveTexture, Эта функция предназначена для мультитекстурирования, и я предполагаю, что к каждому полигону применяется только одна текстура. Так что просто свяжите необходимую текстуру, используя glBindTexture(GL_TEXTURE_2D, textures[tex]) и не забудьте glEnable(GL_TEXTURE_2D) (если не использовать шейдеры) перед рисованием многоугольника.

Но хотя это работает, это, очевидно, не лучший способ сделать это. Вершинные массивы предназначены для визуализации нескольких примитивов (треугольников) за один раз (один вызов glDrawElements) и вы их не используете, чтобы сделать отдельные треугольники. Первой и самой простой идеей было бы, по крайней мере, отсортировать полигоны по индексу текстуры, а затем визуализировать все треугольники с одинаковой текстурой за один вызов. glDrawElements, Посмотрите на ответ Николя для более продвинутых подходов.

Другие вопросы по тегам