Fix for reflection mapping unlit faces: normals were not being sent, hence reflectio...
[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         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         if (bgl::QueryExtension(bgl::_GL_EXT_separate_specular_color) || bgl::QueryVersion(1, 2))
268                 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
269         
270         EndFrame();
271 }
272
273
274
275 bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
276 {
277         m_time = time;
278         m_drawingmode = drawingmode;
279         
280         m_2DCanvas->ClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
281         m_2DCanvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER);
282
283         // Blender camera routine destroys the settings
284         if (m_drawingmode < KX_SOLID)
285         {
286                 glDisable (GL_CULL_FACE);
287                 glDisable (GL_DEPTH_TEST);
288         }
289         else
290         {
291                 glEnable(GL_DEPTH_TEST);
292                 glEnable (GL_CULL_FACE);
293         }
294
295         glShadeModel(GL_SMOOTH);
296
297         m_2DCanvas->BeginFrame();
298         
299         return true;
300 }
301
302
303
304 void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode)
305 {
306         m_drawingmode = drawingmode;
307
308         switch (m_drawingmode)
309         {
310         case KX_BOUNDINGBOX:
311                 {
312                 }
313         case KX_WIREFRAME:
314                 {
315                         glDisable (GL_CULL_FACE);
316                         break;
317                 }
318         case KX_TEXTURED:
319                 {
320                 }
321         case KX_SHADED:
322                 {
323                 }
324         case KX_SOLID:
325                 {
326                 }
327         default:
328                 {
329                 }
330         }
331 }
332
333
334
335 int RAS_OpenGLRasterizer::GetDrawingMode()
336 {
337         return m_drawingmode;
338 }
339
340
341
342 void RAS_OpenGLRasterizer::SetDepthMask(int depthmask)
343 {
344         switch (depthmask)
345         {
346         case KX_DEPTHMASK_ENABLED:
347                 {
348                         glDepthMask(GL_TRUE);
349                         //glDisable ( GL_ALPHA_TEST );
350                         break;
351                 };
352         case KX_DEPTHMASK_DISABLED:
353                 {
354                         glDepthMask(GL_FALSE);
355                         //glAlphaFunc ( GL_GREATER, 0.0 ) ;
356                         //glEnable ( GL_ALPHA_TEST ) ;
357                         break;
358                 };
359         default:
360                 {
361                 //printf("someone made a mistake, RAS_OpenGLRasterizer::SetDepthMask(int depthmask)\n");
362                 exit(0);
363                 }
364         }
365 }
366
367
368
369 void RAS_OpenGLRasterizer::ClearDepthBuffer()
370 {
371         m_2DCanvas->ClearBuffer(RAS_ICanvas::DEPTH_BUFFER);
372 }
373
374
375 void RAS_OpenGLRasterizer::ClearCachingInfo(void)
376 {
377         m_materialCachingInfo = 0;
378 }
379
380
381 void RAS_OpenGLRasterizer::EndFrame()
382 {
383         m_2DCanvas->EndFrame();
384 }       
385
386
387 void RAS_OpenGLRasterizer::SetRenderArea()
388 {
389         // only above/below stereo method needs viewport adjustment
390         if(m_stereomode == RAS_STEREO_ABOVEBELOW)
391         {
392                 switch(m_curreye)
393                 {
394                         case RAS_STEREO_LEFTEYE:
395                                 // upper half of window
396                                 m_2DCanvas->GetDisplayArea().SetLeft(0);
397                                 m_2DCanvas->GetDisplayArea().SetBottom(m_2DCanvas->GetHeight() -
398                                         int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
399
400                                 m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
401                                 m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight()));
402                                 break;
403                         case RAS_STEREO_RIGHTEYE:
404                                 // lower half of window
405                                 m_2DCanvas->GetDisplayArea().SetLeft(0);
406                                 m_2DCanvas->GetDisplayArea().SetBottom(0);
407                                 m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
408                                 m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
409                                 break;
410                 }
411         }
412         else
413         {
414                 // every available pixel
415                 m_2DCanvas->GetDisplayArea().SetLeft(0);
416                 m_2DCanvas->GetDisplayArea().SetBottom(0);
417                 m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
418                 m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight()));
419         }
420 }
421
422         
423 void RAS_OpenGLRasterizer::SetStereoMode(const int stereomode)
424 {
425         m_stereomode = stereomode;
426 }
427
428
429
430 bool RAS_OpenGLRasterizer::Stereo()
431 {
432         if(m_stereomode == RAS_STEREO_NOSTEREO)
433                 return false;
434         else
435                 return true;
436 }
437
438
439 void RAS_OpenGLRasterizer::SetEye(int eye)
440 {
441         m_curreye = eye;
442         if(m_stereomode == RAS_STEREO_QUADBUFFERED) {
443                 if(m_curreye == RAS_STEREO_LEFTEYE)
444                         glDrawBuffer(GL_BACK_LEFT);
445                 else
446                         glDrawBuffer(GL_BACK_RIGHT);
447         }
448 }
449
450
451 void RAS_OpenGLRasterizer::SetEyeSeparation(float eyeseparation)
452 {
453         m_eyeseparation = eyeseparation;
454 }
455
456
457 void RAS_OpenGLRasterizer::SetFocalLength(float focallength)
458 {
459         m_focallength = focallength;
460 }
461
462
463 void RAS_OpenGLRasterizer::SwapBuffers()
464 {
465         m_2DCanvas->SwapBuffers();
466 }
467
468
469
470 void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays,
471                                                                         const vecIndexArrays & indexarrays,
472                                                                         int mode,
473                                                                         class RAS_IPolyMaterial* polymat,
474                                                                         class RAS_IRenderTools* rendertools,
475                                                                         bool useObjectColor,
476                                                                         const MT_Vector4& rgbacolor
477                                                                         )
478
479         GLenum drawmode;
480         switch (mode)
481         {
482         case 0:
483                 drawmode = GL_TRIANGLES;
484                 break;
485         case 1:
486                 drawmode = GL_LINES;
487                 break;
488         case 2:
489                 drawmode = GL_QUADS;
490                 break;
491         default:
492                 drawmode = GL_LINES;
493                 break;
494         }
495         
496         const RAS_TexVert* vertexarray ;
497         unsigned int numindices,vt;
498
499         for (vt=0;vt<vertexarrays.size();vt++)
500         {
501                 vertexarray = &((*vertexarrays[vt]) [0]);
502                 const KX_IndexArray & indexarray = (*indexarrays[vt]);
503                 numindices = indexarray.size();
504                 
505                 if (!numindices)
506                         break;
507                 
508                 int vindex=0;
509                 switch (mode)
510                 {
511                 case 1:
512                         {
513                                 glBegin(GL_LINES);
514                                 vindex=0;
515                                 for (unsigned int i=0;i<numindices;i+=2)
516                                 {
517                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
518                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
519                                 }
520                                 glEnd();
521                         }
522                         break;
523                 case 2:
524                         {
525                                 glBegin(GL_QUADS);
526                                 vindex=0;
527                                 if (useObjectColor)
528                                 {
529                                         for (unsigned int i=0;i<numindices;i+=4)
530                                         {
531
532                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
533
534                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
535                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
536                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
537                                                 vindex++;
538                                                 
539                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
540                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
541                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
542                                                 vindex++;
543                                                 
544                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
545                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
546                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
547                                                 vindex++;
548                                                 
549                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
550                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
551                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
552                                                 vindex++;
553                                         }
554                                 }
555                                 else
556                                 {
557                                         for (unsigned int i=0;i<numindices;i+=4)
558                                         {
559                                                 // This looks curiously endian unsafe to me.
560                                                 // However it depends on the way the colors are packed into 
561                                                 // the m_rgba field of RAS_TexVert
562
563                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
564                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
565                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
566                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
567                                                 vindex++;
568                                                 
569                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
570                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
571                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
572                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
573                                                 vindex++;
574                                                 
575                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
576                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
577                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
578                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
579                                                 vindex++;
580                                                 
581                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
582                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
583                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
584                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
585                                                 vindex++;
586                                         }
587                                 }
588                                 glEnd();        
589                                 break;
590                         }
591                 case 0:
592                         {
593                                 glBegin(GL_TRIANGLES);
594                                 vindex=0;
595                                 if (useObjectColor)
596                                 {
597                                         for (unsigned int i=0;i<numindices;i+=3)
598                                         {
599
600                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
601
602                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
603                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
604                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
605                                                 vindex++;
606                                                 
607                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
608                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
609                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
610                                                 vindex++;
611                                                 
612                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
613                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
614                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
615                                                 vindex++;
616                                         }
617                                 }
618                                 else 
619                                 {
620                                         for (unsigned int i=0;i<numindices;i+=3)
621                                         {
622
623                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
624                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
625                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
626                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
627                                                 vindex++;
628                                                 
629                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
630                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
631                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
632                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
633                                                 vindex++;
634                                                 
635                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
636                                                 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
637                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
638                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
639                                                 vindex++;
640                                         }
641                                 }
642                                 glEnd();        
643                                 break;
644                         }
645                 default:
646                         {
647                         }
648                         
649                 } // switch
650         } // for each vertexarray
651
652 }
653
654 void RAS_OpenGLRasterizer::IndexPrimitives_Ex(const vecVertexArray & vertexarrays,
655                                                                         const vecIndexArrays & indexarrays,
656                                                                         int mode,
657                                                                         class RAS_IPolyMaterial* polymat,
658                                                                         class RAS_IRenderTools* rendertools,
659                                                                         bool useObjectColor,
660                                                                         const MT_Vector4& rgbacolor
661                                                                         )
662
663         bool    recalc;
664         GLenum drawmode;
665         switch (mode)
666         {
667         case 0:
668                 drawmode = GL_TRIANGLES;
669                 break;
670         case 1:
671                 drawmode = GL_LINES;
672                 break;
673         case 2:
674                 drawmode = GL_QUADS;
675                 break;
676         default:
677                 drawmode = GL_LINES;
678                 break;
679         }
680         
681         const RAS_TexVert* vertexarray ;
682         unsigned int numindices,vt;
683
684         for (vt=0;vt<vertexarrays.size();vt++)
685         {
686                 vertexarray = &((*vertexarrays[vt]) [0]);
687                 const KX_IndexArray & indexarray = (*indexarrays[vt]);
688                 numindices = indexarray.size();
689                 
690                 if (!numindices)
691                         continue;
692                 
693                 int vindex=0;
694                 switch (mode)
695                 {
696                 case 1:
697                         {
698                                 glBegin(GL_LINES);
699                                 vindex=0;
700                                 for (unsigned int i=0;i<numindices;i+=2)
701                                 {
702                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
703                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
704                                 }
705                                 glEnd();
706                         }
707                         break;
708                 case 2:
709                         {
710                                 glBegin(GL_QUADS);
711                                 vindex=0;
712                                 if (useObjectColor)
713                                 {
714                                         for (unsigned int i=0;i<numindices;i+=4)
715                                         {
716                                                 MT_Point3 mv1, mv2, mv3, mv4, fnor;
717                                                 /* Calc a new face normal */
718
719                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
720                                                         recalc= true;
721                                                 else
722                                                         recalc=false;
723
724                                                 if (recalc){
725                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
726                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
727                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
728                                                         mv4 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
729                                                         
730                                                         fnor = (((mv2-mv1).cross(mv3-mv2))+((mv4-mv3).cross(mv1-mv4))).safe_normalized();
731
732                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
733                                                 }
734
735                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
736
737                                                 if (!recalc)
738                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
739                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
740                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
741                                                 vindex++;
742                                                 
743                                                 if (!recalc)
744                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
745                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
746                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
747                                                 vindex++;
748                                                 
749                                                 if (!recalc)
750                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());                                             
751                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
752                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
753                                                 vindex++;
754                                                 
755                                                 if (!recalc)
756                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
757                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
758                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
759                                                 vindex++;
760                                         }
761                                 }
762                                 else
763                                 {
764                                         for (unsigned int i=0;i<numindices;i+=4)
765                                         {
766                                                 // This looks curiously endian unsafe to me.
767                                                 // However it depends on the way the colors are packed into 
768                                                 // the m_rgba field of RAS_TexVert
769                                                 MT_Point3 mv1, mv2, mv3, mv4, fnor;
770                                                 /* Calc a new face normal */
771
772                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
773                                                         recalc= true;
774                                                 else
775                                                         recalc=false;
776
777
778                                                 if (recalc){
779                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
780                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
781                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
782                                                         mv4 = MT_Point3(vertexarray[(indexarray[vindex+3])].getLocalXYZ());
783                                                         
784                                                         fnor = (((mv2-mv1).cross(mv3-mv2))+((mv4-mv3).cross(mv1-mv4))).safe_normalized();
785
786                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
787                                                 }
788
789                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
790                                                 if (!recalc)
791                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
792                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
793                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
794                                                 vindex++;
795                                                 
796                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
797                                                 if (!recalc)
798                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
799                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
800                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
801                                                 vindex++;
802                                                 
803                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
804                                                 if (!recalc)
805                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
806                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
807                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
808                                                 vindex++;
809                                                 
810                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
811                                                 if (!recalc)
812                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
813                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
814                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
815                                                 vindex++;
816                                         }
817                                 }
818                                 glEnd();        
819                                 break;
820                         }
821                 case 0:
822                         {
823                                 glBegin(GL_TRIANGLES);
824                                 vindex=0;
825                                 if (useObjectColor)
826                                 {
827                                         for (unsigned int i=0;i<numindices;i+=3)
828                                         {
829                                                 MT_Point3 mv1, mv2, mv3, fnor;
830                                                 /* Calc a new face normal */
831
832                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
833                                                         recalc= true;
834                                                 else
835                                                         recalc=false;
836
837                                                 if (recalc){
838                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
839                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
840                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
841                                                         
842                                                         fnor = ((mv2-mv1).cross(mv3-mv2)).safe_normalized();
843                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
844                                                 }
845
846                                                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
847
848                                                 if (!recalc)
849                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
850                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
851                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
852                                                 vindex++;
853                                                 
854                                                 if (!recalc)
855                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
856                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
857                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
858                                                 vindex++;
859                                                 
860                                                 if (!recalc)
861                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
862                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
863                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
864                                                 vindex++;
865                                         }
866                                 }
867                                 else 
868                                 {
869                                         for (unsigned int i=0;i<numindices;i+=3)
870                                         {
871                                                 MT_Point3 mv1, mv2, mv3, fnor;
872                                                 /* Calc a new face normal */
873
874                                                 if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
875                                                         recalc= true;
876                                                 else
877                                                         recalc=false;
878
879
880                                                 if (recalc){
881                                                         mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
882                                                         mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
883                                                         mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
884                                                         
885                                                         fnor = ((mv2-mv1).cross(mv3-mv2)).safe_normalized();
886                                                         glNormal3f(fnor[0], fnor[1], fnor[2]);
887                                                 }
888
889                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
890                                                 if (!recalc)
891                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
892                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
893                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
894                                                 vindex++;
895                                                 
896                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
897                                                 if (!recalc)
898                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
899                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
900                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
901                                                 vindex++;
902                                                 
903                                                 glColor4ubv((const GLubyte *)&(vertexarray[(indexarray[vindex])].getRGBA()));
904                                                 if (!recalc)
905                                                         glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
906                                                 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
907                                                 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
908                                                 vindex++;
909                                         }
910                                 }
911                                 glEnd();        
912                                 break;
913                         }
914                 default:
915                         {
916                         }
917                         
918                 } // switch
919         } // for each vertexarray
920
921 }
922
923
924
925 void RAS_OpenGLRasterizer::IndexPrimitives_3DText(const vecVertexArray & vertexarrays,
926                                                                         const vecIndexArrays & indexarrays,
927                                                                         int mode,
928                                                                         class RAS_IPolyMaterial* polymat,
929                                                                         class RAS_IRenderTools* rendertools,
930                                                                         bool useObjectColor,
931                                                                         const MT_Vector4& rgbacolor
932                                                                         )
933
934         GLenum drawmode;
935         switch (mode)
936         {
937         case 0:
938                 drawmode = GL_TRIANGLES;
939                 break;
940         case 1:
941                 drawmode = GL_LINES;
942                 break;
943         case 2:
944                 drawmode = GL_QUADS;
945                 break;
946         default:
947                 drawmode = GL_LINES;
948                 break;
949         }
950         
951         const RAS_TexVert* vertexarray ;
952         
953         unsigned int numindices, vt;
954         
955         if (useObjectColor)
956         {
957                 glDisableClientState(GL_COLOR_ARRAY);
958                 glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
959         }
960         else
961         {
962                 glEnableClientState(GL_COLOR_ARRAY);
963         }
964         
965         for (vt=0;vt<vertexarrays.size();vt++)
966         {
967                 vertexarray = &((*vertexarrays[vt]) [0]);
968                 const KX_IndexArray & indexarray = (*indexarrays[vt]);
969                 numindices = indexarray.size();
970                 
971                 if (!numindices)
972                         break;
973                 
974                 int vindex=0;
975                 switch (mode)
976                 {
977                 case 1:
978                         {
979                                 glBegin(GL_LINES);
980                                 vindex=0;
981                                 for (unsigned int i=0;i<numindices;i+=2)
982                                 {
983                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
984                                         glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
985                                 }
986                                 glEnd();
987                         }
988                         break;
989                 case 2:
990                         {
991                                 vindex=0;
992                                 for (unsigned int i=0;i<numindices;i+=4)
993                                 {
994                                         float v1[3],v2[3],v3[3],v4[3];
995                                         
996                                         char *cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
997                                         v1[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
998                                         v1[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
999                                         v1[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1000                                         vindex++;
1001                                         
1002                                         cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
1003                                         v2[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1004                                         v2[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1005                                         v2[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1006                                         vindex++;
1007                                         
1008                                         cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
1009                                         v3[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1010                                         v3[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1011                                         v3[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1012                                         vindex++;
1013                                         
1014                                         cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
1015                                         v4[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1016                                         v4[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1017                                         v4[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1018                                         
1019                                         vindex++;
1020                                         
1021                                         rendertools->RenderText(polymat->GetDrawingMode(),polymat,v1,v2,v3,v4);
1022                                         ClearCachingInfo();
1023                                 }
1024                                 break;
1025                         }
1026                 case 0:
1027                         {
1028                                 glBegin(GL_TRIANGLES);
1029                                 vindex=0;
1030                                 for (unsigned int i=0;i<numindices;i+=3)
1031                                 {
1032                                         float v1[3],v2[3],v3[3];
1033                                         
1034                                         v1[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1035                                         v1[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1036                                         v1[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1037                                         vindex++;
1038                                         
1039                                         v2[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1040                                         v2[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1041                                         v2[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1042                                         vindex++;
1043                                         
1044                                         v3[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
1045                                         v3[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
1046                                         v3[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
1047                                         vindex++;
1048                                         
1049                                         rendertools->RenderText(polymat->GetDrawingMode(),polymat,v1,v2,v3,NULL);               
1050                                         ClearCachingInfo();
1051                                 }
1052                                 glEnd();        
1053                                 break;
1054                         }
1055                 default:
1056                         {
1057                         }
1058                 }       //switch
1059         }       //for each vertexarray
1060 }
1061
1062
1063
1064 void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat)
1065 {
1066         glMatrixMode(GL_PROJECTION);
1067         double* matrix = &mat(0,0);
1068         glLoadMatrixd(matrix);
1069 }
1070
1071
1072 void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat)
1073 {
1074         glMatrixMode(GL_PROJECTION);
1075         double matrix[16];
1076         /* Get into argument. Looks a bit dodgy, but it's ok. */
1077         mat.getValue(matrix);
1078         /* Internally, MT_Matrix4x4 uses doubles (MT_Scalar). */
1079         glLoadMatrixd(matrix);  
1080 }
1081
1082 MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
1083         float left,
1084         float right,
1085         float bottom,
1086         float top,
1087         float frustnear,
1088         float frustfar,
1089         bool perspective
1090 ){
1091         MT_Matrix4x4 result;
1092         double mat[16];
1093
1094         // correction for stereo
1095         if(m_stereomode != RAS_STEREO_NOSTEREO)
1096         {
1097                         float near_div_focallength;
1098                         // next 2 params should be specified on command line and in Blender publisher
1099                         m_focallength = 1.5 * right;  // derived from example
1100                         m_eyeseparation = 0.18 * right;  // just a guess...
1101
1102                         near_div_focallength = frustnear / m_focallength;
1103                         switch(m_curreye)
1104                         {
1105                                 case RAS_STEREO_LEFTEYE:
1106                                                 left += 0.5 * m_eyeseparation * near_div_focallength;
1107                                                 right += 0.5 * m_eyeseparation * near_div_focallength;
1108                                                 break;
1109                                 case RAS_STEREO_RIGHTEYE:
1110                                                 left -= 0.5 * m_eyeseparation * near_div_focallength;
1111                                                 right -= 0.5 * m_eyeseparation * near_div_focallength;
1112                                                 break;
1113                         }
1114                         // leave bottom, top, bottom and top untouched
1115         }
1116         
1117         glMatrixMode(GL_PROJECTION);
1118         glLoadIdentity();
1119         glFrustum(left, right, bottom, top, frustnear, frustfar);
1120                 
1121         glGetDoublev(GL_PROJECTION_MATRIX, mat);
1122         result.setValue(mat);
1123
1124         return result;
1125 }
1126
1127
1128 // next arguments probably contain redundant info, for later...
1129 void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, const MT_Vector3& campos,
1130                 const MT_Point3 &camLoc, const MT_Quaternion &camOrientQuat)
1131 {
1132         MT_Matrix4x4 viewMat = mat;
1133
1134         // correction for stereo
1135         if(m_stereomode != RAS_STEREO_NOSTEREO)
1136         {
1137                 MT_Matrix3x3 camOrientMat3x3(camOrientQuat);
1138                 MT_Vector3 unitViewDir(0.0, -1.0, 0.0);  // minus y direction, Blender convention
1139                 MT_Vector3 unitViewupVec(0.0, 0.0, 1.0);
1140                 MT_Vector3 viewDir, viewupVec;
1141                 MT_Vector3 eyeline;
1142
1143                 // actual viewDir
1144                 viewDir = camOrientMat3x3 * unitViewDir;  // this is the moto convention, vector on right hand side
1145                 // actual viewup vec
1146                 viewupVec = camOrientMat3x3 * unitViewupVec;
1147
1148                 // vector between eyes
1149                 eyeline = viewDir.cross(viewupVec);
1150
1151                 switch(m_curreye)
1152                 {
1153                         case RAS_STEREO_LEFTEYE:
1154                                 {
1155                                 // translate to left by half the eye distance
1156                                 MT_Transform transform;
1157                                 transform.setIdentity();
1158                                 transform.translate(-(eyeline * m_eyeseparation / 2.0));
1159                                 viewMat *= transform;
1160                                 }
1161                                 break;
1162                         case RAS_STEREO_RIGHTEYE:
1163                                 {
1164                                 // translate to right by half the eye distance
1165                                 MT_Transform transform;
1166                                 transform.setIdentity();
1167                                 transform.translate(eyeline * m_eyeseparation / 2.0);
1168                                 viewMat *= transform;
1169                                 }
1170                                 break;
1171                 }
1172         }
1173
1174         // convert row major matrix 'viewMat' to column major for OpenGL
1175         MT_Scalar cammat[16];
1176         viewMat.getValue(cammat);
1177         MT_CmMatrix4x4 viewCmmat = cammat;
1178
1179         glMatrixMode(GL_MODELVIEW);
1180         m_viewmatrix = viewCmmat;
1181         glLoadMatrixd(&m_viewmatrix(0,0));
1182         m_campos = campos;
1183 }
1184
1185
1186 const MT_Point3& RAS_OpenGLRasterizer::GetCameraPosition()
1187 {
1188         return m_campos;
1189 }
1190
1191
1192
1193 void RAS_OpenGLRasterizer::LoadViewMatrix()
1194 {
1195         glLoadMatrixd(&m_viewmatrix(0,0));
1196 }
1197
1198
1199
1200 void RAS_OpenGLRasterizer::EnableTextures(bool enable)
1201 {
1202 }
1203
1204
1205
1206 void RAS_OpenGLRasterizer::SetCullFace(bool enable)
1207 {
1208         if (enable)
1209                 glEnable(GL_CULL_FACE);
1210         else
1211                 glDisable(GL_CULL_FACE);
1212 }
1213
1214 void RAS_OpenGLRasterizer::SetLines(bool enable)
1215 {
1216         if (enable)
1217                 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1218         else
1219                 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1220 }
1221
1222 void RAS_OpenGLRasterizer::SetSpecularity(float specX,
1223                                                                                   float specY,
1224                                                                                   float specZ,
1225                                                                                   float specval)
1226 {
1227         GLfloat mat_specular[] = {specX, specY, specZ, specval};
1228         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
1229 }
1230
1231
1232
1233 void RAS_OpenGLRasterizer::SetShinyness(float shiny)
1234 {
1235         GLfloat mat_shininess[] = {     shiny };
1236         glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
1237 }
1238
1239
1240
1241 void RAS_OpenGLRasterizer::SetDiffuse(float difX,float difY,float difZ,float diffuse)
1242 {
1243         GLfloat mat_diffuse [] = {difX, difY,difZ, diffuse};
1244         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
1245 }
1246
1247 double RAS_OpenGLRasterizer::GetTime()
1248 {
1249         return m_time;
1250 }
1251
1252