2.50: svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r19323...
[blender.git] / source / gameengine / Rasterizer / RAS_OpenGLRasterizer / RAS_OpenGLRasterizer.cpp
index 1a3f40491f7af1ab8930f6b2bd1f72171a229db4..1a9a28916de1c1794fe37029cd6813c81517eea2 100644 (file)
@@ -1,14 +1,11 @@
 /**
  * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License.  See http://www.blender.org/BL/ for information
- * about this.
+ * of the License, or (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  *
  * Contributor(s): none yet.
  *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
  */
+#include <math.h>
+#include <stdlib.h>
 #include "RAS_OpenGLRasterizer.h"
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef WIN32
-#include <windows.h>
-#endif // WIN32
-#ifdef __APPLE__
-#include <OpenGL/gl.h>
-#else
-#include <GL/gl.h>
-#endif
+#include "GL/glew.h"
 
 #include "RAS_Rect.h"
 #include "RAS_TexVert.h"
 #include "MT_CmMatrix4x4.h"
 #include "RAS_IRenderTools.h" // rendering text
 
-#include "RAS_GLExtensionManager.h"
+#include "GPU_draw.h"
+#include "GPU_material.h"
+
+/**
+ *  32x32 bit masks for vinterlace stereo mode
+ */
+static GLuint left_eye_vinterlace_mask[32];
+static GLuint right_eye_vinterlace_mask[32];
 
+/**
+ *  32x32 bit masks for hinterlace stereo mode.
+ *  Left eye = &hinterlace_mask[0]
+ *  Right eye = &hinterlace_mask[1]
+ */
+static GLuint hinterlace_mask[33];
 
 RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
        :RAS_IRasterizer(canvas),
        m_2DCanvas(canvas),
        m_fogenabled(false),
        m_time(0.0),
+       m_campos(0.0f, 0.0f, 0.0f),
+       m_camortho(false),
        m_stereomode(RAS_STEREO_NOSTEREO),
        m_curreye(RAS_STEREO_LEFTEYE),
+       m_eyeseparation(0.0),
+       m_seteyesep(false),
+       m_focallength(0.0),
+       m_setfocallength(false),
        m_noOfScanlines(32),
+       m_motionblur(0),
+       m_motionblurvalue(-1.0),
+       m_texco_num(0),
+       m_attrib_num(0),
+       m_last_blendmode(GPU_BLEND_SOLID),
+       m_last_frontface(true),
        m_materialCachingInfo(0)
 {
-       m_viewmatrix.Identity();
+       m_viewmatrix.setIdentity();
+       m_viewinvmatrix.setIdentity();
+       
+       for (int i = 0; i < 32; i++)
+       {
+               left_eye_vinterlace_mask[i] = 0x55555555;
+               right_eye_vinterlace_mask[i] = 0xAAAAAAAA;
+               hinterlace_mask[i] = (i&1)*0xFFFFFFFF;
+       }
+       hinterlace_mask[32] = 0;
 }
 
 
@@ -70,80 +94,26 @@ RAS_OpenGLRasterizer::~RAS_OpenGLRasterizer()
 {
 }
 
-
-
-static void Myinit_gl_stuff(void)      
-{
-       float mat_specular[] = { 0.5, 0.5, 0.5, 1.0 };
-       float mat_shininess[] = { 35.0 };
-/*     float one= 1.0; */
-       int a, x, y;
-       GLubyte pat[32*32];
-       const GLubyte *patc= pat;
-               
-       glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_specular);
-       glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
-       glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
-
-
-#if defined(__FreeBSD) || defined(__linux__)
-       glDisable(GL_DITHER);   /* op sgi/sun hardware && 12 bits */
-#endif
-       
-       /* no local viewer, looks ugly in ortho mode */
-       /* glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, &one); */
-       
-       glDepthFunc(GL_LEQUAL);
-       /* scaling matrices */
-       glEnable(GL_NORMALIZE);
-
-       glShadeModel(GL_FLAT);
-
-       glDisable(GL_ALPHA_TEST);
-       glDisable(GL_BLEND);
-       glDisable(GL_DEPTH_TEST);
-       glDisable(GL_FOG);
-       glDisable(GL_LIGHTING);
-       glDisable(GL_LOGIC_OP);
-       glDisable(GL_STENCIL_TEST);
-       glDisable(GL_TEXTURE_1D);
-       glDisable(GL_TEXTURE_2D);
-
-       glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
-       glPixelTransferi(GL_RED_SCALE, 1);
-       glPixelTransferi(GL_RED_BIAS, 0);
-       glPixelTransferi(GL_GREEN_SCALE, 1);
-       glPixelTransferi(GL_GREEN_BIAS, 0);
-       glPixelTransferi(GL_BLUE_SCALE, 1);
-       glPixelTransferi(GL_BLUE_BIAS, 0);
-       glPixelTransferi(GL_ALPHA_SCALE, 1);
-       glPixelTransferi(GL_ALPHA_BIAS, 0);
-
-       a = 0;
-       for(x=0; x<32; x++)
-       {
-               for(y=0; y<4; y++)
-               {
-                       if( (x) & 1) pat[a++]= 0x88;
-                       else pat[a++]= 0x22;
-               }
-       }
-       
-       glPolygonStipple(patc);
-}
-
-
-
 bool RAS_OpenGLRasterizer::Init()
 {
-
-       Myinit_gl_stuff();
+       GPU_state_init();
 
        m_redback = 0.4375;
        m_greenback = 0.4375;
        m_blueback = 0.4375;
        m_alphaback = 0.0;
        
+       m_ambr = 0.0f;
+       m_ambg = 0.0f;
+       m_ambb = 0.0f;
+
+       glDisable(GL_BLEND);
+       glDisable(GL_ALPHA_TEST);
+       m_last_blendmode = GPU_BLEND_SOLID;
+
+       glFrontFace(GL_CCW);
+       m_last_frontface = true;
+
        glClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -154,6 +124,20 @@ bool RAS_OpenGLRasterizer::Init()
 }
 
 
