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