Lighting updates:
[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 #include "RAS_OpenGLRasterizer.h"
32
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
36
37 #ifdef WIN32
38 #include <windows.h>
39 #endif // WIN32
40 #ifdef __APPLE__
41 #include <OpenGL/gl.h>
42 #else
43 #include <GL/gl.h>
44 #endif
45
46 #include "RAS_Rect.h"
47 #include "RAS_TexVert.h"
48 #include "MT_CmMatrix4x4.h"
49 #include "RAS_IRenderTools.h" // rendering text
50
51 #include "RAS_GLExtensionManager.h"
52
53
54 RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
55         :RAS_IRasterizer(canvas),
56         m_2DCanvas(canvas),
57         m_fogenabled(false),
58         m_noOfScanlines(32),
59         m_materialCachingInfo(0)
60 {
61         m_viewmatrix.Identity();
62         m_stereomode = RAS_STEREO_NOSTEREO;
63 }
64
65
66
67 RAS_OpenGLRasterizer::~RAS_OpenGLRasterizer()
68 {
69 }
70
71
72
73 static void Myinit_gl_stuff(void)       
74 {
75         float mat_specular[] = { 0.5, 0.5, 0.5, 1.0 };
76         float mat_shininess[] = { 35.0 };
77 /*      float one= 1.0; */
78         int a, x, y;
79         GLubyte pat[32*32];
80         const GLubyte *patc= pat;
81                 
82         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_specular);
83         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
84         glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
85
86
87 #if defined(__FreeBSD) || defined(__linux__)
88         glDisable(GL_DITHER);   /* op sgi/sun hardware && 12 bits */
89 #endif
90         
91         /* no local viewer, looks ugly in ortho mode */
92         /* glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, &one); */
93         
94         glDepthFunc(GL_LEQUAL);
95         /* scaling matrices */
96         glEnable(GL_NORMALIZE);
97
98         glShadeModel(GL_FLAT);
99
100         glDisable(GL_ALPHA_TEST);
101         glDisable(GL_BLEND);
102         glDisable(GL_DEPTH_TEST);
103         glDisable(GL_FOG);
104         glDisable(GL_LIGHTING);
105         glDisable(GL_LOGIC_OP);
106         glDisable(GL_STENCIL_TEST);
107         glDisable(GL_TEXTURE_1D);
108         glDisable(GL_TEXTURE_2D);
109
110         glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
111         glPixelTransferi(GL_RED_SCALE, 1);
112         glPixelTransferi(GL_RED_BIAS, 0);
113         glPixelTransferi(GL_GREEN_SCALE, 1);
114         glPixelTransferi(GL_GREEN_BIAS, 0);
115         glPixelTransferi(GL_BLUE_SCALE, 1);
116         glPixelTransferi(GL_BLUE_BIAS, 0);
117         glPixelTransferi(GL_ALPHA_SCALE, 1);
118         glPixelTransferi(GL_ALPHA_BIAS, 0);
119
120         a = 0;
121         for(x=0; x<32; x++)
122         {
123                 for(y=0; y<4; y++)
124                 {
125                         if( (x) & 1) pat[a++]= 0x88;
126                         else pat[a++]= 0x22;
127                 }
128         }
129         
130         glPolygonStipple(patc);
131                 
132 }
133
134
135
136 bool RAS_OpenGLRasterizer::Init()
137 {
138
139         Myinit_gl_stuff();
140
141         m_redback = 0.4375;
142         m_greenback = 0.4375;
143         m_blueback = 0.4375;
144         m_alphaback = 0.0;
145         
146         // enable both vertexcolor AND lighting color
147         glEnable(GL_COLOR_MATERIAL);
148         
149         glClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
150         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
151
152         glShadeModel(GL_SMOOTH);
153
154         return true;
155 }
156
157
158
159 void RAS_OpenGLRasterizer::SetBackColor(float red,
160                                                                                 float green,
161                                                                                 float blue,
162                                                                                 float alpha)
163 {
164         m_redback = red;
165         m_greenback = green;
166         m_blueback = blue;
167         m_alphaback = alpha;
168 }
169
170
171
172 void RAS_OpenGLRasterizer::SetFogColor(float r,
173                                                                            float g,
174                                                                            float b)
175 {
176         m_fogr = r;
177         m_fogg = g;
178         m_fogb = b;
179         m_fogenabled = true;
180 }
181
182
183
184 void RAS_OpenGLRasterizer::SetFogStart(float start)
185 {
186         m_fogstart = start;
187         m_fogenabled = true;
188 }
189
190
191
192 void RAS_OpenGLRasterizer::SetFogEnd(float fogend)
193 {
194         m_fogdist = fogend;
195         m_fogenabled = true;
196 }
197
198
199
200 void RAS_OpenGLRasterizer::SetFog(float start,
201                                                                   float dist,
202                                                                   float r,
203                                                                   float g,
204                                                                   float b)
205 {
206         m_fogstart = start;
207         m_fogdist = dist;
208         m_fogr = r;
209         m_fogg = g;
210         m_fogb = b;
211         m_fogenabled = true;
212 }
213
214
215
216 void RAS_OpenGLRasterizer::DisableFog()
217 {
218         m_fogenabled = false;
219 }
220
221
222
223 void RAS_OpenGLRasterizer::DisplayFog()
224 {
225         if ((m_drawingmode >= KX_SOLID) && m_fogenabled)
226         {
227                 float params[5];
228                 glFogi(GL_FOG_MODE, GL_LINEAR);
229                 glFogf(GL_FOG_DENSITY, 0.1f);
230                 glFogf(GL_FOG_START, m_fogstart);
231                 glFogf(GL_FOG_END, m_fogstart + m_fogdist);
232                 params[0]= m_fogr;
233                 params[1]= m_fogg;
234                 params[2]= m_fogb;
235                 params[3]= 0.0;
236                 glFogfv(GL_FOG_COLOR, params); 
237                 glEnable(GL_FOG);
238         } 
239         else
240         {
241                 glDisable(GL_FOG);
242         }
243 }
244
245
246
247 void RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat)
248 {
249         if (mat.GetCachingInfo() != m_materialCachingInfo)
250         {
251                 mat.Activate(this, m_materialCachingInfo);
252         }
253 }
254
255
256
257 void RAS_OpenGLRasterizer::Exit()
258 {
259
260         glEnable(GL_CULL_FACE);
261         glEnable(GL_DEPTH_TEST);
262         glClearDepth(1.0); 
263         glClearColor(m_redback, m_greenback, m_blueback, m_alphaback);
264         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
265         glDepthMask (GL_TRUE);
266         glDepthFunc(GL_LEQUAL);
267         glBlendFunc(GL_ONE, GL_ZERO);
268
269         glDisable(GL_LIGHTING);
270         if (bgl::QueryExtension(bgl::_GL_EXT_separate_specular_color) || bgl::QueryVersion(1, 2))
271                 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
272         
273         EndFrame();
274 }
275
276
277
278 bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
279 {
280         m_time = time;
281         m_drawingmode = drawingmode;
282         
283         m_2DCanvas->ClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
284         m_2DCanvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER);
285
286         // Blender camera routine destroys the settings
287         if (m_drawingmode < KX_SOLID)
288         {
289                 glDisable (GL_CULL_FACE);
290                 glDisable (GL_DEPTH_TEST);
291         }
292         else
293         {
294                 glEnable(GL_DEPTH_TEST);
295                 glEnable (GL_CULL_FACE);
296         }
297
298         glShadeModel(GL_SMOOTH);
299
300         m_2DCanvas->BeginFrame();
301         
302         return true;
303 }
304
305
306
307 void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode)
308 {
309         m_drawingmode = drawingmode;
310
311         switch (m_drawingmode)
312         {
313         case KX_BOUNDINGBOX:
314                 {
315                 }
316         case KX_WIREFRAME:
317                 {
318                         glDisable (GL_CULL_FACE);
319                         break;
320                 }
321         case KX_TEXTURED:
322                 {
323                 }
324         case KX_SHADED:
325                 {
326                 }
327         case KX_SOLID:
328                 {
329                 }
330         default:
331                 {
332                 }
333         }
334 }
335
336
337
338 int RAS_OpenGLRasterizer::GetDrawingMode()
339 {
340         return m_drawingmode;
341 }
342
343
344
345 void RAS_OpenGLRasterizer::SetDepthMask(int depthmask)
346 {
347         switch (depthmask)
348         {
349         case KX_DEPTHMASK_ENABLED:
350                 {
351                         glDepthMask(GL_TRUE);
352                         //glDisable ( GL_ALPHA_TEST );
353                         break;
354                 };
355         case KX_DEPTHMASK_DISABLED:
356                 {
357                         glDepthMask(GL_FALSE);
358                         //glAlphaFunc ( GL_GREATER, 0.0 ) ;
359                         //glEnable ( GL_ALPHA_TEST ) ;
360                         break;
361                 };
362         default:
363                 {
364                 //printf("someone made a mistake, RAS_OpenGLRasterizer::SetDepthMask(int depthmask)\n");
365                 exit(0);
366                 }
367         }
368 }
369
370
371
372 void RAS_OpenGLRasterizer::ClearDepthBuffer()
373 {
374         m_2DCanvas->ClearBuffer(RAS_ICanvas::DEPTH_BUFFER);
375 }
376
377
378 void RAS_OpenGLRasterizer::ClearCachingInfo(void)
379 {
380         m_materialCachingInfo = 0;
381 }
382
383
384 void RAS_OpenGLRasterizer::EndFrame()
385 {
386         m_2DCanvas->EndFrame();
387 }       
388
389
390 void RAS_OpenGLRasterizer::SetRenderArea()
391 {
392         // only above/below stereo method needs viewport adjustment
393         if(m_stereomode == RAS_STEREO_ABOVEBELOW)
394         {
395                 switch(m_curreye)
396                 {
397                         case RAS_STEREO_LEFTEYE:
398                                 // upper half of window
399                                 m_2DCanvas->GetDisplayArea().SetLeft(0);
400                                 m_2DCanvas->GetDisplayArea().SetBottom(m_2DCanvas->GetHeight() -
401                                         int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
402
403                                 m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
404                                 m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight()));
405                                 break;
406                         case RAS_STEREO_RIGHTEYE:
407                                 // lower half of window
408                                 m_2DCanvas->GetDisplayArea().SetLeft(0);
409                                 m_2DCanvas->GetDisplayArea().SetBottom(0);
410                                 m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
411                                 m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
412                                 break;
413                 }
414         }
415         else
416         {
417                 // every available pixel
418                 m_2DCanvas->GetDisplayArea().SetLeft(0);
419                 m_2DCanvas->GetDisplayArea().SetBottom(0);
420                 m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
421                 m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight()));
422         }
423 }
424
425         
426 void RAS_OpenGLRasterizer::SetStereoMode(const int stereomode)
427 {
428         m_stereomode = stereomode;
429 }
430
431
432
433 bool RAS_OpenGLRasterizer::Stereo()
434 {
435         if(m_stereomode == RAS_STEREO_NOSTEREO)
436                 return false;
437         else
438                 return true;
439 }
440
441
442 void RAS_OpenGLRasterizer::SetEye(int eye)
443 {
444         m_curreye = eye;
445         if(m_stereomode == RAS_STEREO_QUADBUFFERED) {
446                 if(m_curreye == RAS_STEREO_LEFTEYE)
447                         glDrawBuffer(GL_BACK_LEFT);
448                 else
449                         glDrawBuffer(GL_BACK_RIGHT);
450         }
451 }
452
453
454 void RAS_OpenGLRasterizer::SetEyeSeparation(float eyeseparation)
455 {
456         m_eyeseparation = eyeseparation;
457 }
458
459
460 void RAS_OpenGLRasterizer::SetFocalLength(float focallength)
461 {
462         m_focallength = focallength;
463 }
464
465
466 void RAS_OpenGLRasterizer::SwapBuffers()
467 {
468         m_2DCanvas->SwapBuffers();
469 }
470
471
472
473 void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays,
474                                                                         const vecIndexArrays & indexarrays,
475                                                                         int mode,
476                                                                         class RAS_IPolyMaterial* polymat,
477                                                                         class RAS_IRenderTools* rendertools,
478                                                                         bool useObjectColor,
479                                                                         const MT_Vector4& rgbacolor
480                                                                         )
481
482         GLenum drawmode;
483         switch (mode)
484         {
485         case 0:
486                 drawmode = GL_TRIANGLES;
487                 break;
488         case 1:
489                 drawmode = GL_LINES;
490                 break;
491         case 2:
492                 drawmode = GL_QUADS;
493                 break;
494         default:
495                 drawmode = GL_LINES;
496                 break;
497         }
498         
499         const RAS_TexVert* vertexarray ;
500         unsigned int numindices,vt;
501
502         for (vt=0;vt<vertexarrays.size();vt++)
503         {
504                 vertexarray = &((*vertexarrays[vt]) [0]);
505                 const KX_IndexArray & indexarray = (*indexarrays[vt]);
506                 numindices = indexarray.size();
507                 
508                 if (!numindices)
509                         break;
510                 
511                 int vindex=0;
512                 switch (mode)
513                 {
514                 case 1:
515                         {
516                                 glBegin(GL_LINES);
517                                 vindex=0;
518                                 for (unsigned int i=0;i<numindices;i+=2)
519                                 {
520                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
521                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
522                                 }
523                                 glEnd();
524                         }
525                         break;
526                 case 2:
527                         {
528                                 glBegin(GL_QUADS);
529                                 vindex=0;
530                                 if (useObjectColor)
531                                 {
532                                         for (unsigned int i=0;i<numindices;i+=4)
533                                         {
534
535                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
536
537                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
538                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
539                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
540                                                 vindex++;
541                                                 
542                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
543                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
544                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
545                                                 vindex++;
546                                                 
547                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
548                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
549                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
550                                                 vindex++;
551                                                 
552                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
553                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
554                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
555                                                 vindex++;
556                                         }
557                                 }
558                                 else
559                                 {
560                                         for (unsigned int i=0;i<numindices;i+=4)
561                                         {
562                                                 // This looks curiously endian unsafe to me.
563                                                 // However it depends on the way the colors are packed into 
564                                                 // the m_rgba field of RAS_TexVert
565
566                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
567                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
568                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
569                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
570                                                 vindex++;
571                                                 
572                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
573                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
574                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
575                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
576                                                 vindex++;
577                                                 
578                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
579                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
580                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
581                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
582                                                 vindex++;
583                                                 
584                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
585                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
586                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
587                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
588                                                 vindex++;
589                                         }
590                                 }
591                                 glEnd();        
592                                 break;
593                         }
594                 case 0:
595                         {
596                                 glBegin(GL_TRIANGLES);
597                                 vindex=0;
598                                 if (useObjectColor)
599                                 {
600                                         for (unsigned int i=0;i<numindices;i+=3)
601                                         {
602
603                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
604
605                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
606                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
607                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
608                                                 vindex++;
609                                                 
610                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
611                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
612                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
613                                                 vindex++;
614                                                 
615                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
616                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
617                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
618                                                 vindex++;
619                                         }
620                                 }
621                                 else 
622                                 {
623                                         for (unsigned int i=0;i<numindices;i+=3)
624                                         {
625
626                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
627                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
628                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
629                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
630                                                 vindex++;
631                                                 
632                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
633                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
634                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
635                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
636                                                 vindex++;
637                                                 
638                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
639                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
640                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
641                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
642                                                 vindex++;
643                                         }
644                                 }
645                                 glEnd();        
646                                 break;
647                         }
648                 default:
649                         {
650                         }
651                         
652                 } // switch
653         } // for each vertexarray
654
655 }
656
657 void RAS_OpenGLRasterizer::IndexPrimitives_Ex(const vecVertexArray & vertexarrays,
658                                                                         const vecIndexArrays & indexarrays,
659                                                                         int mode,
660                                                                         class RAS_IPolyMaterial* polymat,
661                                                                         class RAS_IRenderTools* rendertools,
662                                                                         bool useObjectColor,
663                                                                         const MT_Vector4& rgbacolor
664                                                                         )
665
666         bool    recalc;
667         GLenum drawmode;
668         switch (mode)
669         {
670         case 0:
671                 drawmode = GL_TRIANGLES;
672                 break;
673         case 1:
674                 drawmode = GL_LINES;
675                 break;
676         case 2:
677                 drawmode = GL_QUADS;
678                 break;
679         default:
680                 drawmode = GL_LINES;
681                 break;
682         }
683         
684         const RAS_TexVert* vertexarray ;
685         unsigned int numindices,vt;
686
687         for (vt=0;vt<vertexarrays.size();vt++)
688         {
689                 vertexarray = &((*vertexarrays[vt]) [0]);
690                 const KX_IndexArray & indexarray = (*indexarrays[vt]);
691                 numindices = indexarray.size();
692                 
693                 if (!numindices)
694                         continue;
695                 
696                 int vindex=0;
697                 switch (mode)
698                 {
699                 case 1:
700                         {
701                                 glBegin(GL_LINES);
702                                 vindex=0;
703                                 for (unsigned int i=0;i<numindices;i+=2)
704                                 {
705                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
706                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
707                                 }
708                                 glEnd();
709                         }
710                         break;
711                 case 2:
712                         {
713                                 glBegin(GL_QUADS);
714                                 vindex=0;
715                                 if (useObjectColor)
716                                 {
717                                         for (unsigned int i=0;i<numindices;i+=4)
718                                         {
719                                                 MT_Point3 mv1, mv2, mv3, mv4, fnor;
720                                                 /* Calc a new face normal */
721
722                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
723                                                         recalc= true;
724                                                 else
725                                                         recalc=false;
726
727                                                 if (recalc){
728                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
729                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
730                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
731                                                         mv4 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
732                                                         
733                                                         fnor = (((mv2-mv1).cross(mv3-mv2))+((mv4-mv3).cross(mv1-mv4))).safe_normalized();
734
735                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
736                                                 }
737
738                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
739
740                                                 if (!recalc)
741                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
742                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
743                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
744                                                 vindex++;
745                                                 
746                                                 if (!recalc)
747                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
748                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
749                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
750                                                 vindex++;
751                                                 
752                                                 if (!recalc)
753                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());                                             
754                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
755                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
756                                                 vindex++;
757                                                 
758                                                 if (!recalc)
759                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
760                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
761                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
762                                                 vindex++;
763                                         }
764                                 }
765                                 else
766                                 {
767                                         for (unsigned int i=0;i<numindices;i+=4)
768                                         {
769                                                 // This looks curiously endian unsafe to me.
770                                                 // However it depends on the way the colors are packed into 
771                                                 // the m_rgba field of RAS_TexVert
772                                                 MT_Point3 mv1, mv2, mv3, mv4, fnor;
773                                                 /* Calc a new face normal */
774
775                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
776                                                         recalc= true;
777                                                 else
778                                                         recalc=false;
779
780
781                                                 if (recalc){
782                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
783                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
784                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
785                                                         mv4 = MT_Point3(vertexarray[(indexarray[vindex+3])].getLocalXYZ());
786                                                         
787                                                         fnor = (((mv2-mv1).cross(mv3-mv2))+((mv4-mv3).cross(mv1-mv4))).safe_normalized();
788
789                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
790                                                 }
791
792                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
793                                                 if (!recalc)
794                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
795                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
796                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
797                                                 vindex++;
798                                                 
799                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
800                                                 if (!recalc)
801                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
802                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
803                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
804                                                 vindex++;
805                                                 
806                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
807                                                 if (!recalc)
808                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
809                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
810                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
811                                                 vindex++;
812                                                 
813                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
814                                                 if (!recalc)
815                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
816                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
817                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
818                                                 vindex++;
819                                         }
820                                 }
821                                 glEnd();        
822                                 break;
823                         }
824                 case 0:
825                         {
826                                 glBegin(GL_TRIANGLES);
827                                 vindex=0;
828                                 if (useObjectColor)
829                                 {
830                                         for (unsigned int i=0;i<numindices;i+=3)
831                                         {
832                                                 MT_Point3 mv1, mv2, mv3, fnor;
833                                                 /* Calc a new face normal */
834
835                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
836                                                         recalc= true;
837                                                 else
838                                                         recalc=false;
839
840                                                 if (recalc){
841                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
842                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
843                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
844                                                         
845                                                         fnor = ((mv2-mv1).cross(mv3-mv2)).safe_normalized();
846                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
847                                                 }
848
849                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
850
851                                                 if (!recalc)
852                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
853                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
854                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
855                                                 vindex++;
856                                                 
857                                                 if (!recalc)
858                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
859                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
860                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
861                                                 vindex++;
862                                                 
863                                                 if (!recalc)
864                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
865                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
866                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
867                                                 vindex++;
868                                         }
869                                 }
870                                 else 
871                                 {
872                                         for (unsigned int i=0;i<numindices;i+=3)
873                                         {
874                                                 MT_Point3 mv1, mv2, mv3, fnor;
875                                                 /* Calc a new face normal */
876
877                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
878                                                         recalc= true;
879                                                 else
880                                                         recalc=false;
881
882
883                                                 if (recalc){
884                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
885                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
886                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
887                                                         
888                                                         fnor = ((mv2-mv1).cross(mv3-mv2)).safe_normalized();
889                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
890                                                 }
891
892                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
893                                                 if (!recalc)
894                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
895                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
896                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
897                                                 vindex++;
898                                                 
899                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
900                                                 if (!recalc)
901                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
902                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
903                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
904                                                 vindex++;
905                                                 
906                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
907                                                 if (!recalc)
908                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
909                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
910                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
911                                                 vindex++;
912                                         }
913                                 }
914                                 glEnd();        
915                                 break;
916                         }
917                 default:
918                         {
919                         }
920                         
921                 } // switch
922         } // for each vertexarray
923
924 }
925
926
927
928 void RAS_OpenGLRasterizer::IndexPrimitives_3DText(const vecVertexArray & vertexarrays,
929                                                                         const vecIndexArrays & indexarrays,
930                                                                         int mode,
931                                                                         class RAS_IPolyMaterial* polymat,
932                                                                         class RAS_IRenderTools* rendertools,
933                                                                         bool useObjectColor,
934                                                                         const MT_Vector4& rgbacolor
935                                                                         )
936
937         GLenum drawmode;
938         switch (mode)
939         {
940         case 0:
941                 drawmode = GL_TRIANGLES;
942                 break;
943         case 1:
944                 drawmode = GL_LINES;
945                 break;
946         case 2:
947                 drawmode = GL_QUADS;
948                 break;
949         default:
950                 drawmode = GL_LINES;
951                 break;
952         }
953         
954         const RAS_TexVert* vertexarray ;
955         
956         unsigned int numindices, vt;
957         
958         if (useObjectColor)
959         {
960                 glDisableClientState(GL_COLOR_ARRAY);
961                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
962         }
963         else
964         {
965                 glEnableClientState(GL_COLOR_ARRAY);
966         }
967         
968         for (vt=0;vt<vertexarrays.size();vt++)
969         {
970                 vertexarray = &((*vertexarrays[vt]) [0]);
971                 const KX_IndexArray & indexarray = (*indexarrays[vt]);
972                 numindices = indexarray.size();
973                 
974                 if (!numindices)
975                         break;
976                 
977                 int vindex=0;
978                 switch (mode)
979                 {
980                 case 1:
981                         {
982                                 glBegin(GL_LINES);
983                                 vindex=0;
984                                 for (unsigned int i=0;i<numindices;i+=2)
985                                 {
986                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
987                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
988                                 }
989                                 glEnd();
990                         }
991                         break;
992                 case 2:
993                         {
994                                 vindex=0;
995                                 for (unsigned int i=0;i<numindices;i+=4)
996                                 {
997                                         float v1[3],v2[3],v3[3],v4[3];
998                                         
999                                         char *cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
1000                                         v1[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1001                                         v1[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1002                                         v1[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1003                                         vindex++;
1004                                         
1005                                         cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
1006                                         v2[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1007                                         v2[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1008                                         v2[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1009                                         vindex++;
1010                                         
1011                                         cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
1012                                         v3[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1013                                         v3[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1014                                         v3[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1015                                         vindex++;
1016                                         
1017                                         cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
1018                                         v4[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1019                                         v4[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1020                                         v4[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1021                                         
1022                                         vindex++;
1023                                         
1024                                         rendertools->RenderText(polymat->GetDrawingMode(),polymat,v1,v2,v3,v4);
1025                                         ClearCachingInfo();
1026                                 }
1027                                 break;
1028                         }
1029                 case 0:
1030                         {
1031                                 glBegin(GL_TRIANGLES);
1032                                 vindex=0;
1033                                 for (unsigned int i=0;i<numindices;i+=3)
1034                                 {
1035                                         float v1[3],v2[3],v3[3];
1036                                         
1037                                         v1[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1038                                         v1[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1039                                         v1[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1040                                         vindex++;
1041                                         
1042                                         v2[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1043                                         v2[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1044                                         v2[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1045                                         vindex++;
1046                                         
1047                                         v3[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1048                                         v3[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1049                                         v3[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1050                                         vindex++;
1051                                         
1052                                         rendertools->RenderText(polymat->GetDrawingMode(),polymat,v1,v2,v3,NULL);               
1053                                         ClearCachingInfo();
1054                                 }
1055                                 glEnd();        
1056                                 break;
1057                         }
1058                 default:
1059                         {
1060                         }
1061                 }       //switch
1062         }       //for each vertexarray
1063 }
1064
1065
1066
1067 void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat)
1068 {
1069         glMatrixMode(GL_PROJECTION);
1070         double* matrix = &mat(0,0);
1071         glLoadMatrixd(matrix);
1072 }
1073
1074
1075 void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat)
1076 {
1077         glMatrixMode(GL_PROJECTION);
1078         double matrix[16];
1079         /* Get into argument. Looks a bit dodgy, but it's ok. */
1080         mat.getValue(matrix);
1081         /* Internally, MT_Matrix4x4 uses doubles (MT_Scalar). */
1082         glLoadMatrixd(matrix);  
1083 }
1084
1085 MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
1086         float left,
1087         float right,
1088         float bottom,
1089         float top,
1090         float frustnear,
1091         float frustfar,
1092         bool perspective
1093 ){
1094         MT_Matrix4x4 result;
1095         double mat[16];
1096
1097         // correction for stereo
1098         if(m_stereomode != RAS_STEREO_NOSTEREO)
1099         {
1100                         float near_div_focallength;
1101                         // next 2 params should be specified on command line and in Blender publisher
1102                         m_focallength = 1.5 * right;  // derived from example
1103                         m_eyeseparation = 0.18 * right;  // just a guess...
1104
1105                         near_div_focallength = frustnear / m_focallength;
1106                         switch(m_curreye)
1107                         {
1108                                 case RAS_STEREO_LEFTEYE:
1109                                                 left += 0.5 * m_eyeseparation * near_div_focallength;
1110                                                 right += 0.5 * m_eyeseparation * near_div_focallength;
1111                                                 break;
1112                                 case RAS_STEREO_RIGHTEYE:
1113                                                 left -= 0.5 * m_eyeseparation * near_div_focallength;
1114                                                 right -= 0.5 * m_eyeseparation * near_div_focallength;
1115                                                 break;
1116                         }
1117                         // leave bottom, top, bottom and top untouched
1118         }
1119         
1120         glMatrixMode(GL_PROJECTION);
1121         glLoadIdentity();
1122         glFrustum(left, right, bottom, top, frustnear, frustfar);
1123                 
1124         glGetDoublev(GL_PROJECTION_MATRIX, mat);
1125         result.setValue(mat);
1126
1127         return result;
1128 }
1129
1130
1131 // next arguments probably contain redundant info, for later...
1132 void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, const MT_Vector3& campos,
1133                 const MT_Point3 &camLoc, const MT_Quaternion &camOrientQuat)
1134 {
1135         MT_Matrix4x4 viewMat = mat;
1136
1137         // correction for stereo
1138         if(m_stereomode != RAS_STEREO_NOSTEREO)
1139         {
1140                 MT_Matrix3x3 camOrientMat3x3(camOrientQuat);
1141                 MT_Vector3 unitViewDir(0.0, -1.0, 0.0);  // minus y direction, Blender convention
1142                 MT_Vector3 unitViewupVec(0.0, 0.0, 1.0);
1143                 MT_Vector3 viewDir, viewupVec;
1144                 MT_Vector3 eyeline;
1145
1146                 // actual viewDir
1147                 viewDir = camOrientMat3x3 * unitViewDir;  // this is the moto convention, vector on right hand side
1148                 // actual viewup vec
1149                 viewupVec = camOrientMat3x3 * unitViewupVec;
1150
1151                 // vector between eyes
1152                 eyeline = viewDir.cross(viewupVec);
1153
1154                 switch(m_curreye)
1155                 {
1156                         case RAS_STEREO_LEFTEYE:
1157                                 {
1158                                 // translate to left by half the eye distance
1159                                 MT_Transform transform;
1160                                 transform.setIdentity();
1161                                 transform.translate(-(eyeline * m_eyeseparation / 2.0));
1162                                 viewMat *= transform;
1163                                 }
1164                                 break;
1165                         case RAS_STEREO_RIGHTEYE:
1166                                 {
1167                                 // translate to right by half the eye distance
1168                                 MT_Transform transform;
1169                                 transform.setIdentity();
1170                                 transform.translate(eyeline * m_eyeseparation / 2.0);
1171                                 viewMat *= transform;
1172                                 }
1173                                 break;
1174                 }
1175         }
1176
1177         // convert row major matrix 'viewMat' to column major for OpenGL
1178         MT_Scalar cammat[16];
1179         viewMat.getValue(cammat);
1180         MT_CmMatrix4x4 viewCmmat = cammat;
1181
1182         glMatrixMode(GL_MODELVIEW);
1183         m_viewmatrix = viewCmmat;
1184         glLoadMatrixd(&m_viewmatrix(0,0));
1185         m_campos = campos;
1186 }
1187
1188
1189 const MT_Point3& RAS_OpenGLRasterizer::GetCameraPosition()
1190 {
1191         return m_campos;
1192 }
1193
1194
1195
1196 void RAS_OpenGLRasterizer::LoadViewMatrix()
1197 {
1198         glLoadMatrixd(&m_viewmatrix(0,0));
1199 }
1200
1201
1202
1203 void RAS_OpenGLRasterizer::EnableTextures(bool enable)
1204 {
1205 }
1206
1207
1208
1209 void RAS_OpenGLRasterizer::SetCullFace(bool enable)
1210 {
1211         if (enable)
1212                 glEnable(GL_CULL_FACE);
1213         else
1214                 glDisable(GL_CULL_FACE);
1215 }
1216
1217 void RAS_OpenGLRasterizer::SetLines(bool enable)
1218 {
1219         if (enable)
1220                 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1221         else
1222                 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1223 }
1224
1225 void RAS_OpenGLRasterizer::SetSpecularity(float specX,
1226                                                                                   float specY,
1227                                                                                   float specZ,
1228                                                                                   float specval)
1229 {
1230         GLfloat mat_specular[] = {specX, specY, specZ, specval};
1231         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
1232 }
1233
1234
1235
1236 void RAS_OpenGLRasterizer::SetShinyness(float shiny)
1237 {
1238         GLfloat mat_shininess[] = {     shiny };
1239         glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
1240 }
1241
1242
1243
1244 void RAS_OpenGLRasterizer::SetDiffuse(float difX,float difY,float difZ,float diffuse)
1245 {
1246         GLfloat mat_diffuse [] = {difX, difY,difZ, diffuse};
1247         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
1248 }
1249
1250 double RAS_OpenGLRasterizer::GetTime()
1251 {
1252         return m_time;
1253 }
1254
1255