2016-10-31 5 views
0

Я работаю над игрой minecraft-ish, и я работал немного больше с vbos. Однако; при рисовании нескольких лиц в одном vbo у меня, похоже, немного проблема.Несколько квадов в одном vbo

Вот мой код ВБО поколения:

glGenBuffers(1, &VBO); 
glBindBuffer(GL_ARRAY_BUFFER, verts); 
glBindBuffer(GL_ARRAY_BUFFER, 0); 
glBindBuffer(GL_ARRAY_BUFFER, VBO); 
glBufferData(GL_ARRAY_BUFFER, verts * 9 * sizeof(GLfloat), NULL, GL_STATIC_DRAW); 
void* ptr = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE); 

GLfloat*model = (GLfloat*)ptr; 
GLfloat*tex = ((GLfloat*)ptr) + verts * 6; 
GLfloat*color = ((GLfloat*)ptr) + verts * 3; 
int p = 0; 
int k = p * 3; 

    for (int mcy = 0; mcy < 5; mcy++) { 
     for (int mcx = 0; mcx < 5; mcx++) { 
     double addonX = mcx*32.0; 
     double addonY = mcy*32.0; 
     int addonx = mcx * 32; 
     int addony = mcy * 32; 
     if (!(hill.get(addonX, addonY)*400.0 > 100 && hill.get(32 + addonX, addonY)*400.0 > 100 && hill.get(addonX, 32 + addonY)*400.0 > 100 && hill.get(32 + addonX, 32 + addonY)*400.0 > 100)) { 
      draw = true; 

      int biome1 = BiomeToColor(GetBiome(x, y, addonX, addonY), hill.get(addonX, addonY)*400.0); 
      int biome2 = BiomeToColor(GetBiome(x, y, 32 + addonX, addonY), hill.get(32 + addonX, addonY)*400.0); 
      int biome3 = BiomeToColor(GetBiome(x, y, addonX, 32 + addonY), hill.get(addonX, 32 + addonY)*400.0); 
      int biome4 = BiomeToColor(GetBiome(x, y, 32 + addonX, 32 + addonY), hill.get(32 + addonY, 32 + addonY)*400.0); 







      model[k] = addonx+ 32; 
      model[k + 1] = addony; 
      model[k + 2] = hill.get(addonX + 32, addonY)*400.0; 

      color[k] = BiomeColors[biome2].r; 
      color[k + 1] = BiomeColors[biome2].g; 
      color[k + 2] = BiomeColors[biome2].b; 


      p++; 
      k = p * 3; 



      model[k] = addonx + 32; 
      model[k + 1] = addony + 32; 
      model[k + 2] = hill.get(addonX + 32, addonY + 32)*400.0; 

      color[k] = BiomeColors[biome4].r; 
      color[k + 1] = BiomeColors[biome4].g; 
      color[k + 2] = BiomeColors[biome4].b; 
      p++; 
      k = p * 3; 



      model[k] = addonx; 
      model[k + 1] = addony + 32; 
      model[k + 2] = hill.get(addonX, addonY + 32)*400.0; 

      color[k] = BiomeColors[biome3].r; 
      color[k + 1] = BiomeColors[biome3].g; 
      color[k + 2] = BiomeColors[biome3].b; 



      p++; 
      k = p * 3; 





      model[k] = addony; 
      model[k + 1] = addony; 
      model[k + 2] = hill.get(addonX, addonY)*400.0; 

      color[k] = BiomeColors[biome1].r; 
      color[k + 1] = BiomeColors[biome1].g; 
      color[k + 2] = BiomeColors[biome1].b; 


      p++; 
      k = p * 3; 

     } 
    } 
} 
glUnmapBuffer(GL_ARRAY_BUFFER); 
glBindBuffer(GL_ARRAY_BUFFER, 0); 

А вот код, я использую, чтобы сделать VBO:

glBindBuffer(GL_ARRAY_BUFFER, VBO); 

    glVertexPointer(3, GL_FLOAT, 0, 0); 
    glTexCoordPointer(3, GL_FLOAT, 0, (char*)NULL + verts * 6 * sizeof(GLfloat)); 
    glColorPointer(3, GL_FLOAT, 0, (char*)NULL + verts * 3 * sizeof(GLfloat)); 

    glDrawArrays(GL_QUADS, 0, VBO); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 

Вот результат я хочу (с использованием одного четверной в каждом VBO):

unfortunatly I'm still new so you have to click this link :/

И вот результат я получаю с Умножить е квадрациклов в каждом VBO:

image

