Statistics
| Revision:

root / PyOpenGL-Demo / NeHe / lesson44 / glCamera.py @ 1

History | View | Annotate | Download (32.1 kB)

1 1 equemene
# // Code writen by: Vic Hollis 09/07/2003
2 1 equemene
# // I don't mind if you use this class in your own code. All I ask is
3 1 equemene
# // that you give me credit for it if you do.  And plug NeHe while your
4 1 equemene
# // at it! :P  Thanks go to David Steere, Cameron Tidwell, Bert Sammons,
5 1 equemene
# // and Brannon Martindale for helping me test all the code!  Enjoy.
6 1 equemene
# //////////////////////////////////////////////////////////////////////
7 1 equemene
# // glCamera.h: interface for the glCamera class.
8 1 equemene
# //////////////////////////////////////////////////////////////////////
9 1 equemene
#
10 1 equemene
# //////////////////////////////////////////////////////////////////////
11 1 equemene
# // Some minimal additions by rIO.Spinning Kids
12 1 equemene
# // For testing flares against occluding objects.
13 1 equemene
# // Not using proprietary extensions, this is PURE OpenGL1.1
14 1 equemene
# //
15 1 equemene
# // Just call the IsOccluded function, passing it the glPoint to check
16 1 equemene
# //
17 1 equemene
# //////////////////////////////////////////////////////////////////////
18 1 equemene
#
19 1 equemene
# Ported to Python, PyOpenGL by Brian Leair 2004.
20 1 equemene
# The numarray python module can perform matrix math more effieciently
21 1 equemene
# than direct python code. However, for this tutorial the differnce
22 1 equemene
# in performance isn't huge and it makes for a better tutorial to see
23 1 equemene
# the math operations directly.
24 1 equemene
25 1 equemene
from OpenGL.GL import *
26 1 equemene
from OpenGL.GLU import *
27 1 equemene
from OpenGL.GLUT import *
28 1 equemene
from glPoint import *
29 1 equemene
from glVector import *
30 1 equemene
from math import sqrt, fabs
31 1 equemene
32 1 equemene
try:
33 1 equemene
        import numpy as Numeric
34 1 equemene
except ImportError, err:
35 1 equemene
        try:
36 1 equemene
                import Numeric
37 1 equemene
        except ImportError, err:
38 1 equemene
                print "This demo requires the numpy or Numeric extension, sorry"
39 1 equemene
                import sys
40 1 equemene
                sys.exit()
41 1 equemene
import copy
42 1 equemene
43 1 equemene
class glCamera:
44 1 equemene
        # //////////// CONSTRUCTORS /////////////////////////////////////////
45 1 equemene
        def __init__ (self):
46 1 equemene
                # // Initalize all our member varibles.
47 1 equemene
                self.m_MaxPitchRate                        = 0.0;
48 1 equemene
                self.m_MaxHeadingRate                = 0.0;
49 1 equemene
                self.m_HeadingDegrees                = 0.0;
50 1 equemene
                self.m_PitchDegrees                        = 0.0;
51 1 equemene
                self.m_MaxForwardVelocity        = 0.0;
52 1 equemene
                self.m_ForwardVelocity                = 0.0;
53 1 equemene
                self.m_GlowTexture          = None;
54 1 equemene
                # bleair: NOTE that glCamera.cpp has a bug. m_BigGlowTexture isn't initialized.
55 1 equemene
                # Very minor bug because only in the case where we fail to get an earlier
56 1 equemene
                # texture will the class potentially read from the uninited memory. Most of
57 1 equemene
                # the time the field is assigned to straight away in InitGL ().
58 1 equemene
                self.m_BigGlowTexture       = None;
59 1 equemene
                self.m_HaloTexture                        = None;
60 1 equemene
                self.m_StreakTexture                = None;
61 1 equemene
                self.m_MaxPointSize                        = 0.0;
62 1 equemene
                self.m_Frustum = Numeric.zeros ( (6,4), 'f')
63 1 equemene
64 1 equemene
                self.m_LightSourcePos                 = glPoint ()
65 1 equemene
                self.m_Position = glPoint ()
66 1 equemene
                self.m_DirectionVector = glVector ()
67 1 equemene
                self.m_ptIntersect = glPoint ()
68 1 equemene
69 1 equemene
70 1 equemene
71 1 equemene
72 1 equemene
        def __del__ (self):
73 1 equemene
                self.release ()
74 1 equemene
                return
75 1 equemene
76 1 equemene
        def release (self):
77 1 equemene
                if (self.m_GlowTexture != None):
78 1 equemene
                        glDeleteTextures (self.m_GlowTexture)
79 1 equemene
                if (self.m_HaloTexture != None):
80 1 equemene
                        glDeleteTextures (self.m_HaloTexture)
81 1 equemene
                if (self.m_BigGlowTexture != None):
82 1 equemene
                        glDeleteTextures (self.m_BigGlowTexture)
83 1 equemene
                if (self.m_StreakTexture != None):
84 1 equemene
                        glDeleteTextures (self.m_StreakTexture)
85 1 equemene
                return
86 1 equemene
87 1 equemene
        def ChangePitch (self, degrees):
88 1 equemene
                if (fabs (degrees) < fabs (self.m_MaxPitchRate)):
89 1 equemene
                        # // Our pitch is less than the max pitch rate that we
90 1 equemene
                        # // defined so lets increment it.
91 1 equemene
                        self.m_PitchDegrees += degrees;
92 1 equemene
                else:
93 1 equemene
                        # // Our pitch is greater than the max pitch rate that
94 1 equemene
                        # // we defined so we can only increment our pitch by the
95 1 equemene
                        # // maximum allowed value.
96 1 equemene
                        if(degrees < 0):
97 1 equemene
                                # // We are pitching down so decrement
98 1 equemene
                                self.m_PitchDegrees -= self.m_MaxPitchRate;
99 1 equemene
                        else:
100 1 equemene
                                # // We are pitching up so increment
101 1 equemene
                                self.m_PitchDegrees += self.m_MaxPitchRate;
102 1 equemene
103 1 equemene
                # // We don't want our pitch to run away from us. Although it
104 1 equemene
                # // really doesn't matter I prefer to have my pitch degrees
105 1 equemene
                # // within the range of -360.0f to 360.0f
106 1 equemene
                if (self.m_PitchDegrees > 360.0):
107 1 equemene
                        self.m_PitchDegrees -= 360.0;
108 1 equemene
                elif (self.m_PitchDegrees < -360.0):
109 1 equemene
                        self.m_PitchDegrees += 360.0;
110 1 equemene
111 1 equemene
                return
112 1 equemene
113 1 equemene
        def ChangeHeading (self, degrees):
114 1 equemene
                if(fabs(degrees) < fabs(self.m_MaxHeadingRate)):
115 1 equemene
                        # // Our Heading is less than the max heading rate that we
116 1 equemene
                        # // defined so lets increment it but first we must check
117 1 equemene
                        # // to see if we are inverted so that our heading will not
