2012-09-09 1 views
0

인덱스와 정점을 사용하여 그리드 모양의 삼각형 집합을 그리는 코드가 있습니다. 모든 정점은 glDrawElements()을 사용하여 그려집니다. 이제 각 정점에 대해 그리드의 정사각형을 형성하는 각 삼각형 세트에 대해 해당하는 텍스처 좌표를 0 또는 1로 설정합니다. 기본적으로 "사각형"(두 개의 삼각형으로 구성) 각각에 임의의 텍스처로 collage 개의 그림을 그려야합니다. 고정 기능 파이프 라인을 사용하여 for 루프 내에서 glBegin()glEnd() 메서드 호출을 사용하여이 작업을 수행 할 수 있지만 Vertex Arrays을 사용하여이 작업을 수행하는 방법을 알고 싶습니다. 내가하려고하는 것에 대한 코드보기는 아래에서 볼 수 있습니다.OpenGL은 텍스처를 정점 배열 안에 저장된 격자에 매핑합니다.

#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); 
} 
+0

그래서 ... 문제가 뭐니? –

+0

for 루프없이 여러 텍스처를 격자 내에서 매핑하는 방법은 무엇입니까? –

+0

* for 루프와 함께 * 그리드 내의 여러 텍스처를 어떻게 매핑합니까? 쿼드를 그린 다음 새로운 텍스처를 바인딩 한 다음 새로운 쿼드를 그리는 것에 대해 이야기하고 있습니까? 아니면 여러 독립 쿼드를 그리는 것에 대해 이야기하고 있습니까? –

답변

1

그래서, 당신은 텍스처를 많이 사용 그리려는,하지만 당신은 분명히 다시 결합 할 수없는 새로운 텍스처가 모두 하나 개의 배열에서 그려있다. 이에 대한 한 가지 해결책은 texture atlas을 사용하는 것입니다. 그 안에 모든 텍스처가 포함 된 단일 비트 맵입니다. 예를 들어 16 가지 텍스처가있는 경우 4x4 섹션으로 비트 맵을 만듭니다. 대신 0에서 1 텍스처 좌표를 사용하여, 당신은 0.25-0, 또는 0.50-0.25를 사용하는 등

당신이 알아야 할 몇 가지 단점이 있습니다

당신이 원하는 경우
  1. 고해상도 , 텍스처 아트라스는 분명히 아주 커질 것입니다.
  2. 확대 및 확대는 당신과 함께 트릭을 재생할 수 있습니다. GL_NEAREST는 아무런 문제가되지 않지만 GL_LINEAR 또는 밉 매핑의 변형을 사용하면 픽셀 주변의 평균 값을 얻게됩니다. 이는 하나의 서브 이미지의 경계에있는 픽셀에 대한 아티팩트로 이어질 수 있습니다.
  3. UV 좌표가 더 많이 변하므로 더 적은 수의 꼭지점이 공통의 꼭지점 데이터를 가지므로 인덱스 수가 증가합니다.

각각의 텍스처를 리바 인딩하는 드로잉을 여러 번 사용하면 충분하지 않음을 보여주는 프로파일 링을 수행했다고 가정합니다. 이 명백한 해결책은 놀라 울 정도로 효과적 일 수 있습니다.

+0

배열 텍스처는 어떻습니까? 이것이 옵션일까요? http://www.opengl.org/wiki/Array_Texture –

+0

예, 그들은 똑같은 일을 할 것입니다. 그것들을 사용하려면 3 개의 UV 숫자가 필요합니다 (좌표와 배열 인덱스 각각 2 개). 그러나 국경 문제의 단점은 없습니다. –