+void RAS_OpenGLRasterizer::SetAmbientColor(float red, float green, float blue)
+{
+       m_ambr = red;
+       m_ambg = green;
+       m_ambb = blue;
+}
+
+
+void RAS_OpenGLRasterizer::SetAmbient(float factor)
+{
+       float ambient[] = { m_ambr*factor, m_ambg*factor, m_ambb*factor, 1.0f };
+       glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
+}
+
 
 void RAS_OpenGLRasterizer::SetBackColor(float red,
                                                                                float green,
@@ -243,12 +227,9 @@ void RAS_OpenGLRasterizer::DisplayFog()
 
 
 
-void RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat)
+bool RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat)
 {
-       if (mat.GetCachingInfo() != m_materialCachingInfo)
-       {
-               mat.Activate(this, m_materialCachingInfo);
-       }
+       return mat.Activate(this, m_materialCachingInfo);
 }
 
 
@@ -265,23 +246,20 @@ void RAS_OpenGLRasterizer::Exit()
        glDepthMask (GL_TRUE);
        glDepthFunc(GL_LEQUAL);
        glBlendFunc(GL_ONE, GL_ZERO);
-
+       
+       glDisable(GL_POLYGON_STIPPLE);
+       
        glDisable(GL_LIGHTING);
-       if (bgl::QueryExtension(bgl::_GL_EXT_separate_specular_color) || bgl::QueryVersion(1, 2))
+       if (GLEW_EXT_separate_specular_color || GLEW_VERSION_1_2)
                glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
        
        EndFrame();
 }
 
-
-
 bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
 {
        m_time = time;
        m_drawingmode = drawingmode;
-       
-       m_2DCanvas->ClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
-       m_2DCanvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER);
 
        // Blender camera routine destroys the settings
        if (m_drawingmode < KX_SOLID)
@@ -295,6 +273,13 @@ bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
                glEnable (GL_CULL_FACE);
        }
 
+       glDisable(GL_BLEND);
+       glDisable(GL_ALPHA_TEST);
+       m_last_blendmode = GPU_BLEND_SOLID;
+
+       glFrontFace(GL_CCW);
+       m_last_frontface = true;
+
        glShadeModel(GL_SMOOTH);
 
        m_2DCanvas->BeginFrame();
@@ -308,46 +293,28 @@ void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode)
 {
        m_drawingmode = drawingmode;
 
-       switch (m_drawingmode)
-       {
-       case KX_BOUNDINGBOX:
-               {
-               }
-       case KX_WIREFRAME:
-               {
-                       glDisable (GL_CULL_FACE);
-                       break;
-               }
-       case KX_TEXTURED:
-               {
-               }
-       case KX_SHADED:
-               {
-               }
-       case KX_SOLID:
-               {
-               }
-       default:
-               {
-               }
-       }
+       if(m_drawingmode == KX_WIREFRAME)
+               glDisable(GL_CULL_FACE);
 }
 
-
-
 int RAS_OpenGLRasterizer::GetDrawingMode()
 {
        return m_drawingmode;
 }
 
 
-
 void RAS_OpenGLRasterizer::SetDepthMask(DepthMask depthmask)
 {
        glDepthMask(depthmask == KX_DEPTHMASK_DISABLED ? GL_FALSE : GL_TRUE);
 }
 
 
+void RAS_OpenGLRasterizer::ClearColorBuffer()
+{
+       m_2DCanvas->ClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
+       m_2DCanvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER);
+}
+
 
 void RAS_OpenGLRasterizer::ClearDepthBuffer()
 {
@@ -360,9 +327,44 @@ void RAS_OpenGLRasterizer::ClearCachingInfo(void)
        m_materialCachingInfo = 0;
 }
 
