Drawing reflection capture the extra realism of the Object in 3D programming.For example Bouncing ball having its reflection on the floor can make the bouncing scenario more beautiful and realistic. So,OpenGL has all the features needed to render fast high-quality reflections on planar surfaces.
Reflection technique is not so hard its pretty simple.If you want to draw reflection on floor then suppose your floor is in x-z plane and your object along positive y-axis above the plane then for reflection of object draw the copy of object along the negative y-axis vertically below the plane or floor.Your floor must look like the reflecting surface to see the object which is below the floor for this we use alpha blending which make the floor transparent by certain percent say 40% then it is specified to be 40% the color of the floor and 60% the color of the reflection or object.But only alpha blending doesn’t make the reflection real because the reflected copy of the object may leak outside or bottom of the floor so to fixed this problem we actually going to use the stencil buffer concept.With OpenGL stenciling, we can "pre-draw" the floor into the stencil buffer without updating the color or depth buffers. Then when we go to draw the reflection, just only allow the reflection to update pixels marked as belonging to the floor's stencil value. The floor can then be any complex (but coplanar) polygon and the reflection only shows up in the floor.
Here is the sample source code, copy and compile it.I hope it will help you.
#include <windows.h>
#include <iostream>
#include <stdlib.h>
#include <GL/glut.h>
using namespace std;
const float LIGHT_POS = 7.0f; //The length of each side of the cube
const float BOX_HEIGHT = LIGHT_POS ; //The height of the box off of the ground
const float FLOOR_SIZE = 20.0f; //The length of each side of the floor
//Draws the cubevoid drawCube(float angle) {
glPushMatrix();
glRotatef(-angle, 1.0f, 1.0f, 0.0f);
glBegin(GL_QUADS);
//Cross backglColor4f(0.0f,1.0f, 0.0f, 0.9f);
glVertex3f(-0.5, 2.5, -0.5);
glVertex3f(-0.5, -3.0, -0.5);
glVertex3f(0.5, -3.0, -0.5);
glVertex3f(0.5, 2.5, -0.5);
glVertex3f(-2.0, 1.0, -0.5);
glVertex3f(-2.0, 0.0, -0.5);
glVertex3f(2.0, 0.0, -0.5);
glVertex3f(2.0, 1.0, -0.5);
//Cross frontglColor4f(1.0f, 1.0f, 0.0f, 0.9f);
glVertex3f(-0.5, 2.5, 0.5);
glVertex3f(-0.5, -3.0, 0.5);
glVertex3f(0.5, -3.0, 0.5);
glVertex3f(0.5, 2.5, 0.5);
glVertex3f(-2.0, 1.0, 0.5);
glVertex3f(-2.0, 0.0, 0.5);
glVertex3f(2.0, 0.0, 0.5);
glVertex3f(2.0, 1.0, 0.5);
//Cross topglColor3f(1.0,0.0,0.0);
glVertex3f(0.5, 2.5, 0.5);
glVertex3f(-0.5, 2.5, 0.5);
glVertex3f(-0.5, 2.5, -0.5);
glVertex3f(0.5, 2.5, -0.5);
//Cross left top sideglColor3f(0.0,0.0,1.0);
glVertex3f(-0.5, 2.5, 0.5);
glVertex3f(-0.5, 2.5, -0.5);
glVertex3f(-0.5, 1.0, -0.5);
glVertex3f(-0.5, 1.0, 0.5);
//Cross left side topglVertex3f(-0.5, 1.0, 0.5);
glVertex3f(-0.5, 1.0, -0.5);
glVertex3f(-2.0, 1.0, -0.5);
glVertex3f(-2.0, 1.0, 0.5);
//Cross left side endglColor3f(1.0,0.0,0.0);
glVertex3f(-2.0, 1.0, 0.5);
glVertex3f(-2.0, 1.0, -0.5);
glVertex3f(-2.0, 0.0, -0.5);
glVertex3f(-2.0, 0.0, 0.5);
//Cross left side bottomglColor3f(0.0,0.0,1.0);
glVertex3f(-2.0, 0.0, 0.5);
glVertex3f(-0.5, 0.0, 0.5);
glVertex3f(-0.5, 0.0, -0.5);
glVertex3f(-2.0, 0.0, -0.5);
//Cross left bottom sideglVertex3f(-0.5, 0.0, 0.5);
glVertex3f(-0.5, 0.0, -0.5);
glVertex3f(-0.5, -3.0, -0.5);
glVertex3f(-0.5, -3.0, 0.5);
//Cross bottomglColor3f(1.0,0.0,0.0);
glVertex3f(0.5, -3.0, 0.5);
glVertex3f(0.5, -3.0, -0.5);
glVertex3f(-0.5, -3.0, -0.5);
glVertex3f(-0.5, -3.0, 0.5);
//Cross right bottom sideglColor3f(0.0,0.0,1.0);
glVertex3f(0.5, 0.0, 0.5);
glVertex3f(0.5, -3.0, 0.5);
glVertex3f(0.5, -3.0, -0.5);
glVertex3f(0.5, 0.0, -0.5);
//Cross right side bottomglVertex3f(0.5, 0.0, 0.5);
glVertex3f(0.5, 0.0, -0.5);
glVertex3f(2.0, 0.0, -0.5);
glVertex3f(2.0, 0.0, 0.5);
//Cross right side endglColor3f(1.0,0.0,0.0);
glVertex3f(2.0, 1.0, 0.5);
glVertex3f(2.0, 0.0, 0.5);
glVertex3f(2.0, 0.0, -0.5);
glVertex3f(2.0, 1.0, -0.5);
//Cross right side topglColor3f(0.0,0.0,1.0);
glVertex3f(0.5, 1.0, 0.5);
glVertex3f(2.0, 1.0, 0.5);
glVertex3f(2.0, 1.0, -0.5);
glVertex3f(0.5, 1.0, -0.5);
//Cross right side topglVertex3f(0.5, 1.0, 0.5);
glVertex3f(0.5, 1.0, -0.5);
glVertex3f(0.5, 2.5, -0.5);
glVertex3f(0.5, 2.5, 0.5);
glEnd();
glPopMatrix();
}
//Draws the floorvoid drawFloor() {glBegin(GL_QUADS);
glNormal3f(0, 1, 0);
glVertex3f(-FLOOR_SIZE / 2, 0, FLOOR_SIZE / 2);
glVertex3f(-FLOOR_SIZE / 2, 0, -FLOOR_SIZE / 2);
glVertex3f(FLOOR_SIZE / 2, 0, -FLOOR_SIZE / 2);
glVertex3f(FLOOR_SIZE / 2, 0, FLOOR_SIZE / 2);
glEnd();
}
float _angle = 0;void handleKeypress(unsigned char key, int x, int y) {
switch (key) {case 27: //Escape key
exit(0);
}
}
void initRendering() {glClearColor(1.0,1.0,1.0,1.0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void handleResize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (float)w / (float)h, 1.0, 200.0);
}
void drawScene() {glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -40.0f);
glRotatef(30, 1, 0, 0);
GLfloat ambientLight[] = {0.3f, 0.3f, 0.3f, 1.0f};glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);
GLfloat lightColor[] = {0.7f, 0.7f, 0.7f, 1.0f};GLfloat lightPos[] = {-2 * LIGHT_POS , LIGHT_POS , 4 * LIGHT_POS , 1.0f};glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
glPushMatrix();
glTranslatef(0, BOX_HEIGHT, 0);
drawCube(_angle);
glPopMatrix();
glEnable(GL_STENCIL_TEST); //Enable using the stencil bufferglColorMask(0, 0, 0, 0); //Disable drawing colors to the screenglDisable(GL_DEPTH_TEST); //Disable depth testingglStencilFunc(GL_ALWAYS, 1, 1); //Make the stencil test always pass//Make pixels in the stencil buffer be set to 1 when the stencil test passesglStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
//Set all of the pixels covered by the floor to be 1 in the stencil bufferdrawFloor();
glColorMask(1, 1, 1, 1); //Enable drawing colors to the screenglEnable(GL_DEPTH_TEST); //Enable depth testing//Make the stencil test pass only when the pixel is 1 in the stencil bufferglStencilFunc(GL_EQUAL, 1, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); //Make the stencil buffer not change//Draw the cube, reflected vertically, at all pixels where the stencil//buffer is 1glPushMatrix();
glScalef(1, -1, 1);
glTranslatef(0, BOX_HEIGHT, 0);
drawCube(_angle);
glPopMatrix();
glDisable(GL_STENCIL_TEST); //Disable using the stencil buffer//Blend the floor onto the screenglEnable(GL_BLEND);
glColor4f(0, 0, 0.5, 0.5f);
drawFloor();
glDisable(GL_BLEND);
glutSwapBuffers();
}
void update(int value) {
_angle += 1.0f;
if (_angle > 360) {_angle -= 360;
}
glutPostRedisplay();
glutTimerFunc(25, update, 0);
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_STENCIL);
glutInitWindowSize(600, 600);
glutCreateWindow("www.codeincodeblock.blogspot.com");initRendering();
glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutReshapeFunc(handleResize);
glutTimerFunc(25, update, 0);
glutMainLoop();
return 0;}
No comments:
Post a Comment