2011-11-16 1 views
1

Я пытаюсь изменить этот образец Digiben, чтобы получить эффект частиц, которые генерируются из пятна (точки удара), и плавать вверх, подобно искрам огня. Образец имеет частицы, вращающиеся по кругу ... Я попытался удалить функции косинуса/синуса и заменить их нормальным glTranslate с увеличением значения Y, но я просто не могу получить никаких реальных результатов ... может кто-нибудь отметить где я должен добавить/изменить перевод в этом коде, чтобы получить этот результат?Частицы OpenGL, управление направлением управления

void ParticleMgr::init(){ 
    tex.Load("part.bmp"); 
    GLfloat angle = 0; // A particle's angle 
    GLfloat speed = 0; // A particle's speed 
    // Create all the particles 
    for(int i = 0; i < P_MAX; i++) 
    { 
     speed = float(rand()%50 + 450); // Make a random speed 
     // Init the particle with a random speed 
     InitParticle(particle[i],speed,angle); 
     angle += 360/(float)P_MAX; // Increment the angle so when all the particles are 
            // initialized they will be equally positioned in a 
            // circular fashion 
    } 
} 
void ParticleMgr::InitParticle(PARTICLE &particle, GLfloat sss, GLfloat aaa) 
{ 
    particle.speed = sss; // Set the particle's speed 
    particle.angle = aaa; // Set the particle's current angle of rotation 
    // Randomly set the particles color 
    particle.red = rand()%255; 
    particle.green = rand()%255; 
    particle.blue = rand()%255; 
} 
void ParticleMgr::DrawParticle(const PARTICLE &particle) 
{ 
    tex.Use(); 
    // Calculate the current x any y positions of the particle based on the particle's 
    // current angle -- This will make the particles move in a "circular pattern" 
    GLfloat xPos = sinf(particle.angle); 
    GLfloat yPos = cosf(particle.angle); 
    // Translate to the x and y position and the #defined PDEPTH (particle depth) 
    glTranslatef(xPos,yPos,PDEPTH); 
    // Draw the first quad 
    glBegin(GL_QUADS); 
     glTexCoord2f(0,0); 
     glVertex3f(-5, 5, 0); 
     glTexCoord2f(1,0); 
     glVertex3f(5, 5, 0); 
     glTexCoord2f(1,1); 
     glVertex3f(5, -5, 0); 
     glTexCoord2f(0,1); 
     glVertex3f(-5, -5, 0); 
    glEnd(); // Done drawing quad 
    // Draw the SECOND part of our particle 
    tex.Use(); 
    glRotatef(particle.angle,0,0,1); // Rotate around the z-axis (depth axis) 
    //glTranslatef(0, particle.angle, 0); 
    // Draw the second quad 
    glBegin(GL_QUADS); 
     glTexCoord2f(0,0); 
     glVertex3f(-4, 4, 0); 
     glTexCoord2f(1,0); 
     glVertex3f(4, 4, 0); 
     glTexCoord2f(1,1); 
     glVertex3f(4, -4, 0); 
     glTexCoord2f(0,1); 
     glVertex3f(-4, -4, 0); 
    glEnd(); // Done drawing quad 
    // Translate back to where we began 
    glTranslatef(-xPos,-yPos,-PDEPTH); 
} 
void ParticleMgr::run(){ 
    for(int i = 0; i < P_MAX; i++) 
    { 
     DrawParticle(particle[i]); 
     // Increment the particle's angle 
     particle[i].angle += ANGLE_INC; 
    } 
} 

На данный момент я добавление glPushMatrix(), glTranslate (х, у, г) в функции Run() выше, прямо перед циклом, с х, у, г как позиции противника для размещения их на вершине врага .... это лучшее место для этого?

Спасибо за любой ввод!

+1

Можете ли вы также показать модифицированный код, который вы пытались использовать, который не использует sin и cos? – NickLH

+0

Я понимаю, что на каждом проходе частица [i] .angle увеличивается, поэтому я заменил 'glTranslatef (xPos, yPos, PDEPTH);' с помощью 'glTranslatef (0, particle [i] .angle, PDEPTH); получить Y-апелляцию, но я получаю частицы, разбросанные по всему пространству во всех направлениях ..... – Alex

+0

Если вы используете glTranslatef, постарайтесь не использовать glRotatef, так как это вызовет рассеяние. После того, как вы получите перевод, затем начните возвращать вращения и будьте осторожны с порядком, который вы делаете, перевод, за которым следует поворот, не совпадает с поворотом, за которым следует перевод. – NickLH

ответ

1

Использование glTranslate и glRotate таким образом фактически уменьшит производительность вашей программы. OpenGL не является графиком сцены, поэтому функции манипуляции с матрицами непосредственно влияют на процесс рисования, то есть не устанавливают «состояние объекта». Проблема, с которой вы сталкиваетесь, заключается в том, что умножение матричной матрицы размером 4 × 4 включает в себя 64 умножения и 16 дополнений. Таким образом, вы тратите 96 раз на вычислительную мощность для перемещения частицы, а не просто обновляете позицию вершины напрямую.

Теперь к вашей проблеме: Как я уже сказал вам, glTranslate работает (глобальное) матричное состояние одной из 4 выбираемых матриц. И эффекты накапливаются, т. Е. Каждый glTranslate будет начинаться с матрицы, оставленной предыдущим glTranslate. OpenGL предоставляет матричный стек, в который можно нажать копию текущей матрицы для работы, а затем поп, чтобы вернуться к состоянию раньше.

Однако: Матричные манипуляции были удалены из ядра OpenGL-3, а затем полностью. Матричные манипуляции с OpenGL никогда не были ускорены (за исключением одной конкретной рабочей станции графики, созданной SGI около 1996 года). Сегодня это анахронизм, так как каждая респектабельная программа, работающая с 3D-геометрией, использовала гораздо более сложную матричную манипуляцию либо собственной реализацией, либо сторонней библиотекой. Матричный стек OpenGL был просто лишним. Поэтому я настоятельно рекомендую вам забыть о функциях манипулирования матрицей OpenGL и сворачивать свои собственные.

+0

Двумя матричными функциями манипуляции являются glPushMatrix (http://www.opengl.org/sdk/docs/man/xhtml/glPushMatrix.xml) и glPopMatrix (http://www.opengl.org/sdk/docs/man/ xhtml/glPushMatrix.xml) – Lalaland

+0

Ну, вы не должны использовать их для этого конкретного сценария. Производительность будет ужасной. – datenwolf

+0

Идея состоит в том, чтобы заставить что-то работать, а затем беспокоиться об эффективности. В противном случае вы могли бы потратить навсегда попытку придумать «идеальное» решение. – Lalaland