Klockwork (http://www.klocwork.com) report; game engine fixes, related to 'Use Blende...
[blender-staging.git] / source / gameengine / Rasterizer / RAS_OpenGLRasterizer / RAS_OpenGLRasterizer.cpp
1 /**
2  * $Id$
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30  */
31  
32 #include <math.h>
33  
34 #include "RAS_OpenGLRasterizer.h"
35
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
39
40 #ifdef WIN32
41 #include <windows.h>
42 #endif // WIN32
43 #ifdef __APPLE__
44 #define GL_GLEXT_LEGACY 1
45 #include <OpenGL/gl.h>
46 #include <OpenGL/glu.h>
47 #else
48 #include <GL/gl.h>
49 #include <GL/glu.h>
50 #endif
51
52 #include "RAS_Rect.h"
53 #include "RAS_TexVert.h"
54 #include "MT_CmMatrix4x4.h"
55 #include "RAS_IRenderTools.h" // rendering text
56
57 #include "RAS_GLExtensionManager.h"
58
59 /**
60  *  32x32 bit masks for vinterlace stereo mode
61  */
62 static GLuint left_eye_vinterlace_mask[32];
63 static GLuint right_eye_vinterlace_mask[32];
64
65 /**
66  *  32x32 bit masks for hinterlace stereo mode.
67  *  Left eye = &hinterlace_mask[0]
68  *  Right eye = &hinterlace_mask[1]
69  */
70 static GLuint hinterlace_mask[33];
71
72 RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
73         :RAS_IRasterizer(canvas),
74         m_2DCanvas(canvas),
75         m_fogenabled(false),
76         m_time(0.0),
77         m_stereomode(RAS_STEREO_NOSTEREO),
78         m_curreye(RAS_STEREO_LEFTEYE),
79         m_eyeseparation(0.0),
80         m_seteyesep(false),
81         m_focallength(0.0),
82         m_setfocallength(false),
83         m_noOfScanlines(32),
84         m_useTang(false),
85         m_materialCachingInfo(0)
86 {
87         m_viewmatrix.Identity();
88         
89         for (int i = 0; i < 32; i++)
90         {
91                 left_eye_vinterlace_mask[i] = 0x55555555;
92                 right_eye_vinterlace_mask[i] = 0xAAAAAAAA;
93                 hinterlace_mask[i] = (i&1)*0xFFFFFFFF;
94         }
95         hinterlace_mask[32] = 0;
96 }
97
98
99
100 RAS_OpenGLRasterizer::~RAS_OpenGLRasterizer()
101 {
102 }
103
104
105
106 static void Myinit_gl_stuff(void)       
107 {
108         float mat_specular[] = { 0.5, 0.5, 0.5, 1.0 };
109         float mat_shininess[] = { 35.0 };
110 /*      float one= 1.0; */
111         int a, x, y;
112         GLubyte pat[32*32];
113         const GLubyte *patc= pat;
114                 
115         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_specular);
116         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
117         glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
118
119
120 #if defined(__FreeBSD) || defined(__linux__)
121         glDisable(GL_DITHER);   /* op sgi/sun hardware && 12 bits */
122 #endif
123         
124         /* no local viewer, looks ugly in ortho mode */
125         /* glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, &one); */
126         
127         glDepthFunc(GL_LEQUAL);
128         /* scaling matrices */
129         glEnable(GL_NORMALIZE);
130
131         glShadeModel(GL_FLAT);
132
133         glDisable(GL_ALPHA_TEST);
134         glDisable(GL_BLEND);
135         glDisable(GL_DEPTH_TEST);
136         glDisable(GL_FOG);
137         glDisable(GL_LIGHTING);
138         glDisable(GL_LOGIC_OP);
139         glDisable(GL_STENCIL_TEST);
140         glDisable(GL_TEXTURE_1D);
141         glDisable(GL_TEXTURE_2D);
142
143         glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
144         glPixelTransferi(GL_RED_SCALE, 1);
145         glPixelTransferi(GL_RED_BIAS, 0);
146         glPixelTransferi(GL_GREEN_SCALE, 1);
147         glPixelTransferi(GL_GREEN_BIAS, 0);
148         glPixelTransferi(GL_BLUE_SCALE, 1);
149         glPixelTransferi(GL_BLUE_BIAS, 0);
150         glPixelTransferi(GL_ALPHA_SCALE, 1);
151         glPixelTransferi(GL_ALPHA_BIAS, 0);
152
153         a = 0;
154         for(x=0; x<32; x++)
155         {
156                 for(y=0; y<4; y++)
157                 {
158                         if( (x) & 1) pat[a++]= 0x88;
159                         else pat[a++]= 0x22;
160                 }
161         }
162         
163         glPolygonStipple(patc);
164         
165         glFrontFace(GL_CCW);
166         glCullFace(GL_BACK);
167         glEnable(GL_CULL_FACE);
168 }
169
170
171
172 bool RAS_OpenGLRasterizer::Init()
173 {
174
175         Myinit_gl_stuff();
176
177         m_redback = 0.4375;
178         m_greenback = 0.4375;
179         m_blueback = 0.4375;
180         m_alphaback = 0.0;
181         
182         m_ambr = 0.0f;
183         m_ambg = 0.0f;
184         m_ambb = 0.0f;
185
186         glClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
187         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
188         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
189
190         glShadeModel(GL_SMOOTH);
191
192         return true;
193 }
194
195
196 void RAS_OpenGLRasterizer::SetAmbientColor(float red, float green, float blue)
197 {
198         m_ambr = red;
199         m_ambg = green;
200         m_ambb = blue;
201 }
202
203
204 void RAS_OpenGLRasterizer::SetAlphaTest(bool enable)
205 {
206         if (enable)
207         {
208                 glEnable(GL_ALPHA_TEST);
209                 glAlphaFunc(GL_GREATER, 0.6f);
210         }
211         else glDisable(GL_ALPHA_TEST);
212 }
213
214
215
216 void RAS_OpenGLRasterizer::SetAmbient(float factor)
217 {
218         float ambient[] = { m_ambr*factor, m_ambg*factor, m_ambb*factor, 1.0f };
219         glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
220 }
221
222
223 void RAS_OpenGLRasterizer::SetBackColor(float red,
224                                                                                 float green,
225                                                                                 float blue,
226                                                                                 float alpha)
227 {
228         m_redback = red;
229         m_greenback = green;
230         m_blueback = blue;
231         m_alphaback = alpha;
232 }
233
234
235
236 void RAS_OpenGLRasterizer::SetFogColor(float r,
237                                                                            float g,
238                                                                            float b)
239 {
240         m_fogr = r;
241         m_fogg = g;
242         m_fogb = b;
243         m_fogenabled = true;
244 }
245
246
247
248 void RAS_OpenGLRasterizer::SetFogStart(float start)
249 {
250         m_fogstart = start;
251         m_fogenabled = true;
252 }
253
254
255
256 void RAS_OpenGLRasterizer::SetFogEnd(float fogend)
257 {
258         m_fogdist = fogend;
259         m_fogenabled = true;
260 }
261
262
263
264 void RAS_OpenGLRasterizer::SetFog(float start,
265                                                                   float dist,
266                                                                   float r,
267                                                                   float g,
268                                                                   float b)
269 {
270         m_fogstart = start;
271         m_fogdist = dist;
272         m_fogr = r;
273         m_fogg = g;
274         m_fogb = b;
275         m_fogenabled = true;
276 }
277
278
279
280 void RAS_OpenGLRasterizer::DisableFog()
281 {
282         m_fogenabled = false;
283 }
284
285
286
287 void RAS_OpenGLRasterizer::DisplayFog()
288 {
289         if ((m_drawingmode >= KX_SOLID) && m_fogenabled)
290         {
291                 float params[5];
292                 glFogi(GL_FOG_MODE, GL_LINEAR);
293                 glFogf(GL_FOG_DENSITY, 0.1f);
294                 glFogf(GL_FOG_START, m_fogstart);
295                 glFogf(GL_FOG_END, m_fogstart + m_fogdist);
296                 params[0]= m_fogr;
297                 params[1]= m_fogg;
298                 params[2]= m_fogb;
299                 params[3]= 0.0;
300                 glFogfv(GL_FOG_COLOR, params); 
301                 glEnable(GL_FOG);
302         } 
303         else
304         {
305                 glDisable(GL_FOG);
306         }
307 }
308
309
310
311 bool RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat)
312 {
313         return mat.Activate(this, m_materialCachingInfo);
314 }
315
316
317
318 void RAS_OpenGLRasterizer::Exit()
319 {
320
321         glEnable(GL_CULL_FACE);
322         glEnable(GL_DEPTH_TEST);
323         glClearDepth(1.0); 
324         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
325         glClearColor(m_redback, m_greenback, m_blueback, m_alphaback);
326         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
327         glDepthMask (GL_TRUE);
328         glDepthFunc(GL_LEQUAL);
329         glBlendFunc(GL_ONE, GL_ZERO);
330         
331         glDisable(GL_POLYGON_STIPPLE);
332         
333         glDisable(GL_LIGHTING);
334         if (bgl::QueryExtension(bgl::_GL_EXT_separate_specular_color) || bgl::QueryVersion(1, 2))
335                 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
336         
337         EndFrame();
338 }
339
340 bool RAS_OpenGLRasterizer::InterlacedStereo() const
341 {
342         return m_stereomode == RAS_STEREO_VINTERLACE || m_stereomode == RAS_STEREO_INTERLACED;
343 }
344
345 bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
346 {
347         m_time = time;
348         m_drawingmode = drawingmode;
349         
350         if (!InterlacedStereo() || m_curreye == RAS_STEREO_LEFTEYE)
351         {
352                 m_2DCanvas->ClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
353                 m_2DCanvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER);
354         }
355
356         // Blender camera routine destroys the settings
357         if (m_drawingmode < KX_SOLID)
358         {
359                 glDisable (GL_CULL_FACE);
360                 glDisable (GL_DEPTH_TEST);
361         }
362         else
363         {
364                 glEnable(GL_DEPTH_TEST);
365                 glEnable (GL_CULL_FACE);
366         }
367
368         glShadeModel(GL_SMOOTH);
369
370         m_2DCanvas->BeginFrame();
371         
372         return true;
373 }
374
375
376
377 void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode)
378 {
379         m_drawingmode = drawingmode;
380
381         switch (m_drawingmode)
382         {
383         case KX_BOUNDINGBOX:
384                 {
385                 }
386         case KX_WIREFRAME:
387                 {
388                         glDisable (GL_CULL_FACE);
389                         break;
390                 }
391         case KX_TEXTURED:
392                 {
393                 }
394         case KX_SHADED:
395                 {
396                 }
397         case KX_SOLID:
398                 {
399                 }
400         default:
401                 {
402                 }
403         }
404 }
405
406
407
408 int RAS_OpenGLRasterizer::GetDrawingMode()
409 {
410         return m_drawingmode;
411 }
412
413
414
415 void RAS_OpenGLRasterizer::SetDepthMask(DepthMask depthmask)
416 {
417         glDepthMask(depthmask == KX_DEPTHMASK_DISABLED ? GL_FALSE : GL_TRUE);
418 }
419
420
421
422 void RAS_OpenGLRasterizer::ClearDepthBuffer()
423 {
424         m_2DCanvas->ClearBuffer(RAS_ICanvas::DEPTH_BUFFER);
425 }
426
427
428 void RAS_OpenGLRasterizer::ClearCachingInfo(void)
429 {
430         m_materialCachingInfo = 0;
431 }
432
433
434 void RAS_OpenGLRasterizer::EndFrame()
435 {
436         glDisable(GL_LIGHTING);
437         glDisable(GL_TEXTURE_2D);
438
439         //DrawDebugLines
440         glBegin(GL_LINES);
441         for (unsigned int i=0;i<m_debugLines.size();i++)
442         {
443                 
444
445                 glColor4f(m_debugLines[i].m_color[0],m_debugLines[i].m_color[1],m_debugLines[i].m_color[2],1.f);
446                 const MT_Scalar* fromPtr = &m_debugLines[i].m_from.x();
447                 const MT_Scalar* toPtr= &m_debugLines[i].m_to.x();
448
449                 glVertex3dv(fromPtr);
450                 glVertex3dv(toPtr);
451         }
452         glEnd();
453
454         m_debugLines.clear();
455
456         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
457         m_2DCanvas->EndFrame();
458 }       
459
460 void RAS_OpenGLRasterizer::SetRenderArea()
461 {
462         // only above/below stereo method needs viewport adjustment
463         switch (m_stereomode)
464         {
465                 case RAS_STEREO_ABOVEBELOW:
466                         switch(m_curreye)
467                         {
468                                 case RAS_STEREO_LEFTEYE:
469                                         // upper half of window
470                                         m_2DCanvas->GetDisplayArea().SetLeft(0);
471                                         m_2DCanvas->GetDisplayArea().SetBottom(m_2DCanvas->GetHeight() -
472                                                 int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
473         
474                                         m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
475                                         m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight()));
476                                         break;
477                                 case RAS_STEREO_RIGHTEYE:
478                                         // lower half of window
479                                         m_2DCanvas->GetDisplayArea().SetLeft(0);
480                                         m_2DCanvas->GetDisplayArea().SetBottom(0);
481                                         m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
482                                         m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
483                                         break;
484                         }
485                         break;
486                 case RAS_STEREO_SIDEBYSIDE:
487                         switch (m_curreye)
488                         {
489                                 case RAS_STEREO_LEFTEYE:
490                                         // Left half of window
491                                         m_2DCanvas->GetDisplayArea().SetLeft(0);
492                                         m_2DCanvas->GetDisplayArea().SetBottom(0);
493                                         m_2DCanvas->GetDisplayArea().SetRight(m_2DCanvas->GetWidth()/2);
494                                         m_2DCanvas->GetDisplayArea().SetTop(m_2DCanvas->GetHeight());
495                                         break;
496                                 case RAS_STEREO_RIGHTEYE:
497                                         // Right half of window
498                                         m_2DCanvas->GetDisplayArea().SetLeft(m_2DCanvas->GetWidth()/2);
499                                         m_2DCanvas->GetDisplayArea().SetBottom(0);
500                                         m_2DCanvas->GetDisplayArea().SetRight(m_2DCanvas->GetWidth());
501                                         m_2DCanvas->GetDisplayArea().SetTop(m_2DCanvas->GetHeight());
502                                         break;
503                         }
504                         break;
505                 default:
506                         // every available pixel
507                         m_2DCanvas->GetDisplayArea().SetLeft(0);
508                         m_2DCanvas->GetDisplayArea().SetBottom(0);
509                         m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
510                         m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight()));
511                         break;
512         }
513 }
514
515         
516 void RAS_OpenGLRasterizer::SetStereoMode(const StereoMode stereomode)
517 {
518         m_stereomode = stereomode;
519 }
520
521
522
523 bool RAS_OpenGLRasterizer::Stereo()
524 {
525         if(m_stereomode == RAS_STEREO_NOSTEREO)
526                 return false;
527         else
528                 return true;
529 }
530
531
532 void RAS_OpenGLRasterizer::SetEye(const StereoEye eye)
533 {
534         m_curreye = eye;
535         switch (m_stereomode)
536         {
537                 case RAS_STEREO_QUADBUFFERED:
538                         glDrawBuffer(m_curreye == RAS_STEREO_LEFTEYE ? GL_BACK_LEFT : GL_BACK_RIGHT);
539                         break;
540                 case RAS_STEREO_ANAGLYPH:
541                         if (m_curreye == RAS_STEREO_LEFTEYE)
542                         {
543                                 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_FALSE);
544                         } else {
545                                 //glAccum(GL_LOAD, 1.0);
546                                 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
547                                 ClearDepthBuffer();
548                         }
549                         break;
550                 case RAS_STEREO_VINTERLACE:
551                 {
552                         glEnable(GL_POLYGON_STIPPLE);
553                         glPolygonStipple((const GLubyte*) ((m_curreye == RAS_STEREO_LEFTEYE) ? left_eye_vinterlace_mask : right_eye_vinterlace_mask));
554                         if (m_curreye == RAS_STEREO_RIGHTEYE)
555                                 ClearDepthBuffer();
556                         break;
557                 }
558                 case RAS_STEREO_INTERLACED:
559                 {
560                         glEnable(GL_POLYGON_STIPPLE);
561                         glPolygonStipple((const GLubyte*) &hinterlace_mask[m_curreye == RAS_STEREO_LEFTEYE?0:1]);
562                         if (m_curreye == RAS_STEREO_RIGHTEYE)
563                                 ClearDepthBuffer();
564                         break;
565                 }
566                 default:
567                         break;
568         }
569 }
570
571 RAS_IRasterizer::StereoEye RAS_OpenGLRasterizer::GetEye()
572 {
573         return m_curreye;
574 }
575
576
577 void RAS_OpenGLRasterizer::SetEyeSeparation(const float eyeseparation)
578 {
579         m_eyeseparation = eyeseparation;
580         m_seteyesep = true;
581 }
582
583 float RAS_OpenGLRasterizer::GetEyeSeparation()
584 {
585         return m_eyeseparation;
586 }
587
588 void RAS_OpenGLRasterizer::SetFocalLength(const float focallength)
589 {
590         m_focallength = focallength;
591         m_setfocallength = true;
592 }
593
594 float RAS_OpenGLRasterizer::GetFocalLength()
595 {
596         return m_focallength;
597 }
598
599
600 void RAS_OpenGLRasterizer::SwapBuffers()
601 {
602         m_2DCanvas->SwapBuffers();
603 }
604
605
606
607 void RAS_OpenGLRasterizer::GetViewMatrix(MT_Matrix4x4 &mat) const
608 {
609         float viewmat[16];
610         glGetFloatv(GL_MODELVIEW_MATRIX, viewmat);
611         mat.setValue(viewmat);
612 }
613
614
615
616 void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays,
617                                                                         const vecIndexArrays & indexarrays,
618                                                                         int mode,
619                                                                         class RAS_IPolyMaterial* polymat,
620                                                                         class RAS_IRenderTools* rendertools,
621                                                                         bool useObjectColor,
622                                                                         const MT_Vector4& rgbacolor,
623                                                                         class KX_ListSlot** slot
624                                                                         )
625
626         GLenum drawmode;
627         switch (mode)
628         {
629         case 0:
630                 drawmode = GL_TRIANGLES;
631                 break;
632         case 1:
633                 drawmode = GL_LINES;
634                 break;
635         case 2:
636                 drawmode = GL_QUADS;
637                 break;
638         default:
639                 drawmode = GL_LINES;
640                 break;
641         }
642         
643         const RAS_TexVert* vertexarray ;
644         unsigned int numindices,vt;
645
646         for (vt=0;vt<vertexarrays.size();vt++)
647         {
648                 vertexarray = &((*vertexarrays[vt]) [0]);
649                 const KX_IndexArray & indexarray = (*indexarrays[vt]);
650                 numindices = indexarray.size();
651                 
652                 if (!numindices)
653                         break;
654                 
655                 int vindex=0;
656                 switch (mode)
657                 {
658                 case 1:
659                         {
660                                 glBegin(GL_LINES);
661                                 vindex=0;
662                                 for (unsigned int i=0;i<numindices;i+=2)
663                                 {
664                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
665                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
666                                 }
667                                 glEnd();
668                         }
669                         break;
670                 case 2:
671                         {
672                                 glBegin(GL_QUADS);
673                                 vindex=0;
674                                 if (useObjectColor)
675                                 {
676                                         for (unsigned int i=0;i<numindices;i+=4)
677                                         {
678
679                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
680
681                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
682                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
683                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
684                                                 vindex++;
685                                                 
686                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
687                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
688                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
689                                                 vindex++;
690                                                 
691                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
692                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
693                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
694                                                 vindex++;
695                                                 
696                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
697                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
698                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
699                                                 vindex++;
700                                         }
701                                 }
702                                 else
703                                 {
704                                         for (unsigned int i=0;i<numindices;i+=4)
705                                         {
706                                                 // This looks curiously endian unsafe to me.
707                                                 // However it depends on the way the colors are packed into 
708                                                 // the m_rgba field of RAS_TexVert
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                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
723                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
724                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
725                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
726                                                 vindex++;
727                                                 
728                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
729                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
730                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
731                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
732                                                 vindex++;
733                                         }
734                                 }
735                                 glEnd();        
736                                 break;
737                         }
738                 case 0:
739                         {
740                                 glBegin(GL_TRIANGLES);
741                                 vindex=0;
742                                 if (useObjectColor)
743                                 {
744                                         for (unsigned int i=0;i<numindices;i+=3)
745                                         {
746
747                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
748
749                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
750                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
751                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
752                                                 vindex++;
753                                                 
754                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
755                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
756                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
757                                                 vindex++;
758                                                 
759                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
760                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
761                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
762                                                 vindex++;
763                                         }
764                                 }
765                                 else 
766                                 {
767                                         for (unsigned int i=0;i<numindices;i+=3)
768                                         {
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                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
777                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
778                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
779                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
780                                                 vindex++;
781                                                 
782                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
783                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
784                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
785                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
786                                                 vindex++;
787                                         }
788                                 }
789                                 glEnd();        
790                                 break;
791                         }
792                 default:
793                         {
794                         }
795                         
796                 } // switch
797         } // for each vertexarray
798
799 }
800
801 void RAS_OpenGLRasterizer::IndexPrimitives_Ex(const vecVertexArray & vertexarrays,
802                                                                         const vecIndexArrays & indexarrays,
803                                                                         int mode,
804                                                                         class RAS_IPolyMaterial* polymat,
805                                                                         class RAS_IRenderTools* rendertools,
806                                                                         bool useObjectColor,
807                                                                         const MT_Vector4& rgbacolor
808                                                                         )
809
810         bool    recalc;
811         GLenum drawmode;
812         switch (mode)
813         {
814         case 0:
815                 drawmode = GL_TRIANGLES;
816                 break;
817         case 1:
818                 drawmode = GL_LINES;
819                 break;
820         case 2:
821                 drawmode = GL_QUADS;
822                 break;
823         default:
824                 drawmode = GL_LINES;
825                 break;
826         }
827         
828         const RAS_TexVert* vertexarray ;
829         unsigned int numindices,vt;
830
831         for (vt=0;vt<vertexarrays.size();vt++)
832         {
833                 vertexarray = &((*vertexarrays[vt]) [0]);
834                 const KX_IndexArray & indexarray = (*indexarrays[vt]);
835                 numindices = indexarray.size();
836                 
837                 if (!numindices)
838                         continue;
839                 
840                 int vindex=0;
841                 switch (mode)
842                 {
843                 case 1:
844                         {
845                                 glBegin(GL_LINES);
846                                 vindex=0;
847                                 for (unsigned int i=0;i<numindices;i+=2)
848                                 {
849                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
850                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
851                                 }
852                                 glEnd();
853                         }
854                         break;
855                 case 2:
856                         {
857                                 glBegin(GL_QUADS);
858                                 vindex=0;
859                                 if (useObjectColor)
860                                 {
861                                         for (unsigned int i=0;i<numindices;i+=4)
862                                         {
863                                                 MT_Point3 mv1, mv2, mv3, mv4, fnor;
864                                                 /* Calc a new face normal */
865
866                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
867                                                         recalc= true;
868                                                 else
869                                                         recalc=false;
870
871                                                 if (recalc){
872                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
873                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
874                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
875                                                         mv4 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
876                                                         
877                                                         fnor = (((mv2-mv1).cross(mv3-mv2))+((mv4-mv3).cross(mv1-mv4))).safe_normalized();
878
879                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
880                                                 }
881
882                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
883
884                                                 if (!recalc)
885                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
886                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
887                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
888                                                 vindex++;
889                                                 
890                                                 if (!recalc)
891                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
892                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
893                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
894                                                 vindex++;
895                                                 
896                                                 if (!recalc)
897                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());                                             
898                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
899                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
900                                                 vindex++;
901                                                 
902                                                 if (!recalc)
903                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
904                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
905                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
906                                                 vindex++;
907                                         }
908                                 }
909                                 else
910                                 {
911                                         for (unsigned int i=0;i<numindices;i+=4)
912                                         {
913                                                 // This looks curiously endian unsafe to me.
914                                                 // However it depends on the way the colors are packed into 
915                                                 // the m_rgba field of RAS_TexVert
916                                                 MT_Point3 mv1, mv2, mv3, mv4, fnor;
917                                                 /* Calc a new face normal */
918
919                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
920                                                         recalc= true;
921                                                 else
922                                                         recalc=false;
923
924
925                                                 if (recalc){
926                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
927                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
928                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
929                                                         mv4 = MT_Point3(vertexarray[(indexarray[vindex+3])].getLocalXYZ());
930                                                         
931                                                         fnor = (((mv2-mv1).cross(mv3-mv2))+((mv4-mv3).cross(mv1-mv4))).safe_normalized();
932
933                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
934                                                 }
935
936                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
937                                                 if (!recalc)
938                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
939                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
940                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
941                                                 vindex++;
942                                                 
943                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
944                                                 if (!recalc)
945                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
946                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
947                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
948                                                 vindex++;
949                                                 
950                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
951                                                 if (!recalc)
952                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
953                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
954                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
955                                                 vindex++;
956                                                 
957                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
958                                                 if (!recalc)
959                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
960                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
961                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
962                                                 vindex++;
963                                         }
964                                 }
965                                 glEnd();        
966                                 break;
967                         }
968                 case 0:
969                         {
970                                 glBegin(GL_TRIANGLES);
971                                 vindex=0;
972                                 if (useObjectColor)
973                                 {
974                                         for (unsigned int i=0;i<numindices;i+=3)
975                                         {
976                                                 MT_Point3 mv1, mv2, mv3, fnor;
977                                                 /* Calc a new face normal */
978
979                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
980                                                         recalc= true;
981                                                 else
982                                                         recalc=false;
983
984                                                 if (recalc){
985                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
986                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
987                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
988                                                         
989                                                         fnor = ((mv2-mv1).cross(mv3-mv2)).safe_normalized();
990                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
991                                                 }
992
993                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
994
995                                                 if (!recalc)
996                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
997                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
998                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
999                                                 vindex++;
1000                                                 
1001                                                 if (!recalc)
1002                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1003                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
1004                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1005                                                 vindex++;
1006                                                 
1007                                                 if (!recalc)
1008                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1009                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
1010                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1011                                                 vindex++;
1012                                         }
1013                                 }
1014                                 else 
1015                                 {
1016                                         for (unsigned int i=0;i<numindices;i+=3)
1017                                         {
1018                                                 MT_Point3 mv1, mv2, mv3, fnor;
1019                                                 /* Calc a new face normal */
1020
1021                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
1022                                                         recalc= true;
1023                                                 else
1024                                                         recalc=false;
1025
1026
1027                                                 if (recalc){
1028                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
1029                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
1030                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
1031                                                         
1032                                                         fnor = ((mv2-mv1).cross(mv3-mv2)).safe_normalized();
1033                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
1034                                                 }
1035
1036                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1037                                                 if (!recalc)
1038                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1039                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
1040                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1041                                                 vindex++;
1042                                                 
1043                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1044                                                 if (!recalc)
1045                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1046                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
1047                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1048                                                 vindex++;
1049                                                 
1050                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1051                                                 if (!recalc)
1052                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1053                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
1054                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1055                                                 vindex++;
1056                                         }
1057                                 }
1058                                 glEnd();        
1059                                 break;
1060                         }
1061                 default:
1062                         {
1063                         }
1064                         
1065                 } // switch
1066         } // for each vertexarray
1067
1068 }
1069
1070
1071
1072 void RAS_OpenGLRasterizer::IndexPrimitives_3DText(const vecVertexArray & vertexarrays,
1073                                                                         const vecIndexArrays & indexarrays,
1074                                                                         int mode,
1075                                                                         class RAS_IPolyMaterial* polymat,
1076                                                                         class RAS_IRenderTools* rendertools,
1077                                                                         bool useObjectColor,
1078                                                                         const MT_Vector4& rgbacolor
1079                                                                         )
1080
1081         GLenum drawmode;
1082         switch (mode)
1083         {
1084         case 0:
1085                 drawmode = GL_TRIANGLES;
1086                 break;
1087         case 1:
1088                 drawmode = GL_LINES;
1089                 break;
1090         case 2:
1091                 drawmode = GL_QUADS;
1092                 break;
1093         default:
1094                 drawmode = GL_LINES;
1095                 break;
1096         }
1097         
1098         const RAS_TexVert* vertexarray ;
1099         
1100         unsigned int numindices, vt;
1101         
1102         if (useObjectColor)
1103         {
1104                 glDisableClientState(GL_COLOR_ARRAY);
1105                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
1106         }
1107         else
1108         {
1109                 glEnableClientState(GL_COLOR_ARRAY);
1110         }
1111         
1112         for (vt=0;vt<vertexarrays.size();vt++)
1113         {
1114                 vertexarray = &((*vertexarrays[vt]) [0]);
1115                 const KX_IndexArray & indexarray = (*indexarrays[vt]);
1116                 numindices = indexarray.size();
1117                 
1118                 if (!numindices)
1119                         break;
1120                 
1121                 int vindex=0;
1122                 switch (mode)
1123                 {
1124                 case 1:
1125                         {
1126                                 glBegin(GL_LINES);
1127                                 vindex=0;
1128                                 for (unsigned int i=0;i<numindices;i+=2)
1129                                 {
1130                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
1131                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
1132                                 }
1133                                 glEnd();
1134                         }
1135                         break;
1136                 case 2:
1137                         {
1138                                 vindex=0;
1139                                 for (unsigned int i=0;i<numindices;i+=4)
1140                                 {
1141                                         float v1[3],v2[3],v3[3],v4[3];
1142                                         
1143                                         v1[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1144                                         v1[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1145                                         v1[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1146                                         vindex++;
1147                                         
1148                                         v2[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1149                                         v2[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1150                                         v2[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1151                                         vindex++;
1152                                         
1153                                         v3[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1154                                         v3[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1155                                         v3[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1156                                         vindex++;
1157                                         
1158                                         v4[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1159                                         v4[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1160                                         v4[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1161                                         
1162                                         vindex++;
1163                                         
1164                                         rendertools->RenderText(polymat->GetDrawingMode(),polymat,v1,v2,v3,v4);
1165                                         ClearCachingInfo();
1166                                 }
1167                                 break;
1168                         }
1169                 case 0:
1170                         {
1171                                 glBegin(GL_TRIANGLES);
1172                                 vindex=0;
1173                                 for (unsigned int i=0;i<numindices;i+=3)
1174                                 {
1175                                         float v1[3],v2[3],v3[3];
1176                                         
1177                                         v1[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1178                                         v1[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1179                                         v1[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1180                                         vindex++;
1181                                         
1182                                         v2[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1183                                         v2[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1184                                         v2[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1185                                         vindex++;
1186                                         
1187                                         v3[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1188                                         v3[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1189                                         v3[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1190                                         vindex++;
1191                                         
1192                                         rendertools->RenderText(polymat->GetDrawingMode(),polymat,v1,v2,v3,NULL);               
1193                                         ClearCachingInfo();
1194                                 }
1195                                 glEnd();        
1196                                 break;
1197                         }
1198                 default:
1199                         {
1200                         }
1201                 }       //switch
1202         }       //for each vertexarray
1203 }
1204
1205 void RAS_OpenGLRasterizer::SetTexCoords(TexCoGen coords,int unit)
1206 {
1207         // this changes from material to material
1208         if(unit < RAS_MAX)
1209                 m_texco[unit] = coords;
1210 }
1211
1212 void RAS_OpenGLRasterizer::SetAttrib(int type)
1213 {
1214         if(type == RAS_TEXTANGENT) m_useTang=true;
1215 }
1216
1217 void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv, int enabled)
1218 {
1219 #ifdef GL_ARB_multitexture
1220         if(bgl::RAS_EXT_support._ARB_multitexture)
1221         {
1222                 for(int unit=0; unit<enabled; unit++)
1223                 {
1224                         if( tv.getFlag() & TV_2NDUV && tv.getUnit() == unit ) {
1225                                 bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
1226                                 continue;
1227                         }
1228                         switch(m_texco[unit])
1229                         {
1230                         case RAS_TEXCO_DISABLE:
1231                         case RAS_TEXCO_OBJECT:
1232                         case RAS_TEXCO_GEN:
1233                                 break;
1234                         case RAS_TEXCO_ORCO:
1235                         case RAS_TEXCO_GLOB:
1236                                 bgl::blMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getLocalXYZ());
1237                                 break;
1238                         case RAS_TEXCO_UV1:
1239                                 bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV1());
1240                                 break;
1241                         case RAS_TEXCO_NORM:
1242                                 bgl::blMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getNormal());
1243                                 break;
1244                         case RAS_TEXTANGENT:
1245                                 bgl::blMultiTexCoord4fvARB(GL_TEXTURE0_ARB+unit, tv.getTangent());
1246                                 break;
1247                         case RAS_TEXCO_UV2:
1248                                 bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
1249                                 break;
1250                         }
1251                 }
1252         }
1253 #endif
1254
1255 #ifdef GL_ARB_vertex_program
1256         if(m_useTang && bgl::RAS_EXT_support._ARB_vertex_program)
1257                 bgl::blVertexAttrib4fvARB(1/*tangent*/, tv.getTangent());
1258 #endif
1259
1260 }
1261 void RAS_OpenGLRasterizer::Tangent(     const RAS_TexVert& v1,
1262                                                                         const RAS_TexVert& v2,
1263                                                                         const RAS_TexVert& v3,
1264                                                                         const MT_Vector3 &no)
1265 {
1266 #ifdef GL_ARB_multitexture
1267         // TODO: set for deformer... 
1268         MT_Vector3 x1(v1.getLocalXYZ()), x2(v2.getLocalXYZ()), x3(v3.getLocalXYZ());
1269         MT_Vector2 uv1(v1.getUV1()), uv2(v2.getUV1()), uv3(v3.getUV1());
1270         MT_Vector3 dx1(x2 - x1), dx2(x3 - x1);
1271         MT_Vector2 duv1(uv2 - uv1), duv2(uv3 - uv1);
1272         
1273         MT_Scalar r = 1.0 / (duv1.x() * duv2.y() - duv2.x() * duv1.y());
1274         duv1 *= r;
1275         duv2 *= r;
1276         MT_Vector3 sdir(duv2.y() * dx1 - duv1.y() * dx2);
1277         MT_Vector3 tdir(duv1.x() * dx2 - duv2.x() * dx1);
1278         
1279         // Gram-Schmidt orthogonalize
1280         MT_Vector3 t(sdir - no.cross(no.cross(sdir)));
1281         if (!MT_fuzzyZero(t))
1282                 t /= t.length();
1283
1284         float tangent[4];
1285         t.getValue(tangent);
1286         // Calculate handedness
1287         tangent[3] = no.dot(sdir.cross(tdir)) < 0.0 ? -1.0 : 1.0;
1288 #endif
1289 }
1290
1291
1292 void RAS_OpenGLRasterizer::IndexPrimitivesMulti(
1293                 const vecVertexArray& vertexarrays,
1294                 const vecIndexArrays & indexarrays,
1295                 int mode,
1296                 class RAS_IPolyMaterial* polymat,
1297                 class RAS_IRenderTools* rendertools,
1298                 bool useObjectColor,
1299                 const MT_Vector4& rgbacolor,
1300                 class KX_ListSlot** slot
1301                 )
1302
1303 #ifdef GL_ARB_multitexture
1304
1305         GLenum drawmode;
1306         switch (mode)
1307         {
1308         case 0:
1309                 drawmode = GL_TRIANGLES;
1310                 break;
1311         case 1:
1312                 drawmode = GL_LINES;
1313                 break;
1314         case 2:
1315                 drawmode = GL_QUADS;
1316                 break;
1317         default:
1318                 drawmode = GL_LINES;
1319                 break;
1320         }
1321         
1322         const RAS_TexVert* vertexarray ;
1323         unsigned int numindices,vt;
1324
1325         for (vt=0;vt<vertexarrays.size();vt++)
1326         {
1327                 vertexarray = &((*vertexarrays[vt]) [0]);
1328                 const KX_IndexArray & indexarray = (*indexarrays[vt]);
1329                 numindices = indexarray.size();
1330                 const unsigned int enabled = polymat->GetEnabled();
1331
1332                 if (!numindices)
1333                         break;
1334                 
1335                 int vindex=0;
1336                 switch (mode)
1337                 {
1338                 case 1:
1339                         {
1340                                 glBegin(GL_LINES);
1341                                 vindex=0;
1342                                 for (unsigned int i=0;i<numindices;i+=2)
1343                                 {
1344                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
1345                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
1346                                 }
1347                                 glEnd();
1348                         }
1349                         break;
1350                 case 2:
1351                         {
1352                                 glBegin(GL_QUADS);
1353                                 vindex=0;
1354                                 if (useObjectColor)
1355                                 {
1356                                         for (unsigned int i=0;i<numindices;i+=4)
1357                                         {
1358
1359                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
1360                                                 
1361                                                 //
1362                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1363                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1364                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1365                                                 vindex++;
1366                                                 
1367                                                 //
1368                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1369                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1370                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1371                                                 vindex++;
1372                                                 
1373                                                 //
1374                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1375                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1376                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1377                                                 vindex++;
1378                                                 
1379                                                 //
1380                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1381                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1382                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1383                                                 vindex++;
1384                                         }
1385                                 }
1386                                 else
1387                                 {
1388                                         for (unsigned int i=0;i<numindices;i+=4)
1389                                         {
1390                                                 // This looks curiously endian unsafe to me.
1391                                                 // However it depends on the way the colors are packed into 
1392                                                 // the m_rgba field of RAS_TexVert
1393                                                 
1394                                                 //
1395                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1396                                         
1397                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1398                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1399                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1400                                                 vindex++;
1401                                                 
1402                                                 //
1403                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1404                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1405                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1406                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1407                                                 vindex++;
1408                                                 
1409                                                 //
1410                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1411                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1412                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1413                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1414                                                 vindex++;
1415                                                 
1416                                                 //
1417                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1418                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1419                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1420                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1421                                                 vindex++;
1422                                         }
1423                                 }
1424                                 glEnd();        
1425                                 break;
1426                         }
1427                 case 0:
1428                         {
1429                                 glBegin(GL_TRIANGLES);
1430                                 vindex=0;
1431                                 if (useObjectColor)
1432                                 {
1433                                         for (unsigned int i=0;i<numindices;i+=3)
1434                                         {
1435
1436                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
1437                                                 //
1438                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1439                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1440                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1441                                                 vindex++;
1442                                                 
1443                                                 //
1444                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1445                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1446                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1447                                                 vindex++;
1448                                                 
1449                                                 //
1450                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1451                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1452                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1453                                                 vindex++;
1454                                         }
1455                                 }
1456                                 else 
1457                                 {
1458                                         for (unsigned int i=0;i<numindices;i+=3)
1459                                         {
1460                                                 //
1461                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1462                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1463                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1464                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1465                                                 vindex++;
1466                                                 
1467                                                 //
1468                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1469                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1470                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1471                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1472                                                 vindex++;
1473                                                 
1474                                                 //
1475                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1476                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1477                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1478                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1479                                                 vindex++;
1480                                         }
1481                                 }
1482                                 glEnd();        
1483                                 break;
1484                         }
1485                 default:
1486                         {
1487                         }
1488                 } // switch
1489         } // for each vertexarray
1490 #endif// GL_ARB_multitexture
1491
1492 }
1493
1494 void RAS_OpenGLRasterizer::IndexPrimitivesMulti_Ex(
1495                                                                         const vecVertexArray & vertexarrays,
1496                                                                         const vecIndexArrays & indexarrays,
1497                                                                         int mode,
1498                                                                         class RAS_IPolyMaterial* polymat,
1499                                                                         class RAS_IRenderTools* rendertools,
1500                                                                         bool useObjectColor,
1501                                                                         const MT_Vector4& rgbacolor)
1502
1503 #ifdef GL_ARB_multitexture
1504         bool    recalc;
1505         GLenum drawmode;
1506         switch (mode)
1507         {
1508         case 0:
1509                 drawmode = GL_TRIANGLES;
1510                 break;
1511         case 1:
1512                 drawmode = GL_LINES;
1513                 break;
1514         case 2:
1515                 drawmode = GL_QUADS;
1516                 break;
1517         default:
1518                 drawmode = GL_LINES;
1519                 break;
1520         }
1521         
1522         const RAS_TexVert* vertexarray ;
1523         unsigned int numindices,vt;
1524
1525         for (vt=0;vt<vertexarrays.size();vt++)
1526         {
1527                 vertexarray = &((*vertexarrays[vt]) [0]);
1528                 const KX_IndexArray & indexarray = (*indexarrays[vt]);
1529                 numindices = indexarray.size();
1530                 const unsigned int enabled = polymat->GetEnabled();
1531                 
1532                 if (!numindices)
1533                         continue;
1534                 
1535                 int vindex=0;
1536                 switch (mode)
1537                 {
1538                 case 1:
1539                         {
1540                                 glBegin(GL_LINES);
1541                                 vindex=0;
1542                                 for (unsigned int i=0;i<numindices;i+=2)
1543                                 {
1544                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
1545                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
1546                                 }
1547                                 glEnd();
1548                         }
1549                         break;
1550                 case 2:
1551                         {
1552                                 glBegin(GL_QUADS);
1553                                 vindex=0;
1554                                 if (useObjectColor)
1555                                 {
1556                                         for (unsigned int i=0;i<numindices;i+=4)
1557                                         {
1558                                                 MT_Point3 mv1, mv2, mv3, mv4, fnor;
1559                                                 /* Calc a new face normal */
1560
1561                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
1562                                                         recalc= true;
1563                                                 else
1564                                                         recalc=false;
1565
1566                                                 if (recalc){
1567                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
1568                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
1569                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
1570                                                         mv4 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
1571                                                         
1572                                                         fnor = (((mv2-mv1).cross(mv3-mv2))+((mv4-mv3).cross(mv1-mv4))).safe_normalized();
1573
1574                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
1575                                                 }
1576
1577                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
1578
1579                                                 if (!recalc)
1580                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1581                                         
1582                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1583                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1584                                                 vindex++;
1585                                                 
1586                                                 if (!recalc)
1587                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1588                                         
1589                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1590                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1591                                                 vindex++;
1592                                                 
1593                                                 if (!recalc)
1594                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());                                             
1595                                         
1596                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1597                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1598                                                 vindex++;
1599                                                 
1600                                                 if (!recalc)
1601                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1602                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1603                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1604                                                 vindex++;
1605                                         }
1606                                 }
1607                                 else
1608                                 {
1609                                         for (unsigned int i=0;i<numindices;i+=4)
1610                                         {
1611                                                 // This looks curiously endian unsafe to me.
1612                                                 // However it depends on the way the colors are packed into 
1613                                                 // the m_rgba field of RAS_TexVert
1614                                                 MT_Point3 mv1, mv2, mv3, mv4, fnor;
1615                                                 /* Calc a new face normal */
1616
1617                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
1618                                                         recalc= true;
1619                                                 else
1620                                                         recalc=false;
1621
1622
1623                                                 if (recalc){
1624                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
1625                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
1626                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
1627                                                         mv4 = MT_Point3(vertexarray[(indexarray[vindex+3])].getLocalXYZ());
1628                                                         
1629                                                         fnor = (((mv2-mv1).cross(mv3-mv2))+((mv4-mv3).cross(mv1-mv4))).safe_normalized();
1630
1631                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
1632                                                 }
1633
1634                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1635                                                 if (!recalc)
1636                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1637                                         
1638                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1639                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1640                                                 vindex++;
1641                                                 
1642                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1643                                                 if (!recalc)
1644                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1645                                         
1646                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1647                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1648                                                 vindex++;
1649                                                 
1650                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1651                                                 if (!recalc)
1652                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1653                                         
1654                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1655                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1656                                                 vindex++;
1657                                                 
1658                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1659                                                 if (!recalc)
1660                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1661
1662                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1663                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1664                                                 vindex++;
1665                                         }
1666                                 }
1667                                 glEnd();        
1668                                 break;
1669                         }
1670                 case 0:
1671                         {
1672                                 glBegin(GL_TRIANGLES);
1673                                 vindex=0;
1674                                 if (useObjectColor)
1675                                 {
1676                                         for (unsigned int i=0;i<numindices;i+=3)
1677                                         {
1678                                                 MT_Point3 mv1, mv2, mv3, fnor;
1679                                                 /* Calc a new face normal */
1680
1681                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
1682                                                         recalc= true;
1683                                                 else
1684                                                         recalc=false;
1685
1686                                                 if (recalc){
1687                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
1688                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
1689                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
1690                                                         
1691                                                         fnor = ((mv2-mv1).cross(mv3-mv2)).safe_normalized();
1692                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
1693                                                 }
1694
1695                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
1696
1697                                                 if (!recalc)
1698                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1699                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1700                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1701                                                 vindex++;
1702                                                 
1703                                                 if (!recalc)
1704                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1705                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1706                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1707                                                 vindex++;
1708                                                 
1709                                                 if (!recalc)
1710                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1711                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1712                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1713                                                 vindex++;
1714                                         }
1715                                 }
1716                                 else 
1717                                 {
1718                                         for (unsigned int i=0;i<numindices;i+=3)
1719                                         {
1720                                                 MT_Point3 mv1, mv2, mv3, fnor;
1721                                                 /* Calc a new face normal */
1722
1723                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
1724                                                         recalc= true;
1725                                                 else
1726                                                         recalc=false;
1727
1728
1729                                                 if (recalc){
1730                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
1731                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
1732                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
1733                                                         
1734                                                         fnor = ((mv2-mv1).cross(mv3-mv2)).safe_normalized();
1735                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
1736                                                 }
1737
1738                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1739                                                 if (!recalc)
1740                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1741                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1742                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1743                                                 vindex++;
1744                                                 
1745                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1746                                                 if (!recalc)
1747                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1748                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1749                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1750                                                 vindex++;
1751                                                 
1752                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1753                                                 if (!recalc)
1754                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1755                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1756                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1757                                                 vindex++;
1758                                         }
1759                                 }
1760                                 glEnd();        
1761                                 break;
1762                         }
1763                 default:
1764                         {
1765                         }
1766                         
1767                 } // switch
1768         } // for each vertexarray
1769 #endif
1770 }
1771
1772
1773
1774 void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat)
1775 {
1776         glMatrixMode(GL_PROJECTION);
1777         double* matrix = &mat(0,0);
1778         glLoadMatrixd(matrix);
1779 }
1780
1781
1782 void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat)
1783 {
1784         glMatrixMode(GL_PROJECTION);
1785         double matrix[16];
1786         /* Get into argument. Looks a bit dodgy, but it's ok. */
1787         mat.getValue(matrix);
1788         /* Internally, MT_Matrix4x4 uses doubles (MT_Scalar). */
1789         glLoadMatrixd(matrix);  
1790 }
1791
1792 MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
1793         float left,
1794         float right,
1795         float bottom,
1796         float top,
1797         float frustnear,
1798         float frustfar,
1799         bool
1800 ){
1801         MT_Matrix4x4 result;
1802         double mat[16];
1803
1804         // correction for stereo
1805         if(m_stereomode != RAS_STEREO_NOSTEREO)
1806         {
1807                         float near_div_focallength;
1808                         // next 2 params should be specified on command line and in Blender publisher
1809                         if (!m_setfocallength)
1810                                 m_focallength = 1.5 * right;  // derived from example
1811                         if (!m_seteyesep)
1812                                 m_eyeseparation = 0.18 * right;  // just a guess...
1813
1814                         near_div_focallength = frustnear / m_focallength;
1815                         switch(m_curreye)
1816                         {
1817                                 case RAS_STEREO_LEFTEYE:
1818                                                 left += 0.5 * m_eyeseparation * near_div_focallength;
1819                                                 right += 0.5 * m_eyeseparation * near_div_focallength;
1820                                                 break;
1821                                 case RAS_STEREO_RIGHTEYE:
1822                                                 left -= 0.5 * m_eyeseparation * near_div_focallength;
1823                                                 right -= 0.5 * m_eyeseparation * near_div_focallength;
1824                                                 break;
1825                         }
1826                         // leave bottom, top, bottom and top untouched
1827         }
1828         
1829         glMatrixMode(GL_PROJECTION);
1830         glLoadIdentity();
1831         glFrustum(left, right, bottom, top, frustnear, frustfar);
1832                 
1833         glGetDoublev(GL_PROJECTION_MATRIX, mat);
1834         result.setValue(mat);
1835
1836         return result;
1837 }
1838
1839
1840 // next arguments probably contain redundant info, for later...
1841 void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, const MT_Vector3& campos,
1842                 const MT_Point3 &, const MT_Quaternion &camOrientQuat)
1843 {
1844         MT_Matrix4x4 viewMat = mat;
1845
1846         // correction for stereo
1847         if(m_stereomode != RAS_STEREO_NOSTEREO)
1848         {
1849                 MT_Matrix3x3 camOrientMat3x3(camOrientQuat);
1850                 MT_Vector3 unitViewDir(0.0, -1.0, 0.0);  // minus y direction, Blender convention
1851                 MT_Vector3 unitViewupVec(0.0, 0.0, 1.0);
1852                 MT_Vector3 viewDir, viewupVec;
1853                 MT_Vector3 eyeline;
1854
1855                 // actual viewDir
1856                 viewDir = camOrientMat3x3 * unitViewDir;  // this is the moto convention, vector on right hand side
1857                 // actual viewup vec
1858                 viewupVec = camOrientMat3x3 * unitViewupVec;
1859
1860                 // vector between eyes
1861                 eyeline = viewDir.cross(viewupVec);
1862
1863                 switch(m_curreye)
1864                 {
1865                         case RAS_STEREO_LEFTEYE:
1866                                 {
1867                                 // translate to left by half the eye distance
1868                                 MT_Transform transform;
1869                                 transform.setIdentity();
1870                                 transform.translate(-(eyeline * m_eyeseparation / 2.0));
1871                                 viewMat *= transform;
1872                                 }
1873                                 break;
1874                         case RAS_STEREO_RIGHTEYE:
1875                                 {
1876                                 // translate to right by half the eye distance
1877                                 MT_Transform transform;
1878                                 transform.setIdentity();
1879                                 transform.translate(eyeline * m_eyeseparation / 2.0);
1880                                 viewMat *= transform;
1881                                 }
1882                                 break;
1883                 }
1884         }
1885
1886         // convert row major matrix 'viewMat' to column major for OpenGL
1887         MT_Scalar cammat[16];
1888         viewMat.getValue(cammat);
1889         MT_CmMatrix4x4 viewCmmat = cammat;
1890
1891         glMatrixMode(GL_MODELVIEW);
1892         m_viewmatrix = viewCmmat;
1893         glLoadMatrixd(&m_viewmatrix(0,0));
1894         m_campos = campos;
1895 }
1896
1897
1898 const MT_Point3& RAS_OpenGLRasterizer::GetCameraPosition()
1899 {
1900         return m_campos;
1901 }
1902
1903
1904
1905 void RAS_OpenGLRasterizer::LoadViewMatrix()
1906 {
1907         glLoadMatrixd(&m_viewmatrix(0,0));
1908 }
1909
1910
1911
1912 void RAS_OpenGLRasterizer::EnableTextures(bool enable)
1913 {
1914 }
1915
1916
1917
1918 void RAS_OpenGLRasterizer::SetCullFace(bool enable)
1919 {
1920         if (enable)
1921                 glEnable(GL_CULL_FACE);
1922         else
1923                 glDisable(GL_CULL_FACE);
1924 }
1925
1926 void RAS_OpenGLRasterizer::SetLines(bool enable)
1927 {
1928         if (enable)
1929                 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1930         else
1931                 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1932 }
1933
1934 void RAS_OpenGLRasterizer::SetSpecularity(float specX,
1935                                                                                   float specY,
1936                                                                                   float specZ,
1937                                                                                   float specval)
1938 {
1939         GLfloat mat_specular[] = {specX, specY, specZ, specval};
1940         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
1941 }
1942
1943
1944
1945 void RAS_OpenGLRasterizer::SetShinyness(float shiny)
1946 {
1947         GLfloat mat_shininess[] = {     shiny };
1948         glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
1949 }
1950
1951
1952
1953 void RAS_OpenGLRasterizer::SetDiffuse(float difX,float difY,float difZ,float diffuse)
1954 {
1955         GLfloat mat_diffuse [] = {difX, difY,difZ, diffuse};
1956         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
1957 }
1958
1959 void RAS_OpenGLRasterizer::SetEmissive(float eX, float eY, float eZ, float e)
1960 {
1961         GLfloat mat_emit [] = {eX,eY,eZ,e};
1962         glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_emit);
1963 }
1964
1965
1966 double RAS_OpenGLRasterizer::GetTime()
1967 {
1968         return m_time;
1969 }
1970
1971 void RAS_OpenGLRasterizer::SetPolygonOffset(float mult, float add)
1972 {
1973         glPolygonOffset(mult, add);
1974         GLint mode = GL_POLYGON_OFFSET_FILL;
1975         if (m_drawingmode < KX_SHADED)
1976                 mode = GL_POLYGON_OFFSET_LINE;
1977         if (mult != 0.0f || add != 0.0f)
1978                 glEnable(mode);
1979         else
1980                 glDisable(mode);
1981 }