added SetDisplayArea, GetDisplayArea was used in a confusing way
[blender-staging.git] / source / gameengine / Rasterizer / RAS_OpenGLRasterizer / RAS_OpenGLRasterizer.cpp
index 53ec7a02e6f79043196c9407b96ab5ca983265b0..5b732e802f6847341b3d7ef6eed5c622c13b46f3 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__
-#define GL_GLEXT_LEGACY 1
-#include <OpenGL/gl.h>
-#include <OpenGL/glu.h>
-#else
-#include <GL/gl.h>
-#include <GL/glu.h>
-#endif
+#include "GL/glew.h"
 
 #include "RAS_Rect.h"
 #include "RAS_TexVert.h"
+#include "RAS_MeshObject.h"
 #include "MT_CmMatrix4x4.h"
 #include "RAS_IRenderTools.h" // rendering text
 
-#include "RAS_GLExtensionManager.h"
+#include "GPU_draw.h"
+#include "GPU_material.h"
+#include "GPU_extensions.h"
+
+#include "DNA_image_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_material_types.h"
+#include "DNA_scene_types.h"
+
+#include "BKE_DerivedMesh.h"
 
 /**
  *  32x32 bit masks for vinterlace stereo mode
@@ -74,6 +68,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),
@@ -81,10 +77,16 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
        m_focallength(0.0),
        m_setfocallength(false),
        m_noOfScanlines(32),
-       m_useTang(false),
+       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++)
        {
@@ -101,78 +103,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;
@@ -183,6 +116,14 @@ 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;
+       GPU_set_material_blend_mode(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);
@@ -201,18 +142,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 };
@@ -282,6 +211,10 @@ void RAS_OpenGLRasterizer::DisableFog()
        m_fogenabled = false;
 }
 
+bool RAS_OpenGLRasterizer::IsFogEnabled()
+{
+       return m_fogenabled;
+}
 
 
 void RAS_OpenGLRasterizer::DisplayFog()
@@ -331,27 +264,16 @@ void RAS_OpenGLRasterizer::Exit()
        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::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)
@@ -365,6 +287,14 @@ 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;
+       GPU_set_material_blend_mode(GPU_BLEND_SOLID);
+
+       glFrontFace(GL_CCW);
+       m_last_frontface = true;
+
        glShadeModel(GL_SMOOTH);
 
        m_2DCanvas->BeginFrame();
@@ -378,46 +308,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()
 {
@@ -430,18 +342,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();
@@ -451,7 +368,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();
@@ -459,6 +386,7 @@ void RAS_OpenGLRasterizer::EndFrame()
 
 void RAS_OpenGLRasterizer::SetRenderArea()
 {
+       RAS_Rect area;
        // only above/below stereo method needs viewport adjustment
        switch (m_stereomode)
        {
@@ -467,19 +395,21 @@ void RAS_OpenGLRasterizer::SetRenderArea()
                        {
                                case RAS_STEREO_LEFTEYE:
                                        // upper half of window
-                                       m_2DCanvas->GetDisplayArea().SetLeft(0);
-                                       m_2DCanvas->GetDisplayArea().SetBottom(m_2DCanvas->GetHeight() -
+                                       area.SetLeft(0);
+                                       area.SetBottom(m_2DCanvas->GetHeight() -
                                                int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
        
-                                       m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
-                                       m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight()));
+                                       area.SetRight(int(m_2DCanvas->GetWidth()));
+                                       area.SetTop(int(m_2DCanvas->GetHeight()));
+                                       m_2DCanvas->SetDisplayArea(&area);
                                        break;
                                case RAS_STEREO_RIGHTEYE:
                                        // lower half of window
-                                       m_2DCanvas->GetDisplayArea().SetLeft(0);
-                                       m_2DCanvas->GetDisplayArea().SetBottom(0);
-                                       m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
-                                       m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
+                                       area.SetLeft(0);
+                                       area.SetBottom(0);
+                                       area.SetRight(int(m_2DCanvas->GetWidth()));
+                                       area.SetTop(int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
+                                       m_2DCanvas->SetDisplayArea(&area);
                                        break;
                        }
                        break;
@@ -488,46 +418,55 @@ void RAS_OpenGLRasterizer::SetRenderArea()
                        {
                                case RAS_STEREO_LEFTEYE:
                                        // Left half of window
-                                       m_2DCanvas->GetDisplayArea().SetLeft(0);
-                                       m_2DCanvas->GetDisplayArea().SetBottom(0);
-                                       m_2DCanvas->GetDisplayArea().SetRight(m_2DCanvas->GetWidth()/2);
-                                       m_2DCanvas->GetDisplayArea().SetTop(m_2DCanvas->GetHeight());
+                                       area.SetLeft(0);
+                                       area.SetBottom(0);
+                                       area.SetRight(m_2DCanvas->GetWidth()/2);
+                                       area.SetTop(m_2DCanvas->GetHeight());
+                                       m_2DCanvas->SetDisplayArea(&area);
                                        break;
                                case RAS_STEREO_RIGHTEYE:
                                        // Right half of window
-                                       m_2DCanvas->GetDisplayArea().SetLeft(m_2DCanvas->GetWidth()/2);
-                                       m_2DCanvas->GetDisplayArea().SetBottom(0);
-                                       m_2DCanvas->GetDisplayArea().SetRight(m_2DCanvas->GetWidth());
-                                       m_2DCanvas->GetDisplayArea().SetTop(m_2DCanvas->GetHeight());
+                                       area.SetLeft(m_2DCanvas->GetWidth()/2);
+                                       area.SetBottom(0);
+                                       area.SetRight(m_2DCanvas->GetWidth());
+                                       area.SetTop(m_2DCanvas->GetHeight());
+                                       m_2DCanvas->SetDisplayArea(&area);
                                        break;
                        }
                        break;
                default:
                        // every available pixel
-                       m_2DCanvas->GetDisplayArea().SetLeft(0);
-                       m_2DCanvas->GetDisplayArea().SetBottom(0);
-                       m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
-                       m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight()));
+                       area.SetLeft(0);
+                       area.SetBottom(0);
+                       area.SetRight(int(m_2DCanvas->GetWidth()));
+                       area.SetTop(int(m_2DCanvas->GetHeight()));
+                       m_2DCanvas->SetDisplayArea(&area);
                        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)
-               return false;
-       else
+       if(m_stereomode > RAS_STEREO_NOSTEREO) // > 0
                return true;
+       else
+               return false;
 }
 
+bool RAS_OpenGLRasterizer::InterlacedStereo()
+{
+       return m_stereomode == RAS_STEREO_VINTERLACE || m_stereomode == RAS_STEREO_INTERLACED;
+}
 
 void RAS_OpenGLRasterizer::SetEye(const StereoEye eye)
 {
@@ -604,1180 +543,333 @@ 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;
 }
 
+const MT_Matrix4x4& RAS_OpenGLRasterizer::GetViewInvMatrix() const
+{
+       return m_viewinvmatrix;
+}
 
-
-void RAS_OpenGLRasterizer::IndexPrimitives(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 KX_ListSlot** slot
-                                                                       )
+                                                                       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();
-               
-               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:
-                       {
-                               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
+               numvert = it.array->m_type;
 
-}
+               if(it.array->m_type == RAS_DisplayArray::LINE) {
+                       // line drawing, no text
+                       glBegin(GL_LINES);
 
-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;
-
-       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:
+                       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();
-                       }
-                       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 */
+                               vertex = &it.vertex[it.index[i]];
+                               glVertex3fv(vertex->getXYZ());
 
