cgv
Loading...
Searching...
No Matches
gl_depth_peeler.cxx
1#include <cgv_gl/gl/gl.h>
2#include "gl_depth_peeler.h"
3
4namespace cgv {
5 namespace render {
6 namespace gl {
7
9gl_depth_peeler::gl_depth_peeler(bool f2b, float _depth_bias)
10 : depth_texture("[D]", TF_NEAREST, TF_NEAREST, TW_CLAMP, TW_CLAMP)
11{
12 query = -1;
13 front_to_back = f2b;
14 ctx_ptr = 0;
15 depth_bias = _depth_bias;
16 _invert_t = false;
17}
18
21{
22 _invert_t = enable;
23}
24
27{
28 front_to_back = false;
29}
32{
33 front_to_back = true;
34}
35
36
39{
40 return front_to_back;
41}
42
49
52{
53 depth_texture.destruct(ctx);
54}
55
58{
59 depth_bias = (GLfloat) bias;
60}
63{
64 return depth_bias;
65}
66
69{
70 return ctx_ptr != 0;
71}
72
75{
77 last_error = "could not initialize glew";
78 return false;
79 }
80 if (!GLEW_ARB_occlusion_query) {
81 last_error = "missing ARB occlusion query extension";
82 return false;
83 }
84 if (!GLEW_ARB_texture_rectangle) {
85 last_error = "missing ARB texture rectangle extension";
86 return false;
87 }
88 if (!GLEW_ARB_depth_texture) {
89 last_error = "missing ARB depth texture extension";
90 return false;
91 }
92 if (!GLEW_ARB_shadow) {
93 last_error = "missing ARB shadow extension";
94 return false;
95 }
96 ctx_ptr = &ctx;
97 return true;
98}
99
101{
102 // allocate memory for depth texture
103 GLint vp[4];
104 glGetIntegerv(GL_VIEWPORT, vp);
105 if (!depth_texture.is_created() || vp[2] != depth_texture.get_width() || vp[3] != depth_texture.get_height()) {
106 if (depth_texture.is_created())
107 depth_texture.destruct(ctx);
108 depth_texture.set_width(vp[2]);
109 depth_texture.set_height(vp[3]);
110 depth_texture.set_compare_mode(true);
111 depth_texture.set_compare_function(CF_GREATER);
112 depth_texture.create(ctx);
113 }
114}
115
117{
118 GLint vp[4];
119 glGetIntegerv(GL_VIEWPORT, vp);
120 depth_texture.replace_from_buffer(ctx,0,0,vp[0],vp[1],vp[2],vp[3],0);
121}
122
123void gl_depth_peeler::begin_layer(context& ctx, int tex_unit)
124{
125 glPushAttrib(GL_TEXTURE_BIT);
126 glPushAttrib(GL_COLOR_BUFFER_BIT);
127
128 // enable the depth texture (2nd depth buffer)
129 depth_texture.enable(ctx, tex_unit);
130
131 if (tex_unit >= 0) {
132 if (!ensure_glew_initialized() || !glActiveTextureARB)
133 tex_unit = -1;
134 else
135 glActiveTextureARB(GL_TEXTURE0_ARB+tex_unit);
136 }
137
138 // Use OpenGL- Extension GL_ARB_shadow and set the r texture coordinate to be tested
139 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
140 // check whether the computed texture coordinate is greater or equal to the value stored in the texture
141 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, front_to_back?GL_GEQUAL:GL_LEQUAL);
142 // write the result of the test to the alpha channel (1 for r >= tex(s,t) and 0 for r < tex(s,t) )
143 glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA);
144
145 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
146
147 /*************************************************************
148
149 the texture coordinates with which the 2nd depth buffer
150 is accessed must correspond to in s and t to the normalized
151 device but re-normalized from [-1,1] to [0,1]. The r texture
152 coordinate must correspond to the z-buffer value [0,1]. To
153 compute (s,t,r) 4D texture coordinates (s',t',r',q') are used
154 together with the q'-clip ( s=s'/q', t=t'/q', r=r'/q' ).
155
156 We use the matrices
157
158 mm ... modelview matrix
159 mp ... modelview projection
160 transAndScale ... re-normalization matrix
161
162 these are multiplied together to
163
164 M = transAndScale*mp*mm
165
166 to compute s' we compute the scalar product of the first row of M
167 with the current vertex (x,y,z,w). t/r/q are computed from the
168 second/third/fourth rows of M. This is done by the automatic
169 texture coordinate generation.
170
171 ********************************************************************/
172
173 // gather all matrices
174 static GLdouble transAndScale[] = {
175 0.5,0.0,0.0,0.0,
176 0.0,0.5,0.0,0.0,
177 0.0,0.0,0.5,0.0,
178 0.5,0.5,0.5,1.0};
179 GLdouble mp[16];
180 glGetDoublev(GL_PROJECTION_MATRIX, &mp[0]);
181
182 GLdouble mm[16];
183 glGetDoublev(GL_MODELVIEW_MATRIX, &mm[0]);
184
185 // remember matrix mode and set to texture mode
186 GLenum current_matrix_mode;
187 glGetIntegerv(GL_MATRIX_MODE, (GLint*)&current_matrix_mode);
188 glMatrixMode(GL_TEXTURE);
189
190 // push a matrix onto the stack that is only used to compute M = transAndScale*mp*mm
191 glPushMatrix();
192 glLoadMatrixd(transAndScale);
193 glMultMatrixd(mp);
194 glMultMatrixd(mm);
195
196 // read M into the variable mm
197 glGetDoublev(GL_TEXTURE_MATRIX, mm);
198 glPopMatrix();
199
200 // ensure that now texture matrix is used
201 glLoadIdentity();
202
203 // restore matrix mode
204 glMatrixMode(current_matrix_mode);
205
206 // get the rows of m which are used to compute (s',t',r',q')
207 GLdouble rowForS[] = {mm[0], mm[4], mm[8], mm[12]};
208 GLdouble rowForT[] = {
209 _invert_t ? (mm[3] -mm[1]) : mm[1],
210 _invert_t ? (mm[7] -mm[5]) : mm[5],
211 _invert_t ? (mm[11]-mm[9]) : mm[9],
212 _invert_t ? (mm[15]-mm[13]) : mm[13] };
213 // subtract depth bias in the r-component to implement the depth-epsilon
214 GLdouble rowForR[] = {
215 front_to_back?(mm[2]-mm[3]*depth_bias):(mm[2]+mm[3]*depth_bias),
216 front_to_back?(mm[6]-mm[7]*depth_bias):(mm[6]+mm[7]*depth_bias),
217 front_to_back?(mm[10]-mm[11]*depth_bias):(mm[10]+mm[11]*depth_bias),
218 front_to_back?(mm[14]-mm[15]*depth_bias):(mm[14]+mm[15]*depth_bias)
219 };
220 GLdouble rowForQ[] = {mm[3], mm[7], mm[11], mm[15]};
221
222 // use automatic texture generation of OpenGL
223 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
224 glTexGendv(GL_S, GL_EYE_PLANE, rowForS);
225 glEnable(GL_TEXTURE_GEN_S);
226
227 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
228 glTexGendv(GL_T, GL_EYE_PLANE, rowForT);
229 glEnable(GL_TEXTURE_GEN_T);
230
231 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
232 glTexGendv(GL_R, GL_EYE_PLANE, rowForR);
233 glEnable(GL_TEXTURE_GEN_R);
234
235 glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
236 glTexGendv(GL_Q, GL_EYE_PLANE, rowForQ);
237 glEnable(GL_TEXTURE_GEN_Q);
238
239 if (tex_unit >= 0)
240 glActiveTextureARB(GL_TEXTURE0_ARB);
241
242 // create occlusion query, that counts the number of rendered fragments
243 glGenQueriesARB(1, &query);
244 glBeginQueryARB(GL_SAMPLES_PASSED_ARB, query);
245
246 // enable alpha test, where the alpha results from the depth comparison and discards fragments of previous layers
247 glEnable(GL_ALPHA_TEST);
248 glAlphaFunc(GL_GREATER, 0.01f);
249}
250
253{
254 glEndQueryARB(GL_SAMPLES_PASSED_ARB);
255 depth_texture.disable(ctx);
256 glPopAttrib();
257 glPopAttrib();
258 // evaluation of occlusion query
259 GLuint nr_drawn_fragments;
260 glGetQueryObjectuivARB(query,GL_QUERY_RESULT_ARB,&nr_drawn_fragments);
261 glDeleteQueriesARB(1,&query);
262 query = -1;
263 return (unsigned int) nr_drawn_fragments;
264}
265
266 }
267 }
268}
void set_height(size_t _height)
set the resolution in the second dimension, add dimensions if necessary
void set_width(size_t _width)
set the resolution in the first dimension, add dimensions if necessary
size_t get_width() const
return the resolution in the first dimension, or 1 if not defined
size_t get_height() const
return the resolution in the second dimension, or 1 if not defined
base class for all drawables, which is independent of the used rendering API.
Definition context.h:621
void copy_depth_buffer(context &ctx)
copies the current depth buffer to the second depth buffer, what is typically done before peeling a l...
bool is_front_to_back() const
return whether the mode is front to back
bool is_initialized() const
check whether the depth peeler has been initialized, i.e. the init method has been called successfull...
void begin_layer(context &ctx, int tex_unit=-1)
start to extract the next layer. Within begin_layer and end_layer the following OpenGL features are u...
virtual bool init(context &ctx)
checks for extensions and init depth peeler, return success
unsigned int end_layer(context &ctx)
finish the layer and return the number of drawn fragments in the layer. All OpenGL settings are resto...
std::string last_error
a string that contains the last error, which is only set by the init method
virtual ~gl_depth_peeler()
destruct the depth peeler
gl_depth_peeler(bool front_to_back=true, float _depth_bias=0.001)
construct uninitialized depth peeler
void set_front_to_back()
enable front to back mode
void set_depth_bias(float bias)
the depth bias is used as epsilon for the test against the second depth buffer and is initialized to ...
virtual void destruct(context &ctx)
destruct the depth peeler
float get_depth_bias() const
return the current depth bias
void invert_t(bool enable=true)
set the sign for the vertical texture coordinate. In case of some ATI-cards this needs to be enabled ...
void set_back_to_front()
enable back to front mode
virtual void init_frame(context &ctx)
call this after the viewport has been set and before the first call to copy_depth_buffer or begin_lay...
virtual bool is_created() const
return whether component has been created
Definition context.cxx:2046
bool create(const context &ctx, TextureType _tt=TT_UNDEF, unsigned width=-1, unsigned height=-1, unsigned depth=-1)
create the texture of dimension and resolution specified in the data format base class.
Definition texture.cxx:208
void set_compare_function(CompareFunction compare_function)
set the texture compare function
Definition texture.cxx:172
bool replace_from_buffer(const context &ctx, int x, int y, int x_buffer, int y_buffer, int width, int height, int level=-1)
replace a block within a 2d texture from the current read buffer.
Definition texture.cxx:667
bool disable(const context &ctx)
disable texture and restore state from before last enable call
Definition texture.cxx:756
bool enable(const context &ctx, int tex_unit=-1)
enable this texture in the given texture unit, -1 corresponds to the current unit.
Definition texture.cxx:745
bool destruct(const context &ctx)
destruct the texture and free texture memory and handle
Definition texture.cxx:730
void set_compare_mode(bool use_compare_function)
set the texture compare mode and function
Definition texture.cxx:160
bool ensure_glew_initialized()
initialize glew in the first call to this function and always return whether this was successful
Definition gl.cxx:19
the cgv namespace
Definition print.h:11