2011-11-16 48 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(X,Y,Z)在上面的run()函数,在循环之前右,其中x,Y,Z为敌人的位置把它们放在敌人的顶端....那是最好的地方吗?

感谢您的任何意见!

+1

你也可以显示你正在尝试使用的修改过的代码,它不使用sin和cos吗? – NickLH

+0

据我所知,在每遍粒子[I] .angle增加,所以我取代了'的glTranslatef(XPOS,yPos,PDEPTH);''用的glTranslatef(0,粒子[I] .angle,PDEPTH);'到希望获得Ÿaccelleration但我得到各个方向分散在整个空间粒子..... – 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