【发布时间】:2016-01-21 05:29:28
【问题描述】:
我有一个用 OpenGL 和 glut 制作的小精灵粒子系统,使用纹理来绘制基本的火焰。火焰对称地再现,以说明它在一个小盒子/场景中的表现。如下图所示,存在两个问题:
1- 为了产生看起来不错的火焰效果,我想对我的粒子使用添加剂混合,但混合还考虑了更深的青色面板的颜色并产生白色火焰。
2.1 - 此外,为了正确实现加法混合,我必须在绘制粒子时禁用深度测试,但这样做会启用粒子的绘制,即使它们应该“隐藏”。
2.2 - 如果我在绘制粒子时启用深度测试,效果如下。
如果有任何帮助,这里是我应用到粒子的纹理。
这里是显示场景和粒子的相关代码。
void drawParticles()
{
glPushAttrib(GL_ALL_ATTRIB_BITS);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
glBindTexture(GL_TEXTURE_2D,explosionTexture[0]);
glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
for (int i = 0; i < particlesNumber; ++i)
{
glPointSize(50.0f);
glBegin(GL_POINTS);
glColor4f(particlesArray[i].color[0],particlesArray[i].color[1],particlesArray[i].color[2],0.5f);
glVertex3f(particlesArray[i].position[0],particlesArray[i].position[1],particlesArray[i].position[2]);
glEnd();
}
glBindTexture(GL_TEXTURE_2D, 0);
glDisable( GL_BLEND );
glEnable( GL_DEPTH_TEST );
glPopAttrib();
}
void drawScene()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 60.0f, (GLdouble) g_width / (GLdouble) g_height, 0.1f, 300.0f );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
gluLookAt( dist*sin(phi)*sin(theta), dist*cos(phi), dist*sin(phi)*cos(theta), 0, 0, 0, 0, 1, 0 );
glEnable( GL_DEPTH_TEST );
glDisable( GL_BLEND );
glBegin( GL_LINES );
glColor3f( 1.0f, 0.0f, 0.0f );
glVertex3f( 0.0f, 0.0f, 0.0f );
glVertex3f( 0.5f, 0.0f, 0.0f );
glColor3f( 0.0f, 1.0f, 0.0f );
glVertex3f( 0.0f, 0.0f, 0.0f );
glVertex3f( 0.0f, 0.5f, 0.0f );
glColor3f( 0.0f, 0.0f, 1.0f );
glVertex3f( 0.0f, 0.0f, 0.0f );
glVertex3f( 0.0f, 0.0f, 0.5f );
glEnd();
glBegin( GL_QUADS );
glColor4f( 1.0f, 1.0f, 1.0f , 0.0f);
glVertex3f( -1.0f, -0.2f, 1.0f );
glVertex3f( 1.0f, -0.2f, 1.0f );
glVertex3f( 1.0f, -0.2f, -1.0f );
glVertex3f( -1.0f, -0.2f, -1.0f );
glColor4f( 1.0f, 1.0f, 0.0f , 0.0f );
glVertex3f( 1.0f, -2.0f, 1.0f );
glVertex3f( 1.0f, -2.0f, -1.0f );
glVertex3f( 1.0f, -0.2f, -1.0f );
glVertex3f( 1.0f, -0.2f, 1.0f );
glColor4f( 1.0f, 0.0f, 1.0f , 0.0f );
glVertex3f( -1.0f, -2.0f, 1.0f );
glVertex3f( -1.0f, -2.0f, -1.0f );
glVertex3f( -1.0f, -0.2f, -1.0f );
glVertex3f( -1.0f, -0.2f, 1.0f );
glColor4f( 0.0f, 1.0f, 1.0f , 1.0f );
glVertex3f( 1.0f, -2.0f, -1.0f );
glVertex3f( -1.0f, -2.0f, -1.0f );
glVertex3f( -1.0f, -0.2f, -1.0f );
glVertex3f( 1.0f, -0.2f, -1.0f );
glEnd();
glPushMatrix();
drawParticles();
glScalef(1.0f, -1.0f, 1.0f);
drawParticles();
glPopMatrix();
glutSwapBuffers();
}
我愿意接受任何类型的建议,甚至涉及着色器(但我很想知道是否可以仅使用普通的 OpenGL)。
更新:
也许我不清楚,我不一定对严格的固定管道解决方案感兴趣,我想知道如何在场景中管理加法混合,即使这意味着将着色器代码添加到我的项目中。
现在,正如 Columbo 指出的那样,启用深度测试并禁用深度写入解决了我的第二个问题。现在关于加法混合问题,我仍然不知道如何在场景中管理加法混合。即使场景中可能没有这样的基本颜色,问题仍然存在,因为火焰仍然是白色的,我愿意知道我必须按照建议使用像素着色器。
【问题讨论】:
-
"只有普通的 OpenGL":OpenGL 2.1+ 它是普通的 OpenGL 来编写着色器。
-
@CoffeeandCode 我认为我们可以通过引用带有 GLSL 的着色器来区分 OpenGL 和着色器。抱歉使用的术语具有误导性...无论如何,我的意思是我没有为此编写任何着色器,并且想知道如果不编写着色器是否有可能。
-
如果您正在学习 OpenGL 并希望将来真正使用您的知识,我建议您忘记所有固定功能的东西,只学习 OpenGL 3.3 核心配置文件并进行扩展测试。
标签: c++ c opengl shader particle-system