BGE Rasterizer Cleanup: Removing RAS_IRenderTools and moving the functionality to...
[blender.git] / source / gameengine / Rasterizer / RAS_OpenGLRasterizer / RAS_OpenGLRasterizer.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
29  *  \ingroup bgerastogl
30  */
31
32  
33 #include <math.h>
34 #include <stdlib.h>
35  
36 #include "RAS_OpenGLRasterizer.h"
37
38 #include "GL/glew.h"
39
40 #include "RAS_Rect.h"
41 #include "RAS_TexVert.h"
42 #include "RAS_MeshObject.h"
43 #include "RAS_LightObject.h"
44 #include "MT_CmMatrix4x4.h"
45
46 #include "RAS_StorageIM.h"
47 #include "RAS_StorageVA.h"
48 #include "RAS_StorageVBO.h"
49
50 #include "GPU_draw.h"
51 #include "GPU_material.h"
52 #include "GPU_extensions.h"
53
54 #include "DNA_image_types.h"
55 #include "DNA_meshdata_types.h"
56 #include "DNA_material_types.h"
57 #include "DNA_scene_types.h"
58
59 extern "C"{
60         #include "BLI_utildefines.h"
61         #include "BKE_DerivedMesh.h"
62         #include "BLF_api.h"
63 }
64
65
66 // XXX Clean these up <<<
67 #include "BL_Material.h" // MAXTEX
68 #include "Value.h"
69 #include "KX_BlenderMaterial.h"
70 #include "KX_PolygonMaterial.h"
71 #include "KX_Light.h"
72 #include "KX_Scene.h"
73 #include "KX_RayCast.h"
74 #include "KX_GameObject.h"
75 // >>>
76
77 #ifndef M_PI
78 #define M_PI            3.14159265358979323846
79 #endif
80
81 /**
82  *  32x32 bit masks for vinterlace stereo mode
83  */
84 static GLuint left_eye_vinterlace_mask[32];
85 static GLuint right_eye_vinterlace_mask[32];
86
87 /**
88  *  32x32 bit masks for hinterlace stereo mode.
89  *  Left eye = &hinterlace_mask[0]
90  *  Right eye = &hinterlace_mask[1]
91  */
92 static GLuint hinterlace_mask[33];
93
94 RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas, int storage)
95         :RAS_IRasterizer(canvas),
96         m_2DCanvas(canvas),
97         m_fogenabled(false),
98         m_time(0.0),
99         m_campos(0.0f, 0.0f, 0.0f),
100         m_camortho(false),
101         m_stereomode(RAS_STEREO_NOSTEREO),
102         m_curreye(RAS_STEREO_LEFTEYE),
103         m_eyeseparation(0.0),
104         m_focallength(0.0),
105         m_setfocallength(false),
106         m_noOfScanlines(32),
107         m_motionblur(0),
108         m_motionblurvalue(-1.0),
109         m_usingoverrideshader(false),
110     m_clientobject(NULL),
111     m_auxilaryClientInfo(NULL),
112         m_texco_num(0),
113         m_attrib_num(0),
114         //m_last_alphablend(GPU_BLEND_SOLID),
115         m_last_frontface(true),
116         m_materialCachingInfo(0),
117         m_storage_type(storage)
118 {
119         m_viewmatrix.setIdentity();
120         m_viewinvmatrix.setIdentity();
121         
122         for (int i = 0; i < 32; i++)
123         {
124                 left_eye_vinterlace_mask[i] = 0x55555555;
125                 right_eye_vinterlace_mask[i] = 0xAAAAAAAA;
126                 hinterlace_mask[i] = (i&1)*0xFFFFFFFF;
127         }
128         hinterlace_mask[32] = 0;
129
130         m_prevafvalue = GPU_get_anisotropic();
131
132         if (m_storage_type == RAS_VBO /*|| m_storage_type == RAS_AUTO_STORAGE && GLEW_ARB_vertex_buffer_object*/)
133         {
134                 m_storage = new RAS_StorageVBO(&m_texco_num, m_texco, &m_attrib_num, m_attrib, m_attrib_layer);
135                 m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib, m_attrib_layer);
136                 m_storage_type = RAS_VBO;
137         }
138         else if ((m_storage_type == RAS_VA) || (m_storage_type == RAS_AUTO_STORAGE && GLEW_VERSION_1_1))
139         {
140                 m_storage = new RAS_StorageVA(&m_texco_num, m_texco, &m_attrib_num, m_attrib, m_attrib_layer);
141                 m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib, m_attrib_layer);
142                 m_storage_type = RAS_VA;
143         }
144         else
145         {
146                 m_storage = m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib, m_attrib_layer);
147                 m_storage_type = RAS_IMMEDIATE;
148         }
149
150         glGetIntegerv(GL_MAX_LIGHTS, (GLint *) &m_numgllights);
151         if (m_numgllights < 8)
152                 m_numgllights = 8;
153 }
154
155
156
157 RAS_OpenGLRasterizer::~RAS_OpenGLRasterizer()
158 {
159         // Restore the previous AF value
160         GPU_set_anisotropic(m_prevafvalue);
161         if (m_failsafe_storage && m_failsafe_storage != m_storage)
162                 delete m_failsafe_storage;
163
164         if (m_storage)
165                 delete m_storage;
166 }
167
168 bool RAS_OpenGLRasterizer::Init()
169 {
170         bool storage_init;
171         GPU_state_init();
172
173
174         m_ambr = 0.0f;
175         m_ambg = 0.0f;
176         m_ambb = 0.0f;
177
178         glDisable(GL_BLEND);
179         glDisable(GL_ALPHA_TEST);
180         //m_last_alphablend = GPU_BLEND_SOLID;
181         GPU_set_material_alpha_blend(GPU_BLEND_SOLID);
182
183         glFrontFace(GL_CCW);
184         m_last_frontface = true;
185
186         m_redback = 0.4375;
187         m_greenback = 0.4375;
188         m_blueback = 0.4375;
189         m_alphaback = 0.0;
190
191         glClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
192         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
193         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
194
195
196         glShadeModel(GL_SMOOTH);
197
198         storage_init = m_storage->Init();
199
200         return true && storage_init;
201 }
202
203
204 void RAS_OpenGLRasterizer::SetAmbientColor(float red, float green, float blue)
205 {
206         m_ambr = red;
207         m_ambg = green;
208         m_ambb = blue;
209 }
210
211
212 void RAS_OpenGLRasterizer::SetAmbient(float factor)
213 {
214         float ambient[] = { m_ambr*factor, m_ambg*factor, m_ambb*factor, 1.0f };
215         glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
216 }
217
218
219 void RAS_OpenGLRasterizer::SetBackColor(float red,
220                                                                                 float green,
221                                                                                 float blue,
222                                                                                 float alpha)
223 {
224         m_redback = red;
225         m_greenback = green;
226         m_blueback = blue;
227         m_alphaback = alpha;
228 }
229
230
231
232 void RAS_OpenGLRasterizer::SetFogColor(float r,
233                                                                            float g,
234                                                                            float b)
235 {
236         m_fogr = r;
237         m_fogg = g;
238         m_fogb = b;
239         m_fogenabled = true;
240 }
241
242
243
244 void RAS_OpenGLRasterizer::SetFogStart(float start)
245 {
246         m_fogstart = start;
247         m_fogenabled = true;
248 }
249
250
251
252 void RAS_OpenGLRasterizer::SetFogEnd(float fogend)
253 {
254         m_fogdist = fogend;
255         m_fogenabled = true;
256 }
257
258
259
260 void RAS_OpenGLRasterizer::SetFog(float start,
261                                                                   float dist,
262                                                                   float r,
263                                                                   float g,
264                                                                   float b)
265 {
266         m_fogstart = start;
267         m_fogdist = dist;
268         m_fogr = r;
269         m_fogg = g;
270         m_fogb = b;
271         m_fogenabled = true;
272 }
273
274
275
276 void RAS_OpenGLRasterizer::DisableFog()
277 {
278         m_fogenabled = false;
279 }
280
281 bool RAS_OpenGLRasterizer::IsFogEnabled()
282 {
283         return m_fogenabled;
284 }
285
286
287 void RAS_OpenGLRasterizer::DisplayFog()
288 {
289         if ((m_drawingmode >= KX_SOLID) && m_fogenabled)
290         {
291                 float params[5];
292                 glFogi(GL_FOG_MODE, GL_LINEAR);
293                 glFogf(GL_FOG_DENSITY, 0.1f);
294                 glFogf(GL_FOG_START, m_fogstart);
295                 glFogf(GL_FOG_END, m_fogstart + m_fogdist);
296                 params[0] = m_fogr;
297                 params[1] = m_fogg;
298                 params[2] = m_fogb;
299                 params[3] = 0.0;
300                 glFogfv(GL_FOG_COLOR, params); 
301                 glEnable(GL_FOG);
302         } 
303         else
304         {
305                 glDisable(GL_FOG);
306         }
307 }
308
309
310
311 bool RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat)
312 {
313         return mat.Activate(this, m_materialCachingInfo);
314 }
315
316
317
318 void RAS_OpenGLRasterizer::Exit()
319 {
320
321         m_storage->Exit();
322
323         glEnable(GL_CULL_FACE);
324         glEnable(GL_DEPTH_TEST);
325         glClearDepth(1.0); 
326         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
327         glClearColor(m_redback, m_greenback, m_blueback, m_alphaback);
328         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
329         glDepthMask (GL_TRUE);
330         glDepthFunc(GL_LEQUAL);
331         glBlendFunc(GL_ONE, GL_ZERO);
332         
333         glDisable(GL_POLYGON_STIPPLE);
334         
335         glDisable(GL_LIGHTING);
336         if (GLEW_EXT_separate_specular_color || GLEW_VERSION_1_2)
337                 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
338         
339         EndFrame();
340 }
341
342 bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
343 {
344         m_time = time;
345         SetDrawingMode(drawingmode);
346
347         // Blender camera routine destroys the settings
348         if (m_drawingmode < KX_SOLID)
349         {
350                 glDisable(GL_CULL_FACE);
351                 glDisable(GL_DEPTH_TEST);
352         }
353         else
354         {
355                 glEnable(GL_DEPTH_TEST);
356                 glEnable(GL_CULL_FACE);
357         }
358
359         glDisable(GL_BLEND);
360         glDisable(GL_ALPHA_TEST);
361         //m_last_alphablend = GPU_BLEND_SOLID;
362         GPU_set_material_alpha_blend(GPU_BLEND_SOLID);
363
364         glFrontFace(GL_CCW);
365         m_last_frontface = true;
366
367         glShadeModel(GL_SMOOTH);
368
369         glEnable(GL_MULTISAMPLE_ARB);
370
371         m_2DCanvas->BeginFrame();
372
373         // Render Tools
374         m_clientobject = NULL;
375         m_lastlightlayer = -1;
376         m_lastauxinfo = NULL;
377         m_lastlighting = true; /* force disable in DisableOpenGLLights() */
378         DisableOpenGLLights();
379         
380         return true;
381 }
382
383
384
385 void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode)
386 {
387         m_drawingmode = drawingmode;
388
389         if (m_drawingmode == KX_WIREFRAME)
390                 glDisable(GL_CULL_FACE);
391
392         m_storage->SetDrawingMode(drawingmode);
393         if (m_failsafe_storage && m_failsafe_storage != m_storage) {
394                 m_failsafe_storage->SetDrawingMode(drawingmode);
395         }
396 }
397
398 int RAS_OpenGLRasterizer::GetDrawingMode()
399 {
400         return m_drawingmode;
401 }
402
403
404 void RAS_OpenGLRasterizer::SetDepthMask(DepthMask depthmask)
405 {
406         glDepthMask(depthmask == KX_DEPTHMASK_DISABLED ? GL_FALSE : GL_TRUE);
407 }
408
409
410 void RAS_OpenGLRasterizer::ClearColorBuffer()
411 {
412         m_2DCanvas->ClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
413         m_2DCanvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER);
414 }
415
416
417 void RAS_OpenGLRasterizer::ClearDepthBuffer()
418 {
419         m_2DCanvas->ClearBuffer(RAS_ICanvas::DEPTH_BUFFER);
420 }
421
422
423 void RAS_OpenGLRasterizer::ClearCachingInfo(void)
424 {
425         m_materialCachingInfo = 0;
426 }
427
428 void RAS_OpenGLRasterizer::FlushDebugShapes()
429 {
430         if (m_debugShapes.empty())
431                 return;
432
433         // DrawDebugLines
434         GLboolean light, tex;
435
436         light= glIsEnabled(GL_LIGHTING);
437         tex= glIsEnabled(GL_TEXTURE_2D);
438
439         if (light) glDisable(GL_LIGHTING);
440         if (tex) glDisable(GL_TEXTURE_2D);
441
442         //draw lines
443         glBegin(GL_LINES);
444         for (unsigned int i=0;i<m_debugShapes.size();i++)
445         {
446                 if (m_debugShapes[i].m_type != OglDebugShape::LINE)
447                         continue;
448                 glColor4f(m_debugShapes[i].m_color[0],m_debugShapes[i].m_color[1],m_debugShapes[i].m_color[2],1.f);
449                 const MT_Scalar* fromPtr = &m_debugShapes[i].m_pos.x();
450                 const MT_Scalar* toPtr= &m_debugShapes[i].m_param.x();
451                 glVertex3dv(fromPtr);
452                 glVertex3dv(toPtr);
453         }
454         glEnd();
455
456         //draw circles
457         for (unsigned int i=0;i<m_debugShapes.size();i++)
458         {
459                 if (m_debugShapes[i].m_type != OglDebugShape::CIRCLE)
460                         continue;
461                 glBegin(GL_LINE_LOOP);
462                 glColor4f(m_debugShapes[i].m_color[0],m_debugShapes[i].m_color[1],m_debugShapes[i].m_color[2],1.f);
463
464                 static const MT_Vector3 worldUp(0.0, 0.0, 1.0);
465                 MT_Vector3 norm = m_debugShapes[i].m_param;
466                 MT_Matrix3x3 tr;
467                 if (norm.fuzzyZero() || norm == worldUp)
468                 {
469                         tr.setIdentity();
470                 }
471                 else
472                 {
473                         MT_Vector3 xaxis, yaxis;
474                         xaxis = MT_cross(norm, worldUp);
475                         yaxis = MT_cross(xaxis, norm);
476                         tr.setValue(xaxis.x(), xaxis.y(), xaxis.z(),
477                                 yaxis.x(), yaxis.y(), yaxis.z(),
478                                 norm.x(), norm.y(), norm.z());
479                 }
480                 MT_Scalar rad = m_debugShapes[i].m_param2.x();
481                 int n = (int) m_debugShapes[i].m_param2.y();
482                 for (int j = 0; j<n; j++)
483                 {
484                         MT_Scalar theta = j*M_PI*2/n;
485                         MT_Vector3 pos(cos(theta) * rad, sin(theta) * rad, 0.0);
486                         pos = pos*tr;
487                         pos += m_debugShapes[i].m_pos;
488                         const MT_Scalar* posPtr = &pos.x();
489                         glVertex3dv(posPtr);
490                 }
491                 glEnd();
492         }
493
494         if (light) glEnable(GL_LIGHTING);
495         if (tex) glEnable(GL_TEXTURE_2D);
496
497         m_debugShapes.clear();
498 }
499
500 void RAS_OpenGLRasterizer::EndFrame()
501 {
502         FlushDebugShapes();
503
504         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
505
506         glDisable(GL_MULTISAMPLE_ARB);
507
508         m_2DCanvas->EndFrame();
509 }
510
511 void RAS_OpenGLRasterizer::SetRenderArea()
512 {
513         RAS_Rect area;
514         // only above/below stereo method needs viewport adjustment
515         switch (m_stereomode)
516         {
517                 case RAS_STEREO_ABOVEBELOW:
518                         switch (m_curreye) {
519                                 case RAS_STEREO_LEFTEYE:
520                                         // upper half of window
521                                         area.SetLeft(0);
522                                         area.SetBottom(m_2DCanvas->GetHeight() -
523                                                 int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
524         
525                                         area.SetRight(int(m_2DCanvas->GetWidth()));
526                                         area.SetTop(int(m_2DCanvas->GetHeight()));
527                                         m_2DCanvas->SetDisplayArea(&area);
528                                         break;
529                                 case RAS_STEREO_RIGHTEYE:
530                                         // lower half of window
531                                         area.SetLeft(0);
532                                         area.SetBottom(0);
533                                         area.SetRight(int(m_2DCanvas->GetWidth()));
534                                         area.SetTop(int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
535                                         m_2DCanvas->SetDisplayArea(&area);
536                                         break;
537                         }
538                         break;
539                 case RAS_STEREO_SIDEBYSIDE:
540                         switch (m_curreye)
541                         {
542                                 case RAS_STEREO_LEFTEYE:
543                                         // Left half of window
544                                         area.SetLeft(0);
545                                         area.SetBottom(0);
546                                         area.SetRight(m_2DCanvas->GetWidth()/2);
547                                         area.SetTop(m_2DCanvas->GetHeight());
548                                         m_2DCanvas->SetDisplayArea(&area);
549                                         break;
550                                 case RAS_STEREO_RIGHTEYE:
551                                         // Right half of window
552                                         area.SetLeft(m_2DCanvas->GetWidth()/2);
553                                         area.SetBottom(0);
554                                         area.SetRight(m_2DCanvas->GetWidth());
555                                         area.SetTop(m_2DCanvas->GetHeight());
556                                         m_2DCanvas->SetDisplayArea(&area);
557                                         break;
558                         }
559                         break;
560                 default:
561                         // every available pixel
562                         area.SetLeft(0);
563                         area.SetBottom(0);
564                         area.SetRight(int(m_2DCanvas->GetWidth()));
565                         area.SetTop(int(m_2DCanvas->GetHeight()));
566                         m_2DCanvas->SetDisplayArea(&area);
567                         break;
568         }
569 }
570         
571 void RAS_OpenGLRasterizer::SetStereoMode(const StereoMode stereomode)
572 {
573         m_stereomode = stereomode;
574 }
575
576 RAS_IRasterizer::StereoMode RAS_OpenGLRasterizer::GetStereoMode()
577 {
578         return m_stereomode;
579 }
580
581 bool RAS_OpenGLRasterizer::Stereo()
582 {
583         if (m_stereomode > RAS_STEREO_NOSTEREO) // > 0
584                 return true;
585         else
586                 return false;
587 }
588
589 bool RAS_OpenGLRasterizer::InterlacedStereo()
590 {
591         return m_stereomode == RAS_STEREO_VINTERLACE || m_stereomode == RAS_STEREO_INTERLACED;
592 }
593
594 void RAS_OpenGLRasterizer::SetEye(const StereoEye eye)
595 {
596         m_curreye = eye;
597         switch (m_stereomode)
598         {
599                 case RAS_STEREO_QUADBUFFERED:
600                         glDrawBuffer(m_curreye == RAS_STEREO_LEFTEYE ? GL_BACK_LEFT : GL_BACK_RIGHT);
601                         break;
602                 case RAS_STEREO_ANAGLYPH:
603                         if (m_curreye == RAS_STEREO_LEFTEYE) {
604                                 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
605                         }
606                         else {
607                                 //glAccum(GL_LOAD, 1.0);
608                                 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_FALSE);
609                                 ClearDepthBuffer();
610                         }
611                         break;
612                 case RAS_STEREO_VINTERLACE:
613                 {
614                         glEnable(GL_POLYGON_STIPPLE);
615                         glPolygonStipple((const GLubyte*) ((m_curreye == RAS_STEREO_LEFTEYE) ? left_eye_vinterlace_mask : right_eye_vinterlace_mask));
616                         if (m_curreye == RAS_STEREO_RIGHTEYE)
617                                 ClearDepthBuffer();
618                         break;
619                 }
620                 case RAS_STEREO_INTERLACED:
621                 {
622                         glEnable(GL_POLYGON_STIPPLE);
623                         glPolygonStipple((const GLubyte*) &hinterlace_mask[m_curreye == RAS_STEREO_LEFTEYE?0:1]);
624                         if (m_curreye == RAS_STEREO_RIGHTEYE)
625                                 ClearDepthBuffer();
626                         break;
627                 }
628                 default:
629                         break;
630         }
631 }
632
633 RAS_IRasterizer::StereoEye RAS_OpenGLRasterizer::GetEye()
634 {
635         return m_curreye;
636 }
637
638
639 void RAS_OpenGLRasterizer::SetEyeSeparation(const float eyeseparation)
640 {
641         m_eyeseparation = eyeseparation;
642 }
643
644 float RAS_OpenGLRasterizer::GetEyeSeparation()
645 {
646         return m_eyeseparation;
647 }
648
649 void RAS_OpenGLRasterizer::SetFocalLength(const float focallength)
650 {
651         m_focallength = focallength;
652         m_setfocallength = true;
653 }
654
655 float RAS_OpenGLRasterizer::GetFocalLength()
656 {
657         return m_focallength;
658 }
659
660
661 void RAS_OpenGLRasterizer::SwapBuffers()
662 {
663         m_2DCanvas->SwapBuffers();
664 }
665
666
667
668 const MT_Matrix4x4& RAS_OpenGLRasterizer::GetViewMatrix() const
669 {
670         return m_viewmatrix;
671 }
672
673 const MT_Matrix4x4& RAS_OpenGLRasterizer::GetViewInvMatrix() const
674 {
675         return m_viewinvmatrix;
676 }
677
678 void RAS_OpenGLRasterizer::IndexPrimitives_3DText(RAS_MeshSlot& ms,
679                                                                         class RAS_IPolyMaterial* polymat)
680
681         bool obcolor = ms.m_bObjectColor;
682         MT_Vector4& rgba = ms.m_RGBAcolor;
683         RAS_MeshSlot::iterator it;
684
685         // handle object color
686         if (obcolor) {
687                 glDisableClientState(GL_COLOR_ARRAY);
688                 glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
689         }
690         else
691                 glEnableClientState(GL_COLOR_ARRAY);
692
693         for (ms.begin(it); !ms.end(it); ms.next(it)) {
694                 RAS_TexVert *vertex;
695                 size_t i, j, numvert;
696                 
697                 numvert = it.array->m_type;
698
699                 if (it.array->m_type == RAS_DisplayArray::LINE) {
700                         // line drawing, no text
701                         glBegin(GL_LINES);
702
703                         for (i=0; i<it.totindex; i+=2)
704                         {
705                                 vertex = &it.vertex[it.index[i]];
706                                 glVertex3fv(vertex->getXYZ());
707
708                                 vertex = &it.vertex[it.index[i+1]];
709                                 glVertex3fv(vertex->getXYZ());
710                         }
711
712                         glEnd();
713                 }
714                 else {
715                         // triangle and quad text drawing
716                         for (i=0; i<it.totindex; i+=numvert)
717                         {
718                                 float v[4][3];
719                                 int glattrib, unit;
720
721                                 for (j=0; j<numvert; j++) {
722                                         vertex = &it.vertex[it.index[i+j]];
723
724                                         v[j][0] = vertex->getXYZ()[0];
725                                         v[j][1] = vertex->getXYZ()[1];
726                                         v[j][2] = vertex->getXYZ()[2];
727                                 }
728
729                                 // find the right opengl attribute
730                                 glattrib = -1;
731                                 if (GLEW_ARB_vertex_program)
732                                         for (unit=0; unit<m_attrib_num; unit++)
733                                                 if (m_attrib[unit] == RAS_TEXCO_UV)
734                                                         glattrib = unit;
735                                 
736                                 RenderText(polymat->GetDrawingMode(), polymat,
737                                         v[0], v[1], v[2], (numvert == 4)? v[3]: NULL, glattrib);
738
739                                 ClearCachingInfo();
740                         }
741                 }
742         }
743
744         glDisableClientState(GL_COLOR_ARRAY);
745 }
746
747 void RAS_OpenGLRasterizer::SetTexCoordNum(int num)
748 {
749         m_texco_num = num;
750         if (m_texco_num > RAS_MAX_TEXCO)
751                 m_texco_num = RAS_MAX_TEXCO;
752 }
753
754 void RAS_OpenGLRasterizer::SetAttribNum(int num)
755 {
756         m_attrib_num = num;
757         if (m_attrib_num > RAS_MAX_ATTRIB)
758                 m_attrib_num = RAS_MAX_ATTRIB;
759 }
760
761 void RAS_OpenGLRasterizer::SetTexCoord(TexCoGen coords, int unit)
762 {
763         // this changes from material to material
764         if (unit < RAS_MAX_TEXCO)
765                 m_texco[unit] = coords;
766 }
767
768 void RAS_OpenGLRasterizer::SetAttrib(TexCoGen coords, int unit, int layer)
769 {
770         // this changes from material to material
771         if (unit < RAS_MAX_ATTRIB) {
772                 m_attrib[unit] = coords;
773                 m_attrib_layer[unit] = layer;
774         }
775 }
776
777 void RAS_OpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
778 {
779         if (ms.m_pDerivedMesh)
780                 m_failsafe_storage->IndexPrimitives(ms);
781         else
782                 m_storage->IndexPrimitives(ms);
783 }
784
785 void RAS_OpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
786 {
787         if (ms.m_pDerivedMesh)
788                 m_failsafe_storage->IndexPrimitivesMulti(ms);
789         else
790                 m_storage->IndexPrimitivesMulti(ms);
791 }
792
793 void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat)
794 {
795         glMatrixMode(GL_PROJECTION);
796         double* matrix = &mat(0, 0);
797         glLoadMatrixd(matrix);
798
799         m_camortho = (mat(3, 3) != 0.0);
800 }
801
802 void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat)
803 {
804         glMatrixMode(GL_PROJECTION);
805         double matrix[16];
806         /* Get into argument. Looks a bit dodgy, but it's ok. */
807         mat.getValue(matrix);
808         /* Internally, MT_Matrix4x4 uses doubles (MT_Scalar). */
809         glLoadMatrixd(matrix);
810
811         m_camortho= (mat[3][3] != 0.0);
812 }
813
814 MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
815         float left,
816         float right,
817         float bottom,
818         float top,
819         float frustnear,
820         float frustfar,
821         float focallength,
822         bool 
823 ) {
824         MT_Matrix4x4 result;
825         double mat[16];
826
827         // correction for stereo
828         if (Stereo())
829         {
830                         float near_div_focallength;
831                         float offset;
832
833                         // if Rasterizer.setFocalLength is not called we use the camera focallength
834                         if (!m_setfocallength)
835                                 // if focallength is null we use a value known to be reasonable
836                                 m_focallength = (focallength == 0.f) ? m_eyeseparation * 30.0f
837                                         : focallength;
838
839                         near_div_focallength = frustnear / m_focallength;
840                         offset = 0.5f * m_eyeseparation * near_div_focallength;
841                         switch (m_curreye) {
842                                 case RAS_STEREO_LEFTEYE:
843                                                 left += offset;
844                                                 right += offset;
845                                                 break;
846                                 case RAS_STEREO_RIGHTEYE:
847                                                 left -= offset;
848                                                 right -= offset;
849                                                 break;
850                         }
851                         // leave bottom and top untouched
852         }
853         
854         glMatrixMode(GL_PROJECTION);
855         glLoadIdentity();
856         glFrustum(left, right, bottom, top, frustnear, frustfar);
857                 
858         glGetDoublev(GL_PROJECTION_MATRIX, mat);
859         result.setValue(mat);
860
861         return result;
862 }
863
864 MT_Matrix4x4 RAS_OpenGLRasterizer::GetOrthoMatrix(
865         float left,
866         float right,
867         float bottom,
868         float top,
869         float frustnear,
870         float frustfar
871 ) {
872         MT_Matrix4x4 result;
873         double mat[16];
874
875         // stereo is meaning less for orthographic, disable it
876         glMatrixMode(GL_PROJECTION);
877         glLoadIdentity();
878         glOrtho(left, right, bottom, top, frustnear, frustfar);
879                 
880         glGetDoublev(GL_PROJECTION_MATRIX, mat);
881         result.setValue(mat);
882
883         return result;
884 }
885
886
887 // next arguments probably contain redundant info, for later...
888 void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, 
889                                                                                  const MT_Matrix3x3 & camOrientMat3x3,
890                                                                                  const MT_Point3 & pos,
891                                                                                  bool perspective)
892 {
893         m_viewmatrix = mat;
894
895         // correction for stereo
896         if (Stereo() && perspective)
897         {
898                 MT_Vector3 unitViewDir(0.0, -1.0, 0.0);  // minus y direction, Blender convention
899                 MT_Vector3 unitViewupVec(0.0, 0.0, 1.0);
900                 MT_Vector3 viewDir, viewupVec;
901                 MT_Vector3 eyeline;
902
903                 // actual viewDir
904                 viewDir = camOrientMat3x3 * unitViewDir;  // this is the moto convention, vector on right hand side
905                 // actual viewup vec
906                 viewupVec = camOrientMat3x3 * unitViewupVec;
907
908                 // vector between eyes
909                 eyeline = viewDir.cross(viewupVec);
910
911                 switch (m_curreye) {
912                         case RAS_STEREO_LEFTEYE:
913                                 {
914                                 // translate to left by half the eye distance
915                                 MT_Transform transform;
916                                 transform.setIdentity();
917                                 transform.translate(-(eyeline * m_eyeseparation / 2.0));
918                                 m_viewmatrix *= transform;
919                                 }
920                                 break;
921                         case RAS_STEREO_RIGHTEYE:
922                                 {
923                                 // translate to right by half the eye distance
924                                 MT_Transform transform;
925                                 transform.setIdentity();
926                                 transform.translate(eyeline * m_eyeseparation / 2.0);
927                                 m_viewmatrix *= transform;
928                                 }
929                                 break;
930                 }
931         }
932
933         m_viewinvmatrix = m_viewmatrix;
934         m_viewinvmatrix.invert();
935
936         // note: getValue gives back column major as needed by OpenGL
937         MT_Scalar glviewmat[16];
938         m_viewmatrix.getValue(glviewmat);
939
940         glMatrixMode(GL_MODELVIEW);
941         glLoadMatrixd(glviewmat);
942         m_campos = pos;
943 }
944
945
946 const MT_Point3& RAS_OpenGLRasterizer::GetCameraPosition()
947 {
948         return m_campos;
949 }
950
951 bool RAS_OpenGLRasterizer::GetCameraOrtho()
952 {
953         return m_camortho;
954 }
955
956 void RAS_OpenGLRasterizer::SetCullFace(bool enable)
957 {
958         if (enable)
959                 glEnable(GL_CULL_FACE);
960         else
961                 glDisable(GL_CULL_FACE);
962 }
963
964 void RAS_OpenGLRasterizer::SetLines(bool enable)
965 {
966         if (enable)
967                 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
968         else
969                 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
970 }
971
972 void RAS_OpenGLRasterizer::SetSpecularity(float specX,
973                                                                                   float specY,
974                                                                                   float specZ,
975                                                                                   float specval)
976 {
977         GLfloat mat_specular[] = {specX, specY, specZ, specval};
978         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
979 }
980
981
982
983 void RAS_OpenGLRasterizer::SetShinyness(float shiny)
984 {
985         GLfloat mat_shininess[] = {     shiny };
986         glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
987 }
988
989
990
991 void RAS_OpenGLRasterizer::SetDiffuse(float difX,float difY,float difZ,float diffuse)
992 {
993         GLfloat mat_diffuse [] = {difX, difY,difZ, diffuse};
994         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
995 }
996
997 void RAS_OpenGLRasterizer::SetEmissive(float eX, float eY, float eZ, float e)
998 {
999         GLfloat mat_emit [] = {eX,eY,eZ,e};
1000         glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_emit);
1001 }
1002
1003
1004 double RAS_OpenGLRasterizer::GetTime()
1005 {
1006         return m_time;
1007 }
1008
1009 void RAS_OpenGLRasterizer::SetPolygonOffset(float mult, float add)
1010 {
1011         glPolygonOffset(mult, add);
1012         GLint mode = GL_POLYGON_OFFSET_FILL;
1013         if (m_drawingmode < KX_SHADED)
1014                 mode = GL_POLYGON_OFFSET_LINE;
1015         if (mult != 0.0f || add != 0.0f)
1016                 glEnable(mode);
1017         else
1018                 glDisable(mode);
1019 }
1020
1021 void RAS_OpenGLRasterizer::EnableMotionBlur(float motionblurvalue)
1022 {
1023         /* don't just set m_motionblur to 1, but check if it is 0 so
1024          * we don't reset a motion blur that is already enabled */
1025         if (m_motionblur == 0)
1026                 m_motionblur = 1;
1027         m_motionblurvalue = motionblurvalue;
1028 }
1029
1030 void RAS_OpenGLRasterizer::DisableMotionBlur()
1031 {
1032         m_motionblur = 0;
1033         m_motionblurvalue = -1.0;
1034 }
1035
1036 void RAS_OpenGLRasterizer::SetAlphaBlend(int alphablend)
1037 {
1038         /* Variance shadow maps don't handle alpha well, best to not allow it for now  */
1039         if (m_drawingmode == KX_SHADOW && m_usingoverrideshader)
1040                 GPU_set_material_alpha_blend(GPU_BLEND_SOLID);
1041         else
1042                 GPU_set_material_alpha_blend(alphablend);
1043 /*
1044         if (alphablend == m_last_alphablend)
1045                 return;
1046
1047         if (alphablend == GPU_BLEND_SOLID) {
1048                 glDisable(GL_BLEND);
1049                 glDisable(GL_ALPHA_TEST);
1050                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1051         }
1052         else if (alphablend == GPU_BLEND_ADD) {
1053                 glBlendFunc(GL_ONE, GL_ONE);
1054                 glEnable(GL_BLEND);
1055                 glDisable(GL_ALPHA_TEST);
1056         }
1057         else if (alphablend == GPU_BLEND_ALPHA) {
1058                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1059                 glEnable(GL_BLEND);
1060                 glEnable(GL_ALPHA_TEST);
1061                 glAlphaFunc(GL_GREATER, 0.0f);
1062         }
1063         else if (alphablend == GPU_BLEND_CLIP) {
1064                 glDisable(GL_BLEND); 
1065                 glEnable(GL_ALPHA_TEST);
1066                 glAlphaFunc(GL_GREATER, 0.5f);
1067         }
1068
1069         m_last_alphablend = alphablend;
1070 */
1071 }
1072
1073 void RAS_OpenGLRasterizer::SetFrontFace(bool ccw)
1074 {
1075         if (m_last_frontface == ccw)
1076                 return;
1077
1078         if (ccw)
1079                 glFrontFace(GL_CCW);
1080         else
1081                 glFrontFace(GL_CW);
1082         
1083         m_last_frontface = ccw;
1084 }
1085
1086 void RAS_OpenGLRasterizer::SetAnisotropicFiltering(short level)
1087 {
1088         GPU_set_anisotropic((float)level);
1089 }
1090
1091 short RAS_OpenGLRasterizer::GetAnisotropicFiltering()
1092 {
1093         return (short)GPU_get_anisotropic();
1094 }
1095
1096 void RAS_OpenGLRasterizer::SetMipmapping(MipmapOption val)
1097 {
1098         if (val == RAS_IRasterizer::RAS_MIPMAP_LINEAR)
1099         {
1100                 GPU_set_linear_mipmap(1);
1101                 GPU_set_mipmap(1);
1102         }
1103         else if (val == RAS_IRasterizer::RAS_MIPMAP_NEAREST)
1104         {
1105                 GPU_set_linear_mipmap(0);
1106                 GPU_set_mipmap(1);
1107         }
1108         else
1109         {
1110                 GPU_set_linear_mipmap(0);
1111                 GPU_set_mipmap(0);
1112         }
1113 }
1114
1115 RAS_IRasterizer::MipmapOption RAS_OpenGLRasterizer::GetMipmapping()
1116 {
1117         if (GPU_get_linear_mipmap())
1118                 return RAS_IRasterizer::RAS_MIPMAP_LINEAR;
1119         else if (GPU_get_mipmap())
1120                 return RAS_IRasterizer::RAS_MIPMAP_NEAREST;
1121         else
1122                 return RAS_IRasterizer::RAS_MIPMAP_NONE;
1123 }
1124
1125 void RAS_OpenGLRasterizer::SetUsingOverrideShader(bool val)
1126 {
1127         m_usingoverrideshader = val;
1128 }
1129
1130 bool RAS_OpenGLRasterizer::GetUsingOverrideShader()
1131 {
1132         return m_usingoverrideshader;
1133 }
1134
1135 /**
1136  * Render Tools
1137  */
1138
1139 /* ProcessLighting performs lighting on objects. the layer is a bitfield that
1140  * contains layer information. There are 20 'official' layers in blender. A
1141  * light is applied on an object only when they are in the same layer. OpenGL
1142  * has a maximum of 8 lights (simultaneous), so 20 * 8 lights are possible in
1143  * a scene. */
1144
1145 void RAS_OpenGLRasterizer::ProcessLighting(bool uselights, const MT_Transform& viewmat)
1146 {
1147         bool enable = false;
1148         int layer= -1;
1149
1150         /* find the layer */
1151         if (uselights) {
1152                 if (m_clientobject)
1153                         layer = static_cast<KX_GameObject*>(m_clientobject)->GetLayer();
1154         }
1155
1156         /* avoid state switching */
1157         if (m_lastlightlayer == layer && m_lastauxinfo == m_auxilaryClientInfo)
1158                 return;
1159
1160         m_lastlightlayer = layer;
1161         m_lastauxinfo = m_auxilaryClientInfo;
1162
1163         /* enable/disable lights as needed */
1164         if (layer >= 0)
1165                 enable = ApplyLights(layer, viewmat);
1166
1167         if (enable)
1168                 EnableOpenGLLights();
1169         else
1170                 DisableOpenGLLights();
1171 }
1172
1173 void RAS_OpenGLRasterizer::EnableOpenGLLights()
1174 {
1175         if (m_lastlighting == true)
1176                 return;
1177
1178         glEnable(GL_LIGHTING);
1179         glEnable(GL_COLOR_MATERIAL);
1180
1181         glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
1182         glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
1183         glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, (GetCameraOrtho())? GL_FALSE: GL_TRUE);
1184         if (GLEW_EXT_separate_specular_color || GLEW_VERSION_1_2)
1185                 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1186
1187         m_lastlighting = true;
1188 }
1189
1190 void RAS_OpenGLRasterizer::DisableOpenGLLights()
1191 {
1192         if (m_lastlighting == false)
1193                 return;
1194
1195         glDisable(GL_LIGHTING);
1196         glDisable(GL_COLOR_MATERIAL);
1197
1198         m_lastlighting = false;
1199 }
1200
1201 void RAS_OpenGLRasterizer::AddLight(struct RAS_LightObject* lightobject)
1202 {
1203         m_lights.push_back(lightobject);
1204 }
1205
1206 void RAS_OpenGLRasterizer::RemoveLight(struct RAS_LightObject* lightobject)
1207 {
1208         std::vector<struct      RAS_LightObject*>::iterator lit =
1209                 std::find(m_lights.begin(),m_lights.end(),lightobject);
1210
1211         if (!(lit==m_lights.end()))
1212                 m_lights.erase(lit);
1213 }
1214
1215 bool RAS_OpenGLRasterizer::RayHit(class KX_ClientObjectInfo *client, KX_RayCast *result, void * const data)
1216 {
1217         double* const oglmatrix = (double* const) data;
1218
1219         RAS_Polygon* poly = result->m_hitMesh->GetPolygon(result->m_hitPolygon);
1220         if (!poly->IsVisible())
1221                 return false;
1222
1223         MT_Point3 resultpoint(result->m_hitPoint);
1224         MT_Vector3 resultnormal(result->m_hitNormal);
1225         MT_Vector3 left(oglmatrix[0],oglmatrix[1],oglmatrix[2]);
1226         MT_Vector3 dir = -(left.cross(resultnormal)).safe_normalized();
1227         left = (dir.cross(resultnormal)).safe_normalized();
1228         // for the up vector, we take the 'resultnormal' returned by the physics
1229
1230         double maat[16] = {left[0],         left[1],         left[2],         0,
1231                            dir[0],          dir[1],          dir[2],          0,
1232                            resultnormal[0], resultnormal[1], resultnormal[2], 0,
1233                            0,               0,               0,               1};
1234
1235         glTranslated(resultpoint[0],resultpoint[1],resultpoint[2]);
1236         //glMultMatrixd(oglmatrix);
1237         glMultMatrixd(maat);
1238         return true;
1239 }
1240
1241 void RAS_OpenGLRasterizer::applyTransform(double* oglmatrix,int objectdrawmode )
1242 {
1243         /* FIXME:
1244         blender: intern/moto/include/MT_Vector3.inl:42: MT_Vector3 operator/(const
1245         MT_Vector3&, double): Assertion `!MT_fuzzyZero(s)' failed.
1246
1247         Program received signal SIGABRT, Aborted.
1248         [Switching to Thread 16384 (LWP 1519)]
1249         0x40477571 in kill () from /lib/libc.so.6
1250         (gdb) bt
1251         #7  0x08334368 in MT_Vector3::normalized() const ()
1252         #8  0x0833e6ec in RAS_OpenGLRasterizer::applyTransform(RAS_IRasterizer*, double*, int) ()
1253         */
1254
1255         if (objectdrawmode & RAS_IPolyMaterial::BILLBOARD_SCREENALIGNED ||
1256                 objectdrawmode & RAS_IPolyMaterial::BILLBOARD_AXISALIGNED)
1257         {
1258                 // rotate the billboard/halo
1259                 //page 360/361 3D Game Engine Design, David Eberly for a discussion
1260                 // on screen aligned and axis aligned billboards
1261                 // assumed is that the preprocessor transformed all billboard polygons
1262                 // so that their normal points into the positive x direction (1.0, 0.0, 0.0)
1263                 // when new parenting for objects is done, this rotation
1264                 // will be moved into the object
1265
1266                 MT_Point3 objpos (oglmatrix[12],oglmatrix[13],oglmatrix[14]);
1267                 MT_Point3 campos = GetCameraPosition();
1268                 MT_Vector3 dir = (campos - objpos).safe_normalized();
1269                 MT_Vector3 up(0,0,1.0);
1270
1271                 KX_GameObject* gameobj = (KX_GameObject*)m_clientobject;
1272                 // get scaling of halo object
1273                 MT_Vector3  size = gameobj->GetSGNode()->GetWorldScaling();
1274
1275                 bool screenaligned = (objectdrawmode & RAS_IPolyMaterial::BILLBOARD_SCREENALIGNED)!=0;//false; //either screen or axisaligned
1276                 if (screenaligned)
1277                 {
1278                         up = (up - up.dot(dir) * dir).safe_normalized();
1279                 } else
1280                 {
1281                         dir = (dir - up.dot(dir)*up).safe_normalized();
1282                 }
1283
1284                 MT_Vector3 left = dir.normalized();
1285                 dir = (up.cross(left)).normalized();
1286
1287                 // we have calculated the row vectors, now we keep
1288                 // local scaling into account:
1289
1290                 left *= size[0];
1291                 dir  *= size[1];
1292                 up   *= size[2];
1293
1294                 double maat[16] = {left[0], left[1], left[2], 0,
1295                                    dir[0],  dir[1],  dir[2],  0,
1296                                    up[0],   up[1],   up[2],   0,
1297                                    0,       0,       0,       1};
1298
1299                 glTranslated(objpos[0],objpos[1],objpos[2]);
1300                 glMultMatrixd(maat);
1301
1302         }
1303         else {
1304                 if (objectdrawmode & RAS_IPolyMaterial::SHADOW)
1305                 {
1306                         // shadow must be cast to the ground, physics system needed here!
1307                         MT_Point3 frompoint(oglmatrix[12],oglmatrix[13],oglmatrix[14]);
1308                         KX_GameObject *gameobj = (KX_GameObject*)m_clientobject;
1309                         MT_Vector3 direction = MT_Vector3(0,0,-1);
1310
1311                         direction.normalize();
1312                         direction *= 100000;
1313
1314                         MT_Point3 topoint = frompoint + direction;
1315
1316                         KX_Scene* kxscene = (KX_Scene*) m_auxilaryClientInfo;
1317                         PHY_IPhysicsEnvironment* physics_environment = kxscene->GetPhysicsEnvironment();
1318                         KX_IPhysicsController* physics_controller = gameobj->GetPhysicsController();
1319
1320                         KX_GameObject *parent = gameobj->GetParent();
1321                         if (!physics_controller && parent)
1322                                 physics_controller = parent->GetPhysicsController();
1323                         if (parent)
1324                                 parent->Release();
1325
1326                         KX_RayCast::Callback<RAS_OpenGLRasterizer> callback(this, physics_controller, oglmatrix);
1327                         if (!KX_RayCast::RayTest(physics_environment, frompoint, topoint, callback))
1328                         {
1329                                 // couldn't find something to cast the shadow on...
1330                                 glMultMatrixd(oglmatrix);
1331                         }
1332                         else
1333                         { // we found the "ground", but the cast matrix doesn't take
1334                           // scaling in consideration, so we must apply the object scale
1335                                 MT_Vector3  size = gameobj->GetSGNode()->GetLocalScale();
1336                                 glScalef(size[0], size[1], size[2]);
1337                         }
1338                 } else
1339                 {
1340
1341                         // 'normal' object
1342                         glMultMatrixd(oglmatrix);
1343                 }
1344         }
1345 }
1346
1347 static void DisableForText()
1348 {
1349         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); /* needed for texture fonts otherwise they render as wireframe */
1350
1351         glDisable(GL_BLEND);
1352         glDisable(GL_ALPHA_TEST);
1353
1354         glDisable(GL_LIGHTING);
1355         glDisable(GL_COLOR_MATERIAL);
1356
1357         if (GLEW_ARB_multitexture) {
1358                 for (int i=0; i<MAXTEX; i++) {
1359                         glActiveTextureARB(GL_TEXTURE0_ARB+i);
1360
1361                         if (GLEW_ARB_texture_cube_map)
1362                                 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1363
1364                         glDisable(GL_TEXTURE_2D);
1365                 }
1366
1367                 glActiveTextureARB(GL_TEXTURE0_ARB);
1368         }
1369         else {
1370                 if (GLEW_ARB_texture_cube_map)
1371                         glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1372
1373                 glDisable(GL_TEXTURE_2D);
1374         }
1375 }
1376
1377 void RAS_OpenGLRasterizer::RenderBox2D(int xco,
1378                         int yco,
1379                         int width,
1380                         int height,
1381                         float percentage)
1382 {
1383         /* This is a rather important line :( The gl-mode hasn't been left
1384          * behind quite as neatly as we'd have wanted to. I don't know
1385          * what cause it, though :/ .*/
1386         glDisable(GL_DEPTH_TEST);
1387
1388         glMatrixMode(GL_PROJECTION);
1389         glPushMatrix();
1390         glLoadIdentity();
1391
1392         glOrtho(0, width, 0, height, -100, 100);
1393
1394         glMatrixMode(GL_MODELVIEW);
1395         glPushMatrix();
1396         glLoadIdentity();
1397
1398         yco = height - yco;
1399         int barsize = 50;
1400
1401         /* draw in black first*/
1402         glColor3ub(0, 0, 0);
1403         glBegin(GL_QUADS);
1404         glVertex2f(xco + 1 + 1 + barsize * percentage, yco - 1 + 10);
1405         glVertex2f(xco + 1, yco - 1 + 10);
1406         glVertex2f(xco + 1, yco - 1);
1407         glVertex2f(xco + 1 + 1 + barsize * percentage, yco - 1);
1408         glEnd();
1409
1410         glColor3ub(255, 255, 255);
1411         glBegin(GL_QUADS);
1412         glVertex2f(xco + 1 + barsize * percentage, yco + 10);
1413         glVertex2f(xco, yco + 10);
1414         glVertex2f(xco, yco);
1415         glVertex2f(xco + 1 + barsize * percentage, yco);
1416         glEnd();
1417
1418         glMatrixMode(GL_PROJECTION);
1419         glPopMatrix();
1420         glMatrixMode(GL_MODELVIEW);
1421         glPopMatrix();
1422         glEnable(GL_DEPTH_TEST);
1423 }
1424
1425 void RAS_OpenGLRasterizer::RenderText3D(int fontid,
1426                                                                                  const char* text,
1427                                                                                  int size,
1428                                                                                  int dpi,
1429                                                                                  float* color,
1430                                                                                  double* mat,
1431                                                                                  float aspect)
1432 {
1433         /* gl prepping */
1434         DisableForText();
1435
1436         /* the actual drawing */
1437         glColor4fv(color);
1438
1439         /* multiply the text matrix by the object matrix */
1440         BLF_enable(fontid, BLF_MATRIX|BLF_ASPECT);
1441         BLF_matrix(fontid, mat);
1442
1443         /* aspect is the inverse scale that allows you to increase */
1444         /* your resolution without sizing the final text size      */
1445         /* the bigger the size, the smaller the aspect             */
1446         BLF_aspect(fontid, aspect, aspect, aspect);
1447
1448         BLF_size(fontid, size, dpi);
1449         BLF_position(fontid, 0, 0, 0);
1450         BLF_draw(fontid, (char *)text, 65535);
1451
1452         BLF_disable(fontid, BLF_MATRIX|BLF_ASPECT);
1453 }
1454
1455 void RAS_OpenGLRasterizer::RenderText2D(RAS_TEXT_RENDER_MODE mode,
1456                                                                                  const char* text,
1457                                                                                  int xco,
1458                                                                                  int yco,
1459                                                                                  int width,
1460                                                                                  int height)
1461 {
1462         /* This is a rather important line :( The gl-mode hasn't been left
1463          * behind quite as neatly as we'd have wanted to. I don't know
1464          * what cause it, though :/ .*/
1465         DisableForText();
1466         glDisable(GL_DEPTH_TEST);
1467
1468         glMatrixMode(GL_PROJECTION);
1469         glPushMatrix();
1470         glLoadIdentity();
1471
1472         glOrtho(0, width, 0, height, -100, 100);
1473
1474         glMatrixMode(GL_MODELVIEW);
1475         glPushMatrix();
1476         glLoadIdentity();
1477
1478         if (mode == RAS_TEXT_PADDED) {
1479                 /* draw in black first*/
1480                 glColor3ub(0, 0, 0);
1481                 BLF_size(blf_mono_font, 11, 72);
1482                 BLF_position(blf_mono_font, (float)xco+1, (float)(height-yco-1), 0.0f);
1483                 BLF_draw(blf_mono_font, (char *)text, 65535);/* XXX, use real len */
1484
1485                 glColor3ub(255, 255, 255);
1486                 BLF_position(blf_mono_font, (float)xco, (float)(height-yco), 0.0f);
1487                 BLF_draw(blf_mono_font, (char *)text, 65535);
1488         } else {
1489                 /* the actual drawing */
1490                 glColor3ub(255, 255, 255);
1491                 BLF_size(blf_mono_font, 11, 72);
1492                 BLF_position(blf_mono_font, (float)xco, (float)(height-yco), 0.0f);
1493                 BLF_draw(blf_mono_font, (char *)text, 65535); /* XXX, use real len */
1494         }
1495
1496         glMatrixMode(GL_PROJECTION);
1497         glPopMatrix();
1498         glMatrixMode(GL_MODELVIEW);
1499         glPopMatrix();
1500         glEnable(GL_DEPTH_TEST);
1501 }
1502
1503 /* Render Text renders text into a (series of) polygon, using a texture font,
1504  * Each character consists of one polygon (one quad or two triangles) */
1505
1506 void RAS_OpenGLRasterizer::RenderText(
1507         int mode,
1508         RAS_IPolyMaterial* polymat,
1509         float v1[3], float v2[3], float v3[3], float v4[3], int glattrib)
1510 {
1511         const STR_String& mytext = ((CValue*)m_clientobject)->GetPropertyText("Text");
1512
1513         const unsigned int flag = polymat->GetFlag();
1514         struct MTFace* tface = 0;
1515         unsigned int *col = 0;
1516
1517         if (flag & RAS_BLENDERMAT) {
1518                 KX_BlenderMaterial *bl_mat = static_cast<KX_BlenderMaterial*>(polymat);
1519                 tface = bl_mat->GetMTFace();
1520                 col = bl_mat->GetMCol();
1521         } else {
1522                 KX_PolygonMaterial* blenderpoly = static_cast<KX_PolygonMaterial*>(polymat);
1523                 tface = blenderpoly->GetMTFace();
1524                 col = blenderpoly->GetMCol();
1525         }
1526
1527         GPU_render_text(tface, mode, mytext, mytext.Length(), col, v1, v2, v3, v4, glattrib);
1528 }
1529
1530
1531 void RAS_OpenGLRasterizer::PushMatrix()
1532 {
1533         glPushMatrix();
1534 }
1535
1536 void RAS_OpenGLRasterizer::PopMatrix()
1537 {
1538         glPopMatrix();
1539 }
1540
1541
1542 int RAS_OpenGLRasterizer::ApplyLights(int objectlayer, const MT_Transform& viewmat)
1543 {
1544         // taken from blender source, incompatibility between Blender Object / GameObject
1545         KX_Scene* kxscene = (KX_Scene*)m_auxilaryClientInfo;
1546         float glviewmat[16];
1547         unsigned int count;
1548         std::vector<struct      RAS_LightObject*>::iterator lit = m_lights.begin();
1549
1550         for (count=0; count<m_numgllights; count++)
1551                 glDisable((GLenum)(GL_LIGHT0+count));
1552
1553         viewmat.getValue(glviewmat);
1554
1555         glPushMatrix();
1556         glLoadMatrixf(glviewmat);
1557         for (lit = m_lights.begin(), count = 0; !(lit==m_lights.end()) && count < m_numgllights; ++lit)
1558         {
1559                 RAS_LightObject* lightdata = (*lit);
1560                 KX_LightObject *kxlight = (KX_LightObject*)lightdata->m_light;
1561
1562                 if (kxlight->ApplyLight(kxscene, objectlayer, count))
1563                         count++;
1564         }
1565         glPopMatrix();
1566
1567         return count;
1568 }
1569
1570 void RAS_OpenGLRasterizer::MotionBlur()
1571 {
1572         int state = GetMotionBlurState();
1573         float motionblurvalue;
1574         if (state)
1575         {
1576                 motionblurvalue = GetMotionBlurValue();
1577                 if (state==1)
1578                 {
1579                         //bugfix:load color buffer into accum buffer for the first time(state=1)
1580                         glAccum(GL_LOAD, 1.0);
1581                         SetMotionBlurState(2);
1582                 }
1583                 else if (motionblurvalue >= 0.0f && motionblurvalue <= 1.0f) {
1584                         glAccum(GL_MULT, motionblurvalue);
1585                         glAccum(GL_ACCUM, 1-motionblurvalue);
1586                         glAccum(GL_RETURN, 1.0);
1587                         glFlush();
1588                 }
1589         }
1590 }
1591
1592 void RAS_OpenGLRasterizer::SetClientObject(void* obj)
1593 {
1594         if (m_clientobject != obj)
1595         {
1596                 bool ccw = (obj == NULL || !((KX_GameObject*)obj)->IsNegativeScaling());
1597                 SetFrontFace(ccw);
1598
1599                 m_clientobject = obj;
1600         }
1601 }
1602
1603 void RAS_OpenGLRasterizer::SetAuxilaryClientInfo(void* inf)
1604 {
1605         m_auxilaryClientInfo = inf;
1606 }
1607