Tweek the stereo settings: allow negative eye separation.
[blender.git] / source / gameengine / Rasterizer / RAS_OpenGLRasterizer / RAS_OpenGLRasterizer.cpp
1 /**
2  * $Id$
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30  */
31  
32 #include <math.h>
33  
34 #include "RAS_OpenGLRasterizer.h"
35
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
39
40 #ifdef WIN32
41 #include <windows.h>
42 #endif // WIN32
43 #ifdef __APPLE__
44 #include <OpenGL/gl.h>
45 #else
46 #include <GL/gl.h>
47 #endif
48
49 #include "RAS_Rect.h"
50 #include "RAS_TexVert.h"
51 #include "MT_CmMatrix4x4.h"
52 #include "RAS_IRenderTools.h" // rendering text
53
54 #include "RAS_GLExtensionManager.h"
55
56 /**
57  *  32x32 bit masks for vinterlace stereo mode
58  */
59 static GLuint left_eye_vinterlace_mask[32];
60 static GLuint right_eye_vinterlace_mask[32];
61
62 /**
63  *  32x32 bit masks for hinterlace stereo mode.
64  *  Left eye = &hinterlace_mask[0]
65  *  Right eye = &hinterlace_mask[1]
66  */
67 static GLuint hinterlace_mask[33];
68
69 RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
70         :RAS_IRasterizer(canvas),
71         m_2DCanvas(canvas),
72         m_fogenabled(false),
73         m_time(0.0),
74         m_stereomode(RAS_STEREO_NOSTEREO),
75         m_curreye(RAS_STEREO_LEFTEYE),
76         m_eyeseparation(0.0),
77         m_seteyesep(false),
78         m_focallength(0.0),
79         m_setfocallength(false),
80         m_noOfScanlines(32),
81         m_materialCachingInfo(0)
82 {
83         m_viewmatrix.Identity();
84         
85         for (int i = 0; i < 32; i++)
86         {
87                 left_eye_vinterlace_mask[i] = 0x55555555;
88                 right_eye_vinterlace_mask[i] = 0xAAAAAAAA;
89                 hinterlace_mask[i] = (i&1)*0xFFFFFFFF;
90         }
91         hinterlace_mask[32] = 0;
92 }
93
94
95
96 RAS_OpenGLRasterizer::~RAS_OpenGLRasterizer()
97 {
98 }
99
100
101
102 static void Myinit_gl_stuff(void)       
103 {
104         float mat_specular[] = { 0.5, 0.5, 0.5, 1.0 };
105         float mat_shininess[] = { 35.0 };
106 /*      float one= 1.0; */
107         int a, x, y;
108         GLubyte pat[32*32];
109         const GLubyte *patc= pat;
110                 
111         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_specular);
112         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
113         glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
114
115
116 #if defined(__FreeBSD) || defined(__linux__)
117         glDisable(GL_DITHER);   /* op sgi/sun hardware && 12 bits */
118 #endif
119         
120         /* no local viewer, looks ugly in ortho mode */
121         /* glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, &one); */
122         
123         glDepthFunc(GL_LEQUAL);
124         /* scaling matrices */
125         glEnable(GL_NORMALIZE);
126
127         glShadeModel(GL_FLAT);
128
129         glDisable(GL_ALPHA_TEST);
130         glDisable(GL_BLEND);
131         glDisable(GL_DEPTH_TEST);
132         glDisable(GL_FOG);
133         glDisable(GL_LIGHTING);
134         glDisable(GL_LOGIC_OP);
135         glDisable(GL_STENCIL_TEST);
136         glDisable(GL_TEXTURE_1D);
137         glDisable(GL_TEXTURE_2D);
138
139         glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
140         glPixelTransferi(GL_RED_SCALE, 1);
141         glPixelTransferi(GL_RED_BIAS, 0);
142         glPixelTransferi(GL_GREEN_SCALE, 1);
143         glPixelTransferi(GL_GREEN_BIAS, 0);
144         glPixelTransferi(GL_BLUE_SCALE, 1);
145         glPixelTransferi(GL_BLUE_BIAS, 0);
146         glPixelTransferi(GL_ALPHA_SCALE, 1);
147         glPixelTransferi(GL_ALPHA_BIAS, 0);
148
149         a = 0;
150         for(x=0; x<32; x++)
151         {
152                 for(y=0; y<4; y++)
153                 {
154                         if( (x) & 1) pat[a++]= 0x88;
155                         else pat[a++]= 0x22;
156                 }
157         }
158         
159         glPolygonStipple(patc);
160 }
161
162
163
164 bool RAS_OpenGLRasterizer::Init()
165 {
166
167         Myinit_gl_stuff();
168
169         m_redback = 0.4375;
170         m_greenback = 0.4375;
171         m_blueback = 0.4375;
172         m_alphaback = 0.0;
173         
174         glClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
175         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
176         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
177
178         glShadeModel(GL_SMOOTH);
179
180         return true;
181 }
182
183
184
185 void RAS_OpenGLRasterizer::SetBackColor(float red,
186                                                                                 float green,
187                                                                                 float blue,
188                                                                                 float alpha)
189 {
190         m_redback = red;
191         m_greenback = green;
192         m_blueback = blue;
193         m_alphaback = alpha;
194 }
195
196
197
198 void RAS_OpenGLRasterizer::SetFogColor(float r,
199                                                                            float g,
200                                                                            float b)
201 {
202         m_fogr = r;
203         m_fogg = g;
204         m_fogb = b;
205         m_fogenabled = true;
206 }
207
208
209
210 void RAS_OpenGLRasterizer::SetFogStart(float start)
211 {
212         m_fogstart = start;
213         m_fogenabled = true;
214 }
215
216
217
218 void RAS_OpenGLRasterizer::SetFogEnd(float fogend)
219 {
220         m_fogdist = fogend;
221         m_fogenabled = true;
222 }
223
224
225
226 void RAS_OpenGLRasterizer::SetFog(float start,
227                                                                   float dist,
228                                                                   float r,
229                                                                   float g,
230                                                                   float b)
231 {
232         m_fogstart = start;
233         m_fogdist = dist;
234         m_fogr = r;
235         m_fogg = g;
236         m_fogb = b;
237         m_fogenabled = true;
238 }
239
240
241
242 void RAS_OpenGLRasterizer::DisableFog()
243 {
244         m_fogenabled = false;
245 }
246
247
248
249 void RAS_OpenGLRasterizer::DisplayFog()
250 {
251         if ((m_drawingmode >= KX_SOLID) && m_fogenabled)
252         {
253                 float params[5];
254                 glFogi(GL_FOG_MODE, GL_LINEAR);
255                 glFogf(GL_FOG_DENSITY, 0.1f);
256                 glFogf(GL_FOG_START, m_fogstart);
257                 glFogf(GL_FOG_END, m_fogstart + m_fogdist);
258                 params[0]= m_fogr;
259                 params[1]= m_fogg;
260                 params[2]= m_fogb;
261                 params[3]= 0.0;
262                 glFogfv(GL_FOG_COLOR, params); 
263                 glEnable(GL_FOG);
264         } 
265         else
266         {
267                 glDisable(GL_FOG);
268         }
269 }
270
271
272
273 void RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat)
274 {
275         if (mat.GetCachingInfo() != m_materialCachingInfo)
276         {
277                 mat.Activate(this, m_materialCachingInfo);
278         }
279 }
280
281
282
283 void RAS_OpenGLRasterizer::Exit()
284 {
285
286         glEnable(GL_CULL_FACE);
287         glEnable(GL_DEPTH_TEST);
288         glClearDepth(1.0); 
289         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
290         glClearColor(m_redback, m_greenback, m_blueback, m_alphaback);
291         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
292         glDepthMask (GL_TRUE);
293         glDepthFunc(GL_LEQUAL);
294         glBlendFunc(GL_ONE, GL_ZERO);
295         
296         glDisable(GL_POLYGON_STIPPLE);
297         
298         glDisable(GL_LIGHTING);
299         if (bgl::QueryExtension(bgl::_GL_EXT_separate_specular_color) || bgl::QueryVersion(1, 2))
300                 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
301         
302         EndFrame();
303 }
304
305 bool RAS_OpenGLRasterizer::InterlacedStereo() const
306 {
307         return m_stereomode == RAS_STEREO_VINTERLACE || m_stereomode == RAS_STEREO_INTERLACED;
308 }
309
310 bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
311 {
312         m_time = time;
313         m_drawingmode = drawingmode;
314         
315         if (!InterlacedStereo() || m_curreye == RAS_STEREO_LEFTEYE)
316         {
317                 m_2DCanvas->ClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
318                 m_2DCanvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER);
319         }
320
321         // Blender camera routine destroys the settings
322         if (m_drawingmode < KX_SOLID)
323         {
324                 glDisable (GL_CULL_FACE);
325                 glDisable (GL_DEPTH_TEST);
326         }
327         else
328         {
329                 glEnable(GL_DEPTH_TEST);
330                 glEnable (GL_CULL_FACE);
331         }
332
333         glShadeModel(GL_SMOOTH);
334
335         m_2DCanvas->BeginFrame();
336         
337         return true;
338 }
339
340
341
342 void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode)
343 {
344         m_drawingmode = drawingmode;
345
346         switch (m_drawingmode)
347         {
348         case KX_BOUNDINGBOX:
349                 {
350                 }
351         case KX_WIREFRAME:
352                 {
353                         glDisable (GL_CULL_FACE);
354                         break;
355                 }
356         case KX_TEXTURED:
357                 {
358                 }
359         case KX_SHADED:
360                 {
361                 }
362         case KX_SOLID:
363                 {
364                 }
365         default:
366                 {
367                 }
368         }
369 }
370
371
372
373 int RAS_OpenGLRasterizer::GetDrawingMode()
374 {
375         return m_drawingmode;
376 }
377
378
379
380 void RAS_OpenGLRasterizer::SetDepthMask(DepthMask depthmask)
381 {
382         glDepthMask(depthmask == KX_DEPTHMASK_DISABLED ? GL_FALSE : GL_TRUE);
383 }
384
385
386
387 void RAS_OpenGLRasterizer::ClearDepthBuffer()
388 {
389         m_2DCanvas->ClearBuffer(RAS_ICanvas::DEPTH_BUFFER);
390 }
391
392
393 void RAS_OpenGLRasterizer::ClearCachingInfo(void)
394 {
395         m_materialCachingInfo = 0;
396 }
397
398
399 void RAS_OpenGLRasterizer::EndFrame()
400 {
401         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
402         m_2DCanvas->EndFrame();
403 }       
404
405 void RAS_OpenGLRasterizer::SetRenderArea()
406 {
407         // only above/below stereo method needs viewport adjustment
408         switch (m_stereomode)
409         {
410                 case RAS_STEREO_ABOVEBELOW:
411                         switch(m_curreye)
412                         {
413                                 case RAS_STEREO_LEFTEYE:
414                                         // upper half of window
415                                         m_2DCanvas->GetDisplayArea().SetLeft(0);
416                                         m_2DCanvas->GetDisplayArea().SetBottom(m_2DCanvas->GetHeight() -
417                                                 int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
418         
419                                         m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
420                                         m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight()));
421                                         break;
422                                 case RAS_STEREO_RIGHTEYE:
423                                         // lower half of window
424                                         m_2DCanvas->GetDisplayArea().SetLeft(0);
425                                         m_2DCanvas->GetDisplayArea().SetBottom(0);
426                                         m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
427                                         m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
428                                         break;
429                         }
430                         break;
431                 case RAS_STEREO_SIDEBYSIDE:
432                         switch (m_curreye)
433                         {
434                                 case RAS_STEREO_LEFTEYE:
435                                         // Left half of window
436                                         m_2DCanvas->GetDisplayArea().SetLeft(0);
437                                         m_2DCanvas->GetDisplayArea().SetBottom(0);
438                                         m_2DCanvas->GetDisplayArea().SetRight(m_2DCanvas->GetWidth()/2);
439                                         m_2DCanvas->GetDisplayArea().SetTop(m_2DCanvas->GetHeight());
440                                         break;
441                                 case RAS_STEREO_RIGHTEYE:
442                                         // Right half of window
443                                         m_2DCanvas->GetDisplayArea().SetLeft(m_2DCanvas->GetWidth()/2);
444                                         m_2DCanvas->GetDisplayArea().SetBottom(0);
445                                         m_2DCanvas->GetDisplayArea().SetRight(m_2DCanvas->GetWidth());
446                                         m_2DCanvas->GetDisplayArea().SetTop(m_2DCanvas->GetHeight());
447                                         break;
448                         }
449                         break;
450                 default:
451                         // every available pixel
452                         m_2DCanvas->GetDisplayArea().SetLeft(0);
453                         m_2DCanvas->GetDisplayArea().SetBottom(0);
454                         m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
455                         m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight()));
456                         break;
457         }
458 }
459
460         
461 void RAS_OpenGLRasterizer::SetStereoMode(const StereoMode stereomode)
462 {
463         m_stereomode = stereomode;
464 }
465
466
467
468 bool RAS_OpenGLRasterizer::Stereo()
469 {
470         if(m_stereomode == RAS_STEREO_NOSTEREO)
471                 return false;
472         else
473                 return true;
474 }
475
476
477 void RAS_OpenGLRasterizer::SetEye(StereoEye eye)
478 {
479         m_curreye = eye;
480         switch (m_stereomode)
481         {
482                 case RAS_STEREO_QUADBUFFERED:
483                         glDrawBuffer(m_curreye == RAS_STEREO_LEFTEYE ? GL_BACK_LEFT : GL_BACK_RIGHT);
484                         break;
485                 case RAS_STEREO_ANAGLYPH:
486                         if (m_curreye == RAS_STEREO_LEFTEYE)
487                         {
488                                 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_FALSE);
489                         } else {
490                                 //glAccum(GL_LOAD, 1.0);
491                                 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
492                                 ClearDepthBuffer();
493                         }
494                         break;
495                 case RAS_STEREO_VINTERLACE:
496                 {
497                         glEnable(GL_POLYGON_STIPPLE);
498                         glPolygonStipple((const GLubyte*) ((m_curreye == RAS_STEREO_LEFTEYE) ? left_eye_vinterlace_mask : right_eye_vinterlace_mask));
499                         if (m_curreye == RAS_STEREO_RIGHTEYE)
500                                 ClearDepthBuffer();
501                         break;
502                 }
503                 case RAS_STEREO_INTERLACED:
504                 {
505                         glEnable(GL_POLYGON_STIPPLE);
506                         glPolygonStipple((const GLubyte*) &hinterlace_mask[m_curreye == RAS_STEREO_LEFTEYE?0:1]);
507                         if (m_curreye == RAS_STEREO_RIGHTEYE)
508                                 ClearDepthBuffer();
509                         break;
510                 }
511                 default:
512                         break;
513         }
514 }
515
516 RAS_IRasterizer::StereoEye RAS_OpenGLRasterizer::GetEye()
517 {
518         return m_curreye;
519 }
520
521
522 void RAS_OpenGLRasterizer::SetEyeSeparation(float eyeseparation)
523 {
524         m_eyeseparation = eyeseparation;
525         m_seteyesep = true;
526 }
527
528 float RAS_OpenGLRasterizer::GetEyeSeparation()
529 {
530         return m_eyeseparation;
531 }
532
533 void RAS_OpenGLRasterizer::SetFocalLength(float focallength)
534 {
535         m_focallength = focallength;
536         m_setfocallength = true;
537 }
538
539 float RAS_OpenGLRasterizer::GetFocalLength()
540 {
541         return m_focallength;
542 }
543
544
545 void RAS_OpenGLRasterizer::SwapBuffers()
546 {
547         m_2DCanvas->SwapBuffers();
548 }
549
550
551
552 void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays,
553                                                                         const vecIndexArrays & indexarrays,
554                                                                         int mode,
555                                                                         class RAS_IPolyMaterial* polymat,
556                                                                         class RAS_IRenderTools* rendertools,
557                                                                         bool useObjectColor,
558                                                                         const MT_Vector4& rgbacolor
559                                                                         )
560
561         GLenum drawmode;
562         switch (mode)
563         {
564         case 0:
565                 drawmode = GL_TRIANGLES;
566                 break;
567         case 1:
568                 drawmode = GL_LINES;
569                 break;
570         case 2:
571                 drawmode = GL_QUADS;
572                 break;
573         default:
574                 drawmode = GL_LINES;
575                 break;
576         }
577         
578         const RAS_TexVert* vertexarray ;
579         unsigned int numindices,vt;
580
581         for (vt=0;vt<vertexarrays.size();vt++)
582         {
583                 vertexarray = &((*vertexarrays[vt]) [0]);
584                 const KX_IndexArray & indexarray = (*indexarrays[vt]);
585                 numindices = indexarray.size();
586                 
587                 if (!numindices)
588                         break;
589                 
590                 int vindex=0;
591                 switch (mode)
592                 {
593                 case 1:
594                         {
595                                 glBegin(GL_LINES);
596                                 vindex=0;
597                                 for (unsigned int i=0;i<numindices;i+=2)
598                                 {
599                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
600                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
601                                 }
602                                 glEnd();
603                         }
604                         break;
605                 case 2:
606                         {
607                                 glBegin(GL_QUADS);
608                                 vindex=0;
609                                 if (useObjectColor)
610                                 {
611                                         for (unsigned int i=0;i<numindices;i+=4)
612                                         {
613
614                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
615
616                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
617                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
618                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
619                                                 vindex++;
620                                                 
621                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
622                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
623                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
624                                                 vindex++;
625                                                 
626                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
627                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
628                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
629                                                 vindex++;
630                                                 
631                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
632                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
633                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
634                                                 vindex++;
635                                         }
636                                 }
637                                 else
638                                 {
639                                         for (unsigned int i=0;i<numindices;i+=4)
640                                         {
641                                                 // This looks curiously endian unsafe to me.
642                                                 // However it depends on the way the colors are packed into 
643                                                 // the m_rgba field of RAS_TexVert
644
645                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
646                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
647                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
648                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
649                                                 vindex++;
650                                                 
651                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
652                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
653                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
654                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
655                                                 vindex++;
656                                                 
657                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
658                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
659                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
660                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
661                                                 vindex++;
662                                                 
663                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
664                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
665                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
666                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
667                                                 vindex++;
668                                         }
669                                 }
670                                 glEnd();        
671                                 break;
672                         }
673                 case 0:
674                         {
675                                 glBegin(GL_TRIANGLES);
676                                 vindex=0;
677                                 if (useObjectColor)
678                                 {
679                                         for (unsigned int i=0;i<numindices;i+=3)
680                                         {
681
682                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
683
684                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
685                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
686                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
687                                                 vindex++;
688                                                 
689                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
690                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
691                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
692                                                 vindex++;
693                                                 
694                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
695                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
696                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
697                                                 vindex++;
698                                         }
699                                 }
700                                 else 
701                                 {
702                                         for (unsigned int i=0;i<numindices;i+=3)
703                                         {
704
705                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
706                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
707                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
708                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
709                                                 vindex++;
710                                                 
711                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
712                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
713                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
714                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
715                                                 vindex++;
716                                                 
717                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
718                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
719                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
720                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
721                                                 vindex++;
722                                         }
723                                 }
724                                 glEnd();        
725                                 break;
726                         }
727                 default:
728                         {
729                         }
730                         
731                 } // switch
732         } // for each vertexarray
733
734 }
735
736 void RAS_OpenGLRasterizer::IndexPrimitives_Ex(const vecVertexArray & vertexarrays,
737                                                                         const vecIndexArrays & indexarrays,
738                                                                         int mode,
739                                                                         class RAS_IPolyMaterial* polymat,
740                                                                         class RAS_IRenderTools* rendertools,
741                                                                         bool useObjectColor,
742                                                                         const MT_Vector4& rgbacolor
743                                                                         )
744
745         bool    recalc;
746         GLenum drawmode;
747         switch (mode)
748         {
749         case 0:
750                 drawmode = GL_TRIANGLES;
751                 break;
752         case 1:
753                 drawmode = GL_LINES;
754                 break;
755         case 2:
756                 drawmode = GL_QUADS;
757                 break;
758         default:
759                 drawmode = GL_LINES;
760                 break;
761         }
762         
763         const RAS_TexVert* vertexarray ;
764         unsigned int numindices,vt;
765
766         for (vt=0;vt<vertexarrays.size();vt++)
767         {
768                 vertexarray = &((*vertexarrays[vt]) [0]);
769                 const KX_IndexArray & indexarray = (*indexarrays[vt]);
770                 numindices = indexarray.size();
771                 
772                 if (!numindices)
773                         continue;
774                 
775                 int vindex=0;
776                 switch (mode)
777                 {
778                 case 1:
779                         {
780                                 glBegin(GL_LINES);
781                                 vindex=0;
782                                 for (unsigned int i=0;i<numindices;i+=2)
783                                 {
784                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
785                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
786                                 }
787                                 glEnd();
788                         }
789                         break;
790                 case 2:
791                         {
792                                 glBegin(GL_QUADS);
793                                 vindex=0;
794                                 if (useObjectColor)
795                                 {
796                                         for (unsigned int i=0;i<numindices;i+=4)
797                                         {
798                                                 MT_Point3 mv1, mv2, mv3, mv4, fnor;
799                                                 /* Calc a new face normal */
800
801                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
802                                                         recalc= true;
803                                                 else
804                                                         recalc=false;
805
806                                                 if (recalc){
807                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
808                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
809                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
810                                                         mv4 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
811                                                         
812                                                         fnor = (((mv2-mv1).cross(mv3-mv2))+((mv4-mv3).cross(mv1-mv4))).safe_normalized();
813
814                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
815                                                 }
816
817                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
818
819                                                 if (!recalc)
820                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
821                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
822                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
823                                                 vindex++;
824                                                 
825                                                 if (!recalc)
826                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
827                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
828                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
829                                                 vindex++;
830                                                 
831                                                 if (!recalc)
832                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());                                             
833                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
834                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
835                                                 vindex++;
836                                                 
837                                                 if (!recalc)
838                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
839                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
840                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
841                                                 vindex++;
842                                         }
843                                 }
844                                 else
845                                 {
846                                         for (unsigned int i=0;i<numindices;i+=4)
847                                         {
848                                                 // This looks curiously endian unsafe to me.
849                                                 // However it depends on the way the colors are packed into 
850                                                 // the m_rgba field of RAS_TexVert
851                                                 MT_Point3 mv1, mv2, mv3, mv4, fnor;
852                                                 /* Calc a new face normal */
853
854                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
855                                                         recalc= true;
856                                                 else
857                                                         recalc=false;
858
859
860                                                 if (recalc){
861                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
862                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
863                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
864                                                         mv4 = MT_Point3(vertexarray[(indexarray[vindex+3])].getLocalXYZ());
865                                                         
866                                                         fnor = (((mv2-mv1).cross(mv3-mv2))+((mv4-mv3).cross(mv1-mv4))).safe_normalized();
867
868                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
869                                                 }
870
871                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
872                                                 if (!recalc)
873                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
874                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
875                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
876                                                 vindex++;
877                                                 
878                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
879                                                 if (!recalc)
880                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
881                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
882                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
883                                                 vindex++;
884                                                 
885                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
886                                                 if (!recalc)
887                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
888                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
889                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
890                                                 vindex++;
891                                                 
892                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
893                                                 if (!recalc)
894                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
895                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
896                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
897                                                 vindex++;
898                                         }
899                                 }
900                                 glEnd();        
901                                 break;
902                         }
903                 case 0:
904                         {
905                                 glBegin(GL_TRIANGLES);
906                                 vindex=0;
907                                 if (useObjectColor)
908                                 {
909                                         for (unsigned int i=0;i<numindices;i+=3)
910                                         {
911                                                 MT_Point3 mv1, mv2, mv3, fnor;
912                                                 /* Calc a new face normal */
913
914                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
915                                                         recalc= true;
916                                                 else
917                                                         recalc=false;
918
919                                                 if (recalc){
920                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
921                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
922                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
923                                                         
924                                                         fnor = ((mv2-mv1).cross(mv3-mv2)).safe_normalized();
925                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
926                                                 }
927
928                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
929
930                                                 if (!recalc)
931                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
932                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
933                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
934                                                 vindex++;
935                                                 
936                                                 if (!recalc)
937                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
938                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
939                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
940                                                 vindex++;
941                                                 
942                                                 if (!recalc)
943                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
944                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
945                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
946                                                 vindex++;
947                                         }
948                                 }
949                                 else 
950                                 {
951                                         for (unsigned int i=0;i<numindices;i+=3)
952                                         {
953                                                 MT_Point3 mv1, mv2, mv3, fnor;
954                                                 /* Calc a new face normal */
955
956                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
957                                                         recalc= true;
958                                                 else
959                                                         recalc=false;
960
961
962                                                 if (recalc){
963                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
964                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
965                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
966                                                         
967                                                         fnor = ((mv2-mv1).cross(mv3-mv2)).safe_normalized();
968                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
969                                                 }
970
971                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
972                                                 if (!recalc)
973                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
974                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
975                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
976                                                 vindex++;
977                                                 
978                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
979                                                 if (!recalc)
980                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
981                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
982                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
983                                                 vindex++;
984                                                 
985                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
986                                                 if (!recalc)
987                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
988                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
989                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
990                                                 vindex++;
991                                         }
992                                 }
993                                 glEnd();        
994                                 break;
995                         }
996                 default:
997                         {
998                         }
999                         
1000                 } // switch
1001         } // for each vertexarray
1002
1003 }
1004
1005
1006
1007 void RAS_OpenGLRasterizer::IndexPrimitives_3DText(const vecVertexArray & vertexarrays,
1008                                                                         const vecIndexArrays & indexarrays,
1009                                                                         int mode,
1010                                                                         class RAS_IPolyMaterial* polymat,
1011                                                                         class RAS_IRenderTools* rendertools,
1012                                                                         bool useObjectColor,
1013                                                                         const MT_Vector4& rgbacolor
1014                                                                         )
1015
1016         GLenum drawmode;
1017         switch (mode)
1018         {
1019         case 0:
1020                 drawmode = GL_TRIANGLES;
1021                 break;
1022         case 1:
1023                 drawmode = GL_LINES;
1024                 break;
1025         case 2:
1026                 drawmode = GL_QUADS;
1027                 break;
1028         default:
1029                 drawmode = GL_LINES;
1030                 break;
1031         }
1032         
1033         const RAS_TexVert* vertexarray ;
1034         
1035         unsigned int numindices, vt;
1036         
1037         if (useObjectColor)
1038         {
1039                 glDisableClientState(GL_COLOR_ARRAY);
1040                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
1041         }
1042         else
1043         {
1044                 glEnableClientState(GL_COLOR_ARRAY);
1045         }
1046         
1047         for (vt=0;vt<vertexarrays.size();vt++)
1048         {
1049                 vertexarray = &((*vertexarrays[vt]) [0]);
1050                 const KX_IndexArray & indexarray = (*indexarrays[vt]);
1051                 numindices = indexarray.size();
1052                 
1053                 if (!numindices)
1054                         break;
1055                 
1056                 int vindex=0;
1057                 switch (mode)
1058                 {
1059                 case 1:
1060                         {
1061                                 glBegin(GL_LINES);
1062                                 vindex=0;
1063                                 for (unsigned int i=0;i<numindices;i+=2)
1064                                 {
1065                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
1066                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
1067                                 }
1068                                 glEnd();
1069                         }
1070                         break;
1071                 case 2:
1072                         {
1073                                 vindex=0;
1074                                 for (unsigned int i=0;i<numindices;i+=4)
1075                                 {
1076                                         float v1[3],v2[3],v3[3],v4[3];
1077                                         
1078                                         v1[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1079                                         v1[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1080                                         v1[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1081                                         vindex++;
1082                                         
1083                                         v2[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1084                                         v2[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1085                                         v2[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1086                                         vindex++;
1087                                         
1088                                         v3[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1089                                         v3[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1090                                         v3[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1091                                         vindex++;
1092                                         
1093                                         v4[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1094                                         v4[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1095                                         v4[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1096                                         
1097                                         vindex++;
1098                                         
1099                                         rendertools->RenderText(polymat->GetDrawingMode(),polymat,v1,v2,v3,v4);
1100                                         ClearCachingInfo();
1101                                 }
1102                                 break;
1103                         }
1104                 case 0:
1105                         {
1106                                 glBegin(GL_TRIANGLES);
1107                                 vindex=0;
1108                                 for (unsigned int i=0;i<numindices;i+=3)
1109                                 {
1110                                         float v1[3],v2[3],v3[3];
1111                                         
1112                                         v1[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1113                                         v1[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1114                                         v1[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1115                                         vindex++;
1116                                         
1117                                         v2[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1118                                         v2[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1119                                         v2[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1120                                         vindex++;
1121                                         
1122                                         v3[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1123                                         v3[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1124                                         v3[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1125                                         vindex++;
1126                                         
1127                                         rendertools->RenderText(polymat->GetDrawingMode(),polymat,v1,v2,v3,NULL);               
1128                                         ClearCachingInfo();
1129                                 }
1130                                 glEnd();        
1131                                 break;
1132                         }
1133                 default:
1134                         {
1135                         }
1136                 }       //switch
1137         }       //for each vertexarray
1138 }
1139
1140
1141
1142 void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat)
1143 {
1144         glMatrixMode(GL_PROJECTION);
1145         double* matrix = &mat(0,0);
1146         glLoadMatrixd(matrix);
1147 }
1148
1149
1150 void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat)
1151 {
1152         glMatrixMode(GL_PROJECTION);
1153         double matrix[16];
1154         /* Get into argument. Looks a bit dodgy, but it's ok. */
1155         mat.getValue(matrix);
1156         /* Internally, MT_Matrix4x4 uses doubles (MT_Scalar). */
1157         glLoadMatrixd(matrix);  
1158 }
1159
1160 MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
1161         float left,
1162         float right,
1163         float bottom,
1164         float top,
1165         float frustnear,
1166         float frustfar,
1167         bool
1168 ){
1169         MT_Matrix4x4 result;
1170         double mat[16];
1171
1172         // correction for stereo
1173         if(m_stereomode != RAS_STEREO_NOSTEREO)
1174         {
1175                         float near_div_focallength;
1176                         // next 2 params should be specified on command line and in Blender publisher
1177                         if (!m_setfocallength)
1178                                 m_focallength = 1.5 * right;  // derived from example
1179                         if (!m_seteyesep)
1180                                 m_eyeseparation = 0.18 * right;  // just a guess...
1181
1182                         near_div_focallength = frustnear / m_focallength;
1183                         switch(m_curreye)
1184                         {
1185                                 case RAS_STEREO_LEFTEYE:
1186                                                 left += 0.5 * m_eyeseparation * near_div_focallength;
1187                                                 right += 0.5 * m_eyeseparation * near_div_focallength;
1188                                                 break;
1189                                 case RAS_STEREO_RIGHTEYE:
1190                                                 left -= 0.5 * m_eyeseparation * near_div_focallength;
1191                                                 right -= 0.5 * m_eyeseparation * near_div_focallength;
1192                                                 break;
1193                         }
1194                         // leave bottom, top, bottom and top untouched
1195         }
1196         
1197         glMatrixMode(GL_PROJECTION);
1198         glLoadIdentity();
1199         glFrustum(left, right, bottom, top, frustnear, frustfar);
1200                 
1201         glGetDoublev(GL_PROJECTION_MATRIX, mat);
1202         result.setValue(mat);
1203
1204         return result;
1205 }
1206
1207
1208 // next arguments probably contain redundant info, for later...
1209 void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, const MT_Vector3& campos,
1210                 const MT_Point3 &, const MT_Quaternion &camOrientQuat)
1211 {
1212         MT_Matrix4x4 viewMat = mat;
1213
1214         // correction for stereo
1215         if(m_stereomode != RAS_STEREO_NOSTEREO)
1216         {
1217                 MT_Matrix3x3 camOrientMat3x3(camOrientQuat);
1218                 MT_Vector3 unitViewDir(0.0, -1.0, 0.0);  // minus y direction, Blender convention
1219                 MT_Vector3 unitViewupVec(0.0, 0.0, 1.0);
1220                 MT_Vector3 viewDir, viewupVec;
1221                 MT_Vector3 eyeline;
1222
1223                 // actual viewDir
1224                 viewDir = camOrientMat3x3 * unitViewDir;  // this is the moto convention, vector on right hand side
1225                 // actual viewup vec
1226                 viewupVec = camOrientMat3x3 * unitViewupVec;
1227
1228                 // vector between eyes
1229                 eyeline = viewDir.cross(viewupVec);
1230
1231                 switch(m_curreye)
1232                 {
1233                         case RAS_STEREO_LEFTEYE:
1234                                 {
1235                                 // translate to left by half the eye distance
1236                                 MT_Transform transform;
1237                                 transform.setIdentity();
1238                                 transform.translate(-(eyeline * m_eyeseparation / 2.0));
1239                                 viewMat *= transform;
1240                                 }
1241                                 break;
1242                         case RAS_STEREO_RIGHTEYE:
1243                                 {
1244                                 // translate to right by half the eye distance
1245                                 MT_Transform transform;
1246                                 transform.setIdentity();
1247                                 transform.translate(eyeline * m_eyeseparation / 2.0);
1248                                 viewMat *= transform;
1249                                 }
1250                                 break;
1251                 }
1252         }
1253
1254         // convert row major matrix 'viewMat' to column major for OpenGL
1255         MT_Scalar cammat[16];
1256         viewMat.getValue(cammat);
1257         MT_CmMatrix4x4 viewCmmat = cammat;
1258
1259         glMatrixMode(GL_MODELVIEW);
1260         m_viewmatrix = viewCmmat;
1261         glLoadMatrixd(&m_viewmatrix(0,0));
1262         m_campos = campos;
1263 }
1264
1265
1266 const MT_Point3& RAS_OpenGLRasterizer::GetCameraPosition()
1267 {
1268         return m_campos;
1269 }
1270
1271
1272
1273 void RAS_OpenGLRasterizer::LoadViewMatrix()
1274 {
1275         glLoadMatrixd(&m_viewmatrix(0,0));
1276 }
1277
1278
1279
1280 void RAS_OpenGLRasterizer::EnableTextures(bool enable)
1281 {
1282 }
1283
1284
1285
1286 void RAS_OpenGLRasterizer::SetCullFace(bool enable)
1287 {
1288         if (enable)
1289                 glEnable(GL_CULL_FACE);
1290         else
1291                 glDisable(GL_CULL_FACE);
1292 }
1293
1294 void RAS_OpenGLRasterizer::SetLines(bool enable)
1295 {
1296         if (enable)
1297                 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1298         else
1299                 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1300 }
1301
1302 void RAS_OpenGLRasterizer::SetSpecularity(float specX,
1303                                                                                   float specY,
1304                                                                                   float specZ,
1305                                                                                   float specval)
1306 {
1307         GLfloat mat_specular[] = {specX, specY, specZ, specval};
1308         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
1309 }
1310
1311
1312
1313 void RAS_OpenGLRasterizer::SetShinyness(float shiny)
1314 {
1315         GLfloat mat_shininess[] = {     shiny };
1316         glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
1317 }
1318
1319
1320
1321 void RAS_OpenGLRasterizer::SetDiffuse(float difX,float difY,float difZ,float diffuse)
1322 {
1323         GLfloat mat_diffuse [] = {difX, difY,difZ, diffuse};
1324         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
1325 }
1326
1327 double RAS_OpenGLRasterizer::GetTime()
1328 {
1329         return m_time;
1330 }
1331
1332