118 1 equemene
                        # // become inverted.
119 1 equemene
                        if (self.m_PitchDegrees > 90 and self.m_PitchDegrees < 270 or
120 1 equemene
                                (self.m_PitchDegrees < -90 and self.m_PitchDegrees > -270)):
121 1 equemene
                                self.m_HeadingDegrees -= degrees;
122 1 equemene
                        else:
123 1 equemene
                                self.m_HeadingDegrees += degrees;
124 1 equemene
                else:
125 1 equemene
                        # // Our heading is greater than the max heading rate that
126 1 equemene
                        # // we defined so we can only increment our heading by the
127 1 equemene
                        # // maximum allowed value.
128 1 equemene
                        if(degrees < 0):
129 1 equemene
                                # // Check to see if we are upside down.
130 1 equemene
                                if ((self.m_PitchDegrees > 90 and self.m_PitchDegrees < 270) or
131 1 equemene
                                        (self.m_PitchDegrees < -90 and self.m_PitchDegrees > -270)):
132 1 equemene
                                        # // Ok we would normally decrement here but since we are upside
133 1 equemene
                                        # // down then we need to increment our heading
134 1 equemene
                                        self.m_HeadingDegrees += self.m_MaxHeadingRate;
135 1 equemene
                                else:
136 1 equemene
                                        # // We are not upside down so decrement as usual
137 1 equemene
                                        self.m_HeadingDegrees -= self.m_MaxHeadingRate;
138 1 equemene
                        else:
139 1 equemene
                                # // Check to see if we are upside down.
140 1 equemene
                                if (self.m_PitchDegrees > 90 and self.m_PitchDegrees < 270 or
141 1 equemene
                                        (self.m_PitchDegrees < -90 and self.m_PitchDegrees > -270)):
142 1 equemene
                                        # // Ok we would normally increment here but since we are upside
143 1 equemene
                                        # // down then we need to decrement our heading.
144 1 equemene
                                        self.m_HeadingDegrees -= self.m_MaxHeadingRate;
145 1 equemene
                                else:
146 1 equemene
                                        # // We are not upside down so increment as usual.
147 1 equemene
                                        self.m_HeadingDegrees += self.m_MaxHeadingRate;
148 1 equemene
149 1 equemene
                # // We don't want our heading to run away from us either. Although it
150 1 equemene
                # // really doesn't matter I prefer to have my heading degrees
151 1 equemene
                # // within the range of -360.0f to 360.0f
152 1 equemene
                if(self.m_HeadingDegrees > 360.0):
153 1 equemene
                        self.m_HeadingDegrees -= 360.0;
154 1 equemene
                elif(self.m_HeadingDegrees < -360.0):
155 1 equemene
                        self.m_HeadingDegrees += 360.0;
156 1 equemene
157 1 equemene
                return
158 1 equemene
159 1 equemene
        # //////////// FUNCTIONS TO CHANGE CAMERA ORIENTATION AND SPEED /////
160 1 equemene
        def ChangeVelocity(self, vel):
161 1 equemene
                if(fabs(vel) < fabs(self.m_MaxForwardVelocity)):
162 1 equemene
                        # // Our velocity is less than the max velocity increment that we
163 1 equemene
                        # // defined so lets increment it.
164 1 equemene
                        self.m_ForwardVelocity += vel;
165 1 equemene
                else:
166 1 equemene
                        # // Our velocity is greater than the max velocity increment that
167 1 equemene
                        # // we defined so we can only increment our velocity by the
168 1 equemene
                        # // maximum allowed value.
169 1 equemene
                        if(vel < 0):
170 1 equemene
                                # // We are slowing down so decrement
171 1 equemene
                                self.m_ForwardVelocity -= -self.m_MaxForwardVelocity;
172 1 equemene
                        else:
173 1 equemene
                                # // We are speeding up so increment
174 1 equemene
                                self.m_ForwardVelocity += self.m_MaxForwardVelocity;
175 1 equemene
176 1 equemene
                return
177 1 equemene
178 1 equemene
        def UpdateFrustum(self):
179 1 equemene
                """ // I found this code here: http://www.markmorley.com/opengl/frustumculling.html
180 1 equemene
                // and decided to make it part of
181 1 equemene
                // the camera class just in case I might want to rotate
182 1 equemene
                // and translate the projection matrix. This code will
183 1 equemene
                // make sure that the Frustum is updated correctly but
184 1 equemene
                // this member is computational expensive with:
185 1 equemene
                // 82 muliplications, 72 additions, 24 divisions, and
186 1 equemene
                // 12 subtractions for a total of 190 operations. Ouch! """
187 1 equemene
188 1 equemene
                # /* Get the current PROJECTION matrix from OpenGL */
189 1 equemene
                proj = glGetFloatv( GL_PROJECTION_MATRIX);
190 1 equemene
191 1 equemene
                # /* Get the current MODELVIEW matrix from OpenGL */
192 1 equemene
                modl = glGetFloatv( GL_MODELVIEW_MATRIX);
193 1 equemene
194 1 equemene
                # /* Combine the two matrices (multiply projection by modelview) */
195 1 equemene
                # Careful, Note, that replication is simple scalars is OK, but replicate of objects
196 1 equemene
                # and lists is very bad.
197 1 equemene
                clip = [None,] * 16
198 1 equemene
                # clip = Numeric.zeros ( (16), 'f')
199 1 equemene
                clip[ 0] = modl[ 0] * proj[ 0] + modl[ 1] * proj[ 4] + modl[ 2] * proj[ 8] + modl[ 3] * proj[12];
200 1 equemene
                clip[ 1] = modl[ 0] * proj[ 1] + modl[ 1] * proj[ 5] + modl[ 2] * proj[ 9] + modl[ 3] * proj[13];
201 1 equemene
                clip[ 2] = modl[ 0] * proj[ 2] + modl[ 1] * proj[ 6] + modl[ 2] * proj[10] + modl[ 3] * proj[14];
202 1 equemene
                clip[ 3] = modl[ 0] * proj[ 3] + modl[ 1] * proj[ 7] + modl[ 2] * proj[11] + modl[ 3] * proj[15];
203 1 equemene
204 1 equemene
                clip[ 4] = modl[ 4] * proj[ 0] + modl[ 5] * proj[ 4] + modl[ 6] * proj[ 8] + modl[ 7] * proj[12];
205 1 equemene
                clip[ 5] = modl[ 4] * proj[ 1] + modl[ 5] * proj[ 5] + modl[ 6] * proj[ 9] + modl[ 7] * proj[13];
206 1 equemene
                clip[ 6] = modl[ 4] * proj[ 2] + modl[ 5] * proj[ 6] + modl[ 6] * proj[10] + modl[ 7] * proj[14];
207 1 equemene
                clip[ 7] = modl[ 4] * proj[ 3] + modl[ 5] * proj[ 7] + modl[ 6] * proj[11] + modl[ 7] * proj[15];
