Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Программирование игр, графики и искусственного интеллекта > particle Engine


Автор: Graf_h 21.4.2008, 10:33
Может кто подскажет как в играх делают системы частиц,и как это можно в реализовать в ОпенЖЛ так что бы не затрачалось много ресурсов, а то я експерементирую, ставлю 100 000 частиц, но это жрет очень много ресурсов процессора, и в игре будут ужасные тормоза! + может подскажете как сейчас делают огонь, воду...

Автор: Graf_h 25.4.2008, 09:16
спасибо

Автор: arilou 25.4.2008, 14:53
Graf_h, Google particle system, OpenGL

Автор: Rickert 30.4.2008, 10:54
Graf_h, Во-первых где ты в игре видел 100 000 частиц в кадре одновременно?
А во-вторых делается всё руками, через аналитическую геометрию. Я реализовывал источник частиц давно, но ничего сложного не было. Просто время и понимание.

Автор: mr.DUDA 2.5.2008, 10:09
Цитата(Rickert @  30.4.2008,  10:54 Найти цитируемый пост)
Graf_h, Во-первых где ты в игре видел 100 000 частиц в кадре одновременно?

Сорри, но вот у меня например максимум был 1,5 миллиона (потом тормозить начинало ниже 40 фпс). Вот.  smile 

Автор: arilou 2.5.2008, 11:07
mr.DUDA, ты забыл добавить, что это работает на C#  smile 

Автор: Rickert 2.5.2008, 12:22
mr.DUDA, это в реальных игровых условиях? Неоптимально. Как правило берут размерами, а не кол-вом. ИМХО

Автор: arilou 2.5.2008, 13:05
Rickert, в демке просто смотрели, сколько максимально переварит без потери перформанса.

Автор: Rickert 3.5.2008, 06:51
arilou, а ну так для тестов - то можно хоть и 2 kkk - понятное дело.

Автор: arilou 3.5.2008, 12:21
Graf_h, так что делай выводы. 100К частиц - это мало, чтобы загнуть комп. Скорее всего, у тебя ненужные перерасчеты происходят.

Автор: Rickert 3.5.2008, 15:53
Обычно основные такты забирают расчёты углов, если ты их применяешь. Sin / Cos - можно оптимизировать.

Автор: Graf_h 5.5.2008, 12:28
Код

void render_part(){
glPushMatrix();

switch(zoomst){
case 1:zoom+=0.1;
    if (zoom>-40){zoomst=2;};
        break;
case 2:zoom-=0.1;
    if (zoom<-180){zoomst=1;};
        break;

};
rot+=0.00005f;

for (loop=0;loop<MAX_PARTICLES;loop++) // Цикл по всем частицам 
  {

    if (particle[loop].active) // Если частицы не активны 
    {
          float x=particle[loop].x; // Захватим позицию X нашей частицы 
          float y=particle[loop].y; // Захватим позицию Н нашей частицы
          float z=particle[loop].z+zoom; // Позиция частицы по Z + Zoom
          col=rand()%12;
          glColor4f(particle[loop].r,particle[loop].g,particle[loop].b,particle[loop].life);
        
         glRotatef(rot,0,0,1);

            glBegin(GL_TRIANGLE_STRIP);
                glTexCoord2d(1,1); glVertex3f(x+0.2f,y+0.2f,z); // Верхняя правая
                glTexCoord2d(0,1); glVertex3f(x-0.2f,y+0.3f,z); // Верхняя левая
                glTexCoord2d(1,0); glVertex3f(x+0.2f,y-0.2f,z); // Нижняя правая 
                glTexCoord2d(0,0); glVertex3f(x-0.2f,y-0.2f,z); // Нижняя левая

            glEnd();
         
                //dvigenie
             particle[loop].x+=particle[loop].xi/(slowdown*1000); 
             particle[loop].y+=particle[loop].yi/(slowdown*1000);
             particle[loop].z+=particle[loop].zi/(slowdown*1000);
             
             particle[loop].xi+=particle[loop].xg;// Притяжение по X для этой записи 
             particle[loop].yi+=particle[loop].yg; // Притяжение по Y для этой записи
             particle[loop].zi+=particle[loop].zg;
            
             particle[loop].life-=particle[loop].fade;
                    if (particle[loop].life<0.0f) // Если частица погасла 
                     {
                        
                          particle[loop].life=1.0f;
                          particle[loop].fade=float(rand()%100)/1000.0f+0.003f;
                          particle[loop].x=0.0f; // На центр оси X 
                          particle[loop].y=0.0f; // На центр оси Y
                          particle[loop].z=0.0f; // На центр оси Z
                          particle[loop].xi=xspeed+float((rand()%60)-32.0f)*1.0f;//Скорость и направление по оси X
                          particle[loop].yi=yspeed+float((rand()%60)-30.0f)*1.0f;//Скорость и направление по оси Y
                          particle[loop].zi=float((rand()%60)-30.0f)*10.0f;       //Скорость и направление по оси Z
                          particle[loop].r=colors[col][0]; // Выбор красного из таблицы цветов
                          particle[loop].g=colors[col][1]; // Выбор зеленого из таблицы цветов
                          particle[loop].b=colors[col][2]; // Выбор синего из таблицы цветов

                            
            
                    }

    }
}
glPopMatrix();
}



