2009-05-23 82 views
3

我在使用GL_POINTS的OpenGL中有一個簡單的粒子效果。被調用時,被傳遞的顆粒,以便從顆粒最遠從相機第一到一個最近的相機最後以下:在OpenGL中使用粒子效應的Alpha透明度

void draw_particle(particle* part) { 
    /* The following is how the distance is calculated when ordering. 
    * GLfloat distance = sqrt(pow(get_camera_pos_x() - part->pos_x, 2) + pow(get_camera_pos_y() - part->pos_y, 2) + pow(get_camera_pos_z() - part->pos_z, 2)); 
    */ 

    static GLfloat quadratic[] = {0.005, 0.01, 1/600.0}; 
    glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, quadratic); 
    glPointSize(part->size); 
    glEnable(GL_BLEND); 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
    glEnable(GL_POINT_SPRITE_ARB); 
    glEnable(GL_TEXTURE_2D); 

    glBegin(GL_POINTS); 
     glColor4f(part->r, part->g, part->b, part->a); 
     glVertex3f(part->pos_x, part->pos_y, part->pos_z); 
    glEnd(); 

    glDisable(GL_BLEND); 
    glDisable(GL_POINT_SPRITE_ARB); 
} 

然而,如在下面的效果可以看出渲染時一些僞像: artifacted image http://img199.imageshack.us/img199/9574/particleeffect.png

如果我禁用深度測試,問題就會消失,但我需要的效果能夠與場景中的其他元素進行交互,出現在相同GL_TRIANGLE_STRIP元素的前面和後面,具體取決於深度。

+1

只是關於你的代碼的評論。我認爲你應該從draw_particle()函數中提取所有非'particle *'相關代碼: 1.啓用你想要使用的東西,設置混合函數,調用glPointParameterfvARB等 2.調用draw_particles(const std ::矢量 & v); 3.禁用融合等 – ralphtheninja 2009-05-23 17:10:24

回答

3

如果您particules已經排序可以使這樣的:

  • 渲染與GL WRITE深度,但是沒有深入的測試particule(我不記得確切的常量)
  • 渲染的休息場景與深度測試。

這樣,您一定會與漂亮的粒子獲得場景交互。

+0

設法找到了在同一時間,答案的解決方案是使用: glDepthMask(GL_FALSE); [渲染粒子] glDepthMask(GL_TRUE); – ICR 2009-05-23 16:50:32

2

注意:請在發佈問題時指定使用哪個OpenGL版本。這適用於任何API。 如果要使用alpha混合呈現圖元,則不能啓用深度寫入。您需要繪製您的混合基元,並將其重新排序。如果場景中有不透明的對象,則首先渲染它們,然後以深度測試已啓用且深度寫入禁用的方式以透明基元以前後排序的方式繪製。

glEnable(GL_DEPTH_TEST); 
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
glEnable(GL_POINT_SPRITE); 
glEnable(GL_CULL_FACE); 

while(1) 
{ 
    ... 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glDisable(GL_BLEND); 
    glDepthMask(1); 
    RenderOpaque(); 
    SortSprites(); 
    glEnable(GL_BLEND); 
    glDepthMask(0); 
    DrawSprites(); 
    ... 
}