1

この Digiben サンプルを変更して、スポット (衝突点) から生成され、火の火花のように上向きに浮遊するパーティクルの効果を得ようとしています。サンプルには円を描いて回転する粒子があります...コサイン/サイン関数を削除して、Y値を増やして通常のglTranslateに置き換えようとしましたが、実際の結果を得ることができません...誰か指摘してくださいその結果を得るために、このコードのどこに翻訳を追加/変更する必要がありますか?

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) をループの直前に追加しています。敵……そこが一番いいのか?

ご意見ありがとうございます。

4

1 に答える 1

1

そのように glTranslate と glRotate を使用すると、実際にはプログラムのパフォーマンスが低下します。OpenGL はシーン グラフではないため、マトリックス操作関数は描画プロセスに直接影響します。つまり、「オブジェクトの状態」を設定しません。あなたが直面している問題は、4×4 行列 - 行列の乗算には 64 回の乗算と 16 回の加算が含まれることです。したがって、頂点の位置を直接更新するよりも、パーティクルを移動するために 96 倍の計算能力を費やしていることになります。

さて、あなたの問題: すでに言ったように、glTranslate は 4 つの選択可能なマトリックスの 1 つの (グローバルな) マトリックス状態で動作します。そして、効果が蓄積されます。つまり、各 glTranslate は、前の glTranslate が残した行列から開始されます。OpenGL は、現在のマトリックスのコピーをプッシュして操作し、ポップして前の状態に戻すことができるマトリックス スタックを提供します。

ただし、行列操作は OpenGL-3 コアから削除され、その後完全に削除されました。OpenGL マトリックス操作が高速化されることはありませんでした (1996 年頃に SGI によって作成された 1 つの特定のグラフィックス ワークステーションを除く)。今日では、3D ジオメトリを操作する立派なプログラムはすべて、独自の実装またはサード パーティのライブラリによって、はるかに洗練された行列操作を使用していたため、これは時代錯誤です。OpenGL のマトリックス スタックは冗長でした。したがって、OpenGL の行列操作機能については忘れて、自分で作成することを強くお勧めします。

于 2011-11-17T00:51:06.113 に答える