2013-07-08 2 views
1

Я пытаюсь сделать некоторые opengl программирования с помощью freeglut. Предположим, что объект (комета/самолет), который перемещается в трехмерном пространстве, и я хочу отобразить путь, прослеженный им как облако точек (которое представляет собой белый след, оставленный позади самолета).opengl: Как отобразить комету и трассировку?

Моя проблема, мне нужно, чтобы очистить экран с помощью glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) каждый раз, когда glutDispFunc называется в-для того, чтобы дать движение самолета (я использую keyboardfunction, чтобы изменить положение плоскости). Однако я также должен отображать огромное количество точек, которые идут на накопление в плоскости moves.I попытался с четким экрана с помощью

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 

, что приводит к значительному ухудшению производительности, как количество точек увеличения, но может отображать а также облако точек. Кто-нибудь знает, как справиться с такими сценариями?

ответ

6

Да, вы очищаете экран и каждый раз перерисовываете все. Вот как работает много игровых движков.

Однако я также должен отображать огромное количество точек, которые идут на накопление как самолет moves.I попытались с прозрачным экраном с помощью

Вы, вероятно, пытается сделать слишком много частиц. 100 частиц (или несколько сотен, но меньше тысячи) должно быть достаточно, чтобы провести след комет. С помощью всего 200 (БОЛЬШИХ) частиц вы можете создать очень убедительное облако.

Кроме того, вам не нужны очки для рисования кометы. Используя альфа-смешение, вы можете легко рисовать полупрозрачные светло-саблевидные линии, используя треугольники.

Светло-сабля, как, плазма-подобное, подобное пламя должны использовать любой цвет с небольшим оттенком белого цвета (RGB 255, 10, 10, например), и традиционно рисуется с использованием glBlendFunc(GL_SRC_ALPHA, GL_ONE)

Вот несколько примеров. Примеры показывают треугольную сетку, которую вы должны использовать. Цифры обозначают альфа. 0 - полностью прозрачный, 1 - полностью непрозрачный. косые черты указывают на триангуляцию, когда это необходимо."|" и "-" обозначают лицо края:

светящиеся линии

0--0--0--0 
| \| | /| 
0--1--1--0 
| /| | \| 
0--0--0--0 

repeat 
0--0 
| | 
1--1 
| | 
0--0 
to add more segments 

толщиной светящейся линии

0--0--0--0 
| \| | /| 
0--1--1--0 
| | | | 
0--1--1--0 
| /| | \| 
0--0--0--0 
repeat 
0--0 
| | 
1--1 
| | 
1--1 
| | 
0--0 
to add more segments. 

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

--edit--

белого след самолета

Для реализации дыма любого вида ...

  1. вам нужно использовать очень большие текстурированные частицы с «дымчатым "/" облачная "текстура. Если вы google «текстура дыма частиц» на изображениях Google, вы увидите, о чем я говорю.
  2. Эти «большие» частицы не могут быть обычно нарисованы с использованием точечных спрайтов (потому что они могут быть больше, чем экран на близком расстоянии) и требуют «рекламных щитов». Billboard - это квадрат, который всегда смотрит на камеру.
  3. Идеально цветной канал текстуры дыма должен быть полностью белым (так что вы можете окрашивать отдельные частицы с использованием вершинного цвета), а «дым» должен быть окрашен в альфа.
  4. Частицы дыма должны быть отсортированы по глубине, когда вы их рисуете, и должны быть отображены от дальнего до ближайшего (от камеры). Алгоритм сортировки вставки хорошо работает с «частично отсортированными» данными.
  5. частицы дыма должны быть оказаны с глубиной отключением записи (glDepthMask(0), если я помню правильно)
  6. частицы дыма должны использовать glBlendFunc(GL_SRC_ALPHA, GL_INV_SRC_ALPHA) смешивание.
  7. Однако, если пламя внутри дыма, пламя должно использовать glBlendFunc(GL_SRC_ALPHA, GL_ONE). Частицы пламени должны быть либо смешаны (то есть отсортированы по глубине вместе с ними), либо нарисованы после дыма (если используется отдельная система частиц).
  8. Чтобы сделать дым реалистичным, назначьте небольшую начальную скорость всем частицам, медленно увеличивайте их размер со временем и сделайте их более прозрачными. Когда частицы становятся полностью прозрачными, удалите их из системы частиц.
  9. При рисовании полупрозрачной альфа-смешанной поверхности включите альфа-тест и отрежьте пиксели с альфа == 0. Это ускорит рендеринг. (Важно, потому что вы можете убить частоту кадров со слишком большим количеством частиц дыма даже на приличном оборудовании)
  10. с использованием множества дымовых частиц для биллинга может быть дорогостоящим, особенно если они очень близки, поэтому, если вы хотите заполнить большую площадь этим дымом и частицами будут большими и плавать на уровне глаз, покрывая всю площадь экрана полупрозрачными поверхностями несколько раз, вам может понадобиться изучить некоторые другие объемные технологии тумана.
  11. Не перемещайте отдельные частицы с помощью матриц. Не набирайте одну частицу за звонок. Нарисуйте их все за один раз, это будет намного быстрее.
