Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Extras / CDTestFramework / RenderingHelpers.cpp
1 /*
2 CDTestFramework http://codercorner.com
3 Copyright (c) 2007-2008 Pierre Terdiman,  pierre@codercorner.com
4
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose, 
8 including commercial applications, and to alter it and redistribute it freely, 
9 subject to the following restrictions:
10
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15 #include "stdafx.h"
16
17 #include <stdio.h>
18 #include "GL/glut.h"
19
20 #include "RenderingHelpers.h"
21
22 ////////////////////////
23
24 void DrawLine(const Point& p0, const Point& p1, const Point& color, float line_width)
25 {
26         glDisable(GL_LIGHTING);
27         glLineWidth(line_width);
28         glColor4f(color.x, color.y, color.z, 1.0f);
29         Point tmp[] = {p0, p1};
30         glEnableClientState(GL_VERTEX_ARRAY);
31         glVertexPointer(3, GL_FLOAT, sizeof(Point), &tmp[0].x);
32         glDrawArrays(GL_LINES, 0, 2);
33         glDisableClientState(GL_VERTEX_ARRAY);
34         glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
35         glEnable(GL_LIGHTING);
36 }
37
38 void DrawTriangle(const Point& p0, const Point& p1, const Point& p2, const Point& color)
39 {
40 //      glDisable(GL_LIGHTING);
41         glColor4f(color.x, color.y, color.z, 1.0f);
42         Point tmp[] = {p0, p1, p2};
43         glEnableClientState(GL_VERTEX_ARRAY);
44         glVertexPointer(3, GL_FLOAT, sizeof(Point), &tmp[0].x);
45         glDrawArrays(GL_TRIANGLES, 0, 3);
46         glDisableClientState(GL_VERTEX_ARRAY);
47 //      glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
48 //      glEnable(GL_LIGHTING);
49 }
50
51
52 ////////////////////////
53
54 static void SetupGLMatrix(const Point& pos)
55 {
56         float glmat[16];        //4x4 column major matrix for OpenGL.
57         glmat[0] = 1.0f;
58         glmat[1] = 0.0f;
59         glmat[2] = 0.0f;
60         glmat[3] = 0.0f;
61
62         glmat[4] = 0.0f;
63         glmat[5] = 1.0f;
64         glmat[6] = 0.0f;
65         glmat[7] = 0.0f;
66
67         glmat[8] = 0.0f;
68         glmat[9] = 0.0f;
69         glmat[10] = 1.0f;
70         glmat[11] = 0.0f;
71
72         glmat[12] = pos.x;
73         glmat[13] = pos.y;
74         glmat[14] = pos.z;
75         glmat[15] = 1.0f;
76
77         glMultMatrixf(glmat);
78 }
79
80 void SetupGLMatrix(const Point& pos, const Matrix3x3& rot)
81 {
82         float glmat[16];        //4x4 column major matrix for OpenGL.
83         glmat[0] = rot.m[0][0];
84         glmat[1] = rot.m[0][1];
85         glmat[2] = rot.m[0][2];
86         glmat[3] = 0.0f;
87
88         glmat[4] = rot.m[1][0];
89         glmat[5] = rot.m[1][1];
90         glmat[6] = rot.m[1][2];
91         glmat[7] = 0.0f;
92
93         glmat[8] = rot.m[2][0];
94         glmat[9] = rot.m[2][1];
95         glmat[10] = rot.m[2][2];
96         glmat[11] = 0.0f;
97
98         glmat[12] = pos.x;
99         glmat[13] = pos.y;
100         glmat[14] = pos.z;
101         glmat[15] = 1.0f;
102
103         glMultMatrixf(glmat);
104 }
105
106 void SetupGLMatrix(const Matrix4x4& world)
107 {
108         SetupGLMatrix(world.GetTrans(), world);
109 }
110
111 ////////////////////////
112
113 static void RenderSphere(float radius)
114 {
115         glutSolidSphere(radius, 12, 12);        // Radius / slices / stacks
116 }
117
118 void DrawSphere(const Sphere& sphere)
119 {
120         glPushMatrix();
121         SetupGLMatrix(sphere.mCenter);
122         RenderSphere(sphere.mRadius);
123         glPopMatrix();
124 }
125
126 ////////////////////////
127
128 static void RenderBox(int size)
129 {
130         glutSolidCube(size);
131 }
132
133 void DrawOBB(const OBB& obb)
134 {
135         glPushMatrix();
136         SetupGLMatrix(obb.mCenter, obb.mRot);
137         glScalef(obb.mExtents.x, obb.mExtents.y, obb.mExtents.z);
138         RenderBox(2);
139         glPopMatrix();
140 }
141
142 ////////////////////////
143
144 static float gCylinderData[]={
145         1.0f,0.0f,1.0f,1.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,
146         0.866025f,0.500000f,1.0f,0.866025f,0.500000f,1.0f,0.866025f,0.500000f,0.0f,0.866025f,0.500000f,0.0f,
147         0.500000f,0.866025f,1.0f,0.500000f,0.866025f,1.0f,0.500000f,0.866025f,0.0f,0.500000f,0.866025f,0.0f,
148         -0.0f,1.0f,1.0f,-0.0f,1.0f,1.0f,-0.0f,1.0f,0.0f,-0.0f,1.0f,0.0f,
149         -0.500000f,0.866025f,1.0f,-0.500000f,0.866025f,1.0f,-0.500000f,0.866025f,0.0f,-0.500000f,0.866025f,0.0f,
150         -0.866025f,0.500000f,1.0f,-0.866025f,0.500000f,1.0f,-0.866025f,0.500000f,0.0f,-0.866025f,0.500000f,0.0f,
151         -1.0f,-0.0f,1.0f,-1.0f,-0.0f,1.0f,-1.0f,-0.0f,0.0f,-1.0f,-0.0f,0.0f,
152         -0.866025f,-0.500000f,1.0f,-0.866025f,-0.500000f,1.0f,-0.866025f,-0.500000f,0.0f,-0.866025f,-0.500000f,0.0f,
153         -0.500000f,-0.866025f,1.0f,-0.500000f,-0.866025f,1.0f,-0.500000f,-0.866025f,0.0f,-0.500000f,-0.866025f,0.0f,
154         0.0f,-1.0f,1.0f,0.0f,-1.0f,1.0f,0.0f,-1.0f,0.0f,0.0f,-1.0f,0.0f,
155         0.500000f,-0.866025f,1.0f,0.500000f,-0.866025f,1.0f,0.500000f,-0.866025f,0.0f,0.500000f,-0.866025f,0.0f,
156         0.866026f,-0.500000f,1.0f,0.866026f,-0.500000f,1.0f,0.866026f,-0.500000f,0.0f,0.866026f,-0.500000f,0.0f,
157         1.0f,0.0f,1.0f,1.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f
158 };
159
160 static float gCylinderDataCapsTop[]={
161         0.866026f,-0.500000f,1.000000f,0.000000f,1.000000f,1.000000f,
162         0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
163         0.500000f,-0.866025f,1.000000f,0.000000f,1.000000f,1.000000f,
164         0.500000f,-0.866025f,1.000000f,0.000000f,1.000000f,1.000000f,
165         0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
166         0.000000f,-1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
167         0.000000f,-1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
168         0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
169         -0.500000f,-0.866025f,1.000000f,0.000000f,1.000000f,1.000000f,
170         -0.500000f,-0.866025f,1.000000f,0.000000f,1.000000f,1.000000f,
171         0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
172         -0.866025f,-0.500000f,1.000000f,0.000000f,1.000000f,1.000000f,
173         -0.866025f,-0.500000f,1.000000f,0.000000f,1.000000f,1.000000f,
174         0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
175         -1.000000f,-0.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
176         -1.000000f,-0.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
177         0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
178         -0.866025f,0.500000f,1.000000f,0.000000f,1.000000f,1.000000f,
179         -0.866025f,0.500000f,1.000000f,0.000000f,1.000000f,1.000000f,
180         0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
181         -0.500000f,0.866025f,1.000000f,0.000000f,1.000000f,1.000000f,
182         -0.500000f,0.866025f,1.000000f,0.000000f,1.000000f,1.000000f,
183         0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
184         -0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
185         -0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
186         0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
187         0.500000f,0.866025f,1.000000f,0.000000f,1.000000f,1.000000f,
188         0.500000f,0.866025f,1.000000f,0.000000f,1.000000f,1.000000f,
189         0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
190         0.866025f,0.500000f,1.000000f,0.000000f,1.000000f,1.000000f,
191         0.866025f,0.500000f,1.000000f,0.000000f,1.000000f,1.000000f,
192         0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
193         1.000000f,0.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
194         1.000000f,0.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
195         0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
196         0.866026f,-0.500000f,1.000000f,0.000000f,1.000000f,1.000000f,
197 };
198
199 static float gCylinderDataCapsBottom[]={
200         1.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
201         0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
202         0.866025f,0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f,
203         0.866025f,0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f,
204         0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
205         0.500000f,0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f,
206         0.500000f,0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f,
207         0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
208         -0.000000f,1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
209         -0.000000f,1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
210         0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
211         -0.500000f,0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f,
212         -0.500000f,0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f,
213         0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
214         -0.866025f,0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f,
215         -0.866025f,0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f,
216         0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
217         -1.000000f,-0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
218         -1.000000f,-0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
219         0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
220         -0.866025f,-0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f,
221         -0.866025f,-0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f,
222         0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
223         -0.500000f,-0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f,
224         -0.500000f,-0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f,
225         0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
226         0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
227         0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
228         0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
229         0.500000f,-0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f,
230         0.500000f,-0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f,
231         0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
232         0.866026f,-0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f,
233         0.866026f,-0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f,
234         0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
235         1.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
236 };
237
238 static void RenderCylinder()
239 {
240         glEnableClientState(GL_VERTEX_ARRAY);
241         glEnableClientState(GL_NORMAL_ARRAY);
242     glVertexPointer(3, GL_FLOAT, 2*3*sizeof(float), gCylinderData);
243     glNormalPointer(GL_FLOAT, 2*3*sizeof(float), gCylinderData+3);
244         glDrawArrays(GL_TRIANGLE_STRIP, 0, 13*2);
245
246     glVertexPointer(3, GL_FLOAT, 2*3*sizeof(float), gCylinderDataCapsTop);
247     glNormalPointer(GL_FLOAT, 2*3*sizeof(float), gCylinderDataCapsTop+3);
248         glDrawArrays(GL_TRIANGLES, 0, 36);
249
250     glVertexPointer(3, GL_FLOAT, 2*3*sizeof(float), gCylinderDataCapsBottom);
251     glNormalPointer(GL_FLOAT, 2*3*sizeof(float), gCylinderDataCapsBottom+3);
252         glDrawArrays(GL_TRIANGLES, 0, 36);
253
254     glDisableClientState(GL_VERTEX_ARRAY);
255     glDisableClientState(GL_NORMAL_ARRAY);
256 }
257
258 void DrawCapsule(const Matrix4x4& world, const Point& p0, const Point& p1, float r)
259 {
260         const float h = p0.Distance(p1);
261
262         glPushMatrix();
263         SetupGLMatrix(world);
264
265         glPushMatrix();
266         glTranslatef(0.0f, h*0.5f, 0.0f);
267         RenderSphere(r);
268         glPopMatrix();
269
270         glPushMatrix();
271         glTranslatef(0.0f,-h*0.5f, 0.0f);
272         RenderSphere(r);
273         glPopMatrix();
274
275         glPushMatrix();
276         glTranslatef(0.0f,h*0.5f, 0.0f);
277         glScalef(r,h,r);
278         glRotatef(90.0f,1.0f,0.0f,0.0f);
279         RenderCylinder();
280         glPopMatrix();
281
282         glPopMatrix();
283 }
284
285
286
287 #ifdef TOSEE
288 #include "NxPhysics.h"
289 #include "DrawObjects.h"
290
291 #include <GL/glut.h>
292
293 static float gPlaneData[]={
294     -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
295     1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
296         1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f
297 };
298
299
300 static void RenderPlane()
301 {
302         glEnableClientState(GL_VERTEX_ARRAY);
303         glEnableClientState(GL_NORMAL_ARRAY);
304     glVertexPointer(3, GL_FLOAT, 2*3*sizeof(float), gPlaneData);
305     glNormalPointer(GL_FLOAT, 2*3*sizeof(float), gPlaneData+3);
306         glDrawArrays(GL_TRIANGLES, 0, 6);
307     glDisableClientState(GL_VERTEX_ARRAY);
308     glDisableClientState(GL_NORMAL_ARRAY);
309 }
310
311 void SetupGLMatrix(const NxVec3& pos, const NxMat33& orient)
312 {
313         float glmat[16];        //4x4 column major matrix for OpenGL.
314         orient.getColumnMajorStride4(&(glmat[0]));
315         pos.get(&(glmat[12]));
316
317         //clear the elements we don't need:
318         glmat[3] = glmat[7] = glmat[11] = 0.0f;
319         glmat[15] = 1.0f;
320
321         glMultMatrixf(&(glmat[0]));
322 }
323
324 void DrawLine(const NxVec3& p0, const NxVec3& p1, const NxVec3& color, float lineWidth)
325 {
326         glDisable(GL_LIGHTING);
327         glLineWidth(lineWidth);
328         glColor4f(color.x, color.y, color.z, 1.0f);
329         NxVec3 av3LineEndpoints[] = {p0, p1};
330         glEnableClientState(GL_VERTEX_ARRAY);
331         glVertexPointer(3, GL_FLOAT, sizeof(NxVec3), &av3LineEndpoints[0].x);
332         glDrawArrays(GL_LINES, 0, 2);
333         glDisableClientState(GL_VERTEX_ARRAY);
334         glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
335         glEnable(GL_LIGHTING);
336 }
337
338 void DrawTriangle(const NxVec3& p0, const NxVec3& p1, const NxVec3& p2, const NxVec3& color)
339 {
340         glDisable(GL_LIGHTING);
341         glColor4f(color.x, color.y, color.z, 1.0f);
342         NxVec3 av3LineEndpoints[] = {p0, p1, p2};
343         glEnableClientState(GL_VERTEX_ARRAY);
344         glVertexPointer(3, GL_FLOAT, sizeof(NxVec3), &av3LineEndpoints[0].x);
345         glDrawArrays(GL_TRIANGLES, 0, 3);
346         glDisableClientState(GL_VERTEX_ARRAY);
347         glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
348         glEnable(GL_LIGHTING);
349 }
350
351 void DrawCircle(NxU32 nbSegments, const NxMat34& matrix, const NxVec3& color, const NxF32 radius, const bool semicircle)
352 {
353         NxF32 step = NxTwoPiF32/NxF32(nbSegments);
354         NxU32 segs = nbSegments;
355         if(semicircle)
356         {
357                 segs /= 2;
358         }
359
360         for(NxU32 i=0;i<segs;i++)
361         {
362                 NxU32 j=i+1;
363                 if(j==nbSegments)       j=0;
364
365                 NxF32 angle0 = NxF32(i)*step;
366                 NxF32 angle1 = NxF32(j)*step;
367
368                 NxVec3 p0,p1;
369                 matrix.multiply(NxVec3(radius * sinf(angle0), radius * cosf(angle0), 0.0f), p0);
370                 matrix.multiply(NxVec3(radius * sinf(angle1), radius * cosf(angle1), 0.0f), p1);
371
372                 DrawLine(p0, p1, color);
373         }
374 }
375
376
377 void DrawEllipse(NxU32 nbSegments, const NxMat34& matrix, const NxVec3& color, const NxF32 radius1, const NxF32 radius2, const bool semicircle)
378 {
379         NxF32 step = NxTwoPiF32/NxF32(nbSegments);
380         NxU32 segs = nbSegments;
381         if(semicircle)
382         {
383                 segs /= 2;
384         }
385
386         for(NxU32 i=0;i<segs;i++)
387         {
388                 NxU32 j=i+1;
389                 if(j==nbSegments)       j=0;
390
391                 NxF32 angle0 = NxF32(i)*step;
392                 NxF32 angle1 = NxF32(j)*step;
393
394                 NxVec3 p0,p1;
395                 matrix.multiply(NxVec3(radius1 * sinf(angle0), radius2 * cosf(angle0), 0.0f), p0);
396                 matrix.multiply(NxVec3(radius1 * sinf(angle1), radius2 * cosf(angle1), 0.0f), p1);
397
398                 DrawLine(p0, p1, color);
399         }
400 }
401
402 void DrawWirePlane(NxShape* plane, const NxVec3& color)
403 {
404 }
405
406 void DrawPlane(NxShape* plane)
407 {
408         NxMat34 pose =  plane->getGlobalPose();
409         NxPlaneShape* planeShape = plane->isPlane();
410         NxPlane p = planeShape->getPlane();
411         pose.t.x += p.d;
412         pose.t.y += p.d;
413         pose.t.z += p.d;
414
415         glPushMatrix();
416         glDisable(GL_LIGHTING);
417         glColor4f(0.1f, 0.2f, 0.3f, 1.0f);
418         pose.t.y -= 0.1f;
419         SetupGLMatrix(pose.t, pose.M);
420         glScalef(1024,0,1024);
421         RenderPlane();
422         glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
423         glEnable(GL_LIGHTING);
424         glPopMatrix();
425 }
426
427 void DrawWireBox(const NxBox& obb, const NxVec3& color, float lineWidth)
428 {
429         // Compute obb vertices
430         NxVec3 pp[8];
431         NxComputeBoxPoints(obb, pp);
432                 
433         // Draw all lines
434         const NxU32* Indices = NxGetBoxEdges();
435         for(NxU32 i=0;i<12;i++)
436         {
437                 NxU32 VRef0 = *Indices++;
438                 NxU32 VRef1 = *Indices++;
439                 DrawLine(pp[VRef0], pp[VRef1], color, lineWidth);
440         }
441 }
442
443 void DrawWireBox(NxShape* box, const NxVec3& color, float lineWidth)
444 {
445         NxBox obb;
446         box->isBox()->getWorldOBB(obb);
447
448         DrawWireBox(obb, color, lineWidth);
449 }
450
451
452 void DrawWireSphere(NxShape* sphere, const NxVec3& color)
453 {
454         NxMat34 pose = sphere->getGlobalPose();
455
456         glPushMatrix();
457         NxReal r = sphere->isSphere()->getRadius();
458
459         NxVec3 c0;      pose.M.getColumn(0, c0);
460         NxVec3 c1;      pose.M.getColumn(1, c1);
461         NxVec3 c2;      pose.M.getColumn(2, c2);
462         DrawCircle(20, pose, color, r);
463
464         pose.M.setColumn(0, c1);
465         pose.M.setColumn(1, c2);
466         pose.M.setColumn(2, c0);
467         DrawCircle(20, pose, color, r);
468
469         pose.M.setColumn(0, c2);
470         pose.M.setColumn(1, c0);
471         pose.M.setColumn(2, c1);
472         DrawCircle(20, pose, color, r);
473
474         glPopMatrix();
475 }
476
477 void DrawSphere(NxShape* sphere)
478 {
479         NxMat34 pose = sphere->getGlobalPose();
480
481         glPushMatrix();
482         SetupGLMatrix(pose.t, pose.M);
483         NxReal r = sphere->isSphere()->getRadius();
484         glScalef(r,r,r);
485         RenderSphere();
486         glPopMatrix();
487 }
488
489 void DrawWireCapsule(NxShape* capsule, const NxVec3& color)
490 {
491         NxMat34 pose = capsule->getGlobalPose();
492
493         NxReal r = capsule->isCapsule()->getRadius();
494         NxReal h = capsule->isCapsule()->getHeight();
495
496         NxSegment SG;
497         pose.M.getColumn(1, SG.p1);
498         SG.p1 *= 0.5f*h;
499         SG.p0 = -SG.p1;
500         SG.p0 += pose.t;
501         SG.p1 += pose.t;
502
503         NxVec3 c0;      pose.M.getColumn(0, c0);
504         NxVec3 c1;      pose.M.getColumn(1, c1);
505         NxVec3 c2;      pose.M.getColumn(2, c2);
506         DrawLine(SG.p0 + c0*r, SG.p1 + c0*r, color);
507         DrawLine(SG.p0 - c0*r, SG.p1 - c0*r, color);
508         DrawLine(SG.p0 + c2*r, SG.p1 + c2*r, color);
509         DrawLine(SG.p0 - c2*r, SG.p1 - c2*r, color);
510
511         pose.M.setColumn(0, -c1);
512         pose.M.setColumn(1, -c0);
513         pose.M.setColumn(2, c2);
514         pose.t = SG.p0;
515         DrawCircle(20, pose, color, r, true);   //halfcircle -- flipped
516
517         pose.M.setColumn(0, c1);
518         pose.M.setColumn(1, -c0);
519         pose.M.setColumn(2, c2);
520         pose.t = SG.p1;
521         DrawCircle(20, pose, color, r, true);
522
523         pose.M.setColumn(0, -c1);
524         pose.M.setColumn(1, c2);
525         pose.M.setColumn(2, c0);
526         pose.t = SG.p0;
527         DrawCircle(20, pose, color, r, true);//halfcircle -- good
528
529         pose.M.setColumn(0, c1);
530         pose.M.setColumn(1, c2);
531         pose.M.setColumn(2, c0);
532         pose.t = SG.p1;
533         DrawCircle(20, pose, color, r, true);
534
535         pose.M.setColumn(0, c2);
536         pose.M.setColumn(1, c0);
537         pose.M.setColumn(2, c1);
538         pose.t = SG.p0;
539         DrawCircle(20, pose, color, r); //full circle
540         pose.t = SG.p1;
541         DrawCircle(20, pose, color, r);
542 }
543
544 static void computeBasis(const NxVec3& dir, NxVec3& right, NxVec3& up)
545 {
546         // Derive two remaining vectors
547         if(fabsf(dir.y)>0.9999f)        right = NxVec3(1.0f, 0.0f, 0.0f);
548         else                                            right = (NxVec3(0.0f, 1.0f, 0.0f) ^ dir);
549         right.normalize();
550         up = dir ^ right;
551 }
552
553 void DrawWireCapsule(const NxCapsule& capsule, const NxVec3& color)
554 {
555         NxReal r = capsule.radius;
556         NxVec3 dir = capsule.p0 - capsule.p1;
557         NxReal h = dir.magnitude();
558         NxMat34 pose;
559         pose.t = (capsule.p0 + capsule.p1)*0.5f;
560
561         if(h!=0.0f)
562         {
563                 dir/=h;
564                 NxVec3 right, up;
565                 computeBasis(dir, right, up);
566                 pose.M.setColumn(0, right);
567                 pose.M.setColumn(1, dir);
568                 pose.M.setColumn(2, up);
569         }
570         else
571         {
572                 pose.M.id();
573         }
574
575 //      NxMat34 pose = capsule->getGlobalPose();
576 //      const NxReal & r = capsule->isCapsule()->getRadius();
577 //      const NxReal & h = capsule->isCapsule()->getHeight();
578
579
580
581         NxSegment SG;
582         pose.M.getColumn(1, SG.p1);
583         SG.p1 *= 0.5f*h;
584         SG.p0 = -SG.p1;
585         SG.p0 += pose.t;
586         SG.p1 += pose.t;
587
588         NxVec3 c0;      pose.M.getColumn(0, c0);
589         NxVec3 c1;      pose.M.getColumn(1, c1);
590         NxVec3 c2;      pose.M.getColumn(2, c2);
591         DrawLine(SG.p0 + c0*r, SG.p1 + c0*r, color);
592         DrawLine(SG.p0 - c0*r, SG.p1 - c0*r, color);
593         DrawLine(SG.p0 + c2*r, SG.p1 + c2*r, color);
594         DrawLine(SG.p0 - c2*r, SG.p1 - c2*r, color);
595
596         pose.M.setColumn(0, -c1);
597         pose.M.setColumn(1, -c0);
598         pose.M.setColumn(2, c2);
599         pose.t = SG.p0;
600         DrawCircle(20, pose, color, r, true);   //halfcircle -- flipped
601
602         pose.M.setColumn(0, c1);
603         pose.M.setColumn(1, -c0);
604         pose.M.setColumn(2, c2);
605         pose.t = SG.p1;
606         DrawCircle(20, pose, color, r, true);
607
608         pose.M.setColumn(0, -c1);
609         pose.M.setColumn(1, c2);
610         pose.M.setColumn(2, c0);
611         pose.t = SG.p0;
612         DrawCircle(20, pose, color, r, true);//halfcircle -- good
613
614         pose.M.setColumn(0, c1);
615         pose.M.setColumn(1, c2);
616         pose.M.setColumn(2, c0);
617         pose.t = SG.p1;
618         DrawCircle(20, pose, color, r, true);
619
620         pose.M.setColumn(0, c2);
621         pose.M.setColumn(1, c0);
622         pose.M.setColumn(2, c1);
623         pose.t = SG.p0;
624         DrawCircle(20, pose, color, r); //full circle
625         pose.t = SG.p1;
626         DrawCircle(20, pose, color, r);
627 }
628
629 void DrawCapsule(const NxVec3& color, NxF32 r, NxF32 h)
630 {
631         glColor4f(color.x, color.y, color.z, 1.0f);
632
633         glPushMatrix();
634         glTranslatef(0.0f, h*0.5f, 0.0f);
635         glScalef(r,r,r);
636         RenderSphere();
637         glPopMatrix();
638
639         glPushMatrix();
640         glTranslatef(0.0f,-h*0.5f, 0.0f);
641         glScalef(r,r,r);
642         RenderSphere();
643         glPopMatrix();
644
645         glPushMatrix();
646         glTranslatef(0.0f,h*0.5f, 0.0f);
647         glScalef(r,h,r);
648         glRotatef(90.0f,1.0f,0.0f,0.0f);
649         RenderCylinder();
650         glPopMatrix();
651 }
652
653 typedef NxVec3 Point;
654 typedef struct _Triangle { NxU32 p0; NxU32 p1; NxU32 p2; } Triangle;
655
656 void DrawWireConvex(NxShape* mesh, const NxVec3& color)
657 {
658     if(mesh->userData == NULL) return;
659
660         NxMat34 pose = mesh->getGlobalPose();
661
662         NxConvexMeshDesc meshDesc = *((NxConvexMeshDesc*)(mesh->userData));
663 //      mesh->isConvexMesh()->getConvexMesh().saveToDesc(meshDesc);
664
665         NxU32 nbVerts = meshDesc.numVertices;
666         NxU32 nbTriangles = meshDesc.numTriangles;
667
668         Point* points = (Point *)meshDesc.points;
669         Triangle* triangles = (Triangle *)meshDesc.triangles;
670
671         glPushMatrix();
672
673         float glmat[16];        //4x4 column major matrix for OpenGL.
674         pose.M.getColumnMajorStride4(&(glmat[0]));
675         pose.t.get(&(glmat[12]));
676
677         //clear the elements we don't need:
678         glmat[3] = glmat[7] = glmat[11] = 0.0f;
679         glmat[15] = 1.0f;
680
681         glMultMatrixf(&(glmat[0]));
682
683         while(nbTriangles--)
684         {
685                 DrawLine(points[triangles->p0], points[triangles->p1], color);
686                 DrawLine(points[triangles->p1], points[triangles->p2], color);
687                 DrawLine(points[triangles->p2], points[triangles->p0], color);
688                 triangles++;
689         }
690
691         glPopMatrix();
692 }
693
694 void DrawTriangleList(int iTriangleCount, Triangle *pTriangles, Point *pPoints)
695 {
696         static int iBufferSize=0;
697         static float *pfVertexBuffer=NULL;
698         static float *pfNormalBuffer=NULL;
699
700         if(iBufferSize < iTriangleCount*3)
701         {
702                 iBufferSize=3*iTriangleCount;
703
704                 delete[] pfVertexBuffer;
705                 pfVertexBuffer = new float[iBufferSize*3];
706
707                 delete[] pfNormalBuffer;
708                 pfNormalBuffer = new float[iBufferSize*3];
709         }
710
711         float *pfDestinationVertex=pfVertexBuffer;
712         float *pfDestinationNormal=pfNormalBuffer;
713
714         for(int iTriangle=0; iTriangle<iTriangleCount; iTriangle++)
715         {
716                 *pfDestinationVertex++=pPoints[pTriangles->p0].x;
717                 *pfDestinationVertex++=pPoints[pTriangles->p0].y;
718                 *pfDestinationVertex++=pPoints[pTriangles->p0].z;
719                 *pfDestinationVertex++=pPoints[pTriangles->p1].x;
720                 *pfDestinationVertex++=pPoints[pTriangles->p1].y;
721                 *pfDestinationVertex++=pPoints[pTriangles->p1].z;
722                 *pfDestinationVertex++=pPoints[pTriangles->p2].x;
723                 *pfDestinationVertex++=pPoints[pTriangles->p2].y;
724                 *pfDestinationVertex++=pPoints[pTriangles->p2].z;
725
726                 NxVec3 edge1 = pPoints[pTriangles->p1] - pPoints[pTriangles->p0];
727                 NxVec3 edge2 = pPoints[pTriangles->p2] - pPoints[pTriangles->p0];
728                 NxVec3 normal = edge1.cross(edge2);
729                 normal.normalize();
730
731                 *pfDestinationNormal++=normal.x;
732                 *pfDestinationNormal++=normal.y;
733                 *pfDestinationNormal++=normal.z;
734                 *pfDestinationNormal++=normal.x;
735                 *pfDestinationNormal++=normal.y;
736                 *pfDestinationNormal++=normal.z;
737                 *pfDestinationNormal++=normal.x;
738                 *pfDestinationNormal++=normal.y;
739                 *pfDestinationNormal++=normal.z;
740
741                 pTriangles++;
742         }
743
744         glEnableClientState(GL_VERTEX_ARRAY);
745         glVertexPointer(3, GL_FLOAT, 0, pfVertexBuffer);
746         glEnableClientState(GL_NORMAL_ARRAY);
747         glNormalPointer(GL_FLOAT, 0, pfNormalBuffer);
748
749         glDrawArrays(GL_TRIANGLES, 0, 3*iTriangleCount);
750
751         glDisableClientState(GL_VERTEX_ARRAY);
752         glDisableClientState(GL_NORMAL_ARRAY);
753
754 }
755
756 void DrawConvex(NxShape* mesh)
757 {
758     NxConvexMeshDesc meshDesc;
759
760         // SRM : Please note that I looked into a crash issue posed by
761         // one of our customers, and this code (i.e. reinterpreting the
762         // NxShape's userData as an NxConvexMeshDesc * was crashing because
763         // in the SampleRaycastCar demo, it sets that pointer equal to the
764         // NxWheel because that is used in NxVehicle::handleContactPair().  Thus
765         // in order to allow this code not to crash on the PS3, we should
766         // simply force the shape to save its description here.
767         mesh->isConvexMesh()->getConvexMesh().saveToDesc(meshDesc);
768         /**
769         if(mesh->userData != NULL)
770         {
771                 meshDesc = *((NxConvexMeshDesc*)(mesh->userData));
772         } else {
773                 mesh->isConvexMesh()->getConvexMesh().saveToDesc(meshDesc);
774         }
775         **/
776
777         NxMat34 pose = mesh->getGlobalPose();
778
779         NxU32 nbVerts = meshDesc.numVertices;
780         NxU32 nbTriangles = meshDesc.numTriangles;
781
782         Point* points = (Point *)meshDesc.points;
783         Triangle* triangles = (Triangle *)meshDesc.triangles;
784
785         glPushMatrix();
786
787         float glmat[16];        //4x4 column major matrix for OpenGL.
788         pose.M.getColumnMajorStride4(&(glmat[0]));
789         pose.t.get(&(glmat[12]));
790
791         //clear the elements we don't need:
792         glmat[3] = glmat[7] = glmat[11] = 0.0f;
793         glmat[15] = 1.0f;
794
795         glMultMatrixf(&(glmat[0]));
796
797         DrawTriangleList(nbTriangles, triangles, points);
798         
799         glPopMatrix();
800 }
801
802 void DrawWireMesh(NxShape* mesh, const NxVec3& color)
803 {
804     if(mesh->userData == NULL) return;
805
806         NxMat34 pose = mesh->getGlobalPose();
807
808         NxTriangleMeshDesc meshDesc = *((NxTriangleMeshDesc*)(mesh->userData));
809 //      mesh->isTriangleMesh()->getTriangleMesh().saveToDesc(meshDesc);
810
811         NxU32 nbVerts = meshDesc.numVertices;
812         NxU32 nbTriangles = meshDesc.numTriangles;
813
814         Point* points = (Point *)meshDesc.points;
815         Triangle* triangles = (Triangle *)meshDesc.triangles;
816
817         glPushMatrix();
818
819         float glmat[16];        //4x4 column major matrix for OpenGL.
820         pose.M.getColumnMajorStride4(&(glmat[0]));
821         pose.t.get(&(glmat[12]));
822
823         //clear the elements we don't need:
824         glmat[3] = glmat[7] = glmat[11] = 0.0f;
825         glmat[15] = 1.0f;
826
827         glMultMatrixf(&(glmat[0]));
828
829         while(nbTriangles--)
830         {
831                 DrawLine(points[triangles->p0], points[triangles->p1], color);
832                 DrawLine(points[triangles->p1], points[triangles->p2], color);
833                 DrawLine(points[triangles->p2], points[triangles->p0], color);
834                 triangles++;
835         }
836
837         glPopMatrix();
838 }
839
840 void DrawMesh(NxShape* mesh)
841 {
842     if(mesh->userData == NULL) return;
843
844         NxMat34 pose = mesh->getGlobalPose();
845
846         NxTriangleMeshDesc meshDesc = *((NxTriangleMeshDesc*)(mesh->userData));
847 //      mesh->isTriangleMesh()->getTriangleMesh().saveToDesc(meshDesc);
848
849         NxU32 nbVerts = meshDesc.numVertices;
850         NxU32 nbTriangles = meshDesc.numTriangles;
851
852         Point* points = (Point *)meshDesc.points;
853         Triangle* triangles = (Triangle *)meshDesc.triangles;
854
855         glPushMatrix();
856
857         float glmat[16];        //4x4 column major matrix for OpenGL.
858         pose.M.getColumnMajorStride4(&(glmat[0]));
859         pose.t.get(&(glmat[12]));
860
861         //clear the elements we don't need:
862         glmat[3] = glmat[7] = glmat[11] = 0.0f;
863         glmat[15] = 1.0f;
864
865         glMultMatrixf(&(glmat[0]));
866
867         if(meshDesc.heightFieldVerticalAxis != NX_NOT_HEIGHTFIELD) 
868         {
869             glDisable(GL_LIGHT0);
870             glEnable(GL_LIGHT1);
871         }
872
873         DrawTriangleList(nbTriangles, triangles, points);
874
875         if(meshDesc.heightFieldVerticalAxis != NX_NOT_HEIGHTFIELD) 
876         {
877             glDisable(GL_LIGHT1);
878             glEnable(GL_LIGHT0);
879         }
880         
881         glPopMatrix();
882 }
883
884 void DrawWheelShape(NxShape* wheel)
885 {
886         if(wheel->is(NX_SHAPE_WHEEL) != NULL)
887         {
888                 NxWheelShape* wheelShape = (NxWheelShape*)wheel;
889                 glPushMatrix();
890
891                 float glmat[16];
892                 wheel->getGlobalPose().getColumnMajor44(glmat);
893
894                 NxWheelShapeDesc wheelShapeDesc;
895
896                 float r = wheelShape->getRadius();
897                 float a = wheelShape->getSteerAngle();
898
899                 glMultMatrixf(&(glmat[0]));
900                 glTranslatef(-r/2,0,0);
901                 glRotatef(90,0,1,0);
902                 glRotatef(NxMath::radToDeg(a),0,1,0);
903
904                 glScalef(r, r, r);
905                 RenderCylinder();
906                 glPopMatrix();
907         }
908 }
909
910 void DrawArrow(const NxVec3& posA, const NxVec3& posB, const NxVec3& color)
911 {
912         NxVec3 vec = posB - posA;
913         NxVec3 t0, t1, t2;
914         NxNormalToTangents(vec, t1, t2);
915
916         t0 = posB - posA;
917         t0.normalize();
918
919         NxVec3 lobe1  = posB - t0*0.15 + t1 * 0.15;
920         NxVec3 lobe2  = posB - t0*0.15 - t1 * 0.15;
921         NxVec3 lobe3  = posB - t0*0.15 + t2 * 0.15;
922         NxVec3 lobe4  = posB - t0*0.15 - t2 * 0.15;
923
924         NxVec3 v3ArrowShape[] = {
925                 NxVec3(posA), NxVec3(posB),
926                 NxVec3(posB), NxVec3(lobe1),
927                 NxVec3(posB), NxVec3(lobe2),
928                 NxVec3(posB), NxVec3(lobe3),
929                 NxVec3(posB), NxVec3(lobe4),
930         };
931
932         glDisable(GL_LIGHTING);
933         glLineWidth(3.0f);
934         glColor4f(color.x,color.y,color.z,1.0f);
935         glEnableClientState(GL_VERTEX_ARRAY);
936         glVertexPointer(3, GL_FLOAT, sizeof(NxVec3), &v3ArrowShape[0].x);
937         glDrawArrays(GL_LINES, 0, sizeof(v3ArrowShape)/sizeof(NxVec3));
938         glDisableClientState(GL_VERTEX_ARRAY);
939         glColor4f(1.0f,1.0f,1.0f,1.0f);
940 }
941
942 void DrawContactPoint(const NxVec3& pos, const NxReal radius, const NxVec3& color)
943 {
944         NxMat34 pose;
945         pose.t = pos;
946
947         NxVec3 c0;      pose.M.getColumn(0, c0);
948         NxVec3 c1;      pose.M.getColumn(1, c1);
949         NxVec3 c2;      pose.M.getColumn(2, c2);
950         DrawCircle(20, pose, color, radius);
951
952         pose.M.setColumn(0, c1);
953         pose.M.setColumn(1, c2);
954         pose.M.setColumn(2, c0);
955         DrawCircle(20, pose, color, radius);
956
957         pose.M.setColumn(0, c2);
958         pose.M.setColumn(1, c0);
959         pose.M.setColumn(2, c1);
960         DrawCircle(20, pose, color, radius);
961 }
962
963 void DrawWireShape(NxShape *shape, const NxVec3& color)
964 {
965     switch(shape->getType())
966     {
967                 case NX_SHAPE_PLANE:
968                         DrawWirePlane(shape, color);
969                 break;
970                 case NX_SHAPE_BOX:
971                         DrawWireBox(shape, color);
972                 break;
973                 case NX_SHAPE_SPHERE:
974                         DrawWireSphere(shape, color);
975                 break;
976                 case NX_SHAPE_CAPSULE:
977                         DrawWireCapsule(shape, color);
978                 break;
979                 case NX_SHAPE_CONVEX:
980                         DrawWireConvex(shape, color);
981                 break;          
982                 case NX_SHAPE_MESH:
983                         DrawWireMesh(shape, color);
984                 break;
985         }
986 }
987
988 void DrawShape(NxShape* shape)
989 {
990     switch(shape->getType())
991     {
992                 case NX_SHAPE_PLANE:
993                         DrawPlane(shape);
994                 break;
995                 case NX_SHAPE_BOX:
996                         DrawBox(shape);
997                 break;
998                 case NX_SHAPE_SPHERE:
999                         DrawSphere(shape);
1000                 break;
1001                 case NX_SHAPE_CAPSULE:
1002                         DrawCapsule(shape);
1003                 break;
1004                 case NX_SHAPE_CONVEX:
1005                         DrawConvex(shape);
1006                 break;
1007                 case NX_SHAPE_MESH:
1008                         DrawMesh(shape);
1009                 break;
1010                 case NX_SHAPE_WHEEL:
1011                         DrawWheelShape(shape);
1012                 break;
1013         }
1014 }
1015
1016 void DrawActor(NxActor* actor, NxActor* gSelectedActor)
1017 {
1018         NxShape*const* shapes = actor->getShapes();
1019         NxU32 nShapes = actor->getNbShapes();
1020         if (actor == gSelectedActor) 
1021         {
1022                 while (nShapes--)
1023                 {
1024                         DrawWireShape(shapes[nShapes], NxVec3(1,1,1));
1025                 }
1026         }
1027         nShapes = actor->getNbShapes();
1028         while (nShapes--)
1029         {
1030                 DrawShape(shapes[nShapes]);
1031         }
1032 }
1033
1034 void DrawWireActor(NxActor* actor)
1035 {
1036         NxShape*const* shapes = actor->getShapes();
1037         NxU32 nShapes = actor->getNbShapes();
1038         nShapes = actor->getNbShapes();
1039         while (nShapes--)
1040         {
1041                 DrawWireShape(shapes[nShapes], NxVec3(1,1,1));
1042         }
1043 }
1044
1045 static void DrawActorShadow(NxActor* actor, const float* ShadowMat)
1046 {
1047         glPushMatrix();
1048         glMultMatrixf(ShadowMat);
1049
1050         glDisable(GL_LIGHTING);
1051         glColor4f(0.05f, 0.1f, 0.15f, 1.0f);
1052         
1053         NxShape*const* shapes = actor->getShapes();
1054         NxU32 nShapes = actor->getNbShapes();
1055         while (nShapes--)
1056         {
1057                 switch(shapes[nShapes]->getType())
1058                 {
1059                     case NX_SHAPE_BOX:
1060                             DrawBox(shapes[nShapes]);
1061                         break;
1062                     case NX_SHAPE_SPHERE:
1063                             DrawSphere(shapes[nShapes]);
1064                         break;
1065                     case NX_SHAPE_CAPSULE:
1066                             DrawCapsule(shapes[nShapes]);
1067                         break;
1068                     case NX_SHAPE_CONVEX:
1069                             DrawConvex(shapes[nShapes]);
1070                         break;              
1071                 }
1072         }       
1073         
1074         glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
1075         glEnable(GL_LIGHTING);
1076
1077         glPopMatrix();
1078 }
1079
1080
1081 void DrawActorShadow(NxActor* actor)
1082 {
1083         const static float ShadowMat[]={ 1,0,0,0, 0,0,0,0, 0,0,1,0, 0,0,0,1 };
1084         DrawActorShadow(actor, ShadowMat);
1085 }
1086
1087 void DrawActorShadow2(NxActor* actor)
1088 {
1089     const static float ShadowMat[]={ 1,0,0,0, 1,0,-0.2,0, 0,0,1,0, 0,0,0,1 };
1090         DrawActorShadow(actor, ShadowMat);
1091 }
1092
1093 void DrawActorShadowZUp(NxActor* actor)
1094 {
1095     const static float ShadowMat[]={ 1,0,0,0, 0,1,0,0, 0,0,0,0, 0,0,0,1 };
1096         DrawActorShadow(actor, ShadowMat);
1097 }
1098
1099 void DrawCloth(NxCloth *cloth, bool shadows)
1100 {
1101         NxMeshData meshData = cloth->getMeshData();
1102
1103         NxU32 numVertices = *meshData.numVerticesPtr;
1104         NxU32 numTriangles = *meshData.numIndicesPtr / 3;
1105
1106         glEnableClientState(GL_VERTEX_ARRAY);
1107         glEnableClientState(GL_NORMAL_ARRAY);
1108         glVertexPointer(3, GL_FLOAT, 0, meshData.verticesPosBegin);
1109         glNormalPointer(GL_FLOAT, 0, meshData.verticesNormalBegin);
1110
1111 #ifdef __CELLOS_LV2__   
1112         glDrawRangeElements(GL_TRIANGLES, 0, numVertices-1, 3*numTriangles, GL_UNSIGNED_INT, meshData.indicesBegin);
1113 #else
1114         glDrawElements(GL_TRIANGLES, 3*numTriangles, GL_UNSIGNED_INT, meshData.indicesBegin);
1115 #endif
1116
1117         if (shadows) {
1118                 const static float ShadowMat[]={ 1,0,0,0, 0,0,0,0, 0,0,1,0, 0,0,0,1 };
1119                 glPushMatrix();
1120                 glMultMatrixf(ShadowMat);
1121                 glDisable(GL_LIGHTING);
1122                 glColor4f(0.05f, 0.1f, 0.15f,1.0f);
1123
1124 #ifdef __CELLOS_LV2__   
1125                 glDrawRangeElements(GL_TRIANGLES, 0, numVertices-1, 3*numTriangles, GL_UNSIGNED_INT, meshData.indicesBegin);
1126 #else
1127                 glDrawElements(GL_TRIANGLES, 3*numTriangles, GL_UNSIGNED_INT, meshData.indicesBegin);
1128 #endif
1129                 
1130                 glColor4f(1.0f, 1.0f, 1.0f,1.0f);
1131                 glEnable(GL_LIGHTING);
1132                 glPopMatrix();
1133         }
1134
1135         glDisableClientState(GL_VERTEX_ARRAY);
1136         glDisableClientState(GL_NORMAL_ARRAY);
1137 }
1138
1139 #ifdef WIN32
1140 #include <windows.h>
1141 typedef BOOL (APIENTRY *PFNWGLSWAPINTERVALFARPROC)( int );
1142 PFNWGLSWAPINTERVALFARPROC wglSwapIntervalEXT = 0;
1143 int vsyncState = 1;
1144 #endif
1145
1146 void toggleVSync()
1147 {
1148 #ifdef WIN32
1149         if (wglSwapIntervalEXT == NULL)
1150         {
1151                 const char* extensions = (const char*)glGetString(GL_EXTENSIONS);
1152                 if (strstr(extensions, "WGL_EXT_swap_control") != 0)
1153                 {
1154                          wglSwapIntervalEXT = (PFNWGLSWAPINTERVALFARPROC)wglGetProcAddress( "wglSwapIntervalEXT" );
1155                 }
1156         }
1157         if (wglSwapIntervalEXT != NULL)
1158         {
1159                 vsyncState = 1 - vsyncState;
1160                 wglSwapIntervalEXT(vsyncState);
1161         }
1162 #endif
1163 }
1164 #endif