208 1 equemene
209 1 equemene
                clip[ 8] = modl[ 8] * proj[ 0] + modl[ 9] * proj[ 4] + modl[10] * proj[ 8] + modl[11] * proj[12];
210 1 equemene
                clip[ 9] = modl[ 8] * proj[ 1] + modl[ 9] * proj[ 5] + modl[10] * proj[ 9] + modl[11] * proj[13];
211 1 equemene
                clip[10] = modl[ 8] * proj[ 2] + modl[ 9] * proj[ 6] + modl[10] * proj[10] + modl[11] * proj[14];
212 1 equemene
                clip[11] = modl[ 8] * proj[ 3] + modl[ 9] * proj[ 7] + modl[10] * proj[11] + modl[11] * proj[15];
213 1 equemene
214 1 equemene
                clip[12] = modl[12] * proj[ 0] + modl[13] * proj[ 4] + modl[14] * proj[ 8] + modl[15] * proj[12];
215 1 equemene
                clip[13] = modl[12] * proj[ 1] + modl[13] * proj[ 5] + modl[14] * proj[ 9] + modl[15] * proj[13];
216 1 equemene
                clip[14] = modl[12] * proj[ 2] + modl[13] * proj[ 6] + modl[14] * proj[10] + modl[15] * proj[14];
217 1 equemene
                clip[15] = modl[12] * proj[ 3] + modl[13] * proj[ 7] + modl[14] * proj[11] + modl[15] * proj[15];
218 1 equemene
219 1 equemene
                # ### Use a shortened name to reference to our camera's Frustum (does
220 1 equemene
                # ### not copy anything, just a ref to make code less wordy
221 1 equemene
                Frustum = self.m_Frustum
222 1 equemene
223 1 equemene
                # /* Extract the numbers for the RIGHT plane */
224 1 equemene
                Frustum[0][0] = clip[ 3] - clip[ 0];
225 1 equemene
                Frustum[0][1] = clip[ 7] - clip[ 4];
226 1 equemene
                Frustum[0][2] = clip[11] - clip[ 8];
227 1 equemene
                Frustum[0][3] = clip[15] - clip[12];
228 1 equemene
229 1 equemene
            # /* Normalize the result */
230 1 equemene
                t = (sqrt( Frustum[0][0] * Frustum[0][0] + \
231 1 equemene
                Frustum[0][1] * Frustum[0][1] + Frustum[0][2] * Frustum[0][2] ));
232 1 equemene
                Frustum[0][0] /= t;
233 1 equemene
                Frustum[0][1] /= t;
234 1 equemene
                Frustum[0][2] /= t;
235 1 equemene
                Frustum[0][3] /= t;
236 1 equemene
237 1 equemene
                # /* Extract the numbers for the LEFT plane */
238 1 equemene
                Frustum[1][0] = clip[ 3] + clip[ 0];
239 1 equemene
                Frustum[1][1] = clip[ 7] + clip[ 4];
240 1 equemene
                Frustum[1][2] = clip[11] + clip[ 8];
241 1 equemene
                Frustum[1][3] = clip[15] + clip[12];
242 1 equemene
243 1 equemene
                # /* Normalize the result */
244 1 equemene
                t = sqrt( Frustum[1][0] * Frustum[1][0] + Frustum[1][1] * Frustum[1][1] + Frustum[1][2] * Frustum[1][2] );
245 1 equemene
                Frustum[1][0] /= t;
246 1 equemene
                Frustum[1][1] /= t;
247 1 equemene
                Frustum[1][2] /= t;
248 1 equemene
                Frustum[1][3] /= t;
249 1 equemene
250 1 equemene
                # /* Extract the BOTTOM plane */
251 1 equemene
                Frustum[2][0] = clip[ 3] + clip[ 1];
252 1 equemene
                Frustum[2][1] = clip[ 7] + clip[ 5];
253 1 equemene
                Frustum[2][2] = clip[11] + clip[ 9];
254 1 equemene
                Frustum[2][3] = clip[15] + clip[13];
255 1 equemene
256 1 equemene
                # /* Normalize the result */
257 1 equemene
                t = sqrt( Frustum[2][0] * Frustum[2][0] + Frustum[2][1] * Frustum[2][1] + Frustum[2][2] * Frustum[2][2] );
258 1 equemene
                Frustum[2][0] /= t;
259 1 equemene
                Frustum[2][1] /= t;
260 1 equemene
                Frustum[2][2] /= t;
261 1 equemene
                Frustum[2][3] /= t;
262 1 equemene
263 1 equemene
                # /* Extract the TOP plane */
264 1 equemene
                Frustum[3][0] = clip[ 3] - clip[ 1];
265 1 equemene
                Frustum[3][1] = clip[ 7] - clip[ 5];
266 1 equemene
                Frustum[3][2] = clip[11] - clip[ 9];
267 1 equemene
                Frustum[3][3] = clip[15] - clip[13];
268 1 equemene
269 1 equemene
            # /* Normalize the result */
270 1 equemene
                t = sqrt( Frustum[3][0] * Frustum[3][0] + Frustum[3][1] * Frustum[3][1] + Frustum[3][2] * Frustum[3][2] )
271 1 equemene
                Frustum[3][0] /= t;
272 1 equemene
                Frustum[3][1] /= t;
273 1 equemene
                Frustum[3][2] /= t;
274 1 equemene
                Frustum[3][3] /= t;
275 1 equemene
276 1 equemene
                 # /* Extract the FAR plane */
277 1 equemene
                 Frustum[4][0] = clip[ 3] - clip[ 2];
278 1 equemene
                 Frustum[4][1] = clip[ 7] - clip[ 6];
279 1 equemene
                 Frustum[4][2] = clip[11] - clip[10];
280 1 equemene
                Frustum[4][3] = clip[15] - clip[14];
281 1 equemene
282 1 equemene
                # /* Normalize the result */
283 1 equemene
                 t = sqrt( Frustum[4][0] * Frustum[4][0] + Frustum[4][1] * Frustum[4][1] + Frustum[4][2] * Frustum[4][2] )
284 1 equemene
                 Frustum[4][0] /= t;
285 1 equemene
                 Frustum[4][1] /= t;
286 1 equemene
                 Frustum[4][2] /= t;
287 1 equemene
                 Frustum[4][3] /= t;
288 1 equemene
289 1 equemene
                 # /* Extract the NEAR plane */
290 1 equemene
                 Frustum[5][0] = clip[ 3] + clip[ 2];
291 1 equemene
                 Frustum[5][1] = clip[ 7] + clip[ 6];
292 1 equemene
                 Frustum[5][2] = clip[11] + clip[10];
293 1 equemene
                 Frustum[5][3] = clip[15] + clip[14];
294 1 equemene
295 1 equemene
                 # /* Normalize the result */
296 1 equemene
                 t = sqrt( Frustum[5][0] * Frustum[5][0] + Frustum[5][1] * Frustum[5][1] + Frustum[5][2] * Frustum[5][2] );
