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