Вот собственно код! комп загинается  smile 

Автор: Rickert 5.5.2008, 12:36
А ты потимизировать вообще пробовал? Одни и теже константы пересчитываешь по 10 раз - но это мелочь. У тебя вывод идёт через glBegin / glEnd.
Вообще забудь про них. Тебе надо смотреть массивы отображений.

Автор: Graf_h 5.5.2008, 12:51
Цитата(Rickert @  5.5.2008,  12:36 Найти цитируемый пост)
Вообще забудь про них. Тебе надо смотреть массивы отображений. 

я знаю про glDrawArray, glDrawElements! их стоит использовать когда много вершин! а уменя рисуется всего 4!

Автор: Rickert 6.5.2008, 06:58
Graf_h, где четыре? Не вижу.
Это раз. А во-вторых попробуй закомментировать часть с частицами - может это вообще не из - за них?

Автор: Graf_h 6.5.2008, 09:19
Цитата(Rickert @  6.5.2008,  06:58 Найти цитируемый пост)
 где четыре? Не вижу.

Код

glBegin(GL_TRIANGLE_STRIP);
                glTexCoord2d(1,1); glVertex3f(x+0.2f,y+0.2f,z); // Верхняя правая
                glTexCoord2d(0,1); glVertex3f(x-0.2f,y+0.3f,z); // Верхняя левая
                glTexCoord2d(1,0); glVertex3f(x+0.2f,y-0.2f,z); // Нижняя правая 
                glTexCoord2d(0,0); glVertex3f(x-0.2f,y-0.2f,z); // Нижняя левая

            glEnd();




Цитата(Rickert @  6.5.2008,  06:58 Найти цитируемый пост)
Это раз. А во-вторых попробуй закомментировать часть с частицами - может это вообще не из - за них?

Точно из - за них, потому что прога ничего больше и не делает,это эксперимент! хочу здесь все отладить и тогда уже бросать в саму игру smile

Автор: Velud 4.9.2008, 20:15
ну воду вроде бы шейдерами делают, а не частицами... а еще огонь можно сделать спрайтом, с меняющейся текстурой. точнее два спрайта, перпендикулярных.

Автор: arilou 4.9.2008, 23:14
Цитата(Velud @  4.9.2008,  20:15 Найти цитируемый пост)
ну воду вроде бы шейдерами делают, а не частицами... а еще огонь можно сделать спрайтом, с меняющейся текстурой. точнее два спрайта, перпендикулярных. 

может быть я тебя удивлю, но вот к примеру в BioShock'е вода сделана спрайтами.

А огонь на перпедникулярных спрайтах выглядит отстойно. Гораздо прикольнее он выглядит на волюметрической текстуре. 

Автор: Dronchik 5.9.2008, 18:22
arilou, а ещё крассивее огонь делаеться на HLSL(ну или любом другом языке написания шейдеров). Использую вершинные и пиксельные шейдеры можно вообще делать отличные эффекты, а вся нагрузка графических вычислений ляжет на видеокарту а не на проц. Для OpenGL есть GLSL(типо HLSL тока для OpenGL).

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)