485 489














Open GL Super Bible:Buffers: Not Just for Animation















To access the contents, click the chapter and section titles.


Open GL Super Bible


(Publisher: Macmillan Computer Publishing)

Author(s): Waite group Press

ISBN: 1571690735

Publication Date: 08/01/96

 




Previous
Table of Contents
Next




Listing 15-2 Using
glDrawBuffer to cut away selected pieces of an object

/*
* "depthcut.c" - A test program demonstrating the use of glDepthFunc()
* and glDrawBuffer() to cut away parts of a scene.
*
* Press the 'd' key to toggle between GL_LESS and GL_GREATER depth
* tests. Press the 'ESC' key to quit.
*/

#include <GL/glaux.h>

/*
* These #define constants are provided for compatibility between MS
* Windows and the rest of the world.
*
* CALLBACK and APIENTRY are function modifiers under MS Windows.
*/

#ifndef WIN32
# define CALLBACK
# define APIENTRY
#endif /* !WIN32 */

GLenum depth_function = GL_LESS; /* Current depth function */
GLfloat cutting_plane = -15.0, /* Cutting plane distance */
cutting_dir = -1.0; /* Cutting plane direction */

/*
* 'reshape_scene()' - Change the size of the scene...
*/

void CALLBACK
reshape_scene(GLsizei width, /* I - Width of the window in pixels */
GLsizei height) /* I - Height of the window in pixels */
{

/*
* Reset the current viewport and perspective transformation...
*/

glViewport(0, 0, width, height);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(22.5, (float)width / (float)height, 0.1, 1000.0);

glMatrixMode(GL_MODELVIEW);
}

/*
* 'draw_scene()' - Draw a scene containing a cube with a sphere in
* front of it.
*/

void CALLBACK
draw_scene(void)
{
static float red_light[4] = { 1.0, 0.0, 0.0, 1.0 };
static float red_pos[4] = { 1.0, 1.0, 1.0, 0.0 };
static float blue_light[4] = { 0.0, 0.0, 1.0, 1.0 };
static float blue_pos[4] = { -1.0, -1.0, -1.0, 0.0 };

/*
* Enable drawing features that we need...
*/

glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);

glShadeModel(GL_SMOOTH);
glDepthFunc(depth_function);

/*
* Clear the color and depth buffers...
*/

if (depth_function == GL_LESS)
glClearDepth(1.0);
else
glClearDepth(0.0);

glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

/*
* Draw the cutting plane. Note that we disable drawing into the normal
* color buffer while we do this...
*/

glDrawBuffer(GL_NONE);
glBegin(GL_POLYGON);
glVertex3f(-100.0, 100.0, cutting_plane);
glVertex3f(100.0, 100.0, cutting_plane);
glVertex3f(100.0, -100.0, cutting_plane);
glVertex3f(-100.0, -100.0, cutting_plane);
glEnd();

glDrawBuffer(GL_BACK);

/*
* Draw the cube and sphere in different colors...
*
* We have positioned two lights in this scene. The first is red and
* located above, to the right, and behind the viewer. The second

* is blue and located below, to the left, and in front of the viewer.
*/

glLightfv(GL_LIGHT0, GL_DIFFUSE, red_light);
glLightfv(GL_LIGHT0, GL_POSITION, red_pos);

glLightfv(GL_LIGHT1, GL_DIFFUSE, blue_light);
glLightfv(GL_LIGHT1, GL_POSITION, blue_pos);

glPushMatrix();
glTranslatef(-1.0, 0.0, -20.0);
auxSolidSphere(1.0);
glPopMatrix();

glPushMatrix();
glTranslatef(1.0, 0.0, -20.0);
glRotatef(15.0, 0.0, 1.0, 0.0);
glRotatef(15.0, 0.0, 0.0, 1.0);
auxSolidCube(2.0);
glPopMatrix();

auxSwapBuffers();
}

/*
* 'toggle_depth()' - Toggle the depth function between GL_LESS and
* GL_GREATER.
*/

void CALLBACK
toggle_depth(void)
{
if (depth_function == GL_LESS)
depth_function = GL_GREATER;
else
depth_function = GL_LESS;
}

/*
* 'move_plane()' - Move the cutting plane while we are idle...
*/

void CALLBACK
move_plane(void)
{
cutting_plane += cutting_dir;

/*
* Reverse directions as needed...
*/

if (cutting_plane <= -30.0 ||
cutting_plane >= -15.0)
cutting_dir = -cutting_dir;

draw_scene();
}

/*
* 'main()' - Initialize the window and display the scene until the
* user presses the ESCape key.
*/

void
main(void)
{
auxInitDisplayMode(AUX_RGB | AUX_DOUBLE | AUX_DEPTH);
auxInitWindow("Depth Function");

auxKeyFunc(AUX_d, toggle_depth);
auxReshapeFunc(reshape_scene);
auxIdleFunc(move_plane);

auxMainLoop(draw_scene);
}

/*
* End of "depthcut.c".
*/

The Stencil Buffer
The stencil buffer provides many options to restrict drawing on the screen and has many applications that the depth buffer just canłt do. At its simplest level, the stencil buffer can be used to block out certain areas on the screen. For example, a flight simulation program might use the stencil buffer to restrict drawing operations to the inside of the aircraftłs round controls such as the artificial horizon and airspeed indicators.

Perhaps the most exciting application of the stencil buffer is for shadows. Depending on your graphics hardware, you can generate hard and soft shadows from multiple light sources, making your scenes much more realistic and exciting.
Using the Stencil Buffer
To use the stencil buffer, you have to first request one. For Windows, this means setting the cStencilBits field in the Pixel Format Descriptor (PFD) for your window, as in


pfd.cStencilBits = 1;

Once you have requested a stencil buffer, you must enable stenciling by calling glEnable(GL_STENCIL_TEST). Without this call, all stencil buffer operations are disabled.
Stencil Buffer Functions
There are four stenciling functions in OpenGL:


void glClearStencil(GLint s)
void glStencilFunc(GLenum func, GLint ref, GLuint mask)
void glStencilMask(GLuint mask)
void glStencilOp(GLenum fail, GLenum zfail, GLzpass)

The glClearStencil function is similar to glClearColor, glClearDepth, and glClearIndex; it provides the initial value that is stored in the stencil buffer when glClear(GL_STENCIL_BIT) is called. By default, a 0 stencil value is stored in the stencil buffer. Unlike the depth and color buffers, you donłt always clear the stencil buffer every time you redisplay your scene. In the flight simulator example mentioned earlier, the aircraft control area might never change position or size, so redrawing into the stencil buffer would be unnecessary.



Previous
Table of Contents
Next














 


Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.












Wyszukiwarka

Podobne podstrony:
485 489
489 Polska reklamaq51 874 4
485 Gordon Lucy Dziesiąta rocznica ślubu
411 489
489 Jaką metodę amortyzacji środków trwałych wybrać
485 486
RS 422 RS 485 Communication protocol user s guide(1)
482 485
06 (485)
485 488
05 (489)
482 485
index (485)
489 493

więcej podobnych podstron