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