297 1 equemene
                 Frustum[5][0] /= t;
298 1 equemene
                 Frustum[5][1] /= t;
299 1 equemene
                 Frustum[5][2] /= t;
300 1 equemene
                 Frustum[5][3] /= t;
301 1 equemene
302 1 equemene
                return
303 1 equemene
304 1 equemene
        # //////////// FUNCTIONS TO UPDATE THE FRUSTUM //////////////////////
305 1 equemene
        def UpdateFrustumFaster (self):
306 1 equemene
                """ // This is the much faster version of the above member
307 1 equemene
                // function, however the speed increase is not gained
308 1 equemene
                // without a cost. If you rotate or translate the projection
309 1 equemene
                // matrix then this member will not work correctly. That is acceptable
310 1 equemene
                // in my book considering I very rarely do such a thing.
311 1 equemene
                // This function has far fewer operations in it and I
312 1 equemene
                // shaved off 2 square root functions by passing in the
313 1 equemene
                // near and far values. This member has:
314 1 equemene
                // 38 muliplications, 28 additions, 24 divisions, and
315 1 equemene
                // 12 subtractions for a total of 102 operations. Still hurts
316 1 equemene
                // but at least it is decent now. In practice this will
317 1 equemene
                // run about 2 times faster than the above function. """
318 1 equemene
319 1 equemene
                # /* Get the current PROJECTION matrix from OpenGL */
320 1 equemene
                proj = glGetFloatv( GL_PROJECTION_MATRIX);
321 1 equemene
322 1 equemene
                # /* Get the current MODELVIEW matrix from OpenGL */
323 1 equemene
                modl = glGetFloatv( GL_MODELVIEW_MATRIX);
324 1 equemene
325 1 equemene
                # /* Combine the two matrices (multiply projection by modelview)
326 1 equemene
                   # but keep in mind this function will only work if you do NOT
327 1 equemene
                   # rotate or translate your projection matrix                  */
328 1 equemene
                clip = [0,] * 16
329 1 equemene
                modl_row1 = modl [0]
330 1 equemene
                clip[ 0] = modl [0] [0] * proj[0][0];
331 1 equemene
                clip[ 1] = modl  [0][ 1] * proj[1][1];
332 1 equemene
                clip[ 2] = modl [0][ 2] * proj[2][2] + modl_row1[ 3] * proj[3][2]
333 1 equemene
                clip[ 3] = modl [0][ 2] * proj[2][3]
334 1 equemene
335 1 equemene
                modl_row2 = modl [1]
336 1 equemene
                clip[ 4] = modl_row2[ 0] * proj[0][0]
337 1 equemene
                clip[ 5] = modl_row2[ 1] * proj[1][1]
338 1 equemene
                clip[ 6] = modl_row2[ 2] * proj[2][2] + modl_row2[ 3] * proj[3][2]
339 1 equemene
                clip[ 7] = modl_row2[ 2] * proj[2][3]
340 1 equemene
341 1 equemene
                modl_row3 = modl [2]
342 1 equemene
                clip[ 8] = modl_row3[ 0] * proj[0][0];
343 1 equemene
                clip[ 9] = modl_row3[ 1] * proj[1][1]
344 1 equemene
                clip[10] = modl_row3[2] * proj[2][2] + modl_row3[3] * proj[3][2]
345 1 equemene
                clip[11] = modl_row3[2] * proj[2][3]
346 1 equemene
347 1 equemene
                modl_row4 = modl [3]
348 1 equemene
                clip[12] = modl_row4[0] * proj[0][0]
349 1 equemene
                clip[13] = modl_row4[1] * proj[1][1]
350 1 equemene
                clip[14] = modl_row4[2] * proj[2][2] + modl_row4[3] * proj[3][2]
351 1 equemene
                clip[15] = modl_row4[2] * proj[2][3]
352 1 equemene
353 1 equemene
                # ### Use a shortened name to reference to our camera's Frustum (does
354 1 equemene
                # ### not copy anything, just a ref to make code less wordy
355 1 equemene
                Frustum = self.m_Frustum
356 1 equemene
357 1 equemene
                # /* Extract the numbers for the RIGHT plane */
358 1 equemene
                Frustum[0][0] = clip[ 3] - clip[ 0];
359 1 equemene
                Frustum[0][1] = clip[ 7] - clip[ 4];
360 1 equemene
                Frustum[0][2] = clip[11] - clip[ 8];
361 1 equemene
                Frustum[0][3] = clip[15] - clip[12];
362 1 equemene
363 1 equemene
                # /* Normalize the result */
364 1 equemene
                t = sqrt( (Frustum[0][0] * Frustum[0][0]) + (Frustum[0][1] * Frustum[0][1]) + (Frustum[0][2] * Frustum[0][2]) );
365 1 equemene
                Frustum[0][0] /= t;
366 1 equemene
                Frustum[0][1] /= t;
367 1 equemene
                Frustum[0][2] /= t;
368 1 equemene
                Frustum[0][3] /= t;
369 1 equemene
370 1 equemene
                 # /* Extract the numbers for the LEFT plane */
371 1 equemene
                 Frustum[1][0] = clip[ 3] + clip[ 0];
372 1 equemene
                 Frustum[1][1] = clip[ 7] + clip[ 4];
373 1 equemene
                 Frustum[1][2] = clip[11] + clip[ 8];
374 1 equemene
                 Frustum[1][3] = clip[15] + clip[12];
375 1 equemene
376 1 equemene
            # /* Normalize the result */
377 1 equemene
                 t = sqrt( Frustum[1][0] * Frustum[1][0] + Frustum[1][1] * Frustum[1][1] + Frustum[1][2] * Frustum[1][2] );
378 1 equemene
                 Frustum[1][0] /= t;
379 1 equemene
                 Frustum[1][1] /= t;
380 1 equemene
                 Frustum[1][2] /= t;
381 1 equemene
                 Frustum[1][3] /= t;
382 1 equemene
383 1 equemene
                # /* Extract the BOTTOM plane */
384 1 equemene
                Frustum[2][0] = clip[ 3] + clip[ 1];
385 1 equemene
                Frustum[2][1] = clip[ 7] + clip[ 5];
386 1 equemene
                Frustum[2][2] = clip[11] + clip[ 9];
387 1 equemene
                Frustum[2][3] = clip[15] + clip[13];
388 1 equemene
389 1 equemene
            # /* Normalize the result */
390 1 equemene
                t = sqrt( Frustum[2][0] * Frustum[2][0] + Frustum[2][1] * Frustum[2][1] + Frustum[2][2] * Frustum[2][2] );
391 1 equemene
                Frustum[2][0] /= t;
392 1 equemene
                Frustum[2][1] /= t;
393 1 equemene
                Frustum[2][2] /= t;
394 1 equemene
                Frustum[2][3] /= t;
395 1 equemene
396 1 equemene
            # /* Extract the TOP plane */
397 1 equemene
                 Frustum[3][0] = clip[ 3] - clip[ 1];