-                                               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;
+                               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)
-                                       {
-                                               MT_Point3 mv1, mv2, mv3, fnor;
-                                               /* Calc a new face normal */
+                               float v[4][3];
+                               int glattrib, unit;
 
-                                               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 */
+                               for(j=0; j<numvert; j++) {
+                                       vertex = &it.vertex[it.index[i+j]];
 
-                                               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++;
-                                       }
+                                       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)
+{
+       m_texco_num = num;
+       if(m_texco_num > RAS_MAX_TEXCO)
+               m_texco_num = RAS_MAX_TEXCO;
+}
 
-
-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
-                                                                       )
-{ 
-       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();
-               
-               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:
-                       {
-                               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;
-                       }
-               case 0:
-                       {
-                               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:
-                       {
-                       }
-               }       //switch
-       }       //for each vertexarray
+void RAS_OpenGLRasterizer::SetAttribNum(int num)
+{
+       m_attrib_num = num;
+       if(m_attrib_num > RAS_MAX_ATTRIB)
+               m_attrib_num = RAS_MAX_ATTRIB;
 }
 
-void RAS_OpenGLRasterizer::SetTexCoords(TexCoGen coords,int unit)
+void RAS_OpenGLRasterizer::SetTexCoord(TexCoGen coords, int unit)
 {
        // this changes from material to material
-       if(unit < RAS_MAX)
+       if(unit < RAS_MAX_TEXCO)
                m_texco[unit] = coords;
 }
 
