BGE bugfix/patch "[#26075] game anaglyph colors are inverted" by Juha Maki-Kanto...
[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 "MT_CmMatrix4x4.h"
44 #include "RAS_IRenderTools.h" // rendering text
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 }
63
64 #ifndef M_PI
65 #define M_PI            3.14159265358979323846
66 #endif
67
68 /**
69  *  32x32 bit masks for vinterlace stereo mode
70  */
71 static GLuint left_eye_vinterlace_mask[32];
72 static GLuint right_eye_vinterlace_mask[32];
73
74 /**
75  *  32x32 bit masks for hinterlace stereo mode.
76  *  Left eye = &hinterlace_mask[0]
77  *  Right eye = &hinterlace_mask[1]
78  */
79 static GLuint hinterlace_mask[33];
80
81 RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas, int storage)
82         :RAS_IRasterizer(canvas),
83         m_2DCanvas(canvas),
84         m_fogenabled(false),
85         m_time(0.0),
86         m_campos(0.0f, 0.0f, 0.0f),
87         m_camortho(false),
88         m_stereomode(RAS_STEREO_NOSTEREO),
89         m_curreye(RAS_STEREO_LEFTEYE),
90         m_eyeseparation(0.0),
91         m_focallength(0.0),
92         m_setfocallength(false),
93         m_noOfScanlines(32),
94         m_motionblur(0),
95         m_motionblurvalue(-1.0),
96         m_usingoverrideshader(false),
97         m_texco_num(0),
98         m_attrib_num(0),
99         //m_last_alphablend(GPU_BLEND_SOLID),
100         m_last_frontface(true),
101         m_materialCachingInfo(0),
102         m_storage_type(storage)
103 {
104         m_viewmatrix.setIdentity();
105         m_viewinvmatrix.setIdentity();
106         
107         for (int i = 0; i < 32; i++)
108         {
109                 left_eye_vinterlace_mask[i] = 0x55555555;
110                 right_eye_vinterlace_mask[i] = 0xAAAAAAAA;
111                 hinterlace_mask[i] = (i&1)*0xFFFFFFFF;
112         }
113         hinterlace_mask[32] = 0;
114
115         m_prevafvalue = GPU_get_anisotropic();
116
117         if (m_storage_type == RAS_VBO /*|| m_storage_type == RAS_AUTO_STORAGE && GLEW_ARB_vertex_buffer_object*/)
118         {
119                 m_storage = new RAS_StorageVBO(&m_texco_num, m_texco, &m_attrib_num, m_attrib, m_attrib_layer);
120                 m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib, m_attrib_layer);
121                 m_storage_type = RAS_VBO;
122         }
123         else if ((m_storage_type == RAS_VA) || (m_storage_type == RAS_AUTO_STORAGE && GLEW_VERSION_1_1))
124         {
125                 m_storage = new RAS_StorageVA(&m_texco_num, m_texco, &m_attrib_num, m_attrib, m_attrib_layer);
126                 m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib, m_attrib_layer);
127                 m_storage_type = RAS_VA;
128         }
129         else
130         {
131                 m_storage = m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib, m_attrib_layer);
132                 m_storage_type = RAS_IMMEDIATE;
133         }
134 }
135
136
137
138 RAS_OpenGLRasterizer::~RAS_OpenGLRasterizer()
139 {
140         // Restore the previous AF value
141         GPU_set_anisotropic(m_prevafvalue);
142         if (m_failsafe_storage && m_failsafe_storage != m_storage)
143                 delete m_failsafe_storage;
144
145         if (m_storage)
146                 delete m_storage;
147 }
148
149 bool RAS_OpenGLRasterizer::Init()
150 {
151         bool storage_init;
152         GPU_state_init();
153
154
155         m_ambr = 0.0f;
156         m_ambg = 0.0f;
157         m_ambb = 0.0f;
158
159         glDisable(GL_BLEND);
160         glDisable(GL_ALPHA_TEST);
161         //m_last_alphablend = GPU_BLEND_SOLID;
162         GPU_set_material_alpha_blend(GPU_BLEND_SOLID);
163
164         glFrontFace(GL_CCW);
165         m_last_frontface = true;
166
167         m_redback = 0.4375;
168         m_greenback = 0.4375;
169         m_blueback = 0.4375;
170         m_alphaback = 0.0;
171
172         glClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
173         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
174         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
175
176
177         glShadeModel(GL_SMOOTH);
178
179         storage_init = m_storage->Init();
180
181         return true && storage_init;
182 }
183
184
185 void RAS_OpenGLRasterizer::SetAmbientColor(float red, float green, float blue)
186 {
187         m_ambr = red;
188         m_ambg = green;
189         m_ambb = blue;
190 }
191
192
193 void RAS_OpenGLRasterizer::SetAmbient(float factor)
194 {
195         float ambient[] = { m_ambr*factor, m_ambg*factor, m_ambb*factor, 1.0f };
196         glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
197 }
198
199
200 void RAS_OpenGLRasterizer::SetBackColor(float red,
201                                                                                 float green,
202                                                                                 float blue,
203                                                                                 float alpha)
204 {
205         m_redback = red;
206         m_greenback = green;
207         m_blueback = blue;
208         m_alphaback = alpha;
209 }
210
211
212
213 void RAS_OpenGLRasterizer::SetFogColor(float r,
214                                                                            float g,
215                                                                            float b)
216 {
217         m_fogr = r;
218         m_fogg = g;
219         m_fogb = b;
220         m_fogenabled = true;
221 }
222
223
224
225 void RAS_OpenGLRasterizer::SetFogStart(float start)
226 {
227         m_fogstart = start;
228         m_fogenabled = true;
229 }
230
231
232
233 void RAS_OpenGLRasterizer::SetFogEnd(float fogend)
234 {
235         m_fogdist = fogend;
236         m_fogenabled = true;
237 }
238
239
240
241 void RAS_OpenGLRasterizer::SetFog(float start,
242                                                                   float dist,
243                                                                   float r,
244                                                                   float g,
245                                                                   float b)
246 {
247         m_fogstart = start;
248         m_fogdist = dist;
249         m_fogr = r;
250         m_fogg = g;
251         m_fogb = b;
252         m_fogenabled = true;
253 }
254
255
256
257 void RAS_OpenGLRasterizer::DisableFog()
258 {
259         m_fogenabled = false;
260 }
261
262 bool RAS_OpenGLRasterizer::IsFogEnabled()
263 {
264         return m_fogenabled;
265 }
266
267
268 void RAS_OpenGLRasterizer::DisplayFog()
269 {
270         if ((m_drawingmode >= KX_SOLID) && m_fogenabled)
271         {
272                 float params[5];
273                 glFogi(GL_FOG_MODE, GL_LINEAR);
274                 glFogf(GL_FOG_DENSITY, 0.1f);
275                 glFogf(GL_FOG_START, m_fogstart);
276                 glFogf(GL_FOG_END, m_fogstart + m_fogdist);
277                 params[0] = m_fogr;
278                 params[1] = m_fogg;
279                 params[2] = m_fogb;
280                 params[3] = 0.0;
281                 glFogfv(GL_FOG_COLOR, params); 
282                 glEnable(GL_FOG);
283         } 
284         else
285         {
286                 glDisable(GL_FOG);
287         }
288 }
289
290
291
292 bool RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat)
293 {
294         return mat.Activate(this, m_materialCachingInfo);
295 }
296
297
298
299 void RAS_OpenGLRasterizer::Exit()
300 {
301
302         m_storage->Exit();
303
304         glEnable(GL_CULL_FACE);
305         glEnable(GL_DEPTH_TEST);
306         glClearDepth(1.0); 
307         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
308         glClearColor(m_redback, m_greenback, m_blueback, m_alphaback);
309         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
310         glDepthMask (GL_TRUE);
311         glDepthFunc(GL_LEQUAL);
312         glBlendFunc(GL_ONE, GL_ZERO);
313         
314         glDisable(GL_POLYGON_STIPPLE);
315         
316         glDisable(GL_LIGHTING);
317         if (GLEW_EXT_separate_specular_color || GLEW_VERSION_1_2)
318                 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
319         
320         EndFrame();
321 }
322
323 bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
324 {
325         m_time = time;
326         SetDrawingMode(drawingmode);
327
328         // Blender camera routine destroys the settings
329         if (m_drawingmode < KX_SOLID)
330         {
331                 glDisable(GL_CULL_FACE);
332                 glDisable(GL_DEPTH_TEST);
333         }
334         else
335         {
336                 glEnable(GL_DEPTH_TEST);
337                 glEnable(GL_CULL_FACE);
338         }
339
340         glDisable(GL_BLEND);
341         glDisable(GL_ALPHA_TEST);
342         //m_last_alphablend = GPU_BLEND_SOLID;
343         GPU_set_material_alpha_blend(GPU_BLEND_SOLID);
344
345         glFrontFace(GL_CCW);
346         m_last_frontface = true;
347
348         glShadeModel(GL_SMOOTH);
349
350         glEnable(GL_MULTISAMPLE_ARB);
351
352         m_2DCanvas->BeginFrame();
353         
354         return true;
355 }
356
357
358
359 void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode)
360 {
361         m_drawingmode = drawingmode;
362
363         if (m_drawingmode == KX_WIREFRAME)
364                 glDisable(GL_CULL_FACE);
365
366         m_storage->SetDrawingMode(drawingmode);
367         if (m_failsafe_storage && m_failsafe_storage != m_storage) {
368                 m_failsafe_storage->SetDrawingMode(drawingmode);
369         }
370 }
371
372 int RAS_OpenGLRasterizer::GetDrawingMode()
373 {
374         return m_drawingmode;
375 }
376
377
378 void RAS_OpenGLRasterizer::SetDepthMask(DepthMask depthmask)
379 {
380         glDepthMask(depthmask == KX_DEPTHMASK_DISABLED ? GL_FALSE : GL_TRUE);
381 }
382
383
384 void RAS_OpenGLRasterizer::ClearColorBuffer()
385 {
386         m_2DCanvas->ClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
387         m_2DCanvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER);
388 }
389
390
391 void RAS_OpenGLRasterizer::ClearDepthBuffer()
392 {
393         m_2DCanvas->ClearBuffer(RAS_ICanvas::DEPTH_BUFFER);
394 }
395
396
397 void RAS_OpenGLRasterizer::ClearCachingInfo(void)
398 {
399         m_materialCachingInfo = 0;
400 }
401
402 void RAS_OpenGLRasterizer::FlushDebugShapes()
403 {
404         if (m_debugShapes.empty())
405                 return;
406
407         // DrawDebugLines
408         GLboolean light, tex;
409
410         light= glIsEnabled(GL_LIGHTING);
411         tex= glIsEnabled(GL_TEXTURE_2D);
412
413         if (light) glDisable(GL_LIGHTING);
414         if (tex) glDisable(GL_TEXTURE_2D);
415
416         //draw lines
417         glBegin(GL_LINES);
418         for (unsigned int i=0;i<m_debugShapes.size();i++)
419         {
420                 if (m_debugShapes[i].m_type != OglDebugShape::LINE)
421                         continue;
422                 glColor4f(m_debugShapes[i].m_color[0],m_debugShapes[i].m_color[1],m_debugShapes[i].m_color[2],1.f);
423                 const MT_Scalar* fromPtr = &m_debugShapes[i].m_pos.x();
424                 const MT_Scalar* toPtr= &m_debugShapes[i].m_param.x();
425                 glVertex3dv(fromPtr);
426                 glVertex3dv(toPtr);
427         }
428         glEnd();
429
430         //draw circles
431         for (unsigned int i=0;i<m_debugShapes.size();i++)
432         {
433                 if (m_debugShapes[i].m_type != OglDebugShape::CIRCLE)
434                         continue;
435                 glBegin(GL_LINE_LOOP);
436                 glColor4f(m_debugShapes[i].m_color[0],m_debugShapes[i].m_color[1],m_debugShapes[i].m_color[2],1.f);
437
438                 static const MT_Vector3 worldUp(0.0, 0.0, 1.0);
439                 MT_Vector3 norm = m_debugShapes[i].m_param;
440                 MT_Matrix3x3 tr;
441                 if (norm.fuzzyZero() || norm == worldUp)
442                 {
443                         tr.setIdentity();
444                 }
445                 else
446                 {
447                         MT_Vector3 xaxis, yaxis;
448                         xaxis = MT_cross(norm, worldUp);
449                         yaxis = MT_cross(xaxis, norm);
450                         tr.setValue(xaxis.x(), xaxis.y(), xaxis.z(),
451                                 yaxis.x(), yaxis.y(), yaxis.z(),
452                                 norm.x(), norm.y(), norm.z());
453                 }
454                 MT_Scalar rad = m_debugShapes[i].m_param2.x();
455                 int n = (int) m_debugShapes[i].m_param2.y();
456                 for (int j = 0; j<n; j++)
457                 {
458                         MT_Scalar theta = j*M_PI*2/n;
459                         MT_Vector3 pos(cos(theta) * rad, sin(theta) * rad, 0.0);
460                         pos = pos*tr;
461                         pos += m_debugShapes[i].m_pos;
462                         const MT_Scalar* posPtr = &pos.x();
463                         glVertex3dv(posPtr);
464                 }
465                 glEnd();
466         }
467
468         if (light) glEnable(GL_LIGHTING);
469         if (tex) glEnable(GL_TEXTURE_2D);
470
471         m_debugShapes.clear();
472 }
473
474 void RAS_OpenGLRasterizer::EndFrame()
475 {
476         FlushDebugShapes();
477
478         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
479
480         glDisable(GL_MULTISAMPLE_ARB);
481
482         m_2DCanvas->EndFrame();
483 }
484
485 void RAS_OpenGLRasterizer::SetRenderArea()
486 {
487         RAS_Rect area;
488         // only above/below stereo method needs viewport adjustment
489         switch (m_stereomode)
490         {
491                 case RAS_STEREO_ABOVEBELOW:
492                         switch (m_curreye) {
493                                 case RAS_STEREO_LEFTEYE:
494                                         // upper half of window
495                                         area.SetLeft(0);
496                                         area.SetBottom(m_2DCanvas->GetHeight() -
497                                                 int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
498         
499                                         area.SetRight(int(m_2DCanvas->GetWidth()));
500                                         area.SetTop(int(m_2DCanvas->GetHeight()));
501                                         m_2DCanvas->SetDisplayArea(&area);
502                                         break;
503                                 case RAS_STEREO_RIGHTEYE:
504                                         // lower half of window
505                                         area.SetLeft(0);
506                                         area.SetBottom(0);
507                                         area.SetRight(int(m_2DCanvas->GetWidth()));
508                                         area.SetTop(int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
509                                         m_2DCanvas->SetDisplayArea(&area);
510                                         break;
511                         }
512                         break;
513                 case RAS_STEREO_SIDEBYSIDE:
514                         switch (m_curreye)
515                         {
516                                 case RAS_STEREO_LEFTEYE:
517                                         // Left half of window
518                                         area.SetLeft(0);
519                                         area.SetBottom(0);
520                                         area.SetRight(m_2DCanvas->GetWidth()/2);
521                                         area.SetTop(m_2DCanvas->GetHeight());
522                                         m_2DCanvas->SetDisplayArea(&area);
523                                         break;
524                                 case RAS_STEREO_RIGHTEYE:
525                                         // Right half of window
526                                         area.SetLeft(m_2DCanvas->GetWidth()/2);
527                                         area.SetBottom(0);
528                                         area.SetRight(m_2DCanvas->GetWidth());
529                                         area.SetTop(m_2DCanvas->GetHeight());
530                                         m_2DCanvas->SetDisplayArea(&area);
531                                         break;
532                         }
533                         break;
534                 default:
535                         // every available pixel
536                         area.SetLeft(0);
537                         area.SetBottom(0);
538                         area.SetRight(int(m_2DCanvas->GetWidth()));
539                         area.SetTop(int(m_2DCanvas->GetHeight()));
540                         m_2DCanvas->SetDisplayArea(&area);
541                         break;
542         }
543 }
544         
545 void RAS_OpenGLRasterizer::SetStereoMode(const StereoMode stereomode)
546 {
547         m_stereomode = stereomode;
548 }
549
550 RAS_IRasterizer::StereoMode RAS_OpenGLRasterizer::GetStereoMode()
551 {
552         return m_stereomode;
553 }
554
555 bool RAS_OpenGLRasterizer::Stereo()
556 {
557         if (m_stereomode > RAS_STEREO_NOSTEREO) // > 0
558                 return true;
559         else
560                 return false;
561 }
562
563 bool RAS_OpenGLRasterizer::InterlacedStereo()
564 {
565         return m_stereomode == RAS_STEREO_VINTERLACE || m_stereomode == RAS_STEREO_INTERLACED;
566 }
567
568 void RAS_OpenGLRasterizer::SetEye(const StereoEye eye)
569 {
570         m_curreye = eye;
571         switch (m_stereomode)
572         {
573                 case RAS_STEREO_QUADBUFFERED:
574                         glDrawBuffer(m_curreye == RAS_STEREO_LEFTEYE ? GL_BACK_LEFT : GL_BACK_RIGHT);
575                         break;
576                 case RAS_STEREO_ANAGLYPH:
577                         if (m_curreye == RAS_STEREO_LEFTEYE) {
578                                 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
579                         }
580                         else {
581                                 //glAccum(GL_LOAD, 1.0);
582                                 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_FALSE);
583                                 ClearDepthBuffer();
584                         }
585                         break;
586                 case RAS_STEREO_VINTERLACE:
587                 {
588                         glEnable(GL_POLYGON_STIPPLE);
589                         glPolygonStipple((const GLubyte*) ((m_curreye == RAS_STEREO_LEFTEYE) ? left_eye_vinterlace_mask : right_eye_vinterlace_mask));
590                         if (m_curreye == RAS_STEREO_RIGHTEYE)
591                                 ClearDepthBuffer();
592                         break;
593                 }
594                 case RAS_STEREO_INTERLACED:
595                 {
596                         glEnable(GL_POLYGON_STIPPLE);
597                         glPolygonStipple((const GLubyte*) &hinterlace_mask[m_curreye == RAS_STEREO_LEFTEYE?0:1]);
598                         if (m_curreye == RAS_STEREO_RIGHTEYE)
599                                 ClearDepthBuffer();
600                         break;
601                 }
602                 default:
603                         break;
604         }
605 }
606
607 RAS_IRasterizer::StereoEye RAS_OpenGLRasterizer::GetEye()
608 {
609         return m_curreye;
610 }
611
612
613 void RAS_OpenGLRasterizer::SetEyeSeparation(const float eyeseparation)
614 {
615         m_eyeseparation = eyeseparation;
616 }
617
618 float RAS_OpenGLRasterizer::GetEyeSeparation()
619 {
620         return m_eyeseparation;
621 }
622
623 void RAS_OpenGLRasterizer::SetFocalLength(const float focallength)
624 {
625         m_focallength = focallength;
626         m_setfocallength = true;
627 }
628
629 float RAS_OpenGLRasterizer::GetFocalLength()
630 {
631         return m_focallength;
632 }
633
634
635 void RAS_OpenGLRasterizer::SwapBuffers()
636 {
637         m_2DCanvas->SwapBuffers();
638 }
639
640
641
642 const MT_Matrix4x4& RAS_OpenGLRasterizer::GetViewMatrix() const
643 {
644         return m_viewmatrix;
645 }
646
647 const MT_Matrix4x4& RAS_OpenGLRasterizer::GetViewInvMatrix() const
648 {
649         return m_viewinvmatrix;
650 }
651
652 void RAS_OpenGLRasterizer::IndexPrimitives_3DText(RAS_MeshSlot& ms,
653                                                                         class RAS_IPolyMaterial* polymat,
654                                                                         class RAS_IRenderTools* rendertools)
655
656         bool obcolor = ms.m_bObjectColor;
657         MT_Vector4& rgba = ms.m_RGBAcolor;
658         RAS_MeshSlot::iterator it;
659
660         // handle object color
661         if (obcolor) {
662                 glDisableClientState(GL_COLOR_ARRAY);
663                 glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
664         }
665         else
666                 glEnableClientState(GL_COLOR_ARRAY);
667
668         for (ms.begin(it); !ms.end(it); ms.next(it)) {
669                 RAS_TexVert *vertex;
670                 size_t i, j, numvert;
671                 
672                 numvert = it.array->m_type;
673
674                 if (it.array->m_type == RAS_DisplayArray::LINE) {
675                         // line drawing, no text
676                         glBegin(GL_LINES);
677
678                         for (i=0; i<it.totindex; i+=2)
679                         {
680                                 vertex = &it.vertex[it.index[i]];
681                                 glVertex3fv(vertex->getXYZ());
682
683                                 vertex = &it.vertex[it.index[i+1]];
684                                 glVertex3fv(vertex->getXYZ());
685                         }
686
687                         glEnd();
688                 }
689                 else {
690                         // triangle and quad text drawing
691                         for (i=0; i<it.totindex; i+=numvert)
692                         {
693                                 float v[4][3];
694                                 int glattrib, unit;
695
696                                 for (j=0; j<numvert; j++) {
697                                         vertex = &it.vertex[it.index[i+j]];
698
699                                         v[j][0] = vertex->getXYZ()[0];
700                                         v[j][1] = vertex->getXYZ()[1];
701                                         v[j][2] = vertex->getXYZ()[2];
702                                 }
703
704                                 // find the right opengl attribute
705                                 glattrib = -1;
706                                 if (GLEW_ARB_vertex_program)
707                                         for (unit=0; unit<m_attrib_num; unit++)
708                                                 if (m_attrib[unit] == RAS_TEXCO_UV)
709                                                         glattrib = unit;
710                                 
711                                 rendertools->RenderText(polymat->GetDrawingMode(), polymat,
712                                         v[0], v[1], v[2], (numvert == 4)? v[3]: NULL, glattrib);
713
714                                 ClearCachingInfo();
715                         }
716                 }
717         }
718
719         glDisableClientState(GL_COLOR_ARRAY);
720 }
721
722 void RAS_OpenGLRasterizer::SetTexCoordNum(int num)
723 {
724         m_texco_num = num;
725         if (m_texco_num > RAS_MAX_TEXCO)
726                 m_texco_num = RAS_MAX_TEXCO;
727 }
728
729 void RAS_OpenGLRasterizer::SetAttribNum(int num)
730 {
731         m_attrib_num = num;
732         if (m_attrib_num > RAS_MAX_ATTRIB)
733                 m_attrib_num = RAS_MAX_ATTRIB;
734 }
735
736 void RAS_OpenGLRasterizer::SetTexCoord(TexCoGen coords, int unit)
737 {
738         // this changes from material to material
739         if (unit < RAS_MAX_TEXCO)
740                 m_texco[unit] = coords;
741 }
742
743 void RAS_OpenGLRasterizer::SetAttrib(TexCoGen coords, int unit, int layer)
744 {
745         // this changes from material to material
746         if (unit < RAS_MAX_ATTRIB) {
747                 m_attrib[unit] = coords;
748                 m_attrib_layer[unit] = layer;
749         }
750 }
751
752 void RAS_OpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
753 {
754         if (ms.m_pDerivedMesh)
755                 m_failsafe_storage->IndexPrimitives(ms);
756         else
757                 m_storage->IndexPrimitives(ms);
758 }
759
760 void RAS_OpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
761 {
762         if (ms.m_pDerivedMesh)
763                 m_failsafe_storage->IndexPrimitivesMulti(ms);
764         else
765                 m_storage->IndexPrimitivesMulti(ms);
766 }
767
768 void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat)
769 {
770         glMatrixMode(GL_PROJECTION);
771         double* matrix = &mat(0, 0);
772         glLoadMatrixd(matrix);
773
774         m_camortho = (mat(3, 3) != 0.0);
775 }
776
777 void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat)
778 {
779         glMatrixMode(GL_PROJECTION);
780         double matrix[16];
781         /* Get into argument. Looks a bit dodgy, but it's ok. */
782         mat.getValue(matrix);
783         /* Internally, MT_Matrix4x4 uses doubles (MT_Scalar). */
784         glLoadMatrixd(matrix);
785
786         m_camortho= (mat[3][3] != 0.0);
787 }
788
789 MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
790         float left,
791         float right,
792         float bottom,
793         float top,
794         float frustnear,
795         float frustfar,
796         float focallength,
797         bool 
798 ) {
799         MT_Matrix4x4 result;
800         double mat[16];
801
802         // correction for stereo
803         if (Stereo())
804         {
805                         float near_div_focallength;
806                         float offset;
807
808                         // if Rasterizer.setFocalLength is not called we use the camera focallength
809                         if (!m_setfocallength)
810                                 // if focallength is null we use a value known to be reasonable
811                                 m_focallength = (focallength == 0.f) ? m_eyeseparation * 30.0f
812                                         : focallength;
813
814                         near_div_focallength = frustnear / m_focallength;
815                         offset = 0.5f * m_eyeseparation * near_div_focallength;
816                         switch (m_curreye) {
817                                 case RAS_STEREO_LEFTEYE:
818                                                 left += offset;
819                                                 right += offset;
820                                                 break;
821                                 case RAS_STEREO_RIGHTEYE:
822                                                 left -= offset;
823                                                 right -= offset;
824                                                 break;
825                         }
826                         // leave bottom and top untouched
827         }
828         
829         glMatrixMode(GL_PROJECTION);
830         glLoadIdentity();
831         glFrustum(left, right, bottom, top, frustnear, frustfar);
832                 
833         glGetDoublev(GL_PROJECTION_MATRIX, mat);
834         result.setValue(mat);
835
836         return result;
837 }
838
839 MT_Matrix4x4 RAS_OpenGLRasterizer::GetOrthoMatrix(
840         float left,
841         float right,
842         float bottom,
843         float top,
844         float frustnear,
845         float frustfar
846 ) {
847         MT_Matrix4x4 result;
848         double mat[16];
849
850         // stereo is meaning less for orthographic, disable it
851         glMatrixMode(GL_PROJECTION);
852         glLoadIdentity();
853         glOrtho(left, right, bottom, top, frustnear, frustfar);
854                 
855         glGetDoublev(GL_PROJECTION_MATRIX, mat);
856         result.setValue(mat);
857
858         return result;
859 }
860
861
862 // next arguments probably contain redundant info, for later...
863 void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, 
864                                                                                  const MT_Matrix3x3 & camOrientMat3x3,
865                                                                                  const MT_Point3 & pos,
866                                                                                  bool perspective)
867 {
868         m_viewmatrix = mat;
869
870         // correction for stereo
871         if (Stereo() && perspective)
872         {
873                 MT_Vector3 unitViewDir(0.0, -1.0, 0.0);  // minus y direction, Blender convention
874                 MT_Vector3 unitViewupVec(0.0, 0.0, 1.0);
875                 MT_Vector3 viewDir, viewupVec;
876                 MT_Vector3 eyeline;
877
878                 // actual viewDir
879                 viewDir = camOrientMat3x3 * unitViewDir;  // this is the moto convention, vector on right hand side
880                 // actual viewup vec
881                 viewupVec = camOrientMat3x3 * unitViewupVec;
882
883                 // vector between eyes
884                 eyeline = viewDir.cross(viewupVec);
885
886                 switch (m_curreye) {
887                         case RAS_STEREO_LEFTEYE:
888                                 {
889                                 // translate to left by half the eye distance
890                                 MT_Transform transform;
891                                 transform.setIdentity();
892                                 transform.translate(-(eyeline * m_eyeseparation / 2.0));
893                                 m_viewmatrix *= transform;
894                                 }
895                                 break;
896                         case RAS_STEREO_RIGHTEYE:
897                                 {
898                                 // translate to right by half the eye distance
899                                 MT_Transform transform;
900                                 transform.setIdentity();
901                                 transform.translate(eyeline * m_eyeseparation / 2.0);
902                                 m_viewmatrix *= transform;
903                                 }
904                                 break;
905                 }
906         }
907
908         m_viewinvmatrix = m_viewmatrix;
909         m_viewinvmatrix.invert();
910
911         // note: getValue gives back column major as needed by OpenGL
912         MT_Scalar glviewmat[16];
913         m_viewmatrix.getValue(glviewmat);
914
915         glMatrixMode(GL_MODELVIEW);
916         glLoadMatrixd(glviewmat);
917         m_campos = pos;
918 }
919
920
921 const MT_Point3& RAS_OpenGLRasterizer::GetCameraPosition()
922 {
923         return m_campos;
924 }
925
926 bool RAS_OpenGLRasterizer::GetCameraOrtho()
927 {
928         return m_camortho;
929 }
930
931 void RAS_OpenGLRasterizer::SetCullFace(bool enable)
932 {
933         if (enable)
934                 glEnable(GL_CULL_FACE);
935         else
936                 glDisable(GL_CULL_FACE);
937 }
938
939 void RAS_OpenGLRasterizer::SetLines(bool enable)
940 {
941         if (enable)
942                 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
943         else
944                 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
945 }
946
947 void RAS_OpenGLRasterizer::SetSpecularity(float specX,
948                                                                                   float specY,
949                                                                                   float specZ,
950                                                                                   float specval)
951 {
952         GLfloat mat_specular[] = {specX, specY, specZ, specval};
953         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
954 }
955
956
957
958 void RAS_OpenGLRasterizer::SetShinyness(float shiny)
959 {
960         GLfloat mat_shininess[] = {     shiny };
961         glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
962 }
963
964
965
966 void RAS_OpenGLRasterizer::SetDiffuse(float difX,float difY,float difZ,float diffuse)
967 {
968         GLfloat mat_diffuse [] = {difX, difY,difZ, diffuse};
969         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
970 }
971
972 void RAS_OpenGLRasterizer::SetEmissive(float eX, float eY, float eZ, float e)
973 {
974         GLfloat mat_emit [] = {eX,eY,eZ,e};
975         glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_emit);
976 }
977
978
979 double RAS_OpenGLRasterizer::GetTime()
980 {
981         return m_time;
982 }
983
984 void RAS_OpenGLRasterizer::SetPolygonOffset(float mult, float add)
985 {
986         glPolygonOffset(mult, add);
987         GLint mode = GL_POLYGON_OFFSET_FILL;
988         if (m_drawingmode < KX_SHADED)
989                 mode = GL_POLYGON_OFFSET_LINE;
990         if (mult != 0.0f || add != 0.0f)
991                 glEnable(mode);
992         else
993                 glDisable(mode);
994 }
995
996 void RAS_OpenGLRasterizer::EnableMotionBlur(float motionblurvalue)
997 {
998         /* don't just set m_motionblur to 1, but check if it is 0 so
999          * we don't reset a motion blur that is already enabled */
1000         if (m_motionblur == 0)
1001                 m_motionblur = 1;
1002         m_motionblurvalue = motionblurvalue;
1003 }
1004
1005 void RAS_OpenGLRasterizer::DisableMotionBlur()
1006 {
1007         m_motionblur = 0;
1008         m_motionblurvalue = -1.0;
1009 }
1010
1011 void RAS_OpenGLRasterizer::SetAlphaBlend(int alphablend)
1012 {
1013         GPU_set_material_alpha_blend(alphablend);
1014 /*
1015         if (alphablend == m_last_alphablend)
1016                 return;
1017
1018         if (alphablend == GPU_BLEND_SOLID) {
1019                 glDisable(GL_BLEND);
1020                 glDisable(GL_ALPHA_TEST);
1021                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1022         }
1023         else if (alphablend == GPU_BLEND_ADD) {
1024                 glBlendFunc(GL_ONE, GL_ONE);
1025                 glEnable(GL_BLEND);
1026                 glDisable(GL_ALPHA_TEST);
1027         }
1028         else if (alphablend == GPU_BLEND_ALPHA) {
1029                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1030                 glEnable(GL_BLEND);
1031                 glEnable(GL_ALPHA_TEST);
1032                 glAlphaFunc(GL_GREATER, 0.0f);
1033         }
1034         else if (alphablend == GPU_BLEND_CLIP) {
1035                 glDisable(GL_BLEND); 
1036                 glEnable(GL_ALPHA_TEST);
1037                 glAlphaFunc(GL_GREATER, 0.5f);
1038         }
1039
1040         m_last_alphablend = alphablend;
1041 */
1042 }
1043
1044 void RAS_OpenGLRasterizer::SetFrontFace(bool ccw)
1045 {
1046         if (m_last_frontface == ccw)
1047                 return;
1048
1049         if (ccw)
1050                 glFrontFace(GL_CCW);
1051         else
1052                 glFrontFace(GL_CW);
1053         
1054         m_last_frontface = ccw;
1055 }
1056
1057 void RAS_OpenGLRasterizer::SetAnisotropicFiltering(short level)
1058 {
1059         GPU_set_anisotropic((float)level);
1060 }
1061
1062 short RAS_OpenGLRasterizer::GetAnisotropicFiltering()
1063 {
1064         return (short)GPU_get_anisotropic();
1065 }
1066
1067 void RAS_OpenGLRasterizer::SetMipmapping(MipmapOption val)
1068 {
1069         if (val == RAS_IRasterizer::RAS_MIPMAP_LINEAR)
1070         {
1071                 GPU_set_linear_mipmap(1);
1072                 GPU_set_mipmap(1);
1073         }
1074         else if (val == RAS_IRasterizer::RAS_MIPMAP_NEAREST)
1075         {
1076                 GPU_set_linear_mipmap(0);
1077                 GPU_set_mipmap(1);
1078         }
1079         else
1080         {
1081                 GPU_set_linear_mipmap(0);
1082                 GPU_set_mipmap(0);
1083         }
1084 }
1085
1086 RAS_IRasterizer::MipmapOption RAS_OpenGLRasterizer::GetMipmapping()
1087 {
1088         if (GPU_get_linear_mipmap())
1089                 return RAS_IRasterizer::RAS_MIPMAP_LINEAR;
1090         else if (GPU_get_mipmap())
1091                 return RAS_IRasterizer::RAS_MIPMAP_NEAREST;
1092         else
1093                 return RAS_IRasterizer::RAS_MIPMAP_NONE;
1094 }
1095
1096 void RAS_OpenGLRasterizer::SetUsingOverrideShader(bool val)
1097 {
1098         m_usingoverrideshader = val;
1099 }
1100
1101 bool RAS_OpenGLRasterizer::GetUsingOverrideShader()
1102 {
1103         return m_usingoverrideshader;
1104 }
1105