Текстуриране на VBOs (вертексни буферни обекти)

В момента работя върху процедурен инструмент за генериране на планети, който работи, като взема куб, картографира го в сфера и след това прилага карта на височината към всяко лице, за да генерира терен.

Използвам VBO за всяко лице, което се създава по следния метод:

void Planet::setVertexBufferObject()
{
 Vertex* vertices;
 int currentVertex;
 Vertex* vertex;

 for(int i = 0; i < 6; i++)
 {
  // bottom face
  if(i == 0)
  {
   glBindBuffer(GL_ARRAY_BUFFER, bottomVBO);    
  }
  // top face
  else if(i == 1)
  {
   glBindBuffer(GL_ARRAY_BUFFER, topVBO);    
  }
  // front face
  else if(i == 2)
  {
   glBindBuffer(GL_ARRAY_BUFFER, frontVBO);    
  }
  // back face
  else if(i == 3)
  {
   glBindBuffer(GL_ARRAY_BUFFER, backVBO);    
  }
  // left face
  else if(i == 4)
  {
   glBindBuffer(GL_ARRAY_BUFFER, leftVBO);    
  }
  // right face
  else
  {
   glBindBuffer(GL_ARRAY_BUFFER, rightVBO);    
  } 

  vertices = (Vertex*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);

  currentVertex = 0;

  for(int x = 0; x < size; x++)
  {
   for(int z = 0; z < size; z++)
   {
    currentVertex = z * size + x;

    vertex = &vertices[currentVertex];

    vertex->xTextureCoord = (x * 1.0f) / 512.0f;
    vertex->zTextureCoord = (z * 1.0f) / 512.0f;

    Vector3 normal;

    vertex->xNormal = normal.x;
    vertex->yNormal = normal.y;
    vertex->zNormal = normal.z;

    vertex->x = heightMapCubeFace[i][x][z][0];
    vertex->y = heightMapCubeFace[i][x][z][1];
    vertex->z = heightMapCubeFace[i][x][z][2];

    vertex->x *= (1.0f +((heightMaps[i][z][x]/256.0f) * 0.1));
    vertex->y *= (1.0f +((heightMaps[i][z][x]/256.0f) * 0.1));
    vertex->z *= (1.0f +((heightMaps[i][z][x]/256.0f) * 0.1));
   }
  }
  glUnmapBuffer(GL_ARRAY_BUFFER);
  glBindBuffer(GL_ARRAY_BUFFER, 0);
 }
}

Изоставих метода setIndexBufferObject(), тъй като той работи добре.

След това изобразявам сферата, използвайки този метод:

void Planet::render()
{
    // bottom face

    glBindBuffer(GL_ARRAY_BUFFER, bottomVBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bottomIBO);

    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(6 * sizeof(float)));

    glEnableClientState(GL_NORMAL_ARRAY);
    glNormalPointer(GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(3 * sizeof(float)));

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(0));

 TextureManager::Inst()->BindTexture(textueIDs[0]);
 glClientActiveTexture(GL_TEXTURE0+textueIDs[0]);
 glDrawElements(GL_TRIANGLE_STRIP, numberOfIndices, GL_UNSIGNED_INT, BUFFER_OFFSET(0)); 

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

 // next face and so on...

Текстурите се зареждат с помощта на безплатно изображение, както можете да видите от горния код, аз просто използвам примерния мениджър на текстури, който дойде с freeimage.

Защо обвързването на текстурата не работи?


person henryprescott    schedule 07.11.2010    source източник


Отговори (2)


Защо обвързването на текстурата не работи?

Описването много конкретно на поведението, което виждате, или по-добре прикачването на URL адрес към екранна снимка, минава дълъг път, когато се опитвате да преминете през графични въпроси.

След това трябва да включите gl състояние на грешка или поне да демонстрирате това в кода, който проверявате и се проваля, ако glGetError() не върне GL_NO_ERROR.

Вашето състояние на VBO / чертащ елемент изглежда разумно, въпреки че умишлено сте пропуснали дефиницията на обекта на индексния буфер, така че ще приемем, че изпращате истински индекси във вашето извикване glDrawElements(). За проверка на разумността направете извикването на glDrawElements() с указателя на необработените индекси, вместо да обвързвате VBO за елементите.

Вие също сте пропуснали дефиницията на типа на Vertex, която е необходима, за да знаете дали отместванията, които предоставяте на glTexCoordPointer(), са в съответствие с дефиницията на структурата.

И накрая, предполагам, че повечето хора във форума не знаят „безплатно изображение“, което според мен е това, което казахте, че използвате за зареждане на текстури. Ако има проблем с текстурирането, това е невъзможно да се види поради непрозрачния характер на използването на тази библиотека на трета страна за настройване на текстуриране от ваше име.

Ако са объркали идентификаторите на текстури, настройте режим на обвиване, който не се поддържа, не задайте филтъра за минимизиране в съответствие с очакваното mipmapping (включване/изключване), не активирайте текстурирането или задайте режима на средата на текстурата, така че модулацията с цветът на основната геометрия не е такъв, какъвто очаквате - всичко това би накарало текстурирането да не работи / да изглежда, че работи.

За отстраняване на неизправности просто използвайте библиотеката за зареждане на текстури и използвайте идентификатора на текстурата, който предоставят. След това настройте сами режимите на филтриране и текстурната среда. Изключете mipmapping, докато отстранявате неизправности. Непълните вериги на mipmap са много често срещана грешка при текстуриране.

Можете също така да изключите операциите за всеки фрагмент, за да опростите отстраняването на проблеми. Деактивирайте смесването, тестването на дълбочината и ножицата.

Ако приемем, че вашата текстура е мощност от две измерения или вашата реализация поддържа NPOT, опитайте тези настройки веднага преди да рисувате:

glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glDisable(GL_SCISSOR_TEST);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBindTexture(GL_TEXTURE_2D, texID);< br> glTexEnvi(GL_TEXTURE_ENV_MODE, GL_REPLACE); // изключване на модулацията
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // изключване на mipmapping
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); // изключване на повторенията
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

person user487158    schedule 07.11.2010

glClientActiveTexture(GL_TEXTURE0+textueIDs[0]);

Какво се опитваш да правиш тук?

Активната текстурна единица няма нищо общо с произволен текстурен обект.

person genpfault    schedule 07.11.2010