-void RAS_OpenGLRasterizer::SetAttrib(int type)
+void RAS_OpenGLRasterizer::SetAttrib(TexCoGen coords, int unit)
 {
-       if(type == RAS_TEXTANGENT) m_useTang=true;
+       // this changes from material to material
+       if(unit < RAS_MAX_ATTRIB)
+               m_attrib[unit] = coords;
 }
 
-void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv, int enabled)
+void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv)
 {
-#ifdef GL_ARB_multitexture
-       if(bgl::RAS_EXT_support._ARB_multitexture)
-       {
-               for(int unit=0; unit<enabled; unit++)
-               {
-                       if( tv.getFlag() & TV_2NDUV && tv.getUnit() == unit ) {
-                               bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
+       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_DISABLE:
-                       case RAS_TEXCO_OBJECT:
-                       case RAS_TEXCO_GEN:
-                               break;
+                       switch(m_texco[unit]) {
                        case RAS_TEXCO_ORCO:
                        case RAS_TEXCO_GLOB:
-                               bgl::blMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getLocalXYZ());
+                               glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getXYZ());
                                break;
                        case RAS_TEXCO_UV1:
-                               bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV1());
+                               glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV1());
                                break;
                        case RAS_TEXCO_NORM:
-                               bgl::blMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getNormal());
+                               glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getNormal());
                                break;
                        case RAS_TEXTANGENT:
-                               bgl::blMultiTexCoord4fvARB(GL_TEXTURE0_ARB+unit, tv.getTangent());
+                               glMultiTexCoord4fvARB(GL_TEXTURE0_ARB+unit, tv.getTangent());
                                break;
                        case RAS_TEXCO_UV2:
-                               bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
+                               glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
+                               break;
+                       default:
                                break;
                        }
                }
        }
-#endif
 
-#ifdef GL_ARB_vertex_program
-       if(m_useTang && bgl::RAS_EXT_support._ARB_vertex_program)
-               bgl::blVertexAttrib4fvARB(1/*tangent*/, tv.getTangent());
-#endif
+       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;
+                       }
+               }
+       }
 
 }
