Patch by VladimĂ­r Marek (neuron), part of bugfix #5298
[blender.git] / source / gameengine / Rasterizer / RAS_OpenGLRasterizer / RAS_OpenGLRasterizer.cpp
1 /**
2  * $Id$
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30  */
31  
32 #include <math.h>
33  
34 #include "RAS_OpenGLRasterizer.h"
35
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
39
40 #ifdef WIN32
41 #include <windows.h>
42 #endif // WIN32
43 #ifdef __APPLE__
44 #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                         }
1247                 }
1248         }
1249 #endif
1250
1251 #ifdef GL_ARB_vertex_program
1252         if(m_useTang && bgl::RAS_EXT_support._ARB_vertex_program)
1253                 bgl::blVertexAttrib4fvARB(1/*tangent*/, tv.getTangent());
1254 #endif
1255
1256 }
1257 void RAS_OpenGLRasterizer::Tangent(     const RAS_TexVert& v1,
1258                                                                         const RAS_TexVert& v2,
1259                                                                         const RAS_TexVert& v3,
1260                                                                         const MT_Vector3 &no)
1261 {
1262 #ifdef GL_ARB_multitexture
1263         // TODO: set for deformer... 
1264         MT_Vector3 x1(v1.getLocalXYZ()), x2(v2.getLocalXYZ()), x3(v3.getLocalXYZ());
1265         MT_Vector2 uv1(v1.getUV1()), uv2(v2.getUV1()), uv3(v3.getUV1());
1266         MT_Vector3 dx1(x2 - x1), dx2(x3 - x1);
1267         MT_Vector2 duv1(uv2 - uv1), duv2(uv3 - uv1);
1268         
1269         MT_Scalar r = 1.0 / (duv1.x() * duv2.y() - duv2.x() * duv1.y());
1270         duv1 *= r;
1271         duv2 *= r;
1272         MT_Vector3 sdir(duv2.y() * dx1 - duv1.y() * dx2);
1273         MT_Vector3 tdir(duv1.x() * dx2 - duv2.x() * dx1);
1274         
1275         // Gram-Schmidt orthogonalize
1276         MT_Vector3 t(sdir - no.cross(no.cross(sdir)));
1277         if (!MT_fuzzyZero(t))
1278                 t /= t.length();
1279
1280         float tangent[4];
1281         t.getValue(tangent);
1282         // Calculate handedness
1283         tangent[3] = no.dot(sdir.cross(tdir)) < 0.0 ? -1.0 : 1.0;
1284 #endif
1285 }
1286
1287
1288 void RAS_OpenGLRasterizer::IndexPrimitivesMulti(
1289                 const vecVertexArray& vertexarrays,
1290                 const vecIndexArrays & indexarrays,
1291                 int mode,
1292                 class RAS_IPolyMaterial* polymat,
1293                 class RAS_IRenderTools* rendertools,
1294                 bool useObjectColor,
1295                 const MT_Vector4& rgbacolor,
1296                 class KX_ListSlot** slot
1297                 )
1298
1299 #ifdef GL_ARB_multitexture
1300
1301         GLenum drawmode;
1302         switch (mode)
1303         {
1304         case 0:
1305                 drawmode = GL_TRIANGLES;
1306                 break;
1307         case 1:
1308                 drawmode = GL_LINES;
1309                 break;
1310         case 2:
1311                 drawmode = GL_QUADS;
1312                 break;
1313         default:
1314                 drawmode = GL_LINES;
1315                 break;
1316         }
1317         
1318         const RAS_TexVert* vertexarray ;
1319         unsigned int numindices,vt;
1320
1321         for (vt=0;vt<vertexarrays.size();vt++)
1322         {
1323                 vertexarray = &((*vertexarrays[vt]) [0]);
1324                 const KX_IndexArray & indexarray = (*indexarrays[vt]);
1325                 numindices = indexarray.size();
1326                 const unsigned int enabled = polymat->GetEnabled();
1327
1328                 if (!numindices)
1329                         break;
1330                 
1331                 int vindex=0;
1332                 switch (mode)
1333                 {
1334                 case 1:
1335                         {
1336                                 glBegin(GL_LINES);
1337                                 vindex=0;
1338                                 for (unsigned int i=0;i<numindices;i+=2)
1339                                 {
1340                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
1341                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
1342                                 }
1343                                 glEnd();
1344                         }
1345                         break;
1346                 case 2:
1347                         {
1348                                 glBegin(GL_QUADS);
1349                                 vindex=0;
1350                                 if (useObjectColor)
1351                                 {
1352                                         for (unsigned int i=0;i<numindices;i+=4)
1353                                         {
1354
1355                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
1356                                                 
1357                                                 //
1358                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1359                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1360                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1361                                                 vindex++;
1362                                                 
1363                                                 //
1364                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1365                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1366                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1367                                                 vindex++;
1368                                                 
1369                                                 //
1370                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1371                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1372                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1373                                                 vindex++;
1374                                                 
1375                                                 //
1376                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1377                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1378                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1379                                                 vindex++;
1380                                         }
1381                                 }
1382                                 else
1383                                 {
1384                                         for (unsigned int i=0;i<numindices;i+=4)
1385                                         {
1386                                                 // This looks curiously endian unsafe to me.
1387                                                 // However it depends on the way the colors are packed into 
1388                                                 // the m_rgba field of RAS_TexVert
1389                                                 
1390                                                 //
1391                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1392                                         
1393                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1394                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1395                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1396                                                 vindex++;
1397                                                 
1398                                                 //
1399                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1400                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1401                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1402                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1403                                                 vindex++;
1404                                                 
1405                                                 //
1406                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1407                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1408                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1409                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1410                                                 vindex++;
1411                                                 
1412                                                 //
1413                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1414                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1415                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1416                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1417                                                 vindex++;
1418                                         }
1419                                 }
1420                                 glEnd();        
1421                                 break;
1422                         }
1423                 case 0:
1424                         {
1425                                 glBegin(GL_TRIANGLES);
1426                                 vindex=0;
1427                                 if (useObjectColor)
1428                                 {
1429                                         for (unsigned int i=0;i<numindices;i+=3)
1430                                         {
1431
1432                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
1433                                                 //
1434                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1435                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1436                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1437                                                 vindex++;
1438                                                 
1439                                                 //
1440                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1441                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1442                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1443                                                 vindex++;
1444                                                 
1445                                                 //
1446                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1447                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1448                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1449                                                 vindex++;
1450                                         }
1451                                 }
1452                                 else 
1453                                 {
1454                                         for (unsigned int i=0;i<numindices;i+=3)
1455                                         {
1456                                                 //
1457                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1458                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1459                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1460                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1461                                                 vindex++;
1462                                                 
1463                                                 //
1464                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1465                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1466                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1467                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1468                                                 vindex++;
1469                                                 
1470                                                 //
1471                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1472                                                 glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1473                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1474                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1475                                                 vindex++;
1476                                         }
1477                                 }
1478                                 glEnd();        
1479                                 break;
1480                         }
1481                 default:
1482                         {
1483                         }
1484                 } // switch
1485         } // for each vertexarray
1486 #endif// GL_ARB_multitexture
1487
1488 }
1489
1490 void RAS_OpenGLRasterizer::IndexPrimitivesMulti_Ex(
1491                                                                         const vecVertexArray & vertexarrays,
1492                                                                         const vecIndexArrays & indexarrays,
1493                                                                         int mode,
1494                                                                         class RAS_IPolyMaterial* polymat,
1495                                                                         class RAS_IRenderTools* rendertools,
1496                                                                         bool useObjectColor,
1497                                                                         const MT_Vector4& rgbacolor)
1498
1499 #ifdef GL_ARB_multitexture
1500         bool    recalc;
1501         GLenum drawmode;
1502         switch (mode)
1503         {
1504         case 0:
1505                 drawmode = GL_TRIANGLES;
1506                 break;
1507         case 1:
1508                 drawmode = GL_LINES;
1509                 break;
1510         case 2:
1511                 drawmode = GL_QUADS;
1512                 break;
1513         default:
1514                 drawmode = GL_LINES;
1515                 break;
1516         }
1517         
1518         const RAS_TexVert* vertexarray ;
1519         unsigned int numindices,vt;
1520
1521         for (vt=0;vt<vertexarrays.size();vt++)
1522         {
1523                 vertexarray = &((*vertexarrays[vt]) [0]);
1524                 const KX_IndexArray & indexarray = (*indexarrays[vt]);
1525                 numindices = indexarray.size();
1526                 const unsigned int enabled = polymat->GetEnabled();
1527                 
1528                 if (!numindices)
1529                         continue;
1530                 
1531                 int vindex=0;
1532                 switch (mode)
1533                 {
1534                 case 1:
1535                         {
1536                                 glBegin(GL_LINES);
1537                                 vindex=0;
1538                                 for (unsigned int i=0;i<numindices;i+=2)
1539                                 {
1540                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
1541                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
1542                                 }
1543                                 glEnd();
1544                         }
1545                         break;
1546                 case 2:
1547                         {
1548                                 glBegin(GL_QUADS);
1549                                 vindex=0;
1550                                 if (useObjectColor)
1551                                 {
1552                                         for (unsigned int i=0;i<numindices;i+=4)
1553                                         {
1554                                                 MT_Point3 mv1, mv2, mv3, mv4, fnor;
1555                                                 /* Calc a new face normal */
1556
1557                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
1558                                                         recalc= true;
1559                                                 else
1560                                                         recalc=false;
1561
1562                                                 if (recalc){
1563                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
1564                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
1565                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
1566                                                         mv4 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
1567                                                         
1568                                                         fnor = (((mv2-mv1).cross(mv3-mv2))+((mv4-mv3).cross(mv1-mv4))).safe_normalized();
1569
1570                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
1571                                                 }
1572
1573                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
1574
1575                                                 if (!recalc)
1576                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1577                                         
1578                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1579                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1580                                                 vindex++;
1581                                                 
1582                                                 if (!recalc)
1583                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1584                                         
1585                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1586                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1587                                                 vindex++;
1588                                                 
1589                                                 if (!recalc)
1590                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());                                             
1591                                         
1592                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1593                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1594                                                 vindex++;
1595                                                 
1596                                                 if (!recalc)
1597                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1598                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1599                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1600                                                 vindex++;
1601                                         }
1602                                 }
1603                                 else
1604                                 {
1605                                         for (unsigned int i=0;i<numindices;i+=4)
1606                                         {
1607                                                 // This looks curiously endian unsafe to me.
1608                                                 // However it depends on the way the colors are packed into 
1609                                                 // the m_rgba field of RAS_TexVert
1610                                                 MT_Point3 mv1, mv2, mv3, mv4, fnor;
1611                                                 /* Calc a new face normal */
1612
1613                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
1614                                                         recalc= true;
1615                                                 else
1616                                                         recalc=false;
1617
1618
1619                                                 if (recalc){
1620                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
1621                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
1622                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
1623                                                         mv4 = MT_Point3(vertexarray[(indexarray[vindex+3])].getLocalXYZ());
1624                                                         
1625                                                         fnor = (((mv2-mv1).cross(mv3-mv2))+((mv4-mv3).cross(mv1-mv4))).safe_normalized();
1626
1627                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
1628                                                 }
1629
1630                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1631                                                 if (!recalc)
1632                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1633                                         
1634                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1635                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1636                                                 vindex++;
1637                                                 
1638                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1639                                                 if (!recalc)
1640                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1641                                         
1642                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1643                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1644                                                 vindex++;
1645                                                 
1646                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1647                                                 if (!recalc)
1648                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1649                                         
1650                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1651                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1652                                                 vindex++;
1653                                                 
1654                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1655                                                 if (!recalc)
1656                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1657
1658                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1659                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1660                                                 vindex++;
1661                                         }
1662                                 }
1663                                 glEnd();        
1664                                 break;
1665                         }
1666                 case 0:
1667                         {
1668                                 glBegin(GL_TRIANGLES);
1669                                 vindex=0;
1670                                 if (useObjectColor)
1671                                 {
1672                                         for (unsigned int i=0;i<numindices;i+=3)
1673                                         {
1674                                                 MT_Point3 mv1, mv2, mv3, fnor;
1675                                                 /* Calc a new face normal */
1676
1677                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
1678                                                         recalc= true;
1679                                                 else
1680                                                         recalc=false;
1681
1682                                                 if (recalc){
1683                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
1684                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
1685                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
1686                                                         
1687                                                         fnor = ((mv2-mv1).cross(mv3-mv2)).safe_normalized();
1688                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
1689                                                 }
1690
1691                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
1692
1693                                                 if (!recalc)
1694                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1695                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1696                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1697                                                 vindex++;
1698                                                 
1699                                                 if (!recalc)
1700                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1701                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1702                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1703                                                 vindex++;
1704                                                 
1705                                                 if (!recalc)
1706                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1707                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1708                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1709                                                 vindex++;
1710                                         }
1711                                 }
1712                                 else 
1713                                 {
1714                                         for (unsigned int i=0;i<numindices;i+=3)
1715                                         {
1716                                                 MT_Point3 mv1, mv2, mv3, fnor;
1717                                                 /* Calc a new face normal */
1718
1719                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
1720                                                         recalc= true;
1721                                                 else
1722                                                         recalc=false;
1723
1724
1725                                                 if (recalc){
1726                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
1727                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
1728                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
1729                                                         
1730                                                         fnor = ((mv2-mv1).cross(mv3-mv2)).safe_normalized();
1731                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
1732                                                 }
1733
1734                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1735                                                 if (!recalc)
1736                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1737                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1738                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1739                                                 vindex++;
1740                                                 
1741                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1742                                                 if (!recalc)
1743                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1744                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1745                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1746                                                 vindex++;
1747                                                 
1748                                                 glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
1749                                                 if (!recalc)
1750                                                         glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
1751                                                 TexCoord(vertexarray[(indexarray[vindex])],enabled );
1752                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
1753                                                 vindex++;
1754                                         }
1755                                 }
1756                                 glEnd();        
1757                                 break;
1758                         }
1759                 default:
1760                         {
1761                         }
1762                         
1763                 } // switch
1764         } // for each vertexarray
1765 #endif
1766 }
1767
1768
1769
1770 void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat)
1771 {
1772         glMatrixMode(GL_PROJECTION);
1773         double* matrix = &mat(0,0);
1774         glLoadMatrixd(matrix);
1775 }
1776
1777
1778 void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat)
1779 {
1780         glMatrixMode(GL_PROJECTION);
1781         double matrix[16];
1782         /* Get into argument. Looks a bit dodgy, but it's ok. */
1783         mat.getValue(matrix);
1784         /* Internally, MT_Matrix4x4 uses doubles (MT_Scalar). */
1785         glLoadMatrixd(matrix);  
1786 }
1787
1788 MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
1789         float left,
1790         float right,
1791         float bottom,
1792         float top,
1793         float frustnear,
1794         float frustfar,
1795         bool
1796 ){
1797         MT_Matrix4x4 result;
1798         double mat[16];
1799
1800         // correction for stereo
1801         if(m_stereomode != RAS_STEREO_NOSTEREO)
1802         {
1803                         float near_div_focallength;
1804                         // next 2 params should be specified on command line and in Blender publisher
1805                         if (!m_setfocallength)
1806                                 m_focallength = 1.5 * right;  // derived from example
1807                         if (!m_seteyesep)
1808                                 m_eyeseparation = 0.18 * right;  // just a guess...
1809
1810                         near_div_focallength = frustnear / m_focallength;
1811                         switch(m_curreye)
1812                         {
1813                                 case RAS_STEREO_LEFTEYE:
1814                                                 left += 0.5 * m_eyeseparation * near_div_focallength;
1815                                                 right += 0.5 * m_eyeseparation * near_div_focallength;
1816                                                 break;
1817                                 case RAS_STEREO_RIGHTEYE:
1818                                                 left -= 0.5 * m_eyeseparation * near_div_focallength;
1819                                                 right -= 0.5 * m_eyeseparation * near_div_focallength;
1820                                                 break;
1821                         }
1822                         // leave bottom, top, bottom and top untouched
1823         }
1824         
1825         glMatrixMode(GL_PROJECTION);
1826         glLoadIdentity();
1827         glFrustum(left, right, bottom, top, frustnear, frustfar);
1828                 
1829         glGetDoublev(GL_PROJECTION_MATRIX, mat);
1830         result.setValue(mat);
1831
1832         return result;
1833 }
1834
1835
1836 // next arguments probably contain redundant info, for later...
1837 void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, const MT_Vector3& campos,
1838                 const MT_Point3 &, const MT_Quaternion &camOrientQuat)
1839 {
1840         MT_Matrix4x4 viewMat = mat;
1841
1842         // correction for stereo
1843         if(m_stereomode != RAS_STEREO_NOSTEREO)
1844         {
1845                 MT_Matrix3x3 camOrientMat3x3(camOrientQuat);
1846                 MT_Vector3 unitViewDir(0.0, -1.0, 0.0);  // minus y direction, Blender convention
1847                 MT_Vector3 unitViewupVec(0.0, 0.0, 1.0);
1848                 MT_Vector3 viewDir, viewupVec;
1849                 MT_Vector3 eyeline;
1850
1851                 // actual viewDir
1852                 viewDir = camOrientMat3x3 * unitViewDir;  // this is the moto convention, vector on right hand side
1853                 // actual viewup vec
1854                 viewupVec = camOrientMat3x3 * unitViewupVec;
1855
1856                 // vector between eyes
1857                 eyeline = viewDir.cross(viewupVec);
1858
1859                 switch(m_curreye)
1860                 {
1861                         case RAS_STEREO_LEFTEYE:
1862                                 {
1863                                 // translate to left by half the eye distance
1864                                 MT_Transform transform;
1865                                 transform.setIdentity();
1866                                 transform.translate(-(eyeline * m_eyeseparation / 2.0));
1867                                 viewMat *= transform;
1868                                 }
1869                                 break;
1870                         case RAS_STEREO_RIGHTEYE:
1871                                 {
1872                                 // translate to right by half the eye distance
1873                                 MT_Transform transform;
1874                                 transform.setIdentity();
1875                                 transform.translate(eyeline * m_eyeseparation / 2.0);
1876                                 viewMat *= transform;
1877                                 }
1878                                 break;
1879                 }
1880         }
1881
1882         // convert row major matrix 'viewMat' to column major for OpenGL
1883         MT_Scalar cammat[16];
1884         viewMat.getValue(cammat);
1885         MT_CmMatrix4x4 viewCmmat = cammat;
1886
1887         glMatrixMode(GL_MODELVIEW);
1888         m_viewmatrix = viewCmmat;
1889         glLoadMatrixd(&m_viewmatrix(0,0));
1890         m_campos = campos;
1891 }
1892
1893
1894 const MT_Point3& RAS_OpenGLRasterizer::GetCameraPosition()
1895 {
1896         return m_campos;
1897 }
1898
1899
1900
1901 void RAS_OpenGLRasterizer::LoadViewMatrix()
1902 {
1903         glLoadMatrixd(&m_viewmatrix(0,0));
1904 }
1905
1906
1907
1908 void RAS_OpenGLRasterizer::EnableTextures(bool enable)
1909 {
1910 }
1911
1912
1913
1914 void RAS_OpenGLRasterizer::SetCullFace(bool enable)
1915 {
1916         if (enable)
1917                 glEnable(GL_CULL_FACE);
1918         else
1919                 glDisable(GL_CULL_FACE);
1920 }
1921
1922 void RAS_OpenGLRasterizer::SetLines(bool enable)
1923 {
1924         if (enable)
1925                 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1926         else
1927                 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1928 }
1929
1930 void RAS_OpenGLRasterizer::SetSpecularity(float specX,
1931                                                                                   float specY,
1932                                                                                   float specZ,
1933                                                                                   float specval)
1934 {
1935         GLfloat mat_specular[] = {specX, specY, specZ, specval};
1936         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
1937 }
1938
1939
1940
1941 void RAS_OpenGLRasterizer::SetShinyness(float shiny)
1942 {
1943         GLfloat mat_shininess[] = {     shiny };
1944         glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
1945 }
1946
1947
1948
1949 void RAS_OpenGLRasterizer::SetDiffuse(float difX,float difY,float difZ,float diffuse)
1950 {
1951         GLfloat mat_diffuse [] = {difX, difY,difZ, diffuse};
1952         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
1953 }
1954
1955 void RAS_OpenGLRasterizer::SetEmissive(float eX, float eY, float eZ, float e)
1956 {
1957         GLfloat mat_emit [] = {eX,eY,eZ,e};
1958         glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_emit);
1959 }
1960
1961
1962 double RAS_OpenGLRasterizer::GetTime()
1963 {
1964         return m_time;
1965 }
1966
1967 void RAS_OpenGLRasterizer::SetPolygonOffset(float mult, float add)
1968 {
1969         glPolygonOffset(mult, add);
1970         GLint mode = GL_POLYGON_OFFSET_FILL;
1971         if (m_drawingmode < KX_SHADED)
1972                 mode = GL_POLYGON_OFFSET_LINE;
1973         if (mult != 0.0f || add != 0.0f)
1974                 glEnable(mode);
1975         else
1976                 glDisable(mode);
1977 }