0

インデックスと頂点を使用して一連の三角形をグリッドの形で描画するコードがあります。すべての頂点はglDrawElements()を使用して描画されます。ここで、頂点ごとに、対応するテクスチャ座標を、グリッド内の正方形を形成する三角形のセットごとに 0 または 1 に設定します。基本的に、「正方形」(2 つの三角形で構成される) のそれぞれにランダムなテクスチャのコラージュを描きたいと考えています。glBegin()固定機能パイプラインを使用して for ループ内でandメソッド呼び出しを使用してこれを行うことができますが、 Vertex ArraysglEnd()を使用してこれを行う方法を知りたいです。私がやろうとしていることのコードビューを以下に示します。

#include "glwidget.h"

GLWidget::GLWidget(QWidget *parent, QGLWidget *glparent) :
    QGLWidget(parent, glparent),
    texture_ids_(NULL),
    col_(30),
    row_(30),
    step_(16.0)
{
    texture_ids_ = new GLuint[row_ * col_];
}

GLWidget::~GLWidget()
{
    if (texture_ids_) {
        glDeleteTextures(row_ * col_, texture_ids_);
    }
}

void GLWidget::resizeEvent(QResizeEvent * /*event*/) {
    initGL();

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glViewport(0, 0, width(), height());
    glOrtho(0, width(), 0, height(), -1, 1);
}

void GLWidget::initGL()
{
    makeCurrent();
    // Variables for vertices
    vertices_.clear();
    int32_t start_y = step_;
    int32_t start_x = step_;

    // Varaibles for indices
    indices_.clear();
    int32_t vertices_per_row = col_ + 1;
    int32_t vertex_num = 0;

    for (int32_t j = 0; j <= row_; ++j) {
        // Generate Vertices on row j
        for (int32_t i = 0; i <= col_; ++i) {
            vertices_.push_back(Vertex<GLfloat>((start_x + (i * step_)),
                (start_y + (j * step_)), 0.0f));
        }

        if (j == row_) {
            break;
        }

        // Generate Indices to get right vertices for traingle
        for (int32_t i = 0; i < col_; ++i) {
            indices_.push_back(Indices<GLuint>(vertex_num, (vertex_num + 1), 
                (vertex_num + vertices_per_row)));

            indices_.push_back(Indices<GLuint>((vertex_num + 1), 
                (vertex_num + vertices_per_row), 
                (vertex_num + vertices_per_row + 1)));

            vertex_num++;
        }
        vertex_num++;
    }
}


void GLWidget::textureInit()
{
    makeCurrent();
    for (int32_t i = 0; i < row_ * col_; ++i) {
        QImage tmpQImage(step_, step_, QImage::Format_ARGB32);
        tmpQImage = QGLWidget::convertToGLFormat(tmpQImage);

        QPainter tmpQPainter;
        tmpQPainter.begin(&tmpQImage);
            tmpQPainter.fillRect(QRect(0, 0, width(), height()),
                QColor(255, 0, 0));
            tmpQPainter.setRenderHint(QPainter::Antialiasing, true);
        tmpQPainter.end();

        glGenTextures(1, &texture_ids_[i]);
        glBindTexture(GL_TEXTURE_2D, texture_ids_[i]);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tmpQImage.width(),
            tmpQImage.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE,
            tmpQImage.bits());
    }
}

void GLWidget::updateGL() {
    if (first_render_) {
        textureInit();
        first_render_ = false;
    }

    glMatrixMode(GL_MODELVIEW);
    glScissor(0, 0, width(), height());
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
    glLoadIdentity();

    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, vertices_.data());
    glDrawElements(GL_TRIANGLES, indices_.size() * 3, GL_UNSIGNED_INT,
        indices_.data());
    glDisableClientState(GL_VERTEX_ARRAY);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
4

1 に答える 1

1

したがって、多くのテクスチャを使用して描画したいのですが、すべて 1 つの配列から描画されるため、明らかに新しいテクスチャを再バインドすることはできません。これに対する 1 つの解決策は、テクスチャ アトラスを使用することです。これは、すべてのテクスチャを内部に含む 1 つのビットマップです。たとえば、16 の異なるテクスチャがある場合、4x4 セクションでビットマップを作成します。0 から 1 のテクスチャ座標を使用する代わりに、0 から 0.25、または 0.25 から 0.50 などを使用します。

注意が必要な欠点がいくつかあります。

  1. 高解像度が必要な場合、テクスチャ アトラスは明らかに非常に大きくなります。
  2. 縮小と拡大は、あなたと一緒にトリックをすることができます。GL_NEAREST は問題ありませんが、GL_LINEAR またはミップマッピングのバリエーションを使用すると、ピクセルの周囲の値が平均化されます。これにより、1 つのサブ画像の境界でピクセルのアーティファクトが発生する可能性があります。
  3. UV 座標の変化が大きくなると、共通の頂点データを持つ頂点が少なくなり、インデックスの数が増加します。

描画を複数回繰り返し、それぞれのテクスチャを再バインドするだけでは不十分であることを示すプロファイリングを行ったと思います。この明白な解決策は、驚くほど効果的です。

于 2012-09-09T05:29:56.940 に答える