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