-void RAS_OpenGLRasterizer::Tangent(    const RAS_TexVert& v1,
-                                                                       const RAS_TexVert& v2,
-                                                                       const RAS_TexVert& v3,
-                                                                       const MT_Vector3 &no)
-{
-#ifdef GL_ARB_multitexture
-       // 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;
-#endif
-}
-
-
-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
-               )
-{ 
-#ifdef GL_ARB_multitexture
 
-       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::IndexPrimitives(RAS_MeshSlot& ms)
+{
+       IndexPrimitivesInternal(ms, false);
+}
 
-       for (vt=0;vt<vertexarrays.size();vt++)
-       {
-               vertexarray = &((*vertexarrays[vt]) [0]);
-               const KX_IndexArray & indexarray = (*indexarrays[vt]);
-               numindices = indexarray.size();
-               const unsigned int enabled = polymat->GetEnabled();
+void RAS_OpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
+{
+       IndexPrimitivesInternal(ms, true);
+}
 
-               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());
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               //
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               //
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               //
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               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])],enabled );
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               //
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               //
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               //
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               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());
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               //
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               //
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               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])],enabled );
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               //
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               //
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                       }
-                               }
-                               glEnd();        
-                               break;
-                       }
-               default:
-                       {
-                       }
-               } // switch
-       } // for each vertexarray
-#endif// GL_ARB_multitexture
+static bool current_wireframe;
+static RAS_MaterialBucket *current_bucket;
+static RAS_IPolyMaterial *current_polymat;
+static RAS_MeshSlot *current_ms;
+static RAS_MeshObject *current_mesh;
+static int current_blmat_nr;
+static GPUVertexAttribs current_gpu_attribs;
+static int CheckMaterialDM(int matnr, void *attribs)
+{
+       // only draw the current material
+       if (matnr != current_blmat_nr)
+               return 0;
+       GPUVertexAttribs *gattribs = (GPUVertexAttribs *)attribs;
+       if (gattribs)
+               memcpy(gattribs, &current_gpu_attribs, sizeof(GPUVertexAttribs));
+       return 1;
+}
+static int CheckTexfaceDM(void *mcol, int index)
+{
 
+       // index is the original face index, retrieve the polygon
+       RAS_Polygon* polygon = (index >= 0 && index < current_mesh->NumPolygons()) ?
+               current_mesh->GetPolygon(index) : NULL;
+       if (polygon && polygon->GetMaterial() == current_bucket) {
+               // must handle color.
+               if (current_wireframe)
+                       return 2;
+               if (current_ms->m_bObjectColor) {
+                       MT_Vector4& rgba = current_ms->m_RGBAcolor;
+                       glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
+                       // don't use mcol
+                       return 2;
+               }
+               if (!mcol) {
+                       // we have to set the color from the material
+                       unsigned char rgba[4];
+                       current_polymat->GetMaterialRGBAColor(rgba);
+                       glColor4ubv((const GLubyte *)rgba);
+                       return 2;
+               }
+               return 1;
+       }
+       return 0;
 }
 
-void RAS_OpenGLRasterizer::IndexPrimitivesMulti_Ex(
-                                                                       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)
 { 
-#ifdef GL_ARB_multitexture
-       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;
+       bool obcolor = ms.m_bObjectColor;
+       bool wireframe = m_drawingmode <= KX_WIREFRAME;
+       MT_Vector4& rgba = ms.m_RGBAcolor;
+       RAS_MeshSlot::iterator it;
+
+       if (ms.m_pDerivedMesh) {
+               // mesh data is in derived mesh, 
+               current_bucket = ms.m_bucket;
+               current_polymat = current_bucket->GetPolyMaterial();
+               current_ms = &ms;
+               current_mesh = ms.m_mesh;
+               current_wireframe = wireframe;
+               MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL);
+               if (current_polymat->GetFlag() & RAS_BLENDERGLSL) {
+                       // GetMaterialIndex return the original mface material index, 
+                       // increment by 1 to match what derived mesh is doing
+                       current_blmat_nr = current_polymat->GetMaterialIndex()+1;
+                       // For GLSL we need to retrieve the GPU material attribute
+                       Material* blmat = current_polymat->GetBlenderMaterial();
+                       Scene* blscene = current_polymat->GetBlenderScene();
+                       if (!wireframe && blscene && blmat)
+                               GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), &current_gpu_attribs);
+                       else
+                               memset(&current_gpu_attribs, 0, sizeof(current_gpu_attribs));
+                       // DM draw can mess up blending mode, restore at the end
+                       int current_blend_mode = GPU_get_material_blend_mode();
+                       ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM);
+                       GPU_set_material_blend_mode(current_blend_mode);
+               } else {
+                       ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol);
+               }
+               return;
        }
