1/** 2 * Test Z compositing with glDrawPixels(GL_DEPTH_COMPONENT) and stencil test. 3 */ 4 5#include <stdio.h> 6#include <stdlib.h> 7#include <math.h> 8#include <GL/glew.h> 9#include "glut_wrap.h" 10 11 12static int Win; 13static GLfloat Xrot = 0, Yrot = 0, Zpos = 6; 14static GLboolean Anim = GL_FALSE; 15 16static int Width = 400, Height = 200; 17static GLfloat *Zimg; 18static GLubyte *Cimg; 19static GLboolean showZ = 0; 20 21 22static void 23Idle(void) 24{ 25 Xrot += 3.0; 26 Yrot += 4.0; 27 glutPostRedisplay(); 28} 29 30 31/** 32 * Draw first object, save color+Z images 33 */ 34static void 35DrawFirst(void) 36{ 37 static const GLfloat red[4] = { 1.0, 0.0, 0.0, 0.0 }; 38 39 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red); 40 41 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 42 43 glPushMatrix(); 44 glTranslatef(-1, 0, 0); 45 glRotatef(45 + Xrot, 1, 0, 0); 46 47 glutSolidTorus(0.75, 2.0, 10, 20); 48 49 glPopMatrix(); 50 51 glReadPixels(0, 0, Width, Height, GL_DEPTH_COMPONENT, GL_FLOAT, Zimg); 52 glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, Cimg); 53} 54 55 56/** 57 * Draw second object. 58 */ 59static void 60DrawSecond(void) 61{ 62 static const GLfloat blue[4] = { 0.0, 0.0, 1.0, 0.0 }; 63 64 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue); 65 66 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 67 68 glPushMatrix(); 69 glTranslatef(+1, 0, 0); 70 glRotatef(-45 + Xrot, 1, 0, 0); 71 72 glutSolidTorus(0.75, 2.0, 10, 20); 73 74 glPopMatrix(); 75} 76 77 78/** 79 * Composite first/saved image over second rendering. 80 */ 81static void 82Composite(void) 83{ 84 glWindowPos2i(0, 0); 85 86 /* Draw Z values, set stencil where Z test passes */ 87 glEnable(GL_STENCIL_TEST); 88 glStencilFunc(GL_ALWAYS, 1, ~0); 89 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); 90 glColorMask(0,0,0,0); 91 glDrawPixels(Width, Height, GL_DEPTH_COMPONENT, GL_FLOAT, Zimg); 92 glColorMask(1,1,1,1); 93 94 /* Draw color where stencil==1 */ 95 glStencilFunc(GL_EQUAL, 1, ~0); 96 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); 97 glDisable(GL_DEPTH_TEST); 98 glDrawPixels(Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, Cimg); 99 glEnable(GL_DEPTH_TEST); 100 101 glDisable(GL_STENCIL_TEST); 102} 103 104 105static void 106Draw(void) 107{ 108 DrawFirst(); 109 DrawSecond(); 110 Composite(); 111 glutSwapBuffers(); 112} 113 114 115static void 116Reshape(int width, int height) 117{ 118 GLfloat ar = (float) width / height; 119 glViewport(0, 0, width, height); 120 glMatrixMode(GL_PROJECTION); 121 glLoadIdentity(); 122 glFrustum(-ar, ar, -1.0, 1.0, 5.0, 30.0); 123 glMatrixMode(GL_MODELVIEW); 124 glLoadIdentity(); 125 glTranslatef(0.0, 0.0, -15.0); 126 127 Width = width; 128 Height = height; 129 130 if (Zimg) 131 free(Zimg); 132 if (Cimg) 133 free(Cimg); 134 Zimg = (float *) malloc(width * height * 4); 135 Cimg = (GLubyte *) malloc(width * height * 4); 136} 137 138 139static void 140Key(unsigned char key, int x, int y) 141{ 142 const GLfloat step = 1.0; 143 (void) x; 144 (void) y; 145 switch (key) { 146 case 'a': 147 Anim = !Anim; 148 if (Anim) 149 glutIdleFunc(Idle); 150 else 151 glutIdleFunc(NULL); 152 break; 153 case 'd': 154 showZ = !showZ; 155 break; 156 case 'z': 157 Zpos -= step; 158 break; 159 case 'Z': 160 Zpos += step; 161 break; 162 case 27: 163 glutDestroyWindow(Win); 164 exit(0); 165 break; 166 } 167 glutPostRedisplay(); 168} 169 170 171static void 172SpecialKey(int key, int x, int y) 173{ 174 const GLfloat step = 3.0; 175 (void) x; 176 (void) y; 177 switch (key) { 178 case GLUT_KEY_UP: 179 Xrot -= step; 180 break; 181 case GLUT_KEY_DOWN: 182 Xrot += step; 183 break; 184 case GLUT_KEY_LEFT: 185 Yrot -= step; 186 break; 187 case GLUT_KEY_RIGHT: 188 Yrot += step; 189 break; 190 } 191 glutPostRedisplay(); 192} 193 194 195static void 196Init(void) 197{ 198 /* setup lighting, etc */ 199 glEnable(GL_DEPTH_TEST); 200 glEnable(GL_LIGHTING); 201 glEnable(GL_LIGHT0); 202} 203 204 205int 206main(int argc, char *argv[]) 207{ 208 glutInit(&argc, argv); 209 glutInitWindowPosition(0, 0); 210 glutInitWindowSize(Width, Height); 211 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL); 212 Win = glutCreateWindow(argv[0]); 213 glewInit(); 214 glutReshapeFunc(Reshape); 215 glutKeyboardFunc(Key); 216 glutSpecialFunc(SpecialKey); 217 glutDisplayFunc(Draw); 218 if (Anim) 219 glutIdleFunc(Idle); 220 Init(); 221 glutMainLoop(); 222 return 0; 223} 224