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