-       
-       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();
-               const unsigned int enabled = polymat->GetEnabled();
+       // 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)
-                       continue;
-               
-               int vindex=0;
-               switch (mode)
-               {
-               case 1:
+               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)
                        {
-                               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)
-                                       {
-                                               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+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());
-                                       
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                       
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());                                             
-                                       
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               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());
-                                       
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                       
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                       
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               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)
-                                       {
-                                               MT_Point3 mv1, mv2, mv3, fnor;
-                                               /* Calc a new face normal */
+                               if(obcolor)
+                                       glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
 
-                                               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());
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               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 */
+                               for(j=0; j<numvert; j++) {
+                                       vertex = &it.vertex[it.index[i+j]];
+
+                                       if(!wireframe) {
+                                               if(!obcolor)
+                                                       glColor4ubv((const GLubyte *)(vertex->getRGBA()));
 
-                                               if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
-                                                       recalc= true;
+                                               glNormal3fv(vertex->getNormal());
+
+                                               if(multi)
+                                                       TexCoord(*vertex);
                                                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());
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
-                                               
-                                               glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
-                                               if (!recalc)
-                                                       glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
-                                               TexCoord(vertexarray[(indexarray[vindex])],enabled );
-                                               glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
-                                               vindex++;
+                                                       glTexCoord2fv(vertex->getUV1());
                                        }
+
+                                       glVertex3fv(vertex->getXYZ());
                                }
-                               glEnd();        
-                               break;
                        }
-               default:
-                       {
-                       }
-                       
-               } // switch
-       } // for each vertexarray
-#endif
-}
-
 
+                       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)
 {
@@ -1787,6 +879,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(
@@ -1796,20 +890,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
                        if (!m_setfocallength)
-                               m_focallength = 1.5 * right;  // derived from example
+                               m_focallength = (focallength == 0.f) ? 1.5 * right  // derived from example
+                                       : focallength; 
                        if (!m_seteyesep)
-                               m_eyeseparation = 0.18 * right;  // just a guess...
+                               m_eyeseparation = m_focallength/30;  // reasonable value...
 
                        near_div_focallength = frustnear / m_focallength;
                        switch(m_curreye)
@@ -1836,17 +932,40 @@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
        return result;
 }
 
+MT_Matrix4x4 RAS_OpenGLRasterizer::GetOrthoMatrix(
+       float left,
+       float right,
+       float bottom,
+       float top,
+       float frustnear,
+       float frustfar
+){
+       MT_Matrix4x4 result;
+       double mat[16];
+
+       // stereo is meaning less for orthographic, disable it
+       glMatrixMode(GL_PROJECTION);
+       glLoadIdentity();
+       glOrtho(left, right, bottom, top, frustnear, frustfar);
+               
+       glGetDoublev(GL_PROJECTION_MATRIX, mat);
+       result.setValue(mat);
+
+       return result;
+}
+
 
 // next arguments probably contain redundant info, for later...
-void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, const MT_Vector3& campos,
-               const MT_Point3 &, const MT_Quaternion &camOrientQuat)
+void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, 
+                                                                                const MT_Matrix3x3 & camOrientMat3x3,
+                                                                                const MT_Point3 & pos,
+                                                                                bool perspective)
 {
-       MT_Matrix4x4 viewMat = mat;
+       m_viewmatrix = mat;
 
        // correction for stereo
-       if(m_stereomode != RAS_STEREO_NOSTEREO)
+       if(Stereo() && perspective)
        {
-               MT_Matrix3x3 camOrientMat3x3(camOrientQuat);
                MT_Vector3 unitViewDir(0.0, -1.0, 0.0);  // minus y direction, Blender convention
                MT_Vector3 unitViewupVec(0.0, 0.0, 1.0);
                MT_Vector3 viewDir, viewupVec;
@@ -1868,7 +987,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:
@@ -1877,21 +996,22 @@ 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));
-       m_campos = campos;
+       glLoadMatrixd(glviewmat);
+       m_campos = pos;
 }
 
 
@@ -1900,21 +1020,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)
@@ -1979,3 +1089,65 @@ void RAS_OpenGLRasterizer::SetPolygonOffset(float mult, float add)
        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)
+{
+       GPU_set_material_blend_mode(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;
+}
+