2014-01-11 3 views
1

У меня есть задача подготовить hipsometric globe в OpenGL. Помимо цветов вершин, мне нужно, чтобы вершины были выше (горы), а некоторые - ниже.Рисунок треугольников после вычисления точек в GLSL

В настоящее время у меня есть программа, которая генерирует глобус, только с точками (каждая 1 градус), все на одной высоте, я делаю это, передавая долготу долготы в мою программу в GLSL и вычисляет матрицу перевода для каждой вершины.

Теперь я могу легко представить, как перемещать вершины выше и ниже - я просто добавлю еще одну равномерную переменную «высота», а в GLSL сделаю все остальное. То же самое легко с проходящим цветом - без проблем.

Однако я понятия не имею, как создать целую карту, используя треугольники (ну, четырехугольники, состоящие из двух треугольников). Лучшее решение, которое у меня есть, состоит в том, что когда у меня есть четыре вершины (x1, x2, x3, x4), которые создают четырехугольник, я мог бы просто преобразовать четырехугольник (который ранее был в буфере) таким образом, чтобы создать четырехугольник который имеет углы в моих четырех вершинах (x1, x2, x3, x4). Затем я просто передаю его в GLSL и сделаю.

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

Дополнительная информация:

Я использую OpenGL 3.3.

Это, как я сделать очки:

for (double lng = 0; lng < 360; lng++) { 
    for (double lat = 0; lat < 180; lat++) { 
     draw_dots(MVP, lat, lng); 
    } 
} 

// draw_dots function: 
glUniform1f(latID, lat); 
glUniform1f(lngID, lng); 
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]); 
glDrawElements(GL_POINTS, 1, GL_UNSIGNED_INT, field1_location); 

Это моя вершинный шейдер:

gl_Position = MVP * transl_mtx * vec4(vertexPosition_modelspace, 1); 

где transl_mtx является перевод матрица вычисляется из однородных переменных "лат" и "LNG".

ответ

3

Nope, nope, nope.

Вещь в отношении рендеринга GPU, как правило, является наибольшим хитом производительности - точкой синхронизации CPU-GPU. Таким образом, вы обычно хотите уменьшить количество команд на кадр до абсолютного минимума. Единственную функцию, которую мы не можем удалить, - это вызов draw; обычно glDrawElements или gDrawArrays.

Однако вы вызываете эту функцию тысячи раз за каждый кадр. Учитывая тот факт, что ваш GPU (наиболее вероятно) имеет несколько гигабайт память, вот лучшее решение:

  1. Генерировать весь набор вершин форума в обычный массив с плавающей точкой.
  2. Скопируйте это на GPU через VBO.
  3. Используйте переменную in вместо uniform и передайте матрицу MVP только через униформу.
  4. Используйте только один drawcall для рендеринга всей модели.

Таким образом, вы можете управлять и подготовить данные удобно на CPU раз, а затем использовать абсурдную скорость GPU сделать это.

+0

Хорошо, еще вопрос. Я также должен реализовать простой уровень детализации. Просто «пропустите каждую секунду/третью вершину», чтобы получить менее точный, но более быстрый результат. Если точка синхронизации является моим узким местом, будет хорошей идеей отправлять весь пакет новых вершин каждый раз, когда пользователь меняет уровень детализации - потому что он будет делать это редко, не так ли? –

+1

@ Świstak35 Ты скажешь мне, если он будет делать это редко: :). Рассматривая LoD, которые идут со степенями двух (1/2 из вершин, 1/4 вершин, ...), вы могли бы фактически создать их * все * и просто переключиться на нужный вам набор, потому что сумма принятая память будет [менее 2 раз нормальной] (http: //www.wolframalpha.com/input/? i = 1 +% 2B + 1% 2F2 +% 2B + 1% 2F4 +% 2B + ...). –

+1

@ Świstak35 Или, альтернативно, вы можете использовать тэссерационный шейдер, чтобы сделать это для вас, но я боюсь, что это выходит за рамки этого вопроса, чтобы объяснить, как это будет работать; все-таки, возможно, вы захотите узнать свои варианты, я полагаю. –

Смежные вопросы