Jump to content
  • Advertisement
Sign in to follow this  
d h k

OpenGL Floor Reflections

This topic is 4766 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everyone, I read the brief article about reflections with OpenGL here at gamedev.net and am trying to include this cool looking effect into my own project. My game uses 3-dimensional tiles ( 5 x 20 for now with each a size of 2 x 1 x 3 [some exceptions] ) - will adding the reflection to all those tiles decrease performance (a lot)? Is the current "draw_scene ( )" funtion correct or do I have some mistake in there that I don't know of? This function makes my game first minimize and then when I maximize it, it is really slow...
void draw_scene ( void )
{

  // clear the screen
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

  // reset the matrix
  glLoadIdentity ( );

  // draw the user
  user.draw ( );

  glLoadIdentity ( );
  /* Don't update color or depth. */
  glDisable(GL_DEPTH_TEST);
  glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

  /* Draw 1 into the stencil buffer. */
  glEnable(GL_STENCIL_TEST);
  glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
  glStencilFunc(GL_ALWAYS, 1, 0xffffffff);

  /* Now drawing the floor just tags the floor pixels
     as stencil value 1. */
  // draw the tiles
	for ( int x = 0; x < MAP_WIDTH; x++ )
	{
		for ( int y = 0; y < MAP_LENGTH; y++ )
		{
			tile[x][y].position.x = (float) x;
			tile[x][y].position.y = 0.0f;
			tile[x][y].position.z = (float) y;
			tile[x][y].draw ( );
		}
	}

  /* Re-enable update of color and depth. */ 
  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  glEnable(GL_DEPTH_TEST);

  /* Now, only render where stencil is set to 1. */
  glStencilFunc(GL_EQUAL, 1, 0xffffffff);  /* draw if stencil ==1 */
  glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

  /* Draw reflected ninja, but only where floor is. */
  glPushMatrix();
    glScalef(1.0, -1.0, 1.0);
    // draw the user
	user.draw ( );
  glPopMatrix();

  glDisable(GL_STENCIL_TEST);
}

Share this post


Link to post
Share on other sites
Advertisement
For reflections, I'd say you need to draw your entire scene (more or less) two-three times more... so, take the time needed for one frame, and simply multiply by three... :D

but then again, that's the result of my engine, not facts.. hehe.

cheers!

Share this post


Link to post
Share on other sites
Update: It turned out that minimization thing was caused by something different... I have cleaned up the "draw_scene" function now and tested several things, but nothing has worked entirely correct yet...

This is the best version so far:


void draw_scene ( void )
{
// clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glEnable(GL_STENCIL_TEST);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
glStencilFunc(GL_ALWAYS, 1, 0xffffffff);

glLoadIdentity ( );

// draw the tiles
for ( int x = 0; x < MAP_WIDTH; x++ )
{
for ( int y = 0; y < MAP_LENGTH; y++ )
{
if ( tile[x][y].type == STANDARD )
{
tile[x][y].position.x = (float) x;
tile[x][y].position.y = 0.0f;
tile[x][y].position.z = (float) y;
tile[x][y].draw ( );
}
}
}

glLoadIdentity ( );

glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

glStencilFunc(GL_EQUAL, 1, 0xffffffff);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

glScalef(1.0, -1.0, 1.0);
glTranslatef ( 0.0f, 5.0f, 0.0f );

glEnable(GL_BLEND );
glColor4f(1.0f,1.0f,1.0f,0.4f);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);

user.draw ( );

glDisable(GL_BLEND);

glPopMatrix();
glDisable(GL_STENCIL_TEST);

glLoadIdentity ( );

user.draw ( );

glLoadIdentity ( );

// move camera behind the ball
glTranslatef ( user.sphere.position.x, -CAM_HEIGHT, user.sphere.position.z );

// draw the tiles
for ( x = 0; x < MAP_WIDTH; x++ )
{
for ( int y = 0; y < MAP_LENGTH; y++ )
{
if ( tile[x][y].type == STANDARD )
{
glEnable(GL_BLEND );
glColor4f(1.0f,1.0f,1.0f,0.2f);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
}
tile[x][y].position.x = (float) x;
tile[x][y].position.y = 0.0f;
tile[x][y].position.z = (float) y;
tile[x][y].draw ( );
if ( tile[x][y].type == STANDARD )
{
glDisable(GL_BLEND);
}
}
}
}



This is really slow and it draws the reflection everywhere - not only on the tile ground... So it seems like the whole stencil buffer thing is not working, but what exactly is wrong?

Thanks for your reply though - keep them coming please.

Share this post


Link to post
Share on other sites
Something you may want to do is look into drawing the scene inverted to a texture (via pbuffer or glTexSubImage). Then though projective texturing you can multi texture your tiles or what ever with this reflection. This is the same method used for doing a vast majority of the reflective water you see every one doing.

Share this post


Link to post
Share on other sites
Sounds similar to an issue I had when I didn't read the nehe stencil test article properly. Have you specified the number of stencil buffer bits in the pixelformatdescriptor of your window setup code?

taken from the NeHe article:


static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be
{
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
bits, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
0, // No Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
16, // 16Bit Z-Buffer (Depth Buffer)
1, // Use Stencil Buffer ( * Important * )
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!