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