+void RAS_OpenGLRasterizer::FlushDebugLines()
+{
+       if(!m_debugLines.size())
+               return;
+
+       // DrawDebugLines
+       GLboolean light, tex;
+
+       light= glIsEnabled(GL_LIGHTING);
+       tex= glIsEnabled(GL_TEXTURE_2D);
+
+       if(light) glDisable(GL_LIGHTING);
+       if(tex) glDisable(GL_TEXTURE_2D);
+
+       glBegin(GL_LINES);
+       for (unsigned int i=0;i<m_debugLines.size();i++)
+       {
+               glColor4f(m_debugLines[i].m_color[0],m_debugLines[i].m_color[1],m_debugLines[i].m_color[2],1.f);
+               const MT_Scalar* fromPtr = &m_debugLines[i].m_from.x();
+               const MT_Scalar* toPtr= &m_debugLines[i].m_to.x();
+
+               glVertex3dv(fromPtr);
+               glVertex3dv(toPtr);
+       }
+       glEnd();
+
+       if(light) glEnable(GL_LIGHTING);
+       if(tex) glEnable(GL_TEXTURE_2D);
+
+       m_debugLines.clear();
+}
 
 void RAS_OpenGLRasterizer::EndFrame()
 {
+       
+
+       FlushDebugLines();
+
        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
        m_2DCanvas->EndFrame();
 }      
@@ -421,25 +423,31 @@ void RAS_OpenGLRasterizer::SetRenderArea()
                        break;
        }
 }
-
        
 void RAS_OpenGLRasterizer::SetStereoMode(const StereoMode stereomode)
 {
        m_stereomode = stereomode;
 }
 
-
+RAS_IRasterizer::StereoMode RAS_OpenGLRasterizer::GetStereoMode()
+{
+       return m_stereomode;
+}
 
 bool RAS_OpenGLRasterizer::Stereo()
 {
-       if(m_stereomode == RAS_STEREO_NOSTEREO)
+       if(m_stereomode == RAS_STEREO_NOSTEREO || m_stereomode == RAS_STEREO_DOME)
                return false;
        else
                return true;
 }
 
+bool RAS_OpenGLRasterizer::InterlacedStereo()
+{
+       return m_stereomode == RAS_STEREO_VINTERLACE || m_stereomode == RAS_STEREO_INTERLACED;
+}
 
-void RAS_OpenGLRasterizer::SetEye(StereoEye eye)
+void RAS_OpenGLRasterizer::SetEye(const StereoEye eye)
 {
        m_curreye = eye;
        switch (m_stereomode)
@@ -451,29 +459,59 @@ void RAS_OpenGLRasterizer::SetEye(StereoEye eye)
                        if (m_curreye == RAS_STEREO_LEFTEYE)
                        {
                                glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_FALSE);
-                               m_2DCanvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER);
-                               glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE);
                        } else {
-                               glAccum(GL_LOAD, 1.0);
+                               //glAccum(GL_LOAD, 1.0);
                                glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
                                ClearDepthBuffer();
                        }
                        break;
+               case RAS_STEREO_VINTERLACE:
+               {
+                       glEnable(GL_POLYGON_STIPPLE);
+                       glPolygonStipple((const GLubyte*) ((m_curreye == RAS_STEREO_LEFTEYE) ? left_eye_vinterlace_mask : right_eye_vinterlace_mask));
+                       if (m_curreye == RAS_STEREO_RIGHTEYE)
+                               ClearDepthBuffer();
+                       break;
+               }
+               case RAS_STEREO_INTERLACED:
+               {
+                       glEnable(GL_POLYGON_STIPPLE);
+                       glPolygonStipple((const GLubyte*) &hinterlace_mask[m_curreye == RAS_STEREO_LEFTEYE?0:1]);
+                       if (m_curreye == RAS_STEREO_RIGHTEYE)
+                               ClearDepthBuffer();
+                       break;
+               }
                default:
                        break;
        }
 }
 
+RAS_IRasterizer::StereoEye RAS_OpenGLRasterizer::GetEye()
+{
+       return m_curreye;
+}
+
 
-void RAS_OpenGLRasterizer::SetEyeSeparation(float eyeseparation)
+void RAS_OpenGLRasterizer::SetEyeSeparation(const float eyeseparation)
 {
        m_eyeseparation = eyeseparation;
+       m_seteyesep = true;
 }
 
+float RAS_OpenGLRasterizer::GetEyeSeparation()
+{
+       return m_eyeseparation;
+}
 
-void RAS_OpenGLRasterizer::SetFocalLength(float focallength)
+void RAS_OpenGLRasterizer::SetFocalLength(const float focallength)
 {
        m_focallength = focallength;
+       m_setfocallength = true;
+}
+
+float RAS_OpenGLRasterizer::GetFocalLength()
+{
+       return m_focallength;
 }
 
 
@@ -484,603 +522,260 @@ void RAS_OpenGLRasterizer::SwapBuffers()
 
 
 
