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 d3c0426de8682d645eda7f51f25acfc3a7654122..1a9a28916de1c1794fe37029cd6813c81517eea2 100644 (file)
@@ -38,6 +38,9 @@
 #include "MT_CmMatrix4x4.h"
 #include "RAS_IRenderTools.h" // rendering text
 
+#include "GPU_draw.h"
+#include "GPU_material.h"
+
 /**
  *  32x32 bit masks for vinterlace stereo mode
  */
@@ -56,6 +59,8 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* 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),
@@ -67,9 +72,12 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
        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++)
        {
@@ -86,78 +94,9 @@ 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);
-       
-       glFrontFace(GL_CCW);
-       glCullFace(GL_BACK);
-       glEnable(GL_CULL_FACE);
-}
-
-
-
 bool RAS_OpenGLRasterizer::Init()
 {
-
-       Myinit_gl_stuff();
+       GPU_state_init();
 
        m_redback = 0.4375;
        m_greenback = 0.4375;
@@ -168,6 +107,13 @@ bool RAS_OpenGLRasterizer::Init()
        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);
@@ -186,18 +132,6 @@ void RAS_OpenGLRasterizer::SetAmbientColor(float red, float green, float blue)
 }
 
 
-void RAS_OpenGLRasterizer::SetAlphaTest(bool enable)
-{
-       if (enable)
-       {
-               glEnable(GL_ALPHA_TEST);
-               glAlphaFunc(GL_GREATER, 0.6f);
-       }
-       else glDisable(GL_ALPHA_TEST);
-}
-
-
-
 void RAS_OpenGLRasterizer::SetAmbient(float factor)
 {
        float ambient[] = { m_ambr*factor, m_ambg*factor, m_ambb*factor, 1.0f };
@@ -322,21 +256,10 @@ void RAS_OpenGLRasterizer::Exit()
        EndFrame();
 }
 
-bool RAS_OpenGLRasterizer::InterlacedStereo() const
-{
-       return m_stereomode == RAS_STEREO_VINTERLACE || m_stereomode == RAS_STEREO_INTERLACED;
-}
-
 bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
 {
        m_time = time;
        m_drawingmode = drawingmode;
-       
-       if (!InterlacedStereo() || m_curreye == RAS_STEREO_LEFTEYE)
-       {
-               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)
@@ -350,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();
@@ -363,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()
 {
@@ -415,18 +327,23 @@ void RAS_OpenGLRasterizer::ClearCachingInfo(void)
        m_materialCachingInfo = 0;
 }
 
-
-void RAS_OpenGLRasterizer::EndFrame()
+void RAS_OpenGLRasterizer::FlushDebugLines()
 {
-       glDisable(GL_LIGHTING);
-       glDisable(GL_TEXTURE_2D);
+       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);
 
-       //DrawDebugLines
        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();
@@ -436,7 +353,17 @@ void RAS_OpenGLRasterizer::EndFrame()
        }
        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();
@@ -496,23 +423,29 @@ 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(const StereoEye eye)
 {
@@ -589,331 +522,84 @@ void RAS_OpenGLRasterizer::SwapBuffers()
 
 
 
-void RAS_OpenGLRasterizer::GetViewMatrix(MT_Matrix4x4 &mat) const
+const MT_Matrix4x4& RAS_OpenGLRasterizer::GetViewMatrix() const
 {
-       float viewmat[16];
-       glGetFloatv(GL_MODELVIEW_MATRIX, viewmat);
-       mat.setValue(viewmat);
+       return m_viewmatrix;
 }
 
-
-
-void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays,
-                                                                       const vecIndexArrays & indexarrays,
-                                                                       int mode,
-                                                                       class RAS_IPolyMaterial* polymat,
-                                                                       class RAS_IRenderTools* rendertools,
-                                                                       bool useObjectColor,
-                                                                       const MT_Vector4& rgbacolor,
-                                                                       class KX_ListSlot** slot
-                                                                       )
-{ 
-       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;
-
-       for (vt=0;vt<vertexarrays.size();vt++)
-       {
-               vertexarray = &((*vertexarrays[vt]) [0]);
-               const KX_IndexArray & indexarray = (*indexarrays[vt]);
-               numindices = indexarray.size();
-               
-               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:
-                       {
-                               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;
-                       }
-               case 0:
-                       {
-                               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++;
-                                       }
-                               }
-                               glEnd();        
-                               break;
-                       }
-               default:
-                       {
-                       }
-                       
-               } // switch
-       } // for each vertexarray
-
+const MT_Matrix4x4& RAS_OpenGLRasterizer::GetViewInvMatrix() const
+{
+       return m_viewinvmatrix;
 }
 
