2011-11-16 70 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