-void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays,
-                                                                       const vecIndexArrays & indexarrays,
-                                                                       int mode,
+const MT_Matrix4x4& RAS_OpenGLRasterizer::GetViewMatrix() const
+{
+       return m_viewmatrix;
+}
+
+const MT_Matrix4x4& RAS_OpenGLRasterizer::GetViewInvMatrix() const
+{
+       return m_viewinvmatrix;
+}
+
+void RAS_OpenGLRasterizer::IndexPrimitives_3DText(RAS_MeshSlot& ms,
                                                                        class RAS_IPolyMaterial* polymat,
-                                                                       class RAS_IRenderTools* rendertools,
-                                                                       bool useObjectColor,
-                                                                       const MT_Vector4& rgbacolor
-                                                                       )
+                                                                       class RAS_IRenderTools* rendertools)
 { 
-       GLenum drawmode;
-       switch (mode)
-       {
-       case 0:
-               drawmode = GL_TRIANGLES;
-               break;
-       case 1:
-               drawmode = GL_LINES;
-               break;
-       case 2:
-               drawmode = GL_QUADS;
-               break;
-       default:
-               drawmode = GL_LINES;
-               break;
+       bool obcolor = ms.m_bObjectColor;
+       MT_Vector4& rgba = ms.m_RGBAcolor;
+       RAS_MeshSlot::iterator it;
+
+       // handle object color
+       if (obcolor) {
+               glDisableClientState(GL_COLOR_ARRAY);
+               glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
        }
-       
-       const RAS_TexVert* vertexarray ;
-       unsigned int numindices,vt;
+       else
+               glEnableClientState(GL_COLOR_ARRAY);
 
-       for (vt=0;vt<vertexarrays.size();vt++)
-       {
-               vertexarray = &((*vertexarrays[vt]) [0]);
-               const KX_IndexArray & indexarray = (*indexarrays[vt]);
-               numindices = indexarray.size();
+       for(ms.begin(it); !ms.end(it); ms.next(it)) {
+               RAS_TexVert *vertex;
+               size_t i, j, numvert;
                
-               if (!numindices)
-                       break;
-               
-               int vindex=0;
-               switch (mode)
-               {
-               case 1:
-                       {
-                               glBegin(GL_LINES);
-                               vindex=0;
-                               for (unsigned int i=0;i<numindices;i+=2)
-                               {
-                                       glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
-                                       glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
-                               }
-                               glEnd();
-                       }
-                       break;
-               case 2:
+               numvert = it.array->m_type;
+
+               if(it.array->m_type == RAS_DisplayArray::LINE) {
+                       // line drawing, no text
+                       glBegin(GL_LINES);
+
+                       for(i=0; i<it.totindex; i+=2)
                        {
-                               glBegin(GL_QUADS);
-                               vindex=0;
-                               if (useObjectColor)
-                               {
-                                       for (unsigned int i=0;i<numindices;i+=4)
-                                       {
-
-                                               glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
-
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                       }
-                               }
-                               else
-                               {
-                                       for (unsigned int i=0;i<numindices;i+=4)
-                                       {
-                                               // This looks curiously endian unsafe to me.
-                                               // However it depends on the way the colors are packed into 
-                                               // the m_rgba field of RAS_TexVert
-
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                       }
-                               }
-                               glEnd();        
-                               break;
+                               vertex = &it.vertex[it.index[i]];
+                               glVertex3fv(vertex->getXYZ());
+
+                               vertex = &it.vertex[it.index[i+1]];
+                               glVertex3fv(vertex->getXYZ());
                        }
-               case 0:
+
+                       glEnd();
+               }
+               else {
+                       // triangle and quad text drawing
+                       for(i=0; i<it.totindex; i+=numvert)
                        {
-                               glBegin(GL_TRIANGLES);
-                               vindex=0;
-                               if (useObjectColor)
-                               {
-                                       for (unsigned int i=0;i<numindices;i+=3)
-                                       {
-
-                                               glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
-
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                       }
-                               }
-                               else 
-                               {
-                                       for (unsigned int i=0;i<numindices;i+=3)
-                                       {
-
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                       }
+                               float v[4][3];
+                               int glattrib, unit;
+
+                               for(j=0; j<numvert; j++) {
+                                       vertex = &it.vertex[it.index[i+j]];
+
+                                       v[j][0] = vertex->getXYZ()[0];
+                                       v[j][1] = vertex->getXYZ()[1];
+                                       v[j][2] = vertex->getXYZ()[2];
                                }
-                               glEnd();        
-                               break;
-                       }
-               default:
-                       {
+
+                               // find the right opengl attribute
+                               glattrib = -1;
+                               if(GLEW_ARB_vertex_program)
+                                       for(unit=0; unit<m_attrib_num; unit++)
+                                               if(m_attrib[unit] == RAS_TEXCO_UV1)
+                                                       glattrib = unit;
+                               
+                               rendertools->RenderText(polymat->GetDrawingMode(), polymat,
+                                       v[0], v[1], v[2], (numvert == 4)? v[3]: NULL, glattrib);
+
+                               ClearCachingInfo();
                        }
-                       
-               } // switch
-       } // for each vertexarray
+               }
+       }
 
+       glDisableClientState(GL_COLOR_ARRAY);
 }
 
-void RAS_OpenGLRasterizer::IndexPrimitives_Ex(const vecVertexArray & vertexarrays,
-                                                                       const vecIndexArrays & indexarrays,
-                                                                       int mode,
-                                                                       class RAS_IPolyMaterial* polymat,
-                                                                       class RAS_IRenderTools* rendertools,
-                                                                       bool useObjectColor,
-                                                                       const MT_Vector4& rgbacolor
-                                                                       )
-{ 
-       bool    recalc;
-       GLenum drawmode;
-       switch (mode)
-       {
-       case 0:
-               drawmode = GL_TRIANGLES;
-               break;
-       case 1:
-               drawmode = GL_LINES;
-               break;
-       case 2:
-               drawmode = GL_QUADS;
-               break;
-       default:
-               drawmode = GL_LINES;
-               break;
-       }
-       
-       const RAS_TexVert* vertexarray ;
-       unsigned int numindices,vt;
+void RAS_OpenGLRasterizer::SetTexCoordNum(int num)
+{
+       m_texco_num = num;
+       if(m_texco_num > RAS_MAX_TEXCO)
+               m_texco_num = RAS_MAX_TEXCO;
+}
 
-       for (vt=0;vt<vertexarrays.size();vt++)
-       {
-               vertexarray = &((*vertexarrays[vt]) [0]);
-               const KX_IndexArray & indexarray = (*indexarrays[vt]);
-               numindices = indexarray.size();
-               
-               if (!numindices)
-                       continue;
-               
-               int vindex=0;
-               switch (mode)
-               {
-               case 1:
-                       {
-                               glBegin(GL_LINES);
-                               vindex=0;
-                               for (unsigned int i=0;i<numindices;i+=2)
-                               {
-                                       glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
-                                       glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
-                               }
-                               glEnd();
-                       }
-                       break;
-               case 2:
-                       {
-                               glBegin(GL_QUADS);
-                               vindex=0;
-                               if (useObjectColor)
-                               {
-                                       for (unsigned int i=0;i<numindices;i+=4)
-                                       {
-                                               MT_Point3 mv1, mv2, mv3, mv4, fnor;
-                                               /* Calc a new face normal */
+void RAS_OpenGLRasterizer::SetAttribNum(int num)
+{
+       m_attrib_num = num;
+       if(m_attrib_num > RAS_MAX_ATTRIB)
+               m_attrib_num = RAS_MAX_ATTRIB;
+}
 
-                                               if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
-                                                       recalc= true;
-                                               else
-                                                       recalc=false;
-
-                                               if (recalc){
-                                                       mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                                       mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
-                                                       mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
-                                                       mv4 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
-                                                       
-                                                       fnor = (((mv2-mv1).cross(mv3-mv2))+((mv4-mv3).cross(mv1-mv4))).safe_normalized();
-
-                                                       glNormal3f(fnor[0], fnor[1], fnor[2]);
-                                               }
-
-                                               glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
-
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());                                             
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                       }
-                               }
-                               else
-                               {
-                                       for (unsigned int i=0;i<numindices;i+=4)
-                                       {
-                                               // This looks curiously endian unsafe to me.
-                                               // However it depends on the way the colors are packed into 
-                                               // the m_rgba field of RAS_TexVert
-                                               MT_Point3 mv1, mv2, mv3, mv4, fnor;
-                                               /* Calc a new face normal */
-
-                                               if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
-                                                       recalc= true;
-                                               else
-                                                       recalc=false;
-
-
-                                               if (recalc){
-                                                       mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                                       mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
-                                                       mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
-                                                       mv4 = MT_Point3(vertexarray[(indexarray[vindex+3])].getLocalXYZ());
-                                                       
-                                                       fnor = (((mv2-mv1).cross(mv3-mv2))+((mv4-mv3).cross(mv1-mv4))).safe_normalized();
-
-                                                       glNormal3f(fnor[0], fnor[1], fnor[2]);
-                                               }
-
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                       }
-                               }
-                               glEnd();        
-                               break;
-                       }
-               case 0:
-                       {
-                               glBegin(GL_TRIANGLES);
-                               vindex=0;
-                               if (useObjectColor)
-                               {
-                                       for (unsigned int i=0;i<numindices;i+=3)
-                                       {
-                                               MT_Point3 mv1, mv2, mv3, fnor;
-                                               /* Calc a new face normal */
+void RAS_OpenGLRasterizer::SetTexCoord(TexCoGen coords, int unit)
+{
+       // this changes from material to material
+       if(unit < RAS_MAX_TEXCO)
+               m_texco[unit] = coords;
+}
 
-                                               if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
-                                                       recalc= true;
-                                               else
-                                                       recalc=false;
-
-                                               if (recalc){
-                                                       mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                                       mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
-                                                       mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
-                                                       
-                                                       fnor = ((mv2-mv1).cross(mv3-mv2)).safe_normalized();
-                                                       glNormal3f(fnor[0], fnor[1], fnor[2]);
-                                               }
-
-                                               glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
-
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                       }
-                               }
-                               else 
-                               {
-                                       for (unsigned int i=0;i<numindices;i+=3)
-                                       {
-                                               MT_Point3 mv1, mv2, mv3, fnor;
-                                               /* Calc a new face normal */
+void RAS_OpenGLRasterizer::SetAttrib(TexCoGen coords, int unit)
+{
+       // this changes from material to material
+       if(unit < RAS_MAX_ATTRIB)
+               m_attrib[unit] = coords;
+}
 
-                                               if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
-                                                       recalc= true;
-                                               else
-                                                       recalc=false;
-
-
-                                               if (recalc){
-                                                       mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                                       mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
-                                                       mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
-                                                       
-                                                       fnor = ((mv2-mv1).cross(mv3-mv2)).safe_normalized();
-                                                       glNormal3f(fnor[0], fnor[1], fnor[2]);
-                                               }
-
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                       }
-                               }
-                               glEnd();        
+void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv)
+{
+       int unit;
+
+       if(GLEW_ARB_multitexture) {
+               for(unit=0; unit<m_texco_num; unit++) {
+                       if(tv.getFlag() & RAS_TexVert::SECOND_UV && (int)tv.getUnit() == unit) {
+                               glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
+                               continue;
+                       }
+                       switch(m_texco[unit]) {
+                       case RAS_TEXCO_ORCO:
+                       case RAS_TEXCO_GLOB:
+                               glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getXYZ());
+                               break;
+                       case RAS_TEXCO_UV1:
+                               glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV1());
+                               break;
+                       case RAS_TEXCO_NORM:
+                               glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getNormal());
+                               break;
+                       case RAS_TEXTANGENT:
+                               glMultiTexCoord4fvARB(GL_TEXTURE0_ARB+unit, tv.getTangent());
+                               break;
+                       case RAS_TEXCO_UV2:
+                               glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
+                               break;
+                       default:
                                break;
                        }
-               default:
-                       {
+               }
+       }
+
+       if(GLEW_ARB_vertex_program) {
+               for(unit=0; unit<m_attrib_num; unit++) {
+                       switch(m_attrib[unit]) {
+                       case RAS_TEXCO_ORCO:
+                       case RAS_TEXCO_GLOB:
+                               glVertexAttrib3fvARB(unit, tv.getXYZ());
+                               break;
+                       case RAS_TEXCO_UV1:
+                               glVertexAttrib2fvARB(unit, tv.getUV1());
+                               break;
+                       case RAS_TEXCO_NORM:
+                               glVertexAttrib3fvARB(unit, tv.getNormal());
+                               break;
+                       case RAS_TEXTANGENT:
+                               glVertexAttrib4fvARB(unit, tv.getTangent());
+                               break;
+                       case RAS_TEXCO_UV2:
+                               glVertexAttrib2fvARB(unit, tv.getUV2());
+                               break;
+                       case RAS_TEXCO_VCOL:
+                               glVertexAttrib4ubvARB(unit, tv.getRGBA());
+                               break;
+                       default:
+                               break;
                        }
-                       
-               } // switch
-       } // for each vertexarray
+               }
+       }
 
 }
 
