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