From 8112d53e4f00f8c536be2cef033ff56bea9efbea Mon Sep 17 00:00:00 2001
From: Matt Kielan <devsh.graphicsprogramming@gmail.com>
Date: Thu, 7 Sep 2017 12:39:42 +0100
Subject: [PATCH] version 0.2.5

---
 examples_tests/12.Splines/main.cpp            |   15 +-
 include/COpenGLStateManager.h                 |  825 ++++++++
 include/COpenGLStateManagerImpl.h             |  256 +++
 include/EDeviceTypes.h                        |    4 -
 include/IDummyTransformationSceneNode.h       |  440 ++--
 include/ISceneNode.h                          |  351 +--
 include/IrrCompileConfig.h                    |   44 -
 include/SAABoxCollider.h                      |    4 +-
 include/SCompoundCollider.h                   |    4 +-
 include/SEllipsoidCollider.h                  |    4 +-
 include/STriangleMeshCollider.h               |    7 +-
 include/irrList.h                             |  416 ----
 include/irrMap.h                              | 1109 ----------
 include/quaternion.h                          |    3 +-
 include/splines.h                             | 1878 +++++++++--------
 include/vectorSIMD.h                          |    8 +-
 source/Irrlicht/CCameraSceneNode.cpp          |    2 +-
 source/Irrlicht/CFileSystem.cpp               |   43 +-
 source/Irrlicht/CIrrDeviceLinux.cpp           |   15 -
 source/Irrlicht/CIrrDeviceSDL.cpp             |    2 +-
 source/Irrlicht/CIrrDeviceWin32.cpp           |   10 +-
 source/Irrlicht/CIrrDeviceWinCE.cpp           |  868 --------
 source/Irrlicht/CIrrDeviceWinCE.h             |  296 ---
 source/Irrlicht/CMeshManipulator.cpp          |    1 -
 source/Irrlicht/CNullDriver.h                 |    1 -
 source/Irrlicht/COBJMeshFileLoader.cpp        |    8 +-
 source/Irrlicht/COBJMeshFileLoader.h          |   34 +-
 source/Irrlicht/COpenGLDriver.cpp             |  125 +-
 source/Irrlicht/COpenGLExtensionHandler.cpp   |  128 +-
 source/Irrlicht/COpenGLExtensionHandler.h     |  608 +++---
 source/Irrlicht/COpenGLSLMaterialRenderer.cpp |   52 +-
 source/Irrlicht/CSceneManager.cpp             |  287 +--
 source/Irrlicht/Irrlicht-gcc.cbp              |    4 +
 source/Irrlicht/Irrlicht.cpp                  |    9 -
 source/Irrlicht/Irrlicht10.0.vcxproj          |    2 -
 source/Irrlicht/Irrlicht10.0.vcxproj.filters  |    6 -
 36 files changed, 3166 insertions(+), 4703 deletions(-)
 create mode 100644 include/COpenGLStateManager.h
 create mode 100644 include/COpenGLStateManagerImpl.h
 delete mode 100644 include/irrList.h
 delete mode 100644 include/irrMap.h
 delete mode 100644 source/Irrlicht/CIrrDeviceWinCE.cpp
 delete mode 100644 source/Irrlicht/CIrrDeviceWinCE.h

diff --git a/examples_tests/12.Splines/main.cpp b/examples_tests/12.Splines/main.cpp
index 92efaecfc..68aa9909d 100644
--- a/examples_tests/12.Splines/main.cpp
+++ b/examples_tests/12.Splines/main.cpp
@@ -58,7 +58,7 @@ class MyEventReceiver : public IEventReceiver
                         spline = NULL;
                         if (controlPts.size())
                         {
-                            spline = new CQuadraticSpline(controlPts.pointer(),controlPts.size(),false);
+                            spline = new irr::core::CQuadraticBSpline(controlPts.pointer(),controlPts.size(),false);
                             printf("Total Len %f\n",spline->getSplineLength());
                             for (size_t i=0; i<spline->getSegmentCount(); i++)
                                 printf("Seg: %d \t\t %f\n",i,spline->getSegmentLength(i));
@@ -74,7 +74,7 @@ class MyEventReceiver : public IEventReceiver
                         spline = NULL;
                         if (controlPts.size())
                         {
-                            spline = new CQuadraticSpline(controlPts.pointer(),controlPts.size(),false,true); //make it be ready for first turn
+                            spline = new CQuadraticBSpline(controlPts.pointer(),controlPts.size(),true); //make it a loop
                             printf("Total Len %f\n",spline->getSplineLength());
                             for (size_t i=0; i<spline->getSegmentCount(); i++)
                                 printf("Seg: %d \t\t %f\n",i,spline->getSegmentLength(i));
@@ -84,17 +84,6 @@ class MyEventReceiver : public IEventReceiver
                     }
                 case KEY_KEY_O:
                     {
-                        if (spline)
-                            delete spline;
-                        spline = NULL;
-                        if (controlPts.size())
-                        {
-                            spline = new CQuadraticSpline(controlPts.pointer(),controlPts.size(),true); //make it loop
-                            printf("Total Len %f\n",spline->getSplineLength());
-                            for (size_t i=0; i<spline->getSegmentCount(); i++)
-                                printf("Seg: %d \t\t %f\n",i,spline->getSegmentLength(i));
-                        }
-
                         return true;
                     }
                     break;
diff --git a/include/COpenGLStateManager.h b/include/COpenGLStateManager.h
new file mode 100644
index 000000000..a76b8a591
--- /dev/null
+++ b/include/COpenGLStateManager.h
@@ -0,0 +1,825 @@
+// Copyright (C) 2017- Mateusz Kielan
+// This file is part of the "IrrlichtBAW".
+
+#ifndef __C_OPENGL_STATE_MANAGER_H_INCLUDED__
+#define __C_OPENGL_STATE_MANAGER_H_INCLUDED__
+
+#include <limits>       // std::numeric_limits
+
+#if defined(_IRR_WINDOWS_API_)
+	// include windows headers for HWND
+	#define WIN32_LEAN_AND_MEAN
+	#include <windows.h>
+	#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
+		#define GL_GLEXT_LEGACY 1
+	#endif
+	#include <GL/gl.h>
+	#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
+		#include "../Irrlicht/glext.h"
+	#endif
+	#include "wglext.h"
+
+	#ifdef _MSC_VER
+		#pragma comment(lib, "OpenGL32.lib")
+//		#pragma comment(lib, "OpenCL.lib")
+	#endif
+
+#elif defined(_IRR_COMPILE_WITH_OSX_DEVICE_)
+	#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
+		#define GL_GLEXT_LEGACY 1
+	#endif
+	#include <OpenGL/gl.h>
+	#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
+		#include "../Irrlicht/glext.h"
+	#endif
+#elif defined(_IRR_COMPILE_WITH_SDL_DEVICE_) && !defined(_IRR_COMPILE_WITH_X11_DEVICE_)
+	#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
+		#define GL_GLEXT_LEGACY 1
+		#define GLX_GLXEXT_LEGACY 1
+	#else
+		#define GL_GLEXT_PROTOTYPES 1
+		#define GLX_GLXEXT_PROTOTYPES 1
+	#endif
+	#define NO_SDL_GLEXT
+	#include <SDL/SDL_video.h>
+	#include <SDL/SDL_opengl.h>
+	#include "../source/Irrlicht/glext.h"
+#else
+	#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
+		#define GL_GLEXT_LEGACY 1
+		#define GLX_GLXEXT_LEGACY 1
+	#else
+		#define GL_GLEXT_PROTOTYPES 1
+		#define GLX_GLXEXT_PROTOTYPES 1
+	#endif
+	#include <GL/gl.h>
+	#include <GL/glx.h>
+	#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
+        #include "../source/Irrlicht/glext.h"
+	#endif
+#endif
+
+namespace irr
+{
+namespace video
+{
+
+    //! To be updated later as time moves on
+	const uint32_t OGL_MAX_ENDISABLE_FLAGS = 36;
+	const uint32_t OGL_MAX_ENDISABLEI_FLAGS = 2;
+
+	const uint32_t OGL_STATE_MAX_VIEWPORTS = 16;
+	const uint32_t OGL_STATE_MAX_DRAW_BUFFERS = 16;
+
+	const uint8_t OGL_MAX_ENDISABLEI_INDICES = 16;//std::max(OGL_STATE_MAX_VIEWPORTS,OGL_STATE_MAX_DRAW_BUFFERS);
+	const uint32_t OGL_STATE_MAX_TEXTURES = 192;
+	//!
+
+            enum E_GL_HINT_BIT
+            {
+                EGHB_FRAGMENT_SHADER_DERIVATIVE_HINT=0,
+                EGHB_LINE_SMOOTH_HINT,
+                EGHB_POLYGON_SMOOTH_HINT,
+                EGHB_TEXTURE_COMPRESSION_HINT,
+                EGHB_COUNT
+            };
+            enum E_GL_ENABLE_BIT
+            {
+                EGEB_DITHER=0,
+                EGEB_FRAMEBUFFER_SRGB,
+                EGEB_TEXTURE_CUBE_MAP_SEAMLESS,
+                ///====>ALWAYS FORCE TO FALSE<====
+                EGEB_POLYGON_OFFSET_FILL,
+                EGEB_POLYGON_OFFSET_LINE,
+                EGEB_POLYGON_OFFSET_POINT,
+                ///====>ALWAYS FORCE TO FALSE<====
+                EGEB_POLYGON_SMOOTH,
+                EGEB_LINE_SMOOTH,
+                EGEB_POINT_SMOOTH,
+                EGEB_MULTISAMPLE,/*
+                EGEB_,
+                EGEB_,
+                EGEB_,
+                EGEB_,
+                EGEB_,*/
+                EGEB_DEPTH_CLAMP,
+                //EGEB_,
+                EGEB_CLIP_DISTANCE0,
+                EGEB_CLIP_DISTANCE1,
+                EGEB_CLIP_DISTANCE2,
+                EGEB_CLIP_DISTANCE3,
+                EGEB_CLIP_DISTANCE4,
+                EGEB_CLIP_DISTANCE5,
+                EGEB_CLIP_DISTANCE6,
+                EGEB_CLIP_DISTANCE7,/*
+                EGEB_,
+                EGEB_,
+                EGEB_,
+                EGEB_,
+                EGEB_,
+                EGEB_,
+                EGEB_,
+                EGEB_,*/
+                EGEB_RASTERIZER_DISCARD,
+                EGEB_COUNT
+            };
+
+            enum E_GL_ENABLE_INDEX_BIT
+            {
+                EGEIB_BLEND=0,
+                EGEIB_SCISSOR_TEST,
+                EGEIB_COUNT
+            };
+
+
+	class COpenGLStateDiff
+	{
+        public:
+            COpenGLStateDiff() : hintsToSet(0), glProvokingVertex_val(GL_INVALID_ENUM), glEnableCount(0), glDisableCount(0), glDisableiCount(0), glEnableiCount(0),
+                                changeGlProgram(false), changeGlProgramPipeline(false), resetPolygonOffset(false),
+                            setDepthRange(0), setViewportArray(0), setScissorBox(0),
+                        glLogicOp_val(GL_INVALID_ENUM), setBlendColor(false), setBlendEquation(0), setBlendFunc(0),
+                    texturesToBind(0), samplersToBind(0)
+            {
+                glPrimitiveSize[0] = std::numeric_limits<float>::quiet_NaN();
+                glPrimitiveSize[1] = std::numeric_limits<float>::quiet_NaN();
+            }
+
+
+            uint8_t hintsToSet;
+            GLenum glHint_pair[EGHB_COUNT][2];
+
+            GLenum glProvokingVertex_val;
+
+            //!
+            GLenum glDisables[OGL_MAX_ENDISABLE_FLAGS];
+            GLenum glEnables[OGL_MAX_ENDISABLE_FLAGS];
+
+            //! these are sorted!
+            struct EnDisAbleIndexedStatus
+            {
+                EnDisAbleIndexedStatus()
+                {
+                    flag = GL_INVALID_ENUM;
+                    indices = 0;
+                }
+
+                GLenum flag;
+                uint8_t indices;
+            };
+            EnDisAbleIndexedStatus glDisableis[OGL_MAX_ENDISABLEI_FLAGS];
+            EnDisAbleIndexedStatus glEnableis[OGL_MAX_ENDISABLEI_FLAGS];
+
+            uint8_t glDisableCount;
+            uint8_t glEnableCount;
+
+            uint8_t glDisableiCount;
+            uint8_t glEnableiCount;
+
+            class IndexedObjectToBind
+            {
+                public:
+                    IndexedObjectToBind() : index(0xdeadbeefu), obj(0)
+                    {
+                    }
+                    IndexedObjectToBind(const uint32_t& ix, const GLuint& object) : index(ix), obj(object)
+                    {
+                    }
+
+                    uint32_t index;
+                    GLuint obj;
+            };
+
+            bool resetPolygonOffset;
+            float glPolygonOffset_factor,glPolygonOffset_units;
+            float glPrimitiveSize[2]; //glPointSize, glLineWidth
+
+
+            bool changeGlProgram,changeGlProgramPipeline;
+            GLuint glUseProgram_val,glBindProgramPipeline_val;
+
+            uint8_t setDepthRange;
+            uint8_t setViewportArray;
+            uint8_t setScissorBox;
+            float glDepthRangeArray_vals[OGL_STATE_MAX_VIEWPORTS][2];
+            GLint glViewportArray_vals[OGL_STATE_MAX_VIEWPORTS][4];
+            GLint glScissorArray_vals[OGL_STATE_MAX_VIEWPORTS][4];
+
+            GLenum glLogicOp_val;
+
+            bool setBlendColor;
+            uint8_t setBlendEquation;
+            uint8_t setBlendFunc;
+            float glBlendColor_vals[4];
+            GLenum glBlendEquationSeparatei_vals[OGL_STATE_MAX_DRAW_BUFFERS][2];
+            GLenum glBlendFuncSeparatei_vals[OGL_STATE_MAX_DRAW_BUFFERS][4];
+
+            class TextureToBind : public IndexedObjectToBind
+            {
+                public:
+                    TextureToBind() : IndexedObjectToBind(), target(GL_INVALID_ENUM)
+                    {
+                    }
+                    TextureToBind(const uint32_t& ix, const GLuint& object, const GLenum& tgt) : IndexedObjectToBind(ix,object), target(tgt)
+                    {
+                    }
+
+                    GLenum target;
+            };
+            uint32_t texturesToBind;
+            uint32_t samplersToBind;
+            TextureToBind bindTextures[OGL_STATE_MAX_TEXTURES];
+            IndexedObjectToBind bindSamplers[OGL_STATE_MAX_TEXTURES];
+        private:
+	};
+
+
+	class COpenGLState
+	{
+        public:
+            inline GLenum glEnableBitToGLenum(const uint64_t &bit) const
+            {
+                switch (bit)
+                {
+                    case EGEB_DITHER:
+                        return GL_DITHER;
+                        break;
+                    case EGEB_FRAMEBUFFER_SRGB:
+                        return GL_FRAMEBUFFER_SRGB;
+                        break;
+                    case EGEB_TEXTURE_CUBE_MAP_SEAMLESS:
+                        return GL_TEXTURE_CUBE_MAP_SEAMLESS;
+                        break;
+                    case EGEB_POLYGON_OFFSET_FILL:
+                        return GL_POLYGON_OFFSET_FILL;
+                        break;
+                    case EGEB_POLYGON_OFFSET_LINE:
+                        return GL_POLYGON_OFFSET_LINE;
+                        break;
+                    case EGEB_POLYGON_OFFSET_POINT:
+                        return GL_POLYGON_OFFSET_POINT;
+                        break;
+                    case EGEB_POLYGON_SMOOTH:
+                        return GL_POLYGON_SMOOTH;
+                        break;
+                    case EGEB_LINE_SMOOTH:
+                        return GL_LINE_SMOOTH;
+                        break;
+                    case EGEB_POINT_SMOOTH:
+                        return GL_POINT_SMOOTH;
+                        break;
+                    case EGEB_MULTISAMPLE:
+                        return GL_MULTISAMPLE;
+                        break;/*
+                    case EGEB_:
+                        return GL_;
+                        break;*/
+                    case EGEB_DEPTH_CLAMP:
+                        return GL_DEPTH_CLAMP;
+                        break;/*
+                    case EGEB_:
+                        return GL_;
+                        break;*/
+                    case EGEB_CLIP_DISTANCE0:
+                        return GL_CLIP_DISTANCE0;
+                        break;
+                    case EGEB_CLIP_DISTANCE1:
+                        return GL_CLIP_DISTANCE1;
+                        break;
+                    case EGEB_CLIP_DISTANCE2:
+                        return GL_CLIP_DISTANCE2;
+                        break;
+                    case EGEB_CLIP_DISTANCE3:
+                        return GL_CLIP_DISTANCE3;
+                        break;
+                    case EGEB_CLIP_DISTANCE4:
+                        return GL_CLIP_DISTANCE4;
+                        break;
+                    case EGEB_CLIP_DISTANCE5:
+                        return GL_CLIP_DISTANCE5;
+                        break;
+                    case EGEB_CLIP_DISTANCE6:
+                        return GL_CLIP_DISTANCE6;
+                        break;
+                    case EGEB_CLIP_DISTANCE7:
+                        return GL_CLIP_DISTANCE7;
+                        break;
+                    case EGEB_RASTERIZER_DISCARD:
+                        return GL_RASTERIZER_DISCARD;
+                        break;
+                    default:
+                        return GL_INVALID_ENUM;
+                        break;
+                }
+            }
+
+            inline GLenum glEnableiBitToGLenum(uint8_t& indexedBitOut, const uint64_t &bit) const
+            {
+                uint64_t ix = bit%OGL_MAX_ENDISABLEI_INDICES;
+                indexedBitOut = 0x1u<<ix;
+                switch (bit/OGL_MAX_ENDISABLEI_INDICES)
+                {
+                    case EGEIB_BLEND:
+                        return GL_BLEND;
+                        break;
+                    case EGEIB_SCISSOR_TEST:
+                        return GL_SCISSOR_TEST;
+                        break;
+                    default:
+                        return GL_INVALID_ENUM;
+                        break;
+                }
+            }
+
+            //default OGL state at start of context as per the spec
+            COpenGLState(const uint32_t& windowSizeX=0, const uint32_t& windowSizeY=0)
+            {
+                for (size_t i=0; i<EGHB_COUNT; i++)
+                    glHint_vals[i] = GL_DONT_CARE;
+
+                glProvokingVertex_val = GL_LAST_VERTEX_CONVENTION;
+
+                size_t glEnableBitfieldByteSize = (EGEB_COUNT+63)/64;
+                memset(glEnableBitfield,0,glEnableBitfieldByteSize);
+                setGlEnableBit(EGEB_DITHER,true);
+                setGlEnableBit(EGEB_MULTISAMPLE,true);
+
+                size_t glEnableiBitfieldByteSize = (EGEIB_COUNT*OGL_MAX_ENDISABLEI_INDICES+63)/64;
+                memset(glEnableiBitfield,0,glEnableiBitfieldByteSize);
+
+                glPolygonOffset_factor = 0.f;
+                glPolygonOffset_units = 0.f;
+
+
+                glUseProgram_val = 0;
+                glBindProgramPipeline_val = 0;
+
+
+                glPrimitiveSize[0] = 1.f;
+                glPrimitiveSize[1] = 1.f;
+
+                for (uint32_t i=0; i<OGL_STATE_MAX_VIEWPORTS; i++)
+                {
+                    glDepthRangeArray_vals[i][0] = 0.f;
+                    glDepthRangeArray_vals[i][1] = 1.f;
+
+                    glViewportArray_vals[i][0] = 0;
+                    glViewportArray_vals[i][1] = 0;
+                    glViewportArray_vals[i][2] = windowSizeX;
+                    glViewportArray_vals[i][3] = windowSizeY;
+
+                    glScissorArray_vals[i][0] = 0;
+                    glScissorArray_vals[i][1] = 0;
+                    glScissorArray_vals[i][2] = windowSizeX;
+                    glScissorArray_vals[i][3] = windowSizeY;
+                }
+
+                glLogicOp_val = GL_COPY;
+
+                memset(glBlendColor_vals,0,4*sizeof(float));
+
+                for (uint32_t i=0; i<OGL_STATE_MAX_DRAW_BUFFERS; i++)
+                {
+                    glBlendEquationSeparatei_vals[i][0] = GL_FUNC_ADD;
+                    glBlendEquationSeparatei_vals[i][1] = GL_FUNC_ADD;
+
+                    glBlendFuncSeparatei_vals[i][0] = GL_ONE;
+                    glBlendFuncSeparatei_vals[i][1] = GL_ZERO;
+                    glBlendFuncSeparatei_vals[i][2] = GL_ONE;
+                    glBlendFuncSeparatei_vals[i][3] = GL_ZERO;
+                }
+
+                for (size_t i=0; i<OGL_STATE_MAX_TEXTURES; i++)
+                    boundTextureTargets[i] = GL_INVALID_ENUM;
+                memset(boundTextures,0,sizeof(GLuint)*OGL_STATE_MAX_TEXTURES);
+                memset(boundSamplers,0,sizeof(GLuint)*OGL_STATE_MAX_TEXTURES);
+            }
+
+            //! THIS IS SLOW AND FOR DEBUG ONLY!
+            inline static COpenGLState collectGLState()
+            {
+                COpenGLState retval;
+
+                //
+
+                return retval;
+            }
+
+            inline void correctTheState()
+            {
+                setGlEnableBit(EGEB_POLYGON_OFFSET_POINT,false);
+                setGlEnableBit(EGEB_POLYGON_OFFSET_LINE,false);
+                setGlEnableBit(EGEB_POLYGON_OFFSET_FILL,false);
+
+                setGlEnableBit(EGEB_POLYGON_SMOOTH,false);
+
+
+                glPolygonOffset_factor = 0.f;
+                glPolygonOffset_units = 0.f;
+
+                //glPrimitiveSize[0] = 1.f;
+                //glPrimitiveSize[1] = 1.f;
+            }
+
+            inline COpenGLStateDiff getStateDiff(const COpenGLState &previousState,
+                                              const bool& careAboutHints=true, //should be default false
+                                              const bool& careAboutPolygonOffset=true, //should be default false
+                                              const bool& careAboutFBOs=true,
+                                              const bool& careAboutProgram=true,
+                                              const bool& careAboutPipeline=true,
+                                              const bool& careAboutViewports=true,
+                                              const bool& careAboutPointSize=true,
+                                              const bool& careAboutLineWidth=true,
+                                              const bool& careAboutLogicOp=true,
+                                              const bool& careAboutBlending=true,
+                                              const bool& careAboutTextures=true) const
+            {
+                COpenGLStateDiff diff;
+
+                if (careAboutHints)
+                {
+                    for (uint64_t i=0; i<EGHB_COUNT; i++)
+                    {
+                        if (glHint_vals[i]!=previousState.glHint_vals[i])
+                        {
+                            switch (i)
+                            {
+                                case EGHB_FRAGMENT_SHADER_DERIVATIVE_HINT:
+                                    diff.glHint_pair[i][0] = GL_FRAGMENT_SHADER_DERIVATIVE_HINT;
+                                    break;
+                                case EGHB_LINE_SMOOTH_HINT:
+                                    diff.glHint_pair[i][0] = GL_LINE_SMOOTH_HINT;
+                                    break;
+                                case EGHB_POLYGON_SMOOTH_HINT:
+                                    diff.glHint_pair[i][0] = GL_POLYGON_SMOOTH_HINT;
+                                    break;
+                                case EGHB_TEXTURE_COMPRESSION_HINT:
+                                    diff.glHint_pair[i][0] = GL_TEXTURE_COMPRESSION_HINT;
+                                    break;
+                                default:
+                                    diff.glHint_pair[i][0] = GL_INVALID_ENUM;
+                                    break;
+                            }
+                            diff.glHint_pair[i][1] = glHint_vals[i];
+                            diff.hintsToSet++;
+                        }
+                    }
+                }
+
+                if (glProvokingVertex_val!=previousState.glProvokingVertex_val)
+                    diff.glProvokingVertex_val = glProvokingVertex_val;
+
+
+                {
+                    for (uint64_t i=0; i<EGEB_COUNT/64u; i++)
+                    {
+                        uint64_t bitdiff = glEnableBitfield[i]^previousState.glEnableBitfield[i];
+
+                        for (uint64_t j=0; j<64u; j++)
+                            setEnableDiffBits(diff,bitdiff,i,j);
+                    }
+                    uint64_t leftOvers = EGEB_COUNT%64u;
+                    if (leftOvers)
+                    {
+                        uint64_t bitdiff = glEnableBitfield[EGEB_COUNT/64u]^previousState.glEnableBitfield[EGEB_COUNT/64u];
+                        for (uint64_t j=0; j<leftOvers; j++)
+                            setEnableDiffBits(diff,bitdiff,EGEB_COUNT/64u,j);
+                    }
+                }
+                {
+                    for (uint64_t i=0; i<(EGEIB_COUNT*OGL_MAX_ENDISABLEI_INDICES)/64u; i++)
+                    {
+                        uint64_t bitdiff = glEnableiBitfield[i]^previousState.glEnableiBitfield[i];
+
+                        for (uint64_t j=0; j<64u; j++)
+                            setEnableiDiffBits(diff,bitdiff,i,j);
+                    }
+                    uint64_t leftOvers = (EGEIB_COUNT*OGL_MAX_ENDISABLEI_INDICES)%64u;
+                    if (leftOvers)
+                    {
+                        uint64_t i = (EGEIB_COUNT*OGL_MAX_ENDISABLEI_INDICES)/64u;
+                        uint64_t bitdiff = glEnableiBitfield[i]^previousState.glEnableiBitfield[i];
+                        for (uint64_t j=0; j<leftOvers; j++)
+                            setEnableiDiffBits(diff,bitdiff,i,j);
+                    }
+                }
+
+
+                if (careAboutPolygonOffset&&(glPolygonOffset_factor!=previousState.glPolygonOffset_factor||glPolygonOffset_units!=previousState.glPolygonOffset_units))
+                {
+                    diff.resetPolygonOffset = false;
+                    diff.glPolygonOffset_factor = glPolygonOffset_factor;
+                    diff.glPolygonOffset_units = glPolygonOffset_units;
+                }
+
+
+                if (careAboutProgram&&glUseProgram_val!=previousState.glUseProgram_val)
+                {
+                    diff.changeGlProgram = true;
+                    diff.glUseProgram_val = glUseProgram_val;
+                }
+                if (careAboutPipeline&&glBindProgramPipeline_val!=previousState.glBindProgramPipeline_val)
+                {
+                    diff.changeGlProgramPipeline = true;
+                    diff.glBindProgramPipeline_val = glBindProgramPipeline_val;
+                }
+
+
+                if (careAboutFBOs)
+                {
+                    //;
+                }
+
+                if (careAboutViewports)
+                {
+                    size_t j=0;
+                    for (uint32_t i=0; i<OGL_STATE_MAX_VIEWPORTS; i++)
+                    {
+                        if (glDepthRangeArray_vals[i][0]!=previousState.glDepthRangeArray_vals[i][0]||
+                            glDepthRangeArray_vals[i][1]!=previousState.glDepthRangeArray_vals[i][1])
+                        {
+                            diff.setDepthRange |= 0x1u<<i;
+                            memcpy(diff.glDepthRangeArray_vals[j],glDepthRangeArray_vals[i],4*sizeof(float));
+                            j++;
+                        }
+                    }
+                    j=0;
+                    for (uint32_t i=0; i<OGL_STATE_MAX_VIEWPORTS; i++)
+                    {
+                        if (glViewportArray_vals[i][0]!=previousState.glViewportArray_vals[i][0]||
+                            glViewportArray_vals[i][1]!=previousState.glViewportArray_vals[i][1]||
+                            glViewportArray_vals[i][2]!=previousState.glViewportArray_vals[i][2]||
+                            glViewportArray_vals[i][3]!=previousState.glViewportArray_vals[i][3])
+                        {
+                            diff.setViewportArray |= 0x1u<<i;
+                            memcpy(diff.glViewportArray_vals[j],glViewportArray_vals[i],4*sizeof(float));
+                            j++;
+                        }
+                    }
+                    j=0;
+                    for (uint32_t i=0; i<OGL_STATE_MAX_VIEWPORTS; i++)
+                    {
+                        if (glScissorArray_vals[i][0]!=previousState.glScissorArray_vals[i][0]||
+                            glScissorArray_vals[i][1]!=previousState.glScissorArray_vals[i][1]||
+                            glScissorArray_vals[i][2]!=previousState.glScissorArray_vals[i][2]||
+                            glScissorArray_vals[i][3]!=previousState.glScissorArray_vals[i][3])
+                        {
+                            diff.setScissorBox |= 0x1u<<i;
+                            memcpy(diff.glScissorArray_vals[j],glScissorArray_vals[i],4*sizeof(float));
+                            j++;
+                        }
+                    }
+                }
+
+                if (careAboutPointSize&&glPrimitiveSize[0]!=previousState.glPrimitiveSize[0])
+                    diff.glPrimitiveSize[0] = glPrimitiveSize[0];
+                if (careAboutLineWidth&&glPrimitiveSize[1]!=previousState.glPrimitiveSize[1])
+                    diff.glPrimitiveSize[1] = glPrimitiveSize[1];
+
+
+                if (careAboutLogicOp&&glLogicOp_val!=previousState.glLogicOp_val)
+                    diff.glLogicOp_val = glLogicOp_val;
+
+
+                if (careAboutBlending)
+                {
+                    if (glBlendColor_vals[0]!=previousState.glBlendColor_vals[0]||
+                        glBlendColor_vals[1]!=previousState.glBlendColor_vals[1]||
+                        glBlendColor_vals[2]!=previousState.glBlendColor_vals[2]||
+                        glBlendColor_vals[3]!=previousState.glBlendColor_vals[3])
+                    {
+                        diff.setBlendColor = true;
+                        memcpy(diff.glBlendColor_vals,glBlendColor_vals,4*sizeof(float));
+                    }
+                    size_t j=0;
+                    for (uint32_t i=0; i<OGL_STATE_MAX_DRAW_BUFFERS; i++)
+                    {
+                        if (glBlendEquationSeparatei_vals[i][0]!=previousState.glBlendEquationSeparatei_vals[i][0]||
+                            glBlendEquationSeparatei_vals[i][1]!=previousState.glBlendEquationSeparatei_vals[i][1])
+                        {
+                            diff.glBlendEquationSeparatei_vals[j][0] = glBlendEquationSeparatei_vals[i][0];
+                            diff.glBlendEquationSeparatei_vals[j][1] = glBlendEquationSeparatei_vals[i][1];
+                            j++;
+                        }
+                    }
+                    j=0;
+                    for (uint32_t i=0; i<OGL_STATE_MAX_DRAW_BUFFERS; i++)
+                    {
+                        if (glBlendFuncSeparatei_vals[i][0]!=previousState.glBlendFuncSeparatei_vals[i][0]||
+                            glBlendFuncSeparatei_vals[i][1]!=previousState.glBlendFuncSeparatei_vals[i][1]||
+                            glBlendFuncSeparatei_vals[i][2]!=previousState.glBlendFuncSeparatei_vals[i][2]||
+                            glBlendFuncSeparatei_vals[i][3]!=previousState.glBlendFuncSeparatei_vals[i][3])
+                        {
+                            diff.glBlendFuncSeparatei_vals[j][0] = glBlendFuncSeparatei_vals[i][0];
+                            diff.glBlendFuncSeparatei_vals[j][1] = glBlendFuncSeparatei_vals[i][1];
+                            diff.glBlendFuncSeparatei_vals[j][2] = glBlendFuncSeparatei_vals[i][2];
+                            diff.glBlendFuncSeparatei_vals[j][3] = glBlendFuncSeparatei_vals[i][3];
+                            j++;
+                        }
+                    }
+                }
+
+                if (careAboutTextures)
+                {
+                    for (uint32_t i=0; i<OGL_STATE_MAX_TEXTURES; i++)
+                    {
+                        if (boundTextures[i]!=previousState.boundTextures[i]||boundTextureTargets[i]!=previousState.boundTextureTargets[i])
+                            diff.bindTextures[diff.texturesToBind++] = COpenGLStateDiff::TextureToBind(i,boundTextures[i],boundTextureTargets[i]);
+
+                        if (boundSamplers[i]!=previousState.boundSamplers[i])
+                            diff.bindSamplers[diff.samplersToBind++] = COpenGLStateDiff::IndexedObjectToBind(i,boundSamplers[i]);
+                    }
+                }
+
+                return diff;
+            }
+
+            inline COpenGLStateDiff operator^(const COpenGLState &previousState) const {return getStateDiff(previousState);}
+
+
+        private:
+            inline void setEnableDiffBits(COpenGLStateDiff& diff, const uint64_t& bitdiff, const uint64_t& i, const uint64_t& j) const
+            {
+                const uint64_t bitFlag = uint64_t(0x1ull)<<j;
+                if (bitdiff&bitFlag)
+                {
+                    if (glEnableBitfield[i]&bitFlag)
+                        diff.glEnables[diff.glEnableCount++] = glEnableBitToGLenum(i*64+j);
+                    else
+                        diff.glDisables[diff.glDisableCount++] = glEnableBitToGLenum(i*64+j);
+                }
+            }
+            inline void setEnableiDiffBits(COpenGLStateDiff& diff, const uint64_t& bitdiff, const uint64_t& i, const uint64_t& j) const
+            {
+                const uint64_t bitFlag = uint64_t(0x1ull)<<j;
+                if (bitdiff&bitFlag)
+                {
+                    uint8_t ix;
+                    GLenum combo = glEnableiBitToGLenum(ix,i*64+j);
+                    if (glEnableBitfield[i]&bitFlag)
+                    {
+                        diff.glEnableis[diff.glEnableiCount].indices |= ix;
+
+                        GLenum currVal = diff.glEnableis[diff.glEnableiCount].flag;
+                        if (currVal!=combo)
+                            diff.glEnableis[diff.glEnableiCount++].flag = combo;
+                    }
+                    else
+                    {
+                        diff.glDisableis[diff.glDisableiCount].indices |= ix;
+
+                        GLenum currVal = diff.glDisableis[diff.glDisableiCount].flag;
+                        if (currVal!=combo)
+                            diff.glDisableis[diff.glDisableiCount++].flag = combo;
+                    }
+                }
+            }
+
+
+            GLenum glHint_vals[EGHB_COUNT];
+            GLenum glProvokingVertex_val;
+
+            uint64_t glEnableBitfield[(EGEB_COUNT+63)/64];
+            inline bool getGlEnableBit(const E_GL_ENABLE_BIT& bit) const
+            {
+                return glEnableBitfield[bit/64]&(uint64_t(0x1ull)<<(bit%64));
+            }
+            inline void setGlEnableBit(const E_GL_ENABLE_BIT& bit, bool value)
+            {
+                if (value)
+                    glEnableBitfield[bit/64] |= uint64_t(0x1ull)<<(bit%64);
+                else
+                    glEnableBitfield[bit/64] &= ~(uint64_t(0x1ull)<<(bit%64));
+            }
+
+            uint64_t glEnableiBitfield[(EGEIB_COUNT*OGL_MAX_ENDISABLEI_INDICES+63)/64];
+            inline bool getGlEnableiBit(uint64_t bit, const uint32_t& index) const
+            {
+                bit *= OGL_MAX_ENDISABLEI_INDICES;
+                bit += index;
+                return glEnableiBitfield[bit/64]&(uint64_t(0x1ull)<<(bit%64));
+            }
+            inline void setGlEnableiBit(uint64_t bit, const uint32_t& index, bool value)
+            {
+                bit *= OGL_MAX_ENDISABLEI_INDICES;
+                bit += index;
+                if (value)
+                    glEnableiBitfield[bit/64] |= uint64_t(0x1ull)<<(bit%64);
+                else
+                    glEnableiBitfield[bit/64] &= ~(uint64_t(0x1ull)<<(bit%64));
+            }
+
+            float glPolygonOffset_factor,glPolygonOffset_units;
+            float glPrimitiveSize[2]; //glPointSize, glLineWidth
+
+
+            GLuint glUseProgram_val,glBindProgramPipeline_val;
+
+            float glDepthRangeArray_vals[OGL_STATE_MAX_VIEWPORTS][2];
+            GLint glViewportArray_vals[OGL_STATE_MAX_VIEWPORTS][4];
+            GLint glScissorArray_vals[OGL_STATE_MAX_VIEWPORTS][4];
+
+            //BUFFER BINDING POINTS
+
+            GLenum glLogicOp_val;
+
+            float glBlendColor_vals[4];
+            GLenum glBlendEquationSeparatei_vals[OGL_STATE_MAX_DRAW_BUFFERS][2];
+            GLenum glBlendFuncSeparatei_vals[OGL_STATE_MAX_DRAW_BUFFERS][4];
+
+            GLenum boundTextureTargets[OGL_STATE_MAX_TEXTURES];
+            GLuint boundTextures[OGL_STATE_MAX_TEXTURES];
+            GLuint boundSamplers[OGL_STATE_MAX_TEXTURES];
+	};
+
+
+} // end namespace video
+} // end namespace irr
+
+#endif
+
+/**
+OpenGLState
+{
+GL_CULL_FACE : 1
+glCullFace
+glFrontFace
+GL_DEPTH_TEST : 1
+glDepthFunc : 3
+glDepthMask : 1 //write to Z
+glDepthRangeIndexed(viewport,zNear = 1, zFar = 1)
+GL_STENCIL_TEST : 1
+glStencilOpSeparate
+glStencilMaskSeparate
+glStencilFuncSeparate
+GL_COLOR_LOGIC_OP
+glLogicOp
+GL_LINE_SMOOTH : 1
+///GL_MULTISAMPLE : 1
+glSampleCoverage
+
+
+GL_POLYGON_SMOOTH : 1
+GL_PRIMITIVE_RESTART : 1
+glPrimitiveRestartIndex
+GL_PRIMITIVE_RESTART_FIXED_INDEX : 1
+GL_SAMPLE_ALPHA_TO_COVERAGE : 1
+GL_SAMPLE_ALPHA_TO_ONE : 1
+GL_SAMPLE_COVERAGE : 1
+glSampleCoverage
+GL_SAMPLE_SHADING
+glMinSampleShading
+GL_SAMPLE_MASK
+glSampleMaski
+
+
+
+glUniformBlockBinding
+glBindBuffer
+glBindBufferBase
+glBindBufferRange
+{
+GL_PIXEL_PACK_BUFFER_BINDING
+GL_PIXEL_UNPACK_BUFFER_BINDING
+GL_UNIFORM_BUFFER_BINDING
+
+}
+
+glShaderStorageBlockBinding
+
+GL_VERTEX_ARRAY_BINDING
+
+GL_POINT_SIZE
+GL_PROGRAM_POINT_SIZE
+GL_POINT_FADE_THRESHOLD_SIZE
+glPointSize
+glPointParameter*
+
+glColorMaski : 4 bool x MRT
+
+glPolygonMode
+GL_POLYGON_SMOOTH
+
+BoundQueries
+
+ActiveXFormFeedback
+
+
+
+glPixelStorei //12 vals
+
+GL_STENCIL_CLEAR_VALUE
+glClearStencil
+
+
+ActiveFBOs
+
+
+glReadPixels
+GL_READ_BUFFER
+
+glClampColor : 1 bool
+
+GL_PROVOKING_VERTEX
+}
+**/
diff --git a/include/COpenGLStateManagerImpl.h b/include/COpenGLStateManagerImpl.h
new file mode 100644
index 000000000..6ebbc3b79
--- /dev/null
+++ b/include/COpenGLStateManagerImpl.h
@@ -0,0 +1,256 @@
+// Copyright (C) 2017- Mateusz Kielan
+// This file is part of the "IrrlichtBAW".
+#include "COpenGLStateManager.h"
+
+#ifndef __C_OPENGL_STATE_MANAGER_IMPLEMENTATION_H_INCLUDED__
+#define __C_OPENGL_STATE_MANAGER_IMPLEMENTATION_H_INCLUDED__
+
+#ifndef glHint_MACRO
+#define glHint_MACRO glHint
+#endif // glHint_MACRO
+
+#ifndef glProvokingVertex_MACRO
+#define glProvokingVertex_MACRO glProvokingVertex
+#endif // glProvokingVertex_MACRO
+
+#ifndef glEnable_MACRO
+#define glEnable_MACRO glEnable
+#endif // glEnable_MACRO
+#ifndef glDisable_MACRO
+#define glDisable_MACRO glDisable
+#endif // glDisable_MACRO
+
+#ifndef glEnablei_MACRO
+#define glEnablei_MACRO glEnablei
+#endif // glEnablei_MACRO
+#ifndef glDisablei_MACRO
+#define glDisablei_MACRO glDisablei
+#endif // glDisablei_MACRO
+
+
+#ifndef glUseProgram_MACRO
+#define glUseProgram_MACRO glUseProgram
+#endif // glUseProgram_MACRO
+#ifndef glBindProgramPipeline_MACRO
+#define glBindProgramPipeline_MACRO glBindProgramPipeline
+#endif // glBindProgramPipeline_MACRO
+
+
+#ifndef glPolygonOffset_MACRO
+#define glPolygonOffset_MACRO glPolygonOffset
+#endif // glPolygonOffset_MACRO
+
+
+#ifndef glDepthRangeIndexed_MACRO
+#define glDepthRangeIndexed_MACRO glDepthRangeIndexed
+#endif // glDepthRangeIndexed_MACRO
+
+
+#ifndef glViewportIndexedv_MACRO
+#define glViewportIndexedv_MACRO glViewportIndexedv
+#endif // glViewportIndexedv_MACRO
+
+
+#ifndef glScissorIndexedv_MACRO
+#define glScissorIndexedv_MACRO glScissorIndexedv
+#endif // glScissorIndexedv_MACRO
+
+
+#ifndef glPointSize_MACRO
+#define glPointSize_MACRO glPointSize
+#endif // glPointSize_MACRO
+
+
+#ifndef glLineWidth_MACRO
+#define glLineWidth_MACRO glLineWidth
+#endif // glLineWidth_MACRO
+
+
+#ifndef glLogicOp_MACRO
+#define glLogicOp_MACRO glLogicOp
+#endif // glLogicOp_MACRO
+
+#ifndef glBlendColor_MACRO
+#define glBlendColor_MACRO glBlendColor
+#endif // glBlendColor_MACRO
+
+
+#ifndef glBlendEquationSeparatei_MACRO
+#define glBlendEquationSeparatei_MACRO glBlendEquationSeparatei
+#endif // glBlendEquationSeparatei_MACRO
+
+
+#ifndef glBlendFuncSeparatei_MACRO
+#define glBlendFuncSeparatei_MACRO glBlendFuncSeparatei
+#endif // glBlendFuncSeparatei_MACRO
+
+
+#ifndef SPECIAL_glBindTextureUnit_MACRO
+#error "No Override for Active Texture Setting"
+#endif // SPECIAL_glBindTextureUnit_MACRO
+
+
+#ifndef glBindSampler_MACRO
+#define glBindSampler_MACRO glBindSampler
+#endif // glBindSampler_MACRO
+
+/*
+#ifndef _MACRO
+#define _MACRO
+#endif // _MACRO
+
+
+#ifndef _MACRO
+#define _MACRO
+#endif // _MACRO
+
+
+#ifndef _MACRO
+#define _MACRO
+#endif // _MACRO
+
+
+#ifndef _MACRO
+#define _MACRO
+#endif // _MACRO
+
+
+#ifndef _MACRO
+#define _MACRO
+#endif // _MACRO
+
+
+#ifndef _MACRO
+#define _MACRO
+#endif // _MACRO
+
+
+#ifndef _MACRO
+#define _MACRO
+#endif // _MACRO
+
+
+#ifndef _MACRO
+#define _MACRO
+#endif // _MACRO
+*/
+
+namespace irr
+{
+namespace video
+{
+
+inline void executeGLDiff(const COpenGLStateDiff& diff)
+{
+    //set hints
+    for (uint8_t i=0; i<diff.hintsToSet; i++)
+        glHint_MACRO(diff.glHint_pair[i][0],diff.glHint_pair[i][1]);
+
+    if (diff.glProvokingVertex_val!=GL_INVALID_ENUM)
+        glProvokingVertex_MACRO(diff.glProvokingVertex_val);
+
+    //enable/disable
+    for (uint32_t i=0; i<diff.glDisableCount; i++)
+        glDisable_MACRO(diff.glDisables[i]);
+    for (uint32_t i=0; i<diff.glEnableCount; i++)
+        glEnable_MACRO(diff.glEnables[i]);
+
+    for (uint32_t i=0; i<diff.glDisableiCount; i++)
+    for (uint8_t j=0; j<OGL_MAX_ENDISABLEI_INDICES; j++)
+    {
+        if (diff.glDisableis[i].indices&(0x1u<<j))
+            glDisablei_MACRO(diff.glDisableis[i].flag,j);
+    }
+    for (uint32_t i=0; i<diff.glEnableiCount; i++)
+    for (uint32_t j=0; j<OGL_MAX_ENDISABLEI_INDICES; j++)
+    {
+        if (diff.glEnableis[i].indices&(0x1u<<j))
+            glEnablei_MACRO(diff.glEnableis[i].flag,j);
+    }
+
+    //change FBO
+
+    //change Shader
+    if (diff.changeGlProgram)
+        glUseProgram_MACRO(diff.glUseProgram_val);
+    if (diff.changeGlProgramPipeline) //!this has no effect with an active program except state modification
+        glBindProgramPipeline_MACRO(diff.glBindProgramPipeline_val);
+
+    //change ROP
+    if (diff.resetPolygonOffset)
+        glPolygonOffset_MACRO(diff.glPolygonOffset_factor,diff.glPolygonOffset_units);
+
+    {
+        size_t j=0;
+        for (uint8_t i=0; i<OGL_STATE_MAX_VIEWPORTS; i++)
+        {
+            if (diff.setDepthRange&(uint8_t(1)<<i))
+            {
+                glDepthRangeIndexed_MACRO(i,diff.glDepthRangeArray_vals[j][0],diff.glDepthRangeArray_vals[j][1]);
+                j++;
+            }
+        }
+        j=0;
+        for (uint8_t i=0; i<OGL_STATE_MAX_VIEWPORTS; i++)
+        {
+            if (diff.setViewportArray&(uint8_t(1)<<i))
+                glViewportIndexedv_MACRO(i,diff.glViewportArray_vals[j++]);
+        }
+        j=0;
+        for (uint8_t i=0; i<OGL_STATE_MAX_VIEWPORTS; i++)
+        {
+            if (diff.setScissorBox&(uint8_t(1)<<i))
+                glScissorIndexedv_MACRO(i,diff.glScissorArray_vals[j++]);
+        }
+    }
+
+    if (diff.glPrimitiveSize[0]==diff.glPrimitiveSize[0])
+        glPointSize_MACRO(diff.glPrimitiveSize[0]);
+    if (diff.glPrimitiveSize[1]==diff.glPrimitiveSize[1])
+        glLineWidth_MACRO(diff.glPrimitiveSize[1]);
+
+    if (diff.glLogicOp_val!=GL_INVALID_ENUM)
+        glLogicOp_MACRO(diff.glLogicOp_val);
+
+    if (diff.setBlendColor)
+        glBlendColor_MACRO(diff.glBlendColor_vals[0],diff.glBlendColor_vals[1],diff.glBlendColor_vals[2],diff.glBlendColor_vals[3]);
+
+    {
+        size_t j=0;
+        for (size_t i=0; i<OGL_STATE_MAX_DRAW_BUFFERS; i++)
+        {
+            if (diff.setBlendEquation&(uint8_t(1)<<i))
+            {
+                glBlendEquationSeparatei_MACRO(i,diff.glBlendEquationSeparatei_vals[0],diff.glBlendEquationSeparatei_vals[1]);
+                j++;
+            }
+        }
+        j=0;
+        for (size_t i=0; i<OGL_STATE_MAX_DRAW_BUFFERS; i++)
+        {
+            if (diff.setBlendFunc&(uint8_t(1)<<i))
+            {
+                glBlendFuncSeparatei_MACRO(i,diff.glBlendEquationSeparatei_vals[0],diff.glBlendEquationSeparatei_vals[1],diff.glBlendEquationSeparatei_vals[2],diff.glBlendEquationSeparatei_vals[3]);
+                j++;
+            }
+        }
+    }
+
+
+    //change Texture
+    for (size_t i=0; i<texturesToBind; i++)
+        SPECIAL_glBindTextureUnit_MACRO(diff.bindTextures[i].index,diff.bindTextures[i].obj,diff.bindTextures[i].target);
+    for (size_t i=0; i<samplersToBind; i++)
+        glBindSampler_MACRO(diff.bindSamplers[i].index,diff.bindSamplers[i].obj);
+
+    //change VAO
+
+    //change UBO
+}
+
+
+} // end namespace video
+} // end namespace irr
+
+#endif
+
diff --git a/include/EDeviceTypes.h b/include/EDeviceTypes.h
index 44b009431..1703b4c4b 100644
--- a/include/EDeviceTypes.h
+++ b/include/EDeviceTypes.h
@@ -16,10 +16,6 @@ namespace irr
 		/** This device uses the Win32 API and works in all versions of Windows. */
 		EIDT_WIN32,
 
-		//! A device native to Windows CE devices
-		/** This device works on Windows Mobile, Pocket PC and Microsoft SmartPhone devices */
-		EIDT_WINCE,
-
 		//! A device native to Unix style operating systems.
 		/** This device uses the X11 windowing system and works in Linux, Solaris, FreeBSD, OSX and
 		other operating systems which support X11. */
diff --git a/include/IDummyTransformationSceneNode.h b/include/IDummyTransformationSceneNode.h
index f3806f0cb..055a9217c 100644
--- a/include/IDummyTransformationSceneNode.h
+++ b/include/IDummyTransformationSceneNode.h
@@ -4,28 +4,28 @@
 
 #ifndef __I_DUMMY_TRANSFORMATION_SCENE_NODE_H_INCLUDED__
 #define __I_DUMMY_TRANSFORMATION_SCENE_NODE_H_INCLUDED__
-
-#include "IReferenceCounted.h"
-#include "ISceneNodeAnimator.h"
-#include "irrList.h"
-#include "matrix4x3.h"
+
+#include "IReferenceCounted.h"
+#include "ISceneNodeAnimator.h"
+#include <vector>
+#include "matrix4x3.h"
 #include "ESceneNodeTypes.h"
 
 namespace irr
 {
 namespace scene
-{
-
-class ISceneManager;
-class ISceneNodeAnimator;
-class IDummyTransformationSceneNode;
-
-
-
-	//! Typedef for list of scene nodes
-	typedef core::list<IDummyTransformationSceneNode*> IDummyTransformationSceneNodeList;
-	//! Typedef for list of scene node animators
-	typedef core::list<ISceneNodeAnimator*> ISceneNodeAnimatorList;
+{
+
+class ISceneManager;
+class ISceneNodeAnimator;
+class IDummyTransformationSceneNode;
+
+
+
+	//! Typedef for array of scene nodes
+	typedef std::vector<IDummyTransformationSceneNode*> IDummyTransformationSceneNodeArray;
+	//! Typedef for array of scene node animators
+	typedef std::vector<ISceneNodeAnimator*> ISceneNodeAnimatorArray;
 
 //! Dummy scene node for adding additional transformations to the scene graph.
 /** This scene node does not render itself, and does not respond to set/getPosition,
@@ -36,11 +36,11 @@ This scene node is for example used by the IAnimatedMeshSceneNode for emulating
 joint scene nodes when playing skeletal animations.
 */
 class IDummyTransformationSceneNode : public virtual IReferenceCounted
-{
-    protected:
-        uint64_t lastTimeRelativeTransRead[5];
-
-        uint64_t relativeTransChanged;
+{
+    protected:
+        uint64_t lastTimeRelativeTransRead[5];
+
+        uint64_t relativeTransChanged;
         bool relativeTransNeedsUpdate;
     public:
 
@@ -48,162 +48,162 @@ class IDummyTransformationSceneNode : public virtual IReferenceCounted
         IDummyTransformationSceneNode(IDummyTransformationSceneNode* parent,
 				const core::vector3df& position = core::vector3df(0,0,0),
 				const core::vector3df& rotation = core::vector3df(0,0,0),
-				const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) :
+				const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) :
                 RelativeTranslation(position), RelativeRotation(rotation), RelativeScale(scale),
-				Parent(0),  relativeTransChanged(1), relativeTransNeedsUpdate(true)
-        {
-            memset(lastTimeRelativeTransRead,0,sizeof(uint64_t)*5);
+				Parent(0),  relativeTransChanged(1), relativeTransNeedsUpdate(true)
+        {
+            memset(lastTimeRelativeTransRead,0,sizeof(uint64_t)*5);
 
 			if (parent)
 				parent->addChild(this);
 
-			updateAbsolutePosition();
-        }
-
-        virtual ~IDummyTransformationSceneNode()
-        {
-            removeAll();
+			updateAbsolutePosition();
+        }
+
+        virtual ~IDummyTransformationSceneNode()
+        {
+            removeAll();
 
 			// delete all animators
-			ISceneNodeAnimatorList::Iterator ait = Animators.begin();
+			ISceneNodeAnimatorArray::iterator ait = Animators.begin();
 			for (; ait != Animators.end(); ++ait)
-				(*ait)->drop();
-        }
-
+				(*ait)->drop();
+        }
+
         virtual const bool isISceneNode() const {return false;}
 
         //! Returns a reference to the current relative transformation matrix.
         /** This is the matrix, this scene node uses instead of scale, translation
         and rotation. */
-        inline virtual const core::matrix4x3& getRelativeTransformationMatrix()
-        {
-            if (relativeTransNeedsUpdate)
-            {
-                RelativeTransformation.setRotationDegrees(RelativeRotation);
-                RelativeTransformation.setTranslation(RelativeTranslation);
-                //
-                RelativeTransformation(0,0) *= RelativeScale.X;
-                RelativeTransformation(1,0) *= RelativeScale.X;
-                RelativeTransformation(2,0) *= RelativeScale.X;
-                RelativeTransformation(0,1) *= RelativeScale.Y;
-                RelativeTransformation(1,1) *= RelativeScale.Y;
-                RelativeTransformation(2,1) *= RelativeScale.Y;
-                RelativeTransformation(0,2) *= RelativeScale.Z;
-                RelativeTransformation(1,2) *= RelativeScale.Z;
-                RelativeTransformation(2,2) *= RelativeScale.Z;
-                //
-                relativeTransChanged++;
-                relativeTransNeedsUpdate = false;
-            }
-            return RelativeTransformation;
-        }
-
-        //!
-        inline void setRelativeTransformationMatrix(const core::matrix4x3& tform)
-        {
-            RelativeTransformation = tform;
-            relativeTransChanged++;
-            relativeTransNeedsUpdate = false;
-        }
-
-        inline const uint64_t& getRelativeTransChangedHint() const {return relativeTransChanged;}
-
+        inline virtual const core::matrix4x3& getRelativeTransformationMatrix()
+        {
+            if (relativeTransNeedsUpdate)
+            {
+                RelativeTransformation.setRotationDegrees(RelativeRotation);
+                RelativeTransformation.setTranslation(RelativeTranslation);
+                //
+                RelativeTransformation(0,0) *= RelativeScale.X;
+                RelativeTransformation(1,0) *= RelativeScale.X;
+                RelativeTransformation(2,0) *= RelativeScale.X;
+                RelativeTransformation(0,1) *= RelativeScale.Y;
+                RelativeTransformation(1,1) *= RelativeScale.Y;
+                RelativeTransformation(2,1) *= RelativeScale.Y;
+                RelativeTransformation(0,2) *= RelativeScale.Z;
+                RelativeTransformation(1,2) *= RelativeScale.Z;
+                RelativeTransformation(2,2) *= RelativeScale.Z;
+                //
+                relativeTransChanged++;
+                relativeTransNeedsUpdate = false;
+            }
+            return RelativeTransformation;
+        }
+
+        //!
+        inline void setRelativeTransformationMatrix(const core::matrix4x3& tform)
+        {
+            RelativeTransformation = tform;
+            relativeTransChanged++;
+            relativeTransNeedsUpdate = false;
+        }
+
+        inline const uint64_t& getRelativeTransChangedHint() const {return relativeTransChanged;}
+
         inline const uint64_t& getAbsoluteTransformLastRecomputeHint() const {return lastTimeRelativeTransRead[3];}
 
-        inline const core::vector3df& getScale()
-        {
-            if (lastTimeRelativeTransRead[0]<relativeTransChanged)
-            {
-                const core::matrix4x3& rel = getRelativeTransformationMatrix();
-                RelativeScale = rel.getScale();
-                lastTimeRelativeTransRead[0] = relativeTransChanged;
-            }
-            return RelativeScale;
+        inline const core::vector3df& getScale()
+        {
+            if (lastTimeRelativeTransRead[0]<relativeTransChanged)
+            {
+                const core::matrix4x3& rel = getRelativeTransformationMatrix();
+                RelativeScale = rel.getScale();
+                lastTimeRelativeTransRead[0] = relativeTransChanged;
+            }
+            return RelativeScale;
         }
 
         inline void setScale(const core::vector3df& scale)
         {
-            RelativeScale = scale;
+            RelativeScale = scale;
             relativeTransNeedsUpdate = true;
         }
 
         inline const core::vector3df& getRotation()
-        {
-            if (lastTimeRelativeTransRead[1]<relativeTransChanged)
-            {
-                const core::matrix4x3& rel = getRelativeTransformationMatrix();
-                RelativeRotation = rel.getRotationDegrees();
-                lastTimeRelativeTransRead[1] = relativeTransChanged;
+        {
+            if (lastTimeRelativeTransRead[1]<relativeTransChanged)
+            {
+                const core::matrix4x3& rel = getRelativeTransformationMatrix();
+                RelativeRotation = rel.getRotationDegrees();
+                lastTimeRelativeTransRead[1] = relativeTransChanged;
             }
             return RelativeRotation;
         }
 
         inline void setRotation(const core::vector3df& rotation)
         {
-            RelativeRotation = rotation;
+            RelativeRotation = rotation;
             relativeTransNeedsUpdate = true;
         }
 
         inline const core::vector3df& getPosition()
-        {
-            if (lastTimeRelativeTransRead[2]<relativeTransChanged)
-            {
-                const core::matrix4x3& rel = getRelativeTransformationMatrix();
-                RelativeTranslation = rel.getTranslation();
-                lastTimeRelativeTransRead[2] = relativeTransChanged;
+        {
+            if (lastTimeRelativeTransRead[2]<relativeTransChanged)
+            {
+                const core::matrix4x3& rel = getRelativeTransformationMatrix();
+                RelativeTranslation = rel.getTranslation();
+                lastTimeRelativeTransRead[2] = relativeTransChanged;
             }
             return RelativeTranslation;
         }
 
         inline void setPosition(const core::vector3df& newpos)
         {
-            RelativeTranslation = newpos;
+            RelativeTranslation = newpos;
             relativeTransNeedsUpdate = true;
-        }
-
-
-        inline virtual bool needsAbsoluteTransformRecompute() const
-        {
-            if (relativeTransNeedsUpdate||lastTimeRelativeTransRead[3]<relativeTransChanged)
-                return true;
-
-            if (Parent)
-                return lastTimeRelativeTransRead[4]<Parent->getAbsoluteTransformLastRecomputeHint();
-
-            return false;
-        }
-
-        inline virtual size_t needsDeepAbsoluteTransformRecompute() const
-        {
-            const IDummyTransformationSceneNode* parentStack[1024];
-            parentStack[0] = this;
-            size_t stackSize=0;
-
-            while (parentStack[stackSize])
-            {
-                parentStack[++stackSize] = parentStack[stackSize];
-                if (stackSize>=1024)
-                    break;
-            }
-
-            size_t maxStackSize = stackSize-1;
-            while (--stackSize)
-            {
-                if (parentStack[stackSize]->relativeTransNeedsUpdate||parentStack[stackSize]->lastTimeRelativeTransRead[3]<parentStack[stackSize]->relativeTransChanged)
-                    return stackSize;
-
-                if (stackSize<maxStackSize)
-                {
-                    if (parentStack[stackSize]->lastTimeRelativeTransRead[4]<parentStack[stackSize+1]->getAbsoluteTransformLastRecomputeHint())
-                        return stackSize;
-                }
-            }
-
-            return 0xdeadbeefu;
-        }
-
-        inline const core::matrix4x3& getAbsoluteTransformation()
-        {
+        }
+
+
+        inline virtual bool needsAbsoluteTransformRecompute() const
+        {
+            if (relativeTransNeedsUpdate||lastTimeRelativeTransRead[3]<relativeTransChanged)
+                return true;
+
+            if (Parent)
+                return lastTimeRelativeTransRead[4]<Parent->getAbsoluteTransformLastRecomputeHint();
+
+            return false;
+        }
+
+        inline virtual size_t needsDeepAbsoluteTransformRecompute() const
+        {
+            const IDummyTransformationSceneNode* parentStack[1024];
+            parentStack[0] = this;
+            size_t stackSize=0;
+
+            while (parentStack[stackSize])
+            {
+                parentStack[++stackSize] = parentStack[stackSize];
+                if (stackSize>=1024)
+                    break;
+            }
+
+            size_t maxStackSize = stackSize-1;
+            while (--stackSize)
+            {
+                if (parentStack[stackSize]->relativeTransNeedsUpdate||parentStack[stackSize]->lastTimeRelativeTransRead[3]<parentStack[stackSize]->relativeTransChanged)
+                    return stackSize;
+
+                if (stackSize<maxStackSize)
+                {
+                    if (parentStack[stackSize]->lastTimeRelativeTransRead[4]<parentStack[stackSize+1]->getAbsoluteTransformLastRecomputeHint())
+                        return stackSize;
+                }
+            }
+
+            return 0xdeadbeefu;
+        }
+
+        inline const core::matrix4x3& getAbsoluteTransformation()
+        {
             return AbsoluteTransformation;
         }
 
@@ -225,30 +225,30 @@ class IDummyTransformationSceneNode : public virtual IReferenceCounted
 		/** Note: This does not recursively update the parents absolute positions, so if you have a deeper
 			hierarchy you might want to update the parents first.*/
 		inline virtual void updateAbsolutePosition()
-		{
-            bool recompute = relativeTransNeedsUpdate||lastTimeRelativeTransRead[3]<relativeTransChanged;
-
-            if (Parent)
-            {
-                uint64_t parentAbsoluteHint = Parent->getAbsoluteTransformLastRecomputeHint();
-                if (lastTimeRelativeTransRead[4] < parentAbsoluteHint)
-                {
-                    lastTimeRelativeTransRead[4] = parentAbsoluteHint;
-                    recompute = true;
-                }
-
-                // recompute if local transform has changed
-                if (recompute)
-                {
-                    const core::matrix4x3& rel = getRelativeTransformationMatrix();
-                    AbsoluteTransformation = concatenateBFollowedByA(Parent->getAbsoluteTransformation(),rel);
-                    lastTimeRelativeTransRead[3] = relativeTransChanged;
-                }
-            }
-            else if (recompute)
-            {
-                AbsoluteTransformation = getRelativeTransformationMatrix();
-                lastTimeRelativeTransRead[3] = relativeTransChanged;
+		{
+            bool recompute = relativeTransNeedsUpdate||lastTimeRelativeTransRead[3]<relativeTransChanged;
+
+            if (Parent)
+            {
+                uint64_t parentAbsoluteHint = Parent->getAbsoluteTransformLastRecomputeHint();
+                if (lastTimeRelativeTransRead[4] < parentAbsoluteHint)
+                {
+                    lastTimeRelativeTransRead[4] = parentAbsoluteHint;
+                    recompute = true;
+                }
+
+                // recompute if local transform has changed
+                if (recompute)
+                {
+                    const core::matrix4x3& rel = getRelativeTransformationMatrix();
+                    AbsoluteTransformation = concatenateBFollowedByA(Parent->getAbsoluteTransformation(),rel);
+                    lastTimeRelativeTransRead[3] = relativeTransChanged;
+                }
+            }
+            else if (recompute)
+            {
+                AbsoluteTransformation = getRelativeTransformationMatrix();
+                lastTimeRelativeTransRead[3] = relativeTransChanged;
             }
 		}
 
@@ -256,7 +256,7 @@ class IDummyTransformationSceneNode : public virtual IReferenceCounted
 
 		//! Returns a const reference to the list of all children.
 		/** \return The list of all children of this node. */
-		inline const core::list<IDummyTransformationSceneNode*>& getChildren() const
+		inline const IDummyTransformationSceneNodeArray& getChildren() const
 		{
 			return Children;
 		}
@@ -265,22 +265,17 @@ class IDummyTransformationSceneNode : public virtual IReferenceCounted
 		//! Changes the parent of the scene node.
 		/** \param newParent The new parent to be used. */
 		virtual void setParent(IDummyTransformationSceneNode* newParent)
-		{
-		    if (newParent==Parent)
-                return;
-
-			grab();
-			remove();
-
-			Parent = newParent;
+		{
+		    if (newParent==Parent)
+                return;
 
-			if (Parent)
+			if (newParent)
             {
-				Parent->addChild(this);
-				lastTimeRelativeTransRead[4] = 0;
-            }
-
-			drop();
+				newParent->addChild(this);
+				lastTimeRelativeTransRead[4] = 0;
+            }
+            else
+                remove();
 		}
 
 
@@ -297,14 +292,15 @@ class IDummyTransformationSceneNode : public virtual IReferenceCounted
 		\param child A pointer to the new child. */
 		virtual void addChild(IDummyTransformationSceneNode* child)
 		{
-			if (child && (child != this))
-			{
-				child->grab();
-				child->remove(); // remove from old parent
-				Children.push_back(child);
-				child->Parent = this;
-				child->lastTimeRelativeTransRead[4] = 0;
-			}
+			if (!child || child == this || child->getParent() == this)
+                return;
+
+            child->grab();
+            child->remove(); // remove from old parent
+            IDummyTransformationSceneNodeArray::iterator insertionPoint = std::lower_bound(Children.begin(),Children.end(),child);
+            Children.insert(insertionPoint,child);
+            child->Parent = this;
+            child->lastTimeRelativeTransRead[4] = 0;
 		}
 
 
@@ -316,17 +312,14 @@ class IDummyTransformationSceneNode : public virtual IReferenceCounted
 		e.g. because it couldn't be found in the children list. */
 		virtual bool removeChild(IDummyTransformationSceneNode* child)
 		{
-			IDummyTransformationSceneNodeList::Iterator it = Children.begin();
-			for (; it != Children.end(); ++it)
-				if ((*it) == child)
-				{
-					(*it)->Parent = 0;
-					(*it)->drop();
-					Children.erase(it);
-					return true;
-				}
-
-			return false;
+            IDummyTransformationSceneNodeArray::iterator found = std::lower_bound(Children.begin(),Children.end(),child);
+            if (found==Children.end() || *found!=child)
+                return false;
+
+			(*found)->Parent = 0;
+            (*found)->drop();
+            Children.erase(found);
+            return true;
 		}
 
 
@@ -336,7 +329,7 @@ class IDummyTransformationSceneNode : public virtual IReferenceCounted
 		*/
 		virtual void removeAll()
 		{
-			IDummyTransformationSceneNodeList::Iterator it = Children.begin();
+			IDummyTransformationSceneNodeArray::iterator it = Children.begin();
 			for (; it != Children.end(); ++it)
 			{
 				(*it)->Parent = 0;
@@ -361,17 +354,21 @@ class IDummyTransformationSceneNode : public virtual IReferenceCounted
 		/** \param animator A pointer to the new animator. */
 		virtual void addAnimator(ISceneNodeAnimator* animator)
 		{
-			if (animator)
-			{
-				Animators.push_back(animator);
-				animator->grab();
-			}
+			if (!animator)
+				return;
+
+			ISceneNodeAnimatorArray::iterator found = std::lower_bound(Animators.begin(),Animators.end(),animator);
+            ///if (found!=Animators.end() && *found==animator) //already in there
+                ///return;
+
+            animator->grab();
+            Animators.insert(found,animator);
 		}
 
 
 		//! Get a list of all scene node animators.
 		/** \return The list of animators attached to this node. */
-		const core::list<ISceneNodeAnimator*>& getAnimators() const
+		const ISceneNodeAnimatorArray& getAnimators() const
 		{
 			return Animators;
 		}
@@ -383,16 +380,13 @@ class IDummyTransformationSceneNode : public virtual IReferenceCounted
 		\param animator A pointer to the animator to be deleted. */
 		virtual void removeAnimator(ISceneNodeAnimator* animator)
 		{
-			ISceneNodeAnimatorList::Iterator it = Animators.begin();
-			for (; it != Animators.end(); ++it)
-			{
-				if ((*it) == animator)
-				{
-					(*it)->drop();
-					Animators.erase(it);
-					return;
-				}
-			}
+			ISceneNodeAnimatorArray::iterator found = std::lower_bound(Animators.begin(),Animators.end(),animator);
+            if (found==Animators.end() || *found!=animator)
+                return;
+
+            (*found)->drop();
+            Animators.erase(found);
+            return;
 		}
 
 
@@ -401,15 +395,15 @@ class IDummyTransformationSceneNode : public virtual IReferenceCounted
 		for them. */
 		virtual void removeAnimators()
 		{
-			ISceneNodeAnimatorList::Iterator it = Animators.begin();
+			ISceneNodeAnimatorArray::iterator it = Animators.begin();
 			for (; it != Animators.end(); ++it)
 				(*it)->drop();
 
 			Animators.clear();
-		}
+		}
 
         //! Returns type of the scene node
-        virtual ESCENE_NODE_TYPE getType() const { return ESNT_DUMMY_TRANSFORMATION; }
+        virtual ESCENE_NODE_TYPE getType() const { return ESNT_DUMMY_TRANSFORMATION; }
 
         //! Creates a clone of this scene node and its children.
         virtual IDummyTransformationSceneNode* clone(IDummyTransformationSceneNode* newParent=0, ISceneManager* newManager=0)
@@ -425,20 +419,20 @@ class IDummyTransformationSceneNode : public virtual IReferenceCounted
             if ( newParent )
                 nb->drop();
             return nb;
-        }
+        }
 
 	protected:
 		//! Pointer to the parent
 		IDummyTransformationSceneNode* Parent;
 
 		//! List of all children of this node
-		core::list<IDummyTransformationSceneNode*> Children;
+		IDummyTransformationSceneNodeArray Children;
 
 		//! List of all animator nodes
-		core::list<ISceneNodeAnimator*> Animators;
+		ISceneNodeAnimatorArray Animators;
 
 		//! Absolute transformation of the node.
-		core::matrix4x3 AbsoluteTransformation;
+		core::matrix4x3 AbsoluteTransformation;
 
         //! Relative transformation of the node.
         core::matrix4x3 RelativeTransformation;
@@ -459,18 +453,18 @@ class IDummyTransformationSceneNode : public virtual IReferenceCounted
 		virtual void cloneMembers(IDummyTransformationSceneNode* toCopyFrom, ISceneManager* newManager)
 		{
 			AbsoluteTransformation = toCopyFrom->AbsoluteTransformation;
-			RelativeTranslation = toCopyFrom->RelativeTranslation;
+			RelativeTranslation = toCopyFrom->RelativeTranslation;
 			RelativeTranslation = toCopyFrom->RelativeTranslation;
 			RelativeRotation = toCopyFrom->RelativeRotation;
 			RelativeScale = toCopyFrom->RelativeScale;
 
 			// clone children
-			IDummyTransformationSceneNodeList::Iterator it = toCopyFrom->Children.begin();
+			IDummyTransformationSceneNodeArray::iterator it = toCopyFrom->Children.begin();
 			for (; it != toCopyFrom->Children.end(); ++it)
 				(*it)->clone(this, newManager);
 
 			// clone animators
-			ISceneNodeAnimatorList::Iterator ait = toCopyFrom->Animators.begin();
+			ISceneNodeAnimatorArray::iterator ait = toCopyFrom->Animators.begin();
 			for (; ait != toCopyFrom->Animators.end(); ++ait)
 			{
 				ISceneNodeAnimator* anim = (*ait)->createClone(this, newManager);
diff --git a/include/ISceneNode.h b/include/ISceneNode.h
index 98bde84c9..37aaba3e4 100644
--- a/include/ISceneNode.h
+++ b/include/ISceneNode.h
@@ -13,18 +13,17 @@
 #include "irrString.h"
 #include "aabbox3d.h"
 #include "matrix4.h"
-#include "irrList.h"
 #include "IOcclusionQuery.h"
-#include "IDummyTransformationSceneNode.h"
-#include "IDriverFence.h"
+#include "IDummyTransformationSceneNode.h"
+#include "IDriverFence.h"
 
 namespace irr
 {
 namespace scene
 {
 	class ISceneManager;
-    class ISceneNode;
-
+    class ISceneNode;
+
 
 
 	//! Scene node interface.
@@ -44,10 +43,10 @@ namespace scene
 				const core::vector3df& position = core::vector3df(0,0,0),
 				const core::vector3df& rotation = core::vector3df(0,0,0),
 				const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f))
-			:   IDummyTransformationSceneNode(parent,position,rotation,scale),
-                SceneManager(mgr), renderFence(0), fenceBehaviour(EFRB_SKIP_DRAW), query(0),
-                ID(id), AutomaticCullingState(EAC_FRUSTUM_BOX),
-                DebugDataVisible(EDS_OFF), mobid(0), mobtype(0), IsVisible(true),
+			:   IDummyTransformationSceneNode(parent,position,rotation,scale),
+                SceneManager(mgr), renderFence(0), fenceBehaviour(EFRB_SKIP_DRAW), query(0),
+                ID(id), AutomaticCullingState(EAC_FRUSTUM_BOX),
+                DebugDataVisible(EDS_OFF), mobid(0), mobtype(0), IsVisible(true),
                 IsDebugObject(false), staticmeshid(0),blockposX(0),blockposY(0),blockposZ(0), renderPriority(0x80000000u)
 		{
 		}
@@ -55,37 +54,37 @@ namespace scene
 
 		//! Destructor
 		virtual ~ISceneNode()
-		{
-            if (query)
-                query->drop();
-
-            if (renderFence)
+		{
+            if (query)
+                query->drop();
+
+            if (renderFence)
+                renderFence->drop();
+		}
+
+        virtual const bool isISceneNode() const {return true;}
+
+
+        virtual const bool supportsDriverFence() const {return false;}
+
+        enum E_FENCE_RENDER_BEHAVIOUR
+        {
+            EFRB_SKIP_DRAW=0,
+            EFRB_CPU_BLOCK,
+            EFRB_GPU_WAIT,
+            EFRB_COUNT
+        };
+        void useFenceForRender(video::IDriverFence* fence, const E_FENCE_RENDER_BEHAVIOUR& behaviour=EFRB_SKIP_DRAW)
+        {
+            if (fence)
+                fence->grab();
+
+            if (renderFence)
                 renderFence->drop();
-		}
-
-        virtual const bool isISceneNode() const {return true;}
-
-
-        virtual const bool supportsDriverFence() const {return false;}
-
-        enum E_FENCE_RENDER_BEHAVIOUR
-        {
-            EFRB_SKIP_DRAW=0,
-            EFRB_CPU_BLOCK,
-            EFRB_GPU_WAIT,
-            EFRB_COUNT
-        };
-        void useFenceForRender(video::IDriverFence* fence, const E_FENCE_RENDER_BEHAVIOUR& behaviour=EFRB_SKIP_DRAW)
-        {
-            if (fence)
-                fence->grab();
-
-            if (renderFence)
-                renderFence->drop();
-
-            renderFence = fence;
-            fenceBehaviour = behaviour;
-        }
+
+            renderFence = fence;
+            fenceBehaviour = behaviour;
+        }
 
 
 		//! This method is called just before the rendering process of the whole scene.
@@ -105,25 +104,25 @@ namespace scene
 		virtual void OnRegisterSceneNode()
 		{
 			OnRegisterSceneNode_static(this);
-		}
-
-
-		virtual void setOcclusionQuery(video::IOcclusionQuery* query_in)
-		{
-		    video::IOcclusionQuery* old_query = query;
-
-            query = query_in;
-
-            if (query)
-                query->grab();
-
-            if (old_query)
-                old_query->drop();
-		}
-
-		virtual video::IOcclusionQuery* getOcclusionQuery() {return query;}
+		}
+
+
+		virtual void setOcclusionQuery(video::IOcclusionQuery* query_in)
+		{
+		    video::IOcclusionQuery* old_query = query;
+
+            query = query_in;
+
+            if (query)
+                query->grab();
+
+            if (old_query)
+                old_query->drop();
+		}
+
+		virtual video::IOcclusionQuery* getOcclusionQuery() {return query;}
 		virtual video::IOcclusionQuery const* getOcclusionQuery() const {return query;}
-
+
 
 		//! Adds a child to this scene node.
 		/** If the scene node already has a parent it is first removed
@@ -136,8 +135,8 @@ namespace scene
 				// Change scene manager?
 				if (SceneManager != child->SceneManager)
 					child->setSceneManager(SceneManager);
-			}
-
+			}
+
 			IDummyTransformationSceneNode::addChild(child);
 		}
 
@@ -411,8 +410,8 @@ namespace scene
 			if (newManager)
 				SceneManager = newManager;
 			else
-				SceneManager = toCopyFrom->SceneManager;
-
+				SceneManager = toCopyFrom->SceneManager;
+
             IDummyTransformationSceneNode::cloneMembers(toCopyFrom,SceneManager);
 		}
 
@@ -427,63 +426,63 @@ namespace scene
 		core::stringc Name;
 
 		//! Pointer to the scene manager
-		ISceneManager* SceneManager;
-
-		//!
-		video::IDriverFence* renderFence;
-		E_FENCE_RENDER_BEHAVIOUR fenceBehaviour;
-
-		inline bool canProceedPastFence()
-		{
-            if (!renderFence)
-                return true;
-
-            switch (fenceBehaviour)
-            {
-                case EFRB_SKIP_DRAW:
-                    switch (renderFence->waitCPU(0))
-                    {
-                        case video::EDFR_FAIL:
-                        case video::EDFR_TIMEOUT_EXPIRED:
-                            return false;
-                            break;
-                        case video::EDFR_CONDITION_SATISFIED:
-                        case video::EDFR_ALREADY_SIGNALED:
-                            renderFence->drop();
-                            renderFence = NULL;
-                            return true;
-                            break;
-                    }
-                    break;
-                case EFRB_CPU_BLOCK:
-                    {
-                        video::E_DRIVER_FENCE_RETVAL rv = renderFence->waitCPU(1000);
-                        while (rv==video::EDFR_TIMEOUT_EXPIRED)
-                        {
-                            rv = renderFence->waitCPU(1000);
-                        }
-
-                        if (rv!=video::EDFR_FAIL)
-                        {
-                            renderFence->drop();
-                            renderFence = NULL;
-                            return true;
-                        }
-                        else
-                            return false;
-                    }
-                    break;
-                case EFRB_GPU_WAIT:
-                    renderFence->waitGPU();
-                    renderFence->drop();
-                    renderFence = NULL;
-                    return true;
-                    break;
-            }
-            return false;
-        }
-
-		//! Pointer to the attached occlusion query
+		ISceneManager* SceneManager;
+
+		//!
+		video::IDriverFence* renderFence;
+		E_FENCE_RENDER_BEHAVIOUR fenceBehaviour;
+
+		inline bool canProceedPastFence()
+		{
+            if (!renderFence)
+                return true;
+
+            switch (fenceBehaviour)
+            {
+                case EFRB_SKIP_DRAW:
+                    switch (renderFence->waitCPU(0))
+                    {
+                        case video::EDFR_FAIL:
+                        case video::EDFR_TIMEOUT_EXPIRED:
+                            return false;
+                            break;
+                        case video::EDFR_CONDITION_SATISFIED:
+                        case video::EDFR_ALREADY_SIGNALED:
+                            renderFence->drop();
+                            renderFence = NULL;
+                            return true;
+                            break;
+                    }
+                    break;
+                case EFRB_CPU_BLOCK:
+                    {
+                        video::E_DRIVER_FENCE_RETVAL rv = renderFence->waitCPU(1000);
+                        while (rv==video::EDFR_TIMEOUT_EXPIRED)
+                        {
+                            rv = renderFence->waitCPU(1000);
+                        }
+
+                        if (rv!=video::EDFR_FAIL)
+                        {
+                            renderFence->drop();
+                            renderFence = NULL;
+                            return true;
+                        }
+                        else
+                            return false;
+                    }
+                    break;
+                case EFRB_GPU_WAIT:
+                    renderFence->waitGPU();
+                    renderFence->drop();
+                    renderFence = NULL;
+                    return true;
+                    break;
+            }
+            return false;
+        }
+
+		//! Pointer to the attached occlusion query
 		video::IOcclusionQuery* query;
 
 		//! ID of the node.
@@ -501,85 +500,99 @@ namespace scene
 		uint32_t renderPriority;
 
 		//! Is debug object?
-		bool IsDebugObject;
-
+		bool IsDebugObject;
+
         static void OnAnimate_static(IDummyTransformationSceneNode* node, uint32_t timeMs)
-		{
+		{
             ISceneNode* tmp = static_cast<ISceneNode*>(node);
 			if (!node->isISceneNode()||tmp->IsVisible)
 			{
 				// animate this node with all animators
 
-				ISceneNodeAnimatorList::ConstIterator ait = node->getAnimators().begin();
-				while (ait != node->getAnimators().end())
+				//! The bloody animator can remove itself!!!!
+				const ISceneNodeAnimatorArray& animators = node->getAnimators();
+				size_t prevSize = animators.size();
+				for (size_t i=0; i<prevSize;)
                 {
-					// continue to the next node before calling animateNode()
-					// so that the animator may remove itself from the scene
-					// node without the iterator becoming invalid
-					ISceneNodeAnimator* anim = *ait;
-					++ait;
+					ISceneNodeAnimator* anim = animators[i];
 					anim->animateNode(node, timeMs);
+					if (animators[i]>anim)
+                        prevSize = animators.size();
+                    else
+                        i++;
 				}
 
 				// update absolute position
 				node->updateAbsolutePosition();
 
 				// perform the post render process on all children
-
-				IDummyTransformationSceneNodeList::ConstIterator it = node->getChildren().begin();
-				for (; it != node->getChildren().end(); ++it)
-                {
-                    ISceneNode* tmpChild = static_cast<ISceneNode*>(*it);
-                    if ((*it)->isISceneNode())
-                        static_cast<ISceneNode*>(*it)->OnAnimate(timeMs);
-                    else
-                        OnAnimate_static(*it,timeMs);
+                const IDummyTransformationSceneNodeArray& children = node->getChildren();
+				prevSize = children.size();
+				for (size_t i=0; i<prevSize;)
+                {
+                    IDummyTransformationSceneNode* tmpChild = children[i];
+                    if (tmpChild->isISceneNode())
+                        static_cast<ISceneNode*>(tmpChild)->OnAnimate(timeMs);
+                    else
+                        OnAnimate_static(tmpChild,timeMs);
+
+					if (children[i]>tmpChild)
+                        prevSize = children.size();
+                    else
+                        i++;
                 }
 			}
-		}
-    private:
-        static void OnRegisterSceneNode_static(IDummyTransformationSceneNode* node)
-        {
+		}
+    private:
+        static void OnRegisterSceneNode_static(IDummyTransformationSceneNode* node)
+        {
             ISceneNode* tmp = static_cast<ISceneNode*>(node);
 			if (!node->isISceneNode()||tmp->IsVisible)
 			{
-				IDummyTransformationSceneNodeList::ConstIterator it = node->getChildren().begin();
-				for (; it != node->getChildren().end(); ++it)
-                {
-                    if ((*it)->isISceneNode())
-                        static_cast<ISceneNode*>(*it)->OnRegisterSceneNode();
-                    else
-                        OnRegisterSceneNode_static(*it);
+                const IDummyTransformationSceneNodeArray& children = node->getChildren();
+				size_t prevSize = children.size();
+				for (size_t i=0; i<prevSize;)
+                {
+                    IDummyTransformationSceneNode* tmpChild = children[i];
+                    if (tmpChild->isISceneNode())
+                        static_cast<ISceneNode*>(tmpChild)->OnRegisterSceneNode();
+                    else
+                        OnRegisterSceneNode_static(tmpChild);
+
+					if (children[i]>tmpChild)
+                        prevSize = children.size();
+                    else
+                        i++;
                 }
-			}
-        }
-
+			}
+        }
+
         static bool isTrulyVisible_static(const IDummyTransformationSceneNode* node)
-		{
-            const ISceneNode* tmp = static_cast<const ISceneNode*>(node);
-
-            if (node->isISceneNode())
+		{
+            const ISceneNode* tmp = static_cast<const ISceneNode*>(node);
+
+            if (node->isISceneNode())
             {
                 if(!tmp->isVisible())
-                    return false;
-            }
-
-            if (node->getParent())
-                return isTrulyVisible_static(node->getParent());
-            else
+                    return false;
+            }
+
+            if (node->getParent())
+                return isTrulyVisible_static(node->getParent());
+            else
                 return true;
-		}
-
-
+		}
+
+
 		static void setSceneManager_static(IDummyTransformationSceneNode* node, ISceneManager* newManager)
-		{
-            ISceneNode* tmp = static_cast<ISceneNode*>(node);
-
+		{
+            ISceneNode* tmp = static_cast<ISceneNode*>(node);
+
             if (node->isISceneNode())
                 tmp->SceneManager = newManager;
 
-			IDummyTransformationSceneNodeList::ConstIterator it = node->getChildren().begin();
-			for (; it != node->getChildren().end(); ++it)
+			IDummyTransformationSceneNodeArray::const_iterator it = node->getChildren().begin();
+			for (; it != node->getChildren().end(); ++it)
                 setSceneManager_static(*it,newManager);
 		}
 	};
diff --git a/include/IrrCompileConfig.h b/include/IrrCompileConfig.h
index 1c45b6a1f..e5f45ce55 100644
--- a/include/IrrCompileConfig.h
+++ b/include/IrrCompileConfig.h
@@ -720,50 +720,6 @@ precision will be lower but speed higher. currently X86 only
 	#undef _IRR_COMPILE_WITH_DIRECT3D_9_
 #endif
 
-//! WinCE does not have OpenGL or DirectX9. use minimal loaders
-#if defined(_WIN32_WCE)
-	#undef _IRR_COMPILE_WITH_OPENGL_
-	#undef _IRR_COMPILE_WITH_DIRECT3D_8_
-	#undef _IRR_COMPILE_WITH_DIRECT3D_9_
-
-	#undef BURNINGVIDEO_RENDERER_BEAUTIFUL
-	#undef BURNINGVIDEO_RENDERER_FAST
-	#undef BURNINGVIDEO_RENDERER_ULTRA_FAST
-	#define BURNINGVIDEO_RENDERER_CE
-
-	#undef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
-	#define _IRR_COMPILE_WITH_WINDOWS_CE_DEVICE_
-
-	#undef _IRR_COMPILE_WITH_3DS_LOADER_
-	#undef _IRR_COMPILE_WITH_CSM_LOADER_
-	#undef _IRR_COMPILE_WITH_BSP_LOADER_
-	#undef _IRR_COMPILE_WITH_DMF_LOADER_
-	#undef _IRR_COMPILE_WITH_LMTS_LOADER_
-	#undef _IRR_COMPILE_WITH_MY3D_LOADER_
-	#undef _IRR_COMPILE_WITH_OBJ_LOADER_
-	#undef _IRR_COMPILE_WITH_OCT_LOADER_
-	#undef _IRR_COMPILE_WITH_OGRE_LOADER_
-	#undef _IRR_COMPILE_WITH_LWO_LOADER_
-	#undef _IRR_COMPILE_WITH_STL_LOADER_
-	#undef _IRR_COMPILE_WITH_STL_WRITER_
-	#undef _IRR_COMPILE_WITH_OBJ_WRITER_
-	//#undef _IRR_COMPILE_WITH_BMP_LOADER_
-	//#undef _IRR_COMPILE_WITH_JPG_LOADER_
-	#undef _IRR_COMPILE_WITH_PCX_LOADER_
-	//#undef _IRR_COMPILE_WITH_PNG_LOADER_
-	#undef _IRR_COMPILE_WITH_PPM_LOADER_
-	#undef _IRR_COMPILE_WITH_PSD_LOADER_
-	//#undef _IRR_COMPILE_WITH_TGA_LOADER_
-	#undef _IRR_COMPILE_WITH_WAL_LOADER_
-	#undef _IRR_COMPILE_WITH_BMP_WRITER_
-	#undef _IRR_COMPILE_WITH_JPG_WRITER_
-	#undef _IRR_COMPILE_WITH_PCX_WRITER_
-	#undef _IRR_COMPILE_WITH_PNG_WRITER_
-	#undef _IRR_COMPILE_WITH_PPM_WRITER_
-	#undef _IRR_COMPILE_WITH_PSD_WRITER_
-	#undef _IRR_COMPILE_WITH_TGA_WRITER_
-
-#endif
 
 #ifndef _IRR_WINDOWS_API_
 	#undef _IRR_WCHAR_FILESYSTEM
diff --git a/include/SAABoxCollider.h b/include/SAABoxCollider.h
index 128780e85..9aa175611 100644
--- a/include/SAABoxCollider.h
+++ b/include/SAABoxCollider.h
@@ -14,7 +14,7 @@ class SAABoxCollider
     public:
         SAABoxCollider(const aabbox3df& box) : Box(box) {}
 
-
+/**
         static inline void* operator new(size_t size) throw(std::bad_alloc)
         {
             void *memoryallocatedaligned = 0;
@@ -61,7 +61,7 @@ class SAABoxCollider
             return p;
         }
         static inline void  operator delete[](void* p,void* t) throw() {}
-
+*/
 
 
         inline bool CollideWithRay(float& collisionDistance, const vectorSIMDf& origin, const vectorSIMDf& direction, const float& dirMaxMultiplier, const vectorSIMDf& reciprocalDirection) const
diff --git a/include/SCompoundCollider.h b/include/SCompoundCollider.h
index 4e06444b4..2e1102036 100644
--- a/include/SCompoundCollider.h
+++ b/include/SCompoundCollider.h
@@ -76,7 +76,7 @@ class SCompoundCollider : public IReferenceCounted
             }
         }
 
-
+/**
         static inline void* operator new(size_t size) throw(std::bad_alloc)
         {
             void *memoryallocatedaligned = 0;
@@ -123,7 +123,7 @@ class SCompoundCollider : public IReferenceCounted
             return p;
         }
         static inline void  operator delete[](void* p,void* t) throw() {}
-
+**/
 
 
         inline SCompoundCollider* clone()
diff --git a/include/SEllipsoidCollider.h b/include/SEllipsoidCollider.h
index be45e4623..2b2ec2c60 100644
--- a/include/SEllipsoidCollider.h
+++ b/include/SEllipsoidCollider.h
@@ -29,7 +29,7 @@ class SEllipsoidCollider
             validEllipse = true;
         }
 
-
+/**
         static inline void* operator new(size_t size) throw(std::bad_alloc)
         {
             void *memoryallocatedaligned = 0;
@@ -76,7 +76,7 @@ class SEllipsoidCollider
             return p;
         }
         static inline void  operator delete[](void* p,void* t) throw() {}
-
+**/
 
         inline bool CollideWithRay(float& collisionDistance, vectorSIMDf origin, vectorSIMDf direction, const float& dirMaxMultiplier) const
         {
diff --git a/include/STriangleMeshCollider.h b/include/STriangleMeshCollider.h
index e7ce5dc8a..f72bf3b57 100644
--- a/include/STriangleMeshCollider.h
+++ b/include/STriangleMeshCollider.h
@@ -30,7 +30,7 @@ class STriangleCollider
             validTriangle = true;
         }
 
-
+/**
         static inline void* operator new(size_t size) throw(std::bad_alloc)
         {
             void *memoryallocatedaligned = 0;
@@ -77,7 +77,7 @@ class STriangleCollider
             return p;
         }
         static inline void  operator delete[](void* p,void* t) throw() {}
-
+**/
 
         inline bool CollideWithRay(float& collisionDistance, const vectorSIMDf& origin, const vectorSIMDf& direction, const float& dirMaxMultiplier) const
         {
@@ -120,7 +120,7 @@ class STriangleMeshCollider : public IReferenceCounted
         STriangleMeshCollider() : BBox(core::aabbox3df()) {}
         ~STriangleMeshCollider() {}
 
-
+/**
         static inline void* operator new(size_t size) throw(std::bad_alloc)
         {
             void *memoryallocatedaligned = 0;
@@ -167,6 +167,7 @@ class STriangleMeshCollider : public IReferenceCounted
             return p;
         }
         static inline void  operator delete[](void* p,void* t) throw() {}
+**/
 
 
         inline const SAABoxCollider& getBoundingBox() const {return BBox;}
diff --git a/include/irrList.h b/include/irrList.h
deleted file mode 100644
index a02c0fb3a..000000000
--- a/include/irrList.h
+++ /dev/null
@@ -1,416 +0,0 @@
-// Copyright (C) 2002-2012 Nikolaus Gebhardt
-// This file is part of the "Irrlicht Engine".
-// For conditions of distribution and use, see copyright notice in irrlicht.h
-
-#ifndef __IRR_LIST_H_INCLUDED__
-#define __IRR_LIST_H_INCLUDED__
-
-#include "irrTypes.h"
-#include "irrAllocator.h"
-#include "irrMath.h"
-
-namespace irr
-{
-namespace core
-{
-
-
-//! Doubly linked list template.
-template <class T>
-class list
-{
-private:
-
-	//! List element node with pointer to previous and next element in the list.
-	struct SKListNode
-	{
-		SKListNode(const T& e) : Next(0), Prev(0), Element(e) {}
-
-		SKListNode* Next;
-		SKListNode* Prev;
-		T Element;
-	};
-
-public:
-	class ConstIterator;
-
-	//! List iterator.
-	class Iterator
-	{
-	public:
-		Iterator() : Current(0) {}
-
-		Iterator& operator ++()    { Current = Current->Next; return *this; }
-		Iterator& operator --()    { Current = Current->Prev; return *this; }
-		Iterator  operator ++(int32_t) { Iterator tmp = *this; Current = Current->Next; return tmp; }
-		Iterator  operator --(int32_t) { Iterator tmp = *this; Current = Current->Prev; return tmp; }
-
-		Iterator& operator +=(int32_t num)
-		{
-			if(num > 0)
-			{
-				while (num-- && this->Current != 0) ++(*this);
-			}
-			else
-			{
-				while(num++ && this->Current != 0) --(*this);
-			}
-			return *this;
-		}
-
-		Iterator  operator + (int32_t num) const { Iterator tmp = *this; return tmp += num; }
-		Iterator& operator -=(int32_t num) { return (*this)+=(-num); }
-		Iterator  operator - (int32_t num) const { return (*this)+ (-num); }
-
-		bool operator ==(const Iterator&      other) const { return Current == other.Current; }
-		bool operator !=(const Iterator&      other) const { return Current != other.Current; }
-		bool operator ==(const ConstIterator& other) const { return Current == other.Current; }
-		bool operator !=(const ConstIterator& other) const { return Current != other.Current; }
-
-		#if defined (_MSC_VER) && (_MSC_VER < 1300)
-			#pragma warning(disable:4284) // infix notation problem when using iterator operator ->
-		#endif
-
-		T & operator * () { return Current->Element; }
-		T * operator ->() { return &Current->Element; }
-
-	private:
-		explicit Iterator(SKListNode* begin) : Current(begin) {}
-
-		SKListNode* Current;
-
-		friend class list<T>;
-		friend class ConstIterator;
-	};
-
-	//! List iterator for const access.
-	class ConstIterator
-	{
-	public:
-
-		ConstIterator() : Current(0) {}
-		ConstIterator(const Iterator& iter) : Current(iter.Current)  {}
-
-		ConstIterator& operator ++()    { Current = Current->Next; return *this; }
-		ConstIterator& operator --()    { Current = Current->Prev; return *this; }
-		ConstIterator  operator ++(int32_t) { ConstIterator tmp = *this; Current = Current->Next; return tmp; }
-		ConstIterator  operator --(int32_t) { ConstIterator tmp = *this; Current = Current->Prev; return tmp; }
-
-		ConstIterator& operator +=(int32_t num)
-		{
-			if(num > 0)
-			{
-				while(num-- && this->Current != 0) ++(*this);
-			}
-			else
-			{
-				while(num++ && this->Current != 0) --(*this);
-			}
-			return *this;
-		}
-
-		ConstIterator  operator + (int32_t num) const { ConstIterator tmp = *this; return tmp += num; }
-		ConstIterator& operator -=(int32_t num) { return (*this)+=(-num); }
-		ConstIterator  operator - (int32_t num) const { return (*this)+ (-num); }
-
-		bool operator ==(const ConstIterator& other) const { return Current == other.Current; }
-		bool operator !=(const ConstIterator& other) const { return Current != other.Current; }
-		bool operator ==(const Iterator&      other) const { return Current == other.Current; }
-		bool operator !=(const Iterator&      other) const { return Current != other.Current; }
-
-		const T & operator * () const { return Current->Element; }
-		const T * operator ->() const { return &Current->Element; }
-
-		ConstIterator & operator =(const Iterator & iterator) { Current = iterator.Current; return *this; }
-
-	private:
-		explicit ConstIterator(SKListNode* begin) : Current(begin) {}
-
-		SKListNode* Current;
-
-		friend class Iterator;
-		friend class list<T>;
-	};
-
-	//! Default constructor for empty list.
-	list()
-		: First(0), Last(0), Size(0) {}
-
-
-	//! Copy constructor.
-	list(const list<T>& other) : First(0), Last(0), Size(0)
-	{
-		*this = other;
-	}
-
-
-	//! Destructor
-	~list()
-	{
-		clear();
-	}
-
-
-	//! Assignment operator
-	void operator=(const list<T>& other)
-	{
-		if(&other == this)
-		{
-			return;
-		}
-
-		clear();
-
-		SKListNode* node = other.First;
-		while(node)
-		{
-			push_back(node->Element);
-			node = node->Next;
-		}
-	}
-
-
-	//! Returns amount of elements in list.
-	/** \return Amount of elements in the list. */
-	uint32_t size() const
-	{
-		return Size;
-	}
-	uint32_t getSize() const
-	{
-		return Size;
-	}
-
-
-	//! Clears the list, deletes all elements in the list.
-	/** All existing iterators of this list will be invalid. */
-	void clear()
-	{
-		while(First)
-		{
-			SKListNode * next = First->Next;
-			allocator.destruct(First);
-			allocator.deallocate(First);
-			First = next;
-		}
-
-		//First = 0; handled by loop
-		Last = 0;
-		Size = 0;
-	}
-
-
-	//! Checks for empty list.
-	/** \return True if the list is empty and false if not. */
-	bool empty() const
-	{
-		return (First == 0);
-	}
-
-
-	//! Adds an element at the end of the list.
-	/** \param element Element to add to the list. */
-	void push_back(const T& element)
-	{
-		SKListNode* node = allocator.allocate(1);
-		allocator.construct(node, element);
-
-		++Size;
-
-		if (First == 0)
-			First = node;
-
-		node->Prev = Last;
-
-		if (Last != 0)
-			Last->Next = node;
-
-		Last = node;
-	}
-
-
-	//! Adds an element at the begin of the list.
-	/** \param element: Element to add to the list. */
-	void push_front(const T& element)
-	{
-		SKListNode* node = allocator.allocate(1);
-		allocator.construct(node, element);
-
-		++Size;
-
-		if (First == 0)
-		{
-			Last = node;
-			First = node;
-		}
-		else
-		{
-			node->Next = First;
-			First->Prev = node;
-			First = node;
-		}
-	}
-
-
-	//! Gets first node.
-	/** \return A list iterator pointing to the beginning of the list. */
-	Iterator begin()
-	{
-		return Iterator(First);
-	}
-
-
-	//! Gets first node.
-	/** \return A const list iterator pointing to the beginning of the list. */
-	ConstIterator begin() const
-	{
-		return ConstIterator(First);
-	}
-
-
-	//! Gets end node.
-	/** \return List iterator pointing to null. */
-	Iterator end()
-	{
-		return Iterator(0);
-	}
-
-
-	//! Gets end node.
-	/** \return Const list iterator pointing to null. */
-	ConstIterator end() const
-	{
-		return ConstIterator(0);
-	}
-
-
-	//! Gets last element.
-	/** \return List iterator pointing to the last element of the list. */
-	Iterator getLast()
-	{
-		return Iterator(Last);
-	}
-
-
-	//! Gets last element.
-	/** \return Const list iterator pointing to the last element of the list. */
-	ConstIterator getLast() const
-	{
-		return ConstIterator(Last);
-	}
-
-
-	//! Inserts an element after an element.
-	/** \param it Iterator pointing to element after which the new element
-	should be inserted.
-	\param element The new element to be inserted into the list.
-	*/
-	void insert_after(const Iterator& it, const T& element)
-	{
-		SKListNode* node = allocator.allocate(1);
-		allocator.construct(node, element);
-
-		node->Next = it.Current->Next;
-
-		if (it.Current->Next)
-			it.Current->Next->Prev = node;
-
-		node->Prev = it.Current;
-		it.Current->Next = node;
-		++Size;
-
-		if (it.Current == Last)
-			Last = node;
-	}
-
-
-	//! Inserts an element before an element.
-	/** \param it Iterator pointing to element before which the new element
-	should be inserted.
-	\param element The new element to be inserted into the list.
-	*/
-	void insert_before(const Iterator& it, const T& element)
-	{
-		SKListNode* node = allocator.allocate(1);
-		allocator.construct(node, element);
-
-		node->Prev = it.Current->Prev;
-
-		if (it.Current->Prev)
-			it.Current->Prev->Next = node;
-
-		node->Next = it.Current;
-		it.Current->Prev = node;
-		++Size;
-
-		if (it.Current == First)
-			First = node;
-	}
-
-
-	//! Erases an element.
-	/** \param it Iterator pointing to the element which shall be erased.
-	\return Iterator pointing to next element. */
-	Iterator erase(Iterator& it)
-	{
-		// suggest changing this to a const Iterator& and
-		// working around line: it.Current = 0 (possibly with a mutable, or just let it be garbage?)
-
-		Iterator returnIterator(it);
-		++returnIterator;
-
-		if(it.Current == First)
-		{
-			First = it.Current->Next;
-		}
-		else
-		{
-			it.Current->Prev->Next = it.Current->Next;
-		}
-
-		if(it.Current == Last)
-		{
-			Last = it.Current->Prev;
-		}
-		else
-		{
-			it.Current->Next->Prev = it.Current->Prev;
-		}
-
-		allocator.destruct(it.Current);
-		allocator.deallocate(it.Current);
-		it.Current = 0;
-		--Size;
-
-		return returnIterator;
-	}
-
-	//! Swap the content of this list container with the content of another list
-	/** Afterwards this object will contain the content of the other object and the other
-	object will contain the content of this object. Iterators will afterwards be valid for
-	the swapped object.
-	\param other Swap content with this object	*/
-	void swap(list<T>& other)
-	{
-		core::swap(First, other.First);
-		core::swap(Last, other.Last);
-		core::swap(Size, other.Size);
-		core::swap(allocator, other.allocator);	// memory is still released by the same allocator used for allocation
-	}
-
-
-private:
-
-	SKListNode* First;
-	SKListNode* Last;
-	uint32_t Size;
-	irrAllocator<SKListNode> allocator;
-
-};
-
-
-} // end namespace core
-}// end namespace irr
-
-#endif
-
diff --git a/include/irrMap.h b/include/irrMap.h
deleted file mode 100644
index 3aee68d1d..000000000
--- a/include/irrMap.h
+++ /dev/null
@@ -1,1109 +0,0 @@
-// Copyright (C) 2006-2012 by Kat'Oun
-// This file is part of the "Irrlicht Engine".
-// For conditions of distribution and use, see copyright notice in irrlicht.h
-
-#ifndef __IRR_MAP_H_INCLUDED__
-#define __IRR_MAP_H_INCLUDED__
-
-#include "irrTypes.h"
-#include "irrMath.h"
-
-namespace irr
-{
-namespace core
-{
-
-//! map template for associative arrays using a red-black tree
-template <class KeyType, class ValueType>
-class map
-{
-	//! red/black tree for map
-	template <class KeyTypeRB, class ValueTypeRB>
-	class RBTree
-	{
-	public:
-
-		RBTree(const KeyTypeRB& k, const ValueTypeRB& v)
-			: LeftChild(0), RightChild(0), Parent(0), Key(k),
-				Value(v), IsRed(true) {}
-
-		void setLeftChild(RBTree* p)
-		{
-			LeftChild=p;
-			if (p)
-				p->setParent(this);
-		}
-
-		void setRightChild(RBTree* p)
-		{
-			RightChild=p;
-			if (p)
-				p->setParent(this);
-		}
-
-		void setParent(RBTree* p)		{ Parent=p; }
-
-		void setValue(const ValueTypeRB& v)	{ Value = v; }
-
-		void setRed()			{ IsRed = true; }
-		void setBlack()			{ IsRed = false; }
-
-		RBTree* getLeftChild() const	{ return LeftChild; }
-		RBTree* getRightChild() const	{ return RightChild; }
-		RBTree* getParent() const		{ return Parent; }
-
-		const ValueTypeRB& getValue() const
-		{
-			return Value;
-		}
-
-		ValueTypeRB& getValue()
-		{
-			return Value;
-		}
-
-		const KeyTypeRB& getKey() const
-		{
-			return Key;
-		}
-
-		bool isRoot() const
-		{
-			return Parent==0;
-		}
-
-		bool isLeftChild() const
-		{
-			return (Parent != 0) && (Parent->getLeftChild()==this);
-		}
-
-		bool isRightChild() const
-		{
-			return (Parent!=0) && (Parent->getRightChild()==this);
-		}
-
-		bool isLeaf() const
-		{
-			return (LeftChild==0) && (RightChild==0);
-		}
-
-		unsigned int getLevel() const
-		{
-			if (isRoot())
-				return 1;
-			else
-				return getParent()->getLevel() + 1;
-		}
-
-
-		bool isRed() const
-		{
-			return IsRed;
-		}
-
-		bool isBlack() const
-		{
-			return !IsRed;
-		}
-
-	private:
-		RBTree();
-
-		RBTree*		LeftChild;
-		RBTree*		RightChild;
-
-		RBTree*		Parent;
-
-		KeyTypeRB	Key;
-		ValueTypeRB	Value;
-
-		bool IsRed;
-	}; // RBTree
-
-	public:
-
-	typedef RBTree<KeyType,ValueType> Node;
-	// We need the forwad declaration for the friend declaration
-	class ConstIterator;
-
-	//! Normal Iterator
-	class Iterator
-	{
-		friend class ConstIterator;
-	public:
-
-		Iterator() : Root(0), Cur(0) {}
-
-		// Constructor(Node*)
-		Iterator(Node* root) : Root(root)
-		{
-			reset();
-		}
-
-		// Copy constructor
-		Iterator(const Iterator& src) : Root(src.Root), Cur(src.Cur) {}
-
-		void reset(bool atLowest=true)
-		{
-			if (atLowest)
-				Cur = getMin(Root);
-			else
-				Cur = getMax(Root);
-		}
-
-		bool atEnd() const
-		{
-			return Cur==0;
-		}
-
-		Node* getNode() const
-		{
-			return Cur;
-		}
-
-		Iterator& operator=(const Iterator& src)
-		{
-			Root = src.Root;
-			Cur = src.Cur;
-			return (*this);
-		}
-
-		void operator++(int)
-		{
-			inc();
-		}
-
-		void operator--(int)
-		{
-			dec();
-		}
-
-		Node* operator->()
-		{
-			return getNode();
-		}
-
-		Node& operator*()
-		{
-			_IRR_DEBUG_BREAK_IF(atEnd()) // access violation
-
-			return *Cur;
-		}
-
-	private:
-
-		Node* getMin(Node* n) const
-		{
-			while(n && n->getLeftChild())
-				n = n->getLeftChild();
-			return n;
-		}
-
-		Node* getMax(Node* n) const
-		{
-			while(n && n->getRightChild())
-				n = n->getRightChild();
-			return n;
-		}
-
-		void inc()
-		{
-			// Already at end?
-			if (Cur==0)
-				return;
-
-			if (Cur->getRightChild())
-			{
-				// If current node has a right child, the next higher node is the
-				// node with lowest key beneath the right child.
-				Cur = getMin(Cur->getRightChild());
-			}
-			else if (Cur->isLeftChild())
-			{
-				// No right child? Well if current node is a left child then
-				// the next higher node is the parent
-				Cur = Cur->getParent();
-			}
-			else
-			{
-				// Current node neither is left child nor has a right child.
-				// Ie it is either right child or root
-				// The next higher node is the parent of the first non-right
-				// child (ie either a left child or the root) up in the
-				// hierarchy. Root's parent is 0.
-				while(Cur->isRightChild())
-					Cur = Cur->getParent();
-				Cur = Cur->getParent();
-			}
-		}
-
-		void dec()
-		{
-			// Already at end?
-			if (Cur==0)
-				return;
-
-			if (Cur->getLeftChild())
-			{
-				// If current node has a left child, the next lower node is the
-				// node with highest key beneath the left child.
-				Cur = getMax(Cur->getLeftChild());
-			}
-			else if (Cur->isRightChild())
-			{
-				// No left child? Well if current node is a right child then
-				// the next lower node is the parent
-				Cur = Cur->getParent();
-			}
-			else
-			{
-				// Current node neither is right child nor has a left child.
-				// Ie it is either left child or root
-				// The next higher node is the parent of the first non-left
-				// child (ie either a right child or the root) up in the
-				// hierarchy. Root's parent is 0.
-
-				while(Cur->isLeftChild())
-					Cur = Cur->getParent();
-				Cur = Cur->getParent();
-			}
-		}
-
-		Node* Root;
-		Node* Cur;
-	}; // Iterator
-
-	//! Const Iterator
-	class ConstIterator
-	{
-		friend class Iterator;
-	public:
-
-		ConstIterator() : Root(0), Cur(0) {}
-
-		// Constructor(Node*)
-		ConstIterator(const Node* root) : Root(root)
-		{
-			reset();
-		}
-
-		// Copy constructor
-		ConstIterator(const ConstIterator& src) : Root(src.Root), Cur(src.Cur) {}
-		ConstIterator(const Iterator& src) : Root(src.Root), Cur(src.Cur) {}
-
-		void reset(bool atLowest=true)
-		{
-			if (atLowest)
-				Cur = getMin(Root);
-			else
-				Cur = getMax(Root);
-		}
-
-		bool atEnd() const
-		{
-			return Cur==0;
-		}
-
-		const Node* getNode() const
-		{
-			return Cur;
-		}
-
-		ConstIterator& operator=(const ConstIterator& src)
-		{
-			Root = src.Root;
-			Cur = src.Cur;
-			return (*this);
-		}
-
-		void operator++(int)
-		{
-			inc();
-		}
-
-		void operator--(int)
-		{
-			dec();
-		}
-
-		const Node* operator->()
-		{
-			return getNode();
-		}
-
-		const Node& operator*()
-		{
-			_IRR_DEBUG_BREAK_IF(atEnd()) // access violation
-
-			return *Cur;
-		}
-
-	private:
-
-		const Node* getMin(const Node* n) const
-		{
-			while(n && n->getLeftChild())
-				n = n->getLeftChild();
-			return n;
-		}
-
-		const Node* getMax(const Node* n) const
-		{
-			while(n && n->getRightChild())
-				n = n->getRightChild();
-			return n;
-		}
-
-		void inc()
-		{
-			// Already at end?
-			if (Cur==0)
-				return;
-
-			if (Cur->getRightChild())
-			{
-				// If current node has a right child, the next higher node is the
-				// node with lowest key beneath the right child.
-				Cur = getMin(Cur->getRightChild());
-			}
-			else if (Cur->isLeftChild())
-			{
-				// No right child? Well if current node is a left child then
-				// the next higher node is the parent
-				Cur = Cur->getParent();
-			}
-			else
-			{
-				// Current node neither is left child nor has a right child.
-				// Ie it is either right child or root
-				// The next higher node is the parent of the first non-right
-				// child (ie either a left child or the root) up in the
-				// hierarchy. Root's parent is 0.
-				while(Cur->isRightChild())
-					Cur = Cur->getParent();
-				Cur = Cur->getParent();
-			}
-		}
-
-		void dec()
-		{
-			// Already at end?
-			if (Cur==0)
-				return;
-
-			if (Cur->getLeftChild())
-			{
-				// If current node has a left child, the next lower node is the
-				// node with highest key beneath the left child.
-				Cur = getMax(Cur->getLeftChild());
-			}
-			else if (Cur->isRightChild())
-			{
-				// No left child? Well if current node is a right child then
-				// the next lower node is the parent
-				Cur = Cur->getParent();
-			}
-			else
-			{
-				// Current node neither is right child nor has a left child.
-				// Ie it is either left child or root
-				// The next higher node is the parent of the first non-left
-				// child (ie either a right child or the root) up in the
-				// hierarchy. Root's parent is 0.
-
-				while(Cur->isLeftChild())
-					Cur = Cur->getParent();
-				Cur = Cur->getParent();
-			}
-		}
-
-		const Node* Root;
-		const Node* Cur;
-	}; // ConstIterator
-
-
-	//! Parent First Iterator.
-	/** Traverses the tree from top to bottom. Typical usage is
-	when storing the tree structure, because when reading it
-	later (and inserting elements) the tree structure will
-	be the same. */
-	class ParentFirstIterator
-	{
-	public:
-
-	ParentFirstIterator() : Root(0), Cur(0)	{}
-
-	explicit ParentFirstIterator(Node* root) : Root(root), Cur(0)
-	{
-		reset();
-	}
-
-	void reset()
-	{
-		Cur = Root;
-	}
-
-	bool atEnd() const
-	{
-		return Cur==0;
-	}
-
-	Node* getNode()
-	{
-		return Cur;
-	}
-
-	ParentFirstIterator& operator=(const ParentFirstIterator& src)
-	{
-		Root = src.Root;
-		Cur = src.Cur;
-		return (*this);
-	}
-
-	void operator++(int)
-	{
-		inc();
-	}
-
-	Node* operator -> ()
-	{
-		return getNode();
-	}
-
-	Node& operator* ()
-	{
-		_IRR_DEBUG_BREAK_IF(atEnd()) // access violation
-
-		return *getNode();
-	}
-
-	private:
-
-	void inc()
-	{
-		// Already at end?
-		if (Cur==0)
-			return;
-
-		// First we try down to the left
-		if (Cur->getLeftChild())
-		{
-			Cur = Cur->getLeftChild();
-		}
-		else if (Cur->getRightChild())
-		{
-			// No left child? The we go down to the right.
-			Cur = Cur->getRightChild();
-		}
-		else
-		{
-			// No children? Move up in the hierarcy until
-			// we either reach 0 (and are finished) or
-			// find a right uncle.
-			while (Cur!=0)
-			{
-				// But if parent is left child and has a right "uncle" the parent
-				// has already been processed but the uncle hasn't. Move to
-				// the uncle.
-				if (Cur->isLeftChild() && Cur->getParent()->getRightChild())
-				{
-					Cur = Cur->getParent()->getRightChild();
-					return;
-				}
-				Cur = Cur->getParent();
-			}
-		}
-	}
-
-	Node* Root;
-	Node* Cur;
-
-	}; // ParentFirstIterator
-
-
-	//! Parent Last Iterator
-	/** Traverse the tree from bottom to top.
-	Typical usage is when deleting all elements in the tree
-	because you must delete the children before you delete
-	their parent. */
-	class ParentLastIterator
-	{
-	public:
-
-		ParentLastIterator() : Root(0), Cur(0) {}
-
-		explicit ParentLastIterator(Node* root) : Root(root), Cur(0)
-		{
-			reset();
-		}
-
-		void reset()
-		{
-			Cur = getMin(Root);
-		}
-
-		bool atEnd() const
-		{
-			return Cur==0;
-		}
-
-		Node* getNode()
-		{
-			return Cur;
-		}
-
-		ParentLastIterator& operator=(const ParentLastIterator& src)
-		{
-			Root = src.Root;
-			Cur = src.Cur;
-			return (*this);
-		}
-
-		void operator++(int)
-		{
-			inc();
-		}
-
-		Node* operator -> ()
-		{
-			return getNode();
-		}
-
-		Node& operator* ()
-		{
-			_IRR_DEBUG_BREAK_IF(atEnd()) // access violation
-
-			return *getNode();
-		}
-	private:
-
-		Node* getMin(Node* n)
-		{
-			while(n!=0 && (n->getLeftChild()!=0 || n->getRightChild()!=0))
-			{
-				if (n->getLeftChild())
-					n = n->getLeftChild();
-				else
-					n = n->getRightChild();
-			}
-			return n;
-		}
-
-		void inc()
-		{
-			// Already at end?
-			if (Cur==0)
-				return;
-
-			// Note: Starting point is the node as far down to the left as possible.
-
-			// If current node has an uncle to the right, go to the
-			// node as far down to the left from the uncle as possible
-			// else just go up a level to the parent.
-			if (Cur->isLeftChild() && Cur->getParent()->getRightChild())
-			{
-				Cur = getMin(Cur->getParent()->getRightChild());
-			}
-			else
-				Cur = Cur->getParent();
-		}
-
-		Node* Root;
-		Node* Cur;
-	}; // ParentLastIterator
-
-
-	// AccessClass is a temporary class used with the [] operator.
-	// It makes it possible to have different behavior in situations like:
-	// myTree["Foo"] = 32;
-	// If "Foo" already exists update its value else insert a new element.
-	// int i = myTree["Foo"]
-	// If "Foo" exists return its value.
-	class AccessClass
-	{
-		// Let map be the only one who can instantiate this class.
-		friend class map<KeyType, ValueType>;
-
-	public:
-
-		// Assignment operator. Handles the myTree["Foo"] = 32; situation
-		void operator=(const ValueType& value)
-		{
-			// Just use the Set method, it handles already exist/not exist situation
-			Tree.set(Key,value);
-		}
-
-		// ValueType operator
-		operator ValueType()
-		{
-			Node* node = Tree.find(Key);
-
-			// Not found
-			_IRR_DEBUG_BREAK_IF(node==0) // access violation
-
-			return node->getValue();
-		}
-
-	private:
-
-		AccessClass(map& tree, const KeyType& key) : Tree(tree), Key(key) {}
-
-		AccessClass();
-
-		map& Tree;
-		const KeyType& Key;
-	}; // AccessClass
-
-
-	// Constructor.
-	map() : Root(0), Size(0) {}
-
-	// Destructor
-	~map()
-	{
-		clear();
-	}
-
-	//------------------------------
-	// Public Commands
-	//------------------------------
-
-	//! Inserts a new node into the tree
-	/** \param keyNew: the index for this value
-	\param v: the value to insert
-	\return True if successful, false if it fails (already exists) */
-	bool insert(const KeyType& keyNew, const ValueType& v)
-	{
-		// First insert node the "usual" way (no fancy balance logic yet)
-		Node* newNode = new Node(keyNew,v);
-		if (!insert(newNode))
-		{
-			delete newNode;
-			return false;
-		}
-
-		// Then attend a balancing party
-		while (!newNode->isRoot() && (newNode->getParent()->isRed()))
-		{
-			if (newNode->getParent()->isLeftChild())
-			{
-				// If newNode is a left child, get its right 'uncle'
-				Node* newNodesUncle = newNode->getParent()->getParent()->getRightChild();
-				if ( newNodesUncle!=0 && newNodesUncle->isRed())
-				{
-					// case 1 - change the colors
-					newNode->getParent()->setBlack();
-					newNodesUncle->setBlack();
-					newNode->getParent()->getParent()->setRed();
-					// Move newNode up the tree
-					newNode = newNode->getParent()->getParent();
-				}
-				else
-				{
-					// newNodesUncle is a black node
-					if ( newNode->isRightChild())
-					{
-						// and newNode is to the right
-						// case 2 - move newNode up and rotate
-						newNode = newNode->getParent();
-						rotateLeft(newNode);
-					}
-					// case 3
-					newNode->getParent()->setBlack();
-					newNode->getParent()->getParent()->setRed();
-					rotateRight(newNode->getParent()->getParent());
-				}
-			}
-			else
-			{
-				// If newNode is a right child, get its left 'uncle'
-				Node* newNodesUncle = newNode->getParent()->getParent()->getLeftChild();
-				if ( newNodesUncle!=0 && newNodesUncle->isRed())
-				{
-					// case 1 - change the colors
-					newNode->getParent()->setBlack();
-					newNodesUncle->setBlack();
-					newNode->getParent()->getParent()->setRed();
-					// Move newNode up the tree
-					newNode = newNode->getParent()->getParent();
-				}
-				else
-				{
-					// newNodesUncle is a black node
-					if (newNode->isLeftChild())
-					{
-						// and newNode is to the left
-						// case 2 - move newNode up and rotate
-						newNode = newNode->getParent();
-						rotateRight(newNode);
-					}
-					// case 3
-					newNode->getParent()->setBlack();
-					newNode->getParent()->getParent()->setRed();
-					rotateLeft(newNode->getParent()->getParent());
-				}
-
-			}
-		}
-		// Color the root black
-		Root->setBlack();
-		return true;
-	}
-
-	//! Replaces the value if the key already exists, otherwise inserts a new element.
-	/** \param k The index for this value
-	\param v The new value of */
-	void set(const KeyType& k, const ValueType& v)
-	{
-		Node* p = find(k);
-		if (p)
-			p->setValue(v);
-		else
-			insert(k,v);
-	}
-
-	//! Removes a node from the tree and returns it.
-	/** The returned node must be deleted by the user
-	\param k the key to remove
-	\return A pointer to the node, or 0 if not found */
-	Node* delink(const KeyType& k)
-	{
-		Node* p = find(k);
-		if (p == 0)
-			return 0;
-
-		// Rotate p down to the left until it has no right child, will get there
-		// sooner or later.
-		while(p->getRightChild())
-		{
-			// "Pull up my right child and let it knock me down to the left"
-			rotateLeft(p);
-		}
-		// p now has no right child but might have a left child
-		Node* left = p->getLeftChild();
-
-		// Let p's parent point to p's child instead of point to p
-		if (p->isLeftChild())
-			p->getParent()->setLeftChild(left);
-
-		else if (p->isRightChild())
-			p->getParent()->setRightChild(left);
-
-		else
-		{
-			// p has no parent => p is the root.
-			// Let the left child be the new root.
-			setRoot(left);
-		}
-
-		// p is now gone from the tree in the sense that
-		// no one is pointing at it, so return it.
-
-		--Size;
-		return p;
-	}
-
-	//! Removes a node from the tree and deletes it.
-	/** \return True if the node was found and deleted */
-	bool remove(const KeyType& k)
-	{
-		Node* p = find(k);
-		return remove(p);
-	}
-
-	//! Removes a node from the tree and deletes it.
-	/** \return True if the node was found and deleted */
-	bool remove(Node* p)
-	{
-		if (p == 0)
-		{
-			return false;
-		}
-
-		// Rotate p down to the left until it has no right child, will get there
-		// sooner or later.
-		while(p->getRightChild())
-		{
-			// "Pull up my right child and let it knock me down to the left"
-			rotateLeft(p);
-		}
-		// p now has no right child but might have a left child
-		Node* left = p->getLeftChild();
-
-		// Let p's parent point to p's child instead of point to p
-		if (p->isLeftChild())
-			p->getParent()->setLeftChild(left);
-
-		else if (p->isRightChild())
-			p->getParent()->setRightChild(left);
-
-		else
-		{
-			// p has no parent => p is the root.
-			// Let the left child be the new root.
-			setRoot(left);
-		}
-
-		// p is now gone from the tree in the sense that
-		// no one is pointing at it. Let's get rid of it.
-		delete p;
-
-		--Size;
-		return true;
-	}
-
-	//! Clear the entire tree
-	void clear()
-	{
-		ParentLastIterator i(getParentLastIterator());
-
-		while(!i.atEnd())
-		{
-			Node* p = i.getNode();
-			i++; // Increment it before it is deleted
-				// else iterator will get quite confused.
-			delete p;
-		}
-		Root = 0;
-		Size= 0;
-	}
-
-	//! Is the tree empty?
-	//! \return Returns true if empty, false if not
-	bool empty() const
-	{
-		return Root == 0;
-	}
-
-	//! \deprecated Use empty() instead. This method may be removed by Irrlicht 1.9
-	_IRR_DEPRECATED_ bool isEmpty() const
-	{
-		return empty();
-	}
-
-	//! Search for a node with the specified key.
-	//! \param keyToFind: The key to find
-	//! \return Returns 0 if node couldn't be found.
-	Node* find(const KeyType& keyToFind) const
-	{
-		Node* pNode = Root;
-
-		while(pNode!=0)
-		{
-			const KeyType& key=pNode->getKey();
-
-			if (keyToFind == key)
-				return pNode;
-			else if (keyToFind < key)
-				pNode = pNode->getLeftChild();
-			else //keyToFind > key
-				pNode = pNode->getRightChild();
-		}
-
-		return 0;
-	}
-
-	//! Gets the root element.
-	//! \return Returns a pointer to the root node, or
-	//! 0 if the tree is empty.
-	Node* getRoot() const
-	{
-		return Root;
-	}
-
-	//! Returns the number of nodes in the tree.
-	uint32_t size() const
-	{
-		return Size;
-	}
-
-	//! Swap the content of this map container with the content of another map
-	/** Afterwards this object will contain the content of the other object and the other
-	object will contain the content of this object. Iterators will afterwards be valid for
-	the swapped object.
-	\param other Swap content with this object	*/
-	void swap(map<KeyType, ValueType>& other)
-	{
-		core::swap(Root, other.Root);
-		core::swap(Size, other.Size);
-	}
-
-	//------------------------------
-	// Public Iterators
-	//------------------------------
-
-	//! Returns an iterator
-	Iterator getIterator() const
-	{
-		Iterator it(getRoot());
-		return it;
-	}
-
-	//! Returns a Constiterator
-	ConstIterator getConstIterator() const
-	{
-		Iterator it(getRoot());
-		return it;
-	}
-
-	//! Returns a ParentFirstIterator.
-	//! Traverses the tree from top to bottom. Typical usage is
-	//! when storing the tree structure, because when reading it
-	//! later (and inserting elements) the tree structure will
-	//! be the same.
-	ParentFirstIterator getParentFirstIterator() const
-	{
-		ParentFirstIterator it(getRoot());
-		return it;
-	}
-
-	//! Returns a ParentLastIterator to traverse the tree from
-	//! bottom to top.
-	//! Typical usage is when deleting all elements in the tree
-	//! because you must delete the children before you delete
-	//! their parent.
-	ParentLastIterator getParentLastIterator() const
-	{
-		ParentLastIterator it(getRoot());
-		return it;
-	}
-
-	//------------------------------
-	// Public Operators
-	//------------------------------
-
-	//! operator [] for access to elements
-	/** for example myMap["key"] */
-	AccessClass operator[](const KeyType& k)
-	{
-		return AccessClass(*this, k);
-	}
-	private:
-
-	//------------------------------
-	// Disabled methods
-	//------------------------------
-	// Copy constructor and assignment operator deliberately
-	// defined but not implemented. The tree should never be
-	// copied, pass along references to it instead.
-	explicit map(const map& src);
-	map& operator = (const map& src);
-
-	//! Set node as new root.
-	/** The node will be set to black, otherwise core dumps may arise
-	(patch provided by rogerborg).
-	\param newRoot Node which will be the new root
-	*/
-	void setRoot(Node* newRoot)
-	{
-		Root = newRoot;
-		if (Root != 0)
-		{
-			Root->setParent(0);
-			Root->setBlack();
-		}
-	}
-
-	//! Insert a node into the tree without using any fancy balancing logic.
-	/** \return false if that key already exist in the tree. */
-	bool insert(Node* newNode)
-	{
-		bool result=true; // Assume success
-
-		if (Root==0)
-		{
-			setRoot(newNode);
-			Size = 1;
-		}
-		else
-		{
-			Node* pNode = Root;
-			const KeyType& keyNew = newNode->getKey();
-			while (pNode)
-			{
-				const KeyType& key=pNode->getKey();
-
-				if (keyNew == key)
-				{
-					result = false;
-					pNode = 0;
-				}
-				else if (keyNew < key)
-				{
-					if (pNode->getLeftChild() == 0)
-					{
-						pNode->setLeftChild(newNode);
-						pNode = 0;
-					}
-					else
-						pNode = pNode->getLeftChild();
-				}
-				else // keyNew > key
-				{
-					if (pNode->getRightChild()==0)
-					{
-						pNode->setRightChild(newNode);
-						pNode = 0;
-					}
-					else
-					{
-						pNode = pNode->getRightChild();
-					}
-				}
-			}
-
-			if (result)
-				++Size;
-		}
-
-		return result;
-	}
-
-	//! Rotate left.
-	//! Pull up node's right child and let it knock node down to the left
-	void rotateLeft(Node* p)
-	{
-		Node* right = p->getRightChild();
-
-		p->setRightChild(right->getLeftChild());
-
-		if (p->isLeftChild())
-			p->getParent()->setLeftChild(right);
-		else if (p->isRightChild())
-			p->getParent()->setRightChild(right);
-		else
-			setRoot(right);
-
-		right->setLeftChild(p);
-	}
-
-	//! Rotate right.
-	//! Pull up node's left child and let it knock node down to the right
-	void rotateRight(Node* p)
-	{
-		Node* left = p->getLeftChild();
-
-		p->setLeftChild(left->getRightChild());
-
-		if (p->isLeftChild())
-			p->getParent()->setLeftChild(left);
-		else if (p->isRightChild())
-			p->getParent()->setRightChild(left);
-		else
-			setRoot(left);
-
-		left->setRightChild(p);
-	}
-
-	//------------------------------
-	// Private Members
-	//------------------------------
-	Node* Root; // The top node. 0 if empty.
-	uint32_t Size; // Number of nodes in the tree
-};
-
-} // end namespace core
-} // end namespace irr
-
-#endif // __IRR_MAP_H_INCLUDED__
-
diff --git a/include/quaternion.h b/include/quaternion.h
index a98f35ebd..a2a4aadc3 100644
--- a/include/quaternion.h
+++ b/include/quaternion.h
@@ -30,6 +30,7 @@ Also useful for interpolations. */
 class quaternion : private vectorSIMDf
 {
 	public:
+/**
         static inline void* operator new(size_t size) throw(std::bad_alloc)
         {
             void *memoryallocatedaligned = 0;
@@ -76,7 +77,7 @@ class quaternion : private vectorSIMDf
             return p;
         }
         static inline void  operator delete[](void* p,void* t) throw() {}
-
+**/
 
 
 		//! Default Constructor
diff --git a/include/splines.h b/include/splines.h
index 6bfeca6e2..2479bed0e 100644
--- a/include/splines.h
+++ b/include/splines.h
@@ -1,907 +1,981 @@
 // Copyright (C) 2014 Mateusz 'DevSH' Kielan
-// This file is part of the "Irrlicht Engine".
+// This file is part of the "Irrlicht Engine".
 // Contributed from "Build a World"
 // For conditions of distribution and use, see copyright notice in irrlicht.h
 
 #ifndef __IRR_SPLINES_H_INCLUDED__
-#define __IRR_SPLINES_H_INCLUDED__
-
-#include "IrrCompileConfig.h"
-#include <cmath>       /* sqrt */
-#include "vectorSIMD.h"
-#include "irrArray.h"
-#include <vector>
-
-
-namespace irr
-{
-namespace core
-{
-
-
-class ISpline
-{
-    public:
-        virtual ~ISpline() {}
-
-        //
-        virtual bool        isLooping() const {return isLoop;}
-        virtual size_t      getSegmentCount() const = 0;
-        virtual float       getSplineLength() const = 0;
-
-        //
-        virtual void        getSegmentLengths(float* outSegLens) const = 0;
-        virtual float       getSegmentLength(const uint32_t& segmentID) const = 0;
-        virtual float       getSegmentParameterRange(const uint32_t& segmentID) const = 0;
-
-        //get position
-        //this function returns the id of the segment you might have moved into
-        virtual uint32_t    getPos(vectorSIMDf& pos, float& distanceAlongSeg, const uint32_t& segmentID, float* paramHint=NULL, const float& accuracyThresh=0.00390625f) const = 0;
-        virtual bool        getPos_fromParameter(vectorSIMDf& pos, const uint32_t& segmentID, const float& parameter) const = 0;
-
-        //to get direction to look in
-        virtual bool        getUnnormDirection(vectorSIMDf& tan, const uint32_t& segmentID, const float& distanceAlongSeg) const = 0;
-        virtual bool        getUnnormDirection_fromParameter(vectorSIMDf& tan, const uint32_t& segmentID, const float& parameter) const = 0;
-
-        //baw specific
-        virtual const bool      canGiveParameterUntilBlockChange() const {return false;}
-        // pass in current position
-        virtual float           getParameterUntilBlockChange(const uint32_t& segmentID, const float& param) = 0;
-        virtual std::vector<float>   getBlockChangesInSegment(const uint32_t& segmentID, float startParam=0.f) = 0;
-
-        //is the distance and parameter the same?
-        virtual bool            isArcLengthPrecise() const = 0;
-        virtual float           parameterToDistance(const float& param) const = 0;
-        virtual float           distanceToParameter(const float& dist) const = 0;
-    protected:
-        ISpline(bool loop) : isLoop(loop) {}
-
-        const bool isLoop;
-    private:
-};
-
-
-class CLinearSpline : public ISpline
-{
-    public:
-        CLinearSpline(vectorSIMDf* controlPoints, const size_t& count, const bool loop = false) : ISpline(loop)
-        {
-            //assert(count<0x80000000u && count);
-            for (size_t i=1; i<count; i++)
-                segments.push_back(Segment(controlPoints[i-1],controlPoints[i]));
-
-            if (isLoop)
-                segments.push_back(Segment(controlPoints[count-1],controlPoints[0]));
-            finalize();
-        }
-        CLinearSpline(vectorSIMDf* controlPoints, float* customDistances, const size_t& count, const bool loop = false) : ISpline(loop)
-        {
-            //assert(count<0x80000000u);
-            for (size_t i=1; i<count; i++)
-                segments.push_back(Segment(controlPoints[i-1],controlPoints[i],customDistances[i-1]));
-
-            if (isLoop)
-                segments.push_back(Segment(controlPoints[count-1],controlPoints[0],customDistances[count-1]));
-            finalize();
-        }
-
-        //
-        virtual size_t      getSegmentCount() const
-        {
-            return segments.size();
-        }
-        virtual float       getSplineLength() const
-        {
-            return splineLen;
-        }
-
-        //
-        virtual void        getSegmentLengths(float* outSegLens) const
-        {
-            for (size_t i=0; i<segments.size(); i++)
-                outSegLens[i] = segments[i].length;
-        }
-        virtual float       getSegmentLength(const uint32_t& segmentID) const
-        {
-            //assert(segmentID<segments.size());
-            return segments[segmentID].length;
-        }
-        virtual float       getSegmentParameterRange(const uint32_t& segmentID) const
-        {
-            return getSegmentLength(segmentID);
-        }
-
-        //get position
-        //this function returns the id of the segment you might have moved into - 0xdeadbeefu is an error code
-        virtual uint32_t    getPos(vectorSIMDf& pos, float& distanceAlongSeg, const uint32_t& segmentID, float* paramHint=NULL, const float& accuracyThresh=0.00390625f) const
-        {
-            if (distanceAlongSeg<0.f)
-                return 0xdeadbeefu;
-
-            uint32_t actualSeg;
-            if (isLoop)
-            {
-                actualSeg = segmentID%segments.size();
-                while (distanceAlongSeg>=segments[actualSeg].length)
-                {
-                    distanceAlongSeg -= segments[actualSeg].length;
-                    actualSeg++;
-                    if (actualSeg==segments.size())
-                        actualSeg = 0;
-                }
-            }
-            else
-            {
-                if (segmentID>=segments.size())
-                    return 0xdeadbeefu;
-
-                actualSeg = segmentID;
-                while (distanceAlongSeg>=segments[actualSeg].length)
-                {
-                    distanceAlongSeg -= segments[actualSeg].length;
-                    actualSeg++;
-                    if (actualSeg==segments.size())
-                        return 0xdeadbeefu;
-                }
-            }
-
-            pos = segments[actualSeg].posHelper(distanceAlongSeg);
-            if (paramHint)
-                *paramHint = distanceAlongSeg;
-
-            return actualSeg;
-        }
-        virtual bool        getPos_fromParameter(vectorSIMDf& pos, const uint32_t& segmentID, const float& parameter) const
-        {
-            if (segmentID>=segments.size()||parameter>segments[segmentID].length)
-                return false;
-
-            pos = segments[segmentID].posHelper(parameter);
-
-            return true;
-        }
-
-        //to get direction to look in
-        virtual bool        getUnnormDirection(vectorSIMDf& tan, const uint32_t& segmentID, const float& distanceAlongSeg) const
-        {
-            if (segmentID>=segments.size()||distanceAlongSeg>segments[segmentID].length)
-                return false;
-
-            tan = segments[segmentID].directionHelper(distanceAlongSeg);
-
-            return true;
-        }
-
-        virtual bool        getUnnormDirection_fromParameter(vectorSIMDf& tan, const uint32_t& segmentID, const float& parameter) const
-        {
-            return getUnnormDirection(tan,segmentID,parameter);
-        }
-
-        //baw specific
-        virtual const bool      canGiveParameterUntilBlockChange() const {return true;}
-        // pass in current position
-        virtual float           getParameterUntilBlockChange(const uint32_t& segmentID, const float& param)
-        {
-            if (segmentID>=segments.size()||param>=segments[segmentID].length)
-                return -1.f;
-
-            return segments[segmentID].findNextBlockChange(param);
-        }
-        virtual std::vector<float>   getBlockChangesInSegment(const uint32_t& segmentID, float startParam=0.f)
-        {
-            std::vector<float> changes;
-            if (segmentID>=segments.size())
-                return changes;
-
-            const Segment& seg = segments[segmentID];
-            while (true)
-            {
-                float fnd = seg.findNextBlockChange(startParam);
-                if (fnd<0.f)
-                    return changes;
-
-                startParam = fnd;
-                reinterpret_cast<uint32_t&>(startParam)++;
-                changes.push_back(fnd);
-            }
-        }
-
-
-        virtual bool            isArcLengthPrecise() const {return true;}
-        virtual float           parameterToDistance(const float& param) const {return param;}
-        virtual float           distanceToParameter(const float& dist) const {return dist;}
-    private:
-        void finalize()
-        {
-            double lenDouble = 0;
-            for (size_t i=0; i<segments.size(); i++)
-            {
-                lenDouble += segments[i].length;
-            }
-            splineLen = lenDouble;
-        }
-
-
-        struct Segment
-        {
-            Segment(const vectorSIMDf& startPt,const vectorSIMDf& endPt)
-            {
-                weights[0] = endPt-startPt;
-                length = weights[0].getLengthAsFloat();
-                weights[0] /= length;
-
-                weights[1] = startPt;
-            }
-            Segment(const vectorSIMDf& startPt,const vectorSIMDf& endPt, const float& customLen)
-            {
-                weights[0] = (endPt-startPt);
-                length = customLen;
-                weights[0] /= length;
-
-                weights[1] = startPt;
-            }
-
-            inline vectorSIMDf posHelper(const float& distanceAlongSeg) const
-            {
-                return weights[0]*distanceAlongSeg+weights[1];
-            }
-            inline vectorSIMDf directionHelper(const float& distanceAlongSeg) const
-            {
-                return weights[0];
-            }
-            inline float findNextBlockChange(const float& param) const
-            {
-                vectorSIMDf startingNegFrac = posHelper(param);
-                startingNegFrac = floor(startingNegFrac)-startingNegFrac;
-                vectorSIMDf dir = directionHelper(param);
-                float changes[3];
-                for (uint32_t i=0; i<3; i++)
-                    changes[i] = findChange(startingNegFrac.pointer[i],dir.pointer[i]);
-
-                float smallest;
-                if (reinterpret_cast<uint32_t*>(changes)[0]<=reinterpret_cast<uint32_t*>(changes)[1])
-                {
-                    if (reinterpret_cast<uint32_t*>(changes)[2]<=reinterpret_cast<uint32_t*>(changes)[0])
-                        smallest = changes[2];
-                    else
-                        smallest = changes[0];
-                }
-                else if (reinterpret_cast<uint32_t*>(changes)[2]<=reinterpret_cast<uint32_t*>(changes)[1])
-                {
-                    smallest = changes[2];
-                }
-                else
-                    smallest = changes[1];
-
-                smallest += param;
-                if (smallest<length)
-                    return smallest;
-
-                return -1.f;
-            }
-            inline float findChange(const float& currentNegFrac, const float& changePerParam) const
-            {
-                if (currentNegFrac==0.f||currentNegFrac==1.f)
-                    return 0.f;
-
-                if (changePerParam < -FLT_MIN)
-                    return currentNegFrac/changePerParam;
-                else if (changePerParam > FLT_MIN)
-                    return (1.f+currentNegFrac)/changePerParam;
-
-                return -1.f;
-            }
-
-            float length;
-            vectorSIMDf weights[2];
-        };
-
-        core::array<Segment> segments;
-        float splineLen;
-};
-
-
-//! Loop code is wrong for now, unable to calculate A_0 so the gradients match all the way around the loop
-class CQuadraticSpline : public ISpline
-{
-    public:
-        CQuadraticSpline(vectorSIMDf* controlPoints, const size_t& count, const bool loop = false, const bool preemptFirstTurn=false) : ISpline(loop)
-        {
-            //assert(count<0x80000000u && count);
-            float currentApproxLen;
-            if (isLoop)
-            {
-                vectorSIMDf firstWeight;
-                vectorSIMDf addPart(0.f);
-                vectorSIMDf mulPart(1.f,1.f,1.f,0.f);/*
-                for (size_t i=0; i<count; i++)
-                {
-                    addPart += controlPoints[]-;
-                }*/
-                mulPart *= 2.f;
-                firstWeight = addPart/(vectorSIMDf(1.f,1.f,1.f,1.f)-mulPart);
-
-
-                segments.push_back(Segment(controlPoints[0],controlPoints[1],currentApproxLen,firstWeight));
-            }
-            else if (preemptFirstTurn)
-            {
-                vectorSIMDf gradientAfter = controlPoints[2]-controlPoints[1];
-                vectorSIMDf gradientBefore = controlPoints[1]-controlPoints[0];
-                currentApproxLen = gradientBefore.getLengthAsFloat();
-                float nextApproxLen = gradientAfter.getLengthAsFloat();
-                vectorSIMDf gradient = normalize(gradientBefore/currentApproxLen+gradientAfter/nextApproxLen);
-
-
-                segments.push_back(Segment(gradient,controlPoints[0],controlPoints[1],currentApproxLen));
-            }
-            else
-            {
-                currentApproxLen = (controlPoints[1]-controlPoints[0]).getLengthAsFloat();
-                segments.push_back(Segment(controlPoints[0],controlPoints[1],currentApproxLen));
-            }
-
-            float lastApproxLen = currentApproxLen;
-            for (size_t i=isLoop ? 1:2; i<count; i++)
-            {
-                vectorSIMDf startPt = controlPoints[i-1];
-                vectorSIMDf endPt = controlPoints[i];
-                currentApproxLen = (endPt-startPt).getLengthAsFloat();
-                segments.push_back(Segment(startPt,endPt,currentApproxLen,segments[segments.size()-1],lastApproxLen));
-                lastApproxLen = currentApproxLen;
-            }
-
-            finalize();
-        }
-
-        //
-        virtual size_t      getSegmentCount() const
-        {
-            return segments.size();
-        }
-        virtual float       getSplineLength() const
-        {
-            return splineLen;
-        }
-
-        //
-        virtual void        getSegmentLengths(float* outSegLens) const
-        {
-            for (size_t i=0; i<segments.size(); i++)
-                outSegLens[i] = segments[i].length;
-        }
-        virtual float       getSegmentLength(const uint32_t& segmentID) const
-        {
-            //assert(segmentID<segments.size());
-            return segments[segmentID].length;
-        }
-        virtual float       getSegmentParameterRange(const uint32_t& segmentID) const
-        {
-            return segments[segmentID].parameterLength;
-        }
-
-        //get position
-        //this function returns the id of the segment you might have moved into - 0xdeadbeefu is an error code
-        virtual uint32_t    getPos(vectorSIMDf& pos, float& distanceAlongSeg, const uint32_t& segmentID, float* paramHint=NULL, const float& accuracyThresh=0.00390625f) const
-        {
-            if (distanceAlongSeg<0.f)
-                return 0xdeadbeefu;
-
-            uint32_t actualSeg;
-            if (isLoop)
-            {
-                actualSeg = segmentID%segments.size();
-                while (distanceAlongSeg>=segments[actualSeg].length)
-                {
-                    distanceAlongSeg -= segments[actualSeg].length;
-                    actualSeg++;
-                    if (actualSeg==segments.size())
-                        actualSeg = 0;
-                }
-            }
-            else
-            {
-                if (segmentID>=segments.size())
-                    return 0xdeadbeefu;
-
-                actualSeg = segmentID;
-                while (distanceAlongSeg>=segments[actualSeg].length)
-                {
-                    distanceAlongSeg -= segments[actualSeg].length;
-                    actualSeg++;
-                    if (actualSeg==segments.size())
-                        return 0xdeadbeefu;
-                }
-            }
-
-            if (paramHint)
-            {
-                if (actualSeg!=segmentID)
-                    *paramHint = -1.f;
-
-                *paramHint = segments[actualSeg].getParameterFromArcLen(distanceAlongSeg,*paramHint,accuracyThresh);
-                pos = segments[actualSeg].posHelper(*paramHint);
-            }
-            else
-                pos = segments[actualSeg].posHelper(segments[actualSeg].getParameterFromArcLen(distanceAlongSeg,-1.f,accuracyThresh));
-
-            return actualSeg;
-        }
-        virtual bool        getPos_fromParameter(vectorSIMDf& pos, const uint32_t& segmentID, const float& parameter) const
-        {
-            if (segmentID>=segments.size()||parameter>segments[segmentID].parameterLength)
-                return false;
-
-            pos = segments[segmentID].posHelper(parameter);
-
-            return true;
-        }
-
-        //to get direction to look in
-        virtual bool        getUnnormDirection(vectorSIMDf& tan, const uint32_t& segmentID, const float& distanceAlongSeg) const
-        {
-            if (segmentID>=segments.size()||distanceAlongSeg>segments[segmentID].length)
-                return false;
-
-            tan = segments[segmentID].directionHelper(segments[segmentID].getParameterFromArcLen(distanceAlongSeg,-1.f,0.00390625f));
-
-            return true;
-        }
-        virtual bool        getUnnormDirection_fromParameter(vectorSIMDf& tan, const uint32_t& segmentID, const float& parameter) const
-        {
-            if (segmentID>=segments.size()||parameter>segments[segmentID].parameterLength)
-                return false;
-
-            tan = segments[segmentID].directionHelper(parameter);
-
-            return true;
-        }
-
-        //baw specific -- to be implemented later
-        virtual const bool      canGiveParameterUntilBlockChange() const {return false;}
-        // pass in current position
-        virtual float           getParameterUntilBlockChange(const uint32_t& segmentID, const float& param)
-        {
-            //if (segmentID>=segments.size()||param>=segments[segmentID].parameterLength)
-                return -1.f;
-
-            //return segments[segmentID].findNextBlockChange(param);
-        }
-        virtual std::vector<float>   getBlockChangesInSegment(const uint32_t& segmentID, float startParam=0.f)
-        {
-            std::vector<float> changes;
-            //if (segmentID>=segments.size())
-                return changes;
-/*
-            const Segment& seg = segments[segmentID];
-            while (true)
-            {
-                float fnd = seg.findNextBlockChange(startParam);
-                if (fnd<0.f)
-                    return changes;
-
-                startParam = fnd;
-                reinterpret_cast<uint32_t&>(startParam)++;
-                changes.push_back(fnd);
-            }*/
-        }
-
-
-        virtual bool            isArcLengthPrecise() const {return true;}
-        virtual float           parameterToDistance(const float& param) const {return param;}
-        virtual float           distanceToParameter(const float& dist) const {return dist;}
-    private:
-        void finalize()
-        {
-            double lenDouble = 0;
-            for (size_t i=0; i<segments.size(); i++)
-            {
-                lenDouble += segments[i].length;
-            }
-            splineLen = lenDouble;
-        }
-
-
-        struct Segment
-        {
-            Segment(const vectorSIMDf& startPt,const vectorSIMDf& endPt, const float& currentApproxLen, const vectorSIMDf& firstWeight)
-            {
-                /// ad^2+bd+y0 = y1
-                /// ad+b = (y1-y0)/d
-                weights[2] = startPt;
-                weights[1] = (endPt-startPt)/currentApproxLen-firstWeight*currentApproxLen;
-                weights[0] = firstWeight;
-
-                finalize(currentApproxLen);
-            }
-            Segment(const vectorSIMDf& startPt,const vectorSIMDf& endPt, const float& currentApproxLen)
-            {
-                /// ad^2+bd+y0 = y1
-                /// ad+b = (y1-y0)/d
-
-                /// The differential 2ad+b is continuous
-                /// At start require f'' = 0 -> a = 0
-                /// => ad = (y1-y0)/d - b
-                weights[2] = startPt;
-                weights[1] = (endPt-startPt)/currentApproxLen;
-                weights[0] = vectorSIMDf(0.f);
-
-                finalize(currentApproxLen);
-            }
-            Segment(const vectorSIMDf& firstEndGradient, const vectorSIMDf& startPt, const vectorSIMDf& endPt, const float& currentApproxLen) //! Unfinished
-            {
-                /// ad^2+bd+y0 = y1
-                /// ad+b = (y1-y0)/d
-
-                /// The differential 2ad+b is continuous
-                /// At end require f'/|f'| = something -> (ad+(y1-y0)/d)^2 = something^2*(ad+(y1-y0)/d)
-                    //botch solution ad = something-(y1-y0)/d
-                    /// (ad-(y1-y0)/d)^2 = a^2 d^2 - 2 ad (y1-y0)/d + (y1-y0)^2/d^2 = something^2*ad-something^2*(y1-y0)/d
-                    /// => ad = (y1-y0)/d - b
-                weights[2] = startPt;
-                weights[1] = (endPt-startPt)*2.f/currentApproxLen-firstEndGradient;
-                weights[0] = (firstEndGradient-(endPt-startPt)/currentApproxLen)/currentApproxLen;
-
-                finalize(currentApproxLen);
-            }
-            Segment(const vectorSIMDf& startPt,const vectorSIMDf& endPt, const float& currentApproxLen, const Segment& previousSeg, const float& prevApproxLen)
-            {
-                /// ad^2+bd+y0 = y1
-                /// ad+b = (y1-y0)/d
-
-                /// The differential 2ad+b is continuous
-
-                /// anywhere else
-                /// (2ad+b)_{i-1} = b_{i}
-                /// (ad+(y1-y0)/d)_{i-1} = b_{i}
-                weights[2] = startPt;
-                weights[1] = previousSeg.weights[0]*prevApproxLen*2.f+previousSeg.weights[1];
-                weights[0] = ((endPt-startPt)/currentApproxLen-weights[1])/currentApproxLen;
-
-                finalize(currentApproxLen);
-            }
-
-            inline void finalize(const float &currentApproxLen)
-            {
-                parameterLength = currentApproxLen;
-
-                lenASq       = dot(weights[0],weights[0]).x;
-                double lenCSq       = dot(weights[1],weights[1]).x;
-                lenC         = std::sqrt(lenCSq);
-                if (std::abs(lenASq)>0.000001f)
-                {
-                    /// integral sqrt(a x^2 + b x + c) dx =
-                    /// ((2 a x + b) sqrt(x (a x + b) + c))/(4 a) - ((b^2 - 4 a c) log(2 sqrt(a) sqrt(x (a x + b) + c) + 2 a x + b))/(8 a^(3/2))
-                    /// @ x=0
-                    /// (b sqrt(c))/(4 a) - ((b^2 - 4 a c) log(2 sqrt(a) sqrt(c) + b))/(8 a^(3/2))
-                    double term_b       = 4.f*dot(weights[1],weights[0]).x;
-                    double lenASq_4     = lenASq*16.f;
-                    double lenA_2       = std::sqrt(lenASq_4);
-
-                    double lenBSq       = dot(weights[1],weights[1]).x;
-
-                    /// integral sqrt(a x^2 + b x + c) dx =
-                    /// ((2 a x + b) sqrt(x (a x + b) + c))/(4 a) - ((b^2 - 4 a c) log(2 sqrt(a) sqrt(x (a x + b) + c) + 2 a x + b))/(8 a^(3/2))
-                    /// ((0.5 x + b/4a) sqrt(x (a x + b) + c)) - ((b*b/4a - c) log(2 sqrt(a) sqrt(x (a x + b) + c) + 2 a x + b))/(2 a^(1/2))
-                    /// differential
-                    /// ((2 a x + b) sqrt(x (a x + b) + c))/(4 a) - ((b^2 - 4 a c) log(2 sqrt(a) sqrt(x (a x + b) + c) + 2 a x + b))/(8 a^(3/2))
-                    arcCalcConstants[0] = term_b/lenASq_4;
-                    arcCalcConstants[1] = lenASq*4.f;
-                    arcCalcConstants[2] = term_b;
-                    arcCalcConstants[3] = lenCSq;
-                    arcCalcConstants[4] = (arcCalcConstants[3]-term_b*arcCalcConstants[0])/lenA_2;
-                    arcCalcConstants[5] = lenA_2;
-
-                    //lowerIntegralValue      = 0.f;
-                    //lowerIntegralValue      = getArcLenFromParameter(0.f);
-                    lowerIntegralValue      = arcCalcConstants[0]*lenC+arcCalcConstants[4]*log(arcCalcConstants[5]*lenC+term_b);
-
-                    length = getArcLenFromParameter(parameterLength);
-                }
-                else
-                {
-                    length = lenC*parameterLength;
-                    lenC_reciprocal = reciprocal(lenC);
-                }
-            }
-
-            inline float getArcLenFromParameter(const float &parameter) const
-            {
-                //assert(std::abs(lenASq)>0.000001f);
-
-                double ax = arcCalcConstants[1]*parameter;
-                double ax_b = ax+arcCalcConstants[2];
-                double theSquareRoot = std::sqrt(parameter*ax_b+arcCalcConstants[3]);
-                float higherIntTerm    = (0.5f*parameter+arcCalcConstants[0])*theSquareRoot+arcCalcConstants[4]*log(arcCalcConstants[5]*theSquareRoot+ax_b+ax);
-/*
-                double a = dot(weights[0],weights[0]).x;
-                double b = dot(weights[0],weights[1]).x*2.f;
-                double c = dot(weights[1],weights[1]).x;
-                double higherIntTerm = ((2.f* a* parameter + b)*std::sqrt(parameter* (a *parameter + b) + c))/(4.f* a) - ((b*b - 4*a*c)*log(2.f*std::sqrt(a)*std::sqrt(parameter*(a*parameter + b) + c) + 2.f*a*parameter + b))/(8.f*a*std::sqrt(a));
-*/
-/*
-                /// extreme debug
-                double checkLen = 0.0;
-                vectorSIMDf prevPoint = weights[2];
-                for (size_t i=1; i<=1024*16; i++)
-                {
-                    double tmp = double(i)/double(1024*16);
-                    tmp *= parameter;
-                    vectorSIMDf nextPoint = posHelper(tmp);
-                    checkLen += (prevPoint - nextPoint).getLengthAsFloat();
-                    prevPoint = nextPoint;
-                }
-                float diff = std::abs(higherIntTerm-lowerIntegralValue-checkLen);
-                assert(diff<0.001f);
-*/
-                return higherIntTerm-lowerIntegralValue;
-            }
-
-            inline float getParameterFromArcLen(const float& arcLen, float parameterHint, const float& accuracyThresh) const
-            {
-                if (std::abs(lenASq)>0.000001f)
-                {
-                    if (arcLen<=accuracyThresh)
-                        return arcLen;
-                    if (arcLen>=length-accuracyThresh)
-                        return parameterLength;
-                    if (parameterHint<0.f||parameterHint>parameterLength)
-                        parameterHint = parameterLength*(arcLen/length);
-                    /// dist = IndefInt(param) - lowerIntVal
-                    /// IndefInt^-1(dist+lowerIntVal) = param
-                    /// Newton-Raphson      f = arcLen - getArcLenFromParameter(parameterHint);
-                    /// Newton-Raphson      f' = -getArcLenFromParameter'(parameterHint);
-                    float arcLenDiffAtParamGuess = arcLen-getArcLenFromParameter(parameterHint);
-                    for (size_t i=0; std::abs(arcLenDiffAtParamGuess)>accuracyThresh&&i<32; i++)
-                    {
-                        float differentialAtGuess = directionHelper(parameterHint).getLengthAsFloat();
-                        parameterHint = parameterHint+arcLenDiffAtParamGuess/differentialAtGuess;
-                        arcLenDiffAtParamGuess = arcLen-getArcLenFromParameter(parameterHint);
-                    }
-                    return parameterHint;
-                }
-                else
-                    return arcLen*lenC_reciprocal;
-            }
-
-            inline vectorSIMDf posHelper(const float& parameter) const
-            {
-                return (weights[0]*parameter+weights[1])*parameter+weights[2];
-            }
-            inline vectorSIMDf directionHelper(const float& parameter) const
-            {
-                return weights[0]*parameter*2.f+weights[1];
-            }/*
-            inline float findNextBlockChange(const float& param) const
-            {
-                vectorSIMDf startingNegFrac = posHelper(param);
-                startingNegFrac = floor(startingNegFrac)-startingNegFrac;
-                vectorSIMDf dir = directionHelper(param);
-                float changes[3];
-                for (uint32_t i=0; i<3; i++)
-                    changes[i] = findChange(startingNegFrac.pointer[i],dir.pointer[i]);
-
-                float smallest;
-                if (reinterpret_cast<uint32_t*>(changes)[0]<=reinterpret_cast<uint32_t*>(changes)[1])
-                {
-                    if (reinterpret_cast<uint32_t*>(changes)[2]<=reinterpret_cast<uint32_t*>(changes)[0])
-                        smallest = changes[2];
-                    else
-                        smallest = changes[0];
-                }
-                else if (reinterpret_cast<uint32_t*>(changes)[2]<=reinterpret_cast<uint32_t*>(changes)[1])
-                {
-                    smallest = changes[2];
-                }
-                else
-                    smallest = changes[1];
-
-                smallest_+= param;
-                if (smallest<length)
-                    return smallest;
-
-                return -1.f;
-            }
-            inline float findChange(const float& currentNegFrac, const float& changePerParam) const
-            {
-                if (currentNegFrac==0.f||currentNegFrac==1.f)
-                    return 0.f;
-
-                if (changePerParam < -FLT_MIN)
-                    return currentNegFrac/changePerParam;
-                else if (changePerParam > FLT_MIN)
-                    return (1.f+currentNegFrac)/changePerParam;
-
-                return -1.f;
-            }*/
-
-            float length,parameterLength,lenASq,lowerIntegralValue;
-            union
-            {
-                float lenC;
-                float lenC_reciprocal;
-            };
-            float arcCalcConstants[6];
-            vectorSIMDf weights[3];
-        };
-
-        core::array<Segment> segments;
-        float splineLen;
-};
-
-/*
-class CCubicSpline : public ISpline
-{
-    public:
-        CCubicSpline(vectorSIMDf* controlPoints, const size_t& count, const bool loop = false) : isLoop(loop)
-        {
-            //assert(count<0x80000000u);
-            finalize();
-        }
-        CCubicSpline(vectorSIMDf* controlPointsPos, bool* discontinuityPoints, const size_t& count, const bool loop = false) : isLoop(loop)
-        {
-            //assert(count<0x80000000u);
-            finalize();
-        }
-
-        //
-        virtual bool        isLoop() const {return isLoop;}
-        virtual size_t      getSegmentCount() const
-        {
-            return segments.size();
-        }
-        virtual float       getSplineLength() const
-        {
-            return splineLen;
-        }
-
-        //
-        virtual void        getSegmentLengths(float* outSegLens) const
-        {
-            for (size_t i=0; i<segments.size(); i++)
-                outSegLens[i] = segments[i].length;
-        }
-        virtual float       getSegmentLength(const uint32_t& segmentID) const
-        {
-            //assert(segmentID<segments.size());
-            return segments[segmentID].length;
-        }
-
-        //get position
-        //this function returns the id of the segment you might have moved into - 0xdeadbeefu is an error code
-        virtual uint32_t    getPos(vectorSIMDf& pos, const uint32_t& segmentID, float distance) const
-        {
-            uint32_t actualSeg;
-            if (isLoop)
-            {
-                actualSeg = segmentID%segments.size();
-                while (distance>=segments[actualSeg].length)
-                {
-                    distance -= segments[actualSeg].length;
-                    actualSeg++;
-                    if (actualSeg==segments.size())
-                        actualSeg = 0;
-                }
-            }
-            else
-            {
-                if (segmentID>=segments.size())
-                    return 0xdeadbeefu;
-
-                actualSeg = segmentID;
-                while (distance>=segments[actualSeg].length)
-                {
-                    distance -= segments[actualSeg].length;
-                    actualSeg++;
-                    if (actualSeg==segments.size())
-                        return 0xdeadbeefu;
-                }
-            }
-
-            float interpol = findFraction(actualSeg,distance);
-            pos = fractionHelper(actualSegment,interpol);
-
-            return true;
-        }
-        virtual bool        getPos_fromFraction(vectorSIMDf& pos, const uint32_t& segmentID, const float& interpolant) const
-        {
-            if (interpolant<0.f||interpolant>=1.f||segmentID>=segments.size())
-                return false;
-
-            pos = fractionHelper(segmentID,interpolant);
-
-            return true;
-        }
-
-        //to get direction to look in
-        virtual bool        getUnnormDirection(vectorSIMDf& tan, const uint32_t& segmentID, const float& distance)
-        {
-            if (segmentID>=segments.size()||distance>segments[segmentID].length)
-                return 0xdeadbeefu;
-
-            float interpol = findFraction(segmentID,distance);
-            tan = directionHelper(segmentID,interpol);
-
-            return true;
-        }
-        virtual bool        getUnnormDirection_fromFraction(vectorSIMDf& tan, const uint32_t& segmentID, const float& interpolant) const
-        {
-            if (interpolant<0.f||interpolant>=1.f||segmentID>=segments.size())
-                return false;
-
-            tan = directionHelper(segmentID,interpolant);
-
-            return true;
-        }
-
-        //baw specific
-        virtual const bool      canGiveParameterUntilBlockChange() const {return true;}
-        // pass in current position
-        virtual float           getParameterUntilBlockChange(const uint32_t& segmentID, const float& distanceAlongSeg) = 0;
-        virtual vector<float>   getBlockChangesInSegment(const uint32_t& segmentID) = 0;
-    private:
-        inline float findFraction(const uint32_t& segmentID, const float& distance) const
-        {
-            //
-        }
-
-        void finalize()
-        {
-            double lenDouble = 0;
-            for (size_t i=0; i<segments.size(); i++)
-            {
-                lenDouble += segments[i].length;
-            }
-            splineLen = lenDouble;
-        }
-
-        bool isLoop;
-
-        struct Segment
-        {
-            Segment(const vectorSIMDf& beforeStart,const vectorSIMDf& startPt,const vectorSIMDf& endPt,const vectorSIMDf& afterEnd)
-            {
-                weights[0] = startPt;
-                weights[1] = endPt-beforeStart;
-                vectorSIMDf a = beforeStart-startPt;
-                vectorSIMDf b = endPt-afterEnd;
-                weights[2] = 2.f*a+b;
-                weights[3] = -b-a;
-
-                length = 0;
-                vectorSIMDf currentPt = endPt;
-                core::array<vectorSIMDf> lenPoints;
-                lenPoints.push_back(startPt);
-                while (lenPoints.size())
-                {
-                    vectorSIMDf diff = currentPt-lenPoints[lenPoints.size()-1];
-                    if (dot(diff,diff)>0.0025)
-                    {
-                        lenPoints[lenPoints.size()-1]
-                    }
-                }
-            }
-
-            inline vectorSIMDf fractionHelper(const float& interpolant) const
-            {
-                return ((weights[0]*interpolant+weights[1])*interpolant+weights[2])*interpolant+weights[3];
-            }
-            inline vectorSIMDf directionHelper(const float& interpolant) const
-            {
-                return (3.f*weights[0]*interpolant+2.f*weights[1])*interpolant+weights[2];
-            }
-
-            float length;
-            vectorSIMDf weights[4];
-        };
-
-        //core::array<vectorSIMDf> controls;
-        core::array<Segment> segments;
-        float splineLen;
-};
-*/
-
-}
-}
-
-#endif
+#define __IRR_SPLINES_H_INCLUDED__
+
+#include "IrrCompileConfig.h"
+#include <cmath>       /* sqrt */
+#include "vectorSIMD.h"
+#include "irrArray.h"
+#include <vector>
+
+
+namespace irr
+{
+namespace core
+{
+
+
+class ISpline
+{
+    public:
+        virtual ~ISpline() {}
+
+        //
+        virtual bool        isLooping() const {return isLoop;}
+        virtual size_t      getSegmentCount() const = 0;
+        virtual float       getSplineLength() const = 0;
+
+        //
+        virtual void        getSegmentLengths(float* outSegLens) const = 0;
+        virtual float       getSegmentLength(const uint32_t& segmentID) const = 0;
+        virtual float       getSegmentParameterRange(const uint32_t& segmentID) const = 0;
+
+        //get position
+        //this function returns the id of the segment you might have moved into
+        virtual uint32_t    getPos(vectorSIMDf& pos, float& distanceAlongSeg, const uint32_t& segmentID, float* paramHint=NULL, const float& accuracyThresh=0.00390625f) const = 0;
+        virtual bool        getPos_fromParameter(vectorSIMDf& pos, const uint32_t& segmentID, const float& parameter) const = 0;
+
+        //to get direction to look in
+        virtual bool        getUnnormDirection(vectorSIMDf& tan, const uint32_t& segmentID, const float& distanceAlongSeg) const = 0;
+        virtual bool        getUnnormDirection_fromParameter(vectorSIMDf& tan, const uint32_t& segmentID, const float& parameter) const = 0;
+
+        //baw specific
+        virtual const bool      canGiveParameterUntilBlockChange() const {return false;}
+        // pass in current position
+        virtual float           getParameterUntilBlockChange(const uint32_t& segmentID, const float& param) = 0;
+        virtual std::vector<float>   getBlockChangesInSegment(const uint32_t& segmentID, float startParam=0.f) = 0;
+
+        //is the distance and parameter the same?
+        virtual bool            isArcLengthPrecise() const = 0;
+        ///virtual float           parameterToDistance(const float& param) const = 0;
+        ///virtual float           distanceToParameter(const float& dist) const = 0;
+    protected:
+        ISpline(bool loop) : isLoop(loop) {}
+
+        const bool isLoop;
+    private:
+};
+
+
+class CLinearSpline : public ISpline
+{
+    public:
+        CLinearSpline(vectorSIMDf* controlPoints, const size_t& count, const bool loop = false) : ISpline(loop)
+        {
+            //assert(count<0x80000000u && count);
+            for (size_t i=1; i<count; i++)
+                segments.push_back(Segment(controlPoints[i-1],controlPoints[i]));
+
+            if (isLoop)
+                segments.push_back(Segment(controlPoints[count-1],controlPoints[0]));
+            finalize();
+        }
+        CLinearSpline(vectorSIMDf* controlPoints, float* customDistances, const size_t& count, const bool loop = false) : ISpline(loop)
+        {
+            //assert(count<0x80000000u);
+            for (size_t i=1; i<count; i++)
+                segments.push_back(Segment(controlPoints[i-1],controlPoints[i],customDistances[i-1]));
+
+            if (isLoop)
+                segments.push_back(Segment(controlPoints[count-1],controlPoints[0],customDistances[count-1]));
+            finalize();
+        }
+
+        //
+        virtual size_t      getSegmentCount() const
+        {
+            return segments.size();
+        }
+        virtual float       getSplineLength() const
+        {
+            return splineLen;
+        }
+
+        //
+        virtual void        getSegmentLengths(float* outSegLens) const
+        {
+            for (size_t i=0; i<segments.size(); i++)
+                outSegLens[i] = segments[i].length;
+        }
+        virtual float       getSegmentLength(const uint32_t& segmentID) const
+        {
+            //assert(segmentID<segments.size());
+            return segments[segmentID].length;
+        }
+        virtual float       getSegmentParameterRange(const uint32_t& segmentID) const
+        {
+            return getSegmentLength(segmentID);
+        }
+
+        //get position
+        //this function returns the id of the segment you might have moved into - 0xdeadbeefu is an error code
+        virtual uint32_t    getPos(vectorSIMDf& pos, float& distanceAlongSeg, const uint32_t& segmentID, float* paramHint=NULL, const float& accuracyThresh=0.00390625f) const
+        {
+            if (distanceAlongSeg<0.f)
+                return 0xdeadbeefu;
+
+            uint32_t actualSeg;
+            if (isLoop)
+            {
+                actualSeg = segmentID%segments.size();
+                while (distanceAlongSeg>=segments[actualSeg].length)
+                {
+                    distanceAlongSeg -= segments[actualSeg].length;
+                    actualSeg++;
+                    if (actualSeg==segments.size())
+                        actualSeg = 0;
+                }
+            }
+            else
+            {
+                if (segmentID>=segments.size())
+                    return 0xdeadbeefu;
+
+                actualSeg = segmentID;
+                while (distanceAlongSeg>=segments[actualSeg].length)
+                {
+                    distanceAlongSeg -= segments[actualSeg].length;
+                    actualSeg++;
+                    if (actualSeg==segments.size())
+                        return 0xdeadbeefu;
+                }
+            }
+
+            pos = segments[actualSeg].posHelper(distanceAlongSeg);
+            if (paramHint)
+                *paramHint = distanceAlongSeg;
+
+            return actualSeg;
+        }
+        virtual bool        getPos_fromParameter(vectorSIMDf& pos, const uint32_t& segmentID, const float& parameter) const
+        {
+            if (segmentID>=segments.size()||parameter>segments[segmentID].length)
+                return false;
+
+            pos = segments[segmentID].posHelper(parameter);
+
+            return true;
+        }
+
+        //to get direction to look in
+        virtual bool        getUnnormDirection(vectorSIMDf& tan, const uint32_t& segmentID, const float& distanceAlongSeg) const
+        {
+            if (segmentID>=segments.size()||distanceAlongSeg>segments[segmentID].length)
+                return false;
+
+            tan = segments[segmentID].directionHelper(distanceAlongSeg);
+
+            return true;
+        }
+
+        virtual bool        getUnnormDirection_fromParameter(vectorSIMDf& tan, const uint32_t& segmentID, const float& parameter) const
+        {
+            return getUnnormDirection(tan,segmentID,parameter);
+        }
+
+        //baw specific
+        virtual const bool      canGiveParameterUntilBlockChange() const {return true;}
+        // pass in current position
+        virtual float           getParameterUntilBlockChange(const uint32_t& segmentID, const float& param)
+        {
+            if (segmentID>=segments.size()||param>=segments[segmentID].length)
+                return -1.f;
+
+            return segments[segmentID].findNextBlockChange(param);
+        }
+        virtual std::vector<float>   getBlockChangesInSegment(const uint32_t& segmentID, float startParam=0.f)
+        {
+            std::vector<float> changes;
+            if (segmentID>=segments.size())
+                return changes;
+
+            const Segment& seg = segments[segmentID];
+            while (true)
+            {
+                float fnd = seg.findNextBlockChange(startParam);
+                if (fnd<0.f)
+                    return changes;
+
+                startParam = fnd;
+                reinterpret_cast<uint32_t&>(startParam)++;
+                changes.push_back(fnd);
+            }
+        }
+
+
+        virtual bool            isArcLengthPrecise() const {return true;}
+        ///virtual float           parameterToDistance(const float& param) const {return param;}
+        ///virtual float           distanceToParameter(const float& dist) const {return dist;}
+    private:
+        void finalize()
+        {
+            double lenDouble = 0;
+            for (size_t i=0; i<segments.size(); i++)
+            {
+                lenDouble += segments[i].length;
+            }
+            splineLen = lenDouble;
+        }
+
+
+        struct Segment
+        {
+            Segment(const vectorSIMDf& startPt,const vectorSIMDf& endPt)
+            {
+                weights[0] = endPt-startPt;
+                length = weights[0].getLengthAsFloat();
+                weights[0] /= length;
+
+                weights[1] = startPt;
+            }
+            Segment(const vectorSIMDf& startPt,const vectorSIMDf& endPt, const float& customLen)
+            {
+                weights[0] = (endPt-startPt);
+                length = customLen;
+                weights[0] /= length;
+
+                weights[1] = startPt;
+            }
+
+            inline vectorSIMDf posHelper(const float& distanceAlongSeg) const
+            {
+                return weights[0]*distanceAlongSeg+weights[1];
+            }
+            inline vectorSIMDf directionHelper(const float& distanceAlongSeg) const
+            {
+                return weights[0];
+            }
+            inline float findNextBlockChange(const float& param) const
+            {
+                vectorSIMDf startingNegFrac = posHelper(param);
+                startingNegFrac = floor(startingNegFrac)-startingNegFrac;
+                vectorSIMDf dir = directionHelper(param);
+                float changes[3];
+                for (uint32_t i=0; i<3; i++)
+                    changes[i] = findChange(startingNegFrac.pointer[i],dir.pointer[i]);
+
+                float smallest;
+                if (reinterpret_cast<uint32_t*>(changes)[0]<=reinterpret_cast<uint32_t*>(changes)[1])
+                {
+                    if (reinterpret_cast<uint32_t*>(changes)[2]<=reinterpret_cast<uint32_t*>(changes)[0])
+                        smallest = changes[2];
+                    else
+                        smallest = changes[0];
+                }
+                else if (reinterpret_cast<uint32_t*>(changes)[2]<=reinterpret_cast<uint32_t*>(changes)[1])
+                {
+                    smallest = changes[2];
+                }
+                else
+                    smallest = changes[1];
+
+                smallest += param;
+                if (smallest<length)
+                    return smallest;
+
+                return -1.f;
+            }
+            inline float findChange(const float& currentNegFrac, const float& changePerParam) const
+            {
+                if (currentNegFrac==0.f||currentNegFrac==1.f)
+                    return 0.f;
+
+                if (changePerParam < -FLT_MIN)
+                    return currentNegFrac/changePerParam;
+                else if (changePerParam > FLT_MIN)
+                    return (1.f+currentNegFrac)/changePerParam;
+
+                return -1.f;
+            }
+
+            float length;
+            vectorSIMDf weights[2];
+        };
+
+        core::array<Segment> segments;
+        float splineLen;
+};
+
+
+//! Loop code is wrong for now, unable to calculate A_0 so the gradients match all the way around the loop
+class CQuadraticSpline : public ISpline
+{
+    public:
+        CQuadraticSpline(vectorSIMDf* controlPoints, const size_t& count, const bool loop = false, const bool preemptFirstTurn=false) : ISpline(loop)
+        {
+            //assert(count<0x80000000u && count);
+            float currentApproxLen;
+            if (isLoop)
+            {
+                vectorSIMDf firstWeight;
+                vectorSIMDf addPart(0.f);
+                vectorSIMDf mulPart(1.f,1.f,1.f,0.f);/*
+                for (size_t i=0; i<count; i++)
+                {
+                    addPart += controlPoints[]-;
+                }*/
+                mulPart *= 2.f;
+                firstWeight = addPart/(vectorSIMDf(1.f,1.f,1.f,1.f)-mulPart);
+
+
+                segments.push_back(Segment(controlPoints[0],controlPoints[1],currentApproxLen,firstWeight));
+            }
+            else if (preemptFirstTurn)
+            {
+                vectorSIMDf gradientAfter = controlPoints[2]-controlPoints[1];
+                vectorSIMDf gradientBefore = controlPoints[1]-controlPoints[0];
+                currentApproxLen = gradientBefore.getLengthAsFloat();
+                float nextApproxLen = gradientAfter.getLengthAsFloat();
+                vectorSIMDf gradient = normalize(gradientBefore/currentApproxLen+gradientAfter/nextApproxLen);
+
+
+                segments.push_back(Segment(gradient,controlPoints[0],controlPoints[1],currentApproxLen));
+            }
+            else
+            {
+                currentApproxLen = (controlPoints[1]-controlPoints[0]).getLengthAsFloat();
+                segments.push_back(Segment(controlPoints[0],controlPoints[1],currentApproxLen));
+            }
+
+            float lastApproxLen = currentApproxLen;
+            for (size_t i=isLoop ? 1:2; i<count; i++)
+            {
+                vectorSIMDf startPt = controlPoints[i-1];
+                vectorSIMDf endPt = controlPoints[i];
+                currentApproxLen = (endPt-startPt).getLengthAsFloat();
+                segments.push_back(Segment(startPt,endPt,currentApproxLen,segments[segments.size()-1],lastApproxLen));
+                lastApproxLen = currentApproxLen;
+            }
+
+            finalize();
+        }
+
+        //
+        virtual size_t      getSegmentCount() const
+        {
+            return segments.size();
+        }
+        virtual float       getSplineLength() const
+        {
+            return splineLen;
+        }
+
+        //
+        virtual void        getSegmentLengths(float* outSegLens) const
+        {
+            for (size_t i=0; i<segments.size(); i++)
+                outSegLens[i] = segments[i].length;
+        }
+        virtual float       getSegmentLength(const uint32_t& segmentID) const
+        {
+            //assert(segmentID<segments.size());
+            return segments[segmentID].length;
+        }
+        virtual float       getSegmentParameterRange(const uint32_t& segmentID) const
+        {
+            return segments[segmentID].parameterLength;
+        }
+
+        //get position
+        //this function returns the id of the segment you might have moved into - 0xdeadbeefu is an error code
+        virtual uint32_t    getPos(vectorSIMDf& pos, float& distanceAlongSeg, const uint32_t& segmentID, float* paramHint=NULL, const float& accuracyThresh=0.00390625f) const
+        {
+            if (distanceAlongSeg<0.f)
+                return 0xdeadbeefu;
+
+            uint32_t actualSeg;
+            if (isLoop)
+            {
+                actualSeg = segmentID%segments.size();
+                while (distanceAlongSeg>=segments[actualSeg].length)
+                {
+                    distanceAlongSeg -= segments[actualSeg].length;
+                    actualSeg++;
+                    if (actualSeg==segments.size())
+                        actualSeg = 0;
+                }
+            }
+            else
+            {
+                if (segmentID>=segments.size())
+                    return 0xdeadbeefu;
+
+                actualSeg = segmentID;
+                while (distanceAlongSeg>=segments[actualSeg].length)
+                {
+                    distanceAlongSeg -= segments[actualSeg].length;
+                    actualSeg++;
+                    if (actualSeg==segments.size())
+                        return 0xdeadbeefu;
+                }
+            }
+
+            if (paramHint)
+            {
+                if (actualSeg!=segmentID)
+                    *paramHint = -1.f;
+
+                *paramHint = segments[actualSeg].getParameterFromArcLen(distanceAlongSeg,*paramHint,accuracyThresh);
+                pos = segments[actualSeg].posHelper(*paramHint);
+            }
+            else
+                pos = segments[actualSeg].posHelper(segments[actualSeg].getParameterFromArcLen(distanceAlongSeg,-1.f,accuracyThresh));
+
+            return actualSeg;
+        }
+        virtual bool        getPos_fromParameter(vectorSIMDf& pos, const uint32_t& segmentID, const float& parameter) const
+        {
+            if (segmentID>=segments.size()||parameter>segments[segmentID].parameterLength)
+                return false;
+
+            pos = segments[segmentID].posHelper(parameter);
+
+            return true;
+        }
+
+        //to get direction to look in
+        virtual bool        getUnnormDirection(vectorSIMDf& tan, const uint32_t& segmentID, const float& distanceAlongSeg) const
+        {
+            if (segmentID>=segments.size()||distanceAlongSeg>segments[segmentID].length)
+                return false;
+
+            tan = segments[segmentID].directionHelper(segments[segmentID].getParameterFromArcLen(distanceAlongSeg,-1.f,0.00390625f));
+
+            return true;
+        }
+        virtual bool        getUnnormDirection_fromParameter(vectorSIMDf& tan, const uint32_t& segmentID, const float& parameter) const
+        {
+            if (segmentID>=segments.size()||parameter>segments[segmentID].parameterLength)
+                return false;
+
+            tan = segments[segmentID].directionHelper(parameter);
+
+            return true;
+        }
+
+        //baw specific -- to be implemented later
+        virtual const bool      canGiveParameterUntilBlockChange() const {return false;}
+        // pass in current position
+        virtual float           getParameterUntilBlockChange(const uint32_t& segmentID, const float& param)
+        {
+            //if (segmentID>=segments.size()||param>=segments[segmentID].parameterLength)
+                return -1.f;
+
+            //return segments[segmentID].findNextBlockChange(param);
+        }
+        virtual std::vector<float>   getBlockChangesInSegment(const uint32_t& segmentID, float startParam=0.f)
+        {
+            std::vector<float> changes;
+            //if (segmentID>=segments.size())
+                return changes;
+/*
+            const Segment& seg = segments[segmentID];
+            while (true)
+            {
+                float fnd = seg.findNextBlockChange(startParam);
+                if (fnd<0.f)
+                    return changes;
+
+                startParam = fnd;
+                reinterpret_cast<uint32_t&>(startParam)++;
+                changes.push_back(fnd);
+            }*/
+        }
+
+
+        virtual bool            isArcLengthPrecise() const {return true;}/**
+        virtual float           parameterToDistance(const float& param) const
+        {
+        }
+        virtual float           distanceToParameter(const float& dist) const
+        {
+        }**/
+
+    protected:
+        CQuadraticSpline(bool loop) : ISpline(loop) {}
+
+        void finalize()
+        {
+            double lenDouble = 0;
+            for (size_t i=0; i<segments.size(); i++)
+            {
+                lenDouble += segments[i].length;
+            }
+            splineLen = lenDouble;
+        }
+
+
+        class Segment
+        {
+            public:
+            Segment(const vectorSIMDf& startPt,const vectorSIMDf& endPt, const float& currentApproxLen, const vectorSIMDf& firstWeight)
+            {
+                /// ad^2+bd+y0 = y1
+                /// ad+b = (y1-y0)/d
+                weights[2] = startPt;
+                weights[1] = (endPt-startPt)/currentApproxLen-firstWeight*currentApproxLen;
+                weights[0] = firstWeight;
+
+                finalize(currentApproxLen);
+            }
+            Segment(const vectorSIMDf& startPt,const vectorSIMDf& endPt, const float& currentApproxLen)
+            {
+                /// ad^2+bd+y0 = y1
+                /// ad+b = (y1-y0)/d
+
+                /// The differential 2ad+b is continuous
+                /// At start require f'' = 0 -> a = 0
+                /// => ad = (y1-y0)/d - b
+                weights[2] = startPt;
+                weights[1] = (endPt-startPt)/currentApproxLen;
+                weights[0] = vectorSIMDf(0.f);
+
+                finalize(currentApproxLen);
+            }
+            Segment(const vectorSIMDf& firstEndGradient, const vectorSIMDf& startPt, const vectorSIMDf& endPt, const float& currentApproxLen) //! Unfinished
+            {
+                /// ad^2+bd+y0 = y1
+                /// ad+b = (y1-y0)/d
+
+                /// The differential 2ad+b is continuous
+                /// At end require f'/|f'| = something -> (ad+(y1-y0)/d)^2 = something^2*(ad+(y1-y0)/d)
+                    //botch solution ad = something-(y1-y0)/d
+                    /// (ad-(y1-y0)/d)^2 = a^2 d^2 - 2 ad (y1-y0)/d + (y1-y0)^2/d^2 = something^2*ad-something^2*(y1-y0)/d
+                    /// => ad = (y1-y0)/d - b
+                weights[2] = startPt;
+                weights[1] = (endPt-startPt)*2.f/currentApproxLen-firstEndGradient;
+                weights[0] = (firstEndGradient-(endPt-startPt)/currentApproxLen)/currentApproxLen;
+
+                finalize(currentApproxLen);
+            }
+            Segment(const vectorSIMDf& startPt,const vectorSIMDf& endPt, const float& currentApproxLen, const Segment& previousSeg, const float& prevApproxLen)
+            {
+                /// ad^2+bd+y0 = y1
+                /// ad+b = (y1-y0)/d
+
+                /// The differential 2ad+b is continuous
+
+                /// anywhere else
+                /// (2ad+b)_{i-1} = b_{i}
+                /// (ad+(y1-y0)/d)_{i-1} = b_{i}
+                weights[2] = startPt;
+                weights[1] = previousSeg.weights[0]*prevApproxLen*2.f+previousSeg.weights[1];
+                weights[0] = ((endPt-startPt)/currentApproxLen-weights[1])/currentApproxLen;
+
+                finalize(currentApproxLen);
+            }
+            static Segment createForBSpline(const vectorSIMDf& startPt, const vectorSIMDf& midCtrl, const vectorSIMDf& endPt)
+            {
+                Segment seg;
+                seg.weights[2] = startPt;
+                seg.weights[1] = (midCtrl-startPt)*2.f;
+                seg.weights[0] = endPt+startPt-midCtrl*2.f;
+
+                float bLen = dot(seg.weights[1],seg.weights[1]).X;
+                if (bLen<0.000001f)
+                {
+                    seg.weights[1] = endPt-startPt;
+                    seg.weights[0].set(0.f,0.f,0.f);
+                }
+                else if (std::abs(dot(seg.weights[2],seg.weights[1]).X)>std::sqrt(bLen*dot(seg.weights[2],seg.weights[2]).X)*0.999999f)
+                {
+                    seg.weights[1] = endPt-startPt;
+                    seg.weights[0].set(0.f,0.f,0.f);
+                }
+
+                seg.finalize(1.f);
+                return seg;
+            }
+
+            inline void finalize(const float &currentApproxLen)
+            {
+                parameterLength = currentApproxLen;
+
+                lenASq       = dot(weights[0],weights[0]).x;
+                double lenCSq= dot(weights[1],weights[1]).x;
+                lenC         = std::sqrt(lenCSq);
+                if (std::abs(lenASq)>0.000001f)
+                {
+                    /// integral sqrt(a x^2 + b x + c) dx =
+                    /// ((2 a x + b) sqrt(x (a x + b) + c))/(4 a) - ((b^2 - 4 a c) log(2 sqrt(a) sqrt(x (a x + b) + c) + 2 a x + b))/(8 a^(3/2))
+                    /// @ x=0
+                    /// (b sqrt(c))/(4 a) - ((b^2 - 4 a c) log(2 sqrt(a) sqrt(c) + b))/(8 a^(3/2))
+                    double term_b       = 4.f*dot(weights[1],weights[0]).x;
+                    double lenASq_4     = lenASq*16.f;
+                    double lenA_2       = std::sqrt(lenASq_4);
+
+                    double lenBSq       = dot(weights[1],weights[1]).x;
+
+                    /// integral sqrt(a x^2 + b x + c) dx =
+                    /// ((2 a x + b) sqrt(x (a x + b) + c))/(4 a) - ((b^2 - 4 a c) log(2 sqrt(a) sqrt(x (a x + b) + c) + 2 a x + b))/(8 a^(3/2))
+                    /// ((0.5 x + b/4a) sqrt(x (a x + b) + c)) - ((b*b/4a - c) log(2 sqrt(a) sqrt(x (a x + b) + c) + 2 a x + b))/(2 a^(1/2))
+                    /// differential
+                    /// ((2 a x + b) sqrt(x (a x + b) + c))/(4 a) - ((b^2 - 4 a c) log(2 sqrt(a) sqrt(x (a x + b) + c) + 2 a x + b))/(8 a^(3/2))
+                    arcCalcConstants[0] = term_b/lenASq_4;
+                    arcCalcConstants[1] = lenASq*4.f;
+                    arcCalcConstants[2] = term_b;
+                    arcCalcConstants[3] = lenCSq;
+                    arcCalcConstants[4] = (arcCalcConstants[3]-term_b*arcCalcConstants[0])/lenA_2;
+                    arcCalcConstants[5] = lenA_2;
+
+                    //lowerIntegralValue      = 0.f;
+                    //lowerIntegralValue      = getArcLenFromParameter(0.f);
+                    lowerIntegralValue      = arcCalcConstants[0]*lenC+arcCalcConstants[4]*log(arcCalcConstants[5]*lenC+term_b);
+
+                    length = getArcLenFromParameter(parameterLength);
+                }
+                else
+                {
+                    length = lenC*parameterLength;
+                    lenC_reciprocal = reciprocal(lenC);
+                }
+            }
+
+            inline float getArcLenFromParameter(const float &parameter) const
+            {
+                //assert(std::abs(lenASq)>0.000001f);
+
+                double ax = arcCalcConstants[1]*parameter;
+                double ax_b = ax+arcCalcConstants[2];
+                double theSquareRoot = std::sqrt(parameter*ax_b+arcCalcConstants[3]);
+                float higherIntTerm    = (0.5f*parameter+arcCalcConstants[0])*theSquareRoot+arcCalcConstants[4]*log(arcCalcConstants[5]*theSquareRoot+ax_b+ax);
+/*
+                double a = dot(weights[0],weights[0]).x;
+                double b = dot(weights[0],weights[1]).x*2.f;
+                double c = dot(weights[1],weights[1]).x;
+                double higherIntTerm = ((2.f* a* parameter + b)*std::sqrt(parameter* (a *parameter + b) + c))/(4.f* a) - ((b*b - 4*a*c)*log(2.f*std::sqrt(a)*std::sqrt(parameter*(a*parameter + b) + c) + 2.f*a*parameter + b))/(8.f*a*std::sqrt(a));
+*/
+/*
+                /// extreme debug
+                double checkLen = 0.0;
+                vectorSIMDf prevPoint = weights[2];
+                for (size_t i=1; i<=1024*16; i++)
+                {
+                    double tmp = double(i)/double(1024*16);
+                    tmp *= parameter;
+                    vectorSIMDf nextPoint = posHelper(tmp);
+                    checkLen += (prevPoint - nextPoint).getLengthAsFloat();
+                    prevPoint = nextPoint;
+                }
+                float diff = std::abs(higherIntTerm-lowerIntegralValue-checkLen);
+                assert(diff<0.001f);
+*/
+                return higherIntTerm-lowerIntegralValue;
+            }
+
+            inline float getParameterFromArcLen(const float& arcLen, float parameterHint, const float& accuracyThresh) const
+            {
+                if (std::abs(lenASq)>0.000001f)
+                {
+                    if (arcLen<=accuracyThresh)
+                        return arcLen;
+                    if (arcLen>=length-accuracyThresh)
+                        return parameterLength;
+                    if (parameterHint<0.f||parameterHint>parameterLength)
+                        parameterHint = parameterLength*(arcLen/length);
+                    /// dist = IndefInt(param) - lowerIntVal
+                    /// IndefInt^-1(dist+lowerIntVal) = param
+                    /// Newton-Raphson      f = arcLen - getArcLenFromParameter(parameterHint);
+                    /// Newton-Raphson      f' = -getArcLenFromParameter'(parameterHint);
+                    float arcLenDiffAtParamGuess = arcLen-getArcLenFromParameter(parameterHint);
+                    for (size_t i=0; std::abs(arcLenDiffAtParamGuess)>accuracyThresh&&i<32; i++)
+                    {
+                        float differentialAtGuess = directionHelper(parameterHint).getLengthAsFloat();
+                        parameterHint = parameterHint+arcLenDiffAtParamGuess/differentialAtGuess;
+                        arcLenDiffAtParamGuess = arcLen-getArcLenFromParameter(parameterHint);
+                    }
+                    return parameterHint;
+                }
+                else
+                    return arcLen*lenC_reciprocal;
+            }
+
+            inline vectorSIMDf posHelper(const float& parameter) const
+            {
+                return (weights[0]*parameter+weights[1])*parameter+weights[2];
+            }
+            inline vectorSIMDf directionHelper(const float& parameter) const
+            {
+                return weights[0]*parameter*2.f+weights[1];
+            }/*
+            inline float findNextBlockChange(const float& param) const
+            {
+                vectorSIMDf startingNegFrac = posHelper(param);
+                startingNegFrac = floor(startingNegFrac)-startingNegFrac;
+                vectorSIMDf dir = directionHelper(param);
+                float changes[3];
+                for (uint32_t i=0; i<3; i++)
+                    changes[i] = findChange(startingNegFrac.pointer[i],dir.pointer[i]);
+
+                float smallest;
+                if (reinterpret_cast<uint32_t*>(changes)[0]<=reinterpret_cast<uint32_t*>(changes)[1])
+                {
+                    if (reinterpret_cast<uint32_t*>(changes)[2]<=reinterpret_cast<uint32_t*>(changes)[0])
+                        smallest = changes[2];
+                    else
+                        smallest = changes[0];
+                }
+                else if (reinterpret_cast<uint32_t*>(changes)[2]<=reinterpret_cast<uint32_t*>(changes)[1])
+                {
+                    smallest = changes[2];
+                }
+                else
+                    smallest = changes[1];
+
+                smallest_+= param;
+                if (smallest<length)
+                    return smallest;
+
+                return -1.f;
+            }
+            inline float findChange(const float& currentNegFrac, const float& changePerParam) const
+            {
+                if (currentNegFrac==0.f||currentNegFrac==1.f)
+                    return 0.f;
+
+                if (changePerParam < -FLT_MIN)
+                    return currentNegFrac/changePerParam;
+                else if (changePerParam > FLT_MIN)
+                    return (1.f+currentNegFrac)/changePerParam;
+
+                return -1.f;
+            }*/
+
+
+            float length,parameterLength,lenASq,lowerIntegralValue;
+            union
+            {
+                float lenC;
+                float lenC_reciprocal;
+            };
+            float arcCalcConstants[6];
+            vectorSIMDf weights[3];
+
+            private:
+                Segment() {}
+        };
+
+        core::array<Segment> segments;
+        float splineLen;
+};
+
+
+//! Loop code is wrong for now, unable to calculate A_0 so the gradients match all the way around the loop
+class CQuadraticBSpline : public CQuadraticSpline
+{
+    public:
+        CQuadraticBSpline(vectorSIMDf* controlPoints, const size_t& count, const bool loop = false) : CQuadraticSpline(loop)
+        {
+            //assert(count<0x80000000u && count);
+            vectorSIMDf firstMidpoint = (controlPoints[0]+controlPoints[1])*0.5f;
+            if (isLoop)
+            {
+                segments.push_back(Segment::createForBSpline((controlPoints[count-1]+controlPoints[0])*0.5f,controlPoints[0],firstMidpoint));
+            }
+            else
+            {
+                segments.push_back(Segment::createForBSpline(controlPoints[0],controlPoints[0],firstMidpoint));
+            }
+
+            vectorSIMDf midpoint = firstMidpoint;
+            vectorSIMDf lastMid = midpoint;
+            for (size_t i=2; i<count; i++)
+            {
+                midpoint = (controlPoints[i-1]+controlPoints[i])*0.5f;
+                segments.push_back(Segment::createForBSpline(lastMid,controlPoints[i-1],midpoint));
+                lastMid = midpoint;
+            }
+
+            if (isLoop)
+            {
+                segments.push_back(Segment::createForBSpline(lastMid,controlPoints[count-1],segments[0].weights[2]));
+            }
+            else
+            {
+                segments.push_back(Segment::createForBSpline(lastMid,lastMid,controlPoints[count-1]));
+            }
+
+            finalize();
+        }
+};
+
+/*
+class CCubicSpline : public ISpline
+{
+    public:
+        CCubicSpline(vectorSIMDf* controlPoints, const size_t& count, const bool loop = false) : isLoop(loop)
+        {
+            //assert(count<0x80000000u);
+            finalize();
+        }
+        CCubicSpline(vectorSIMDf* controlPointsPos, bool* discontinuityPoints, const size_t& count, const bool loop = false) : isLoop(loop)
+        {
+            //assert(count<0x80000000u);
+            finalize();
+        }
+
+        //
+        virtual bool        isLoop() const {return isLoop;}
+        virtual size_t      getSegmentCount() const
+        {
+            return segments.size();
+        }
+        virtual float       getSplineLength() const
+        {
+            return splineLen;
+        }
+
+        //
+        virtual void        getSegmentLengths(float* outSegLens) const
+        {
+            for (size_t i=0; i<segments.size(); i++)
+                outSegLens[i] = segments[i].length;
+        }
+        virtual float       getSegmentLength(const uint32_t& segmentID) const
+        {
+            //assert(segmentID<segments.size());
+            return segments[segmentID].length;
+        }
+
+        //get position
+        //this function returns the id of the segment you might have moved into - 0xdeadbeefu is an error code
+        virtual uint32_t    getPos(vectorSIMDf& pos, const uint32_t& segmentID, float distance) const
+        {
+            uint32_t actualSeg;
+            if (isLoop)
+            {
+                actualSeg = segmentID%segments.size();
+                while (distance>=segments[actualSeg].length)
+                {
+                    distance -= segments[actualSeg].length;
+                    actualSeg++;
+                    if (actualSeg==segments.size())
+                        actualSeg = 0;
+                }
+            }
+            else
+            {
+                if (segmentID>=segments.size())
+                    return 0xdeadbeefu;
+
+                actualSeg = segmentID;
+                while (distance>=segments[actualSeg].length)
+                {
+                    distance -= segments[actualSeg].length;
+                    actualSeg++;
+                    if (actualSeg==segments.size())
+                        return 0xdeadbeefu;
+                }
+            }
+
+            float interpol = findFraction(actualSeg,distance);
+            pos = fractionHelper(actualSegment,interpol);
+
+            return true;
+        }
+        virtual bool        getPos_fromFraction(vectorSIMDf& pos, const uint32_t& segmentID, const float& interpolant) const
+        {
+            if (interpolant<0.f||interpolant>=1.f||segmentID>=segments.size())
+                return false;
+
+            pos = fractionHelper(segmentID,interpolant);
+
+            return true;
+        }
+
+        //to get direction to look in
+        virtual bool        getUnnormDirection(vectorSIMDf& tan, const uint32_t& segmentID, const float& distance)
+        {
+            if (segmentID>=segments.size()||distance>segments[segmentID].length)
+                return 0xdeadbeefu;
+
+            float interpol = findFraction(segmentID,distance);
+            tan = directionHelper(segmentID,interpol);
+
+            return true;
+        }
+        virtual bool        getUnnormDirection_fromFraction(vectorSIMDf& tan, const uint32_t& segmentID, const float& interpolant) const
+        {
+            if (interpolant<0.f||interpolant>=1.f||segmentID>=segments.size())
+                return false;
+
+            tan = directionHelper(segmentID,interpolant);
+
+            return true;
+        }
+
+        //baw specific
+        virtual const bool      canGiveParameterUntilBlockChange() const {return true;}
+        // pass in current position
+        virtual float           getParameterUntilBlockChange(const uint32_t& segmentID, const float& distanceAlongSeg) = 0;
+        virtual vector<float>   getBlockChangesInSegment(const uint32_t& segmentID) = 0;
+    private:
+        inline float findFraction(const uint32_t& segmentID, const float& distance) const
+        {
+            //
+        }
+
+        void finalize()
+        {
+            double lenDouble = 0;
+            for (size_t i=0; i<segments.size(); i++)
+            {
+                lenDouble += segments[i].length;
+            }
+            splineLen = lenDouble;
+        }
+
+        bool isLoop;
+
+        struct Segment
+        {
+            Segment(const vectorSIMDf& beforeStart,const vectorSIMDf& startPt,const vectorSIMDf& endPt,const vectorSIMDf& afterEnd)
+            {
+                weights[0] = startPt;
+                weights[1] = endPt-beforeStart;
+                vectorSIMDf a = beforeStart-startPt;
+                vectorSIMDf b = endPt-afterEnd;
+                weights[2] = 2.f*a+b;
+                weights[3] = -b-a;
+
+                length = 0;
+                vectorSIMDf currentPt = endPt;
+                core::array<vectorSIMDf> lenPoints;
+                lenPoints.push_back(startPt);
+                while (lenPoints.size())
+                {
+                    vectorSIMDf diff = currentPt-lenPoints[lenPoints.size()-1];
+                    if (dot(diff,diff)>0.0025)
+                    {
+                        lenPoints[lenPoints.size()-1]
+                    }
+                }
+            }
+
+            inline vectorSIMDf fractionHelper(const float& interpolant) const
+            {
+                return ((weights[0]*interpolant+weights[1])*interpolant+weights[2])*interpolant+weights[3];
+            }
+            inline vectorSIMDf directionHelper(const float& interpolant) const
+            {
+                return (3.f*weights[0]*interpolant+2.f*weights[1])*interpolant+weights[2];
+            }
+
+            float length;
+            vectorSIMDf weights[4];
+        };
+
+        //core::array<vectorSIMDf> controls;
+        core::array<Segment> segments;
+        float splineLen;
+};
+*/
+
+}
+}
+
+#endif
diff --git a/include/vectorSIMD.h b/include/vectorSIMD.h
index 3d87dcd21..c217430a6 100644
--- a/include/vectorSIMD.h
+++ b/include/vectorSIMD.h
@@ -241,7 +241,7 @@ NO BITSHIFTING SUPPORT
 		//! Copy constructor
 		inline vectorSIMDf(const vectorSIMDf& other) {_mm_store_ps(pointer,other.getAsRegister());}
 
-
+/**
         static inline void* operator new(size_t size) throw(std::bad_alloc)
         {
             void *memoryallocatedaligned = 0;
@@ -288,6 +288,8 @@ NO BITSHIFTING SUPPORT
             return p;
         }
         static inline void  operator delete[](void* p,void* t) throw() {}
+**/
+
 /*
 		inline vectorSIMDf(const vectorSIMDu32& other);
 		inline vectorSIMDf(const vectorSIMDi32& other);
@@ -905,7 +907,7 @@ NO BITSHIFTING SUPPORT
 		//! Copy constructor
 		inline vectorSIMD_32(const vectorSIMD_32<T>& other) {_mm_store_si128((__m128i*)pointer,other.getAsRegister());}
 
-
+/**
         static inline void* operator new(size_t size) throw(std::bad_alloc)
         {
             void *memoryallocatedaligned = 0;
@@ -952,6 +954,8 @@ NO BITSHIFTING SUPPORT
             return p;
         }
         static inline void  operator delete[](void* p,void* t) throw() {}
+**/
+
 /*
 		inline vectorSIMDf(const vectorSIMDu32& other);
 		inline vectorSIMDf(const vectorSIMDi32& other);
diff --git a/source/Irrlicht/CCameraSceneNode.cpp b/source/Irrlicht/CCameraSceneNode.cpp
index 26924b0fd..a27605309 100644
--- a/source/Irrlicht/CCameraSceneNode.cpp
+++ b/source/Irrlicht/CCameraSceneNode.cpp
@@ -94,7 +94,7 @@ bool CCameraSceneNode::OnEvent(const SEvent& event)
 
 	// send events to event receiving animators
 
-	ISceneNodeAnimatorList::Iterator ait = Animators.begin();
+	ISceneNodeAnimatorArray::iterator ait = Animators.begin();
 
 	for (; ait != Animators.end(); ++ait)
 		if ((*ait)->isEventReceiverEnabled() && (*ait)->OnEvent(event))
diff --git a/source/Irrlicht/CFileSystem.cpp b/source/Irrlicht/CFileSystem.cpp
index eab4e981a..a2295275a 100644
--- a/source/Irrlicht/CFileSystem.cpp
+++ b/source/Irrlicht/CFileSystem.cpp
@@ -3,7 +3,7 @@
 // For conditions of distribution and use, see copyright notice in irrlicht.h
 
 #include "IrrCompileConfig.h"
-
+#include <list>
 #include "CFileSystem.h"
 #include "IReadFile.h"
 #include "IWriteFile.h"
@@ -18,7 +18,7 @@
 #include "os.h"
 #include "CMemoryFile.h"
 #include "CLimitReadFile.h"
-#include "irrList.h"
+
 
 #if defined (_IRR_WINDOWS_API_)
 	#if !defined ( _WIN32_WCE )
@@ -731,8 +731,39 @@ io::path& CFileSystem::flattenFilename(io::path& directory, const io::path& root
 	}
 	directory = dir;
 	return directory;
-}
-
+}
+/*
+	template<class container>
+	uint32_t split(container& ret, const T* const c, uint32_t count=1, bool ignoreEmptyTokens=true, bool keepSeparators=false) const
+	{
+		if (!c)
+			return 0;
+
+		const uint32_t oldSize=ret.size();
+		uint32_t lastpos = 0;
+		bool lastWasSeparator = false;
+		for (uint32_t i=0; i<used; ++i)
+		{
+			bool foundSeparator = false;
+			for (uint32_t j=0; j<count; ++j)
+			{
+				if (array[i] == c[j])
+				{
+					if ((!ignoreEmptyTokens || i - lastpos != 0) &&
+							!lastWasSeparator)
+						ret.push_back(string<T,TAlloc>(&array[lastpos], i - lastpos));
+					foundSeparator = true;
+					lastpos = (keepSeparators ? i : i + 1);
+					break;
+				}
+			}
+			lastWasSeparator = foundSeparator;
+		}
+		if ((used - 1) > lastpos)
+			ret.push_back(string<T,TAlloc>(&array[lastpos], (used - 1) - lastpos));
+		return ret.size()-oldSize;
+	}
+*/
 
 //! Get the relative filename, relative to the given directory
 path CFileSystem::getRelativeFilename(const path& filename, const path& directory) const
@@ -743,11 +774,11 @@ path CFileSystem::getRelativeFilename(const path& filename, const path& director
 	io::path path1, file, ext;
 	core::splitFilename(getAbsolutePath(filename), &path1, &file, &ext);
 	io::path path2(getAbsolutePath(directory));
-	core::list<io::path> list1, list2;
+	std::list<io::path> list1, list2;
 	path1.split(list1, _IRR_TEXT("/\\"), 2);
 	path2.split(list2, _IRR_TEXT("/\\"), 2);
 	uint32_t i=0;
-	core::list<io::path>::ConstIterator it1,it2;
+	std::list<io::path>::const_iterator it1,it2;
 	it1=list1.begin();
 	it2=list2.begin();
 
diff --git a/source/Irrlicht/CIrrDeviceLinux.cpp b/source/Irrlicht/CIrrDeviceLinux.cpp
index 293ed333b..587d9c80a 100644
--- a/source/Irrlicht/CIrrDeviceLinux.cpp
+++ b/source/Irrlicht/CIrrDeviceLinux.cpp
@@ -757,21 +757,6 @@ bool CIrrDeviceLinux::createWindow()
                     context_attribs[3] = 3;
                     Context = pGlxCreateContextAttribsARB( display, bestFbc, 0, True, context_attribs );
                 } //! everything below will go!
-                if (!Context)
-                {
-                    context_attribs[3] = 2;
-                    Context = pGlxCreateContextAttribsARB( display, bestFbc, 0, True, context_attribs );
-                }
-                if (!Context)
-                {
-                    context_attribs[3] = 1;
-                    Context = pGlxCreateContextAttribsARB( display, bestFbc, 0, True, context_attribs );
-                }
-				if (!Context)
-				{
-					context_attribs[3] = 0;
-					Context = pGlxCreateContextAttribsARB(display, bestFbc, 0, True, context_attribs);
-				}
 
                 if (Context)
                 {
diff --git a/source/Irrlicht/CIrrDeviceSDL.cpp b/source/Irrlicht/CIrrDeviceSDL.cpp
index d1c632f90..2204d911d 100644
--- a/source/Irrlicht/CIrrDeviceSDL.cpp
+++ b/source/Irrlicht/CIrrDeviceSDL.cpp
@@ -9,7 +9,7 @@
 #include "CIrrDeviceSDL.h"
 #include "CSceneManager.h"
 #include "IEventReceiver.h"
-#include "irrList.h"
+
 #include "os.h"
 #include "CTimer.h"
 #include "irrString.h"
diff --git a/source/Irrlicht/CIrrDeviceWin32.cpp b/source/Irrlicht/CIrrDeviceWin32.cpp
index b15b253ec..46ab689f7 100644
--- a/source/Irrlicht/CIrrDeviceWin32.cpp
+++ b/source/Irrlicht/CIrrDeviceWin32.cpp
@@ -9,7 +9,7 @@
 #include "CIrrDeviceWin32.h"
 #include "CSceneManager.h"
 #include "IEventReceiver.h"
-#include "irrList.h"
+#include <list>
 #include "os.h"
 
 #include "CTimer.h"
@@ -604,7 +604,7 @@ namespace
 		HWND hWnd;
 		irr::CIrrDeviceWin32* irrDev;
 	};
-	irr::core::list<SEnvMapper> EnvMap;
+	std::list<SEnvMapper> EnvMap;
 
 	HKL KEYBOARD_INPUT_HKL=0;
 	unsigned int KEYBOARD_INPUT_CODEPAGE = 1252;
@@ -612,7 +612,7 @@ namespace
 
 SEnvMapper* getEnvMapperFromHWnd(HWND hWnd)
 {
-	irr::core::list<SEnvMapper>::Iterator it = EnvMap.begin();
+	std::list<SEnvMapper>::iterator it = EnvMap.begin();
 	for (; it!= EnvMap.end(); ++it)
 		if ((*it).hWnd == hWnd)
 			return &(*it);
@@ -623,7 +623,7 @@ SEnvMapper* getEnvMapperFromHWnd(HWND hWnd)
 
 irr::CIrrDeviceWin32* getDeviceFromHWnd(HWND hWnd)
 {
-	irr::core::list<SEnvMapper>::Iterator it = EnvMap.begin();
+	std::list<SEnvMapper>::iterator it = EnvMap.begin();
 	for (; it!= EnvMap.end(); ++it)
 		if ((*it).hWnd == hWnd)
 			return (*it).irrDev;
@@ -1068,7 +1068,7 @@ CIrrDeviceWin32::~CIrrDeviceWin32()
 
 	// unregister environment
 
-	irr::core::list<SEnvMapper>::Iterator it = EnvMap.begin();
+	std::list<SEnvMapper>::iterator it = EnvMap.begin();
 	for (; it!= EnvMap.end(); ++it)
 	{
 		if ((*it).hWnd == HWnd)
diff --git a/source/Irrlicht/CIrrDeviceWinCE.cpp b/source/Irrlicht/CIrrDeviceWinCE.cpp
deleted file mode 100644
index f192d0364..000000000
--- a/source/Irrlicht/CIrrDeviceWinCE.cpp
+++ /dev/null
@@ -1,868 +0,0 @@
-// Copyright (C) 2002-2012 Nikolaus Gebhardt
-// This file is part of the "Irrlicht Engine".
-// For conditions of distribution and use, see copyright notice in irrlicht.h
-
-#include "IrrCompileConfig.h"
-
-#ifdef _IRR_COMPILE_WITH_WINDOWS_CE_DEVICE_
-
-#include "CIrrDeviceWinCE.h"
-#include "IEventReceiver.h"
-#include "irrList.h"
-#include "os.h"
-
-#include "CTimer.h"
-#include "irrString.h"
-#include "COSOperator.h"
-#include "dimension2d.h"
-#include <winuser.h>
-#include "irrlicht.h"
-
-#ifdef _MSC_VER
-	#pragma comment (lib, "aygshell.lib")
-#endif
-
-
-namespace irr
-{
-	namespace video
-	{
-		#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_
-		IVideoDriver* createDirectX8Driver(const irr::SIrrlichtCreationParameters& params,
-			io::IFileSystem* io, HWND window);
-		#endif
-
-		#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
-		IVideoDriver* createDirectX9Driver(const irr::SIrrlichtCreationParameters& params,
-			io::IFileSystem* io, HWND window);
-		#endif
-
-		#ifdef _IRR_COMPILE_WITH_OPENGL_
-		IVideoDriver* createOpenGLDriver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io, this);
-		#endif
-	}
-} // end namespace irr
-
-
-
-struct SEnvMapper
-{
-	HWND hWnd;
-	irr::CIrrDeviceWinCE* irrDev;
-};
-
-irr::core::list<SEnvMapper> EnvMap;
-
-SEnvMapper* getEnvMapperFromHWnd(HWND hWnd)
-{
-	irr::core::list<SEnvMapper>::Iterator it = EnvMap.begin();
-	for (; it!= EnvMap.end(); ++it)
-		if ((*it).hWnd == hWnd)
-			return &(*it);
-
-	return 0;
-}
-
-irr::CIrrDeviceWinCE* getDeviceFromHWnd(HWND hWnd)
-{
-	irr::core::list<SEnvMapper>::Iterator it = EnvMap.begin();
-	for (; it!= EnvMap.end(); ++it)
-		if ((*it).hWnd == hWnd)
-			return (*it).irrDev;
-
-	return 0;
-}
-
-
-LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
-	#ifndef WM_MOUSEWHEEL
-	#define WM_MOUSEWHEEL 0x020A
-	#endif
-	#ifndef WHEEL_DELTA
-	#define WHEEL_DELTA 120
-	#endif
-
-	irr::CIrrDeviceWinCE* dev = 0;
-	irr::SEvent event;
-	SEnvMapper* envm = 0;
-
-	//BYTE allKeys[256];
-
-	static int32_t ClickCount=0;
-	if (GetCapture() != hWnd && ClickCount > 0)
-		ClickCount = 0;
-
-	switch (message)
-	{
-	case WM_PAINT:
-		{
-			PAINTSTRUCT ps;
-			BeginPaint(hWnd, &ps);
-			EndPaint(hWnd, &ps);
-		}
-		return 0;
-
-	case WM_ERASEBKGND:
-		return 0;
-
-	case WM_SETCURSOR:
-		envm = getEnvMapperFromHWnd(hWnd);
-		if (envm && !envm->irrDev->getWin32CursorControl()->isVisible())
-		{
-			SetCursor(NULL);
-			return 0;
-		}
-		break;
-
-	case WM_MOUSEWHEEL:
-		event.EventType = irr::EET_MOUSE_INPUT_EVENT;
-		event.MouseInput.Wheel = ((float)((short)HIWORD(wParam))) / (float)WHEEL_DELTA;
-		event.MouseInput.Event = irr::EMIE_MOUSE_WHEEL;
-
-		POINT p; // fixed by jox
-		p.x = 0; p.y = 0;
-		ClientToScreen(hWnd, &p);
-		event.MouseInput.X = LOWORD(lParam) - p.x;
-		event.MouseInput.Y = HIWORD(lParam) - p.y;
-		event.MouseInput.Shift = ((LOWORD(wParam) & MK_SHIFT) != 0);
-		event.MouseInput.Control = ((LOWORD(wParam) & MK_CONTROL) != 0);
-		// left and right mouse buttons
-		event.MouseInput.ButtonStates = wParam & ( MK_LBUTTON | MK_RBUTTON);
-		// middle and extra buttons
-		if (wParam & MK_MBUTTON)
-			event.MouseInput.ButtonStates |= irr::EMBSM_MIDDLE;
-
-		dev = getDeviceFromHWnd(hWnd);
-		if (dev)
-			dev->postEventFromUser(event);
-		break;
-
-	case WM_LBUTTONDOWN:
-		ClickCount++;
-		SetCapture(hWnd);
-		event.EventType = irr::EET_MOUSE_INPUT_EVENT;
-		event.MouseInput.Event = irr::EMIE_LMOUSE_PRESSED_DOWN;
-		event.MouseInput.X = (short)LOWORD(lParam);
-		event.MouseInput.Y = (short)HIWORD(lParam);
-		event.MouseInput.Shift = ((LOWORD(wParam) & MK_SHIFT) != 0);
-		event.MouseInput.Control = ((LOWORD(wParam) & MK_CONTROL) != 0);
-		// left and right mouse buttons
-		event.MouseInput.ButtonStates = wParam & ( MK_LBUTTON | MK_RBUTTON);
-		// middle and extra buttons
-		if (wParam & MK_MBUTTON)
-			event.MouseInput.ButtonStates |= irr::EMBSM_MIDDLE;
-
-		dev = getDeviceFromHWnd(hWnd);
-		if (dev)
-			dev->postEventFromUser(event);
-		return 0;
-
-	case WM_LBUTTONUP:
-		ClickCount--;
-		if (ClickCount<1)
-		{
-			ClickCount=0;
-			ReleaseCapture();
-		}
-		event.EventType = irr::EET_MOUSE_INPUT_EVENT;
-		event.MouseInput.Event = irr::EMIE_LMOUSE_LEFT_UP;
-		event.MouseInput.X = (short)LOWORD(lParam);
-		event.MouseInput.Y = (short)HIWORD(lParam);
-		event.MouseInput.Shift = ((LOWORD(wParam) & MK_SHIFT) != 0);
-		event.MouseInput.Control = ((LOWORD(wParam) & MK_CONTROL) != 0);
-		// left and right mouse buttons
-		event.MouseInput.ButtonStates = wParam & ( MK_LBUTTON | MK_RBUTTON);
-		// middle and extra buttons
-		if (wParam & MK_MBUTTON)
-			event.MouseInput.ButtonStates |= irr::EMBSM_MIDDLE;
-
-		dev = getDeviceFromHWnd(hWnd);
-		if (dev)
-			dev->postEventFromUser(event);
-		return 0;
-
-	case WM_RBUTTONDOWN:
-		ClickCount++;
-		SetCapture(hWnd);
-		event.EventType = irr::EET_MOUSE_INPUT_EVENT;
-		event.MouseInput.Event = irr::EMIE_RMOUSE_PRESSED_DOWN;
-		event.MouseInput.X = (short)LOWORD(lParam);
-		event.MouseInput.Y = (short)HIWORD(lParam);
-		event.MouseInput.Shift = ((LOWORD(wParam) & MK_SHIFT) != 0);
-		event.MouseInput.Control = ((LOWORD(wParam) & MK_CONTROL) != 0);
-		// left and right mouse buttons
-		event.MouseInput.ButtonStates = wParam & ( MK_LBUTTON | MK_RBUTTON);
-		// middle and extra buttons
-		if (wParam & MK_MBUTTON)
-			event.MouseInput.ButtonStates |= irr::EMBSM_MIDDLE;
-
-		dev = getDeviceFromHWnd(hWnd);
-		if (dev)
-			dev->postEventFromUser(event);
-		return 0;
-
-	case WM_RBUTTONUP:
-		ClickCount--;
-		if (ClickCount<1)
-		{
-			ClickCount=0;
-			ReleaseCapture();
-		}
-		event.EventType = irr::EET_MOUSE_INPUT_EVENT;
-		event.MouseInput.Event = irr::EMIE_RMOUSE_LEFT_UP;
-		event.MouseInput.X = (short)LOWORD(lParam);
-		event.MouseInput.Y = (short)HIWORD(lParam);
-		event.MouseInput.Shift = ((LOWORD(wParam) & MK_SHIFT) != 0);
-		event.MouseInput.Control = ((LOWORD(wParam) & MK_CONTROL) != 0);
-		// left and right mouse buttons
-		event.MouseInput.ButtonStates = wParam & ( MK_LBUTTON | MK_RBUTTON);
-		// middle and extra buttons
-		if (wParam & MK_MBUTTON)
-			event.MouseInput.ButtonStates |= irr::EMBSM_MIDDLE;
-
-		dev = getDeviceFromHWnd(hWnd);
-		if (dev)
-			dev->postEventFromUser(event);
-		return 0;
-
-	case WM_MBUTTONDOWN:
-		ClickCount++;
-		SetCapture(hWnd);
-		event.EventType = irr::EET_MOUSE_INPUT_EVENT;
-		event.MouseInput.Event = irr::EMIE_MMOUSE_PRESSED_DOWN;
-		event.MouseInput.X = (short)LOWORD(lParam);
-		event.MouseInput.Y = (short)HIWORD(lParam);
-		event.MouseInput.Shift = ((LOWORD(wParam) & MK_SHIFT) != 0);
-		event.MouseInput.Control = ((LOWORD(wParam) & MK_CONTROL) != 0);
-		// left and right mouse buttons
-		event.MouseInput.ButtonStates = wParam & ( MK_LBUTTON | MK_RBUTTON);
-		// middle and extra buttons
-		if (wParam & MK_MBUTTON)
-			event.MouseInput.ButtonStates |= irr::EMBSM_MIDDLE;
-
-		dev = getDeviceFromHWnd(hWnd);
-		if (dev)
-			dev->postEventFromUser(event);
-		return 0;
-
-	case WM_MBUTTONUP:
-		ClickCount--;
-		if (ClickCount<1)
-		{
-			ClickCount=0;
-			ReleaseCapture();
-		}
-		event.EventType = irr::EET_MOUSE_INPUT_EVENT;
-		event.MouseInput.Event = irr::EMIE_MMOUSE_LEFT_UP;
-		event.MouseInput.X = (short)LOWORD(lParam);
-		event.MouseInput.Y = (short)HIWORD(lParam);
-		event.MouseInput.Shift = ((LOWORD(wParam) & MK_SHIFT) != 0);
-		event.MouseInput.Control = ((LOWORD(wParam) & MK_CONTROL) != 0);
-		// left and right mouse buttons
-		event.MouseInput.ButtonStates = wParam & ( MK_LBUTTON | MK_RBUTTON);
-		// middle and extra buttons
-		if (wParam & MK_MBUTTON)
-			event.MouseInput.ButtonStates |= irr::EMBSM_MIDDLE;
-
-		dev = getDeviceFromHWnd(hWnd);
-		if (dev)
-			dev->postEventFromUser(event);
-		return 0;
-
-	case WM_MOUSEMOVE:
-		event.EventType = irr::EET_MOUSE_INPUT_EVENT;
-		event.MouseInput.Event = irr::EMIE_MOUSE_MOVED;
-		event.MouseInput.X = (short)LOWORD(lParam);
-		event.MouseInput.Y = (short)HIWORD(lParam);
-		event.MouseInput.Shift = ((LOWORD(wParam) & MK_SHIFT) != 0);
-		event.MouseInput.Control = ((LOWORD(wParam) & MK_CONTROL) != 0);
-		// left and right mouse buttons
-		event.MouseInput.ButtonStates = wParam & ( MK_LBUTTON | MK_RBUTTON);
-		// middle and extra buttons
-		if (wParam & MK_MBUTTON)
-			event.MouseInput.ButtonStates |= irr::EMBSM_MIDDLE;
-
-		dev = getDeviceFromHWnd(hWnd);
-		if (dev)
-			dev->postEventFromUser(event);
-
-		return 0;
-
-	case WM_SYSKEYDOWN:
-	case WM_SYSKEYUP:
-	case WM_KEYDOWN:
-	case WM_KEYUP:
-		{
-			event.EventType = irr::EET_KEY_INPUT_EVENT;
-			event.KeyInput.Key = (irr::EKEY_CODE)wParam;
-			event.KeyInput.PressedDown = (message==WM_KEYDOWN || message == WM_SYSKEYDOWN);
-			dev = getDeviceFromHWnd(hWnd);
-/*
-			WORD KeyAsc=0;
-			GetKeyboardState(allKeys);
-			ToAscii(wParam,lParam,allKeys,&KeyAsc,0);
-*/
-//			event.KeyInput.Shift = ((allKeys[VK_SHIFT] & 0x80)!=0);
-//			event.KeyInput.Control = ((allKeys[VK_CONTROL] & 0x80)!=0);
-//			event.KeyInput.Char = (KeyAsc & 0x00ff); //KeyAsc >= 0 ? KeyAsc : 0;
-
-			if (dev)
-				dev->postEventFromUser(event);
-
-			return 0;
-		}
-
-	case WM_SIZE:
-	{
-		// resize
-		dev = getDeviceFromHWnd(hWnd);
-		if (dev)
-			dev->OnResized();
-	}
-	return 0;
-
-	case WM_DESTROY:
-		PostQuitMessage(0);
-		return 0;
-
-	}
-
-	return DefWindowProc(hWnd, message, wParam, lParam);
-}
-
-namespace irr
-{
-
-//! constructor
-CIrrDeviceWinCE::CIrrDeviceWinCE(const SIrrlichtCreationParameters& params)
-: CIrrDeviceStub(params), HWnd(0),
-	Win32CursorControl(0), ChangedToFullScreen(false), Resized(false),
-	ExternalWindow(false)
-{
-	#ifdef _DEBUG
-	setDebugName("CIrrDeviceWinCE");
-	#endif
-
-	core::stringc winversion;
-	getWindowsVersion(winversion);
-	Operator = new COSOperator(winversion);
-	os::Printer::log(winversion.c_str(), ELL_INFORMATION);
-
-	HINSTANCE hInstance = GetModuleHandle(0);
-
-	// create the window only if we do not use the null device
-	if (!CreationParams.WindowId && (CreationParams.DriverType != video::EDT_NULL))
-	{
-		const wchar_t* ClassName = L"CIrrDeviceWinCE";
-
-		// Register Class
-		WNDCLASS wc;
-		wc.style		= CS_HREDRAW | CS_VREDRAW;
-		wc.lpfnWndProc		= WndProc;
-		wc.cbClsExtra		= 0;
-		wc.cbWndExtra		= 0;
-		wc.hInstance		= hInstance;
-		wc.hIcon		= NULL;
-		wc.hCursor		= LoadCursor(NULL, IDC_ARROW);
-		wc.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
-		wc.lpszMenuName		= 0;
-		wc.lpszClassName	= ClassName;
-
-		// if there is an icon, load it
-		wc.hIcon = (HICON)LoadImageW(hInstance, L"irrlicht.ico", IMAGE_ICON, 0,0, 0);
-
-		RegisterClass(&wc);
-
-		// calculate client size
-
-		RECT clientSize;
-		clientSize.top = 0;
-		clientSize.left = 0;
-		clientSize.right = CreationParams.WindowSize.Width;
-		clientSize.bottom = CreationParams.WindowSize.Height;
-
-		DWORD style = WS_POPUP;
-
-		if (!CreationParams.Fullscreen)
-			style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
-
-		AdjustWindowRectEx(&clientSize, style, FALSE, 0);
-
-		const int32_t realWidth = clientSize.right - clientSize.left;
-		const int32_t realHeight = clientSize.bottom - clientSize.top;
-
-		const int32_t windowLeft = core::s32_max ( 0, (GetSystemMetrics(SM_CXSCREEN) - realWidth) >> 1 );
-		const int32_t windowTop = core::s32_max ( 0, (GetSystemMetrics(SM_CYSCREEN) - realHeight) >> 1 );
-
-		// create window
-
-		HWnd = CreateWindowW( ClassName, L"", style, windowLeft, windowTop,
-					realWidth, realHeight,	NULL, NULL, hInstance, NULL);
-
-		ShowWindow(HWnd , SW_SHOW);
-		UpdateWindow(HWnd);
-
-		// fix ugly ATI driver bugs. Thanks to ariaci
-		MoveWindow(HWnd, windowLeft, windowTop, realWidth, realHeight, TRUE);
-	}
-	else if (CreationParams.WindowId)
-	{
-		// attach external window
-		HWnd = static_cast<HWND>(CreationParams.WindowId);
-		RECT r;
-		GetWindowRect(HWnd, &r);
-		CreationParams.WindowSize.Width = r.right - r.left;
-		CreationParams.WindowSize.Height = r.bottom - r.top;
-		CreationParams.Fullscreen = false;
-		ExternalWindow = true;
-	}
-
-	// create cursor control
-
-	Win32CursorControl = new CCursorControl(CreationParams.WindowSize, HWnd, CreationParams.Fullscreen);
-	CursorControl = Win32CursorControl;
-
-	// create driver
-
-	createDriver();
-
-	if (VideoDriver)
-		createGUIAndScene();
-
-	// register environment
-
-	SEnvMapper em;
-	em.irrDev = this;
-	em.hWnd = HWnd;
-	EnvMap.push_back(em);
-
-	// set this as active window
-	SetActiveWindow(HWnd);
-	SetForegroundWindow(HWnd);
-}
-
-
-//! destructor
-CIrrDeviceWinCE::~CIrrDeviceWinCE()
-{
-	// unregister environment
-
-	if (ChangedToFullScreen)
-		SHFullScreen(HWnd, SHFS_SHOWTASKBAR | SHFS_SHOWSTARTICON | SHFS_SHOWSIPBUTTON);
-
-	irr::core::list<SEnvMapper>::Iterator it = EnvMap.begin();
-	for (; it!= EnvMap.end(); ++it)
-		if ((*it).hWnd == HWnd)
-		{
-			EnvMap.erase(it);
-			break;
-		}
-}
-
-
-//! create the driver
-void CIrrDeviceWinCE::createDriver()
-{
-	switch(CreationParams.DriverType)
-	{
-	case video::EDT_DIRECT3D8:
-		#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_
-		VideoDriver = video::createDirectX8Driver(CreationParams, FileSystem, HWnd);
-		if (!VideoDriver)
-		{
-			os::Printer::log("Could not create DIRECT3D8 Driver.", ELL_ERROR);
-		}
-		#else
-		os::Printer::log("DIRECT3D8 Driver was not compiled into this dll. Try another one.", ELL_ERROR);
-		#endif // _IRR_COMPILE_WITH_DIRECT3D_8_
-
-		break;
-
-	case video::EDT_DIRECT3D9:
-		#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
-		VideoDriver = video::createDirectX9Driver(CreationParams, FileSystem, HWnd);
-		if (!VideoDriver)
-		{
-			os::Printer::log("Could not create DIRECT3D9 Driver.", ELL_ERROR);
-		}
-		#else
-		os::Printer::log("DIRECT3D9 Driver was not compiled into this dll. Try another one.", ELL_ERROR);
-		#endif // _IRR_COMPILE_WITH_DIRECT3D_9_
-
-		break;
-
-	case video::EDT_OPENGL:
-
-		#ifdef _IRR_COMPILE_WITH_OPENGL_
-		if (CreationParams.Fullscreen)
-			switchToFullScreen();
-		VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem);
-		if (!VideoDriver)
-		{
-			os::Printer::log("Could not create OpenGL driver.", ELL_ERROR);
-		}
-		#else
-		os::Printer::log("OpenGL driver was not compiled in.", ELL_ERROR);
-		#endif
-		break;
-
-	case video::EDT_SOFTWARE:
-
-		#ifdef _IRR_COMPILE_WITH_SOFTWARE_
-		if (CreationParams.Fullscreen)
-			switchToFullScreen();
-		VideoDriver = video::createSoftwareDriver(CreationParams.WindowSize, CreationParams.Fullscreen, FileSystem, this);
-		#else
-		os::Printer::log("Software driver was not compiled in.", ELL_ERROR);
-		#endif
-
-		break;
-
-	case video::EDT_BURNINGSVIDEO:
-		#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
-		if (CreationParams.Fullscreen)
-			switchToFullScreen();
-		VideoDriver = video::createBurningVideoDriver(CreationParams, FileSystem, this);
-		#else
-		os::Printer::log("Burning's Video driver was not compiled in.", ELL_ERROR);
-		#endif
-		break;
-
-	case video::EDT_NULL:
-		// create null driver
-		VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize);
-		break;
-
-	default:
-		os::Printer::log("Unable to create video driver of unknown type.", ELL_ERROR);
-		break;
-	}
-}
-
-
-//! runs the device. Returns false if device wants to be deleted
-bool CIrrDeviceWinCE::run()
-{
-	os::Timer::tick();
-
-	MSG msg;
-
-	while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
-	{
-		TranslateMessage(&msg);
-
-		if (ExternalWindow && msg.hwnd == HWnd)
-			WndProc(HWnd, msg.message, msg.wParam, msg.lParam);
-		else
-			DispatchMessage(&msg);
-
-		if (msg.message == WM_QUIT)
-			Close = true;
-	}
-
-	if (!Close)
-		resizeIfNecessary();
-
-	_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
-	return !Close;
-}
-
-
-//! Pause the current process for the minimum time allowed only to allow other processes to execute
-void CIrrDeviceWinCE::yield()
-{
-	Sleep(1);
-}
-
-
-//! Pause execution and let other processes to run for a specified amount of time.
-void CIrrDeviceWinCE::sleep(uint32_t timeMs, bool pauseTimer)
-{
-	const bool wasStopped = Timer ? Timer->isStopped() : true;
-	if (pauseTimer && !wasStopped)
-		Timer->stop();
-
-	Sleep(timeMs);
-
-	if (pauseTimer && !wasStopped)
-		Timer->start();
-}
-
-
-void CIrrDeviceWinCE::resizeIfNecessary()
-{
-	if (!Resized)
-		return;
-
-	RECT r;
-	GetClientRect(HWnd, &r);
-
-	char tmp[255];
-
-	if (r.right < 2 || r.bottom < 2)
-	{
-		sprintf(tmp, "Ignoring resize operation to (%ld %ld)", r.right, r.bottom);
-		os::Printer::log(tmp);
-	}
-	else
-	{
-		sprintf(tmp, "Resizing window (%ld %ld)", r.right, r.bottom);
-		os::Printer::log(tmp);
-
-		getVideoDriver()->OnResize(irr::core::dimension2d<uint32_t>(r.right, r.bottom));
-		getWin32CursorControl()->OnResize(getVideoDriver()->getScreenSize());
-	}
-
-	Resized = false;
-}
-
-
-//! sets the caption of the window
-void CIrrDeviceWinCE::setWindowCaption(const std::wstring& text)
-{
-	SetWindowTextW(HWnd, text);
-}
-
-
-#if !defined(BITMAPV4HEADER)
-typedef struct {
-  DWORD        bV4Size;
-  LONG         bV4Width;
-  LONG         bV4Height;
-  WORD         bV4Planes;
-  WORD         bV4BitCount;
-  DWORD        bV4V4Compression;
-  DWORD        bV4SizeImage;
-  LONG         bV4XPelsPerMeter;
-  LONG         bV4YPelsPerMeter;
-  DWORD        bV4ClrUsed;
-  DWORD        bV4ClrImportant;
-  DWORD        bV4RedMask;
-  DWORD        bV4GreenMask;
-  DWORD        bV4BlueMask;
-  DWORD        bV4AlphaMask;
-  DWORD        bV4CSType;
-  DWORD			un[9];
-} BITMAPV4HEADER, *PBITMAPV4HEADER;
-#endif
-
-
-//! presents a surface in the client area
-bool CIrrDeviceWinCE::present(video::IImage* image, void* windowId, core::rect<int32_t>* src)
-{
-	HWND hwnd = HWnd;
-	if ( windowId )
-		hwnd = (HWND)windowId;
-
-	HDC dc = GetDC(hwnd);
-
-	if ( dc )
-	{
-		RECT rect;
-		GetClientRect(hwnd, &rect);
-		const void* memory = (const void *)image->lock();
-
-		BITMAPV4HEADER bi;
-		memset (&bi, 0, sizeof(bi));
-		bi.bV4Size          = sizeof(BITMAPINFOHEADER);
-		bi.bV4BitCount      = image->getBitsPerPixel();
-		bi.bV4Planes        = 1;
-		bi.bV4Width         = image->getDimension().Width;
-		bi.bV4Height        = 0 - image->getDimension().Height;
-		bi.bV4V4Compression = BI_BITFIELDS;
-		bi.bV4AlphaMask     = image->getAlphaMask ();
-		bi.bV4RedMask       = image->getRedMask ();
-		bi.bV4GreenMask     = image->getGreenMask();
-		bi.bV4BlueMask      = image->getBlueMask();
-
-		int r = 0;
-		if ( src )
-		{
-			r = StretchDIBits(dc, 0,0, rect.right, rect.bottom,
-					src->UpperLeftCorner.X, src->UpperLeftCorner.Y,
-					src->getWidth(), src->getHeight(),
-					memory, (const BITMAPINFO*)(&bi), DIB_RGB_COLORS, SRCCOPY);
-		}
-		else
-		{
-			r = StretchDIBits(dc, 0,0, rect.right, rect.bottom,
-					0, 0, image->getDimension().Width, image->getDimension().Height,
-					memory, (const BITMAPINFO*)(&bi), DIB_RGB_COLORS, SRCCOPY);
-		}
-
-		image->unlock();
-
-		ReleaseDC(hwnd, dc);
-	}
-	return true;
-}
-
-
-//! notifies the device that it should close itself
-void CIrrDeviceWinCE::closeDevice()
-{
-	MSG msg;
-	PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE);
-	PostQuitMessage(0);
-	PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE);
-	if (!ExternalWindow)
-	{
-		DestroyWindow(HWnd);
-		const char* ClassName = __TEXT("CIrrDeviceWin32");
-		HINSTANCE hInstance = GetModuleHandle(0);
-		UnregisterClass(ClassName, hInstance);
-	}
-	Close=true;
-}
-
-
-//! returns if window is active. if not, nothing need to be drawn
-bool CIrrDeviceWinCE::isWindowActive() const
-{
-	bool ret = (GetActiveWindow() == HWnd);
-	_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
-	return ret;
-}
-
-
-//! returns if window has focus
-bool CIrrDeviceWinCE::isWindowFocused() const
-{
-	bool ret = (GetFocus() == HWnd);
-	_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
-	return ret;
-}
-
-
-//! returns if window is minimized
-bool CIrrDeviceWinCE::isWindowMinimized() const
-{
-#if 0
-	WINDOWPLACEMENT plc;
-	plc.length=sizeof(WINDOWPLACEMENT);
-	bool ret=false;
-	if (GetWindowPlacement(HWnd,&plc))
-		ret=(plc.showCmd & SW_SHOWMINIMIZED);
-	_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
-	return ret;
-#endif
-	return false;
-}
-
-
-//! switches to fullscreen
-bool CIrrDeviceWinCE::switchToFullScreen()
-{
-	ChangedToFullScreen = SHFullScreen(HWnd, SHFS_HIDESIPBUTTON | SHFS_HIDETASKBAR) != 0;
-	return ChangedToFullScreen;
-}
-
-
-//! returns the win32 cursor control
-CIrrDeviceWinCE::CCursorControl* CIrrDeviceWinCE::getWin32CursorControl()
-{
-	return Win32CursorControl;
-}
-
-
-//! Return pointer to a list with all video modes supported by the gfx adapter.
-/** \return Pointer to video modes list */
-video::IVideoModeList* CIrrDeviceWinCE::getVideoModeList()
-{
-	if (!VideoModeList->getVideoModeCount())
-	{
-		// enumerate video modes.
-		DWORD i=0;
-		DEVMODE mode;
-		memset(&mode, 0, sizeof(mode));
-		mode.dmSize = sizeof(mode);
-
-		while (EnumDisplaySettings(NULL, i, &mode))
-		{
-			VideoModeList->addMode(core::dimension2d<uint32_t>(mode.dmPelsWidth, mode.dmPelsHeight),
-				mode.dmBitsPerPel);
-
-			++i;
-		}
-
-		if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &mode))
-			VideoModeList->setDesktop(mode.dmBitsPerPel, core::dimension2d<uint32_t>(mode.dmPelsWidth, mode.dmPelsHeight));
-	}
-
-	return VideoModeList;
-}
-
-
-void CIrrDeviceWinCE::getWindowsVersion(core::stringc& out)
-{
-	out = "WinCE";
-}
-
-
-//! Notifies the device, that it has been resized
-void CIrrDeviceWinCE::OnResized()
-{
-	Resized = true;
-}
-
-
-//! Sets if the window should be resizable in windowed mode.
-void CIrrDeviceWinCE::setResizable(bool resize)
-{
-	if (ExternalWindow || !getVideoDriver() || CreationParams.Fullscreen)
-		return;
-
-	LONG style = WS_POPUP;
-
-	if (!resize)
-		style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
-	else
-		style = WS_THICKFRAME | WS_SYSMENU | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_MAXIMIZEBOX;
-
-	if (!SetWindowLong(HWnd, GWL_STYLE, style))
-		os::Printer::log("Could not change window style.");
-
-	RECT clientSize;
-	clientSize.top = 0;
-	clientSize.left = 0;
-	clientSize.right = getVideoDriver()->getScreenSize().Width;
-	clientSize.bottom = getVideoDriver()->getScreenSize().Height;
-
-	AdjustWindowRectEx(&clientSize, style, FALSE, 0);
-
-	const int32_t realWidth = clientSize.right - clientSize.left;
-	const int32_t realHeight = clientSize.bottom - clientSize.top;
-
-	const int32_t windowLeft = (GetSystemMetrics(SM_CXSCREEN) - realWidth) / 2;
-	const int32_t windowTop = (GetSystemMetrics(SM_CYSCREEN) - realHeight) / 2;
-
-	SetWindowPos(HWnd, HWND_TOP, windowLeft, windowTop, realWidth, realHeight,
-		SWP_FRAMECHANGED | SWP_NOMOVE | SWP_SHOWWINDOW);
-}
-
-
-//! Minimizes the window.
-void CIrrDeviceWinCE::minimizeWindow()
-{
-	// do nothing
-}
-
-//! Maximize window
-void CIrrDeviceWinCE::maximizeWindow()
-{
-	// do nothing
-}
-
-
-//! Restore original window size
-void CIrrDeviceWinCE::restoreWindow()
-{
-	// do nothing
-}
-
-
-} // end namespace
-
-#endif // _IRR_COMPILE_WITH_WINDOWS_CE_DEVICE_
-
diff --git a/source/Irrlicht/CIrrDeviceWinCE.h b/source/Irrlicht/CIrrDeviceWinCE.h
deleted file mode 100644
index 9210c7197..000000000
--- a/source/Irrlicht/CIrrDeviceWinCE.h
+++ /dev/null
@@ -1,296 +0,0 @@
-// Copyright (C) 2002-2012 Nikolaus Gebhardt
-// This file is part of the "Irrlicht Engine".
-// For conditions of distribution and use, see copyright notice in irrlicht.h
-
-#ifndef __C_IRR_DEVICE_WINCE_H_INCLUDED__
-#define __C_IRR_DEVICE_WINCE_H_INCLUDED__
-
-#include "IrrCompileConfig.h"
-#ifdef _IRR_COMPILE_WITH_WINDOWS_CE_DEVICE_
-
-#include "CIrrDeviceStub.h"
-#include "IrrlichtDevice.h"
-#include "IImagePresenter.h"
-
-#include <windows.h>
-#include <windowsx.h>
-#include <commctrl.h>
-#include <aygshell.h>
-#include <sipapi.h>
-#include <gx.h>
-
-namespace irr
-{
-	class CIrrDeviceWinCE : public CIrrDeviceStub, video::IImagePresenter
-	{
-	public:
-
-		//! constructor
-		CIrrDeviceWinCE( const SIrrlichtCreationParameters& params);
-
-		//! destructor
-		virtual ~CIrrDeviceWinCE();
-
-		//! runs the device. Returns false if device wants to be deleted
-		virtual bool run();
-
-		//! Cause the device to temporarily pause execution and let other processes to run
-		// This should bring down processor usage without major performance loss for Irrlicht
-		virtual void yield();
-
-		//! Pause execution and let other processes to run for a specified amount of time.
-		virtual void sleep(uint32_t timeMs, bool pauseTimer);
-
-		//! sets the caption of the window
-		virtual void setWindowCaption(const std::wstring& text);
-
-		//! returns if window is active. if not, nothing need to be drawn
-		virtual bool isWindowActive() const;
-
-		//! returns if window has focus
-		virtual bool isWindowFocused() const;
-
-		//! returns if window is minimized
-		virtual bool isWindowMinimized() const;
-
-		//! presents a surface in the client area
-		virtual bool present(video::IImage* surface, void* windowId = 0, core::rect<int32_t>* src=0 );
-
-		//! notifies the device that it should close itself
-		virtual void closeDevice();
-
-		//! \return Returns a pointer to a list with all video modes
-		//! supported by the gfx adapter.
-		video::IVideoModeList* getVideoModeList();
-
-		//! Notifies the device, that it has been resized
-		void OnResized();
-
-		//! Sets if the window should be resizable in windowed mode.
-		virtual void setResizable(bool resize=false);
-
-		//! Minimizes the window.
-		virtual void minimizeWindow();
-
-		//! Maximizes the window.
-		virtual void maximizeWindow();
-
-		//! Restores the window size.
-		virtual void restoreWindow();
-
-		//! Get the device type
-		virtual E_DEVICE_TYPE getType() const
-		{
-				return EIDT_WINCE;
-		}
-
-		//! Implementation of the win32 cursor control
-		class CCursorControl : public gui::ICursorControl
-		{
-		public:
-
-			CCursorControl(const core::dimension2d<uint32_t>& wsize, HWND hwnd, bool fullscreen)
-				: WindowSize(wsize), InvWindowSize(0.0f, 0.0f),
-					HWnd(hwnd), BorderX(0), BorderY(0),
-					UseReferenceRect(false), IsVisible(true)
-			{
-				if (WindowSize.Width!=0)
-					InvWindowSize.Width = 1.0f / WindowSize.Width;
-
-				if (WindowSize.Height!=0)
-					InvWindowSize.Height = 1.0f / WindowSize.Height;
-
-				if (!fullscreen)
-				{
-					BorderX = GetSystemMetrics(SM_CXDLGFRAME);
-					BorderY = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYDLGFRAME);
-				}
-			}
-
-			//! Changes the visible state of the mouse cursor.
-			virtual void setVisible(bool visible)
-			{
-				IsVisible = visible;
-			}
-
-			//! Returns if the cursor is currently visible.
-			virtual bool isVisible() const
-			{
-				_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
-				return IsVisible;
-			}
-
-			//! Sets the new position of the cursor.
-			virtual void setPosition(const core::position2d<float> &pos)
-			{
-				setPosition(pos.X, pos.Y);
-			}
-
-			//! Sets the new position of the cursor.
-			virtual void setPosition(float x, float y)
-			{
-				if (!UseReferenceRect)
-					setPosition(core::round32(x*WindowSize.Width), core::round32(y*WindowSize.Height));
-				else
-					setPosition(core::round32(x*ReferenceRect.getWidth()), core::round32(y*ReferenceRect.getHeight()));
-			}
-
-			//! Sets the new position of the cursor.
-			virtual void setPosition(const core::position2d<int32_t> &pos)
-			{
-				setPosition(pos.X, pos.Y);
-			}
-
-			//! Sets the new position of the cursor.
-			virtual void setPosition(int32_t x, int32_t y)
-			{
-				RECT rect;
-
-				if (UseReferenceRect)
-				{
-					SetCursorPos(ReferenceRect.UpperLeftCorner.X + x,
-								 ReferenceRect.UpperLeftCorner.Y + y);
-				}
-				else
-				{
-					if (GetWindowRect(HWnd, &rect))
-						SetCursorPos(x + rect.left + BorderX, y + rect.top + BorderY);
-				}
-
-				CursorPos.X = x;
-				CursorPos.Y = y;
-			}
-
-			//! Returns the current position of the mouse cursor.
-			virtual const core::position2d<int32_t>& getPosition()
-			{
-				updateInternalCursorPosition();
-				return CursorPos;
-			}
-
-			//! Returns the current position of the mouse cursor.
-			virtual core::position2d<float> getRelativePosition()
-			{
-				updateInternalCursorPosition();
-
-				if (!UseReferenceRect)
-				{
-					return core::position2d<float>(CursorPos.X * InvWindowSize.Width,
-						CursorPos.Y * InvWindowSize.Height);
-				}
-
-				return core::position2d<float>(CursorPos.X / (float)ReferenceRect.getWidth(),
-						CursorPos.Y / (float)ReferenceRect.getHeight());
-			}
-
-			//! Sets an absolute reference rect for calculating the cursor position.
-			virtual void setReferenceRect(core::rect<int32_t>* rect=0)
-			{
-				if (rect)
-				{
-					ReferenceRect = *rect;
-					UseReferenceRect = true;
-
-					// prevent division through zero and uneven sizes
-
-					if (!ReferenceRect.getHeight() || ReferenceRect.getHeight()%2)
-						ReferenceRect.LowerRightCorner.Y += 1;
-
-					if (!ReferenceRect.getWidth() || ReferenceRect.getWidth()%2)
-						ReferenceRect.LowerRightCorner.X += 1;
-				}
-				else
-					UseReferenceRect = false;
-			}
-
-			/** Used to notify the cursor that the window was resized. */
-			virtual void OnResize(const core::dimension2d<uint32_t>& size)
-			{
-				WindowSize = size;
-				if (size.Width!=0)
-					InvWindowSize.Width = 1.0f / size.Width;
-				else
-					InvWindowSize.Width = 0.f;
-
-				if (size.Height!=0)
-					InvWindowSize.Height = 1.0f / size.Height;
-				else
-					InvWindowSize.Height = 0.f;
-			}
-
-		private:
-
-			//! Updates the internal cursor position
-			void updateInternalCursorPosition()
-			{
-				POINT p;
-				if (!GetCursorPos(&p))
-				{
-					DWORD xy = GetMessagePos();
-					p.x = GET_X_LPARAM(xy);
-					p.y = GET_Y_LPARAM(xy);
-				}
-
-				if (UseReferenceRect)
-				{
-					CursorPos.X = p.x - ReferenceRect.UpperLeftCorner.X;
-					CursorPos.Y = p.y - ReferenceRect.UpperLeftCorner.Y;
-				}
-				else
-				{
-					RECT rect;
-					if (GetWindowRect(HWnd, &rect))
-					{
-						CursorPos.X = p.x-rect.left-BorderX;
-						CursorPos.Y = p.y-rect.top-BorderY;
-					}
-					else
-					{
-						// window seems not to be existent, so set cursor to
-						// a negative value
-						CursorPos.X = -1;
-						CursorPos.Y = -1;
-					}
-				}
-			}
-
-			core::position2d<int32_t> CursorPos;
-			core::dimension2d<int32_t> WindowSize;
-			core::dimension2d<float> InvWindowSize;
-			HWND HWnd;
-
-			int32_t BorderX, BorderY;
-			core::rect<int32_t> ReferenceRect;
-			bool UseReferenceRect;
-			bool IsVisible;
-		};
-
-
-		//! returns the win32 cursor control
-		CCursorControl* getWin32CursorControl();
-
-	private:
-
-		//! create the driver
-		void createDriver();
-
-		//! switchs to fullscreen
-		bool switchToFullScreen();
-
-		void getWindowsVersion(core::stringc& version);
-
-		void resizeIfNecessary();
-
-		HWND HWnd;
-		CCursorControl* Win32CursorControl;
-
-		bool ChangedToFullScreen;
-		bool Resized;
-		bool ExternalWindow;
-	};
-
-
-} // end namespace irr
-
-#endif // _IRR_COMPILE_WITH_WINDOWS_CE_DEVICE_
-#endif // __C_IRR_DEVICE_WINCE_H_INCLUDED__
diff --git a/source/Irrlicht/CMeshManipulator.cpp b/source/Irrlicht/CMeshManipulator.cpp
index c9c77eeb8..8e6cb3002 100644
--- a/source/Irrlicht/CMeshManipulator.cpp
+++ b/source/Irrlicht/CMeshManipulator.cpp
@@ -7,7 +7,6 @@
 #include "IMeshBuffer.h"
 #include "SAnimatedMesh.h"
 #include "os.h"
-#include "irrMap.h"
 #include <vector>
 
 namespace irr
diff --git a/source/Irrlicht/CNullDriver.h b/source/Irrlicht/CNullDriver.h
index 5d8360c31..f76c4f14a 100644
--- a/source/Irrlicht/CNullDriver.h
+++ b/source/Irrlicht/CNullDriver.h
@@ -11,7 +11,6 @@
 #include "IGPUProgrammingServices.h"
 #include "irrArray.h"
 #include "irrString.h"
-#include "irrMap.h"
 #include "IMesh.h"
 #include "IMeshBuffer.h"
 #include "IMeshSceneNode.h"
diff --git a/source/Irrlicht/COBJMeshFileLoader.cpp b/source/Irrlicht/COBJMeshFileLoader.cpp
index 777393f31..51bc48166 100644
--- a/source/Irrlicht/COBJMeshFileLoader.cpp
+++ b/source/Irrlicht/COBJMeshFileLoader.cpp
@@ -245,16 +245,16 @@ ICPUMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
 				}
 
 				int vertLocation;
-				core::map<SObjVertex, int>::Node* n = currMtl->VertMap.find(v);
-				if (n)
+				std::map<SObjVertex, int>::iterator n = currMtl->VertMap.find(v);
+				if (n!=currMtl->VertMap.end())
 				{
-					vertLocation = n->getValue();
+					vertLocation = n->second;
 				}
 				else
 				{
 					currMtl->Vertices.push_back(v);
 					vertLocation = currMtl->Vertices.size() -1;
-					currMtl->VertMap.insert(v, vertLocation);
+					currMtl->VertMap.insert(std::pair<SObjVertex, int>(v, vertLocation));
 				}
 
 				faceCorners.push_back(vertLocation);
diff --git a/source/Irrlicht/COBJMeshFileLoader.h b/source/Irrlicht/COBJMeshFileLoader.h
index d5a93baad..f4370fc62 100644
--- a/source/Irrlicht/COBJMeshFileLoader.h
+++ b/source/Irrlicht/COBJMeshFileLoader.h
@@ -8,8 +8,7 @@
 #include "IMeshLoader.h"
 #include "IFileSystem.h"
 #include "ISceneManager.h"
-#include "irrString.h"
-#include "irrMap.h"
+#include "irrString.h"
 #include <vector>
 
 namespace irr
@@ -23,32 +22,27 @@ class SObjVertex
 public:
     inline bool operator<(const SObjVertex& other) const
     {
-        if (pos[0]>other.pos[0])
-            return false;
-        else if (pos[0]==other.pos[0])
+        if (pos[0]==other.pos[0])
         {
-            if (pos[1]>other.pos[1])
-                return false;
-            else if (pos[1]==other.pos[1])
+            if (pos[1]==other.pos[1])
             {
-                if (pos[2]>other.pos[2])
-                    return false;
-                else if (pos[2]==other.pos[2])
+                if (pos[2]==other.pos[2])
                 {
-                    if (uv[0]>other.uv[0])
-                        return false;
-                    else if (uv[0]==other.uv[0])
+                    if (uv[0]==other.uv[0])
                     {
-                        if (uv[1]>other.uv[1])
-                            return false;
-                        else if (uv[1]==other.uv[1]&&normal32bit>other.normal32bit)
-                            return false;
+                        if (uv[1]==other.uv[1])
+                            return normal32bit<other.normal32bit;
+
+                        return uv[1]<other.uv[1];
                     }
+                    return uv[0]<other.uv[0];
                 }
+                return pos[2]<other.pos[2];
             }
+            return pos[1]<other.pos[1];
         }
 
-        return true;
+        return pos[0]<other.pos[0];
     }
     inline bool operator==(const SObjVertex& other) const
     {
@@ -145,7 +139,7 @@ class COBJMeshFileLoader : public IMeshLoader
                 Material = o.Material;
             }
 
-            core::map<SObjVertex, int> VertMap;
+            std::map<SObjVertex, int> VertMap;
             std::vector<SObjVertex> Vertices;
             std::vector<uint32_t> Indices;
             video::SMaterial Material;
diff --git a/source/Irrlicht/COpenGLDriver.cpp b/source/Irrlicht/COpenGLDriver.cpp
index 3fedc7757..1830490aa 100644
--- a/source/Irrlicht/COpenGLDriver.cpp
+++ b/source/Irrlicht/COpenGLDriver.cpp
@@ -429,21 +429,6 @@ bool COpenGLDriver::initDriver(CIrrDeviceWin32* device)
 	{
 		iAttribs[3] = 3;
 		hrc=wglCreateContextAttribs_ARB(HDc, 0, iAttribs);
-	} //! everything below will go
-	if (!hrc)
-	{
-		iAttribs[3] = 2;
-		hrc=wglCreateContextAttribs_ARB(HDc, 0, iAttribs);
-	}
-	if (!hrc)
-	{
-		iAttribs[3] = 1;
-		hrc=wglCreateContextAttribs_ARB(HDc, 0, iAttribs);
-	}
-	if (!hrc)
-	{
-		iAttribs[3] = 0;
-		hrc = wglCreateContextAttribs_ARB(HDc, 0, iAttribs);
 	}
 
 	if (!hrc)
@@ -924,16 +909,11 @@ bool COpenGLDriver::genericDriverInit()
 		return false;
     }
 
-    if (Version<400)
-    {
-		os::Printer::log("OpenGL version is less than 4.0", ELL_ERROR);
-		return false;
-    }/*
     if (Version<430)
     {
 		os::Printer::log("OpenGL version is less than 4.3", ELL_ERROR);
 		return false;
-    }*/
+    }
 
     for (size_t i=0; i<MATERIAL_MAX_TEXTURES; i++)
     {
@@ -1911,26 +1891,29 @@ void COpenGLDriver::drawMeshBuffer(scene::IGPUMeshBuffer* mb, IOcclusionQuery* q
         }
     }
 
-    if (((Version<420&&!FeatureAvailable[IRR_ARB_base_instance])||mb->isIndexCountGivenByXFormFeedback())&&mb->getBaseInstance())
+    if (mb->isIndexCountGivenByXFormFeedback())
     {
-        for (size_t i=0; i<scene::EVAI_COUNT; i++)
+        if (mb->getBaseInstance())
         {
-            if (!meshLayoutVAO->getMappedBuffer((scene::E_VERTEX_ATTRIBUTE_ID)i)||!meshLayoutVAO->getAttribDivisor((scene::E_VERTEX_ATTRIBUTE_ID)i))
-                continue;
+            for (size_t i=0; i<scene::EVAI_COUNT; i++)
+            {
+                if (!meshLayoutVAO->getMappedBuffer((scene::E_VERTEX_ATTRIBUTE_ID)i)||!meshLayoutVAO->getAttribDivisor((scene::E_VERTEX_ATTRIBUTE_ID)i))
+                    continue;
 
-            size_t byteOffset = meshLayoutVAO->getMappedBufferStride((scene::E_VERTEX_ATTRIBUTE_ID)i)*mb->getBaseInstance();
-            meshLayoutVAO->setMappedBufferOffset((scene::E_VERTEX_ATTRIBUTE_ID)i,meshLayoutVAO->getMappedBufferOffset((scene::E_VERTEX_ATTRIBUTE_ID)i)+byteOffset);
+                size_t byteOffset = meshLayoutVAO->getMappedBufferStride((scene::E_VERTEX_ATTRIBUTE_ID)i)*mb->getBaseInstance();
+                meshLayoutVAO->setMappedBufferOffset((scene::E_VERTEX_ATTRIBUTE_ID)i,meshLayoutVAO->getMappedBufferOffset((scene::E_VERTEX_ATTRIBUTE_ID)i)+byteOffset);
+            }
         }
-    }
-    if (mb->isIndexCountGivenByXFormFeedback()&&mb->getBaseVertex()!=0)
-    {
-        for (size_t i=0; i<scene::EVAI_COUNT; i++)
+        if (mb->getBaseVertex()!=0)
         {
-            if (!meshLayoutVAO->getMappedBuffer((scene::E_VERTEX_ATTRIBUTE_ID)i)||meshLayoutVAO->getAttribDivisor((scene::E_VERTEX_ATTRIBUTE_ID)i))
-                continue;
+            for (size_t i=0; i<scene::EVAI_COUNT; i++)
+            {
+                if (!meshLayoutVAO->getMappedBuffer((scene::E_VERTEX_ATTRIBUTE_ID)i)||meshLayoutVAO->getAttribDivisor((scene::E_VERTEX_ATTRIBUTE_ID)i))
+                    continue;
 
-            int64_t byteOffset = int64_t(meshLayoutVAO->getMappedBufferStride((scene::E_VERTEX_ATTRIBUTE_ID)i))*mb->getBaseVertex();
-            meshLayoutVAO->setMappedBufferOffset((scene::E_VERTEX_ATTRIBUTE_ID)i,int64_t(meshLayoutVAO->getMappedBufferOffset((scene::E_VERTEX_ATTRIBUTE_ID)i))+byteOffset);
+                int64_t byteOffset = int64_t(meshLayoutVAO->getMappedBufferStride((scene::E_VERTEX_ATTRIBUTE_ID)i))*mb->getBaseVertex();
+                meshLayoutVAO->setMappedBufferOffset((scene::E_VERTEX_ATTRIBUTE_ID)i,int64_t(meshLayoutVAO->getMappedBufferOffset((scene::E_VERTEX_ATTRIBUTE_ID)i))+byteOffset);
+            }
         }
     }
 
@@ -1961,12 +1944,7 @@ void COpenGLDriver::drawMeshBuffer(scene::IGPUMeshBuffer* mb, IOcclusionQuery* q
 	}
 
     if (indexSize)
-    {
-        if (FeatureAvailable[IRR_ARB_base_instance]||Version>=420)
-            extGlDrawElementsInstancedBaseVertexBaseInstance(primType,mb->getIndexCount(),indexSize,(void*)mb->getIndexBufferOffset(),mb->getInstanceCount(),mb->getBaseVertex(),mb->getBaseInstance());
-        else
-            extGlDrawElementsInstancedBaseVertex(primType,mb->getIndexCount(),indexSize,(void*)mb->getIndexBufferOffset(),mb->getInstanceCount(),mb->getBaseVertex());
-    }
+        extGlDrawElementsInstancedBaseVertexBaseInstance(primType,mb->getIndexCount(),indexSize,(void*)mb->getIndexBufferOffset(),mb->getInstanceCount(),mb->getBaseVertex(),mb->getBaseInstance());
     else if (mb->isIndexCountGivenByXFormFeedback())
     {
         COpenGLTransformFeedback* xfmFb = static_cast<COpenGLTransformFeedback*>(mb->getXFormFeedback());
@@ -1976,42 +1954,36 @@ void COpenGLDriver::drawMeshBuffer(scene::IGPUMeshBuffer* mb, IOcclusionQuery* q
         if (mb->getXFormFeedbackStream()>=MaxVertexStreams)
             os::Printer::log("Trying to use more than GL_MAX_VERTEX_STREAMS vertex streams in transform feedback!\n",ELL_ERROR);
 #endif // _DEBUG
-        if (FeatureAvailable[IRR_ARB_transform_feedback_instanced]||Version>=420)
-            extGlDrawTransformFeedbackStreamInstanced(primType,xfmFb->getOpenGLHandle(),mb->getXFormFeedbackStream(),mb->getInstanceCount());
-        else
-        {
-            extGlDrawTransformFeedbackStream(primType,xfmFb->getOpenGLHandle(),mb->getXFormFeedbackStream());
-            if (mb->getInstanceCount()>1)
-                os::Printer::log("Trying To DrawTransformFeedback with multiple instances, ARB_transform_feedback_instanced missing, hence fail!\n",ELL_ERROR);
-        }
+        extGlDrawTransformFeedbackStreamInstanced(primType,xfmFb->getOpenGLHandle(),mb->getXFormFeedbackStream(),mb->getInstanceCount());
     }
-    else if (FeatureAvailable[IRR_ARB_base_instance]||Version>=420)
-        extGlDrawArraysInstancedBaseInstance(primType, mb->getBaseVertex(), mb->getIndexCount(), mb->getInstanceCount(), mb->getBaseInstance());
     else
-        extGlDrawArraysInstanced(primType, mb->getBaseVertex(), mb->getIndexCount(), mb->getInstanceCount());
+        extGlDrawArraysInstancedBaseInstance(primType, mb->getBaseVertex(), mb->getIndexCount(), mb->getInstanceCount(), mb->getBaseInstance());
 
 
 
-    if (((Version<420&&!FeatureAvailable[IRR_ARB_base_instance])||mb->isIndexCountGivenByXFormFeedback())&&mb->getBaseInstance())
+    if (mb->isIndexCountGivenByXFormFeedback())
     {
-        for (size_t i=0; i<scene::EVAI_COUNT; i++)
+        if (mb->getBaseInstance())
         {
-            if (!meshLayoutVAO->getMappedBuffer((scene::E_VERTEX_ATTRIBUTE_ID)i)||!meshLayoutVAO->getAttribDivisor((scene::E_VERTEX_ATTRIBUTE_ID)i))
-                continue;
+            for (size_t i=0; i<scene::EVAI_COUNT; i++)
+            {
+                if (!meshLayoutVAO->getMappedBuffer((scene::E_VERTEX_ATTRIBUTE_ID)i)||!meshLayoutVAO->getAttribDivisor((scene::E_VERTEX_ATTRIBUTE_ID)i))
+                    continue;
 
-            size_t byteOffset = meshLayoutVAO->getMappedBufferStride((scene::E_VERTEX_ATTRIBUTE_ID)i)*mb->getBaseInstance();
-            meshLayoutVAO->setMappedBufferOffset((scene::E_VERTEX_ATTRIBUTE_ID)i,meshLayoutVAO->getMappedBufferOffset((scene::E_VERTEX_ATTRIBUTE_ID)i)-byteOffset);
+                size_t byteOffset = meshLayoutVAO->getMappedBufferStride((scene::E_VERTEX_ATTRIBUTE_ID)i)*mb->getBaseInstance();
+                meshLayoutVAO->setMappedBufferOffset((scene::E_VERTEX_ATTRIBUTE_ID)i,meshLayoutVAO->getMappedBufferOffset((scene::E_VERTEX_ATTRIBUTE_ID)i)-byteOffset);
+            }
         }
-    }
-    if (mb->isIndexCountGivenByXFormFeedback()&&mb->getBaseVertex()!=0)
-    {
-        for (size_t i=0; i<scene::EVAI_COUNT; i++)
+        if (mb->getBaseVertex()!=0)
         {
-            if (!meshLayoutVAO->getMappedBuffer((scene::E_VERTEX_ATTRIBUTE_ID)i)||meshLayoutVAO->getAttribDivisor((scene::E_VERTEX_ATTRIBUTE_ID)i))
-                continue;
+            for (size_t i=0; i<scene::EVAI_COUNT; i++)
+            {
+                if (!meshLayoutVAO->getMappedBuffer((scene::E_VERTEX_ATTRIBUTE_ID)i)||meshLayoutVAO->getAttribDivisor((scene::E_VERTEX_ATTRIBUTE_ID)i))
+                    continue;
 
-            int64_t byteOffset = int64_t(meshLayoutVAO->getMappedBufferStride((scene::E_VERTEX_ATTRIBUTE_ID)i))*mb->getBaseVertex();
-            meshLayoutVAO->setMappedBufferOffset((scene::E_VERTEX_ATTRIBUTE_ID)i,meshLayoutVAO->getMappedBufferOffset((scene::E_VERTEX_ATTRIBUTE_ID)i)-byteOffset);
+                int64_t byteOffset = int64_t(meshLayoutVAO->getMappedBufferStride((scene::E_VERTEX_ATTRIBUTE_ID)i))*mb->getBaseVertex();
+                meshLayoutVAO->setMappedBufferOffset((scene::E_VERTEX_ATTRIBUTE_ID)i,meshLayoutVAO->getMappedBufferOffset((scene::E_VERTEX_ATTRIBUTE_ID)i)-byteOffset);
+            }
         }
     }
 
@@ -2112,15 +2084,7 @@ void COpenGLDriver::drawArraysIndirect(scene::IGPUMeshDataFormatDesc* vao, scene
 
 
     //actual drawing
-    if (FeatureAvailable[IRR_ARB_multi_draw_indirect] || Version>=430)
-    {
-        extGlMultiDrawArraysIndirect(primType,(void*)offset,count,stride);
-    }
-    else
-    {
-        for (size_t i=0; i<count; i++)
-            extGlDrawArraysIndirect(primType,(void*)(offset+i*stride));
-    }
+    extGlMultiDrawArraysIndirect(primType,(void*)offset,count,stride);
 
 
     if (didConditional)
@@ -2220,15 +2184,8 @@ void COpenGLDriver::drawIndexedIndirect(scene::IGPUMeshDataFormatDesc* vao, scen
 
 
     //actual drawing
-    if (FeatureAvailable[IRR_ARB_multi_draw_indirect] || Version>=430)
-    {
-        extGlMultiDrawElementsIndirect(primType,indexSize,(void*)offset,count,stride);
-    }
-    else
-    {
-        for (size_t i=0; i<count; i++)
-            extGlDrawElementsIndirect(primType,indexSize,(void*)(offset+i*stride));
-    }
+    extGlMultiDrawElementsIndirect(primType,indexSize,(void*)offset,count,stride);
+
 
 
     if (didConditional)
diff --git a/source/Irrlicht/COpenGLExtensionHandler.cpp b/source/Irrlicht/COpenGLExtensionHandler.cpp
index fd8c8ae12..138122214 100644
--- a/source/Irrlicht/COpenGLExtensionHandler.cpp
+++ b/source/Irrlicht/COpenGLExtensionHandler.cpp
@@ -197,6 +197,9 @@ PFNGLTEXTUREBUFFERRANGEEXTPROC COpenGLExtensionHandler::pGlTextureBufferRangeEXT
         ///static PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC COpenGLExtensionHandler::pGlTextureStorage2DMultisample = NULL;
         ///static PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC COpenGLExtensionHandler::pGlTextureStorage3DMultisample = NULL;
 PFNGLTEXSUBIMAGE3DPROC COpenGLExtensionHandler::pGlTexSubImage3D = NULL;
+PFNGLMULTITEXSUBIMAGE1DEXTPROC COpenGLExtensionHandler::pGlMultiTexSubImage1DEXT = NULL;
+PFNGLMULTITEXSUBIMAGE2DEXTPROC COpenGLExtensionHandler::pGlMultiTexSubImage2DEXT = NULL;
+PFNGLMULTITEXSUBIMAGE3DEXTPROC COpenGLExtensionHandler::pGlMultiTexSubImage3DEXT = NULL;
 PFNGLTEXTURESUBIMAGE1DPROC COpenGLExtensionHandler::pGlTextureSubImage1D = NULL;
 PFNGLTEXTURESUBIMAGE2DPROC COpenGLExtensionHandler::pGlTextureSubImage2D = NULL;
 PFNGLTEXTURESUBIMAGE3DPROC COpenGLExtensionHandler::pGlTextureSubImage3D = NULL;
@@ -212,6 +215,13 @@ PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC COpenGLExtensionHandler::pGlCompressedTextu
 PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC COpenGLExtensionHandler::pGlCompressedTextureSubImage1DEXT = NULL;
 PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC COpenGLExtensionHandler::pGlCompressedTextureSubImage2DEXT = NULL;
 PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC COpenGLExtensionHandler::pGlCompressedTextureSubImage3DEXT = NULL;
+PFNGLCOPYTEXSUBIMAGE3DPROC COpenGLExtensionHandler::pGlCopyTexSubImage3D = NULL;
+PFNGLCOPYTEXTURESUBIMAGE1DPROC COpenGLExtensionHandler::pGlCopyTextureSubImage1D = NULL;
+PFNGLCOPYTEXTURESUBIMAGE2DPROC COpenGLExtensionHandler::pGlCopyTextureSubImage2D = NULL;
+PFNGLCOPYTEXTURESUBIMAGE3DPROC COpenGLExtensionHandler::pGlCopyTextureSubImage3D = NULL;
+PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC COpenGLExtensionHandler::pGlCopyTextureSubImage1DEXT = NULL;
+PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC COpenGLExtensionHandler::pGlCopyTextureSubImage2DEXT = NULL;
+PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC COpenGLExtensionHandler::pGlCopyTextureSubImage3DEXT = NULL;
 PFNGLGENERATEMIPMAPPROC COpenGLExtensionHandler::pGlGenerateMipmap = NULL;
 PFNGLGENERATETEXTUREMIPMAPPROC COpenGLExtensionHandler::pGlGenerateTextureMipmap = NULL;
 PFNGLGENERATETEXTUREMIPMAPEXTPROC COpenGLExtensionHandler::pGlGenerateTextureMipmapEXT = NULL;
@@ -247,27 +257,29 @@ PFNGLGETPROGRAMINFOLOGPROC COpenGLExtensionHandler::pGlGetProgramInfoLog = NULL;
 PFNGLGETSHADERIVPROC COpenGLExtensionHandler::pGlGetShaderiv = NULL;
 PFNGLGETSHADERIVPROC COpenGLExtensionHandler::pGlGetProgramiv = NULL;
 PFNGLGETUNIFORMLOCATIONPROC COpenGLExtensionHandler::pGlGetUniformLocation = NULL;
-PFNGLUNIFORM1FVPROC COpenGLExtensionHandler::pGlUniform1fv = NULL;
-PFNGLUNIFORM2FVPROC COpenGLExtensionHandler::pGlUniform2fv = NULL;
-PFNGLUNIFORM3FVPROC COpenGLExtensionHandler::pGlUniform3fv = NULL;
-PFNGLUNIFORM4FVPROC COpenGLExtensionHandler::pGlUniform4fv = NULL;
-PFNGLUNIFORM1IVPROC COpenGLExtensionHandler::pGlUniform1iv = NULL;
-PFNGLUNIFORM2IVPROC COpenGLExtensionHandler::pGlUniform2iv = NULL;
-PFNGLUNIFORM3IVPROC COpenGLExtensionHandler::pGlUniform3iv = NULL;
-PFNGLUNIFORM4IVPROC COpenGLExtensionHandler::pGlUniform4iv = NULL;
-PFNGLUNIFORM1UIVPROC COpenGLExtensionHandler::pGlUniform1uiv = NULL;
-PFNGLUNIFORM2UIVPROC COpenGLExtensionHandler::pGlUniform2uiv = NULL;
-PFNGLUNIFORM3UIVPROC COpenGLExtensionHandler::pGlUniform3uiv = NULL;
-PFNGLUNIFORM4UIVPROC COpenGLExtensionHandler::pGlUniform4uiv = NULL;
-PFNGLUNIFORMMATRIX2FVPROC COpenGLExtensionHandler::pGlUniformMatrix2fv = NULL;
-PFNGLUNIFORMMATRIX3FVPROC COpenGLExtensionHandler::pGlUniformMatrix3fv = NULL;
-PFNGLUNIFORMMATRIX4FVPROC COpenGLExtensionHandler::pGlUniformMatrix4fv = NULL;
-PFNGLUNIFORMMATRIX2X3FVPROC COpenGLExtensionHandler::pGlUniformMatrix2x3fv = NULL;
-PFNGLUNIFORMMATRIX2X4FVPROC COpenGLExtensionHandler::pGlUniformMatrix2x4fv = NULL;
-PFNGLUNIFORMMATRIX3X2FVPROC COpenGLExtensionHandler::pGlUniformMatrix3x2fv = NULL;
-PFNGLUNIFORMMATRIX3X4FVPROC COpenGLExtensionHandler::pGlUniformMatrix3x4fv = NULL;
-PFNGLUNIFORMMATRIX4X2FVPROC COpenGLExtensionHandler::pGlUniformMatrix4x2fv = NULL;
-PFNGLUNIFORMMATRIX4X3FVPROC COpenGLExtensionHandler::pGlUniformMatrix4x3fv = NULL;
+//
+PFNGLPROGRAMUNIFORM1FVPROC COpenGLExtensionHandler::pGlProgramUniform1fv = NULL;
+PFNGLPROGRAMUNIFORM2FVPROC COpenGLExtensionHandler::pGlProgramUniform2fv = NULL;
+PFNGLPROGRAMUNIFORM3FVPROC COpenGLExtensionHandler::pGlProgramUniform3fv = NULL;
+PFNGLPROGRAMUNIFORM4FVPROC COpenGLExtensionHandler::pGlProgramUniform4fv = NULL;
+PFNGLPROGRAMUNIFORM1IVPROC COpenGLExtensionHandler::pGlProgramUniform1iv = NULL;
+PFNGLPROGRAMUNIFORM2IVPROC COpenGLExtensionHandler::pGlProgramUniform2iv = NULL;
+PFNGLPROGRAMUNIFORM3IVPROC COpenGLExtensionHandler::pGlProgramUniform3iv = NULL;
+PFNGLPROGRAMUNIFORM4IVPROC COpenGLExtensionHandler::pGlProgramUniform4iv = NULL;
+PFNGLPROGRAMUNIFORM1UIVPROC COpenGLExtensionHandler::pGlProgramUniform1uiv = NULL;
+PFNGLPROGRAMUNIFORM2UIVPROC COpenGLExtensionHandler::pGlProgramUniform2uiv = NULL;
+PFNGLPROGRAMUNIFORM3UIVPROC COpenGLExtensionHandler::pGlProgramUniform3uiv = NULL;
+PFNGLPROGRAMUNIFORM4UIVPROC COpenGLExtensionHandler::pGlProgramUniform4uiv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2FVPROC COpenGLExtensionHandler::pGlProgramUniformMatrix2fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3FVPROC COpenGLExtensionHandler::pGlProgramUniformMatrix3fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4FVPROC COpenGLExtensionHandler::pGlProgramUniformMatrix4fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC COpenGLExtensionHandler::pGlProgramUniformMatrix2x3fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC COpenGLExtensionHandler::pGlProgramUniformMatrix2x4fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC COpenGLExtensionHandler::pGlProgramUniformMatrix3x2fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC COpenGLExtensionHandler::pGlProgramUniformMatrix3x4fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC COpenGLExtensionHandler::pGlProgramUniformMatrix4x2fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC COpenGLExtensionHandler::pGlProgramUniformMatrix4x3fv = NULL;
+//
 PFNGLGETACTIVEUNIFORMPROC COpenGLExtensionHandler::pGlGetActiveUniform = NULL;
 PFNGLPOINTPARAMETERFPROC COpenGLExtensionHandler:: pGlPointParameterf = NULL;
 PFNGLPOINTPARAMETERFVPROC COpenGLExtensionHandler::pGlPointParameterfv = NULL;
@@ -419,8 +431,7 @@ PFNGLBLENDFUNCINDEXEDAMDPROC COpenGLExtensionHandler::pGlBlendFuncIndexedAMD = N
 PFNGLBLENDFUNCIPROC COpenGLExtensionHandler::pGlBlendFunciARB = NULL;
 PFNGLBLENDEQUATIONINDEXEDAMDPROC COpenGLExtensionHandler::pGlBlendEquationIndexedAMD = NULL;
 PFNGLBLENDEQUATIONIPROC COpenGLExtensionHandler::pGlBlendEquationiARB = NULL;
-PFNGLPROGRAMPARAMETERIARBPROC COpenGLExtensionHandler::pGlProgramParameteriARB = NULL;
-PFNGLPROGRAMPARAMETERIEXTPROC COpenGLExtensionHandler::pGlProgramParameteriEXT = NULL;
+PFNGLPROGRAMPARAMETERIPROC COpenGLExtensionHandler::pGlProgramParameteri = NULL;
 PFNGLPATCHPARAMETERIPROC COpenGLExtensionHandler::pGlPatchParameteri = NULL;
 PFNGLPATCHPARAMETERFVPROC COpenGLExtensionHandler::pGlPatchParameterfv = NULL;
 //
@@ -808,6 +819,9 @@ void COpenGLExtensionHandler::initExtensions(bool stencilBuffer)
     pGlCompressedTextureSubImage1D = NULL;
     pGlCompressedTextureSubImage2D = NULL;
     pGlCompressedTextureSubImage3D = NULL;
+    pGlCopyTextureSubImage1D = NULL;
+    pGlCopyTextureSubImage2D = NULL;
+    pGlCopyTextureSubImage3D = NULL;
     pGlGenerateTextureMipmap = NULL;
     pGlCreateSamplers = NULL;
     pGlBindAttribLocation = NULL;
@@ -864,6 +878,9 @@ void COpenGLExtensionHandler::initExtensions(bool stencilBuffer)
     pGlCompressedTextureSubImage1DEXT = NULL;
     pGlCompressedTextureSubImage2DEXT = NULL;
     pGlCompressedTextureSubImage3DEXT = NULL;
+    pGlCopyTextureSubImage1DEXT = NULL;
+    pGlCopyTextureSubImage2DEXT = NULL;
+    pGlCopyTextureSubImage3DEXT = NULL;
     pGlGenerateTextureMipmapEXT = NULL;
     pGlCheckNamedFramebufferStatusEXT = NULL;
     pGlNamedFramebufferTextureEXT = NULL;
@@ -1017,6 +1034,9 @@ void COpenGLExtensionHandler::loadFunctions()
     ///PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC) IRR_OGL_LOAD_EXTENSION( "glTextureStorage2DMultisample");
     ///PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC) IRR_OGL_LOAD_EXTENSION( "glTextureStorage3DMultisample");
     pGlTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) IRR_OGL_LOAD_EXTENSION( "glTexSubImage3D");
+    pGlMultiTexSubImage1DEXT = (PFNGLMULTITEXSUBIMAGE1DEXTPROC) IRR_OGL_LOAD_EXTENSION( "glMultiTexSubImage1DEXT");
+    pGlMultiTexSubImage2DEXT = (PFNGLMULTITEXSUBIMAGE2DEXTPROC) IRR_OGL_LOAD_EXTENSION( "glMultiTexSubImage2DEXT");
+    pGlMultiTexSubImage3DEXT = (PFNGLMULTITEXSUBIMAGE3DEXTPROC) IRR_OGL_LOAD_EXTENSION( "glMultiTexSubImage3DEXT");
     pGlTextureSubImage1D = (PFNGLTEXTURESUBIMAGE1DPROC) IRR_OGL_LOAD_EXTENSION( "glTextureSubImage1D");
     pGlTextureSubImage2D = (PFNGLTEXTURESUBIMAGE2DPROC) IRR_OGL_LOAD_EXTENSION( "glTextureSubImage2D");
     pGlTextureSubImage3D = (PFNGLTEXTURESUBIMAGE3DPROC) IRR_OGL_LOAD_EXTENSION( "glTextureSubImage3D");
@@ -1032,6 +1052,13 @@ void COpenGLExtensionHandler::loadFunctions()
     pGlCompressedTextureSubImage1DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) IRR_OGL_LOAD_EXTENSION( "glCompressedTextureSubImage1DEXT");
     pGlCompressedTextureSubImage2DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) IRR_OGL_LOAD_EXTENSION( "glCompressedTextureSubImage2DEXT");
     pGlCompressedTextureSubImage3DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) IRR_OGL_LOAD_EXTENSION( "glCompressedTextureSubImage3DEXT");
+    pGlCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) IRR_OGL_LOAD_EXTENSION( "glCopyTexSubImage3D");
+    pGlCopyTextureSubImage1D = (PFNGLCOPYTEXTURESUBIMAGE1DPROC) IRR_OGL_LOAD_EXTENSION( "glCopyTextureSubImage1D");
+    pGlCopyTextureSubImage2D = (PFNGLCOPYTEXTURESUBIMAGE2DPROC) IRR_OGL_LOAD_EXTENSION( "glCopyTextureSubImage2D");
+    pGlCopyTextureSubImage3D = (PFNGLCOPYTEXTURESUBIMAGE3DPROC) IRR_OGL_LOAD_EXTENSION( "glCopyTextureSubImage3D");
+    pGlCopyTextureSubImage1DEXT = (PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) IRR_OGL_LOAD_EXTENSION( "glCopyTextureSubImage1DEXT");
+    pGlCopyTextureSubImage2DEXT = (PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) IRR_OGL_LOAD_EXTENSION( "glCopyTextureSubImage2DEXT");
+    pGlCopyTextureSubImage3DEXT = (PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) IRR_OGL_LOAD_EXTENSION( "glCopyTextureSubImage3DEXT");
     pGlGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) IRR_OGL_LOAD_EXTENSION( "glGenerateMipmap");
     pGlGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC) IRR_OGL_LOAD_EXTENSION( "glGenerateTextureMipmap");
     pGlGenerateTextureMipmapEXT = (PFNGLGENERATETEXTUREMIPMAPEXTPROC) IRR_OGL_LOAD_EXTENSION( "glGenerateTextureMipmapEXT");
@@ -1064,27 +1091,27 @@ void COpenGLExtensionHandler::loadFunctions()
 	pGlGetShaderiv = (PFNGLGETSHADERIVPROC) IRR_OGL_LOAD_EXTENSION("glGetShaderiv");
 	pGlGetProgramiv = (PFNGLGETPROGRAMIVPROC) IRR_OGL_LOAD_EXTENSION("glGetProgramiv");
 	pGlGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) IRR_OGL_LOAD_EXTENSION("glGetUniformLocation");
-	pGlUniform1fv = (PFNGLUNIFORM1FVPROC) IRR_OGL_LOAD_EXTENSION("glUniform1fv");
-	pGlUniform2fv = (PFNGLUNIFORM2FVPROC) IRR_OGL_LOAD_EXTENSION("glUniform2fv");
-	pGlUniform3fv = (PFNGLUNIFORM3FVPROC) IRR_OGL_LOAD_EXTENSION("glUniform3fv");
-	pGlUniform4fv = (PFNGLUNIFORM4FVPROC) IRR_OGL_LOAD_EXTENSION("glUniform4fv");
-	pGlUniform1iv = (PFNGLUNIFORM1IVPROC) IRR_OGL_LOAD_EXTENSION("glUniform1iv");
-	pGlUniform2iv = (PFNGLUNIFORM2IVPROC) IRR_OGL_LOAD_EXTENSION("glUniform2iv");
-	pGlUniform3iv = (PFNGLUNIFORM3IVPROC) IRR_OGL_LOAD_EXTENSION("glUniform3iv");
-	pGlUniform4iv = (PFNGLUNIFORM4IVPROC) IRR_OGL_LOAD_EXTENSION("glUniform4iv");
-	pGlUniform1uiv = (PFNGLUNIFORM1UIVPROC) IRR_OGL_LOAD_EXTENSION("glUniform1uiv");
-	pGlUniform2uiv = (PFNGLUNIFORM2UIVPROC) IRR_OGL_LOAD_EXTENSION("glUniform2uiv");
-	pGlUniform3uiv = (PFNGLUNIFORM3UIVPROC) IRR_OGL_LOAD_EXTENSION("glUniform3uiv");
-	pGlUniform4uiv = (PFNGLUNIFORM4UIVPROC) IRR_OGL_LOAD_EXTENSION("glUniform4uiv");
-	pGlUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) IRR_OGL_LOAD_EXTENSION("glUniformMatrix2fv");
-	pGlUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) IRR_OGL_LOAD_EXTENSION("glUniformMatrix3fv");
-	pGlUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) IRR_OGL_LOAD_EXTENSION("glUniformMatrix4fv");
-	pGlUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC) IRR_OGL_LOAD_EXTENSION("glUniformMatrix2x3fv");
-	pGlUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC) IRR_OGL_LOAD_EXTENSION("glUniformMatrix3x2fv");
-	pGlUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC) IRR_OGL_LOAD_EXTENSION("glUniformMatrix4x2fv");
-	pGlUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC) IRR_OGL_LOAD_EXTENSION("glUniformMatrix2x4fv");
-	pGlUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) IRR_OGL_LOAD_EXTENSION("glUniformMatrix3x4fv");
-	pGlUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC) IRR_OGL_LOAD_EXTENSION("glUniformMatrix4x3fv");
+	pGlProgramUniform1fv = (PFNGLPROGRAMUNIFORM1FVPROC) IRR_OGL_LOAD_EXTENSION("glProgramUniform1fv");
+	pGlProgramUniform2fv = (PFNGLPROGRAMUNIFORM2FVPROC) IRR_OGL_LOAD_EXTENSION("glProgramUniform2fv");
+	pGlProgramUniform3fv = (PFNGLPROGRAMUNIFORM3FVPROC) IRR_OGL_LOAD_EXTENSION("glProgramUniform3fv");
+	pGlProgramUniform4fv = (PFNGLPROGRAMUNIFORM4FVPROC) IRR_OGL_LOAD_EXTENSION("glProgramUniform4fv");
+	pGlProgramUniform1iv = (PFNGLPROGRAMUNIFORM1IVPROC) IRR_OGL_LOAD_EXTENSION("glProgramUniform1iv");
+	pGlProgramUniform2iv = (PFNGLPROGRAMUNIFORM2IVPROC) IRR_OGL_LOAD_EXTENSION("glProgramUniform2iv");
+	pGlProgramUniform3iv = (PFNGLPROGRAMUNIFORM3IVPROC) IRR_OGL_LOAD_EXTENSION("glProgramUniform3iv");
+	pGlProgramUniform4iv = (PFNGLPROGRAMUNIFORM4IVPROC) IRR_OGL_LOAD_EXTENSION("glProgramUniform4iv");
+	pGlProgramUniform1uiv = (PFNGLPROGRAMUNIFORM1UIVPROC) IRR_OGL_LOAD_EXTENSION("glProgramUniform1uiv");
+	pGlProgramUniform2uiv = (PFNGLPROGRAMUNIFORM2UIVPROC) IRR_OGL_LOAD_EXTENSION("glProgramUniform2uiv");
+	pGlProgramUniform3uiv = (PFNGLPROGRAMUNIFORM3UIVPROC) IRR_OGL_LOAD_EXTENSION("glProgramUniform3uiv");
+	pGlProgramUniform4uiv = (PFNGLPROGRAMUNIFORM4UIVPROC) IRR_OGL_LOAD_EXTENSION("glProgramUniform4uiv");
+	pGlProgramUniformMatrix2fv = (PFNGLPROGRAMUNIFORMMATRIX2FVPROC) IRR_OGL_LOAD_EXTENSION("glProgramUniformMatrix2fv");
+	pGlProgramUniformMatrix3fv = (PFNGLPROGRAMUNIFORMMATRIX3FVPROC) IRR_OGL_LOAD_EXTENSION("glProgramUniformMatrix3fv");
+	pGlProgramUniformMatrix4fv = (PFNGLPROGRAMUNIFORMMATRIX4FVPROC) IRR_OGL_LOAD_EXTENSION("glProgramUniformMatrix4fv");
+	pGlProgramUniformMatrix2x3fv = (PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) IRR_OGL_LOAD_EXTENSION("glProgramUniformMatrix2x3fv");
+	pGlProgramUniformMatrix3x2fv = (PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) IRR_OGL_LOAD_EXTENSION("glProgramUniformMatrix3x2fv");
+	pGlProgramUniformMatrix4x2fv = (PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) IRR_OGL_LOAD_EXTENSION("glProgramUniformMatrix4x2fv");
+	pGlProgramUniformMatrix2x4fv = (PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) IRR_OGL_LOAD_EXTENSION("glProgramUniformMatrix2x4fv");
+	pGlProgramUniformMatrix3x4fv = (PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) IRR_OGL_LOAD_EXTENSION("glProgramUniformMatrix3x4fv");
+	pGlProgramUniformMatrix4x3fv = (PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) IRR_OGL_LOAD_EXTENSION("glProgramUniformMatrix4x3fv");
 	pGlGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) IRR_OGL_LOAD_EXTENSION("glGetActiveUniform");
 
 	// get point parameter extension
@@ -1239,8 +1266,7 @@ void COpenGLExtensionHandler::loadFunctions()
 	pGlBlendFunciARB= (PFNGLBLENDFUNCIPROC) IRR_OGL_LOAD_EXTENSION("glBlendFunciARB");
 	pGlBlendEquationIndexedAMD= (PFNGLBLENDEQUATIONINDEXEDAMDPROC) IRR_OGL_LOAD_EXTENSION("glBlendEquationIndexedAMD");
 	pGlBlendEquationiARB= (PFNGLBLENDEQUATIONIPROC) IRR_OGL_LOAD_EXTENSION("glBlendEquationiARB");
-	pGlProgramParameteriARB= (PFNGLPROGRAMPARAMETERIARBPROC) IRR_OGL_LOAD_EXTENSION("glProgramParameteriARB");
-	pGlProgramParameteriEXT= (PFNGLPROGRAMPARAMETERIEXTPROC) IRR_OGL_LOAD_EXTENSION("glProgramParameteriEXT");
+	pGlProgramParameteri= (PFNGLPROGRAMPARAMETERIPROC) IRR_OGL_LOAD_EXTENSION("glProgramParameteri");
 	pGlPatchParameterfv = (PFNGLPATCHPARAMETERFVPROC) IRR_OGL_LOAD_EXTENSION("glPatchParameterfv");
 	pGlPatchParameteri = (PFNGLPATCHPARAMETERIPROC) IRR_OGL_LOAD_EXTENSION("glPatchParameteri");
 
@@ -1406,16 +1432,6 @@ bool COpenGLExtensionHandler::isDeviceCompatibile(core::array<std::string>* fail
             os::Printer::log(error.c_str(), ELL_ERROR);
     }
 
-    if (!FeatureAvailable[IRR_ARB_compute_shader]) //&&Version<430
-    {
-        retval =  false;
-        std::string error = "GL_ARB_compute_shader missing\n";
-        if (failedExtensions)
-            failedExtensions->push_back(error);
-        else
-            os::Printer::log(error.c_str(), ELL_ERROR);
-    }
-
 
     return retval;
 }
diff --git a/source/Irrlicht/COpenGLExtensionHandler.h b/source/Irrlicht/COpenGLExtensionHandler.h
index fc2919459..669bf01e3 100644
--- a/source/Irrlicht/COpenGLExtensionHandler.h
+++ b/source/Irrlicht/COpenGLExtensionHandler.h
@@ -14,62 +14,7 @@
 #include "os.h"
 #include "coreutil.h"
 
-#if defined(_IRR_WINDOWS_API_)
-	// include windows headers for HWND
-	#define WIN32_LEAN_AND_MEAN
-	#include <windows.h>
-	#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
-		#define GL_GLEXT_LEGACY 1
-	#endif
-	#include <GL/gl.h>
-	#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
-		#include "../Irrlicht/glext.h"
-	#endif
-	#include "wglext.h"
-
-	#ifdef _MSC_VER
-		#pragma comment(lib, "OpenGL32.lib")
-//		#pragma comment(lib, "OpenCL.lib")
-	#endif
-
-#elif defined(_IRR_COMPILE_WITH_OSX_DEVICE_)
-	#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
-		#define GL_GLEXT_LEGACY 1
-	#endif
-	#include <OpenGL/gl.h>
-	#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
-		#include "../Irrlicht/glext.h"
-	#endif
-#elif defined(_IRR_COMPILE_WITH_SDL_DEVICE_) && !defined(_IRR_COMPILE_WITH_X11_DEVICE_)
-	#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
-		#define GL_GLEXT_LEGACY 1
-		#define GLX_GLXEXT_LEGACY 1
-	#else
-		#define GL_GLEXT_PROTOTYPES 1
-		#define GLX_GLXEXT_PROTOTYPES 1
-	#endif
-	#define NO_SDL_GLEXT
-	#include <SDL/SDL_video.h>
-	#include <SDL/SDL_opengl.h>
-	#include "../Irrlicht/glext.h"
-#else
-	#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
-		#define GL_GLEXT_LEGACY 1
-		#define GLX_GLXEXT_LEGACY 1
-	#else
-		#define GL_GLEXT_PROTOTYPES 1
-		#define GLX_GLXEXT_PROTOTYPES 1
-	#endif
-	#include <GL/gl.h>
-	#include <GL/glx.h>
-	#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
-        #include "../Irrlicht/glext.h"
-        //#ifndef GL_VERSION_4_6 1
-            //#error "WTF"
-        //#endif // GL_VERSION_4_6
-	#endif
-#endif
-
+#include "COpenGLStateManager.h"
 
 namespace irr
 {
@@ -1070,6 +1015,9 @@ class COpenGLExtensionHandler
     static void extGlCompressedTextureSubImage1D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data);
     static void extGlCompressedTextureSubImage2D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
     static void extGlCompressedTextureSubImage3D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);
+    static void extGlCopyTextureSubImage1D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+    static void extGlCopyTextureSubImage2D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+    static void extGlCopyTextureSubImage3D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
     static void extGlGenerateTextureMipmap(GLuint texture, GLenum target);
     static void setPixelUnpackAlignment(const uint32_t &pitchInBytes, void* ptr);
 
@@ -1102,31 +1050,31 @@ class COpenGLExtensionHandler
 	static void extGlGetShaderiv(GLuint shader, GLenum type, GLint *param);
 	static void extGlGetProgramiv(GLuint program, GLenum type, GLint *param);
 	static GLint extGlGetUniformLocation(GLuint program, const char *name);
-	static void extGlUniform1fv(GLint loc, GLsizei count, const GLfloat *v);
-	static void extGlUniform2fv(GLint loc, GLsizei count, const GLfloat *v);
-	static void extGlUniform3fv(GLint loc, GLsizei count, const GLfloat *v);
-	static void extGlUniform4fv(GLint loc, GLsizei count, const GLfloat *v);
-	static void extGlUniform1bv(GLint loc, GLsizei count, const bool *v);
-	static void extGlUniform2bv(GLint loc, GLsizei count, const bool *v);
-	static void extGlUniform3bv(GLint loc, GLsizei count, const bool *v);
-	static void extGlUniform4bv(GLint loc, GLsizei count, const bool *v);
-	static void extGlUniform1iv(GLint loc, GLsizei count, const GLint *v);
-	static void extGlUniform2iv(GLint loc, GLsizei count, const GLint *v);
-	static void extGlUniform3iv(GLint loc, GLsizei count, const GLint *v);
-	static void extGlUniform4iv(GLint loc, GLsizei count, const GLint *v);
-	static void extGlUniform1uiv(GLint loc, GLsizei count, const GLuint *v);
-	static void extGlUniform2uiv(GLint loc, GLsizei count, const GLuint *v);
-	static void extGlUniform3uiv(GLint loc, GLsizei count, const GLuint *v);
-	static void extGlUniform4uiv(GLint loc, GLsizei count, const GLuint *v);
-	static void extGlUniformMatrix2fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v);
-	static void extGlUniformMatrix3fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v);
-	static void extGlUniformMatrix4fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v);
-	static void extGlUniformMatrix2x3fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v);
-	static void extGlUniformMatrix2x4fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v);
-	static void extGlUniformMatrix3x2fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v);
-	static void extGlUniformMatrix3x4fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v);
-	static void extGlUniformMatrix4x2fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v);
-	static void extGlUniformMatrix4x3fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v);
+	static void extGlProgramUniform1fv(GLuint program, GLint loc, GLsizei count, const GLfloat *v);
+	static void extGlProgramUniform2fv(GLuint program, GLint loc, GLsizei count, const GLfloat *v);
+	static void extGlProgramUniform3fv(GLuint program, GLint loc, GLsizei count, const GLfloat *v);
+	static void extGlProgramUniform4fv(GLuint program, GLint loc, GLsizei count, const GLfloat *v);
+	static void extGlProgramUniform1bv(GLuint program, GLint loc, GLsizei count, const bool *v);
+	static void extGlProgramUniform2bv(GLuint program, GLint loc, GLsizei count, const bool *v);
+	static void extGlProgramUniform3bv(GLuint program, GLint loc, GLsizei count, const bool *v);
+	static void extGlProgramUniform4bv(GLuint program, GLint loc, GLsizei count, const bool *v);
+	static void extGlProgramUniform1iv(GLuint program, GLint loc, GLsizei count, const GLint *v);
+	static void extGlProgramUniform2iv(GLuint program, GLint loc, GLsizei count, const GLint *v);
+	static void extGlProgramUniform3iv(GLuint program, GLint loc, GLsizei count, const GLint *v);
+	static void extGlProgramUniform4iv(GLuint program, GLint loc, GLsizei count, const GLint *v);
+	static void extGlProgramUniform1uiv(GLuint program, GLint loc, GLsizei count, const GLuint *v);
+	static void extGlProgramUniform2uiv(GLuint program, GLint loc, GLsizei count, const GLuint *v);
+	static void extGlProgramUniform3uiv(GLuint program, GLint loc, GLsizei count, const GLuint *v);
+	static void extGlProgramUniform4uiv(GLuint program, GLint loc, GLsizei count, const GLuint *v);
+	static void extGlProgramUniformMatrix2fv(GLuint program, GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v);
+	static void extGlProgramUniformMatrix3fv(GLuint program, GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v);
+	static void extGlProgramUniformMatrix4fv(GLuint program, GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v);
+	static void extGlProgramUniformMatrix2x3fv(GLuint program, GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v);
+	static void extGlProgramUniformMatrix2x4fv(GLuint program, GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v);
+	static void extGlProgramUniformMatrix3x2fv(GLuint program, GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v);
+	static void extGlProgramUniformMatrix3x4fv(GLuint program, GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v);
+	static void extGlProgramUniformMatrix4x2fv(GLuint program, GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v);
+	static void extGlProgramUniformMatrix4x3fv(GLuint program, GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v);
 	static void extGlGetActiveUniform(GLuint program, GLuint index, GLsizei maxlength, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
 
 	// framebuffer objects
@@ -1277,6 +1225,9 @@ class COpenGLExtensionHandler
     ///static PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC pGlTextureStorage2DMultisample;
     ///static PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC pGlTextureStorage3DMultisample;
     static PFNGLTEXSUBIMAGE3DPROC pGlTexSubImage3D;
+    static PFNGLMULTITEXSUBIMAGE1DEXTPROC pGlMultiTexSubImage1DEXT;
+    static PFNGLMULTITEXSUBIMAGE2DEXTPROC pGlMultiTexSubImage2DEXT;
+    static PFNGLMULTITEXSUBIMAGE3DEXTPROC pGlMultiTexSubImage3DEXT;
     static PFNGLTEXTURESUBIMAGE1DPROC pGlTextureSubImage1D; //NULL
     static PFNGLTEXTURESUBIMAGE2DPROC pGlTextureSubImage2D; //NULL
     static PFNGLTEXTURESUBIMAGE3DPROC pGlTextureSubImage3D; //NULL
@@ -1292,6 +1243,13 @@ class COpenGLExtensionHandler
     static PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC pGlCompressedTextureSubImage1DEXT;
     static PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC pGlCompressedTextureSubImage2DEXT;
     static PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC pGlCompressedTextureSubImage3DEXT;
+    static PFNGLCOPYTEXSUBIMAGE3DPROC pGlCopyTexSubImage3D;
+    static PFNGLCOPYTEXTURESUBIMAGE1DPROC pGlCopyTextureSubImage1D;
+    static PFNGLCOPYTEXTURESUBIMAGE2DPROC pGlCopyTextureSubImage2D;
+    static PFNGLCOPYTEXTURESUBIMAGE3DPROC pGlCopyTextureSubImage3D;
+    static PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC pGlCopyTextureSubImage1DEXT;
+    static PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC pGlCopyTextureSubImage2DEXT;
+    static PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC pGlCopyTextureSubImage3DEXT;
     static PFNGLGENERATEMIPMAPPROC pGlGenerateMipmap;
     static PFNGLGENERATETEXTUREMIPMAPPROC pGlGenerateTextureMipmap; //NULL
     static PFNGLGENERATETEXTUREMIPMAPEXTPROC pGlGenerateTextureMipmapEXT;
@@ -1326,27 +1284,27 @@ class COpenGLExtensionHandler
     static PFNGLGETSHADERIVPROC pGlGetShaderiv;
     static PFNGLGETSHADERIVPROC pGlGetProgramiv;
     static PFNGLGETUNIFORMLOCATIONPROC pGlGetUniformLocation;
-    static PFNGLUNIFORM1FVPROC pGlUniform1fv;
-    static PFNGLUNIFORM2FVPROC pGlUniform2fv;
-    static PFNGLUNIFORM3FVPROC pGlUniform3fv;
-    static PFNGLUNIFORM4FVPROC pGlUniform4fv;
-    static PFNGLUNIFORM1IVPROC pGlUniform1iv;
-    static PFNGLUNIFORM2IVPROC pGlUniform2iv;
-    static PFNGLUNIFORM3IVPROC pGlUniform3iv;
-    static PFNGLUNIFORM4IVPROC pGlUniform4iv;
-    static PFNGLUNIFORM1UIVPROC pGlUniform1uiv;
-    static PFNGLUNIFORM2UIVPROC pGlUniform2uiv;
-    static PFNGLUNIFORM3UIVPROC pGlUniform3uiv;
-    static PFNGLUNIFORM4UIVPROC pGlUniform4uiv;
-    static PFNGLUNIFORMMATRIX2FVPROC pGlUniformMatrix2fv;
-    static PFNGLUNIFORMMATRIX3FVPROC pGlUniformMatrix3fv;
-    static PFNGLUNIFORMMATRIX4FVPROC pGlUniformMatrix4fv;
-    static PFNGLUNIFORMMATRIX2X3FVPROC pGlUniformMatrix2x3fv;
-    static PFNGLUNIFORMMATRIX2X4FVPROC pGlUniformMatrix2x4fv;
-    static PFNGLUNIFORMMATRIX3X2FVPROC pGlUniformMatrix3x2fv;
-    static PFNGLUNIFORMMATRIX3X4FVPROC pGlUniformMatrix3x4fv;
-    static PFNGLUNIFORMMATRIX4X2FVPROC pGlUniformMatrix4x2fv;
-    static PFNGLUNIFORMMATRIX4X3FVPROC pGlUniformMatrix4x3fv;
+    static PFNGLPROGRAMUNIFORM1FVPROC pGlProgramUniform1fv;
+    static PFNGLPROGRAMUNIFORM2FVPROC pGlProgramUniform2fv;
+    static PFNGLPROGRAMUNIFORM3FVPROC pGlProgramUniform3fv;
+    static PFNGLPROGRAMUNIFORM4FVPROC pGlProgramUniform4fv;
+    static PFNGLPROGRAMUNIFORM1IVPROC pGlProgramUniform1iv;
+    static PFNGLPROGRAMUNIFORM2IVPROC pGlProgramUniform2iv;
+    static PFNGLPROGRAMUNIFORM3IVPROC pGlProgramUniform3iv;
+    static PFNGLPROGRAMUNIFORM4IVPROC pGlProgramUniform4iv;
+    static PFNGLPROGRAMUNIFORM1UIVPROC pGlProgramUniform1uiv;
+    static PFNGLPROGRAMUNIFORM2UIVPROC pGlProgramUniform2uiv;
+    static PFNGLPROGRAMUNIFORM3UIVPROC pGlProgramUniform3uiv;
+    static PFNGLPROGRAMUNIFORM4UIVPROC pGlProgramUniform4uiv;
+    static PFNGLPROGRAMUNIFORMMATRIX2FVPROC pGlProgramUniformMatrix2fv;
+    static PFNGLPROGRAMUNIFORMMATRIX3FVPROC pGlProgramUniformMatrix3fv;
+    static PFNGLPROGRAMUNIFORMMATRIX4FVPROC pGlProgramUniformMatrix4fv;
+    static PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC pGlProgramUniformMatrix2x3fv;
+    static PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC pGlProgramUniformMatrix2x4fv;
+    static PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC pGlProgramUniformMatrix3x2fv;
+    static PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC pGlProgramUniformMatrix3x4fv;
+    static PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC pGlProgramUniformMatrix4x2fv;
+    static PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC pGlProgramUniformMatrix4x3fv;
     static PFNGLGETACTIVEUNIFORMPROC pGlGetActiveUniform;
     static PFNGLPOINTPARAMETERFPROC  pGlPointParameterf;
     static PFNGLPOINTPARAMETERFVPROC pGlPointParameterfv;
@@ -1499,8 +1457,7 @@ class COpenGLExtensionHandler
     static PFNGLBLENDFUNCIPROC pGlBlendFunciARB;
     static PFNGLBLENDEQUATIONINDEXEDAMDPROC pGlBlendEquationIndexedAMD; //NULL
     static PFNGLBLENDEQUATIONIPROC pGlBlendEquationiARB; //NULL
-    static PFNGLPROGRAMPARAMETERIARBPROC pGlProgramParameteriARB;
-    static PFNGLPROGRAMPARAMETERIEXTPROC pGlProgramParameteriEXT;
+    static PFNGLPROGRAMPARAMETERIPROC pGlProgramParameteri;
     static PFNGLPATCHPARAMETERIPROC pGlPatchParameteri;
     static PFNGLPATCHPARAMETERFVPROC pGlPatchParameterfv;
     //
@@ -2035,7 +1992,7 @@ inline void COpenGLExtensionHandler::extGlCompressedTextureSubImage1D(GLuint tex
         if (pGlCompressedTextureSubImage1D)
             pGlCompressedTextureSubImage1D(texture, level, xoffset, width,format, imageSize, data);
 #else
-        glCompressedTextureSubImage1D(texture, level, xoffset, width,format, imageSize, data));
+        glCompressedTextureSubImage1D(texture, level, xoffset, width,format, imageSize, data);
 #endif // _IRR_OPENGL_USE_EXTPOINTER_
     }
     else if (FeatureAvailable[IRR_EXT_direct_state_access])
@@ -2044,7 +2001,7 @@ inline void COpenGLExtensionHandler::extGlCompressedTextureSubImage1D(GLuint tex
         if (pGlCompressedTextureSubImage1DEXT)
             pGlCompressedTextureSubImage1DEXT(texture, target, level, xoffset, width,format, imageSize, data);
 #else
-        glCompressedTextureSubImage1DEXT(texture, target, level, xoffset, width,format, imageSize, data));
+        glCompressedTextureSubImage1DEXT(texture, target, level, xoffset, width,format, imageSize, data);
 #endif // _IRR_OPENGL_USE_EXTPOINTER_
     }
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
@@ -2080,7 +2037,7 @@ inline void COpenGLExtensionHandler::extGlCompressedTextureSubImage2D(GLuint tex
         if (pGlCompressedTextureSubImage2D)
             pGlCompressedTextureSubImage2D(texture, level, xoffset, yoffset,width, height,format, imageSize, data);
 #else
-        glCompressedTextureSubImage2D(texture, level, xoffset, yoffset,width, height,format, imageSize, data));
+        glCompressedTextureSubImage2D(texture, level, xoffset, yoffset,width, height,format, imageSize, data);
 #endif // _IRR_OPENGL_USE_EXTPOINTER_
     }
     else if (FeatureAvailable[IRR_EXT_direct_state_access])
@@ -2089,7 +2046,7 @@ inline void COpenGLExtensionHandler::extGlCompressedTextureSubImage2D(GLuint tex
         if (pGlCompressedTextureSubImage2DEXT)
             pGlCompressedTextureSubImage2DEXT(texture, target, level, xoffset, yoffset,width, height,format, imageSize, data);
 #else
-        glCompressedTextureSubImage2DEXT(texture, target, level, xoffset, yoffset,width, height,format, imageSize, data));
+        glCompressedTextureSubImage2DEXT(texture, target, level, xoffset, yoffset,width, height,format, imageSize, data);
 #endif // _IRR_OPENGL_USE_EXTPOINTER_
     }
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
@@ -2136,7 +2093,7 @@ inline void COpenGLExtensionHandler::extGlCompressedTextureSubImage3D(GLuint tex
         if (pGlCompressedTextureSubImage3D)
             pGlCompressedTextureSubImage3D(texture, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
 #else
-        glCompressedTextureSubImage3D(texture, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data));
+        glCompressedTextureSubImage3D(texture, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
 #endif // _IRR_OPENGL_USE_EXTPOINTER_
     }
     else if (FeatureAvailable[IRR_EXT_direct_state_access])
@@ -2145,7 +2102,7 @@ inline void COpenGLExtensionHandler::extGlCompressedTextureSubImage3D(GLuint tex
         if (pGlCompressedTextureSubImage3DEXT)
             pGlCompressedTextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
 #else
-        glCompressedTextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data));
+        glCompressedTextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
 #endif // _IRR_OPENGL_USE_EXTPOINTER_
     }
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
@@ -2183,6 +2140,154 @@ inline void COpenGLExtensionHandler::extGlCompressedTextureSubImage3D(GLuint tex
     }
 }
 
+inline void COpenGLExtensionHandler::extGlCopyTextureSubImage1D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)
+{
+    if (Version>=450||FeatureAvailable[IRR_ARB_direct_state_access])
+    {
+#ifdef _IRR_OPENGL_USE_EXTPOINTER_
+        if (pGlCopyTextureSubImage1D)
+            pGlCopyTextureSubImage1D(texture, level, xoffset, x, y, width);
+#else
+        glCopyTextureSubImage1D(texture, level, xoffset, x, y, width);
+#endif // _IRR_OPENGL_USE_EXTPOINTER_
+    }
+    else if (FeatureAvailable[IRR_EXT_direct_state_access])
+    {
+#ifdef _IRR_OPENGL_USE_EXTPOINTER_
+        if (pGlCopyTextureSubImage1DEXT)
+            pGlCopyTextureSubImage1DEXT(texture, target, level, xoffset, x, y, width);
+#else
+        glCopyTextureSubImage1DEXT(texture, target, level, xoffset, x, y, width);
+#endif // _IRR_OPENGL_USE_EXTPOINTER_
+    }
+#ifdef _IRR_OPENGL_USE_EXTPOINTER_
+    else if (pGlCopyTexSubImage3D)
+#else
+    else
+#endif // _IRR_OPENGL_USE_EXTPOINTER_
+    {
+        GLint bound;
+        switch (target)
+        {
+            case GL_TEXTURE_1D:
+                glGetIntegerv(GL_TEXTURE_BINDING_1D, &bound);
+                break;
+            default:
+                os::Printer::log("DevSH would like to ask you what are you doing!!??\n",ELL_ERROR);
+                return;
+        }
+        glBindTexture(target, texture);
+        glCopyTexSubImage1D(target, level, xoffset, x, y, width);
+        glBindTexture(target, bound);
+    }
+}
+inline void COpenGLExtensionHandler::extGlCopyTextureSubImage2D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+    if (Version>=450||FeatureAvailable[IRR_ARB_direct_state_access])
+    {
+#ifdef _IRR_OPENGL_USE_EXTPOINTER_
+        if (pGlCopyTextureSubImage2D)
+            pGlCopyTextureSubImage2D(texture, level, xoffset, yoffset, x, y, width, height);
+#else
+        glCopyTextureSubImage2D(texture, level, xoffset, yoffset, x, y, width, height);
+#endif // _IRR_OPENGL_USE_EXTPOINTER_
+    }
+    else if (FeatureAvailable[IRR_EXT_direct_state_access])
+    {
+#ifdef _IRR_OPENGL_USE_EXTPOINTER_
+        if (pGlCopyTextureSubImage2DEXT)
+            pGlCopyTextureSubImage2DEXT(texture, target, level, xoffset, yoffset, x, y, width, height);
+#else
+        glCopyTextureSubImage2DEXT(texture, target, level, xoffset, yoffset, x, y, width, height);
+#endif // _IRR_OPENGL_USE_EXTPOINTER_
+    }
+#ifdef _IRR_OPENGL_USE_EXTPOINTER_
+    else if (pGlCopyTexSubImage3D)
+#else
+    else
+#endif // _IRR_OPENGL_USE_EXTPOINTER_
+    {
+        GLint bound;
+        switch (target)
+        {
+            case GL_TEXTURE_1D_ARRAY:
+                glGetIntegerv(GL_TEXTURE_BINDING_1D_ARRAY, &bound);
+                break;
+            case GL_TEXTURE_2D:
+                glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound);
+                break;
+            case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+            case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+            case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+            case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+            case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+            case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+                glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &bound);
+                break;
+            default:
+                os::Printer::log("DevSH would like to ask you what are you doing!!??\n",ELL_ERROR);
+                return;
+        }
+        glBindTexture(target, texture);
+        glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+        glBindTexture(target, bound);
+    }
+}
+inline void COpenGLExtensionHandler::extGlCopyTextureSubImage3D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+    if (Version>=450||FeatureAvailable[IRR_ARB_direct_state_access])
+    {
+#ifdef _IRR_OPENGL_USE_EXTPOINTER_
+        if (pGlCopyTextureSubImage3D)
+            pGlCopyTextureSubImage3D(texture, level, xoffset, yoffset, zoffset, x, y, width, height);
+#else
+        glCopyTextureSubImage3D(texture, level, xoffset, yoffset, zoffset, x, y, width, height);
+#endif // _IRR_OPENGL_USE_EXTPOINTER_
+    }
+    else if (FeatureAvailable[IRR_EXT_direct_state_access])
+    {
+#ifdef _IRR_OPENGL_USE_EXTPOINTER_
+        if (pGlCopyTextureSubImage3DEXT)
+            pGlCopyTextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, x, y, width, height);
+#else
+        glCopyTextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, x, y, width, height);
+#endif // _IRR_OPENGL_USE_EXTPOINTER_
+    }
+#ifdef _IRR_OPENGL_USE_EXTPOINTER_
+    else if (pGlCopyTexSubImage3D)
+#else
+    else
+#endif // _IRR_OPENGL_USE_EXTPOINTER_
+    {
+        GLint bound;
+        switch (target)
+        {
+            case GL_TEXTURE_2D_ARRAY:
+                glGetIntegerv(GL_TEXTURE_BINDING_2D_ARRAY, &bound);
+                break;
+            case GL_TEXTURE_3D:
+                glGetIntegerv(GL_TEXTURE_BINDING_3D, &bound);
+                break;
+            case GL_TEXTURE_CUBE_MAP:
+                glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &bound);
+                break;
+            case GL_TEXTURE_CUBE_MAP_ARRAY:
+                glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP_ARRAY, &bound);
+                break;
+            default:
+                os::Printer::log("DevSH would like to ask you what are you doing!!??\n",ELL_ERROR);
+                return;
+        }
+        glBindTexture(target, texture);
+#ifdef _IRR_OPENGL_USE_EXTPOINTER_
+        pGlCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height);
+#else
+        glCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height);
+#endif // _IRR_OPENGL_USE_EXTPOINTER_
+        glBindTexture(target, bound);
+    }
+}
+
 inline void COpenGLExtensionHandler::extGlGenerateTextureMipmap(GLuint texture, GLenum target)
 {
     if (Version>=450||FeatureAvailable[IRR_ARB_direct_state_access])
@@ -2511,208 +2616,208 @@ inline GLint COpenGLExtensionHandler::extGlGetUniformLocation(GLuint program, co
 	return -1;
 }
 
-inline void COpenGLExtensionHandler::extGlUniform1fv(GLint loc, GLsizei count, const GLfloat *v)
+inline void COpenGLExtensionHandler::extGlProgramUniform1fv(GLuint program, GLint loc, GLsizei count, const GLfloat *v)
 {
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-	if (pGlUniform1fv)
-		pGlUniform1fv(loc, count, v);
+	if (pGlProgramUniform1fv)
+		pGlProgramUniform1fv(program, loc, count, v);
 #else
-	glUniform1fv(loc, count, v);
+	glProgramUniform1fv(program, loc, count, v);
 #endif
 }
 
-inline void COpenGLExtensionHandler::extGlUniform2fv(GLint loc, GLsizei count, const GLfloat *v)
+inline void COpenGLExtensionHandler::extGlProgramUniform2fv(GLuint program, GLint loc, GLsizei count, const GLfloat *v)
 {
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-	if (pGlUniform2fv)
-		pGlUniform2fv(loc, count, v);
+	if (pGlProgramUniform2fv)
+		pGlProgramUniform2fv(program, loc, count, v);
 #else
-	glUniform2fv(loc, count, v);
+	glProgramUniform2fv(program, loc, count, v);
 #endif
 }
 
-inline void COpenGLExtensionHandler::extGlUniform3fv(GLint loc, GLsizei count, const GLfloat *v)
+inline void COpenGLExtensionHandler::extGlProgramUniform3fv(GLuint program, GLint loc, GLsizei count, const GLfloat *v)
 {
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-	if (pGlUniform3fv)
-		pGlUniform3fv(loc, count, v);
+	if (pGlProgramUniform3fv)
+		pGlProgramUniform3fv(program, loc, count, v);
 #else
-	glUniform3fv(loc, count, v);
+	glProgramUniform3fv(program, loc, count, v);
 #endif
 }
 
-inline void COpenGLExtensionHandler::extGlUniform4fv(GLint loc, GLsizei count, const GLfloat *v)
+inline void COpenGLExtensionHandler::extGlProgramUniform4fv(GLuint program, GLint loc, GLsizei count, const GLfloat *v)
 {
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-	if (pGlUniform4fv)
-		pGlUniform4fv(loc, count, v);
+	if (pGlProgramUniform4fv)
+		pGlProgramUniform4fv(program, loc, count, v);
 #else
-	glUniform4fv(loc, count, v);
+	glProgramUniform4fv(program, loc, count, v);
 #endif
 }
 
-inline void COpenGLExtensionHandler::extGlUniform1iv(GLint loc, GLsizei count, const GLint *v)
+inline void COpenGLExtensionHandler::extGlProgramUniform1iv(GLuint program, GLint loc, GLsizei count, const GLint *v)
 {
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-	if (pGlUniform1iv)
-		pGlUniform1iv(loc, count, v);
+	if (pGlProgramUniform1iv)
+		pGlProgramUniform1iv(program, loc, count, v);
 #else
-	glUniform1iv(loc, count, v);
+	glProgramUniform1iv(program, loc, count, v);
 #endif
 }
 
-inline void COpenGLExtensionHandler::extGlUniform2iv(GLint loc, GLsizei count, const GLint *v)
+inline void COpenGLExtensionHandler::extGlProgramUniform2iv(GLuint program, GLint loc, GLsizei count, const GLint *v)
 {
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-	if (pGlUniform2iv)
-		pGlUniform2iv(loc, count, v);
+	if (pGlProgramUniform2iv)
+		pGlProgramUniform2iv(program, loc, count, v);
 #else
-	glUniform2iv(loc, count, v);
+	glProgramUniform2iv(program, loc, count, v);
 #endif
 }
 
-inline void COpenGLExtensionHandler::extGlUniform3iv(GLint loc, GLsizei count, const GLint *v)
+inline void COpenGLExtensionHandler::extGlProgramUniform3iv(GLuint program, GLint loc, GLsizei count, const GLint *v)
 {
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-	if (pGlUniform3iv)
-		pGlUniform3iv(loc, count, v);
+	if (pGlProgramUniform3iv)
+		pGlProgramUniform3iv(program, loc, count, v);
 #else
-	glUniform3iv(loc, count, v);
+	glProgramUniform3iv(program, loc, count, v);
 #endif
 }
 
-inline void COpenGLExtensionHandler::extGlUniform4iv(GLint loc, GLsizei count, const GLint *v)
+inline void COpenGLExtensionHandler::extGlProgramUniform4iv(GLuint program, GLint loc, GLsizei count, const GLint *v)
 {
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-	if (pGlUniform4iv)
-		pGlUniform4iv(loc, count, v);
+	if (pGlProgramUniform4iv)
+		pGlProgramUniform4iv(program, loc, count, v);
 #else
-	glUniform4iv(loc, count, v);
+	glProgramUniform4iv(program, loc, count, v);
 #endif
 }
 
-inline void COpenGLExtensionHandler::extGlUniform1uiv(GLint loc, GLsizei count, const GLuint *v)
+inline void COpenGLExtensionHandler::extGlProgramUniform1uiv(GLuint program, GLint loc, GLsizei count, const GLuint *v)
 {
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-	if (pGlUniform1uiv)
-		pGlUniform1uiv(loc, count, v);
+	if (pGlProgramUniform1uiv)
+		pGlProgramUniform1uiv(program, loc, count, v);
 #else
-	glUniform1uiv(loc, count, v);
+	glProgramUniform1uiv(program, loc, count, v);
 #endif
 }
 
-inline void COpenGLExtensionHandler::extGlUniform2uiv(GLint loc, GLsizei count, const GLuint *v)
+inline void COpenGLExtensionHandler::extGlProgramUniform2uiv(GLuint program, GLint loc, GLsizei count, const GLuint *v)
 {
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-	if (pGlUniform2uiv)
-		pGlUniform2uiv(loc, count, v);
+	if (pGlProgramUniform2uiv)
+		pGlProgramUniform2uiv(program, loc, count, v);
 #else
-	glUniform2uiv(loc, count, v);
+	glProgramUniform2uiv(program, loc, count, v);
 #endif
 }
 
-inline void COpenGLExtensionHandler::extGlUniform3uiv(GLint loc, GLsizei count, const GLuint *v)
+inline void COpenGLExtensionHandler::extGlProgramUniform3uiv(GLuint program, GLint loc, GLsizei count, const GLuint *v)
 {
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-	if (pGlUniform3uiv)
-		pGlUniform3uiv(loc, count, v);
+	if (pGlProgramUniform3uiv)
+		pGlProgramUniform3uiv(program, loc, count, v);
 #else
-	glUniform3uiv(loc, count, v);
+	glProgramUniform3uiv(program, loc, count, v);
 #endif
 }
 
-inline void COpenGLExtensionHandler::extGlUniform4uiv(GLint loc, GLsizei count, const GLuint *v)
+inline void COpenGLExtensionHandler::extGlProgramUniform4uiv(GLuint program, GLint loc, GLsizei count, const GLuint *v)
 {
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-	if (pGlUniform4uiv)
-		pGlUniform4uiv(loc, count, v);
+	if (pGlProgramUniform4uiv)
+		pGlProgramUniform4uiv(program, loc, count, v);
 #else
-	glUniform4uiv(loc, count, v);
+	glProgramUniform4uiv(program, loc, count, v);
 #endif
 }
 
-inline void COpenGLExtensionHandler::extGlUniformMatrix2fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v)
+inline void COpenGLExtensionHandler::extGlProgramUniformMatrix2fv(GLuint program, GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v)
 {
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-	if (pGlUniformMatrix2fv)
-		pGlUniformMatrix2fv(loc, count, transpose, v);
+	if (pGlProgramUniformMatrix2fv)
+		pGlProgramUniformMatrix2fv(program, loc, count, transpose, v);
 #else
-	glUniformMatrix2fv(loc, count, transpose, v);
+	glProgramUniformMatrix2fv(program, loc, count, transpose, v);
 #endif
 }
 
-inline void COpenGLExtensionHandler::extGlUniformMatrix3fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v)
+inline void COpenGLExtensionHandler::extGlProgramUniformMatrix3fv(GLuint program, GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v)
 {
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-	if (pGlUniformMatrix3fv)
-		pGlUniformMatrix3fv(loc, count, transpose, v);
+	if (pGlProgramUniformMatrix3fv)
+		pGlProgramUniformMatrix3fv(program, loc, count, transpose, v);
 #else
-	glUniformMatrix3fv(loc, count, transpose, v);
+	glProgramUniformMatrix3fv(program, loc, count, transpose, v);
 #endif
 }
 
-inline void COpenGLExtensionHandler::extGlUniformMatrix4fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v)
+inline void COpenGLExtensionHandler::extGlProgramUniformMatrix4fv(GLuint program, GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v)
 {
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-	if (pGlUniformMatrix4fv)
-		pGlUniformMatrix4fv(loc, count, transpose, v);
+	if (pGlProgramUniformMatrix4fv)
+		pGlProgramUniformMatrix4fv(program, loc, count, transpose, v);
 #else
-	glUniformMatrix4fv(loc, count, transpose, v);
+	glProgramUniformMatrix4fv(program, loc, count, transpose, v);
 #endif
 }
 
-inline void COpenGLExtensionHandler::extGlUniformMatrix2x3fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v)
+inline void COpenGLExtensionHandler::extGlProgramUniformMatrix2x3fv(GLuint program, GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v)
 {
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-	if (pGlUniformMatrix2x3fv)
-		pGlUniformMatrix2x3fv(loc, count, transpose, v);
+	if (pGlProgramUniformMatrix2x3fv)
+		pGlProgramUniformMatrix2x3fv(program, loc, count, transpose, v);
 #else
-	glUniformMatrix2x3fv(loc, count, transpose, v);
+	glProgramUniformMatrix2x3fv(program, loc, count, transpose, v);
 #endif
 }
-inline void COpenGLExtensionHandler::extGlUniformMatrix2x4fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v)
+inline void COpenGLExtensionHandler::extGlProgramUniformMatrix2x4fv(GLuint program, GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v)
 {
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-	if (pGlUniformMatrix2x4fv)
-		pGlUniformMatrix2x4fv(loc, count, transpose, v);
+	if (pGlProgramUniformMatrix2x4fv)
+		pGlProgramUniformMatrix2x4fv(program, loc, count, transpose, v);
 #else
-	glUniformMatrix2x4fv(loc, count, transpose, v);
+	glProgramUniformMatrix2x4fv(program, loc, count, transpose, v);
 #endif
 }
-inline void COpenGLExtensionHandler::extGlUniformMatrix3x2fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v)
+inline void COpenGLExtensionHandler::extGlProgramUniformMatrix3x2fv(GLuint program, GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v)
 {
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-	if (pGlUniformMatrix3x2fv)
-		pGlUniformMatrix3x2fv(loc, count, transpose, v);
+	if (pGlProgramUniformMatrix3x2fv)
+		pGlProgramUniformMatrix3x2fv(program, loc, count, transpose, v);
 #else
-	glUniformMatrix3x2fv(loc, count, transpose, v);
+	glProgramUniformMatrix3x2fv(program, loc, count, transpose, v);
 #endif
 }
-inline void COpenGLExtensionHandler::extGlUniformMatrix3x4fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v)
+inline void COpenGLExtensionHandler::extGlProgramUniformMatrix3x4fv(GLuint program, GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v)
 {
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-	if (pGlUniformMatrix3x4fv)
-		pGlUniformMatrix3x4fv(loc, count, transpose, v);
+	if (pGlProgramUniformMatrix3x4fv)
+		pGlProgramUniformMatrix3x4fv(program, loc, count, transpose, v);
 #else
-	glUniformMatrix3x4fv(loc, count, transpose, v);
+	glProgramUniformMatrix3x4fv(program, loc, count, transpose, v);
 #endif
 }
-inline void COpenGLExtensionHandler::extGlUniformMatrix4x2fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v)
+inline void COpenGLExtensionHandler::extGlProgramUniformMatrix4x2fv(GLuint program, GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v)
 {
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-	if (pGlUniformMatrix4x2fv)
-		pGlUniformMatrix4x2fv(loc, count, transpose, v);
+	if (pGlProgramUniformMatrix4x2fv)
+		pGlProgramUniformMatrix4x2fv(program, loc, count, transpose, v);
 #else
-	glUniformMatrix4x2fv(loc, count, transpose, v);
+	glProgramUniformMatrix4x2fv(program, loc, count, transpose, v);
 #endif
 }
-inline void COpenGLExtensionHandler::extGlUniformMatrix4x3fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v)
+inline void COpenGLExtensionHandler::extGlProgramUniformMatrix4x3fv(GLuint program, GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v)
 {
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-	if (pGlUniformMatrix4x3fv)
-		pGlUniformMatrix4x3fv(loc, count, transpose, v);
+	if (pGlProgramUniformMatrix4x3fv)
+		pGlProgramUniformMatrix4x3fv(program, loc, count, transpose, v);
 #else
-	glUniformMatrix4x3fv(loc, count, transpose, v);
+	glProgramUniformMatrix4x3fv(program, loc, count, transpose, v);
 #endif
 }
 
@@ -3319,7 +3424,7 @@ inline void COpenGLExtensionHandler::extGlClearNamedFramebufferuiv(GLuint frameb
         if (pGlClearBufferuiv)
             pGlClearBufferuiv(buffer, drawbuffer, value);
 #else
-        glClearNamedBufferuiv(buffer, drawbuffer, value);
+        glClearBufferuiv(buffer, drawbuffer, value);
 #endif
         if (boundFBO!=framebuffer)
 	        extGlBindFramebuffer(GL_FRAMEBUFFER,boundFBO);
@@ -3350,7 +3455,7 @@ inline void COpenGLExtensionHandler::extGlClearNamedFramebufferfv(GLuint framebu
         if (pGlClearBufferfv)
             pGlClearBufferfv(buffer, drawbuffer, value);
 #else
-        glClearNamedBufferfv(buffer, drawbuffer, value);
+        glClearBufferfv(buffer, drawbuffer, value);
 #endif
 		if (boundFBO!=framebuffer)
 			extGlBindFramebuffer(GL_FRAMEBUFFER,boundFBO);
@@ -3365,7 +3470,7 @@ inline void COpenGLExtensionHandler::extGlClearNamedFramebufferfi(GLuint framebu
         if (pGlClearNamedFramebufferfi)
             pGlClearNamedFramebufferfi(framebuffer, buffer, depth, stencil);
 #else
-        glClearNamedFramebufferfi(framebuffer, buffer, depth, stencil);
+        glClearFramebufferfi(framebuffer, buffer, depth, stencil);
 #endif
     }
     else
@@ -3379,7 +3484,7 @@ inline void COpenGLExtensionHandler::extGlClearNamedFramebufferfi(GLuint framebu
         if (pGlClearBufferfi)
             pGlClearBufferfi(buffer, depth, stencil);
 #else
-        glClearNamedBufferfi(buffer, depth, stencil);
+        glClearBufferfi(buffer, depth, stencil);
 #endif
         extGlBindFramebuffer(GL_FRAMEBUFFER,boundFBO);
     }*/
@@ -4423,17 +4528,12 @@ inline void COpenGLExtensionHandler::extGlDrawArraysInstanced(GLenum mode, GLint
 
 inline void COpenGLExtensionHandler::extGlDrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance)
 {
-    if (Version>=420||FeatureAvailable[IRR_ARB_base_instance])
-    {
 #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-        if (pGlDrawArraysInstancedBaseInstance)
-            pGlDrawArraysInstancedBaseInstance(mode,first,count,instancecount,baseinstance);
+    if (pGlDrawArraysInstancedBaseInstance)
+        pGlDrawArraysInstancedBaseInstance(mode,first,count,instancecount,baseinstance);
 #else
-        glDrawArraysInstancedBaseInstance(mode,first,count,instancecount,baseinstance);
+    glDrawArraysInstancedBaseInstance(mode,first,count,instancecount,baseinstance);
 #endif // _IRR_OPENGL_USE_EXTPOINTER_
-    }
-    else
-        os::Printer::log("glDrawArraysInstancedBaseInstance not supported", ELL_ERROR);
 }
 
 inline void COpenGLExtensionHandler::extGlDrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex)
@@ -4448,17 +4548,12 @@ inline void COpenGLExtensionHandler::extGlDrawElementsInstancedBaseVertex(GLenum
 
 inline void COpenGLExtensionHandler::extGlDrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance)
 {
-    if (Version>=420||FeatureAvailable[IRR_ARB_base_instance])
-    {
-    #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-        if (pGlDrawElementsInstancedBaseVertexBaseInstance)
-            pGlDrawElementsInstancedBaseVertexBaseInstance(mode,count,type,indices,instancecount,basevertex,baseinstance);
-    #else
-        glDrawElementsInstancedBaseVertexBaseInstance(mode,count,type,indices,instancecount,basevertex,baseinstance);
-    #endif // _IRR_OPENGL_USE_EXTPOINTER_
-    }
-    else
-        os::Printer::log("glDrawElementsInstancedBaseVertexBaseInstance not supported", ELL_ERROR);
+#ifdef _IRR_OPENGL_USE_EXTPOINTER_
+    if (pGlDrawElementsInstancedBaseVertexBaseInstance)
+        pGlDrawElementsInstancedBaseVertexBaseInstance(mode,count,type,indices,instancecount,basevertex,baseinstance);
+#else
+    glDrawElementsInstancedBaseVertexBaseInstance(mode,count,type,indices,instancecount,basevertex,baseinstance);
+#endif // _IRR_OPENGL_USE_EXTPOINTER_
 }
 
 inline void COpenGLExtensionHandler::extGlDrawTransformFeedback(GLenum mode, GLuint id)
@@ -4473,17 +4568,12 @@ inline void COpenGLExtensionHandler::extGlDrawTransformFeedback(GLenum mode, GLu
 
 inline void COpenGLExtensionHandler::extGlDrawTransformFeedbackInstanced(GLenum mode, GLuint id, GLsizei instancecount)
 {
-    if (Version>=420||FeatureAvailable[IRR_ARB_transform_feedback_instanced])
-    {
-    #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-        if (pGlDrawTransformFeedbackInstanced)
-            pGlDrawTransformFeedbackInstanced(mode,id,instancecount);
-    #else
-        glDrawTransformFeedbackInstanced(mode,id,instancecount);
-    #endif // _IRR_OPENGL_USE_EXTPOINTER_
-    }
-    else
-        os::Printer::log("glDrawTransformFeedbackInstanced not supported", ELL_ERROR);
+#ifdef _IRR_OPENGL_USE_EXTPOINTER_
+    if (pGlDrawTransformFeedbackInstanced)
+        pGlDrawTransformFeedbackInstanced(mode,id,instancecount);
+#else
+    glDrawTransformFeedbackInstanced(mode,id,instancecount);
+#endif // _IRR_OPENGL_USE_EXTPOINTER_
 }
 
 inline void COpenGLExtensionHandler::extGlDrawTransformFeedbackStream(GLenum mode, GLuint id, GLuint stream)
@@ -4498,17 +4588,12 @@ inline void COpenGLExtensionHandler::extGlDrawTransformFeedbackStream(GLenum mod
 
 inline void COpenGLExtensionHandler::extGlDrawTransformFeedbackStreamInstanced(GLenum mode, GLuint id, GLuint stream, GLsizei instancecount)
 {
-    if (Version>=420||FeatureAvailable[IRR_ARB_transform_feedback_instanced])
-    {
-    #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-        if (pGlDrawTransformFeedbackStreamInstanced)
-            pGlDrawTransformFeedbackStreamInstanced(mode,id,stream,instancecount);
-    #else
-        glDrawTransformFeedbackStreamInstanced(mode,id,stream,instancecount);
-    #endif // _IRR_OPENGL_USE_EXTPOINTER_
-    }
-    else
-        os::Printer::log("glDrawTransformFeedbackInstanced not supported", ELL_ERROR);
+#ifdef _IRR_OPENGL_USE_EXTPOINTER_
+    if (pGlDrawTransformFeedbackStreamInstanced)
+        pGlDrawTransformFeedbackStreamInstanced(mode,id,stream,instancecount);
+#else
+    glDrawTransformFeedbackStreamInstanced(mode,id,stream,instancecount);
+#endif // _IRR_OPENGL_USE_EXTPOINTER_
 }
 
 inline void COpenGLExtensionHandler::extGlDrawArraysIndirect(GLenum mode, const void *indirect)
@@ -4533,32 +4618,22 @@ inline void COpenGLExtensionHandler::extGlDrawElementsIndirect(GLenum mode, GLen
 
 inline void COpenGLExtensionHandler::extGlMultiDrawArraysIndirect(GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride)
 {
-    if (Version>=430||FeatureAvailable[IRR_ARB_transform_feedback_instanced])
-    {
-    #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-        if (pGlMultiDrawArraysIndirect)
-            pGlMultiDrawArraysIndirect(mode,indirect,drawcount,stride);
-    #else
-        glMultiDrawArraysIndirect(mode,indirect,drawcount,stride);
-    #endif // _IRR_OPENGL_USE_EXTPOINTER_
-    }
-    else
-        os::Printer::log("glMultiDrawArraysIndirect not supported", ELL_ERROR);
+#ifdef _IRR_OPENGL_USE_EXTPOINTER_
+    if (pGlMultiDrawArraysIndirect)
+        pGlMultiDrawArraysIndirect(mode,indirect,drawcount,stride);
+#else
+    glMultiDrawArraysIndirect(mode,indirect,drawcount,stride);
+#endif // _IRR_OPENGL_USE_EXTPOINTER_
 }
 
 inline void COpenGLExtensionHandler::extGlMultiDrawElementsIndirect(GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride)
 {
-    if (Version>=430||FeatureAvailable[IRR_ARB_transform_feedback_instanced])
-    {
-    #ifdef _IRR_OPENGL_USE_EXTPOINTER_
-        if (pGlMultiDrawElementsIndirect)
-            pGlMultiDrawElementsIndirect(mode,type,indirect,drawcount,stride);
-    #else
-        glMultiDrawElementsIndirect(mode,type,indirect,drawcount,stride);
-    #endif // _IRR_OPENGL_USE_EXTPOINTER_
-    }
-    else
-        os::Printer::log("glMultiDrawElementsIndirect not supported", ELL_ERROR);
+#ifdef _IRR_OPENGL_USE_EXTPOINTER_
+    if (pGlMultiDrawElementsIndirect)
+        pGlMultiDrawElementsIndirect(mode,type,indirect,drawcount,stride);
+#else
+    glMultiDrawElementsIndirect(mode,type,indirect,drawcount,stride);
+#endif // _IRR_OPENGL_USE_EXTPOINTER_
 }
 
 inline void COpenGLExtensionHandler::extGlBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
@@ -4672,15 +4747,10 @@ inline void COpenGLExtensionHandler::extGlPatchParameteri(GLenum pname, GLuint v
 inline void COpenGLExtensionHandler::extGlProgramParameteri(GLuint program, GLenum pname, GLint value)
 {
 #if defined(_IRR_OPENGL_USE_EXTPOINTER_)
-	if (queryFeature(EVDF_GEOMETRY_SHADER))
-	{
-		if (pGlProgramParameteriARB)
-			pGlProgramParameteriARB(program, pname, value);
-		else if (pGlProgramParameteriEXT)
-			pGlProgramParameteriEXT(program, pname, value);
-	}
+	if (pGlProgramParameteri)
+        pGlProgramParameteri(program, pname, value);
 #else
-	os::Printer::log("glProgramParameteri not supported", ELL_ERROR);
+    glProgramParameteri(program, pname, value);
 #endif
 }
 
diff --git a/source/Irrlicht/COpenGLSLMaterialRenderer.cpp b/source/Irrlicht/COpenGLSLMaterialRenderer.cpp
index 67aeb6ffe..c2f360b78 100644
--- a/source/Irrlicht/COpenGLSLMaterialRenderer.cpp
+++ b/source/Irrlicht/COpenGLSLMaterialRenderer.cpp
@@ -412,79 +412,79 @@ void COpenGLSLMaterialRenderer::setShaderConstant(const void* data, int32_t loca
     switch (type)
     {
     case ESCT_FLOAT:
-        COpenGLExtensionHandler::extGlUniform1fv(loc,cnt,(GLfloat*)data);
+        COpenGLExtensionHandler::extGlProgramUniform1fv(Program2,loc,cnt,(GLfloat*)data);
         break;
     case ESCT_FLOAT_VEC2:
-        COpenGLExtensionHandler::extGlUniform2fv(loc,cnt,(GLfloat*)data);
+        COpenGLExtensionHandler::extGlProgramUniform2fv(Program2,loc,cnt,(GLfloat*)data);
         break;
     case ESCT_FLOAT_VEC3:
-        COpenGLExtensionHandler::extGlUniform3fv(loc,cnt,(GLfloat*)data);
+        COpenGLExtensionHandler::extGlProgramUniform3fv(Program2,loc,cnt,(GLfloat*)data);
         break;
     case ESCT_FLOAT_VEC4:
-        COpenGLExtensionHandler::extGlUniform4fv(loc,cnt,(GLfloat*)data);
+        COpenGLExtensionHandler::extGlProgramUniform4fv(Program2,loc,cnt,(GLfloat*)data);
         break;
     case ESCT_INT:
-        COpenGLExtensionHandler::extGlUniform1iv(loc,cnt,(GLint*)data);
+        COpenGLExtensionHandler::extGlProgramUniform1iv(Program2,loc,cnt,(GLint*)data);
         break;
     case ESCT_INT_VEC2:
-        COpenGLExtensionHandler::extGlUniform2iv(loc,cnt,(GLint*)data);
+        COpenGLExtensionHandler::extGlProgramUniform2iv(Program2,loc,cnt,(GLint*)data);
         break;
     case ESCT_INT_VEC3:
-        COpenGLExtensionHandler::extGlUniform3iv(loc,cnt,(GLint*)data);
+        COpenGLExtensionHandler::extGlProgramUniform3iv(Program2,loc,cnt,(GLint*)data);
         break;
     case ESCT_INT_VEC4:
-        COpenGLExtensionHandler::extGlUniform4iv(loc,cnt,(GLint*)data);
+        COpenGLExtensionHandler::extGlProgramUniform4iv(Program2,loc,cnt,(GLint*)data);
         break;
     case ESCT_UINT:
-        COpenGLExtensionHandler::extGlUniform1uiv(loc,cnt,(GLuint*)data);
+        COpenGLExtensionHandler::extGlProgramUniform1uiv(Program2,loc,cnt,(GLuint*)data);
         break;
     case ESCT_UINT_VEC2:
-        COpenGLExtensionHandler::extGlUniform2uiv(loc,cnt,(GLuint*)data);
+        COpenGLExtensionHandler::extGlProgramUniform2uiv(Program2,loc,cnt,(GLuint*)data);
         break;
     case ESCT_UINT_VEC3:
-        COpenGLExtensionHandler::extGlUniform3uiv(loc,cnt,(GLuint*)data);
+        COpenGLExtensionHandler::extGlProgramUniform3uiv(Program2,loc,cnt,(GLuint*)data);
         break;
     case ESCT_UINT_VEC4:
-        COpenGLExtensionHandler::extGlUniform4uiv(loc,cnt,(GLuint*)data);
+        COpenGLExtensionHandler::extGlProgramUniform4uiv(Program2,loc,cnt,(GLuint*)data);
         break;
     case ESCT_BOOL:
-        COpenGLExtensionHandler::extGlUniform1iv(loc,cnt,(GLint*)data);
+        COpenGLExtensionHandler::extGlProgramUniform1iv(Program2,loc,cnt,(GLint*)data);
         break;
     case ESCT_BOOL_VEC2:
-        COpenGLExtensionHandler::extGlUniform2iv(loc,cnt,(GLint*)data);
+        COpenGLExtensionHandler::extGlProgramUniform2iv(Program2,loc,cnt,(GLint*)data);
         break;
     case ESCT_BOOL_VEC3:
-        COpenGLExtensionHandler::extGlUniform3iv(loc,cnt,(GLint*)data);
+        COpenGLExtensionHandler::extGlProgramUniform3iv(Program2,loc,cnt,(GLint*)data);
         break;
     case ESCT_BOOL_VEC4:
-        COpenGLExtensionHandler::extGlUniform4iv(loc,cnt,(GLint*)data);
+        COpenGLExtensionHandler::extGlProgramUniform4iv(Program2,loc,cnt,(GLint*)data);
         break;
     case ESCT_FLOAT_MAT2:
-        COpenGLExtensionHandler::extGlUniformMatrix2fv(loc,cnt,false,(GLfloat*)data);
+        COpenGLExtensionHandler::extGlProgramUniformMatrix2fv(Program2,loc,cnt,false,(GLfloat*)data);
         break;
     case ESCT_FLOAT_MAT3:
-        COpenGLExtensionHandler::extGlUniformMatrix3fv(loc,cnt,false,(GLfloat*)data);
+        COpenGLExtensionHandler::extGlProgramUniformMatrix3fv(Program2,loc,cnt,false,(GLfloat*)data);
         break;
     case ESCT_FLOAT_MAT4:
-        COpenGLExtensionHandler::extGlUniformMatrix4fv(loc,cnt,false,(GLfloat*)data);
+        COpenGLExtensionHandler::extGlProgramUniformMatrix4fv(Program2,loc,cnt,false,(GLfloat*)data);
         break;
     case ESCT_FLOAT_MAT2x3:
-        COpenGLExtensionHandler::extGlUniformMatrix2x3fv(loc,cnt,false,(GLfloat*)data);
+        COpenGLExtensionHandler::extGlProgramUniformMatrix2x3fv(Program2,loc,cnt,false,(GLfloat*)data);
         break;
     case ESCT_FLOAT_MAT2x4:
-        COpenGLExtensionHandler::extGlUniformMatrix2x4fv(loc,cnt,false,(GLfloat*)data);
+        COpenGLExtensionHandler::extGlProgramUniformMatrix2x4fv(Program2,loc,cnt,false,(GLfloat*)data);
         break;
     case ESCT_FLOAT_MAT3x2:
-        COpenGLExtensionHandler::extGlUniformMatrix3x2fv(loc,cnt,false,(GLfloat*)data);
+        COpenGLExtensionHandler::extGlProgramUniformMatrix3x2fv(Program2,loc,cnt,false,(GLfloat*)data);
         break;
     case ESCT_FLOAT_MAT3x4:
-        COpenGLExtensionHandler::extGlUniformMatrix3x4fv(loc,cnt,false,(GLfloat*)data);
+        COpenGLExtensionHandler::extGlProgramUniformMatrix3x4fv(Program2,loc,cnt,false,(GLfloat*)data);
         break;
     case ESCT_FLOAT_MAT4x2:
-        COpenGLExtensionHandler::extGlUniformMatrix4x2fv(loc,cnt,false,(GLfloat*)data);
+        COpenGLExtensionHandler::extGlProgramUniformMatrix4x2fv(Program2,loc,cnt,false,(GLfloat*)data);
         break;
     case ESCT_FLOAT_MAT4x3:
-        COpenGLExtensionHandler::extGlUniformMatrix4x3fv(loc,cnt,false,(GLfloat*)data);
+        COpenGLExtensionHandler::extGlProgramUniformMatrix4x3fv(Program2,loc,cnt,false,(GLfloat*)data);
         break;
 #ifdef _DEBUG
     default:
@@ -576,7 +576,7 @@ void COpenGLSLMaterialRenderer::setShaderTextures(const int32_t* textureIndices,
     case ESCT_UINT_SAMPLER_2D_MULTISAMPLE:
     case ESCT_UINT_SAMPLER_2D_MULTISAMPLE_ARRAY:
     case ESCT_UINT_SAMPLER_BUFFER:
-        COpenGLExtensionHandler::extGlUniform1iv(loc,cnt,(GLint*)textureIndices);
+        COpenGLExtensionHandler::extGlProgramUniform1iv(Program2,loc,cnt,(GLint*)textureIndices);
         break;
 #ifdef _DEBUG
     default:
diff --git a/source/Irrlicht/CSceneManager.cpp b/source/Irrlicht/CSceneManager.cpp
index d68c325f4..22f678811 100644
--- a/source/Irrlicht/CSceneManager.cpp
+++ b/source/Irrlicht/CSceneManager.cpp
@@ -15,7 +15,7 @@
 #include "os.h"
 
 // We need this include for the case of skinned mesh support without
-// any such loader
+// any such loader
 #include "CSkinnedMeshSceneNode.h"
 #include "CSkinnedMesh.h"
 
@@ -62,7 +62,7 @@
 
 #ifdef _IRR_COMPILE_WITH_OBJ_LOADER_
 #include "COBJMeshFileLoader.h"
-#endif
+#endif
 
 #ifdef _IRR_COMPILE_WITH_B3D_LOADER_
 #include "CB3DMeshFileLoader.h"
@@ -99,13 +99,13 @@
 #ifdef _IRR_COMPILE_WITH_PLY_WRITER_
 #include "CPLYMeshWriter.h"
 #endif
-
+
 #include "CBillboardSceneNode.h"
 #include "CCubeSceneNode.h"
 #include "CSphereSceneNode.h"
 #include "CAnimatedMeshSceneNode.h"
 #include "CCameraSceneNode.h"
-#include "CMeshSceneNode.h"
+#include "CMeshSceneNode.h"
 #include "CMeshSceneNodeInstanced.h"
 #include "CSkyBoxSceneNode.h"
 #include "CSkyDomeSceneNode.h"
@@ -147,8 +147,8 @@ CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs,
 	// root node's scene manager
 	SceneManager = this;
 
-	// set scene parameters
-	*((float*)&(Parameters[DEBUG_NORMAL_LENGTH])) = 1.f;
+	// set scene parameters
+	*((float*)&(Parameters[DEBUG_NORMAL_LENGTH])) = 1.f;
 	*((video::SColor*)&(Parameters[DEBUG_NORMAL_COLOR])) = video::SColor(255, 34, 221, 221);
 
 	if (Driver)
@@ -158,126 +158,126 @@ CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs,
 		FileSystem->grab();
 
 	if (CursorControl)
-		CursorControl->grab();
+		CursorControl->grab();
 
 	// create geometry creator
-	GeometryCreator = new CGeometryCreator();
-	MeshManipulator = new CMeshManipulator();
-	{
-        //ICPUMesh* boxmesh = GeometryCreator->createCubeMeshCPU();
-
-        size_t redundantMeshDataBufSize = sizeof(char)*24*3+ //data for the skybox positions
-                                        0;
-        void* tmpMem = malloc(redundantMeshDataBufSize);
-        {
+	GeometryCreator = new CGeometryCreator();
+	MeshManipulator = new CMeshManipulator();
+	{
+        //ICPUMesh* boxmesh = GeometryCreator->createCubeMeshCPU();
+
+        size_t redundantMeshDataBufSize = sizeof(char)*24*3+ //data for the skybox positions
+                                        0;
+        void* tmpMem = malloc(redundantMeshDataBufSize);
+        {
             char* skyBoxesVxPositions = (char*)tmpMem;
-            skyBoxesVxPositions[0*3+0] = -1;
-            skyBoxesVxPositions[0*3+1] = -1;
-            skyBoxesVxPositions[0*3+2] = -1;
+            skyBoxesVxPositions[0*3+0] = -1;
+            skyBoxesVxPositions[0*3+1] = -1;
+            skyBoxesVxPositions[0*3+2] = -1;
 
-            skyBoxesVxPositions[1*3+0] = 1;
-            skyBoxesVxPositions[1*3+1] =-1;
-            skyBoxesVxPositions[1*3+2] =-1;
+            skyBoxesVxPositions[1*3+0] = 1;
+            skyBoxesVxPositions[1*3+1] =-1;
+            skyBoxesVxPositions[1*3+2] =-1;
 
-            skyBoxesVxPositions[2*3+0] = 1;
-            skyBoxesVxPositions[2*3+1] = 1;
-            skyBoxesVxPositions[2*3+2] =-1;
+            skyBoxesVxPositions[2*3+0] = 1;
+            skyBoxesVxPositions[2*3+1] = 1;
+            skyBoxesVxPositions[2*3+2] =-1;
 
-            skyBoxesVxPositions[3*3+0] =-1;
-            skyBoxesVxPositions[3*3+1] = 1;
+            skyBoxesVxPositions[3*3+0] =-1;
+            skyBoxesVxPositions[3*3+1] = 1;
             skyBoxesVxPositions[3*3+2] =-1;
 
             // create left side
-            skyBoxesVxPositions[4*3+0] = 1;
-            skyBoxesVxPositions[4*3+1] =-1;
-            skyBoxesVxPositions[4*3+2] =-1;
+            skyBoxesVxPositions[4*3+0] = 1;
+            skyBoxesVxPositions[4*3+1] =-1;
+            skyBoxesVxPositions[4*3+2] =-1;
 
-            skyBoxesVxPositions[5*3+0] = 1;
-            skyBoxesVxPositions[5*3+1] =-1;
-            skyBoxesVxPositions[5*3+2] = 1;
+            skyBoxesVxPositions[5*3+0] = 1;
+            skyBoxesVxPositions[5*3+1] =-1;
+            skyBoxesVxPositions[5*3+2] = 1;
 
-            skyBoxesVxPositions[6*3+0] = 1;
-            skyBoxesVxPositions[6*3+1] = 1;
-            skyBoxesVxPositions[6*3+2] = 1;
+            skyBoxesVxPositions[6*3+0] = 1;
+            skyBoxesVxPositions[6*3+1] = 1;
+            skyBoxesVxPositions[6*3+2] = 1;
 
-            skyBoxesVxPositions[7*3+0] = 1;
-            skyBoxesVxPositions[7*3+1] = 1;
+            skyBoxesVxPositions[7*3+0] = 1;
+            skyBoxesVxPositions[7*3+1] = 1;
             skyBoxesVxPositions[7*3+2] =-1;
 
             // create back side
-            skyBoxesVxPositions[8*3+0] = 1;
-            skyBoxesVxPositions[8*3+1] =-1;
-            skyBoxesVxPositions[8*3+2] = 1;
+            skyBoxesVxPositions[8*3+0] = 1;
+            skyBoxesVxPositions[8*3+1] =-1;
+            skyBoxesVxPositions[8*3+2] = 1;
 
-            skyBoxesVxPositions[9*3+0] =-1;
-            skyBoxesVxPositions[9*3+1] =-1;
-            skyBoxesVxPositions[9*3+2] = 1;
+            skyBoxesVxPositions[9*3+0] =-1;
+            skyBoxesVxPositions[9*3+1] =-1;
+            skyBoxesVxPositions[9*3+2] = 1;
 
-            skyBoxesVxPositions[10*3+0] =-1;
-            skyBoxesVxPositions[10*3+1] = 1;
-            skyBoxesVxPositions[10*3+2] = 1;
+            skyBoxesVxPositions[10*3+0] =-1;
+            skyBoxesVxPositions[10*3+1] = 1;
+            skyBoxesVxPositions[10*3+2] = 1;
 
-            skyBoxesVxPositions[11*3+0] = 1;
-            skyBoxesVxPositions[11*3+1] = 1;
+            skyBoxesVxPositions[11*3+0] = 1;
+            skyBoxesVxPositions[11*3+1] = 1;
             skyBoxesVxPositions[11*3+2] = 1;
 
             // create right side
-            skyBoxesVxPositions[12*3+0] =-1;
-            skyBoxesVxPositions[12*3+1] =-1;
-            skyBoxesVxPositions[12*3+2] = 1;
+            skyBoxesVxPositions[12*3+0] =-1;
+            skyBoxesVxPositions[12*3+1] =-1;
+            skyBoxesVxPositions[12*3+2] = 1;
 
-            skyBoxesVxPositions[13*3+0] =-1;
-            skyBoxesVxPositions[13*3+1] =-1;
-            skyBoxesVxPositions[13*3+2] =-1;
+            skyBoxesVxPositions[13*3+0] =-1;
+            skyBoxesVxPositions[13*3+1] =-1;
+            skyBoxesVxPositions[13*3+2] =-1;
 
-            skyBoxesVxPositions[14*3+0] =-1;
-            skyBoxesVxPositions[14*3+1] = 1;
-            skyBoxesVxPositions[14*3+2] =-1;
+            skyBoxesVxPositions[14*3+0] =-1;
+            skyBoxesVxPositions[14*3+1] = 1;
+            skyBoxesVxPositions[14*3+2] =-1;
 
-            skyBoxesVxPositions[15*3+0] =-1;
-            skyBoxesVxPositions[15*3+1] = 1;
+            skyBoxesVxPositions[15*3+0] =-1;
+            skyBoxesVxPositions[15*3+1] = 1;
             skyBoxesVxPositions[15*3+2] = 1;
 
             // create top side
-            skyBoxesVxPositions[16*3+0] = 1;
-            skyBoxesVxPositions[16*3+1] = 1;
-            skyBoxesVxPositions[16*3+2] =-1;
+            skyBoxesVxPositions[16*3+0] = 1;
+            skyBoxesVxPositions[16*3+1] = 1;
+            skyBoxesVxPositions[16*3+2] =-1;
 
-            skyBoxesVxPositions[17*3+0] = 1;
-            skyBoxesVxPositions[17*3+1] = 1;
-            skyBoxesVxPositions[17*3+2] = 1;
+            skyBoxesVxPositions[17*3+0] = 1;
+            skyBoxesVxPositions[17*3+1] = 1;
+            skyBoxesVxPositions[17*3+2] = 1;
 
-            skyBoxesVxPositions[18*3+0] =-1;
-            skyBoxesVxPositions[18*3+1] = 1;
-            skyBoxesVxPositions[18*3+2] = 1;
+            skyBoxesVxPositions[18*3+0] =-1;
+            skyBoxesVxPositions[18*3+1] = 1;
+            skyBoxesVxPositions[18*3+2] = 1;
 
-            skyBoxesVxPositions[19*3+0] =-1;
-            skyBoxesVxPositions[19*3+1] = 1;
+            skyBoxesVxPositions[19*3+0] =-1;
+            skyBoxesVxPositions[19*3+1] = 1;
             skyBoxesVxPositions[19*3+2] =-1;
 
             // create bottom side
-            skyBoxesVxPositions[20*3+0] = 1;
-            skyBoxesVxPositions[20*3+1] =-1;
-            skyBoxesVxPositions[20*3+2] = 1;
-
-            skyBoxesVxPositions[21*3+0] = 1;
-            skyBoxesVxPositions[21*3+1] =-1;
-            skyBoxesVxPositions[21*3+2] =-1;
-
-            skyBoxesVxPositions[22*3+0] =-1;
-            skyBoxesVxPositions[22*3+1] =-1;
-            skyBoxesVxPositions[22*3+2] =-1;
-
-            skyBoxesVxPositions[23*3+0] =-1;
-            skyBoxesVxPositions[23*3+1] =-1;
-            skyBoxesVxPositions[23*3+2] = 1;
-        }
-        redundantMeshDataBuf = Driver->createGPUBuffer(redundantMeshDataBufSize,tmpMem);
-        free(tmpMem);
+            skyBoxesVxPositions[20*3+0] = 1;
+            skyBoxesVxPositions[20*3+1] =-1;
+            skyBoxesVxPositions[20*3+2] = 1;
+
+            skyBoxesVxPositions[21*3+0] = 1;
+            skyBoxesVxPositions[21*3+1] =-1;
+            skyBoxesVxPositions[21*3+2] =-1;
+
+            skyBoxesVxPositions[22*3+0] =-1;
+            skyBoxesVxPositions[22*3+1] =-1;
+            skyBoxesVxPositions[22*3+2] =-1;
+
+            skyBoxesVxPositions[23*3+0] =-1;
+            skyBoxesVxPositions[23*3+1] =-1;
+            skyBoxesVxPositions[23*3+2] = 1;
+        }
+        redundantMeshDataBuf = Driver->createGPUBuffer(redundantMeshDataBufSize,tmpMem);
+        free(tmpMem);
 	}
 
 	// create mesh cache if not there already
-	MeshCache = new CMeshCache<ICPUMesh>();
+	MeshCache = new CMeshCache<ICPUMesh>();
 
 	// add file format loaders. add the least commonly used ones first,
 	// as these are checked last
@@ -332,13 +332,13 @@ CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs,
 	#endif
 	#ifdef _IRR_COMPILE_WITH_B3D_LOADER_
 	MeshLoaderList.push_back(new CB3DMeshFileLoader(this));
-	#endif
+	#endif
 
 
 	// factories
 	ISceneNodeFactory* factory = new CDefaultSceneNodeFactory(this);
 	registerSceneNodeFactory(factory);
-	factory->drop();
+	factory->drop();
 
 	ISceneNodeAnimatorFactory* animatorFactory = new CDefaultSceneNodeAnimatorFactory(this, CursorControl);
 	registerSceneNodeAnimatorFactory(animatorFactory);
@@ -353,31 +353,31 @@ CSceneManager::~CSceneManager()
 
 	//! force to remove hardwareTextures from the driver
 	//! because Scenes may hold internally data bounded to sceneNodes
-	//! which may be destroyed twice
-    if (redundantMeshDataBuf)
+	//! which may be destroyed twice
+    if (redundantMeshDataBuf)
         redundantMeshDataBuf->drop();
 	if (FileSystem)
 		FileSystem->drop();
 
 	if (CursorControl)
 		CursorControl->drop();
-
-    if (MeshManipulator)
-        MeshManipulator->drop();
+
+    if (MeshManipulator)
+        MeshManipulator->drop();
 
 	if (GeometryCreator)
 		GeometryCreator->drop();
 
 	uint32_t i;
 	for (i=0; i<MeshLoaderList.size(); ++i)
-		MeshLoaderList[i]->drop();
+		MeshLoaderList[i]->drop();
 
 	if (ActiveCamera)
 		ActiveCamera->drop();
 	ActiveCamera = 0;
 
 	if (MeshCache)
-		MeshCache->drop();
+		MeshCache->drop();
 
 	for (i=0; i<SceneNodeFactoryList.size(); ++i)
 		SceneNodeFactoryList[i]->drop();
@@ -406,11 +406,11 @@ ICPUMesh* CSceneManager::getMesh(const io::path& filename)
 	if (msh)
 		return msh;
 
-	io::IReadFile* file = FileSystem->createAndOpenFile(filename);
-	msh = getMesh(file);
-	if (file)
-        file->drop();
-
+	io::IReadFile* file = FileSystem->createAndOpenFile(filename);
+	msh = getMesh(file);
+	if (file)
+        file->drop();
+
 	return msh;
 }
 
@@ -418,10 +418,10 @@ ICPUMesh* CSceneManager::getMesh(const io::path& filename)
 //! gets an animateable mesh. loads it if needed. returned pointer must not be dropped.
 ICPUMesh* CSceneManager::getMesh(io::IReadFile* file)
 {
-	if (!file)
+	if (!file)
     {
 		os::Printer::log("Could not load mesh, because file could not be opened", ELL_ERROR);
-		return 0;
+		return 0;
     }
 
 	io::path name = file->getFileName();
@@ -516,10 +516,10 @@ IMeshSceneNode* CSceneManager::addMeshSceneNode(IGPUMesh* mesh, IDummyTransforma
 	node->drop();
 
 	return node;
-}
-
+}
+
 IMeshSceneNodeInstanced* CSceneManager::addMeshSceneNodeInstanced(IDummyTransformationSceneNode* parent, int32_t id,
-    const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale)
+    const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale)
 {
 	if (!parent)
 		parent = this;
@@ -527,11 +527,11 @@ IMeshSceneNodeInstanced* CSceneManager::addMeshSceneNodeInstanced(IDummyTransfor
 	CMeshSceneNodeInstanced* node = new CMeshSceneNodeInstanced(parent, this, id, position, rotation, scale);
 	node->drop();
 
-	return node;
+	return node;
 }
 
 //! adds a scene node for rendering an animated mesh model
-ISkinnedMeshSceneNode* CSceneManager::addSkinnedMeshSceneNode(
+ISkinnedMeshSceneNode* CSceneManager::addSkinnedMeshSceneNode(
     IGPUSkinnedMesh* mesh, const ISkinningStateManager::E_BONE_UPDATE_MODE& boneControlMode,
     IDummyTransformationSceneNode* parent, int32_t id,
     const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale)
@@ -758,8 +758,8 @@ bool CSceneManager::isCulled(ISceneNode* node) const
 
 	// has occlusion query information
 	if ((node->getAutomaticCulling() & scene::EAC_OCC_QUERY)&&node->getOcclusionQuery())
-	{
-	    uint32_t tmp;
+	{
+	    uint32_t tmp;
 	    node->getOcclusionQuery()->getQueryResult(&tmp);
 		result = tmp==0;
 	}
@@ -767,8 +767,8 @@ bool CSceneManager::isCulled(ISceneNode* node) const
 	// can be seen by a bounding box ?
 	if (!result && (node->getAutomaticCulling() & scene::EAC_BOX))
 	{
-		core::aabbox3d<float> tbox = node->getBoundingBox();
-		if (tbox.MinEdge==tbox.MaxEdge)
+		core::aabbox3d<float> tbox = node->getBoundingBox();
+		if (tbox.MinEdge==tbox.MaxEdge)
             return true;
 		node->getAbsoluteTransformation().transformBoxEx(tbox);
 		result = !(tbox.intersectsWithBox(cam->getViewFrustum()->getBoundingBox() ));
@@ -782,14 +782,14 @@ bool CSceneManager::isCulled(ISceneNode* node) const
 	// can be seen by cam pyramid planes ?
 	if (!result && (node->getAutomaticCulling() & scene::EAC_FRUSTUM_BOX))
 	{
-		core::aabbox3d<float> tbox = node->getBoundingBox();
-		if (tbox.MinEdge==tbox.MaxEdge)
-            return true;
-
-        //transform the frustum to the node's current absolute transformation
-        core::matrix4 worldviewproj = concatenateBFollowedByA(cam->getProjectionMatrix(),concatenateBFollowedByA(cam->getViewMatrix(),node->getAbsoluteTransformation()));
-
-        if (!worldviewproj.isBoxInsideFrustum(tbox))
+		core::aabbox3d<float> tbox = node->getBoundingBox();
+		if (tbox.MinEdge==tbox.MaxEdge)
+            return true;
+
+        //transform the frustum to the node's current absolute transformation
+        core::matrix4 worldviewproj = concatenateBFollowedByA(cam->getProjectionMatrix(),concatenateBFollowedByA(cam->getViewMatrix(),node->getAbsoluteTransformation()));
+
+        if (!worldviewproj.isBoxInsideFrustum(tbox))
             return true;
 	}
 
@@ -906,18 +906,23 @@ uint32_t CSceneManager::registerNodeForRendering(ISceneNode* node, E_SCENE_NODE_
 
 	return taken;
 }
-
+
 //!
 void CSceneManager::OnAnimate(uint32_t timeMs)
 {
-    IDummyTransformationSceneNodeList::ConstIterator it = getChildren().begin();
-    for (; it != getChildren().end(); ++it)
-    {
-        ISceneNode* tmpChild = static_cast<ISceneNode*>(*it);
-        if ((*it)->isISceneNode())
-            static_cast<ISceneNode*>(*it)->OnAnimate(timeMs);
-        else
-            OnAnimate_static(*it,timeMs);
+    size_t prevSize = Children.size();
+    for (size_t i=0; i<prevSize;)
+    {
+        IDummyTransformationSceneNode* tmpChild = Children[i];
+        if (tmpChild->isISceneNode())
+            static_cast<ISceneNode*>(tmpChild)->OnAnimate(timeMs);
+        else
+            OnAnimate_static(tmpChild,timeMs);
+
+        if (Children[i]>tmpChild)
+            prevSize = Children.size();
+        else
+            i++;
     }
 }
 
@@ -1226,7 +1231,7 @@ IMeshLoader* CSceneManager::getMeshLoader(uint32_t index) const
 	else
 		return 0;
 }
-
+
 
 
 //! Returns a pointer to the mesh manipulator.
@@ -1273,8 +1278,8 @@ ISceneNode* CSceneManager::getSceneNodeFromName(const char* name, IDummyTransfor
 
 	IDummyTransformationSceneNode* node = 0;
 
-	const IDummyTransformationSceneNodeList& list = start->getChildren();
-	IDummyTransformationSceneNodeList::ConstIterator it = list.begin();
+	const IDummyTransformationSceneNodeArray& list = start->getChildren();
+	IDummyTransformationSceneNodeArray::ConstIterator it = list.begin();
 	for (; it!=list.end(); ++it)
 	{
 		node = getSceneNodeFromName(name, *it);
@@ -1297,8 +1302,8 @@ ISceneNode* CSceneManager::getSceneNodeFromId(int32_t id, IDummyTransformationSc
 
 	ISceneNode* node = 0;
 
-	const IDummyTransformationSceneNodeList& list = start->getChildren();
-	IDummyTransformationSceneNodeList::ConstIterator it = list.begin();
+	const IDummyTransformationSceneNodeArray& list = start->getChildren();
+	IDummyTransformationSceneNodeArray::ConstIterator it = list.begin();
 	for (; it!=list.end(); ++it)
 	{
 		node = getSceneNodeFromId(id, *it);
@@ -1321,8 +1326,8 @@ ISceneNode* CSceneManager::getSceneNodeFromType(scene::ESCENE_NODE_TYPE type, ID
 
 	ISceneNode* node = 0;
 
-	const IDummyTransformationSceneNodeList& list = start->getChildren();
-	IDummyTransformationSceneNodeList::ConstIterator it = list.begin();
+	const IDummyTransformationSceneNodeArray& list = start->getChildren();
+	IDummyTransformationSceneNodeArray::ConstIterator it = list.begin();
 	for (; it!=list.end(); ++it)
 	{
 		node = getSceneNodeFromType(type, *it);
@@ -1343,8 +1348,8 @@ void CSceneManager::getSceneNodesFromType(ESCENE_NODE_TYPE type, core::array<sce
 	if (start->getType() == type || ESNT_ANY == type)
 		outNodes.push_back(start);
 
-	const IDummyTransformationSceneNodeList& list = start->getChildren();
-	IDummyTransformationSceneNodeList::ConstIterator it = list.begin();
+	const IDummyTransformationSceneNodeArray& list = start->getChildren();
+	IDummyTransformationSceneNodeArray::ConstIterator it = list.begin();
 
 	for (; it!=list.end(); ++it)
 	{
diff --git a/source/Irrlicht/Irrlicht-gcc.cbp b/source/Irrlicht/Irrlicht-gcc.cbp
index ad4a1b5cf..a92a67258 100644
--- a/source/Irrlicht/Irrlicht-gcc.cbp
+++ b/source/Irrlicht/Irrlicht-gcc.cbp
@@ -360,6 +360,7 @@
 					<Add option="-msse3" />
 					<Add option="-ggdb3" />
 					<Add option="-std=c++03" />
+					<Add option="-fstack-protector-strong" />
 					<Add option="-D_IRR_STATIC_LIB_" />
 					<Add option="-D_DEBUG" />
 					<Add directory="../../include" />
@@ -372,6 +373,7 @@
 				</Compiler>
 				<Linker>
 					<Add option="-fuse-ld=gold" />
+					<Add option="-fstack-protector-strong" />
 					<Add library="GL" />
 					<Add library="Xxf86vm" />
 					<Add library="unwind-x86_64" />
@@ -453,6 +455,8 @@
 			<Add option="-D_IRR_COMPILE_WITH_OPENGL_" />
 		</Compiler>
 		<Unit filename="../../include/CFinalBoneHierarchy.h" />
+		<Unit filename="../../include/COpenGLStateManager.h" />
+		<Unit filename="../../include/COpenGLStateManagerImpl.h" />
 		<Unit filename="../../include/ECullingTypes.h" />
 		<Unit filename="../../include/EDebugSceneTypes.h" />
 		<Unit filename="../../include/EDeviceTypes.h" />
diff --git a/source/Irrlicht/Irrlicht.cpp b/source/Irrlicht/Irrlicht.cpp
index 58d90b60f..2d3395822 100644
--- a/source/Irrlicht/Irrlicht.cpp
+++ b/source/Irrlicht/Irrlicht.cpp
@@ -22,10 +22,6 @@ static const char* const copyright = "Irrlicht Engine (c) 2002-2011 Nikolaus Geb
 #include "MacOSX/CIrrDeviceMacOSX.h"
 #endif
 
-#ifdef _IRR_COMPILE_WITH_WINDOWS_CE_DEVICE_
-#include "CIrrDeviceWinCE.h"
-#endif
-
 #ifdef _IRR_COMPILE_WITH_X11_DEVICE_
 #include "CIrrDeviceLinux.h"
 #endif
@@ -77,11 +73,6 @@ namespace irr
 			dev = new CIrrDeviceMacOSX(params);
 #endif
 
-#ifdef _IRR_COMPILE_WITH_WINDOWS_CE_DEVICE_
-		if (params.DeviceType == EIDT_WINCE || (!dev && params.DeviceType == EIDT_BEST))
-			dev = new CIrrDeviceWinCE(params);
-#endif
-
 #ifdef _IRR_COMPILE_WITH_X11_DEVICE_
 		if (params.DeviceType == EIDT_X11 || (!dev && params.DeviceType == EIDT_BEST))
 			dev = new CIrrDeviceLinux(params);
diff --git a/source/Irrlicht/Irrlicht10.0.vcxproj b/source/Irrlicht/Irrlicht10.0.vcxproj
index 98d62a4b1..ccde5c340 100644
--- a/source/Irrlicht/Irrlicht10.0.vcxproj
+++ b/source/Irrlicht/Irrlicht10.0.vcxproj
@@ -1466,7 +1466,6 @@
     <ClInclude Include="CIrrDeviceLinux.h" />
     <ClInclude Include="CIrrDeviceSDL.h" />
     <ClInclude Include="CIrrDeviceStub.h" />
-    <ClInclude Include="CIrrDeviceWinCE.h" />
     <ClInclude Include="CAttributeImpl.h" />
     <ClInclude Include="CFileList.h" />
     <ClInclude Include="CFileSystem.h" />
@@ -1770,7 +1769,6 @@
     <ClCompile Include="CIrrDeviceLinux.cpp" />
     <ClCompile Include="CIrrDeviceSDL.cpp" />
     <ClCompile Include="CIrrDeviceStub.cpp" />
-    <ClCompile Include="CIrrDeviceWinCE.cpp" />
     <ClCompile Include="CFileList.cpp" />
     <ClCompile Include="CFileSystem.cpp" />
     <ClCompile Include="CLimitReadFile.cpp" />
diff --git a/source/Irrlicht/Irrlicht10.0.vcxproj.filters b/source/Irrlicht/Irrlicht10.0.vcxproj.filters
index 010484350..f6c2e4957 100644
--- a/source/Irrlicht/Irrlicht10.0.vcxproj.filters
+++ b/source/Irrlicht/Irrlicht10.0.vcxproj.filters
@@ -942,9 +942,6 @@
     <ClInclude Include="CIrrDeviceStub.h">
       <Filter>Irrlicht\irr\device</Filter>
     </ClInclude>
-    <ClInclude Include="CIrrDeviceWinCE.h">
-      <Filter>Irrlicht\irr\device</Filter>
-    </ClInclude>
     <ClInclude Include="CAttributeImpl.h">
       <Filter>Irrlicht\io</Filter>
     </ClInclude>
@@ -1659,9 +1656,6 @@
     <ClCompile Include="CIrrDeviceStub.cpp">
       <Filter>Irrlicht\irr\device</Filter>
     </ClCompile>
-    <ClCompile Include="CIrrDeviceWinCE.cpp">
-      <Filter>Irrlicht\irr\device</Filter>
-    </ClCompile>
     <ClCompile Include="CFileList.cpp">
       <Filter>Irrlicht\io</Filter>
     </ClCompile>