[go: up one dir, main page]

File: occlusion-test.diff

package info (click to toggle)
coin3 3.1.3-1
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 48,344 kB
  • ctags: 70,042
  • sloc: cpp: 314,328; ansic: 15,927; sh: 13,635; makefile: 8,780; perl: 2,149; lex: 1,302; lisp: 1,247; yacc: 184; xml: 175; sed: 68
file content (206 lines) | stat: -rw-r--r-- 6,886 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
Implementation of GL_HP_occlusion_test testing in SoSeparator's
culling test during GL render traversals.

Changes:
 - Caching of occlusion_test availability in cc_glglue since it's
   queried for each SoSeparator in the scene for each frame.
 - Made space for, and set up, occlusion_query availability flag.

Remaining issues:
 - testing
 - usefulness-consideration
 - figure out a heuristic for when *not* to use this technique
   (since the GL-pipe stalls may cause more delay than they gain)

20031124 larsa

Index: include/Inventor/C/glue/gl.h
===================================================================
RCS file: /export/cvsroot/Coin/include/Inventor/C/glue/gl.h,v
retrieving revision 1.21
diff -u -b -r1.21 gl.h
--- include/Inventor/C/glue/gl.h	18 Nov 2003 17:21:16 -0000	1.21
+++ include/Inventor/C/glue/gl.h	24 Nov 2003 17:56:37 -0000
@@ -414,6 +414,8 @@
 /* GL feature queries */
 COIN_DLL_API SbBool cc_glglue_can_do_bumpmapping(const cc_glglue * glue);
 
+COIN_DLL_API SbBool cc_glglue_has_occlusion_test(const cc_glglue * glue);
+
 /* ********************************************************************** */
 
 /* GLX extensions ***/
Index: include/Inventor/C/glue/glp.h
===================================================================
RCS file: /export/cvsroot/Coin/include/Inventor/C/glue/glp.h,v
retrieving revision 1.26
diff -u -b -r1.26 glp.h
--- include/Inventor/C/glue/glp.h	18 Nov 2003 17:21:16 -0000	1.26
+++ include/Inventor/C/glue/glp.h	24 Nov 2003 17:56:37 -0000
@@ -380,6 +380,8 @@
   GLuint normalizationcubemap;
 
   SbBool can_do_bumpmapping;
+  SbBool can_do_occlusion_test;
+  SbBool can_do_occlusion_query;
 };
 
 /* Exported internally to gl_glx.c and gl_wgl.c. */
Index: include/Inventor/system/gl.h.in
===================================================================
RCS file: /export/cvsroot/Coin/include/Inventor/system/gl.h.in,v
retrieving revision 1.21
diff -u -b -r1.21 gl.h.in
--- include/Inventor/system/gl.h.in	24 Nov 2003 16:08:09 -0000	1.21
+++ include/Inventor/system/gl.h.in	24 Nov 2003 17:56:37 -0000
@@ -510,6 +510,15 @@
 #define GL_DOT3_RGBA                      0x86AF
 #endif /* !GL_DOT3_RGBA */
 
+/* HP occlusion test extension */
+#ifndef GL_OCCLUSION_TEST_HP
+#define GL_OCCLUSION_TEST_HP              0x8165
+#endif /* !GL_OCCLUSION_TEST_HP */
+
+#ifndef GL_OCCLUSION_TEST_RESULT_HP
+#define GL_OCCLUSION_TEST_RESULT_HP       0x8166
+#endif /* !GL_OCCLUSION_TEST_RESULT_HP */
+
 /* SGIS_generate_mipmap */
 #ifndef GL_GENERATE_MIPMAP_SGIS
 #define GL_GENERATE_MIPMAP_SGIS           0x8191
Index: src/glue/gl.c
===================================================================
RCS file: /export/cvsroot/Coin/src/glue/gl.c,v
retrieving revision 1.73
diff -u -b -r1.73 gl.c
--- src/glue/gl.c	18 Nov 2003 17:24:10 -0000	1.73
+++ src/glue/gl.c	24 Nov 2003 17:56:38 -0000
@@ -1081,6 +1081,9 @@
         cc_glglue_glext_supported(w, "ARB_texture_env_dot3")))) {
     w->can_do_bumpmapping = TRUE;
   }
+
+  w->can_do_occlusion_test = cc_glglue_glext_supported(w, "GL_HP_occlusion_test");
+  w->can_do_occlusion_query = cc_glglue_glext_supported(w, "GL_ARB_occlusion_query");
 }
 
 #undef PROC
@@ -2390,6 +2393,12 @@
   return glue->can_do_bumpmapping;
 }
 
