Transparency again.

Started by
12 comments, last by doc_zero 20 years, 10 months ago
Do a check to see what is closer to the camera. The partical or the object. If the object is closer draw the partical first, if the partical is closer draw the object first.

Advertisement
I have objects drawn separatly from particles, so checking is not an easy answer (I hope there is another way).

This is the code to illustrate the problem. See at the end the draw function, where I can play with the order and settings for the depth testing and so on. And it looks like I found the solution. Then i have a different issue, I would like the particle not to be blended with the cube itself. When I have a real particle system, I have a trail of particles to form the fire, it looks great on the dark background, but when I have colored objects under this fire, fire is merely seen (acts like it is transparent).

Any ideas about that?

void draw_axis()
{
glColor3f(1.0f,0.0f,0.0f);
glBegin(GL_LINES);
glVertex3i(0,0,0);
glVertex3i(2,0,0);
glEnd();
glColor3f(0.0f,1.0f,0.0f);
glBegin(GL_LINES);
glVertex3i(0,0,0);
glVertex3i(0,2,0);
glEnd();
glColor3f(0.0f,0.0f,1.0f);
glBegin(GL_LINES);
glVertex3i(0,0,0);
glVertex3i(0,0,2);
glEnd();
}

void billboard()
{
float modelview[16];
// get the current modelview matrix
glGetFloatv(GL_MODELVIEW_MATRIX , modelview);
// undo all rotations
// beware all scaling is lost as well
for(int i=0;i<3;++i)
for(int j=0;j<3;++j)
if(i==j)
modelview[i*4+j]=1.0f;
else
modelview[i*4+j]=0.0f;
// set the modelview with no rotations
glLoadMatrixf(modelview);
}

void DrawCube()
{
float fSize=0.3f;
glPushMatrix();
glTranslatef(0.0f,0.5f,0.5f);
glBegin(GL_QUADS); // Draw A Quad
glColor3f(0.0f,fSize,0.0f); // Set The Color To Green
glVertex3f( fSize, fSize,-fSize); // Top Right Of The Quad (Top)
glVertex3f(-fSize, fSize,-fSize); // Top Left Of The Quad (Top)
glVertex3f(-fSize, fSize, fSize); // Bottom Left Of The Quad (Top)
glVertex3f( fSize, fSize, fSize); // Bottom Right Of The Quad (Top)
glColor3f(fSize,0.5f,0.0f); // Set The Color To Orange
glVertex3f( fSize,-fSize, fSize); // Top Right Of The Quad (Bottom)
glVertex3f(-fSize,-fSize, fSize); // Top Left Of The Quad (Bottom)
glVertex3f(-fSize,-fSize,-fSize); // Bottom Left Of The Quad (Bottom)
glVertex3f( fSize,-fSize,-fSize); // Bottom Right Of The Quad (Bottom)
glColor3f(fSize,0.0f,0.0f); // Set The Color To Red
glVertex3f( fSize, fSize, fSize); // Top Right Of The Quad (Front)
glVertex3f(-fSize, fSize, fSize); // Top Left Of The Quad (Front)
glVertex3f(-fSize,-fSize, fSize); // Bottom Left Of The Quad (Front)
glVertex3f( fSize,-fSize, fSize); // Bottom Right Of The Quad (Front)
glColor3f(fSize,fSize,0.0f); // Set The Color To Yellow
glVertex3f( fSize,-fSize,-fSize); // Top Right Of The Quad (Back)
glVertex3f(-fSize,-fSize,-fSize); // Top Left Of The Quad (Back)
glVertex3f(-fSize, fSize,-fSize); // Bottom Left Of The Quad (Back)
glVertex3f( fSize, fSize,-fSize); // Bottom Right Of The Quad (Back)
glColor3f(0.0f,0.0f,fSize); // Set The Color To Blue
glVertex3f(-fSize, fSize, fSize); // Top Right Of The Quad (Left)
glVertex3f(-fSize, fSize,-fSize); // Top Left Of The Quad (Left)
glVertex3f(-fSize,-fSize,-fSize); // Bottom Left Of The Quad (Left)
glVertex3f(-fSize,-fSize, fSize); // Bottom Right Of The Quad (Left)
glColor3f(fSize,0.0f,fSize); // Set The Color To Violet
glVertex3f( fSize, fSize,-fSize); // Top Right Of The Quad (Right)
glVertex3f( fSize, fSize, fSize); // Top Left Of The Quad (Right)
glVertex3f( fSize,-fSize, fSize); // Bottom Left Of The Quad (Right)
glVertex3f( fSize,-fSize,-fSize); // Bottom Right Of The Quad (Right)
glEnd();
glPopMatrix();
}

void DrawPlane()
{
float fSize=1.0f;
glPushMatrix();
billboard();
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2d(1,1); glVertex3f(+fSize,+fSize,0); // Top Right
glTexCoord2d(0,1); glVertex3f(-fSize,+fSize,0); // Top Left
glTexCoord2d(1,0); glVertex3f(+fSize,-fSize,0); // Bottom Right
glTexCoord2d(0,0); glVertex3f(-fSize,-fSize,0); // Bottom Left
glEnd();
glPopMatrix();
}

float angle=0.0f;

void TestDraw()
{
// setup view
int iScreenWidth=320,iScreenHeight=240;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0,0,iScreenWidth,iScreenHeight);
gluPerspective(45.0f,(GLfloat)iScreenWidth/(GLfloat)iScreenHeight,1.0f,1000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-3.0f); // to see something
glRotatef(angle,0.0f,1.0f,0.0f);angle++; // animation
// setup for drawing 3d objects
glEnable(GL_DEPTH_TEST);
glDepthMask(1);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
// draw object
draw_axis();
DrawCube();
// setup for drawing particles
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
// screws drawing at all if you do not add the same
// function with 1 at the end
glDepthMask(0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,txr);
// draw particles
glColor4f(1.0f,1.0f,1.0f,1.0f);
DrawPlane(); // draw plane one
glTranslatef(0.0f,0.0f,1.0f);
DrawPlane(); // draw plane two
glDepthMask(1);
}
In case you didn''t know about this before:
draw all non-transparent objects, with depth-writing enabled
then, draw transparent objects (preferably sorted back-to-front), with depth-writing disabled.


Kippesoep
quote:Original post by doc_zero
Then i have a different issue, I would like the particle not to be blended with the cube itself. When I have a real particle system, I have a trail of particles to form the fire, it looks great on the dark background, but when I have colored objects under this fire, fire is merely seen (acts like it is transparent).

Any ideas about that?


How about drawing an opaque darker particle behind the position of each fire particle? After you draw all of those, then draw the fire particles on top with blending?

Disclaimer: I haven''t actually delved into particle systems, so I dunno if that is a good method.


-solo (my site)
-solo (my site)

This topic is closed to new replies.

Advertisement