]> git.lizzy.rs Git - irrlicht.git/blobdiff - source/Irrlicht/OpenGL/MaterialRenderer.cpp
Fix line endings in the new driver
[irrlicht.git] / source / Irrlicht / OpenGL / MaterialRenderer.cpp
index 20d684c870845a12ff4aaac4f4dd12b0305903d7..d7aa4837cfc0ab4f4e6b78ff9ca481f48fa66de6 100644 (file)
-// Copyright (C) 2014 Patryk Nadrowski\r
-// This file is part of the "Irrlicht Engine".\r
-// For conditions of distribution and use, see copyright notice in irrlicht.h\r
-\r
-#include "MaterialRenderer.h"\r
-\r
-#include "EVertexAttributes.h"\r
-#include "IGPUProgrammingServices.h"\r
-#include "IShaderConstantSetCallBack.h"\r
-#include "IVideoDriver.h"\r
-#include "os.h"\r
-\r
-#include "Driver.h"\r
-\r
-#include "COpenGLCoreTexture.h"\r
-#include "COpenGLCoreCacheHandler.h"\r
-\r
-namespace irr\r
-{\r
-namespace video\r
-{\r
-\r
-\r
-COpenGL3MaterialRenderer::COpenGL3MaterialRenderer(COpenGL3DriverBase* driver,\r
-               s32& outMaterialTypeNr,\r
-               const c8* vertexShaderProgram,\r
-               const c8* pixelShaderProgram,\r
-               IShaderConstantSetCallBack* callback,\r
-               E_MATERIAL_TYPE baseMaterial,\r
-               s32 userData)\r
-       : Driver(driver), CallBack(callback), Alpha(false), Blending(false), FixedBlending(false), Program(0), UserData(userData)\r
-{\r
-#ifdef _DEBUG\r
-       setDebugName("MaterialRenderer");\r
-#endif\r
-\r
-       switch (baseMaterial)\r
-       {\r
-       case EMT_TRANSPARENT_VERTEX_ALPHA:\r
-       case EMT_TRANSPARENT_ALPHA_CHANNEL:\r
-               Alpha = true;\r
-               break;\r
-       case EMT_TRANSPARENT_ADD_COLOR:\r
-               FixedBlending = true;\r
-               break;\r
-       case EMT_ONETEXTURE_BLEND:\r
-               Blending = true;\r
-               break;\r
-       default:\r
-               break;\r
-       }\r
-\r
-       if (CallBack)\r
-               CallBack->grab();\r
-\r
-       init(outMaterialTypeNr, vertexShaderProgram, pixelShaderProgram);\r
-}\r
-\r
-\r
-COpenGL3MaterialRenderer::COpenGL3MaterialRenderer(COpenGL3DriverBase* driver,\r
-                                       IShaderConstantSetCallBack* callback,\r
-                                       E_MATERIAL_TYPE baseMaterial, s32 userData)\r
-: Driver(driver), CallBack(callback), Alpha(false), Blending(false), FixedBlending(false), Program(0), UserData(userData)\r
-{\r
-       switch (baseMaterial)\r
-       {\r
-       case EMT_TRANSPARENT_VERTEX_ALPHA:\r
-       case EMT_TRANSPARENT_ALPHA_CHANNEL:\r
-               Alpha = true;\r
-               break;\r
-       case EMT_TRANSPARENT_ADD_COLOR:\r
-               FixedBlending = true;\r
-               break;\r
-       case EMT_ONETEXTURE_BLEND:\r
-               Blending = true;\r
-               break;\r
-       default:\r
-               break;\r
-       }\r
-\r
-       if (CallBack)\r
-               CallBack->grab();\r
-}\r
-\r
-\r
-COpenGL3MaterialRenderer::~COpenGL3MaterialRenderer()\r
-{\r
-       if (CallBack)\r
-               CallBack->drop();\r
-\r
-       if (Program)\r
-       {\r
-               GLuint shaders[8];\r
-               GLint count;\r
-               glGetAttachedShaders(Program, 8, &count, shaders);\r
-\r
-               count=core::min_(count,8);\r
-               for (GLint i=0; i<count; ++i)\r
-                       glDeleteShader(shaders[i]);\r
-               glDeleteProgram(Program);\r
-               Program = 0;\r
-       }\r
-\r
-       UniformInfo.clear();\r
-}\r
-\r
-GLuint COpenGL3MaterialRenderer::getProgram() const\r
-{\r
-       return Program;\r
-}\r
-\r
-void COpenGL3MaterialRenderer::init(s32& outMaterialTypeNr,\r
-               const c8* vertexShaderProgram,\r
-               const c8* pixelShaderProgram,\r
-               bool addMaterial)\r
-{\r
-       outMaterialTypeNr = -1;\r
-\r
-       Program = glCreateProgram();\r
-\r
-       if (!Program)\r
-               return;\r
-\r
-       if (vertexShaderProgram)\r
-               if (!createShader(GL_VERTEX_SHADER, vertexShaderProgram))\r
-                       return;\r
-\r
-       if (pixelShaderProgram)\r
-               if (!createShader(GL_FRAGMENT_SHADER, pixelShaderProgram))\r
-                       return;\r
-\r
-       for ( size_t i = 0; i < EVA_COUNT; ++i )\r
-                       glBindAttribLocation( Program, i, sBuiltInVertexAttributeNames[i]);\r
-\r
-       if (!linkProgram())\r
-               return;\r
-\r
-       if (addMaterial)\r
-               outMaterialTypeNr = Driver->addMaterialRenderer(this);\r
-}\r
-\r
-\r
-bool COpenGL3MaterialRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype)\r
-{\r
-       if (CallBack && Program)\r
-               CallBack->OnSetConstants(this, UserData);\r
-\r
-       return true;\r
-}\r
-\r
-\r
-void COpenGL3MaterialRenderer::OnSetMaterial(const video::SMaterial& material,\r
-                               const video::SMaterial& lastMaterial,\r
-                               bool resetAllRenderstates,\r
-                               video::IMaterialRendererServices* services)\r
-{\r
-       COpenGL3CacheHandler* cacheHandler = Driver->getCacheHandler();\r
-\r
-       cacheHandler->setProgram(Program);\r
-\r
-       Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);\r
-\r
-       if (Alpha)\r
-       {\r
-               cacheHandler->setBlend(true);\r
-               cacheHandler->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);\r
-       }\r
-       else if (FixedBlending)\r
-       {\r
-               cacheHandler->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);\r
-               cacheHandler->setBlend(true);\r
-       }\r
-       else if (Blending)\r
-       {\r
-               E_BLEND_FACTOR srcRGBFact,dstRGBFact,srcAlphaFact,dstAlphaFact;\r
-               E_MODULATE_FUNC modulate;\r
-               u32 alphaSource;\r
-               unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulate, alphaSource, material.MaterialTypeParam);\r
-\r
-               cacheHandler->setBlendFuncSeparate(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact),\r
-                       Driver->getGLBlend(srcAlphaFact), Driver->getGLBlend(dstAlphaFact));\r
-\r
-               cacheHandler->setBlend(true);\r
-       }\r
-\r
-       if (CallBack)\r
-               CallBack->OnSetMaterial(material);\r
-}\r
-\r
-\r
-void COpenGL3MaterialRenderer::OnUnsetMaterial()\r
-{\r
-}\r
-\r
-\r
-bool COpenGL3MaterialRenderer::isTransparent() const\r
-{\r
-       return (Alpha || Blending || FixedBlending);\r
-}\r
-\r
-\r
-s32 COpenGL3MaterialRenderer::getRenderCapability() const\r
-{\r
-       return 0;\r
-}\r
-\r
-\r
-bool COpenGL3MaterialRenderer::createShader(GLenum shaderType, const char* shader)\r
-{\r
-       if (Program)\r
-       {\r
-               GLuint shaderHandle = glCreateShader(shaderType);\r
-               glShaderSource(shaderHandle, 1, &shader, NULL);\r
-               glCompileShader(shaderHandle);\r
-\r
-               GLint status = 0;\r
-\r
-               glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &status);\r
-\r
-               if (status != GL_TRUE)\r
-               {\r
-                       os::Printer::log("GLSL shader failed to compile", ELL_ERROR);\r
-\r
-                       GLint maxLength=0;\r
-                       GLint length;\r
-\r
-                       glGetShaderiv(shaderHandle, GL_INFO_LOG_LENGTH,\r
-                                       &maxLength);\r
-\r
-                       if (maxLength)\r
-                       {\r
-                               GLchar *infoLog = new GLchar[maxLength];\r
-                               glGetShaderInfoLog(shaderHandle, maxLength, &length, infoLog);\r
-                               os::Printer::log(reinterpret_cast<const c8*>(infoLog), ELL_ERROR);\r
-                               delete [] infoLog;\r
-                       }\r
-\r
-                       return false;\r
-               }\r
-\r
-               glAttachShader(Program, shaderHandle);\r
-       }\r
-\r
-       return true;\r
-}\r
-\r
-\r
-bool COpenGL3MaterialRenderer::linkProgram()\r
-{\r
-       if (Program)\r
-       {\r
-               glLinkProgram(Program);\r
-\r
-               GLint status = 0;\r
-\r
-               glGetProgramiv(Program, GL_LINK_STATUS, &status);\r
-\r
-               if (!status)\r
-               {\r
-                       os::Printer::log("GLSL shader program failed to link", ELL_ERROR);\r
-\r
-                       GLint maxLength=0;\r
-                       GLsizei length;\r
-\r
-                       glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &maxLength);\r
-\r
-                       if (maxLength)\r
-                       {\r
-                               GLchar *infoLog = new GLchar[maxLength];\r
-                               glGetProgramInfoLog(Program, maxLength, &length, infoLog);\r
-                               os::Printer::log(reinterpret_cast<const c8*>(infoLog), ELL_ERROR);\r
-                               delete [] infoLog;\r
-                       }\r
-\r
-                       return false;\r
-               }\r
-\r
-               GLint num = 0;\r
-\r
-               glGetProgramiv(Program, GL_ACTIVE_UNIFORMS, &num);\r
-\r
-               if (num == 0)\r
-                       return true;\r
-\r
-               GLint maxlen = 0;\r
-\r
-               glGetProgramiv(Program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxlen);\r
-\r
-               if (maxlen == 0)\r
-               {\r
-                       os::Printer::log("GLSL: failed to retrieve uniform information", ELL_ERROR);\r
-                       return false;\r
-               }\r
-\r
-               // seems that some implementations use an extra null terminator.\r
-               ++maxlen;\r
-               c8 *buf = new c8[maxlen];\r
-\r
-               UniformInfo.clear();\r
-               UniformInfo.reallocate(num);\r
-\r
-               for (GLint i=0; i < num; ++i)\r
-               {\r
-                       SUniformInfo ui;\r
-                       memset(buf, 0, maxlen);\r
-\r
-                       GLint size;\r
-                       glGetActiveUniform(Program, i, maxlen, 0, &size, &ui.type, reinterpret_cast<GLchar*>(buf));\r
-\r
-            core::stringc name = "";\r
-\r
-                       // array support, workaround for some bugged drivers.\r
-                       for (s32 i = 0; i < maxlen; ++i)\r
-                       {\r
-                               if (buf[i] == '[' || buf[i] == '\0')\r
-                                       break;\r
-\r
-                name += buf[i];\r
-                       }\r
-\r
-                       ui.name = name;\r
-                       ui.location = glGetUniformLocation(Program, buf);\r
-\r
-                       UniformInfo.push_back(ui);\r
-               }\r
-\r
-               delete [] buf;\r
-       }\r
-\r
-       return true;\r
-}\r
-\r
-\r
-void COpenGL3MaterialRenderer::setBasicRenderStates(const SMaterial& material,\r
-                                               const SMaterial& lastMaterial,\r
-                                               bool resetAllRenderstates)\r
-{\r
-       Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);\r
-}\r
-\r
-s32 COpenGL3MaterialRenderer::getVertexShaderConstantID(const c8* name)\r
-{\r
-       return getPixelShaderConstantID(name);\r
-}\r
-\r
-s32 COpenGL3MaterialRenderer::getPixelShaderConstantID(const c8* name)\r
-{\r
-       for (u32 i = 0; i < UniformInfo.size(); ++i)\r
-       {\r
-               if (UniformInfo[i].name == name)\r
-                       return i;\r
-       }\r
-\r
-       return -1;\r
-}\r
-\r
-void COpenGL3MaterialRenderer::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)\r
-{\r
-       os::Printer::log("Cannot set constant, please use high level shader call instead.", ELL_WARNING);\r
-}\r
-\r
-void COpenGL3MaterialRenderer::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)\r
-{\r
-       os::Printer::log("Cannot set constant, use high level shader call.", ELL_WARNING);\r
-}\r
-\r
-bool COpenGL3MaterialRenderer::setVertexShaderConstant(s32 index, const f32* floats, int count)\r
-{\r
-       return setPixelShaderConstant(index, floats, count);\r
-}\r
-\r
-bool COpenGL3MaterialRenderer::setVertexShaderConstant(s32 index, const s32* ints, int count)\r
-{\r
-       return setPixelShaderConstant(index, ints, count);\r
-}\r
-\r
-bool COpenGL3MaterialRenderer::setVertexShaderConstant(s32 index, const u32* ints, int count)\r
-{\r
-       return setPixelShaderConstant(index, ints, count);\r
-}\r
-\r
-bool COpenGL3MaterialRenderer::setPixelShaderConstant(s32 index, const f32* floats, int count)\r
-{\r
-       if(index < 0 || UniformInfo[index].location < 0)\r
-               return false;\r
-\r
-       bool status = true;\r
-\r
-       switch (UniformInfo[index].type)\r
-       {\r
-               case GL_FLOAT:\r
-                       glUniform1fv(UniformInfo[index].location, count, floats);\r
-                       break;\r
-               case GL_FLOAT_VEC2:\r
-                       glUniform2fv(UniformInfo[index].location, count/2, floats);\r
-                       break;\r
-               case GL_FLOAT_VEC3:\r
-                       glUniform3fv(UniformInfo[index].location, count/3, floats);\r
-                       break;\r
-               case GL_FLOAT_VEC4:\r
-                       glUniform4fv(UniformInfo[index].location, count/4, floats);\r
-                       break;\r
-               case GL_FLOAT_MAT2:\r
-                       glUniformMatrix2fv(UniformInfo[index].location, count/4, false, floats);\r
-                       break;\r
-               case GL_FLOAT_MAT3:\r
-                       glUniformMatrix3fv(UniformInfo[index].location, count/9, false, floats);\r
-                       break;\r
-               case GL_FLOAT_MAT4:\r
-                       glUniformMatrix4fv(UniformInfo[index].location, count/16, false, floats);\r
-                       break;\r
-               case GL_SAMPLER_2D:\r
-               case GL_SAMPLER_CUBE:\r
-                       {\r
-                               if(floats)\r
-                               {\r
-                                       const GLint id = (GLint)(*floats);\r
-                                       glUniform1iv(UniformInfo[index].location, 1, &id);\r
-                               }\r
-                               else\r
-                                       status = false;\r
-                       }\r
-                       break;\r
-               default:\r
-                       status = false;\r
-                       break;\r
-       }\r
-\r
-       return status;\r
-}\r
-\r
-bool COpenGL3MaterialRenderer::setPixelShaderConstant(s32 index, const s32* ints, int count)\r
-{\r
-       if(index < 0 || UniformInfo[index].location < 0)\r
-               return false;\r
-\r
-       bool status = true;\r
-\r
-       switch (UniformInfo[index].type)\r
-       {\r
-               case GL_INT:\r
-               case GL_BOOL:\r
-                       glUniform1iv(UniformInfo[index].location, count, ints);\r
-                       break;\r
-               case GL_INT_VEC2:\r
-               case GL_BOOL_VEC2:\r
-                       glUniform2iv(UniformInfo[index].location, count/2, ints);\r
-                       break;\r
-               case GL_INT_VEC3:\r
-               case GL_BOOL_VEC3:\r
-                       glUniform3iv(UniformInfo[index].location, count/3, ints);\r
-                       break;\r
-               case GL_INT_VEC4:\r
-               case GL_BOOL_VEC4:\r
-                       glUniform4iv(UniformInfo[index].location, count/4, ints);\r
-                       break;\r
-               case GL_SAMPLER_2D:\r
-               case GL_SAMPLER_CUBE:\r
-                       glUniform1iv(UniformInfo[index].location, 1, ints);\r
-                       break;\r
-               default:\r
-                       status = false;\r
-                       break;\r
-       }\r
-\r
-       return status;\r
-}\r
-\r
-bool COpenGL3MaterialRenderer::setPixelShaderConstant(s32 index, const u32* ints, int count)\r
-{\r
-       os::Printer::log("Unsigned int support needs at least GLES 3.0", ELL_WARNING);\r
-       return false;\r
-}\r
-\r
-IVideoDriver* COpenGL3MaterialRenderer::getVideoDriver()\r
-{\r
-       return Driver;\r
-}\r
-\r
-}\r
-}\r
+// Copyright (C) 2014 Patryk Nadrowski
+// This file is part of the "Irrlicht Engine".
+// For conditions of distribution and use, see copyright notice in irrlicht.h
+
+#include "MaterialRenderer.h"
+
+#include "EVertexAttributes.h"
+#include "IGPUProgrammingServices.h"
+#include "IShaderConstantSetCallBack.h"
+#include "IVideoDriver.h"
+#include "os.h"
+
+#include "Driver.h"
+
+#include "COpenGLCoreTexture.h"
+#include "COpenGLCoreCacheHandler.h"
+
+namespace irr
+{
+namespace video
+{
+
+
+COpenGL3MaterialRenderer::COpenGL3MaterialRenderer(COpenGL3DriverBase* driver,
+               s32& outMaterialTypeNr,
+               const c8* vertexShaderProgram,
+               const c8* pixelShaderProgram,
+               IShaderConstantSetCallBack* callback,
+               E_MATERIAL_TYPE baseMaterial,
+               s32 userData)
+       : Driver(driver), CallBack(callback), Alpha(false), Blending(false), FixedBlending(false), Program(0), UserData(userData)
+{
+#ifdef _DEBUG
+       setDebugName("MaterialRenderer");
+#endif
+
+       switch (baseMaterial)
+       {
+       case EMT_TRANSPARENT_VERTEX_ALPHA:
+       case EMT_TRANSPARENT_ALPHA_CHANNEL:
+               Alpha = true;
+               break;
+       case EMT_TRANSPARENT_ADD_COLOR:
+               FixedBlending = true;
+               break;
+       case EMT_ONETEXTURE_BLEND:
+               Blending = true;
+               break;
+       default:
+               break;
+       }
+
+       if (CallBack)
+               CallBack->grab();
+
+       init(outMaterialTypeNr, vertexShaderProgram, pixelShaderProgram);
+}
+
+
+COpenGL3MaterialRenderer::COpenGL3MaterialRenderer(COpenGL3DriverBase* driver,
+                                       IShaderConstantSetCallBack* callback,
+                                       E_MATERIAL_TYPE baseMaterial, s32 userData)
+: Driver(driver), CallBack(callback), Alpha(false), Blending(false), FixedBlending(false), Program(0), UserData(userData)
+{
+       switch (baseMaterial)
+       {
+       case EMT_TRANSPARENT_VERTEX_ALPHA:
+       case EMT_TRANSPARENT_ALPHA_CHANNEL:
+               Alpha = true;
+               break;
+       case EMT_TRANSPARENT_ADD_COLOR:
+               FixedBlending = true;
+               break;
+       case EMT_ONETEXTURE_BLEND:
+               Blending = true;
+               break;
+       default:
+               break;
+       }
+
+       if (CallBack)
+               CallBack->grab();
+}
+
+
+COpenGL3MaterialRenderer::~COpenGL3MaterialRenderer()
+{
+       if (CallBack)
+               CallBack->drop();
+
+       if (Program)
+       {
+               GLuint shaders[8];
+               GLint count;
+               glGetAttachedShaders(Program, 8, &count, shaders);
+
+               count=core::min_(count,8);
+               for (GLint i=0; i<count; ++i)
+                       glDeleteShader(shaders[i]);
+               glDeleteProgram(Program);
+               Program = 0;
+       }
+
+       UniformInfo.clear();
+}
+
+GLuint COpenGL3MaterialRenderer::getProgram() const
+{
+       return Program;
+}
+
+void COpenGL3MaterialRenderer::init(s32& outMaterialTypeNr,
+               const c8* vertexShaderProgram,
+               const c8* pixelShaderProgram,
+               bool addMaterial)
+{
+       outMaterialTypeNr = -1;
+
+       Program = glCreateProgram();
+
+       if (!Program)
+               return;
+
+       if (vertexShaderProgram)
+               if (!createShader(GL_VERTEX_SHADER, vertexShaderProgram))
+                       return;
+
+       if (pixelShaderProgram)
+               if (!createShader(GL_FRAGMENT_SHADER, pixelShaderProgram))
+                       return;
+
+       for ( size_t i = 0; i < EVA_COUNT; ++i )
+                       glBindAttribLocation( Program, i, sBuiltInVertexAttributeNames[i]);
+
+       if (!linkProgram())
+               return;
+
+       if (addMaterial)
+               outMaterialTypeNr = Driver->addMaterialRenderer(this);
+}
+
+
+bool COpenGL3MaterialRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype)
+{
+       if (CallBack && Program)
+               CallBack->OnSetConstants(this, UserData);
+
+       return true;
+}
+
+
+void COpenGL3MaterialRenderer::OnSetMaterial(const video::SMaterial& material,
+                               const video::SMaterial& lastMaterial,
+                               bool resetAllRenderstates,
+                               video::IMaterialRendererServices* services)
+{
+       COpenGL3CacheHandler* cacheHandler = Driver->getCacheHandler();
+
+       cacheHandler->setProgram(Program);
+
+       Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
+
+       if (Alpha)
+       {
+               cacheHandler->setBlend(true);
+               cacheHandler->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+       }
+       else if (FixedBlending)
+       {
+               cacheHandler->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
+               cacheHandler->setBlend(true);
+       }
+       else if (Blending)
+       {
+               E_BLEND_FACTOR srcRGBFact,dstRGBFact,srcAlphaFact,dstAlphaFact;
+               E_MODULATE_FUNC modulate;
+               u32 alphaSource;
+               unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulate, alphaSource, material.MaterialTypeParam);
+
+               cacheHandler->setBlendFuncSeparate(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact),
+                       Driver->getGLBlend(srcAlphaFact), Driver->getGLBlend(dstAlphaFact));
+
+               cacheHandler->setBlend(true);
+       }
+
+       if (CallBack)
+               CallBack->OnSetMaterial(material);
+}
+
+
+void COpenGL3MaterialRenderer::OnUnsetMaterial()
+{
+}
+
+
+bool COpenGL3MaterialRenderer::isTransparent() const
+{
+       return (Alpha || Blending || FixedBlending);
+}
+
+
+s32 COpenGL3MaterialRenderer::getRenderCapability() const
+{
+       return 0;
+}
+
+
+bool COpenGL3MaterialRenderer::createShader(GLenum shaderType, const char* shader)
+{
+       if (Program)
+       {
+               GLuint shaderHandle = glCreateShader(shaderType);
+               glShaderSource(shaderHandle, 1, &shader, NULL);
+               glCompileShader(shaderHandle);
+
+               GLint status = 0;
+
+               glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &status);
+
+               if (status != GL_TRUE)
+               {
+                       os::Printer::log("GLSL shader failed to compile", ELL_ERROR);
+
+                       GLint maxLength=0;
+                       GLint length;
+
+                       glGetShaderiv(shaderHandle, GL_INFO_LOG_LENGTH,
+                                       &maxLength);
+
+                       if (maxLength)
+                       {
+                               GLchar *infoLog = new GLchar[maxLength];
+                               glGetShaderInfoLog(shaderHandle, maxLength, &length, infoLog);
+                               os::Printer::log(reinterpret_cast<const c8*>(infoLog), ELL_ERROR);
+                               delete [] infoLog;
+                       }
+
+                       return false;
+               }
+
+               glAttachShader(Program, shaderHandle);
+       }
+
+       return true;
+}
+
+
+bool COpenGL3MaterialRenderer::linkProgram()
+{
+       if (Program)
+       {
+               glLinkProgram(Program);
+
+               GLint status = 0;
+
+               glGetProgramiv(Program, GL_LINK_STATUS, &status);
+
+               if (!status)
+               {
+                       os::Printer::log("GLSL shader program failed to link", ELL_ERROR);
+
+                       GLint maxLength=0;
+                       GLsizei length;
+
+                       glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &maxLength);
+
+                       if (maxLength)
+                       {
+                               GLchar *infoLog = new GLchar[maxLength];
+                               glGetProgramInfoLog(Program, maxLength, &length, infoLog);
+                               os::Printer::log(reinterpret_cast<const c8*>(infoLog), ELL_ERROR);
+                               delete [] infoLog;
+                       }
+
+                       return false;
+               }
+
+               GLint num = 0;
+
+               glGetProgramiv(Program, GL_ACTIVE_UNIFORMS, &num);
+
+               if (num == 0)
+                       return true;
+
+               GLint maxlen = 0;
+
+               glGetProgramiv(Program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxlen);
+
+               if (maxlen == 0)
+               {
+                       os::Printer::log("GLSL: failed to retrieve uniform information", ELL_ERROR);
+                       return false;
+               }
+
+               // seems that some implementations use an extra null terminator.
+               ++maxlen;
+               c8 *buf = new c8[maxlen];
+
+               UniformInfo.clear();
+               UniformInfo.reallocate(num);
+
+               for (GLint i=0; i < num; ++i)
+               {
+                       SUniformInfo ui;
+                       memset(buf, 0, maxlen);
+
+                       GLint size;
+                       glGetActiveUniform(Program, i, maxlen, 0, &size, &ui.type, reinterpret_cast<GLchar*>(buf));
+
+            core::stringc name = "";
+
+                       // array support, workaround for some bugged drivers.
+                       for (s32 i = 0; i < maxlen; ++i)
+                       {
+                               if (buf[i] == '[' || buf[i] == '\0')
+                                       break;
+
+                name += buf[i];
+                       }
+
+                       ui.name = name;
+                       ui.location = glGetUniformLocation(Program, buf);
+
+                       UniformInfo.push_back(ui);
+               }
+
+               delete [] buf;
+       }
+
+       return true;
+}
+
+
+void COpenGL3MaterialRenderer::setBasicRenderStates(const SMaterial& material,
+                                               const SMaterial& lastMaterial,
+                                               bool resetAllRenderstates)
+{
+       Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
+}
+
+s32 COpenGL3MaterialRenderer::getVertexShaderConstantID(const c8* name)
+{
+       return getPixelShaderConstantID(name);
+}
+
+s32 COpenGL3MaterialRenderer::getPixelShaderConstantID(const c8* name)
+{
+       for (u32 i = 0; i < UniformInfo.size(); ++i)
+       {
+               if (UniformInfo[i].name == name)
+                       return i;
+       }
+
+       return -1;
+}
+
+void COpenGL3MaterialRenderer::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)
+{
+       os::Printer::log("Cannot set constant, please use high level shader call instead.", ELL_WARNING);
+}
+
+void COpenGL3MaterialRenderer::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)
+{
+       os::Printer::log("Cannot set constant, use high level shader call.", ELL_WARNING);
+}
+
+bool COpenGL3MaterialRenderer::setVertexShaderConstant(s32 index, const f32* floats, int count)
+{
+       return setPixelShaderConstant(index, floats, count);
+}
+
+bool COpenGL3MaterialRenderer::setVertexShaderConstant(s32 index, const s32* ints, int count)
+{
+       return setPixelShaderConstant(index, ints, count);
+}
+
+bool COpenGL3MaterialRenderer::setVertexShaderConstant(s32 index, const u32* ints, int count)
+{
+       return setPixelShaderConstant(index, ints, count);
+}
+
+bool COpenGL3MaterialRenderer::setPixelShaderConstant(s32 index, const f32* floats, int count)
+{
+       if(index < 0 || UniformInfo[index].location < 0)
+               return false;
+
+       bool status = true;
+
+       switch (UniformInfo[index].type)
+       {
+               case GL_FLOAT:
+                       glUniform1fv(UniformInfo[index].location, count, floats);
+                       break;
+               case GL_FLOAT_VEC2:
+                       glUniform2fv(UniformInfo[index].location, count/2, floats);
+                       break;
+               case GL_FLOAT_VEC3:
+                       glUniform3fv(UniformInfo[index].location, count/3, floats);
+                       break;
+               case GL_FLOAT_VEC4:
+                       glUniform4fv(UniformInfo[index].location, count/4, floats);
+                       break;
+               case GL_FLOAT_MAT2:
+                       glUniformMatrix2fv(UniformInfo[index].location, count/4, false, floats);
+                       break;
+               case GL_FLOAT_MAT3:
+                       glUniformMatrix3fv(UniformInfo[index].location, count/9, false, floats);
+                       break;
+               case GL_FLOAT_MAT4:
+                       glUniformMatrix4fv(UniformInfo[index].location, count/16, false, floats);
+                       break;
+               case GL_SAMPLER_2D:
+               case GL_SAMPLER_CUBE:
+                       {
+                               if(floats)
+                               {
+                                       const GLint id = (GLint)(*floats);
+                                       glUniform1iv(UniformInfo[index].location, 1, &id);
+                               }
+                               else
+                                       status = false;
+                       }
+                       break;
+               default:
+                       status = false;
+                       break;
+       }
+
+       return status;
+}
+
+bool COpenGL3MaterialRenderer::setPixelShaderConstant(s32 index, const s32* ints, int count)
+{
+       if(index < 0 || UniformInfo[index].location < 0)
+               return false;
+
+       bool status = true;
+
+       switch (UniformInfo[index].type)
+       {
+               case GL_INT:
+               case GL_BOOL:
+                       glUniform1iv(UniformInfo[index].location, count, ints);
+                       break;
+               case GL_INT_VEC2:
+               case GL_BOOL_VEC2:
+                       glUniform2iv(UniformInfo[index].location, count/2, ints);
+                       break;
+               case GL_INT_VEC3:
+               case GL_BOOL_VEC3:
+                       glUniform3iv(UniformInfo[index].location, count/3, ints);
+                       break;
+               case GL_INT_VEC4:
+               case GL_BOOL_VEC4:
+                       glUniform4iv(UniformInfo[index].location, count/4, ints);
+                       break;
+               case GL_SAMPLER_2D:
+               case GL_SAMPLER_CUBE:
+                       glUniform1iv(UniformInfo[index].location, 1, ints);
+                       break;
+               default:
+                       status = false;
+                       break;
+       }
+
+       return status;
+}
+
+bool COpenGL3MaterialRenderer::setPixelShaderConstant(s32 index, const u32* ints, int count)
+{
+       os::Printer::log("Unsigned int support needs at least GLES 3.0", ELL_WARNING);
+       return false;
+}
+
+IVideoDriver* COpenGL3MaterialRenderer::getVideoDriver()
+{
+       return Driver;
+}
+
+}
+}