Так почему же я хочу, чтобы нарисовать несколько каре в одном VBO? Одно слово: производительность, если вы сравните два изображения с тем, что действительно всплывает (ну, кроме ошибки со вторым изображением), это счетчик частоты кадров. Я хочу, чтобы эта игра была большой, поэтому для меня важны все fps.

EDIT: OMG, я так глуп:

model[k] = addony; 

Очень простая ошибка, но так devistating. Просто доказывает, как мелкие вещи могут тормозить игру. Теперь все работает.

+0

Если вы действительно хотите производительность, подумайте о переходе на «современный» OpenGL (> 3.2) – Trevir

ответ

0
glDrawArrays(GL_QUADS, 0, VBO); 

Есть несколько проблем с этим вызовом:

  1. третий параметр glDrawArrays является подсчет вещей вы рисуете так, что вы на самом деле говорят это:

Нарисуйте квады из моего буфера с 0 до VBO, а затем остановитесь.

То, что вы должны сказать это:

тиражная Квадроциклы из моего буфера при 0 до Длина буфера и затем остановить

так теперь выглядит следующим образом:

glDrawArrays(GL_QUADS, 0, verts); 

«ВБО» в ваш код - это идентификатор буфера, который вы хотите использовать. подумайте об этом как указатель, номер которого вы знаете, или, скорее, пользователь с идентификатором.

  1. GL_QUIANS GL_TRIANGLES существует много проблем с GL_QUADS позже, особенно на мобильных телефонах и на других платформах, что делает ваши данные в треугольниках намного приятнее.

Вы не должны рисовать в GL_QUADS по нескольким причинам

Почему вы не используете ВАО-х? Используете ли вы более старую версию OpenGL, у которой нет VAO?В противном случае я бы предложил использовать VAO здесь вместо VBO, поэтому вам не нужно связывать указатели для каждого вызова ничьей.

glBindBuffer(GL_ARRAY_BUFFER, verts); 

Что вы пытаетесь здесь связать VBO id: 'verts', чтобы быть нашим текущим VBO.

'Так почему я хочу нарисовать несколько квадов в одном vbo? Одно слово: производительность '

Вы пытались нарисовать несколько квадроциклов с помощью instancing? Итак, отправьте матрицу модели для каждой из фигур, чтобы вы изменили свои позиции и фигуры в шейдере, а не в буфере. Таким образом, вы можете нарисовать один vbo снова и снова, просто слегка трансформировавшись одним призывом рисования.

Вот хороший учебник по инстансов:

http://learnopengl.com/#!Advanced-OpenGL/Instancing

Просто из любопытства, а почему вы решили использовать:

glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE); 

вместо буферизации данных в glBufferData вызова?

Если вам нужно в буфер данные позже вы можете использовать glBufferSubData

Честно говоря, хотя я думаю, что ваши проблемы производительности вытекают из ряда факторов.

Я бы лично использовал glBufferData вместо данных карты, и когда мне нужно это сделать во время выполнения, а не во время загрузки, я бы использовал glBufferSubData.

Я бы загрузил цвета в шейдер и снова и снова рисовал кратные SAME VBO с другой матрицей модели и цветами, что позволило мне представить ее.

Однако вам не нужно это делать.

То, что я бы рекомендовал, составляет данные в треугольниках и цветах и ​​рисует всю землю как сетку, которую вы, похоже, пытались сделать. Вероятнее всего, ваша проблема вызвана тем, что длина glDrawArrays установлена ​​на длину VBO.

Однако в этом случае я бы построил VBO с использованием glBufferData с размером куска, тогда я бы использовал glBufferSubData для каждого из квадроциклов с цветами и т. Д., И как только я закончу, я нарисую это несколько раз рядом с разными кусками.

Я думаю, вам было бы полезно сделать больше теории OpenGL.

+0

моя ошибка, вызов glDrawArrays был неправильным, однако исправление этого ничего не меняет:/ – Anonymus

+0

«Вы пытались нарисовать несколько квадраты с использованием instancing? Поэтому отправляем модельную матрицу для каждой из фигур, чтобы вы изменяли свои позиции и фигуры в шейдере, а не в буфере. Таким образом, вы можете нарисовать один vbo снова и снова, просто слегка преобразованный с помощью одного вызова рисования «. Итак, вы говорите здесь, что вы рисуете один fbo несколько раз без потери производительности. Звучит здорово и все, но не подходит, что я пытаюсь сделать. – Anonymus

+0

Итак, вы говорите здесь, что вы рисуете один fbo несколько раз без потери производительности.Звучит здорово и все, но не подходит, что я пытаюсь делать вообще – Avalon