-void RAS_OpenGLRasterizer::IndexPrimitives_3DText(const vecVertexArray & vertexarrays,
-                                                                       const vecIndexArrays & indexarrays,
-                                                                       int mode,
+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;
-       }
-       
-       const RAS_TexVert* vertexarray ;
-       
-       unsigned int numindices, vt;
-       
-       if (useObjectColor)
-       {
+       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(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
+               glColor4d(rgba[0], rgba[1], rgba[2], rgba[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();
-               
-               if (!numindices)
-                       break;
+
+       for(ms.begin(it); !ms.end(it); ms.next(it)) {
+               RAS_TexVert *vertex;
+               size_t i, j, numvert;
                
-               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)
                        {
-                               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 text drawing
+                       for(i=0; i<it.totindex; i+=numvert)
                        {
-                               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();
+                               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::SetTexCoordNum(int num)
@@ -950,14 +636,14 @@ void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv)
 
        if(GLEW_ARB_multitexture) {
                for(unit=0; unit<m_texco_num; unit++) {
-                       if(tv.getFlag() & TV_2NDUV && (int)tv.getUnit() == 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.getLocalXYZ());
+                               glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getXYZ());
                                break;
                        case RAS_TEXCO_UV1:
                                glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV1());
@@ -982,7 +668,7 @@ void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv)
                        switch(m_attrib[unit]) {
                        case RAS_TEXCO_ORCO:
                        case RAS_TEXCO_GLOB:
-                               glVertexAttrib3fvARB(unit, tv.getLocalXYZ());
+                               glVertexAttrib3fvARB(unit, tv.getXYZ());
                                break;
                        case RAS_TEXCO_UV1:
                                glVertexAttrib2fvARB(unit, tv.getUV1());
@@ -996,6 +682,9 @@ void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv)
                        case RAS_TEXCO_UV2:
                                glVertexAttrib2fvARB(unit, tv.getUV2());
                                break;
+                       case RAS_TEXCO_VCOL:
+                               glVertexAttrib4ubvARB(unit, tv.getRGBA());
+                               break;
                        default:
                                break;
                        }
@@ -1003,229 +692,80 @@ void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv)
        }
 
 }
-void RAS_OpenGLRasterizer::Tangent(    const RAS_TexVert& v1,
-                                                                       const RAS_TexVert& v2,
-                                                                       const RAS_TexVert& v3,
-                                                                       const MT_Vector3 &no)
+
+void RAS_OpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
 {
-       // TODO: set for deformer... 
-       MT_Vector3 x1(v1.getLocalXYZ()), x2(v2.getLocalXYZ()), x3(v3.getLocalXYZ());
-       MT_Vector2 uv1(v1.getUV1()), uv2(v2.getUV1()), uv3(v3.getUV1());
-       MT_Vector3 dx1(x2 - x1), dx2(x3 - x1);
-       MT_Vector2 duv1(uv2 - uv1), duv2(uv3 - uv1);
-
-       MT_Scalar r = 1.0 / (duv1.x() * duv2.y() - duv2.x() * duv1.y());
-       duv1 *= r;
-       duv2 *= r;
-       MT_Vector3 sdir(duv2.y() * dx1 - duv1.y() * dx2);
-       MT_Vector3 tdir(duv1.x() * dx2 - duv2.x() * dx1);
-
-       // Gram-Schmidt orthogonalize
-       MT_Vector3 t(sdir - no.cross(no.cross(sdir)));
-       if (!MT_fuzzyZero(t)) t /= t.length();
-
-       float tangent[4];
-       t.getValue(tangent);
-       // Calculate handedness
-       tangent[3] = no.dot(sdir.cross(tdir)) < 0.0 ? -1.0 : 1.0;
+       IndexPrimitivesInternal(ms, false);
 }
 