398 1 equemene
                 Frustum[3][1] = clip[ 7] - clip[ 5];
399 1 equemene
                 Frustum[3][2] = clip[11] - clip[ 9];
400 1 equemene
                 Frustum[3][3] = clip[15] - clip[13];
401 1 equemene
402 1 equemene
            # /* Normalize the result */
403 1 equemene
                 t = sqrt( Frustum[3][0] * Frustum[3][0] + Frustum[3][1] * Frustum[3][1] + Frustum[3][2] * Frustum[3][2] );
404 1 equemene
                 Frustum[3][0] /= t;
405 1 equemene
                 Frustum[3][1] /= t;
406 1 equemene
                 Frustum[3][2] /= t;
407 1 equemene
                 Frustum[3][3] /= t;
408 1 equemene
409 1 equemene
            # /* Extract the FAR plane */
410 1 equemene
                 Frustum[4][0] = clip[ 3] - clip[ 2];
411 1 equemene
                 Frustum[4][1] = clip[ 7] - clip[ 6];
412 1 equemene
                 Frustum[4][2] = clip[11] - clip[10];
413 1 equemene
                 Frustum[4][3] = clip[15] - clip[14];
414 1 equemene
415 1 equemene
            # /* Normalize the result */
416 1 equemene
                 t = sqrt( (Frustum[4][0] * Frustum[4][0]) + (Frustum[4][1] * Frustum[4][1]) + (Frustum[4][2] * Frustum[4][2]) );
417 1 equemene
                 Frustum[4][0] /= t;
418 1 equemene
                 Frustum[4][1] /= t;
419 1 equemene
                 Frustum[4][2] /= t;
420 1 equemene
                 Frustum[4][3] /= t;
421 1 equemene
422 1 equemene
            # /* Extract the NEAR plane */
423 1 equemene
                 Frustum[5][0] = clip[ 3] + clip[ 2];
424 1 equemene
                 Frustum[5][1] = clip[ 7] + clip[ 6];
425 1 equemene
                 Frustum[5][2] = clip[11] + clip[10];
426 1 equemene
                 Frustum[5][3] = clip[15] + clip[14];
427 1 equemene
428 1 equemene
                 # /* Normalize the result */
429 1 equemene
                 t = sqrt( Frustum[5][0] * Frustum[5][0] + Frustum[5][1] * Frustum[5][1] + Frustum[5][2] * Frustum[5][2] );
430 1 equemene
                 Frustum[5][0] /= t;
431 1 equemene
                 Frustum[5][1] /= t;
432 1 equemene
                 Frustum[5][2] /= t;
433 1 equemene
                 Frustum[5][3] /= t;
434 1 equemene
435 1 equemene
                return
436 1 equemene
437 1 equemene
438 1 equemene
439 1 equemene
        # //////////// FRUSTUM TESTING FUNCTIONS ////////////////////////////
440 1 equemene
        def SphereInFrustum(self, p, Radius):
441 1 equemene
                """ // This member function checks to see if a sphere is in
442 1 equemene
                        // the viewing volume.   """
443 1 equemene
444 1 equemene
                Frustum = self.m_Frustum
445 1 equemene
                # // The idea here is the same as the PointInFrustum function.
446 1 equemene
                if (Radius != 0):
447 1 equemene
                        for i in xrange (6):
448 1 equemene
                        # // If the point is outside of the plane then its not in the viewing volume.
449 1 equemene
                                if(Frustum[i][0] * p.x + Frustum[i][1] * p.y + Frustum[i][2] * p.z + Frustum[i][3] <= -Radius):
450 1 equemene
                                        return(False);
451 1 equemene
                else:
452 1 equemene
                        # // The idea here is the same as the PointInFrustum function.
453 1 equemene
                        for i in xrange (6):
454 1 equemene
                                # // If the point is outside of the plane then its not in the viewing volume.
455 1 equemene
                                if(Frustum[i][0] * p.x + Frustum[i][1] * p.y + Frustum[i][2] * p.z + Frustum[i][3] <= 0):
456 1 equemene
                                        return(False);
457 1 equemene
458 1 equemene
                return(True);
459 1 equemene
460 1 equemene
        def PointInFrustum(self, x,y,z):
461 1 equemene
                """ // This member fuction checks to see if a point is in
462 1 equemene
                        // the viewing volume. """
463 1 equemene
464 1 equemene
                # // The idea behind this algorithum is that if the point
465 1 equemene
                # // is inside all 6 clipping planes then it is inside our
466 1 equemene
                # // viewing volume so we can return true.
467 1 equemene
468 1 equemene
                Frustum = self.m_Frustum
469 1 equemene
                # // Loop through all our clipping planes
470 1 equemene
                for i in xrange (6):
471 1 equemene
                        # // If the point is outside of the plane then its not in the viewing volume.
472 1 equemene
                        if(Frustum[i][0] * x + Frustum[i][1] * y + Frustum[i][2] * z + Frustum[i][3] <= 0):
473 1 equemene
                                return(False);
474 1 equemene
475 1 equemene
                return(True);
476 1 equemene
477 1 equemene
        # /////////// OCCLUSION TESTING FUNCTIONS ///////////////////////////
478 1 equemene
        def IsOccluded (self, p):
479 1 equemene
                # // Now we will ask OGL to project some geometry for us using the gluProject function.
480 1 equemene
                # // Practically we ask OGL to guess where a point in space will be projected in our current viewport,
481 1 equemene
                # // using arbitrary viewport and transform matrices we pass to the function.
482 1 equemene
                # // If we pass to the function the current matrices  (retrievede with the glGet funcs)
483 1 equemene
                # // we will have the real position on screen where the dot will be drawn.
484 1 equemene
                # // The interesting part is that we also get a Z value back, this means that
485 1 equemene
                # // reading the REAL buffer for Z values we can discover if the flare is in front or
486 1 equemene
                # // if it's occluded by some objects.
487 1 equemene
                # ### This function should be a flat function, not a function of the camera as we
488 1 equemene
                # ### use the immediate GL rendering state entirely.
489 1 equemene
490 1 equemene
491 1 equemene
                # ### Viewport is the rectangle of window pixels that OpenGL is rasterizing into.
492 1 equemene
                viewport = glGetIntegerv (GL_VIEWPORT);                                                # //get actual viewport
493 1 equemene
                  mvmatrix = glGetDoublev (GL_MODELVIEW_MATRIX);                                # //get actual model view matrix
494 1 equemene
                  projmatrix = glGetDoublev (GL_PROJECTION_MATRIX);                        # //get actual projiection matrix
495 1 equemene
496 1 equemene
                # // this asks OGL to guess the 2d position of a 3d point inside the viewport
497 1 equemene
                winx, winy, winz = gluProject(p.x, p.y, p.z, mvmatrix, projmatrix, viewport)
498 1 equemene
                flareZ = winz;
499 1 equemene
500 1 equemene
                # // we read back one pixel from th depth buffer (exactly where our flare should be drawn)
