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

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

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 ]

3 голосов
/ 08 августа 2011

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

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

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

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

1 голос
/ 08 августа 2011

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

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

...