1/* showbuffer.c */
2
3
4/*
5 * Copy the depth buffer to the color buffer as a grayscale image.
6 * Useful for inspecting the depth buffer values.
7 *
8 * This program is in the public domain.
9 *
10 * Brian Paul   November 4, 1998
11 */
12
13
14#include <assert.h>
15#include <stdlib.h>
16#include "gl_wrap.h"
17#include "showbuffer.h"
18
19
20
21/*
22 * Copy the depth buffer values into the current color buffer as a
23 * grayscale image.
24 * Input:  winWidth, winHeight - size of the window
25 *         zBlack - the Z value which should map to black (usually 1)
26 *         zWhite - the Z value which should map to white (usually 0)
27 */
28void
29ShowDepthBuffer( GLsizei winWidth, GLsizei winHeight,
30                 GLfloat zBlack, GLfloat zWhite )
31{
32   GLfloat *depthValues;
33
34   assert(zBlack >= 0.0);
35   assert(zBlack <= 1.0);
36   assert(zWhite >= 0.0);
37   assert(zWhite <= 1.0);
38   assert(zBlack != zWhite);
39
40   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
41   glPixelStorei(GL_PACK_ALIGNMENT, 1);
42
43   /* Read depth values */
44   depthValues = (GLfloat *) malloc(winWidth * winHeight * sizeof(GLfloat));
45   assert(depthValues);
46   glReadPixels(0, 0, winWidth, winHeight, GL_DEPTH_COMPONENT,
47                GL_FLOAT, depthValues);
48
49   /* Map Z values from [zBlack, zWhite] to gray levels in [0, 1] */
50   /* Not using glPixelTransfer() because it's broke on some systems! */
51   if (zBlack != 0.0 || zWhite != 1.0) {
52      GLfloat scale = 1.0 / (zWhite - zBlack);
53      GLfloat bias = -zBlack * scale;
54      int n = winWidth * winHeight;
55      int i;
56      for (i = 0; i < n; i++)
57         depthValues[i] = depthValues[i] * scale + bias;
58   }
59
60   /* save GL state */
61   glPushAttrib(GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT |
62                GL_TRANSFORM_BIT | GL_VIEWPORT_BIT);
63
64   /* setup raster pos for glDrawPixels */
65   glMatrixMode(GL_PROJECTION);
66   glPushMatrix();
67   glLoadIdentity();
68
69   glOrtho(0.0, (GLdouble) winWidth, 0.0, (GLdouble) winHeight, -1.0, 1.0);
70   glMatrixMode(GL_MODELVIEW);
71   glPushMatrix();
72   glLoadIdentity();
73
74   glViewport(0, 0, winWidth, winHeight);
75
76   glDisable(GL_STENCIL_TEST);
77   glDisable(GL_DEPTH_TEST);
78   glRasterPos2f(0, 0);
79
80   glDrawPixels(winWidth, winHeight, GL_LUMINANCE, GL_FLOAT, depthValues);
81
82   glPopMatrix();
83   glMatrixMode(GL_PROJECTION);
84   glPopMatrix();
85   free(depthValues);
86
87   glPopAttrib();
88}
89
90
91
92
93/*
94 * Copy the alpha channel values into the current color buffer as a
95 * grayscale image.
96 * Input:  winWidth, winHeight - size of the window
97 */
98void
99ShowAlphaBuffer( GLsizei winWidth, GLsizei winHeight )
100{
101   GLubyte *alphaValues;
102
103   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
104   glPixelStorei(GL_PACK_ALIGNMENT, 1);
105
106   /* Read alpha values */
107   alphaValues = (GLubyte *) malloc(winWidth * winHeight * sizeof(GLubyte));
108   assert(alphaValues);
109   glReadPixels(0, 0, winWidth, winHeight, GL_ALPHA, GL_UNSIGNED_BYTE, alphaValues);
110
111   /* save GL state */
112   glPushAttrib(GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL |
113                GL_TRANSFORM_BIT | GL_VIEWPORT_BIT);
114
115   /* setup raster pos for glDrawPixels */
116   glMatrixMode(GL_PROJECTION);
117   glPushMatrix();
118   glLoadIdentity();
119
120   glOrtho(0.0, (GLdouble) winWidth, 0.0, (GLdouble) winHeight, -1.0, 1.0);
121   glMatrixMode(GL_MODELVIEW);
122   glPushMatrix();
123   glLoadIdentity();
124
125   glViewport(0, 0, winWidth, winHeight);
126
127   glDisable(GL_STENCIL_TEST);
128   glDisable(GL_DEPTH_TEST);
129   glRasterPos2f(0, 0);
130
131   glDrawPixels(winWidth, winHeight, GL_LUMINANCE, GL_UNSIGNED_BYTE, alphaValues);
132
133   glPopMatrix();
134   glMatrixMode(GL_PROJECTION);
135   glPopMatrix();
136   free(alphaValues);
137
138   glPopAttrib();
139}
140
141
142
143/*
144 * Copy the stencil buffer values into the current color buffer as a
145 * grayscale image.
146 * Input:  winWidth, winHeight - size of the window
147 *         scale, bias - scale and bias to apply to stencil values for display
148 */
149void
150ShowStencilBuffer( GLsizei winWidth, GLsizei winHeight,
151                   GLfloat scale, GLfloat bias )
152{
153   GLubyte *stencilValues;
154
155   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
156   glPixelStorei(GL_PACK_ALIGNMENT, 1);
157
158   /* Read stencil values */
159   stencilValues = (GLubyte *) malloc(winWidth * winHeight * sizeof(GLubyte));
160   assert(stencilValues);
161   glReadPixels(0, 0, winWidth, winHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilValues);
162
163   /* save GL state */
164   glPushAttrib(GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT |
165                GL_PIXEL_MODE_BIT | GL_TRANSFORM_BIT | GL_VIEWPORT_BIT);
166
167   /* setup raster pos for glDrawPixels */
168   glMatrixMode(GL_PROJECTION);
169   glPushMatrix();
170   glLoadIdentity();
171
172   glOrtho(0.0, (GLdouble) winWidth, 0.0, (GLdouble) winHeight, -1.0, 1.0);
173   glMatrixMode(GL_MODELVIEW);
174   glPushMatrix();
175   glLoadIdentity();
176
177   glViewport(0, 0, winWidth, winHeight);
178
179   glDisable(GL_STENCIL_TEST);
180   glDisable(GL_DEPTH_TEST);
181   glRasterPos2f(0, 0);
182
183   glPixelTransferf(GL_RED_SCALE, scale);
184   glPixelTransferf(GL_RED_BIAS, bias);
185   glPixelTransferf(GL_GREEN_SCALE, scale);
186   glPixelTransferf(GL_GREEN_BIAS, bias);
187   glPixelTransferf(GL_BLUE_SCALE, scale);
188   glPixelTransferf(GL_BLUE_BIAS, bias);
189
190   glDrawPixels(winWidth, winHeight, GL_LUMINANCE, GL_UNSIGNED_BYTE, stencilValues);
191
192   glPopMatrix();
193   glMatrixMode(GL_PROJECTION);
194   glPopMatrix();
195   free(stencilValues);
196
197   glPopAttrib();
198}
199