501 1 equemene
                glPixelStorei(GL_PACK_ALIGNMENT, 1)
502 1 equemene
503 1 equemene
                # PyOpenGL 2.0.1.07 bug, Only the type clarified function works.
504 1 equemene
                # bufferZ = glReadPixels(int(winx), int(winy),1,1,GL_DEPTH_COMPONENT, GL_FLOAT)
505 1 equemene
                bufferZ = glReadPixelsf(int(winx), int(winy),1,1,GL_DEPTH_COMPONENT)
506 1 equemene
507 1 equemene
                # // if the buffer Z is lower than our flare guessed Z then don't draw
508 1 equemene
                # // this means there is something in front of our flare
509 1 equemene
                if (bufferZ [0] [0] < flareZ):
510 1 equemene
                        return True;
511 1 equemene
                else:
512 1 equemene
                        return False;
513 1 equemene
514 1 equemene
        # //////////// FUNCTIONS TO RENDER LENS FLARES //////////////////////
515 1 equemene
        def RenderLensFlare(self):
516 1 equemene
                # // Draw the flare only If the light source is in our line of sight (inside the Frustum)
517 1 equemene
                if (self.SphereInFrustum(self.m_LightSourcePos, 1.0) == True):
518 1 equemene
519 1 equemene
                        # Vector pointing from the light's position toward the camera's position (the camera might
520 1 equemene
                        # be pointing elsewhere, this vector is pointing from the light to the camera)
521 1 equemene
                        self.vLightSourceToCamera = self.m_Position - self.m_LightSourcePos;                # // Lets compute the vector that points to the camera from
522 1 equemene
                                                                                                                                                                                # // the light source.
523 1 equemene
524 1 equemene
                        Length = self.vLightSourceToCamera.Magnitude ()                                                 # // Save the length we will need it in a minute
525 1 equemene
526 1 equemene
                        # Move down our look-toward direction vector. Move down the look-toward the same dist. as the
527 1 equemene
                        # distance between camera and the light.
528 1 equemene
                        intersect = self.m_DirectionVector * Length
529 1 equemene
                        self.m_ptIntersect = glPoint (intersect.i, intersect.j, intersect.k)
530 1 equemene
                                                                                                                                                # // Now lets find an point along the cameras direction
531 1 equemene
                                                                                                                                                # // vector that we can use as an intersection point.
532 1 equemene
                                                                                                                                                # // Lets translate down this vector the same distance
533 1 equemene
                                                                                                                                                # // that the camera is away from the light source.
534 1 equemene
                        ptIntersect = self.m_ptIntersect
535 1 equemene
                        # Did the motion in the correct direction above, now translate the intersection position
536 1 equemene
                        # relative to our camera location.
537 1 equemene
                        ptIntersect += self.m_Position;
538 1 equemene
539 1 equemene
540 1 equemene
                        self.vLightSourceToIntersect = ptIntersect - self.m_LightSourcePos;                # // Lets compute the vector that points to the Intersect
541 1 equemene
                                                                                                                                        # // point from the light source
542 1 equemene
543 1 equemene
                        Length = self.vLightSourceToIntersect.Magnitude();                # // Save the length we will need it later.
544 1 equemene
                        self.vLightSourceToIntersect.Normalize();                                # // Normalize the vector so its unit length
545 1 equemene
                        vLightSourceToIntersect = self.vLightSourceToIntersect
546 1 equemene
547 1 equemene
                        glEnable(GL_BLEND);                                                                                # // You should already know what this does
548 1 equemene
                        glBlendFunc(GL_SRC_ALPHA, GL_ONE);                                                # // You should already know what this does
549 1 equemene
                        glDisable(GL_DEPTH_TEST);                                                                # // You should already know what this does
550 1 equemene
                        glEnable(GL_TEXTURE_2D);                                                                # // You should already know what this does
551 1 equemene
552 1 equemene
                        # /////////// Differenet Color Glows & Streaks /////////////////////
553 1 equemene
                        # //RenderBigGlow(1.0f, 1.0f, 1.0f, 1.0f, m_LightSourcePos, 1.0f);
554 1 equemene
                        # //RenderStreaks(1.0f, 1.0f, 0.8f, 1.0f, m_LightSourcePos, 0.7f);
555 1 equemene
                        # //
556 1 equemene
                        # //RenderBigGlow(1.0f, 0.9f, 1.0f, 1.0f, m_LightSourcePos, 1.0f);
557 1 equemene
                        # //RenderStreaks(1.0f, 0.9f, 1.0f, 1.0f, m_LightSourcePos, 0.7f);
558 1 equemene
                        # //////////////////////////////////////////////////////////////////
559 1 equemene
560 1 equemene
561 1 equemene
                        # //########################## NEW STUFF ##################################
562 1 equemene
563 1 equemene
                        if (not self.IsOccluded(self.m_LightSourcePos)):                #        //Check if the center of the flare is occluded
564 1 equemene
                                # // Render the large hazy glow
565 1 equemene
                                self.RenderBigGlow(0.60, 0.60, 0.8, 1.0, self.m_LightSourcePos, 16.0);
566 1 equemene
                                # // Render the streaks
567 1 equemene
                                self.RenderStreaks(0.60, 0.60, 0.8, 1.0, self.m_LightSourcePos, 16.0);
568 1 equemene
                                # // Render the small Glow
569 1 equemene
                                self.RenderGlow(0.8, 0.8, 1.0, 0.5, self.m_LightSourcePos, 3.5);
570 1 equemene
571 1 equemene
                                pt = glPoint (vLightSourceToIntersect * (Length * 0.1));        # // Lets compute a point that is 20%
572 1 equemene
                                pt += self.m_LightSourcePos;                                                                # // away from the light source in the
573 1 equemene
                                                                                                                                                        # // direction of the intersection point.
574 1 equemene
575 1 equemene
                                self.RenderGlow(0.9, 0.6, 0.4, 0.5, pt, 0.6);                                        # // Render the small Glow
576 1 equemene
577 1 equemene
                                pt = glPoint (vLightSourceToIntersect * (Length * 0.15));        # // Lets compute a point that is 30%
578 1 equemene
                                pt += self.m_LightSourcePos;                                                                # // away from the light source in the
579 1 equemene
                                                                                                                                                        # // direction of the intersection point.
580 1 equemene
581 1 equemene
                                self.RenderHalo(0.8, 0.5, 0.6, 0.5, pt, 1.7);                                        # // Render the a Halo
582 1 equemene
583 1 equemene
                                pt = glPoint (vLightSourceToIntersect * (Length * 0.175));                        # // Lets compute a point that is 35%
584 1 equemene
                                pt += self.m_LightSourcePos;                                                                # // away from the light source in the
585 1 equemene
                                                                                                                                                        # // direction of the intersection point.
586 1 equemene
587 1 equemene
                                self.RenderHalo(0.9, 0.2, 0.1, 0.5, pt, 0.83);                                        # // Render the a Halo