+void RAS_OpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
+{
+       IndexPrimitivesInternal(ms, true);
+}
 
-void RAS_OpenGLRasterizer::IndexPrimitivesMulti(
-               const vecVertexArray& vertexarrays,
-               const vecIndexArrays & indexarrays,
-               int mode,
-               class RAS_IPolyMaterial* polymat,
-               class RAS_IRenderTools* rendertools,
-               bool useObjectColor,
-               const MT_Vector4& rgbacolor,
-               class KX_ListSlot** slot
-               )
+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;
-
-       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;
+               
+               numvert = it.array->m_type;
 
-               if (!numindices)
-                       break;
+               if(it.array->m_type == RAS_DisplayArray::LINE) {
+                       // line drawing
+                       glBegin(GL_LINES);
 
-               int vindex=0;
-               switch (mode)
-               {
-               case 1:
+                       for(i=0; i<it.totindex; i+=2)
                        {
-                               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();
+                               vertex = &it.vertex[it.index[i]];
+                               glVertex3fv(vertex->getXYZ());
+
+                               vertex = &it.vertex[it.index[i+1]];
+                               glVertex3fv(vertex->getXYZ());
                        }
-                       break;
-               case 2:
-                       {
+
+                       glEnd();
+               }
+               else {
+                       // triangle and quad drawing
+                       if(it.array->m_type == RAS_DisplayArray::TRIANGLE)
+                               glBegin(GL_TRIANGLES);
+                       else
                                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());
-                                               TexCoord(vertexarray[(indexarray[vindex])]);
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-
-                                               //
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])]);
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-
-                                               //
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])]);
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-
-                                               //
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])]);
-                                               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());
-                                               TexCoord(vertexarray[(indexarray[vindex])]);
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                       
-                                               //
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])]);
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-
-                                               //
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])]);
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-
-                                               //
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])]);
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                       }
-                               }
-                               glEnd();        
-                               break;
-                       }
-               case 0:
+
+                       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());
-                                               TexCoord(vertexarray[(indexarray[vindex])]);
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-
-                                               //
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])]);
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-
-                                               //
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])]);
-                                               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());
-                                               TexCoord(vertexarray[(indexarray[vindex])]);
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                               
-                                               //
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])]);
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-
-                                               //
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])]);
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
+                               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();        
-                               break;
                        }
-               default:
-                       {
-                       }
-               } // switch
-       } // for each vertexarray
+
+                       glEnd();
+               }
+       }
 }
 
 void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat)
@@ -1233,8 +773,9 @@ 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)
 {
@@ -1244,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(
@@ -1254,13 +797,13 @@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
        float frustnear,
        float frustfar,
        float focallength,
-       bool
+       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
@@ -1300,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
@@ -1327,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:
@@ -1336,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;
 }
 
@@ -1359,21 +903,11 @@ const MT_Point3& RAS_OpenGLRasterizer::GetCameraPosition()
        return m_campos;
 }
 
-
-
-void RAS_OpenGLRasterizer::LoadViewMatrix()
+bool RAS_OpenGLRasterizer::GetCameraOrtho()
 {
-       glLoadMatrixd(&m_viewmatrix(0,0));
+       return m_camortho;
 }
 
-
-
-void RAS_OpenGLRasterizer::EnableTextures(bool enable)
-{
-}
-
-
-
 void RAS_OpenGLRasterizer::SetCullFace(bool enable)
 {
        if (enable)
@@ -1441,7 +975,10 @@ void RAS_OpenGLRasterizer::SetPolygonOffset(float mult, float add)
 
 void RAS_OpenGLRasterizer::EnableMotionBlur(float motionblurvalue)
 {
-       m_motionblur = 1;
+       /* 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;
 }
 
@@ -1450,3 +987,47 @@ 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;
+}
+