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