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