+0

Благодарим вас за ответ. Ваша идея действительно приятная, но я понял, что вы пытаетесь показать только короткий хвост кометы, если я не ошибаюсь. То, что я хотел, было чем-то вроде белого следа самолета, который остается навсегда. Другим примером, который я могу дать, является приложение для рисования. Во время рисования я должен иметь возможность отображать движущуюся кисть, а также след краски. Надеюсь, ты понял, что я пытаюсь передать. Я очень ценю ваши усилия и подробный ответ. Я уверен, что это поможет мне в будущем! –

+0

безупречный !! Благодаря... –

1

Если вы не используете их уже, вы должны нарисовать с помощью glDrawArrays, который, например, берет массив точек, и рисует все одним вызовом функции. Это намного быстрее, чем непосредственно API рисования (glBegin и glEnd). Вы можете настроить его так:

float points[100][3]; 
int pointsCount = 0; 
glEnableClientState(GL_VERTEX_ARRAY); 
glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), points); 

Затем, каждый раз, когда объект «производит» точка (скажем, каждый кадр), вы можете добавить свою позицию в массив:

points[pointsCount][0] = object.x; 
points[pointsCount][1] = object.y; 
points[pointsCount][2] = object.z; 
pointsCount++; 

И затем, нарисуйте их как это:

glDrawArrays(GL_POINTS, 0, pointsCount); 

конечно, вы должны сделать что-то, когда массив заполняется, но вы получите идею.

Есть также VBOs, которые могут увеличить скорость еще больше, но являются более продвинутой функцией.

EDIT: Да, вы должны перерисовать все с помощью этого метода. Я бы сказал, что он еще не будет препятствовать производительности на несколько больше очков, чем glBegin/End. Согласно answers here, вы должны иметь возможность изменять размер буфера с помощью glBufferData, но, возможно, вам нужно будет сохранить текущие данные в вашем массиве и перенести их после изменения размера.

+0

Большое вам спасибо за ваш ответ !! Я только что прочитал о Vertex Arrays и VBOs. Так ты говоришь, что мне нужно стереть экран в каждом кадре и перерисовать все? Если я использую вершинные массивы и VBOs, это не будет препятствовать производительности? Я также прочитал, что в VBOs я могу обновить буфер, используя GL_DYNAMIC_DRAW_ARB. Но я не мог понять, как увеличить размер буфера. Не могли бы вы предоставить немного больше информации? –

1

Да, большинство игр работают, стирая экран и перерисовывая его в каждом кадре. Тем не менее, возможно, возможно сделать МНОГО меньше работы за кадр. Есть ли что-нибудь еще на экране, кроме тропы? Как долго эта тропа будет?Должно ли оно оставаться постоянным во времени (в отличие от замирания со временем, похожего на тротушку мыши)?

Если вы можете позволить себе уклониться от своей тропы, вы можете использовать обратную связь с буфером. Этот метод визуализирует полупрозрачный квадрат по экрану (или объекту + след), который имеет эффект отмирания самой дальней части хвоста до цвета фона. Затем объект нарисован на новом месте, снова создавая самую яркую часть хвоста. Это довольно распространенный эффект демо/визуализации и может создавать действительно великолепные хвосты с очень маленькими накладными чертежами для каждого кадра.

Возможно, это не совсем то, что вам нужно (я написал это, прежде чем вы уточнили свою потребность в комментарии к ответу @ SigTerm), но я собираюсь оставить его здесь, потому что кому-то может понадобиться такой «след», ,