+void RAS_OpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
+{
+       IndexPrimitivesInternal(ms, false);
+}
 
+void RAS_OpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
+{
+       IndexPrimitivesInternal(ms, true);
+}
 
-void RAS_OpenGLRasterizer::IndexPrimitives_3DText(const vecVertexArray & vertexarrays,
-                                                                       const vecIndexArrays & indexarrays,
-                                                                       int mode,
-                                                                       class RAS_IPolyMaterial* polymat,
-                                                                       class RAS_IRenderTools* rendertools,
-                                                                       bool useObjectColor,
-                                                                       const MT_Vector4& rgbacolor
-                                                                       )
+void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
 { 
-       GLenum drawmode;
-       switch (mode)
-       {
-       case 0:
-               drawmode = GL_TRIANGLES;
-               break;
-       case 1:
-               drawmode = GL_LINES;
-               break;
-       case 2:
-               drawmode = GL_QUADS;
-               break;
-       default:
-               drawmode = GL_LINES;
-               break;
-       }
-       
-       const RAS_TexVert* vertexarray ;
-       
-       unsigned int numindices, vt;
-       
-       if (useObjectColor)
-       {
-               glDisableClientState(GL_COLOR_ARRAY);
-               glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
-       }
-       else
-       {
-               glEnableClientState(GL_COLOR_ARRAY);
-       }
-       
-       for (vt=0;vt<vertexarrays.size();vt++)
-       {
-               vertexarray = &((*vertexarrays[vt]) [0]);
-               const KX_IndexArray & indexarray = (*indexarrays[vt]);
-               numindices = indexarray.size();
+       bool obcolor = ms.m_bObjectColor;
+       bool wireframe = m_drawingmode <= KX_WIREFRAME;
+       MT_Vector4& rgba = ms.m_RGBAcolor;
+       RAS_MeshSlot::iterator it;
+
+       // iterate over display arrays, each containing an index + vertex array
+       for(ms.begin(it); !ms.end(it); ms.next(it)) {
+               RAS_TexVert *vertex;
+               size_t i, j, numvert;
                
-               if (!numindices)
-                       break;
-               
-               int vindex=0;
-               switch (mode)
-               {
-               case 1:
-                       {
-                               glBegin(GL_LINES);
-                               vindex=0;
-                               for (unsigned int i=0;i<numindices;i+=2)
-                               {
-                                       glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
-                                       glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
-                               }
-                               glEnd();
-                       }
-                       break;
-               case 2:
+               numvert = it.array->m_type;
+
+               if(it.array->m_type == RAS_DisplayArray::LINE) {
+                       // line drawing
+                       glBegin(GL_LINES);
+
+                       for(i=0; i<it.totindex; i+=2)
                        {
-                               vindex=0;
-                               for (unsigned int i=0;i<numindices;i+=4)
-                               {
-                                       float v1[3],v2[3],v3[3],v4[3];
-                                       
-                                       v1[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
-                                       v1[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
-                                       v1[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
-                                       vindex++;
-                                       
-                                       v2[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
-                                       v2[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
-                                       v2[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
-                                       vindex++;
-                                       
-                                       v3[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
-                                       v3[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
-                                       v3[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
-                                       vindex++;
-                                       
-                                       v4[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
-                                       v4[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
-                                       v4[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
-                                       
-                                       vindex++;
-                                       
-                                       rendertools->RenderText(polymat->GetDrawingMode(),polymat,v1,v2,v3,v4);
-                                       ClearCachingInfo();
-                               }
-                               break;
+                               vertex = &it.vertex[it.index[i]];
+                               glVertex3fv(vertex->getXYZ());
+
+                               vertex = &it.vertex[it.index[i+1]];
+                               glVertex3fv(vertex->getXYZ());
                        }
-               case 0:
-                       {
+
+                       glEnd();
+               }
+               else {
+                       // triangle and quad drawing
+                       if(it.array->m_type == RAS_DisplayArray::TRIANGLE)
                                glBegin(GL_TRIANGLES);
-                               vindex=0;
-                               for (unsigned int i=0;i<numindices;i+=3)
-                               {
-                                       float v1[3],v2[3],v3[3];
-                                       
-                                       v1[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
-                                       v1[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
-                                       v1[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
-                                       vindex++;
-                                       
-                                       v2[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
-                                       v2[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
-                                       v2[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
-                                       vindex++;
-                                       
-                                       v3[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
-                                       v3[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
-                                       v3[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
-                                       vindex++;
-                                       
-                                       rendertools->RenderText(polymat->GetDrawingMode(),polymat,v1,v2,v3,NULL);               
-                                       ClearCachingInfo();
-                               }
-                               glEnd();        
-                               break;
-                       }
-               default:
+                       else
+                               glBegin(GL_QUADS);
+
+                       for(i=0; i<it.totindex; i+=numvert)
                        {
-                       }
-               }       //switch
-       }       //for each vertexarray
-}
+                               if(obcolor)
+                                       glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
+
+                               for(j=0; j<numvert; j++) {
+                                       vertex = &it.vertex[it.index[i+j]];
 
+                                       if(!wireframe) {
+                                               if(!obcolor)
+                                                       glColor4ubv((const GLubyte *)(vertex->getRGBA()));
 
+                                               glNormal3fv(vertex->getNormal());
+
+                                               if(multi)
+                                                       TexCoord(*vertex);
+                                               else
+                                                       glTexCoord2fv(vertex->getUV1());
+                                       }
+
+                                       glVertex3fv(vertex->getXYZ());
+                               }
+                       }
+
+                       glEnd();
+               }
+       }
+}
 
 void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat)
 {
        glMatrixMode(GL_PROJECTION);
        double* matrix = &mat(0,0);
        glLoadMatrixd(matrix);
-}
 
+       m_camortho= (mat(3, 3) != 0.0f);
+}
 
 void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat)
 {
@@ -1090,6 +785,8 @@ void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat)
        mat.getValue(matrix);
        /* Internally, MT_Matrix4x4 uses doubles (MT_Scalar). */
        glLoadMatrixd(matrix);  
+
+       m_camortho= (mat[3][3] != 0.0f);
 }
 
 MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
@@ -1099,18 +796,22 @@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
        float top,
        float frustnear,
        float frustfar,
-       bool
+       float focallength,
+       bool 
 ){
        MT_Matrix4x4 result;
        double mat[16];
 
        // correction for stereo
-       if(m_stereomode != RAS_STEREO_NOSTEREO)
+       if(Stereo())
        {
                        float near_div_focallength;
                        // next 2 params should be specified on command line and in Blender publisher
-                       m_focallength = 1.5 * right;  // derived from example
-                       m_eyeseparation = 0.18 * right;  // just a guess...
+                       if (!m_setfocallength)
+                               m_focallength = (focallength == 0.f) ? 1.5 * right  // derived from example
+                                       : focallength; 
+                       if (!m_seteyesep)
+                               m_eyeseparation = m_focallength/30;  // reasonable value...
 
                        near_div_focallength = frustnear / m_focallength;
                        switch(m_curreye)
@@ -1142,10 +843,10 @@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
 void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, const MT_Vector3& campos,
                const MT_Point3 &, const MT_Quaternion &camOrientQuat)
 {
-       MT_Matrix4x4 viewMat = mat;
+       m_viewmatrix = mat;
 
        // correction for stereo
-       if(m_stereomode != RAS_STEREO_NOSTEREO)
+       if(Stereo())
        {
                MT_Matrix3x3 camOrientMat3x3(camOrientQuat);
                MT_Vector3 unitViewDir(0.0, -1.0, 0.0);  // minus y direction, Blender convention
@@ -1169,7 +870,7 @@ void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, const MT_Vecto
                                MT_Transform transform;
                                transform.setIdentity();
                                transform.translate(-(eyeline * m_eyeseparation / 2.0));
-                               viewMat *= transform;
+                               m_viewmatrix *= transform;
                                }
                                break;
                        case RAS_STEREO_RIGHTEYE:
@@ -1178,20 +879,21 @@ void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, const MT_Vecto
                                MT_Transform transform;
                                transform.setIdentity();
                                transform.translate(eyeline * m_eyeseparation / 2.0);
-                               viewMat *= transform;
+                               m_viewmatrix *= transform;
                                }
                                break;
                }
        }
 
-       // convert row major matrix 'viewMat' to column major for OpenGL
-       MT_Scalar cammat[16];
-       viewMat.getValue(cammat);
-       MT_CmMatrix4x4 viewCmmat = cammat;
+       m_viewinvmatrix = m_viewmatrix;
+       m_viewinvmatrix.invert();
+
+       // note: getValue gives back column major as needed by OpenGL
+       MT_Scalar glviewmat[16];
+       m_viewmatrix.getValue(glviewmat);
 
        glMatrixMode(GL_MODELVIEW);
-       m_viewmatrix = viewCmmat;
-       glLoadMatrixd(&m_viewmatrix(0,0));
+       glLoadMatrixd(glviewmat);
        m_campos = campos;
 }
 
@@ -1201,21 +903,11 @@ const MT_Point3& RAS_OpenGLRasterizer::GetCameraPosition()
        return m_campos;
 }
 
-
-
-void RAS_OpenGLRasterizer::LoadViewMatrix()
-{
-       glLoadMatrixd(&m_viewmatrix(0,0));
-}
-
-
-
-void RAS_OpenGLRasterizer::EnableTextures(bool enable)
+bool RAS_OpenGLRasterizer::GetCameraOrtho()
 {
+       return m_camortho;
 }
 
-
-
 void RAS_OpenGLRasterizer::SetCullFace(bool enable)
 {
        if (enable)
@@ -1257,9 +949,85 @@ void RAS_OpenGLRasterizer::SetDiffuse(float difX,float difY,float difZ,float dif
        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
 }
 
+void RAS_OpenGLRasterizer::SetEmissive(float eX, float eY, float eZ, float e)
+{
+       GLfloat mat_emit [] = {eX,eY,eZ,e};
+       glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_emit);
+}
+
+
 double RAS_OpenGLRasterizer::GetTime()
 {
        return m_time;
 }
 
+void RAS_OpenGLRasterizer::SetPolygonOffset(float mult, float add)
+{
+       glPolygonOffset(mult, add);
+       GLint mode = GL_POLYGON_OFFSET_FILL;
+       if (m_drawingmode < KX_SHADED)
+               mode = GL_POLYGON_OFFSET_LINE;
+       if (mult != 0.0f || add != 0.0f)
+               glEnable(mode);
+       else
+               glDisable(mode);
+}
+
+void RAS_OpenGLRasterizer::EnableMotionBlur(float motionblurvalue)
+{
+       /* don't just set m_motionblur to 1, but check if it is 0 so
+        * we don't reset a motion blur that is already enabled */
+       if(m_motionblur == 0)
+               m_motionblur = 1;
+       m_motionblurvalue = motionblurvalue;
+}
+
+void RAS_OpenGLRasterizer::DisableMotionBlur()
+{
+       m_motionblur = 0;
+       m_motionblurvalue = -1.0;
+}
+
+void RAS_OpenGLRasterizer::SetBlendingMode(int blendmode)
+{
+       if(blendmode == m_last_blendmode)
+               return;
+
+       if(blendmode == GPU_BLEND_SOLID) {
+               glDisable(GL_BLEND);
+               glDisable(GL_ALPHA_TEST);
+               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+       }
+       else if(blendmode == GPU_BLEND_ADD) {
+               glBlendFunc(GL_ONE, GL_ONE);
+               glEnable(GL_BLEND);
+               glDisable(GL_ALPHA_TEST);
+       }
+       else if(blendmode == GPU_BLEND_ALPHA) {
+               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+               glEnable(GL_BLEND);
+               glEnable(GL_ALPHA_TEST);
+               glAlphaFunc(GL_GREATER, 0.0f);
+       }
+       else if(blendmode == GPU_BLEND_CLIP) {
+               glDisable(GL_BLEND); 
+               glEnable(GL_ALPHA_TEST);
+               glAlphaFunc(GL_GREATER, 0.5f);
+       }
+
+       m_last_blendmode = blendmode;
+}
+
+void RAS_OpenGLRasterizer::SetFrontFace(bool ccw)
+{
+       if(m_last_frontface == ccw)
+               return;
+
+       if(ccw)
+               glFrontFace(GL_CCW);
+       else
+               glFrontFace(GL_CW);
+       
+       m_last_frontface = ccw;
+}