【问题标题】:OpenGL particles, help controlling directionOpenGL粒子,帮助控制方向
【发布时间】:2011-11-16 23:39:33
【问题描述】:

我正在尝试修改这个 Digiben 样本,以获得从一个点(撞击点)产生的粒子效果,并像火的火花一样向上漂浮。样本中的粒子旋转了一圈...我尝试删除余弦/正弦函数并用正常的 glTranslate 替换它们并增加 Y 值,但我无法得到任何实际结果...谁能指出大致上我应该在哪里添加/修改此代码中的翻译以获得该结果?

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;
    }
}

现在我在上面的 run() 函数中添加一个 glPushMatrix(), glTranslate(x, y, z),就在循环之前,x,y,z 作为敌人放置它们的位置敌人的头顶……那是最好的地方吗?

感谢您的任何意见!

【问题讨论】:

  • 您能否也显示您尝试使用的不使用 sin 和 cos 的修改后的代码?
  • 我知道在每次通过时,particle[i].angle 都会增加,因此我将 glTranslatef(xPos,yPos,PDEPTH); 替换为 glTranslatef(0,particle[i].angle,PDEPTH); 以希望获得 Y 加速度,但我得到粒子分散在各个方向的空间中.....
  • 如果你使用glTranslatef,尽量不要使用glRotatef,因为这会导致散射。一旦你让平移工作,然后开始放回旋转,并注意你做事情的顺序,平移后旋转与旋转后平移不同。

标签: c++ opengl particles


【解决方案1】:

以这种方式使用 glTranslate 和 glRotate 实际上会降低程序的性能。 OpenGL 不是场景图,因此矩阵操作函数直接影响绘图过程,即它们不设置“对象状态”。您遇到的问题是,4×4 矩阵-矩阵乘法涉及 64 次乘法和 16 次加法。因此,移动粒子所花费的计算能力是直接更新顶点位置的 96 倍。

现在解决您的问题:就像我已经告诉您的那样,glTranslate 对 4 个可选矩阵之一的(全局)矩阵状态进行操作。并且效果会累积,即每个 glTranslate 将从前一个 glTranslate 左侧的矩阵开始。 OpenGL 提供了一个矩阵堆栈,可以在其中推送当前矩阵的副本以使用,然后弹出以恢复到之前的状态。

但是:矩阵操作已从 OpenGL-3 核心中移除,之后完全。 OpenGL 矩阵操作从未被加速(除了在 1996 年左右由 SGI 制造的一个特定图形工作站上)。今天它已经过时了,因为每个使用 3D 几何的受人尊敬的程序都通过自己的实现或 3rd 方库使用更复杂的矩阵操作。 OpenGL 的矩阵堆栈只是多余的。所以我强烈建议你忘记 OpenGL 的矩阵操作功能并自己动手。

【讨论】:

  • 好吧,您不应该将它们用于特定场景。性能将很糟糕。
  • 我们的想法是让一些东西工作,然后担心效率。否则,您可能会花很长时间试图提出“完美”的解决方案。
  • @EthanSteinberg:他已经有了一些工作,即根据调整顶点位置进行粒子运动,在这种情况下这是更好的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-26
相关资源
最近更新 更多