+
+SbBool
+cc_glglue_has_occlusion_test(const cc_glglue * w)
+{
+  return w->can_do_occlusion_test;
+}
 
 /*!
   Returns current X11 display the OpenGL context is in. If none, or if
Index: src/nodes/SoSeparator.cpp
===================================================================
RCS file: /export/cvsroot/Coin/src/nodes/SoSeparator.cpp,v
retrieving revision 1.93
diff -u -b -r1.93 SoSeparator.cpp
--- src/nodes/SoSeparator.cpp	4 Apr 2003 13:38:37 -0000	1.93
+++ src/nodes/SoSeparator.cpp	24 Nov 2003 17:56:38 -0000
@@ -52,11 +52,14 @@
 #include <Inventor/elements/SoCullElement.h>
 #include <Inventor/elements/SoLocalBBoxMatrixElement.h>
 #include <Inventor/elements/SoSoundElement.h>
+#include <Inventor/elements/SoGLCacheContextElement.h>
 #include <Inventor/misc/SoChildList.h>
 #include <Inventor/misc/SoGL.h>
 #include <Inventor/misc/SoState.h>
 #include <Inventor/nodes/SoSubNodeP.h>
 #include <Inventor/errors/SoDebugError.h>
+#include <Inventor/system/gl.h>
+#include <Inventor/C/glue/gl.h>
 
 #include <Inventor/C/tidbits.h> // coin_getenv()
 #include <stdlib.h> // strtol(), rand()
@@ -299,6 +302,8 @@
   SoGLCacheList * glcachelist;
 #endif // !COIN_THREADSAFE
 
+  SbBool occlusion_test(SoState * state, const SbBox3f & bbox);
+
   enum { YES, NO, MAYBE } hassoundchild;
 
 public:
@@ -923,6 +928,9 @@
     if (!bbox.isEmpty()) {
       outside = SoCullElement::cullBox(state, bbox);
     }
+    if ( !outside ) {
+      outside = PRIVATE(this)->occlusion_test(state, bbox);
+    }
   }
   return outside;
 }
@@ -945,8 +953,63 @@
     if (!bbox.isEmpty()) {
       outside = SoCullElement::cullTest(state, bbox);
     }
+    if ( !outside ) {
+      outside = PRIVATE(this)->occlusion_test(state, bbox);
+    }
   }
   return outside;
+}
+
+SbBool
+SoSeparatorP::occlusion_test(SoState * state, const SbBox3f & bbox)
+{
+  if ( !(state->getAction()->isOfType(SoGLRenderAction::getClassTypeId())) ) {
+    return FALSE;
+  }
+  const cc_glglue * gl = cc_glglue_instance(SoGLCacheContextElement::get(state));
+  if ( !cc_glglue_has_occlusion_test(gl) ) { return FALSE; }
+
+  const SbVec3f & bmin = bbox.getMin();
+  const SbVec3f & bmax = bbox.getMax();
+  // push state
+  glPushAttrib(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ENABLE_BIT);
+  // disable backface culling
+  glDisable(GL_CULL_FACE);
+  // disable updates to color and depth buffer
+  glDepthMask(GL_FALSE);
+  glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
+  // enable occlusion test
+  glEnable(GL_OCCLUSION_TEST_HP);
+  // render bounding box geometry
+  glBegin(GL_TRIANGLE_FAN);
+  glVertex3f(bmin[0], bmin[1], bmin[2]); // center
+  glVertex3f(bmax[0], bmin[1], bmin[2]); // start
+  glVertex3f(bmax[0], bmax[1], bmin[2]);
+  glVertex3f(bmin[0], bmax[1], bmin[2]);
+  glVertex3f(bmin[0], bmax[1], bmax[2]);
+  glVertex3f(bmin[0], bmin[1], bmax[2]);
+  glVertex3f(bmax[0], bmin[1], bmax[2]);
+  glVertex3f(bmax[0], bmin[1], bmin[2]); // finish = start
+  glEnd();
+  // and the other side
+  glBegin(GL_TRIANGLE_FAN);
+  glVertex3f(bmax[0], bmax[1], bmax[2]); // center
+  glVertex3f(bmin[0], bmax[1], bmax[2]); // start
+  glVertex3f(bmin[0], bmin[1], bmax[2]);
+  glVertex3f(bmax[0], bmin[1], bmax[2]);
+  glVertex3f(bmax[0], bmin[1], bmin[2]);
+  glVertex3f(bmax[0], bmax[1], bmin[2]);
+  glVertex3f(bmin[0], bmax[1], bmin[2]);
+  glVertex3f(bmin[0], bmax[1], bmax[2]); // finish = start
+  glEnd();
+  // disable occlusion test
+  glDisable(GL_OCCLUSION_TEST_HP);
+  // restore state
+  glPopAttrib();
+  // read occlusion test result
+  GLboolean result;
+  glGetBooleanv(GL_OCCLUSION_TEST_RESULT_HP, &result);
+  return result ? FALSE : TRUE;
 }
 
 #undef PRIVATE