588 1 equemene
589 1 equemene
                                pt = glPoint (vLightSourceToIntersect * (Length * 0.285));                        # // Lets compute a point that is 57%
590 1 equemene
                                pt += self.m_LightSourcePos;                                                                # // away from the light source in the
591 1 equemene
                                                                                                                                                        # // direction of the intersection point.
592 1 equemene
593 1 equemene
                                self.RenderHalo(0.7, 0.7, 0.4, 0.5, pt, 1.6);                                        # // Render the a Halo
594 1 equemene
595 1 equemene
                                pt = glPoint (vLightSourceToIntersect * (Length * 0.2755));                        # // Lets compute a point that is 55.1%
596 1 equemene
                                pt += self.m_LightSourcePos;                                                                # // away from the light source in the
597 1 equemene
                                                                                                                                                        # // direction of the intersection point.
598 1 equemene
599 1 equemene
                                self.RenderGlow(0.9, 0.9, 0.2, 0.5, pt, 0.8);                                        # // Render the small Glow
600 1 equemene
601 1 equemene
                                pt = glPoint (vLightSourceToIntersect * (Length * 0.4775));                        # // Lets compute a point that is 95.5%
602 1 equemene
                                pt += self.m_LightSourcePos;                                                                # // away from the light source in the
603 1 equemene
                                                                                                                                                        # // direction of the intersection point.
604 1 equemene
605 1 equemene
                                self.RenderGlow(0.93, 0.82, 0.73, 0.5, pt, 1.0);                                        # // Render the small Glow
606 1 equemene
607 1 equemene
                                pt = glPoint (vLightSourceToIntersect * (Length * 0.49));                                # // Lets compute a point that is 98%
608 1 equemene
                                pt += self.m_LightSourcePos;                                                                # // away from the light source in the
609 1 equemene
                                                                                                                                                        # // direction of the intersection point.
610 1 equemene
611 1 equemene
                                self.RenderHalo(0.7, 0.6, 0.5, 0.5, pt, 1.4);                                        # // Render the a Halo
612 1 equemene
613 1 equemene
                                pt = glPoint (vLightSourceToIntersect * (Length * 0.65));                                # // Lets compute a point that is 130%
614 1 equemene
                                pt += self.m_LightSourcePos;                                                                # // away from the light source in the
615 1 equemene
                                                                                                                                                        # // direction of the intersection point.
616 1 equemene
617 1 equemene
                                self.RenderGlow(0.7, 0.8, 0.3, 0.5, pt, 1.8);                                        # // Render the small Glow
618 1 equemene
619 1 equemene
                                pt = glPoint (vLightSourceToIntersect * (Length * 0.63));                                # // Lets compute a point that is 126%
620 1 equemene
                                pt += self.m_LightSourcePos;                                                                # // away from the light source in the
621 1 equemene
                                                                                                                                                        # // direction of the intersection point.
622 1 equemene
623 1 equemene
                                self.RenderGlow(0.4, 0.3, 0.2, 0.5, pt, 1.4);                                        # // Render the small Glow
624 1 equemene
625 1 equemene
                                pt = glPoint (vLightSourceToIntersect * (Length * 0.8));                                # // Lets compute a point that is 160%
626 1 equemene
                                pt += self.m_LightSourcePos;                                                                # // away from the light source in the
627 1 equemene
                                                                                                                                                        # // direction of the intersection point.
628 1 equemene
629 1 equemene
                                self.RenderHalo(0.7, 0.5, 0.5, 0.5, pt, 1.4);                                        # // Render the a Halo
630 1 equemene
631 1 equemene
                                pt = glPoint (vLightSourceToIntersect * (Length * 0.7825));                        # // Lets compute a point that is 156.5%
632 1 equemene
                                pt += self.m_LightSourcePos;                                                                # // away from the light source in the
633 1 equemene
                                                                                                                                                        # // direction of the intersection point.
634 1 equemene
635 1 equemene
                                self.RenderGlow(0.8, 0.5, 0.1, 0.5, pt, 0.6);                                        # // Render the small Glow
636 1 equemene
637 1 equemene
                                pt = glPoint (vLightSourceToIntersect * (Length * 1.0));                                # // Lets compute a point that is 200%
638 1 equemene
                                pt += self.m_LightSourcePos;                                                                # // away from the light source in the
639 1 equemene
                                                                                                                                                        # // direction of the intersection point.
640 1 equemene
641 1 equemene
                                self.RenderHalo(0.5, 0.5, 0.7, 0.5, pt, 1.7);                                        # // Render the a Halo
642 1 equemene
643 1 equemene
                                pt = glPoint (vLightSourceToIntersect * (Length * 0.975));                        # // Lets compute a point that is 195%
644 1 equemene
                                pt += self.m_LightSourcePos;                                                                # // away from the light source in the
645 1 equemene
                                                                                                                                                        # // direction of the intersection point.
646 1 equemene
647 1 equemene
                                self.RenderGlow(0.4, 0.1, 0.9, 0.5, pt, 2.0);                                        # // Render the small Glow
648 1 equemene
649 1 equemene
                        glDisable(GL_BLEND );                                                                                        # // You should already know what this does
650 1 equemene
                        glEnable(GL_DEPTH_TEST);                                                                                # // You should already know what this does
651 1 equemene
                        glDisable(GL_TEXTURE_2D);                                                                                # // You should already know what this does
652 1 equemene
                return
653 1 equemene
654 1 equemene
        def RenderHalo (self, r, g, b, a, p, scale):
655 1 equemene
                self.RenderFlareTexture (self.m_HaloTexture, r, g, b, a, p, scale)
656 1 equemene
                return
657 1 equemene
658 1 equemene
        def RenderGlow (self, r, g, b, a, p, scale):
659 1 equemene
                self.RenderFlareTexture (self.m_GlowTexture, r, g, b, a, p, scale)
660 1 equemene
                return
661 1 equemene
662 1 equemene
        def RenderBigGlow (self, r, g, b, a, p, scale):
663 1 equemene
                self.RenderFlareTexture (self.m_BigGlowTexture, r, g, b, a, p, scale)
664 1 equemene
                return
665 1 equemene
666 1 equemene
        def RenderStreaks (self, r, g, b, a, p, scale):
667 1 equemene
                self.RenderFlareTexture (self.m_StreakTexture, r, g, b, a, p, scale)
668 1 equemene
                return
669 1 equemene
670 1 equemene
        def RenderFlareTexture (self, tex_ID, r, g, b, a, p, scale):
671 1 equemene
                # bleair: Duplicate functions all the same except for the texture to bind to.
672 1 equemene
673 1 equemene
                q = []
674 1 equemene
                q.append (glPoint ())
675 1 equemene
                q.append (glPoint ())
676 1 equemene
                q.append (glPoint ())
677 1 equemene
                q.append (glPoint ())
678 1 equemene
                # // Basically we are just going to make a 2D box
679 1 equemene
                # // from four points we don't need a z coord because
680 1 equemene
                # // we are rotating the camera by the inverse so the
