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