681 1 equemene
                # // texture mapped quads will always face us.
682 1 equemene
683 1 equemene
                q[0].x = (p.x - scale);                                                                                        # // Set the x coordinate -scale units from the center point.
684 1 equemene
                q[0].y = (p.y - scale);                                                                                        # // Set the y coordinate -scale units from the center point.
685 1 equemene
686 1 equemene
                q[1].x = (p.x - scale);                                                                                        # // Set the x coordinate -scale units from the center point.
687 1 equemene
                q[1].y = (p.y + scale);                                                                                        # // Set the y coordinate scale units from the center point.
688 1 equemene
689 1 equemene
                q[2].x = (p.x + scale);                                                                                        # // Set the x coordinate scale units from the center point.
690 1 equemene
                q[2].y = (p.y - scale);                                                                                        # // Set the y coordinate -scale units from the center point.
691 1 equemene
692 1 equemene
                q[3].x = (p.x + scale);                                                                                        # // Set the x coordinate scale units from the center point.
693 1 equemene
                q[3].y = (p.y + scale);                                                                                        # // Set the y coordinate scale units from the center point.
694 1 equemene
695 1 equemene
                glPushMatrix();                                                                                                        # // Save the model view matrix
696 1 equemene
                glTranslatef(p.x, p.y, p.z);                                                                        # // Translate to our point
697 1 equemene
                glRotatef(-self.m_HeadingDegrees, 0.0, 1.0, 0.0);
698 1 equemene
                glRotatef(-self.m_PitchDegrees, 1.0, 0.0, 0.0);
699 1 equemene
                glBindTexture(GL_TEXTURE_2D, tex_ID);                                                        # // Bind to the Big Glow texture
700 1 equemene
                glColor4f(r, g, b, a);                                                                                        # // Set the color since the texture is a gray scale
701 1 equemene
702 1 equemene
                glBegin(GL_TRIANGLE_STRIP);                                                                                # // Draw the Big Glow on a Triangle Strip
703 1 equemene
                glTexCoord2f(0.0, 0.0);
704 1 equemene
                glVertex2f(q[0].x, q[0].y);
705 1 equemene
                glTexCoord2f(0.0, 1.0);
706 1 equemene
                glVertex2f(q[1].x, q[1].y);
707 1 equemene
                glTexCoord2f(1.0, 0.0);
708 1 equemene
                glVertex2f(q[2].x, q[2].y);
709 1 equemene
                glTexCoord2f(1.0, 1.0);
710 1 equemene
                glVertex2f(q[3].x, q[3].y);
711 1 equemene
                glEnd();
712 1 equemene
                glPopMatrix();                                                                                                        # // Restore the model view matrix
713 1 equemene
                return
714 1 equemene
715 1 equemene
716 1 equemene
717 1 equemene
718 1 equemene
        def SetPrespective (self):
719 1 equemene
                # Matrix = [0] * 16                                         # // A (list) array to hold the model view matrix.
720 1 equemene
721 1 equemene
                # However the MODELVIEW was oriented, we now rotate it based upon our Camer object's state.
722 1 equemene
                # // Going to use glRotate to calculate our direction vector
723 1 equemene
                glRotatef(self.m_HeadingDegrees, 0.0, 1.0, 0.0);                # turn your head left/right (around y axe)
724 1 equemene
                glRotatef(self.m_PitchDegrees, 1.0, 0.0, 0.0);                        # nod your head up/down (around x axe)
725 1 equemene
726 1 equemene
                # // Get the resulting matrix from OpenGL it will have our
727 1 equemene
                # // direction vector in the 3rd row.
728 1 equemene
                Matrix = glGetFloatv(GL_MODELVIEW_MATRIX);
729 1 equemene
730 1 equemene
                # // Get the direction vector from the matrix. Element 10 must
731 1 equemene
                # // be inverted!
732 1 equemene
                self.m_DirectionVector.i = Matrix[2] [0]        #[8];
733 1 equemene
                self.m_DirectionVector.j = Matrix[2] [1]        #[9];
734 1 equemene
                self.m_DirectionVector.k = -Matrix[2] [2]         #[10];
735 1 equemene
736 1 equemene
                # #### bleair: no need to do this as this. Previous rotates already here (because
737 1 equemene
                # #### all invocations have the modelview at identity.
738 1 equemene
                # #### Suspect this was just a bit of code that was mvoed up and not deleted here.
739 1 equemene
                # // Ok erase the results of the last computation.
740 1 equemene
                glLoadIdentity();
741 1 equemene
742 1 equemene
                # // Rotate the scene to get the right orientation.
743 1 equemene
                glRotatef(self.m_PitchDegrees, 1.0, 0.0, 0.0);
744 1 equemene
                glRotatef(self.m_HeadingDegrees, 0.0, 1.0, 0.0);
745 1 equemene
746 1 equemene
                # // A vector to hold our cameras direction * the forward velocity
747 1 equemene
                # // we don't want to destory the Direction vector by using it instead.
748 1 equemene
                # // Scale the direction by our speed.
749 1 equemene
                v = copy.copy (self.m_DirectionVector);
750 1 equemene
                v *= self.m_ForwardVelocity;
751 1 equemene
752 1 equemene
                # // Increment our position by the vector
753 1 equemene
                self.m_Position.x += v.i;
754 1 equemene
                self.m_Position.y += v.j;
755 1 equemene
                self.m_Position.z += v.k;
756 1 equemene
757 1 equemene
                # // Translate to our new position.
758 1 equemene
                glTranslatef(-self.m_Position.x, -self.m_Position.y, -self.m_Position.z);
759 1 equemene
                return
760 1 equemene
761 1 equemene
762 1 equemene
"""
763 1 equemene
        //////////// MEMBER VARIBLES //////////////////////////////////////
764 1 equemene
        glVector vLightSourceToCamera, vLightSourceToIntersect;
765 1 equemene
        glPoint ptIntersect, pt;
766 1 equemene
        GLsizei m_WindowHeight;
767 1 equemene
        GLsizei m_WindowWidth;
768 1 equemene
        GLuint m_StreakTexture;
769 1 equemene
        GLuint m_HaloTexture;
770 1 equemene
        GLuint m_GlowTexture;
771 1 equemene
        GLuint m_BigGlowTexture;
772 1 equemene
        GLfloat m_MaxPointSize;
773 1 equemene
        GLfloat m_Frustum[6][4];
774 1 equemene
        glPoint m_LightSourcePos;
775 1 equemene
        GLfloat m_MaxPitchRate;
776 1 equemene
        GLfloat m_MaxHeadingRate;
777 1 equemene
        GLfloat m_HeadingDegrees;
778 1 equemene
        GLfloat m_PitchDegrees;
779 1 equemene
        GLfloat m_MaxForwardVelocity;
780 1 equemene
        GLfloat m_ForwardVelocity;
781 1 equemene
        glPoint m_Position;
782 1 equemene
        glVector m_DirectionVector;
783 1 equemene
"""