Просмотр исходного кода

WIP: Refactoring OpenGL RAPI in order to support (more restrictive) 4.1 and ES versions
- Added manual error checking for when KHR_debug extension isn't available

BearishSun 8 лет назад
Родитель
Сommit
a3d4e699aa
35 измененных файлов с 547 добавлено и 196 удалено
  1. 3 4
      Source/BansheeCore/Image/BsTexture.cpp
  2. 16 5
      Source/BansheeGLRenderAPI/BsGLBuffer.cpp
  3. 1 1
      Source/BansheeGLRenderAPI/BsGLContext.h
  4. 7 0
      Source/BansheeGLRenderAPI/BsGLEventQuery.cpp
  5. 10 0
      Source/BansheeGLRenderAPI/BsGLFrameBufferObject.cpp
  6. 6 0
      Source/BansheeGLRenderAPI/BsGLGpuBuffer.cpp
  7. 19 2
      Source/BansheeGLRenderAPI/BsGLGpuParamBlockBuffer.cpp
  8. 24 24
      Source/BansheeGLRenderAPI/BsGLHardwareBufferManager.cpp
  9. 7 7
      Source/BansheeGLRenderAPI/BsGLHardwareBufferManager.h
  10. 9 0
      Source/BansheeGLRenderAPI/BsGLOcclusionQuery.cpp
  11. 110 21
      Source/BansheeGLRenderAPI/BsGLPixelBuffer.cpp
  12. 20 20
      Source/BansheeGLRenderAPI/BsGLPixelBuffer.h
  13. 1 1
      Source/BansheeGLRenderAPI/BsGLPixelFormat.h
  14. 31 8
      Source/BansheeGLRenderAPI/BsGLPrerequisites.h
  15. 1 4
      Source/BansheeGLRenderAPI/BsGLRenderAPI.h
  16. 80 15
      Source/BansheeGLRenderAPI/BsGLRenderTexture.cpp
  17. 2 1
      Source/BansheeGLRenderAPI/BsGLSupport.cpp
  18. 29 0
      Source/BansheeGLRenderAPI/BsGLTexture.cpp
  19. 4 4
      Source/BansheeGLRenderAPI/BsGLTexture.h
  20. 9 9
      Source/BansheeGLRenderAPI/BsGLTextureManager.cpp
  21. 6 6
      Source/BansheeGLRenderAPI/BsGLTextureManager.h
  22. 13 2
      Source/BansheeGLRenderAPI/BsGLTextureView.cpp
  23. 8 0
      Source/BansheeGLRenderAPI/BsGLTimerQuery.cpp
  24. 13 2
      Source/BansheeGLRenderAPI/BsGLVertexArrayObjectManager.cpp
  25. 3 3
      Source/BansheeGLRenderAPI/GLSL/BsGLSLGpuProgram.h
  26. 32 0
      Source/BansheeGLRenderAPI/GLSL/BsGLSLParamParser.cpp
  27. 7 7
      Source/BansheeGLRenderAPI/GLSL/BsGLSLProgramFactory.cpp
  28. 4 4
      Source/BansheeGLRenderAPI/GLSL/BsGLSLProgramFactory.h
  29. 8 0
      Source/BansheeGLRenderAPI/GLSL/BsGLSLProgramPipelineManager.cpp
  30. 7 3
      Source/BansheeGLRenderAPI/Win32/BsWin32Context.cpp
  31. 3 3
      Source/BansheeGLRenderAPI/Win32/BsWin32Context.h
  32. 39 31
      Source/BansheeGLRenderAPI/Win32/BsWin32GLSupport.cpp
  33. 7 7
      Source/BansheeGLRenderAPI/Win32/BsWin32GLSupport.h
  34. 2 2
      Source/BansheeGLRenderAPI/Win32/BsWin32Prerequisites.h
  35. 6 0
      Source/BansheeGLRenderAPI/Win32/BsWin32RenderWindow.cpp

+ 3 - 4
Source/BansheeCore/Image/BsTexture.cpp

@@ -72,9 +72,9 @@ namespace bs
 
 
 	Texture::Texture(const TEXTURE_DESC& desc)
 	Texture::Texture(const TEXTURE_DESC& desc)
 		:mProperties(desc)
 		:mProperties(desc)
-    {
-        
-    }
+	{
+		
+	}
 
 
 	Texture::Texture(const TEXTURE_DESC& desc, const SPtr<PixelData>& pixelData)
 	Texture::Texture(const TEXTURE_DESC& desc, const SPtr<PixelData>& pixelData)
 		: mProperties(desc), mInitData(pixelData)
 		: mProperties(desc), mInitData(pixelData)
@@ -497,7 +497,6 @@ namespace bs
 		auto iterFind = mTextureViews.find(key);
 		auto iterFind = mTextureViews.find(key);
 		if (iterFind == mTextureViews.end())
 		if (iterFind == mTextureViews.end())
 		{
 		{
-			SPtr<TextureView> newView = 
 			mTextureViews[key] = createView(key);
 			mTextureViews[key] = createView(key);
 
 
 			iterFind = mTextureViews.find(key);
 			iterFind = mTextureViews.find(key);

+ 16 - 5
Source/BansheeGLRenderAPI/BsGLBuffer.cpp

@@ -20,8 +20,11 @@ namespace bs { namespace ct
 
 
 	GLBuffer::~GLBuffer()
 	GLBuffer::~GLBuffer()
 	{
 	{
-		if(mBufferId != 0)
+		if (mBufferId != 0)
+		{
 			glDeleteBuffers(1, &mBufferId);
 			glDeleteBuffers(1, &mBufferId);
+			BS_CHECK_GL_ERROR();
+		}
 	}
 	}
 
 
 	void GLBuffer::initialize(GLenum target, UINT32 size, GpuBufferUsage usage)
 	void GLBuffer::initialize(GLenum target, UINT32 size, GpuBufferUsage usage)
@@ -31,14 +34,16 @@ namespace bs { namespace ct
 		mTarget = target;
 		mTarget = target;
 
 
 		glGenBuffers(1, &mBufferId);
 		glGenBuffers(1, &mBufferId);
+		BS_CHECK_GL_ERROR();
 
 
 		if (!mBufferId)
 		if (!mBufferId)
-		{
 			BS_EXCEPT(InternalErrorException, "Cannot create GL vertex buffer");
 			BS_EXCEPT(InternalErrorException, "Cannot create GL vertex buffer");
-		}
 
 
 		glBindBuffer(target, mBufferId);
 		glBindBuffer(target, mBufferId);
+		BS_CHECK_GL_ERROR();
+
 		glBufferData(target, size, nullptr, GLHardwareBufferManager::getGLUsage(usage));
 		glBufferData(target, size, nullptr, GLHardwareBufferManager::getGLUsage(usage));
+		BS_CHECK_GL_ERROR();
 	}
 	}
 
 
 	void* GLBuffer::lock(UINT32 offset, UINT32 length, GpuLockOptions options)
 	void* GLBuffer::lock(UINT32 offset, UINT32 length, GpuLockOptions options)
@@ -46,6 +51,7 @@ namespace bs { namespace ct
 		GLenum access = 0;
 		GLenum access = 0;
 
 
 		glBindBuffer(mTarget, mBufferId);
 		glBindBuffer(mTarget, mBufferId);
+		BS_CHECK_GL_ERROR();
 
 
 		if ((options == GBL_WRITE_ONLY) || (options == GBL_WRITE_ONLY_NO_OVERWRITE) || (options == GBL_WRITE_ONLY_DISCARD))
 		if ((options == GBL_WRITE_ONLY) || (options == GBL_WRITE_ONLY_NO_OVERWRITE) || (options == GBL_WRITE_ONLY_DISCARD))
 		{
 		{
@@ -66,11 +72,10 @@ namespace bs { namespace ct
 		if (length > 0)
 		if (length > 0)
 		{
 		{
 			buffer = glMapBufferRange(mTarget, offset, length, access);
 			buffer = glMapBufferRange(mTarget, offset, length, access);
+			BS_CHECK_GL_ERROR();
 
 
 			if (buffer == nullptr)
 			if (buffer == nullptr)
-			{
 				BS_EXCEPT(InternalErrorException, "Cannot map OpenGL buffer.");
 				BS_EXCEPT(InternalErrorException, "Cannot map OpenGL buffer.");
-			}
 
 
 			mZeroLocked = false;
 			mZeroLocked = false;
 		}
 		}
@@ -83,11 +88,13 @@ namespace bs { namespace ct
 	void GLBuffer::unlock()
 	void GLBuffer::unlock()
 	{
 	{
 		glBindBuffer(mTarget, mBufferId);
 		glBindBuffer(mTarget, mBufferId);
+		BS_CHECK_GL_ERROR();
 
 
 		if (!mZeroLocked)
 		if (!mZeroLocked)
 		{
 		{
 			if (!glUnmapBuffer(mTarget))
 			if (!glUnmapBuffer(mTarget))
 			{
 			{
+				BS_CHECK_GL_ERROR();
 				BS_EXCEPT(InternalErrorException, "Buffer data corrupted, please reload.");
 				BS_EXCEPT(InternalErrorException, "Buffer data corrupted, please reload.");
 			}
 			}
 		}
 		}
@@ -117,8 +124,12 @@ namespace bs { namespace ct
 	void GLBuffer::copyData(GLBuffer& dstBuffer, UINT32 srcOffset, UINT32 dstOffset, UINT32 length)
 	void GLBuffer::copyData(GLBuffer& dstBuffer, UINT32 srcOffset, UINT32 dstOffset, UINT32 length)
 	{
 	{
 		glBindBuffer(GL_COPY_READ_BUFFER, getGLBufferId());
 		glBindBuffer(GL_COPY_READ_BUFFER, getGLBufferId());
+		BS_CHECK_GL_ERROR();
+
 		glBindBuffer(GL_COPY_WRITE_BUFFER, dstBuffer.getGLBufferId());
 		glBindBuffer(GL_COPY_WRITE_BUFFER, dstBuffer.getGLBufferId());
+		BS_CHECK_GL_ERROR();
 
 
 		glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, srcOffset, dstOffset, length);
 		glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, srcOffset, dstOffset, length);
+		BS_CHECK_GL_ERROR();
 	}
 	}
 }}
 }}

+ 1 - 1
Source/BansheeGLRenderAPI/BsGLContext.h

@@ -20,7 +20,7 @@ namespace bs { namespace ct
 		virtual ~GLContext();
 		virtual ~GLContext();
 
 
 		/**	Activates the rendering context (all subsequent rendering commands will be executed on it). */
 		/**	Activates the rendering context (all subsequent rendering commands will be executed on it). */
-        virtual void setCurrent(const RenderWindow& window) = 0;
+		virtual void setCurrent(const RenderWindow& window) = 0;
 
 
 		/**	Deactivates the rendering context. Normally called just before setCurrent is called on another context. */
 		/**	Deactivates the rendering context. Normally called just before setCurrent is called on another context. */
 		virtual void endCurrent() = 0;
 		virtual void endCurrent() = 0;

+ 7 - 0
Source/BansheeGLRenderAPI/BsGLEventQuery.cpp

@@ -12,12 +12,16 @@ namespace bs { namespace ct
 		assert(deviceIdx == 0 && "Multiple GPUs not supported natively on OpenGL.");
 		assert(deviceIdx == 0 && "Multiple GPUs not supported natively on OpenGL.");
 
 
 		glGenQueries(1, &mQueryObj);
 		glGenQueries(1, &mQueryObj);
+		BS_CHECK_GL_ERROR();
+
 		BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_Query);
 		BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_Query);
 	}
 	}
 
 
 	GLEventQuery::~GLEventQuery()
 	GLEventQuery::~GLEventQuery()
 	{
 	{
 		glDeleteQueries(1, &mQueryObj);
 		glDeleteQueries(1, &mQueryObj);
+		BS_CHECK_GL_ERROR();
+
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Query);
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Query);
 	}
 	}
 
 
@@ -26,6 +30,8 @@ namespace bs { namespace ct
 		auto execute = [&]()
 		auto execute = [&]()
 		{
 		{
 			glQueryCounter(mQueryObj, GL_TIMESTAMP);
 			glQueryCounter(mQueryObj, GL_TIMESTAMP);
+			BS_CHECK_GL_ERROR();
+
 			setActive(true);
 			setActive(true);
 		};
 		};
 
 
@@ -42,6 +48,7 @@ namespace bs { namespace ct
 	{
 	{
 		GLint done = 0;
 		GLint done = 0;
 		glGetQueryObjectiv(mQueryObj, GL_QUERY_RESULT_AVAILABLE, &done);
 		glGetQueryObjectiv(mQueryObj, GL_QUERY_RESULT_AVAILABLE, &done);
+		BS_CHECK_GL_ERROR();
 
 
 		return done == GL_TRUE;
 		return done == GL_TRUE;
 	}
 	}

+ 10 - 0
Source/BansheeGLRenderAPI/BsGLFrameBufferObject.cpp

@@ -12,6 +12,7 @@ namespace bs { namespace ct
 		: mDepthStencilAllLayers(false)
 		: mDepthStencilAllLayers(false)
 	{
 	{
 		glGenFramebuffers(1, &mFB);
 		glGenFramebuffers(1, &mFB);
+		BS_CHECK_GL_ERROR();
 
 
 		for (UINT32 x = 0; x < BS_MAX_MULTIPLE_RENDER_TARGETS; ++x)
 		for (UINT32 x = 0; x < BS_MAX_MULTIPLE_RENDER_TARGETS; ++x)
 			mColor[x].buffer = nullptr;
 			mColor[x].buffer = nullptr;
@@ -22,6 +23,8 @@ namespace bs { namespace ct
 	GLFrameBufferObject::~GLFrameBufferObject()
 	GLFrameBufferObject::~GLFrameBufferObject()
 	{
 	{
 		glDeleteFramebuffers(1, &mFB);
 		glDeleteFramebuffers(1, &mFB);
+		BS_CHECK_GL_ERROR();
+
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_FrameBufferObject);
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_FrameBufferObject);
 	}
 	}
 
 
@@ -55,6 +58,7 @@ namespace bs { namespace ct
 
 
 		// Bind simple buffer to add color attachments
 		// Bind simple buffer to add color attachments
 		glBindFramebuffer(GL_FRAMEBUFFER, mFB);
 		glBindFramebuffer(GL_FRAMEBUFFER, mFB);
+		BS_CHECK_GL_ERROR();
 
 
 		// Bind all attachment points to frame buffer
 		// Bind all attachment points to frame buffer
 		for (UINT16 x = 0; x < maxSupportedMRTs; ++x)
 		for (UINT16 x = 0; x < maxSupportedMRTs; ++x)
@@ -70,6 +74,7 @@ namespace bs { namespace ct
 			{
 			{
 				// Detach
 				// Detach
 				glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + x, 0, 0);
 				glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + x, 0, 0);
+				BS_CHECK_GL_ERROR();
 			}
 			}
 		}
 		}
 
 
@@ -105,16 +110,20 @@ namespace bs { namespace ct
 		}
 		}
 
 
 		glDrawBuffers(n, bufs);
 		glDrawBuffers(n, bufs);
+		BS_CHECK_GL_ERROR();
 
 
 		// No read buffer, by default, if we want to read anyway we must not forget to set this.
 		// No read buffer, by default, if we want to read anyway we must not forget to set this.
 		glReadBuffer(GL_NONE);
 		glReadBuffer(GL_NONE);
+		BS_CHECK_GL_ERROR();
 
 
 		// Check status
 		// Check status
 		GLuint status;
 		GLuint status;
 		status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
 		status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+		BS_CHECK_GL_ERROR();
 
 
 		// Bind main buffer
 		// Bind main buffer
 		glBindFramebuffer(GL_FRAMEBUFFER, 0);
 		glBindFramebuffer(GL_FRAMEBUFFER, 0);
+		BS_CHECK_GL_ERROR();
 
 
 		switch (status)
 		switch (status)
 		{
 		{
@@ -131,5 +140,6 @@ namespace bs { namespace ct
 	void GLFrameBufferObject::bind()
 	void GLFrameBufferObject::bind()
 	{
 	{
 		glBindFramebuffer(GL_FRAMEBUFFER, mFB);
 		glBindFramebuffer(GL_FRAMEBUFFER, mFB);
+		BS_CHECK_GL_ERROR();
 	}
 	}
 }}
 }}

+ 6 - 0
Source/BansheeGLRenderAPI/BsGLGpuBuffer.cpp

@@ -29,6 +29,7 @@ namespace bs { namespace ct
 	GLGpuBuffer::~GLGpuBuffer()
 	GLGpuBuffer::~GLGpuBuffer()
 	{
 	{
 		glDeleteTextures(1, &mTextureID);
 		glDeleteTextures(1, &mTextureID);
+		BS_CHECK_GL_ERROR();
 
 
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_GpuBuffer);
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_GpuBuffer);
 	}
 	}
@@ -50,8 +51,13 @@ namespace bs { namespace ct
 
 
 			// Create texture
 			// Create texture
 			glGenTextures(1, &mTextureID);
 			glGenTextures(1, &mTextureID);
+			BS_CHECK_GL_ERROR();
+
 			glBindTexture(GL_TEXTURE_BUFFER, mTextureID);
 			glBindTexture(GL_TEXTURE_BUFFER, mTextureID);
+			BS_CHECK_GL_ERROR();
+
 			glTexBuffer(GL_TEXTURE_BUFFER, mFormat, mBuffer.getGLBufferId());
 			glTexBuffer(GL_TEXTURE_BUFFER, mFormat, mBuffer.getGLBufferId());
+			BS_CHECK_GL_ERROR();
 		}
 		}
 
 
 		BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_GpuBuffer);
 		BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_GpuBuffer);

+ 19 - 2
Source/BansheeGLRenderAPI/BsGLGpuParamBlockBuffer.cpp

@@ -15,6 +15,7 @@ namespace bs { namespace ct
 	GLGpuParamBlockBuffer::~GLGpuParamBlockBuffer()
 	GLGpuParamBlockBuffer::~GLGpuParamBlockBuffer()
 	{
 	{
 		glDeleteBuffers(1, &mGLHandle);
 		glDeleteBuffers(1, &mGLHandle);
+		BS_CHECK_GL_ERROR();
 
 
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_GpuParamBuffer);
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_GpuParamBuffer);
 	}
 	}
@@ -22,15 +23,26 @@ namespace bs { namespace ct
 	void GLGpuParamBlockBuffer::initialize()
 	void GLGpuParamBlockBuffer::initialize()
 	{
 	{
 		glGenBuffers(1, &mGLHandle);
 		glGenBuffers(1, &mGLHandle);
+		BS_CHECK_GL_ERROR();
+
 		glBindBuffer(GL_UNIFORM_BUFFER, mGLHandle);
 		glBindBuffer(GL_UNIFORM_BUFFER, mGLHandle);
-		if(mUsage == GPBU_STATIC)
+		BS_CHECK_GL_ERROR();
+
+		if (mUsage == GPBU_STATIC)
+		{
 			glBufferData(GL_UNIFORM_BUFFER, mSize, nullptr, GL_STATIC_DRAW);
 			glBufferData(GL_UNIFORM_BUFFER, mSize, nullptr, GL_STATIC_DRAW);
-		else if(mUsage == GPBU_DYNAMIC)
+			BS_CHECK_GL_ERROR();
+		}
+		else if (mUsage == GPBU_DYNAMIC)
+		{
 			glBufferData(GL_UNIFORM_BUFFER, mSize, nullptr, GL_DYNAMIC_DRAW);
 			glBufferData(GL_UNIFORM_BUFFER, mSize, nullptr, GL_DYNAMIC_DRAW);
+			BS_CHECK_GL_ERROR();
+		}
 		else
 		else
 			BS_EXCEPT(InternalErrorException, "Invalid gpu param block usage.");
 			BS_EXCEPT(InternalErrorException, "Invalid gpu param block usage.");
 
 
 		glBindBuffer(GL_UNIFORM_BUFFER, 0);
 		glBindBuffer(GL_UNIFORM_BUFFER, 0);
+		BS_CHECK_GL_ERROR();
 
 
 		BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_GpuParamBuffer);
 		BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_GpuParamBuffer);
 		GpuParamBlockBuffer::initialize();
 		GpuParamBlockBuffer::initialize();
@@ -39,8 +51,13 @@ namespace bs { namespace ct
 	void GLGpuParamBlockBuffer::writeToGPU(const UINT8* data, UINT32 queueIdx)
 	void GLGpuParamBlockBuffer::writeToGPU(const UINT8* data, UINT32 queueIdx)
 	{
 	{
 		glBindBuffer(GL_UNIFORM_BUFFER, mGLHandle);
 		glBindBuffer(GL_UNIFORM_BUFFER, mGLHandle);
+		BS_CHECK_GL_ERROR();
+
 		glBufferSubData(GL_UNIFORM_BUFFER, 0 , mSize, data);
 		glBufferSubData(GL_UNIFORM_BUFFER, 0 , mSize, data);
+		BS_CHECK_GL_ERROR();
+
 		glBindBuffer(GL_UNIFORM_BUFFER, 0);
 		glBindBuffer(GL_UNIFORM_BUFFER, 0);
+		BS_CHECK_GL_ERROR();
 
 
 		BS_INC_RENDER_STAT_CAT(ResWrite, RenderStatObject_GpuParamBuffer);
 		BS_INC_RENDER_STAT_CAT(ResWrite, RenderStatObject_GpuParamBuffer);
 	}
 	}

+ 24 - 24
Source/BansheeGLRenderAPI/BsGLHardwareBufferManager.cpp

@@ -52,30 +52,30 @@ namespace bs { namespace ct
 		return bufferPtr;
 		return bufferPtr;
 	}
 	}
 
 
-    GLenum GLHardwareBufferManager::getGLUsage(GpuBufferUsage usage)
-    {
+	GLenum GLHardwareBufferManager::getGLUsage(GpuBufferUsage usage)
+	{
 		if(usage & GBU_STATIC)
 		if(usage & GBU_STATIC)
 			return GL_STATIC_DRAW;
 			return GL_STATIC_DRAW;
 
 
 		if(usage & GBU_DYNAMIC)
 		if(usage & GBU_DYNAMIC)
 			return GL_DYNAMIC_DRAW;
 			return GL_DYNAMIC_DRAW;
 
 
-        return GL_DYNAMIC_DRAW;
-    }
+		return GL_DYNAMIC_DRAW;
+	}
 
 
-    GLenum GLHardwareBufferManager::getGLType(VertexElementType type)
-    {
-        switch(type)
-        {
-            case VET_FLOAT1:
-            case VET_FLOAT2:
-            case VET_FLOAT3:
-            case VET_FLOAT4:
-                return GL_FLOAT;
-            case VET_SHORT1:
-            case VET_SHORT2:
-            case VET_SHORT4:
-                return GL_SHORT;
+	GLenum GLHardwareBufferManager::getGLType(VertexElementType type)
+	{
+		switch(type)
+		{
+			case VET_FLOAT1:
+			case VET_FLOAT2:
+			case VET_FLOAT3:
+			case VET_FLOAT4:
+				return GL_FLOAT;
+			case VET_SHORT1:
+			case VET_SHORT2:
+			case VET_SHORT4:
+				return GL_SHORT;
 			case VET_USHORT1:
 			case VET_USHORT1:
 			case VET_USHORT2:
 			case VET_USHORT2:
 			case VET_USHORT4:
 			case VET_USHORT4:
@@ -90,14 +90,14 @@ namespace bs { namespace ct
 			case VET_UINT3:
 			case VET_UINT3:
 			case VET_UINT4:
 			case VET_UINT4:
 				return GL_UNSIGNED_INT;
 				return GL_UNSIGNED_INT;
-            case VET_COLOR:
+			case VET_COLOR:
 			case VET_COLOR_ABGR:
 			case VET_COLOR_ABGR:
 			case VET_COLOR_ARGB:
 			case VET_COLOR_ARGB:
-            case VET_UBYTE4:
+			case VET_UBYTE4:
 			case VET_UBYTE4_NORM:
 			case VET_UBYTE4_NORM:
-                return GL_UNSIGNED_BYTE;
-            default:
-                return 0;
-        };
-    }
+				return GL_UNSIGNED_BYTE;
+			default:
+				return 0;
+		};
+	}
 }}
 }}

+ 7 - 7
Source/BansheeGLRenderAPI/BsGLHardwareBufferManager.h

@@ -12,19 +12,19 @@ namespace bs { namespace ct
 	 */
 	 */
 
 
 	/**	Handles creation of OpenGL specific hardware buffers. */
 	/**	Handles creation of OpenGL specific hardware buffers. */
-    class GLHardwareBufferManager : public HardwareBufferManager
-    {
-    public:
+	class GLHardwareBufferManager : public HardwareBufferManager
+	{
+	public:
 		/**	Converts engine buffer usage flags into OpenGL specific flags. */
 		/**	Converts engine buffer usage flags into OpenGL specific flags. */
 		static GLenum getGLUsage(GpuBufferUsage usage);
 		static GLenum getGLUsage(GpuBufferUsage usage);
 
 
 		/**	Converts vertex element type into OpenGL specific type. */
 		/**	Converts vertex element type into OpenGL specific type. */
-        static GLenum getGLType(VertexElementType type);
+		static GLenum getGLType(VertexElementType type);
 
 
 	protected:
 	protected:
 		/** @copydoc HardwareBufferManager::createVertexBufferInternal */
 		/** @copydoc HardwareBufferManager::createVertexBufferInternal */
-        SPtr<VertexBuffer> createVertexBufferInternal(const VERTEX_BUFFER_DESC& desc, 
-        	GpuDeviceFlags deviceMask = GDF_DEFAULT) override;
+		SPtr<VertexBuffer> createVertexBufferInternal(const VERTEX_BUFFER_DESC& desc, 
+			GpuDeviceFlags deviceMask = GDF_DEFAULT) override;
 
 
 		/** @copydoc HardwareBufferManager::createIndexBufferInternal */
 		/** @copydoc HardwareBufferManager::createIndexBufferInternal */
 		SPtr<IndexBuffer> createIndexBufferInternal(const INDEX_BUFFER_DESC& desc, 
 		SPtr<IndexBuffer> createIndexBufferInternal(const INDEX_BUFFER_DESC& desc, 
@@ -37,7 +37,7 @@ namespace bs { namespace ct
 		/** @copydoc HardwareBufferManager::createGpuBufferInternal */
 		/** @copydoc HardwareBufferManager::createGpuBufferInternal */
 		SPtr<GpuBuffer> createGpuBufferInternal(const GPU_BUFFER_DESC& desc, 
 		SPtr<GpuBuffer> createGpuBufferInternal(const GPU_BUFFER_DESC& desc, 
 			GpuDeviceFlags deviceMask = GDF_DEFAULT) override;
 			GpuDeviceFlags deviceMask = GDF_DEFAULT) override;
-    };
+	};
 
 
 	/** @} */
 	/** @} */
 }}
 }}

+ 9 - 0
Source/BansheeGLRenderAPI/BsGLOcclusionQuery.cpp

@@ -13,12 +13,16 @@ namespace bs { namespace ct
 		assert(deviceIdx == 0 && "Multiple GPUs not supported natively on OpenGL.");
 		assert(deviceIdx == 0 && "Multiple GPUs not supported natively on OpenGL.");
 
 
 		glGenQueries(1, &mQueryObj);
 		glGenQueries(1, &mQueryObj);
+		BS_CHECK_GL_ERROR();
+
 		BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_Query);
 		BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_Query);
 	}
 	}
 
 
 	GLOcclusionQuery::~GLOcclusionQuery()
 	GLOcclusionQuery::~GLOcclusionQuery()
 	{
 	{
 		glDeleteQueries(1, &mQueryObj);
 		glDeleteQueries(1, &mQueryObj);
+		BS_CHECK_GL_ERROR();
+
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Query);
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Query);
 	}
 	}
 
 
@@ -27,6 +31,7 @@ namespace bs { namespace ct
 		auto execute = [&]()
 		auto execute = [&]()
 		{
 		{
 			glBeginQuery(mBinary ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED, mQueryObj);
 			glBeginQuery(mBinary ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED, mQueryObj);
+			BS_CHECK_GL_ERROR();
 
 
 			mNumSamples = 0;
 			mNumSamples = 0;
 			mEndIssued = false;
 			mEndIssued = false;
@@ -47,6 +52,7 @@ namespace bs { namespace ct
 		auto execute = [&]()
 		auto execute = [&]()
 		{
 		{
 			glEndQuery(mBinary ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED);
 			glEndQuery(mBinary ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED);
+			BS_CHECK_GL_ERROR();
 
 
 			mEndIssued = true;
 			mEndIssued = true;
 			mFinalized = false;
 			mFinalized = false;
@@ -68,6 +74,7 @@ namespace bs { namespace ct
 
 
 		GLint done = 0;
 		GLint done = 0;
 		glGetQueryObjectiv(mQueryObj, GL_QUERY_RESULT_AVAILABLE, &done);
 		glGetQueryObjectiv(mQueryObj, GL_QUERY_RESULT_AVAILABLE, &done);
+		BS_CHECK_GL_ERROR();
 
 
 		return done == GL_TRUE;
 		return done == GL_TRUE;
 	}
 	}
@@ -90,6 +97,7 @@ namespace bs { namespace ct
 		{
 		{
 			GLboolean anyPassed = GL_FALSE;
 			GLboolean anyPassed = GL_FALSE;
 			glGetQueryObjectuiv(mQueryObj, GL_QUERY_RESULT_ARB, (GLuint*)&anyPassed);
 			glGetQueryObjectuiv(mQueryObj, GL_QUERY_RESULT_ARB, (GLuint*)&anyPassed);
+			BS_CHECK_GL_ERROR();
 
 
 			mNumSamples = anyPassed == GL_TRUE ? 1 : 0;
 			mNumSamples = anyPassed == GL_TRUE ? 1 : 0;
 		}
 		}
@@ -97,6 +105,7 @@ namespace bs { namespace ct
 		{
 		{
 			GLuint numSamples = 0;
 			GLuint numSamples = 0;
 			glGetQueryObjectuiv(mQueryObj, GL_QUERY_RESULT_ARB, (GLuint*)&numSamples);
 			glGetQueryObjectuiv(mQueryObj, GL_QUERY_RESULT_ARB, (GLuint*)&numSamples);
+			BS_CHECK_GL_ERROR();
 
 
 			mNumSamples = (UINT32)numSamples;
 			mNumSamples = (UINT32)numSamples;
 		}
 		}

+ 110 - 21
Source/BansheeGLRenderAPI/BsGLPixelBuffer.cpp

@@ -36,9 +36,7 @@ namespace bs { namespace ct
 	void GLPixelBuffer::freeBuffer()
 	void GLPixelBuffer::freeBuffer()
 	{
 	{
 		if(mUsage & GBU_STATIC)
 		if(mUsage & GBU_STATIC)
-		{
 			mBuffer.freeInternalBuffer();
 			mBuffer.freeInternalBuffer();
-		}
 	}
 	}
 
 
 	void* GLPixelBuffer::lock(UINT32 offset, UINT32 length, GpuLockOptions options)
 	void* GLPixelBuffer::lock(UINT32 offset, UINT32 length, GpuLockOptions options)
@@ -121,6 +119,7 @@ namespace bs { namespace ct
 		GLint value = 0;
 		GLint value = 0;
 	
 	
 		glBindTexture(mTarget, mTextureID);
 		glBindTexture(mTarget, mTextureID);
+		BS_CHECK_GL_ERROR();
 	
 	
 		// Get face identifier
 		// Get face identifier
 		mFaceTarget = mTarget;
 		mFaceTarget = mTarget;
@@ -129,20 +128,30 @@ namespace bs { namespace ct
 	
 	
 		// Get width
 		// Get width
 		glGetTexLevelParameteriv(mFaceTarget, level, GL_TEXTURE_WIDTH, &value);
 		glGetTexLevelParameteriv(mFaceTarget, level, GL_TEXTURE_WIDTH, &value);
+		BS_CHECK_GL_ERROR();
+
 		mWidth = value;
 		mWidth = value;
 	
 	
 		// Get height
 		// Get height
 		if(target == GL_TEXTURE_1D)
 		if(target == GL_TEXTURE_1D)
 			value = 1;	// Height always 1 for 1D textures
 			value = 1;	// Height always 1 for 1D textures
 		else
 		else
+		{
 			glGetTexLevelParameteriv(mFaceTarget, level, GL_TEXTURE_HEIGHT, &value);
 			glGetTexLevelParameteriv(mFaceTarget, level, GL_TEXTURE_HEIGHT, &value);
+			BS_CHECK_GL_ERROR();
+		}
+
 		mHeight = value;
 		mHeight = value;
 	
 	
 		// Get depth
 		// Get depth
 		if(target != GL_TEXTURE_3D)
 		if(target != GL_TEXTURE_3D)
 			value = 1; // Depth always 1 for non-3D textures
 			value = 1; // Depth always 1 for non-3D textures
 		else
 		else
+		{
 			glGetTexLevelParameteriv(mFaceTarget, level, GL_TEXTURE_DEPTH, &value);
 			glGetTexLevelParameteriv(mFaceTarget, level, GL_TEXTURE_DEPTH, &value);
+			BS_CHECK_GL_ERROR();
+		}
+
 		mDepth = value;
 		mDepth = value;
 
 
 		// Default
 		// Default
@@ -169,7 +178,9 @@ namespace bs { namespace ct
 			return;
 			return;
 		}
 		}
 
 
-		glBindTexture( mTarget, mTextureID );
+		glBindTexture(mTarget, mTextureID);
+		BS_CHECK_GL_ERROR();
+
 		if(PixelUtil::isCompressed(data.getFormat()))
 		if(PixelUtil::isCompressed(data.getFormat()))
 		{
 		{
 			if (data.getFormat() != mFormat || !data.isConsecutive())
 			if (data.getFormat() != mFormat || !data.isConsecutive())
@@ -189,6 +200,7 @@ namespace bs { namespace ct
 							0,
 							0,
 							data.getConsecutiveSize(),
 							data.getConsecutiveSize(),
 							data.getData());
 							data.getData());
+						BS_CHECK_GL_ERROR();
 					}
 					}
 					else
 					else
 					{
 					{
@@ -197,6 +209,7 @@ namespace bs { namespace ct
 							dest.getWidth(),
 							dest.getWidth(),
 							format, data.getConsecutiveSize(),
 							format, data.getConsecutiveSize(),
 							data.getData());
 							data.getData());
+						BS_CHECK_GL_ERROR();
 					}
 					}
 					break;
 					break;
 				case GL_TEXTURE_2D:
 				case GL_TEXTURE_2D:
@@ -210,6 +223,7 @@ namespace bs { namespace ct
 							0,
 							0,
 							data.getConsecutiveSize(),
 							data.getConsecutiveSize(),
 							data.getData());
 							data.getData());
+						BS_CHECK_GL_ERROR();
 					}
 					}
 					else
 					else
 					{
 					{
@@ -218,6 +232,7 @@ namespace bs { namespace ct
 							dest.getWidth(), dest.getHeight(),
 							dest.getWidth(), dest.getHeight(),
 							format, data.getConsecutiveSize(),
 							format, data.getConsecutiveSize(),
 							data.getData());
 							data.getData());
+						BS_CHECK_GL_ERROR();
 					}
 					}
 					break;
 					break;
 				case GL_TEXTURE_3D:
 				case GL_TEXTURE_3D:
@@ -231,6 +246,7 @@ namespace bs { namespace ct
 							0,
 							0,
 							data.getConsecutiveSize(),
 							data.getConsecutiveSize(),
 							data.getData());
 							data.getData());
+						BS_CHECK_GL_ERROR();
 					}
 					}
 					else
 					else
 					{			
 					{			
@@ -239,6 +255,7 @@ namespace bs { namespace ct
 							dest.getWidth(), dest.getHeight(), dest.getDepth(),
 							dest.getWidth(), dest.getHeight(), dest.getDepth(),
 							format, data.getConsecutiveSize(),
 							format, data.getConsecutiveSize(),
 							data.getData());
 							data.getData());
+						BS_CHECK_GL_ERROR();
 					}
 					}
 					break;
 					break;
 			}
 			}
@@ -246,17 +263,31 @@ namespace bs { namespace ct
 		} 
 		} 
 		else
 		else
 		{
 		{
-			if(data.getWidth() != data.getRowPitch())
+			if (data.getWidth() != data.getRowPitch())
+			{
 				glPixelStorei(GL_UNPACK_ROW_LENGTH, data.getRowPitch());
 				glPixelStorei(GL_UNPACK_ROW_LENGTH, data.getRowPitch());
+				BS_CHECK_GL_ERROR();
+			}
 
 
-			if(data.getHeight()*data.getWidth() != data.getSlicePitch())
-				glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, (data.getSlicePitch()/data.getWidth()));
+			if (data.getHeight()*data.getWidth() != data.getSlicePitch())
+			{
+				glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, (data.getSlicePitch() / data.getWidth()));
+				BS_CHECK_GL_ERROR();
+			}
 
 
-			if(data.getLeft() > 0 || data.getTop() > 0 || data.getFront() > 0)
-				glPixelStorei(GL_UNPACK_SKIP_PIXELS, data.getLeft() + data.getRowPitch() * data.getTop() + data.getSlicePitch() * data.getFront());
+			if (data.getLeft() > 0 || data.getTop() > 0 || data.getFront() > 0)
+			{
+				glPixelStorei(
+					GL_UNPACK_SKIP_PIXELS, 
+					data.getLeft() + data.getRowPitch() * data.getTop() + data.getSlicePitch() * data.getFront());
+				BS_CHECK_GL_ERROR();
+			}
 
 
-			if((data.getWidth()*PixelUtil::getNumElemBytes(data.getFormat())) & 3)
+			if ((data.getWidth()*PixelUtil::getNumElemBytes(data.getFormat())) & 3)
+			{
 				glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 				glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+				BS_CHECK_GL_ERROR();
+			}
 
 
 			switch(mTarget) {
 			switch(mTarget) {
 				case GL_TEXTURE_1D:
 				case GL_TEXTURE_1D:
@@ -265,6 +296,7 @@ namespace bs { namespace ct
 						dest.getWidth(),
 						dest.getWidth(),
 						GLPixelUtil::getGLOriginFormat(data.getFormat()), GLPixelUtil::getGLOriginDataType(data.getFormat()),
 						GLPixelUtil::getGLOriginFormat(data.getFormat()), GLPixelUtil::getGLOriginDataType(data.getFormat()),
 						data.getData());
 						data.getData());
+					BS_CHECK_GL_ERROR();
 					break;
 					break;
 				case GL_TEXTURE_2D:
 				case GL_TEXTURE_2D:
 				case GL_TEXTURE_CUBE_MAP:
 				case GL_TEXTURE_CUBE_MAP:
@@ -273,6 +305,7 @@ namespace bs { namespace ct
 						dest.getWidth(), dest.getHeight(),
 						dest.getWidth(), dest.getHeight(),
 						GLPixelUtil::getGLOriginFormat(data.getFormat()), GLPixelUtil::getGLOriginDataType(data.getFormat()),
 						GLPixelUtil::getGLOriginFormat(data.getFormat()), GLPixelUtil::getGLOriginDataType(data.getFormat()),
 						data.getData());
 						data.getData());
+					BS_CHECK_GL_ERROR();
 					break;
 					break;
 				case GL_TEXTURE_3D:
 				case GL_TEXTURE_3D:
 					glTexSubImage3D(
 					glTexSubImage3D(
@@ -281,15 +314,23 @@ namespace bs { namespace ct
 						dest.getWidth(), dest.getHeight(), dest.getDepth(),
 						dest.getWidth(), dest.getHeight(), dest.getDepth(),
 						GLPixelUtil::getGLOriginFormat(data.getFormat()), GLPixelUtil::getGLOriginDataType(data.getFormat()),
 						GLPixelUtil::getGLOriginFormat(data.getFormat()), GLPixelUtil::getGLOriginDataType(data.getFormat()),
 						data.getData());
 						data.getData());
+					BS_CHECK_GL_ERROR();
 					break;
 					break;
 			}	
 			}	
 		}
 		}
 
 
 		// Restore defaults
 		// Restore defaults
 		glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
 		glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+		BS_CHECK_GL_ERROR();
+
 		glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
 		glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
+		BS_CHECK_GL_ERROR();
+
 		glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
 		glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+		BS_CHECK_GL_ERROR();
+
 		glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
 		glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+		BS_CHECK_GL_ERROR();
 
 
 		BS_INC_RENDER_STAT_CAT(ResWrite, RenderStatObject_Texture);
 		BS_INC_RENDER_STAT_CAT(ResWrite, RenderStatObject_Texture);
 	}
 	}
@@ -303,6 +344,8 @@ namespace bs { namespace ct
 		}
 		}
 
 
 		glBindTexture(mTarget, mTextureID);
 		glBindTexture(mTarget, mTextureID);
+		BS_CHECK_GL_ERROR();
+
 		if(PixelUtil::isCompressed(data.getFormat()))
 		if(PixelUtil::isCompressed(data.getFormat()))
 		{
 		{
 			if (data.getFormat() != mFormat || !data.isConsecutive())
 			if (data.getFormat() != mFormat || !data.isConsecutive())
@@ -314,30 +357,53 @@ namespace bs { namespace ct
 			// Data must be consecutive and at beginning of buffer as PixelStorei not allowed
 			// Data must be consecutive and at beginning of buffer as PixelStorei not allowed
 			// for compressed formate
 			// for compressed formate
 			glGetCompressedTexImage(mFaceTarget, mLevel, data.getData());
 			glGetCompressedTexImage(mFaceTarget, mLevel, data.getData());
+			BS_CHECK_GL_ERROR();
 		} 
 		} 
 		else
 		else
 		{
 		{
-			if(data.getWidth() != data.getRowPitch())
+			if (data.getWidth() != data.getRowPitch())
+			{
 				glPixelStorei(GL_PACK_ROW_LENGTH, data.getRowPitch());
 				glPixelStorei(GL_PACK_ROW_LENGTH, data.getRowPitch());
+				BS_CHECK_GL_ERROR();
+			}
 
 
-			if(data.getHeight()*data.getWidth() != data.getSlicePitch())
-				glPixelStorei(GL_PACK_IMAGE_HEIGHT, (data.getSlicePitch()/data.getWidth()));
+			if (data.getHeight()*data.getWidth() != data.getSlicePitch())
+			{
+				glPixelStorei(GL_PACK_IMAGE_HEIGHT, (data.getSlicePitch() / data.getWidth()));
+				BS_CHECK_GL_ERROR();
+			}
 
 
-			if(data.getLeft() > 0 || data.getTop() > 0 || data.getFront() > 0)
-				glPixelStorei(GL_PACK_SKIP_PIXELS, data.getLeft() + data.getRowPitch() * data.getTop() + data.getSlicePitch() * data.getFront());
+			if (data.getLeft() > 0 || data.getTop() > 0 || data.getFront() > 0)
+			{
+				glPixelStorei(
+					GL_PACK_SKIP_PIXELS, 
+					data.getLeft() + data.getRowPitch() * data.getTop() + data.getSlicePitch() * data.getFront());
+				BS_CHECK_GL_ERROR();
+			}
 
 
-			if((data.getWidth()*PixelUtil::getNumElemBytes(data.getFormat())) & 3)
+			if ((data.getWidth()*PixelUtil::getNumElemBytes(data.getFormat())) & 3)
+			{
 				glPixelStorei(GL_PACK_ALIGNMENT, 1);
 				glPixelStorei(GL_PACK_ALIGNMENT, 1);
+				BS_CHECK_GL_ERROR();
+			}
 
 
 			// We can only get the entire texture
 			// We can only get the entire texture
 			glGetTexImage(mFaceTarget, mLevel, GLPixelUtil::getGLOriginFormat(data.getFormat()), 
 			glGetTexImage(mFaceTarget, mLevel, GLPixelUtil::getGLOriginFormat(data.getFormat()), 
 				GLPixelUtil::getGLOriginDataType(data.getFormat()), data.getData());
 				GLPixelUtil::getGLOriginDataType(data.getFormat()), data.getData());
+			BS_CHECK_GL_ERROR();
 
 
 			// Restore defaults
 			// Restore defaults
 			glPixelStorei(GL_PACK_ROW_LENGTH, 0);
 			glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+			BS_CHECK_GL_ERROR();
+
 			glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
 			glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
+			BS_CHECK_GL_ERROR();
+
 			glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
 			glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+			BS_CHECK_GL_ERROR();
+
 			glPixelStorei(GL_PACK_ALIGNMENT, 4);
 			glPixelStorei(GL_PACK_ALIGNMENT, 4);
+			BS_CHECK_GL_ERROR();
 		}
 		}
 
 
 		BS_INC_RENDER_STAT_CAT(ResRead, RenderStatObject_Texture);
 		BS_INC_RENDER_STAT_CAT(ResRead, RenderStatObject_Texture);
@@ -350,21 +416,22 @@ namespace bs { namespace ct
 			switch (mTarget)
 			switch (mTarget)
 			{
 			{
 			case GL_TEXTURE_1D:
 			case GL_TEXTURE_1D:
-				glFramebufferTexture1D(GL_FRAMEBUFFER, attachment,
-					mFaceTarget, mTextureID, mLevel);
+				glFramebufferTexture1D(GL_FRAMEBUFFER, attachment, mFaceTarget, mTextureID, mLevel);
+				BS_CHECK_GL_ERROR();
 				break;
 				break;
 			case GL_TEXTURE_2D:
 			case GL_TEXTURE_2D:
-				glFramebufferTexture2D(GL_FRAMEBUFFER, attachment,
-					mFaceTarget, mTextureID, mLevel);
+				glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, mFaceTarget, mTextureID, mLevel);
+				BS_CHECK_GL_ERROR();
 				break;
 				break;
 			case GL_TEXTURE_2D_MULTISAMPLE:
 			case GL_TEXTURE_2D_MULTISAMPLE:
-				glFramebufferTexture2D(GL_FRAMEBUFFER, attachment,
-					mFaceTarget, mTextureID, 0);
+				glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, mFaceTarget, mTextureID, 0);
+				BS_CHECK_GL_ERROR();
 				break;
 				break;
 			case GL_TEXTURE_CUBE_MAP:
 			case GL_TEXTURE_CUBE_MAP:
 			case GL_TEXTURE_3D:
 			case GL_TEXTURE_3D:
 			default: // Texture arrays (binding all layers)
 			default: // Texture arrays (binding all layers)
 				glFramebufferTexture(GL_FRAMEBUFFER, attachment, mTextureID, mLevel);
 				glFramebufferTexture(GL_FRAMEBUFFER, attachment, mTextureID, mLevel);
+				BS_CHECK_GL_ERROR();
 				break;
 				break;
 			}
 			}
 		}
 		}
@@ -374,9 +441,11 @@ namespace bs { namespace ct
 			{
 			{
 			case GL_TEXTURE_3D:
 			case GL_TEXTURE_3D:
 				glFramebufferTexture3D(GL_FRAMEBUFFER, attachment, mFaceTarget, mTextureID, mLevel, zoffset);
 				glFramebufferTexture3D(GL_FRAMEBUFFER, attachment, mFaceTarget, mTextureID, mLevel, zoffset);
+				BS_CHECK_GL_ERROR();
 				break;
 				break;
 			default: // Texture arrays and cube maps
 			default: // Texture arrays and cube maps
 				glFramebufferTextureLayer(GL_FRAMEBUFFER, attachment, mTextureID, mLevel, mFace);
 				glFramebufferTextureLayer(GL_FRAMEBUFFER, attachment, mTextureID, mLevel, mFace);
+				BS_CHECK_GL_ERROR();
 				break;
 				break;
 			}
 			}
 		}
 		}
@@ -385,17 +454,22 @@ namespace bs { namespace ct
 	void GLTextureBuffer::copyFromFramebuffer(UINT32 zoffset)
 	void GLTextureBuffer::copyFromFramebuffer(UINT32 zoffset)
 	{
 	{
 		glBindTexture(mTarget, mTextureID);
 		glBindTexture(mTarget, mTextureID);
+		BS_CHECK_GL_ERROR();
+
 		switch(mTarget)
 		switch(mTarget)
 		{
 		{
 		case GL_TEXTURE_1D:
 		case GL_TEXTURE_1D:
 			glCopyTexSubImage1D(mFaceTarget, mLevel, 0, 0, 0, mWidth);
 			glCopyTexSubImage1D(mFaceTarget, mLevel, 0, 0, 0, mWidth);
+			BS_CHECK_GL_ERROR();
 			break;
 			break;
 		case GL_TEXTURE_2D:
 		case GL_TEXTURE_2D:
 		case GL_TEXTURE_CUBE_MAP:
 		case GL_TEXTURE_CUBE_MAP:
 			glCopyTexSubImage2D(mFaceTarget, mLevel, 0, 0, 0, 0, mWidth, mHeight);
 			glCopyTexSubImage2D(mFaceTarget, mLevel, 0, 0, 0, 0, mWidth, mHeight);
+			BS_CHECK_GL_ERROR();
 			break;
 			break;
 		case GL_TEXTURE_3D:
 		case GL_TEXTURE_3D:
 			glCopyTexSubImage3D(mFaceTarget, mLevel, 0, 0, zoffset, 0, 0, mWidth, mHeight);
 			glCopyTexSubImage3D(mFaceTarget, mLevel, 0, 0, zoffset, 0, 0, mWidth, mHeight);
+			BS_CHECK_GL_ERROR();
 			break;
 			break;
 		}
 		}
 	}
 	}
@@ -409,30 +483,43 @@ namespace bs { namespace ct
 
 
 			GLint currentFBO = 0;
 			GLint currentFBO = 0;
 			glGetIntegerv(GL_FRAMEBUFFER_BINDING, &currentFBO);
 			glGetIntegerv(GL_FRAMEBUFFER_BINDING, &currentFBO);
+			BS_CHECK_GL_ERROR();
 
 
 			GLuint readFBO = GLRTTManager::instance().getBlitReadFBO();
 			GLuint readFBO = GLRTTManager::instance().getBlitReadFBO();
 			GLuint drawFBO = GLRTTManager::instance().getBlitDrawFBO();
 			GLuint drawFBO = GLRTTManager::instance().getBlitDrawFBO();
 
 
 			// Attach source texture
 			// Attach source texture
 			glBindFramebuffer(GL_FRAMEBUFFER, readFBO);
 			glBindFramebuffer(GL_FRAMEBUFFER, readFBO);
+			BS_CHECK_GL_ERROR();
+
 			src->bindToFramebuffer(0, 0, true);
 			src->bindToFramebuffer(0, 0, true);
 
 
 			// Attach destination texture
 			// Attach destination texture
 			glBindFramebuffer(GL_FRAMEBUFFER, drawFBO);
 			glBindFramebuffer(GL_FRAMEBUFFER, drawFBO);
+			BS_CHECK_GL_ERROR();
+
 			bindToFramebuffer(0, 0, true);
 			bindToFramebuffer(0, 0, true);
 
 
 			// Perform blit
 			// Perform blit
 			glBindFramebuffer(GL_READ_FRAMEBUFFER, readFBO);
 			glBindFramebuffer(GL_READ_FRAMEBUFFER, readFBO);
+			BS_CHECK_GL_ERROR();
+
 			glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO);
 			glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO);
+			BS_CHECK_GL_ERROR();
 
 
 			glReadBuffer(GL_COLOR_ATTACHMENT0);
 			glReadBuffer(GL_COLOR_ATTACHMENT0);
+			BS_CHECK_GL_ERROR();
+
 			glDrawBuffer(GL_COLOR_ATTACHMENT0);
 			glDrawBuffer(GL_COLOR_ATTACHMENT0);
+			BS_CHECK_GL_ERROR();
 
 
 			glBlitFramebuffer(srcBox.left, srcBox.top, srcBox.right, srcBox.bottom, 
 			glBlitFramebuffer(srcBox.left, srcBox.top, srcBox.right, srcBox.bottom, 
 				dstBox.left, dstBox.top, dstBox.right, dstBox.bottom, GL_COLOR_BUFFER_BIT, GL_NEAREST);
 				dstBox.left, dstBox.top, dstBox.right, dstBox.bottom, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+			BS_CHECK_GL_ERROR();
 
 
 			// Restore the previously bound FBO
 			// Restore the previously bound FBO
 			glBindFramebuffer(GL_FRAMEBUFFER, currentFBO);
 			glBindFramebuffer(GL_FRAMEBUFFER, currentFBO);
+			BS_CHECK_GL_ERROR();
 		}
 		}
 		else // Just plain copy
 		else // Just plain copy
 		{
 		{
@@ -443,11 +530,13 @@ namespace bs { namespace ct
 			{
 			{
 				glCopyImageSubData(src->mTextureID, src->mTarget, src->mLevel, srcBox.left, srcBox.top, srcBox.front,
 				glCopyImageSubData(src->mTextureID, src->mTarget, src->mLevel, srcBox.left, srcBox.top, srcBox.front,
 					mTextureID, mTarget, mLevel, dstBox.left, dstBox.top, dstBox.front, srcBox.getWidth(), srcBox.getHeight(), srcBox.getDepth());
 					mTextureID, mTarget, mLevel, dstBox.left, dstBox.top, dstBox.front, srcBox.getWidth(), srcBox.getHeight(), srcBox.getDepth());
+				BS_CHECK_GL_ERROR();
 			}
 			}
 			else
 			else
 			{
 			{
 				glCopyImageSubData(src->mTextureID, src->mTarget, src->mLevel, srcBox.left, srcBox.top, src->mFace,
 				glCopyImageSubData(src->mTextureID, src->mTarget, src->mLevel, srcBox.left, srcBox.top, src->mFace,
 					mTextureID, mTarget, mLevel, dstBox.left, dstBox.top, mFace, srcBox.getWidth(), srcBox.getHeight(), 1);
 					mTextureID, mTarget, mLevel, dstBox.left, dstBox.top, mFace, srcBox.getWidth(), srcBox.getHeight(), 1);
+				BS_CHECK_GL_ERROR();
 			}
 			}
 		}		
 		}		
 	}
 	}

+ 20 - 20
Source/BansheeGLRenderAPI/BsGLPixelBuffer.h

@@ -34,16 +34,16 @@ namespace bs { namespace ct
 		virtual ~GLPixelBuffer();
 		virtual ~GLPixelBuffer();
 
 
 		/**	Returns width of the surface in pixels. */
 		/**	Returns width of the surface in pixels. */
-        UINT32 getWidth() const { return mWidth; }
+		UINT32 getWidth() const { return mWidth; }
 
 
 		/**	Returns height of the surface in pixels. */
 		/**	Returns height of the surface in pixels. */
-        UINT32 getHeight() const { return mHeight; }
+		UINT32 getHeight() const { return mHeight; }
 
 
 		/**	Returns depth of the surface in pixels. */
 		/**	Returns depth of the surface in pixels. */
-        UINT32 getDepth() const { return mDepth; }
+		UINT32 getDepth() const { return mDepth; }
 
 
 		/**	Returns format of the pixels in the surface. */
 		/**	Returns format of the pixels in the surface. */
-        PixelFormat getFormat() const { return mFormat; }
+		PixelFormat getFormat() const { return mFormat; }
 
 
 		/**
 		/**
 		 * Locks a certain region of the pixel buffer for reading and returns a pointer to the locked region.
 		 * Locks a certain region of the pixel buffer for reading and returns a pointer to the locked region.
@@ -64,7 +64,7 @@ namespace bs { namespace ct
 		 *						anything he hasn't requested (for example don't try to read from the buffer unless you
 		 *						anything he hasn't requested (for example don't try to read from the buffer unless you
 		 *						requested it here).
 		 *						requested it here).
 		 */
 		 */
-        void* lock(UINT32 offset, UINT32 length, GpuLockOptions options);
+		void* lock(UINT32 offset, UINT32 length, GpuLockOptions options);
 
 
 		/**
 		/**
 		 * Locks the entire buffer and returns pointer to the locked area. You must call unlock() when done.
 		 * Locks the entire buffer and returns pointer to the locked area. You must call unlock() when done.
@@ -73,10 +73,10 @@ namespace bs { namespace ct
 		 *						anything he hasn't requested (for example don't try to read from the buffer unless you
 		 *						anything he hasn't requested (for example don't try to read from the buffer unless you
 		 *						requested it here).
 		 *						requested it here).
 		 */
 		 */
-        void* lock(GpuLockOptions options)
-        {
-            return lock(0, mSizeInBytes, options);
-        }
+		void* lock(GpuLockOptions options)
+		{
+			return lock(0, mSizeInBytes, options);
+		}
 
 
 		/**	Releases the lock on this buffer. */
 		/**	Releases the lock on this buffer. */
 		void unlock();
 		void unlock();
@@ -139,9 +139,9 @@ namespace bs { namespace ct
 	};
 	};
 
 
 	/**	Pixel buffer specialization that represents a single surface in a texture. */
 	/**	Pixel buffer specialization that represents a single surface in a texture. */
-    class GLTextureBuffer : public GLPixelBuffer
+	class GLTextureBuffer : public GLPixelBuffer
 	{
 	{
-    public:
+	public:
 		/**
 		/**
 		 * Constructs a new texture buffer from a specific surface in the provided texture.
 		 * Constructs a new texture buffer from a specific surface in the provided texture.
 		 *
 		 *
@@ -155,10 +155,10 @@ namespace bs { namespace ct
 		 */
 		 */
 		GLTextureBuffer(GLenum target, GLuint id, GLint face, 
 		GLTextureBuffer(GLenum target, GLuint id, GLint face, 
 			GLint level, GpuBufferUsage usage, PixelFormat format, UINT32 multisampleCount);
 			GLint level, GpuBufferUsage usage, PixelFormat format, UINT32 multisampleCount);
-        ~GLTextureBuffer();
-        
+		~GLTextureBuffer();
+		
 		/** @copydoc GLPixelBuffer::bindToFramebuffer */
 		/** @copydoc GLPixelBuffer::bindToFramebuffer */
-        void bindToFramebuffer(GLenum attachment, UINT32 zoffset, bool allLayers) override;
+		void bindToFramebuffer(GLenum attachment, UINT32 zoffset, bool allLayers) override;
 
 
 		/** @copydoc GLPixelBuffer::upload */
 		/** @copydoc GLPixelBuffer::upload */
 		void upload(const PixelData &data, const PixelVolume &dest) override;
 		void upload(const PixelData &data, const PixelVolume &dest) override;
@@ -169,21 +169,21 @@ namespace bs { namespace ct
 		/** @copydoc GLPixelBuffer::blitFromTexture */
 		/** @copydoc GLPixelBuffer::blitFromTexture */
 		void blitFromTexture(GLTextureBuffer *src, const PixelVolume &srcBox, const PixelVolume &dstBox) override;
 		void blitFromTexture(GLTextureBuffer *src, const PixelVolume &srcBox, const PixelVolume &dstBox) override;
 
 
-        /**
-         * Populate texture buffer with the data in the currently attached frame buffer.
+		/**
+		 * Populate texture buffer with the data in the currently attached frame buffer.
 		 *
 		 *
 		 * @param[in]	zoffset		3D slice of the texture to copy to. 0 if texture is not 3D.
 		 * @param[in]	zoffset		3D slice of the texture to copy to. 0 if texture is not 3D.
-         */
-        void copyFromFramebuffer(UINT32 zoffset);
+		 */
+		void copyFromFramebuffer(UINT32 zoffset);
 
 
-    protected:
+	protected:
 		GLenum mTarget;
 		GLenum mTarget;
 		GLenum mFaceTarget;
 		GLenum mFaceTarget;
 		GLuint mTextureID;
 		GLuint mTextureID;
 		GLint mFace;
 		GLint mFace;
 		GLint mLevel;
 		GLint mLevel;
 		UINT32 mMultisampleCount;
 		UINT32 mMultisampleCount;
-    };
+	};
 
 
 	/** @} */
 	/** @} */
 }}
 }}

+ 1 - 1
Source/BansheeGLRenderAPI/BsGLPixelFormat.h

@@ -23,7 +23,7 @@ namespace bs { namespace ct
 	
 	
 		/**	Returns OpenGL data type used in the provided format. */
 		/**	Returns OpenGL data type used in the provided format. */
 		static GLenum getGLOriginDataType(PixelFormat mFormat);
 		static GLenum getGLOriginDataType(PixelFormat mFormat);
-        
+		
 		/**
 		/**
 		 * Returns matching OpenGL internal pixel format type if one is found, zero otherwise. Optionally returns an SRGB
 		 * Returns matching OpenGL internal pixel format type if one is found, zero otherwise. Optionally returns an SRGB
 		 * format if @p hwGamma is specified and such format exists.
 		 * format if @p hwGamma is specified and such format exists.

+ 31 - 8
Source/BansheeGLRenderAPI/BsGLPrerequisites.h

@@ -8,6 +8,19 @@
 #	define GLEW_MX
 #	define GLEW_MX
 #endif
 #endif
 
 
+// 4.1 is the minimum supported version for OpenGL
+#define BS_OPENGL_4_1 1
+#define BS_OPENGL_4_2 1
+#define BS_OPENGL_4_3 1
+#define BS_OPENGL_4_4 1
+#define BS_OPENGL_4_5 1
+#define BS_OPENGL_4_6 0
+
+// 3.0 is the minimum supported version for OpenGL ES
+#define BS_OPENGLES_3_0 0
+#define BS_OPENGLES_3_1 0
+#define BS_OPENGLES_3_2 0
+
 #if BS_PLATFORM == BS_PLATFORM_WIN32
 #if BS_PLATFORM == BS_PLATFORM_WIN32
 #if !defined( __MINGW32__ )
 #if !defined( __MINGW32__ )
 #   define WIN32_LEAN_AND_MEAN
 #   define WIN32_LEAN_AND_MEAN
@@ -19,14 +32,12 @@
 #   include <wingdi.h>
 #   include <wingdi.h>
 #   include <GL/glew.h>
 #   include <GL/glew.h>
 #   include <GL/wglew.h>
 #   include <GL/wglew.h>
-#   include <GL/glu.h>
 #elif BS_PLATFORM == BS_PLATFORM_LINUX
 #elif BS_PLATFORM == BS_PLATFORM_LINUX
 #   include <GL/glew.h>
 #   include <GL/glew.h>
 #   include <GL/glu.h>
 #   include <GL/glu.h>
 #   define GL_GLEXT_PROTOTYPES
 #   define GL_GLEXT_PROTOTYPES
 #elif BS_PLATFORM == BS_PLATFORM_OSX
 #elif BS_PLATFORM == BS_PLATFORM_OSX
 #   include <GL/glew.h>
 #   include <GL/glew.h>
-#   include <OpenGL/glu.h>
 #endif
 #endif
 
 
 #if BS_THREAD_SUPPORT == 1
 #if BS_THREAD_SUPPORT == 1
@@ -55,15 +66,27 @@
 
 
 namespace bs { namespace ct
 namespace bs { namespace ct
 {
 {
+	/** Translated an OpenGL error code enum to an error code string. */
+	const char* bs_get_gl_error_string(GLenum errorCode);
+
+	/** Checks if there have been any OpenGL errors since the last call, and if so reports them. */
+	void bs_check_gl_error(const char* function, const char* file, INT32 line);
+
+#if BS_DEBUG_MODE && (!BS_OPENGL_4_3 && !BS_OPENGLES_3_2)
+	#define BS_CHECK_GL_ERROR() bs_check_gl_error(__PRETTY_FUNCTION__, __FILE__,__LINE__)
+#else
+	#define BS_CHECK_GL_ERROR()
+#endif
+
 	extern const char* MODULE_NAME;
 	extern const char* MODULE_NAME;
 
 
-    class GLSupport;
-    class GLRenderAPI;
-    class GLTexture;
+	class GLSupport;
+	class GLRenderAPI;
+	class GLTexture;
 	class GLVertexBuffer;
 	class GLVertexBuffer;
-    class GLContext;
-    class GLRTTManager;
-    class GLPixelBuffer;
+	class GLContext;
+	class GLRTTManager;
+	class GLPixelBuffer;
 	class GLGpuParamBlock;
 	class GLGpuParamBlock;
 	class GLSLGpuProgram;
 	class GLSLGpuProgram;
 	class GLVertexArrayObject;
 	class GLVertexArrayObject;

+ 1 - 4
Source/BansheeGLRenderAPI/BsGLRenderAPI.h

@@ -360,9 +360,6 @@ namespace bs { namespace ct
 		 */
 		 */
 		GLint convertStencilOp(StencilOperation op, bool invert = false) const;
 		GLint convertStencilOp(StencilOperation op, bool invert = false) const;
 
 
-		/**	Checks if there are any OpenGL errors and prints them to the log. */
-		bool checkForErrors() const;
-
 	private:
 	private:
 		/** Information about a currently bound texture. */
 		/** Information about a currently bound texture. */
 		struct TextureInfo
 		struct TextureInfo
@@ -419,7 +416,7 @@ namespace bs { namespace ct
 		bool mDrawCallInProgress;
 		bool mDrawCallInProgress;
 
 
 		UINT16 mActiveTextureUnit;
 		UINT16 mActiveTextureUnit;
-    };
+	};
 
 
 	/** @} */
 	/** @} */
 }}
 }}

+ 80 - 15
Source/BansheeGLRenderAPI/BsGLRenderTexture.cpp

@@ -143,13 +143,19 @@ namespace bs
 		detectFBOFormats();
 		detectFBOFormats();
 		
 		
 		glGenFramebuffers(1, &mBlitReadFBO);
 		glGenFramebuffers(1, &mBlitReadFBO);
+		BS_CHECK_GL_ERROR();
+
 		glGenFramebuffers(1, &mBlitWriteFBO);
 		glGenFramebuffers(1, &mBlitWriteFBO);
+		BS_CHECK_GL_ERROR();
 	}
 	}
 
 
 	GLRTTManager::~GLRTTManager()
 	GLRTTManager::~GLRTTManager()
 	{
 	{
 		glDeleteFramebuffers(1, &mBlitReadFBO);
 		glDeleteFramebuffers(1, &mBlitReadFBO);
+		BS_CHECK_GL_ERROR();
+
 		glDeleteFramebuffers(1, &mBlitWriteFBO);
 		glDeleteFramebuffers(1, &mBlitWriteFBO);
+		BS_CHECK_GL_ERROR();
 	}
 	}
 
 
 	bool GLRTTManager::_tryFormat(GLenum depthFormat, GLenum stencilFormat)
 	bool GLRTTManager::_tryFormat(GLenum depthFormat, GLenum stencilFormat)
@@ -161,54 +167,69 @@ namespace bs
 		{
 		{
 			// Generate depth renderbuffer
 			// Generate depth renderbuffer
 			glGenRenderbuffers(1, &depthRB);
 			glGenRenderbuffers(1, &depthRB);
+			BS_CHECK_GL_ERROR();
 
 
 			// Bind it to FBO
 			// Bind it to FBO
 			glBindRenderbuffer(GL_RENDERBUFFER, depthRB);
 			glBindRenderbuffer(GL_RENDERBUFFER, depthRB);
+			BS_CHECK_GL_ERROR();
 
 
 			// Allocate storage for depth buffer
 			// Allocate storage for depth buffer
-			glRenderbufferStorage(GL_RENDERBUFFER, depthFormat,
-				PROBE_SIZE, PROBE_SIZE);
+			glRenderbufferStorage(GL_RENDERBUFFER, depthFormat, PROBE_SIZE, PROBE_SIZE);
+
+			if (glGetError() != GL_NO_ERROR)
+				failed = true;
 
 
 			// Attach depth
 			// Attach depth
-			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
-				GL_RENDERBUFFER, depthRB);
+			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRB);
+
+			if (glGetError() != GL_NO_ERROR)
+				failed = true;
 		}
 		}
 
 
 		if (stencilFormat != GL_NONE)
 		if (stencilFormat != GL_NONE)
 		{
 		{
 			// Generate stencil renderbuffer
 			// Generate stencil renderbuffer
 			glGenRenderbuffers(1, &stencilRB);
 			glGenRenderbuffers(1, &stencilRB);
+			BS_CHECK_GL_ERROR();
 
 
 			// Bind it to FBO
 			// Bind it to FBO
 			glBindRenderbuffer(GL_RENDERBUFFER, stencilRB);
 			glBindRenderbuffer(GL_RENDERBUFFER, stencilRB);
-			glGetError();
+			BS_CHECK_GL_ERROR();
 
 
 			// Allocate storage for stencil buffer
 			// Allocate storage for stencil buffer
-			glRenderbufferStorage(GL_RENDERBUFFER, stencilFormat,
-				PROBE_SIZE, PROBE_SIZE);
+			glRenderbufferStorage(GL_RENDERBUFFER, stencilFormat, PROBE_SIZE, PROBE_SIZE);
 
 
 			if (glGetError() != GL_NO_ERROR)
 			if (glGetError() != GL_NO_ERROR)
 				failed = true;
 				failed = true;
 
 
 			// Attach stencil
 			// Attach stencil
-			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
-				GL_RENDERBUFFER, stencilRB);
+			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencilRB);
 
 
 			if (glGetError() != GL_NO_ERROR)
 			if (glGetError() != GL_NO_ERROR)
 				failed = true;
 				failed = true;
 		}
 		}
 
 
 		status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
 		status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+		BS_CHECK_GL_ERROR();
 
 
 		// Detach and destroy
 		// Detach and destroy
 		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
 		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
+		BS_CHECK_GL_ERROR();
+
 		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
 		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
+		BS_CHECK_GL_ERROR();
 
 
 		if (depthRB)
 		if (depthRB)
+		{
 			glDeleteRenderbuffers(1, &depthRB);
 			glDeleteRenderbuffers(1, &depthRB);
+			BS_CHECK_GL_ERROR();
+		}
 
 
 		if (stencilRB)
 		if (stencilRB)
+		{
 			glDeleteRenderbuffers(1, &stencilRB);
 			glDeleteRenderbuffers(1, &stencilRB);
+			BS_CHECK_GL_ERROR();
+		}
 
 
 		return status == GL_FRAMEBUFFER_COMPLETE && !failed;
 		return status == GL_FRAMEBUFFER_COMPLETE && !failed;
 	}
 	}
@@ -220,13 +241,17 @@ namespace bs
 
 
 		// Generate renderbuffer
 		// Generate renderbuffer
 		glGenRenderbuffers(1, &packedRB);
 		glGenRenderbuffers(1, &packedRB);
+		BS_CHECK_GL_ERROR();
 
 
 		// Bind it to FBO
 		// Bind it to FBO
 		glBindRenderbuffer(GL_RENDERBUFFER, packedRB);
 		glBindRenderbuffer(GL_RENDERBUFFER, packedRB);
+		BS_CHECK_GL_ERROR();
 
 
 		// Allocate storage for buffer
 		// Allocate storage for buffer
 		glRenderbufferStorage(GL_RENDERBUFFER, packedFormat, PROBE_SIZE, PROBE_SIZE);
 		glRenderbufferStorage(GL_RENDERBUFFER, packedFormat, PROBE_SIZE, PROBE_SIZE);
-		glGetError();
+
+		if (glGetError() != GL_NO_ERROR)
+			failed = true;
 
 
 		// Attach depth
 		// Attach depth
 		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
 		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
@@ -243,11 +268,17 @@ namespace bs
 			failed = true;
 			failed = true;
 
 
 		GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
 		GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+		BS_CHECK_GL_ERROR();
 
 
 		// Detach and destroy
 		// Detach and destroy
 		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
 		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
+		BS_CHECK_GL_ERROR();
+
 		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
 		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
+		BS_CHECK_GL_ERROR();
+
 		glDeleteRenderbuffers(1, &packedRB);
 		glDeleteRenderbuffers(1, &packedRB);
+		BS_CHECK_GL_ERROR();
 
 
 		return status == GL_FRAMEBUFFER_COMPLETE && !failed;
 		return status == GL_FRAMEBUFFER_COMPLETE && !failed;
 	}
 	}
@@ -260,9 +291,12 @@ namespace bs
 		GLenum target = GL_TEXTURE_2D;
 		GLenum target = GL_TEXTURE_2D;
 
 
 		glGetIntegerv(GL_DRAW_BUFFER, &oldDrawbuffer);
 		glGetIntegerv(GL_DRAW_BUFFER, &oldDrawbuffer);
+		BS_CHECK_GL_ERROR();
+
 		glGetIntegerv(GL_READ_BUFFER, &oldReadbuffer);
 		glGetIntegerv(GL_READ_BUFFER, &oldReadbuffer);
+		BS_CHECK_GL_ERROR();
 
 
-		for (size_t x = 0; x < PF_COUNT; ++x)
+		for (UINT32 x = 0; x < PF_COUNT; ++x)
 		{
 		{
 			mProps[x].valid = false;
 			mProps[x].valid = false;
 
 
@@ -281,33 +315,54 @@ namespace bs
 
 
 			// Create and attach framebuffer
 			// Create and attach framebuffer
 			glGenFramebuffers(1, &fb);
 			glGenFramebuffers(1, &fb);
+			BS_CHECK_GL_ERROR();
+
 			glBindFramebuffer(GL_FRAMEBUFFER, fb);
 			glBindFramebuffer(GL_FRAMEBUFFER, fb);
+			BS_CHECK_GL_ERROR();
+
 			if (fmt != GL_NONE && !PixelUtil::isDepth((PixelFormat)x))
 			if (fmt != GL_NONE && !PixelUtil::isDepth((PixelFormat)x))
 			{
 			{
 				// Create and attach texture
 				// Create and attach texture
 				glGenTextures(1, &tid);
 				glGenTextures(1, &tid);
+				BS_CHECK_GL_ERROR();
+
 				glBindTexture(target, tid);
 				glBindTexture(target, tid);
+				BS_CHECK_GL_ERROR();
 				
 				
-				// Set some default parameters so it won't fail on NVidia cards         
-				if (GLEW_VERSION_1_2)
-					glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, 0);
+				glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, 0);
+				BS_CHECK_GL_ERROR();
+
 				glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 				glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+				BS_CHECK_GL_ERROR();
+
 				glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 				glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+				BS_CHECK_GL_ERROR();
+
 				glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 				glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+				BS_CHECK_GL_ERROR();
+
 				glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 				glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+				BS_CHECK_GL_ERROR();
 
 
 				glTexImage2D(target, 0, fmt, PROBE_SIZE, PROBE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
 				glTexImage2D(target, 0, fmt, PROBE_SIZE, PROBE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+				BS_CHECK_GL_ERROR();
+
 				glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, tid, 0);
 				glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, tid, 0);
+				BS_CHECK_GL_ERROR();
 			}
 			}
 			else
 			else
 			{
 			{
-				// Draw to nowhere -- stencil/depth only
+				// Draw to nowhere (stencil/depth only)
 				glDrawBuffer(GL_NONE);
 				glDrawBuffer(GL_NONE);
+				BS_CHECK_GL_ERROR();
+
 				glReadBuffer(GL_NONE);
 				glReadBuffer(GL_NONE);
+				BS_CHECK_GL_ERROR();
 			}
 			}
 
 
 			// Check status
 			// Check status
 			GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
 			GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+			BS_CHECK_GL_ERROR();
 
 
 			// Ignore status in case of fmt==GL_NONE, because no implementation will accept
 			// Ignore status in case of fmt==GL_NONE, because no implementation will accept
 			// a buffer without *any* attachment. Buffers with only stencil and depth attachment
 			// a buffer without *any* attachment. Buffers with only stencil and depth attachment
@@ -347,16 +402,26 @@ namespace bs
 
 
 			// Delete texture and framebuffer
 			// Delete texture and framebuffer
 			glBindFramebuffer(GL_FRAMEBUFFER, 0);
 			glBindFramebuffer(GL_FRAMEBUFFER, 0);
+			BS_CHECK_GL_ERROR();
+
 			glDeleteFramebuffers(1, &fb);
 			glDeleteFramebuffers(1, &fb);
+			BS_CHECK_GL_ERROR();
 			
 			
 			glFinish();
 			glFinish();
+			BS_CHECK_GL_ERROR();
 			
 			
 			if (fmt != GL_NONE)
 			if (fmt != GL_NONE)
+			{
 				glDeleteTextures(1, &tid);
 				glDeleteTextures(1, &tid);
+				BS_CHECK_GL_ERROR();
+			}
 		}
 		}
 
 
 		glDrawBuffer(oldDrawbuffer);
 		glDrawBuffer(oldDrawbuffer);
+		BS_CHECK_GL_ERROR();
+
 		glReadBuffer(oldReadbuffer);
 		glReadBuffer(oldReadbuffer);
+		BS_CHECK_GL_ERROR();
 	}
 	}
 
 
 	PixelFormat GLRTTManager::getSupportedAlternative(PixelFormat format)
 	PixelFormat GLRTTManager::getSupportedAlternative(PixelFormat format)

+ 2 - 1
Source/BansheeGLRenderAPI/BsGLSupport.cpp

@@ -11,7 +11,7 @@ namespace bs { namespace ct
 	void GLSupport::initializeExtensions()
 	void GLSupport::initializeExtensions()
 	{
 	{
 		glewContextInit(this);
 		glewContextInit(this);
-		glGetError();
+		BS_CHECK_GL_ERROR();
 
 
 		// Set version string
 		// Set version string
 		const GLubyte* pcVer = glGetString(GL_VERSION);
 		const GLubyte* pcVer = glGetString(GL_VERSION);
@@ -28,6 +28,7 @@ namespace bs { namespace ct
 		// Set extension list
 		// Set extension list
 		INT32 numExtensions = 0;
 		INT32 numExtensions = 0;
 		glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
 		glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
+		BS_CHECK_GL_ERROR();
 
 
 		for (INT32 i = 0; i < numExtensions; i++)
 		for (INT32 i = 0; i < numExtensions; i++)
 			extensionList.insert(String((char*)glGetStringi(GL_EXTENSIONS, i)));
 			extensionList.insert(String((char*)glGetStringi(GL_EXTENSIONS, i)));

+ 29 - 0
Source/BansheeGLRenderAPI/BsGLTexture.cpp

@@ -27,6 +27,7 @@ namespace bs { namespace ct
 	{
 	{
 		mSurfaceList.clear();
 		mSurfaceList.clear();
 		glDeleteTextures(1, &mTextureID);
 		glDeleteTextures(1, &mTextureID);
+		BS_CHECK_GL_ERROR();
 
 
 		clearBufferViews();
 		clearBufferViews();
 
 
@@ -74,12 +75,15 @@ namespace bs { namespace ct
 
 
 		// Generate texture handle
 		// Generate texture handle
 		glGenTextures(1, &mTextureID);
 		glGenTextures(1, &mTextureID);
+		BS_CHECK_GL_ERROR();
 
 
 		// Set texture type
 		// Set texture type
 		glBindTexture(getGLTextureTarget(), mTextureID);
 		glBindTexture(getGLTextureTarget(), mTextureID);
+		BS_CHECK_GL_ERROR();
 
 
 		// This needs to be set otherwise the texture doesn't get rendered
 		// This needs to be set otherwise the texture doesn't get rendered
 		glTexParameteri(getGLTextureTarget(), GL_TEXTURE_MAX_LEVEL, numMips - 1);
 		glTexParameteri(getGLTextureTarget(), GL_TEXTURE_MAX_LEVEL, numMips - 1);
+		BS_CHECK_GL_ERROR();
 
 
 		// Allocate internal buffer so that glTexSubImageXD can be used
 		// Allocate internal buffer so that glTexSubImageXD can be used
 		mGLFormat = GLPixelUtil::getGLInternalFormat(mInternalFormat, mProperties.isHardwareGammaEnabled());
 		mGLFormat = GLPixelUtil::getGLInternalFormat(mInternalFormat, mProperties.isHardwareGammaEnabled());
@@ -88,9 +92,15 @@ namespace bs { namespace ct
 		if((usage & (TU_RENDERTARGET | TU_DEPTHSTENCIL)) != 0 && mProperties.getTextureType() == TEX_TYPE_2D && sampleCount > 1)
 		if((usage & (TU_RENDERTARGET | TU_DEPTHSTENCIL)) != 0 && mProperties.getTextureType() == TEX_TYPE_2D && sampleCount > 1)
 		{
 		{
 			if (numFaces <= 1)
 			if (numFaces <= 1)
+			{
 				glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, sampleCount, mGLFormat, width, height, GL_FALSE);
 				glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, sampleCount, mGLFormat, width, height, GL_FALSE);
+				BS_CHECK_GL_ERROR();
+			}
 			else
 			else
+			{
 				glTexStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, sampleCount, mGLFormat, width, height, numFaces, GL_FALSE);
 				glTexStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, sampleCount, mGLFormat, width, height, numFaces, GL_FALSE);
+				BS_CHECK_GL_ERROR();
+			}
 		}
 		}
 		else
 		else
 		{
 		{
@@ -99,28 +109,47 @@ namespace bs { namespace ct
 			case TEX_TYPE_1D:
 			case TEX_TYPE_1D:
 			{
 			{
 				if (numFaces <= 1)
 				if (numFaces <= 1)
+				{
 					glTexStorage1D(GL_TEXTURE_1D, numMips, mGLFormat, width);
 					glTexStorage1D(GL_TEXTURE_1D, numMips, mGLFormat, width);
+					BS_CHECK_GL_ERROR();
+				}
 				else
 				else
+				{
 					glTexStorage2D(GL_TEXTURE_1D_ARRAY, numMips, mGLFormat, width, numFaces);
 					glTexStorage2D(GL_TEXTURE_1D_ARRAY, numMips, mGLFormat, width, numFaces);
+					BS_CHECK_GL_ERROR();
+				}
 			}
 			}
 				break;
 				break;
 			case TEX_TYPE_2D:
 			case TEX_TYPE_2D:
 			{
 			{
 				if (numFaces <= 1)
 				if (numFaces <= 1)
+				{
 					glTexStorage2D(GL_TEXTURE_2D, numMips, mGLFormat, width, height);
 					glTexStorage2D(GL_TEXTURE_2D, numMips, mGLFormat, width, height);
+					BS_CHECK_GL_ERROR();
+				}
 				else
 				else
+				{
 					glTexStorage3D(GL_TEXTURE_2D_ARRAY, numMips, mGLFormat, width, height, numFaces);
 					glTexStorage3D(GL_TEXTURE_2D_ARRAY, numMips, mGLFormat, width, height, numFaces);
+					BS_CHECK_GL_ERROR();
+				}
 			}
 			}
 				break;
 				break;
 			case TEX_TYPE_3D:
 			case TEX_TYPE_3D:
 				glTexStorage3D(GL_TEXTURE_3D, numMips, mGLFormat, width, height, depth);
 				glTexStorage3D(GL_TEXTURE_3D, numMips, mGLFormat, width, height, depth);
+				BS_CHECK_GL_ERROR();
 				break;
 				break;
 			case TEX_TYPE_CUBE_MAP:
 			case TEX_TYPE_CUBE_MAP:
 			{
 			{
 				if (numFaces <= 6)
 				if (numFaces <= 6)
+				{
 					glTexStorage2D(GL_TEXTURE_CUBE_MAP, numMips, mGLFormat, width, height);
 					glTexStorage2D(GL_TEXTURE_CUBE_MAP, numMips, mGLFormat, width, height);
+					BS_CHECK_GL_ERROR();
+				}
 				else
 				else
+				{
 					glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, numMips, mGLFormat, width, height, numFaces);
 					glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, numMips, mGLFormat, width, height, numFaces);
+					BS_CHECK_GL_ERROR();
+				}
 			}
 			}
 				break;
 				break;
 			}
 			}

+ 4 - 4
Source/BansheeGLRenderAPI/BsGLTexture.h

@@ -77,15 +77,15 @@ namespace bs { namespace ct
 		/**	Creates an empty and uninitialized texture view object. */
 		/**	Creates an empty and uninitialized texture view object. */
 		SPtr<TextureView> createView(const TEXTURE_VIEW_DESC& desc) override;
 		SPtr<TextureView> createView(const TEXTURE_VIEW_DESC& desc) override;
 
 
-    private:
-        GLuint mTextureID;
+	private:
+		GLuint mTextureID;
 		GLenum mGLFormat;
 		GLenum mGLFormat;
 		PixelFormat mInternalFormat;
 		PixelFormat mInternalFormat;
-        GLSupport& mGLSupport;
+		GLSupport& mGLSupport;
 		SPtr<GLPixelBuffer> mLockedBuffer;
 		SPtr<GLPixelBuffer> mLockedBuffer;
 		
 		
 		Vector<SPtr<GLPixelBuffer>>mSurfaceList;
 		Vector<SPtr<GLPixelBuffer>>mSurfaceList;
-    };
+	};
 
 
 	/** @} */
 	/** @} */
 }}
 }}

+ 9 - 9
Source/BansheeGLRenderAPI/BsGLTextureManager.cpp

@@ -7,16 +7,16 @@
 
 
 namespace bs
 namespace bs
 {
 {
-    GLTextureManager::GLTextureManager(ct::GLSupport& support)
-        :TextureManager(), mGLSupport(support)
-    {
+	GLTextureManager::GLTextureManager(ct::GLSupport& support)
+		:TextureManager(), mGLSupport(support)
+	{
 
 
-    }
+	}
 
 
-    GLTextureManager::~GLTextureManager()
-    {
+	GLTextureManager::~GLTextureManager()
+	{
 
 
-    }
+	}
 
 
 	SPtr<RenderTexture> GLTextureManager::createRenderTextureImpl(const RENDER_TEXTURE_DESC& desc)
 	SPtr<RenderTexture> GLTextureManager::createRenderTextureImpl(const RENDER_TEXTURE_DESC& desc)
 	{
 	{
@@ -27,9 +27,9 @@ namespace bs
 
 
 	PixelFormat GLTextureManager::getNativeFormat(TextureType ttype, PixelFormat format, int usage, bool hwGamma)
 	PixelFormat GLTextureManager::getNativeFormat(TextureType ttype, PixelFormat format, int usage, bool hwGamma)
 	{
 	{
-        // Check if this is a valid rendertarget format
+		// Check if this is a valid rendertarget format
 		if(usage & TU_RENDERTARGET)
 		if(usage & TU_RENDERTARGET)
-            return ct::GLRTTManager::instance().getSupportedAlternative(format);
+			return ct::GLRTTManager::instance().getSupportedAlternative(format);
 
 
 		return ct::GLPixelUtil::getClosestSupportedPF(format, ttype, usage);
 		return ct::GLPixelUtil::getClosestSupportedPF(format, ttype, usage);
 	}
 	}

+ 6 - 6
Source/BansheeGLRenderAPI/BsGLTextureManager.h

@@ -14,11 +14,11 @@ namespace bs
 	 */
 	 */
 
 
 	/**	Handles creation of OpenGL textures. */
 	/**	Handles creation of OpenGL textures. */
-    class GLTextureManager : public TextureManager
-    {
-    public:
-        GLTextureManager(ct::GLSupport& support);
-        virtual ~GLTextureManager();
+	class GLTextureManager : public TextureManager
+	{
+	public:
+		GLTextureManager(ct::GLSupport& support);
+		virtual ~GLTextureManager();
 
 
 		/**
 		/**
 		 * Converts the provided format for the specified texture type and usage into a format that is supported by OpenGL.
 		 * Converts the provided format for the specified texture type and usage into a format that is supported by OpenGL.
@@ -30,7 +30,7 @@ namespace bs
 		SPtr<RenderTexture> createRenderTextureImpl(const RENDER_TEXTURE_DESC& desc) override;
 		SPtr<RenderTexture> createRenderTextureImpl(const RENDER_TEXTURE_DESC& desc) override;
 
 
 		ct::GLSupport& mGLSupport;
 		ct::GLSupport& mGLSupport;
-    };
+	};
 
 
 	namespace ct
 	namespace ct
 	{
 	{

+ 13 - 2
Source/BansheeGLRenderAPI/BsGLTextureView.cpp

@@ -65,8 +65,18 @@ namespace bs { namespace ct {
 		}
 		}
 
 
 		glGenTextures(1, &mViewID);
 		glGenTextures(1, &mViewID);
-		glTextureView(mViewID, target, originalTexture, texture->getGLFormat(), desc.mostDetailMip, desc.numMips,
-			desc.firstArraySlice, desc.numArraySlices);
+		BS_CHECK_GL_ERROR();
+
+		glTextureView(
+			mViewID, 
+			target, 
+			originalTexture, 
+			texture->getGLFormat(), 
+			desc.mostDetailMip, 
+			desc.numMips,
+			desc.firstArraySlice, 
+			desc.numArraySlices);
+		BS_CHECK_GL_ERROR();
 
 
 		mTarget = GLTexture::getGLTextureTarget(props.getTextureType(), props.getNumSamples(), desc.numArraySlices);
 		mTarget = GLTexture::getGLTextureTarget(props.getTextureType(), props.getNumSamples(), desc.numArraySlices);
 	}
 	}
@@ -74,5 +84,6 @@ namespace bs { namespace ct {
 	GLTextureView::~GLTextureView()
 	GLTextureView::~GLTextureView()
 	{
 	{
 		glDeleteTextures(1, &mViewID);
 		glDeleteTextures(1, &mViewID);
+		BS_CHECK_GL_ERROR();
 	}
 	}
 }}
 }}

+ 8 - 0
Source/BansheeGLRenderAPI/BsGLTimerQuery.cpp

@@ -14,6 +14,7 @@ namespace bs { namespace ct
 
 
 		GLuint queries[2];
 		GLuint queries[2];
 		glGenQueries(2, queries);
 		glGenQueries(2, queries);
+		BS_CHECK_GL_ERROR();
 
 
 		mQueryStartObj = queries[0];
 		mQueryStartObj = queries[0];
 		mQueryEndObj = queries[1];
 		mQueryEndObj = queries[1];
@@ -28,6 +29,7 @@ namespace bs { namespace ct
 		queries[1] = mQueryEndObj;
 		queries[1] = mQueryEndObj;
 
 
 		glDeleteQueries(2, queries);
 		glDeleteQueries(2, queries);
+		BS_CHECK_GL_ERROR();
 
 
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Query);
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Query);
 	}
 	}
@@ -37,6 +39,7 @@ namespace bs { namespace ct
 		auto execute = [&]()
 		auto execute = [&]()
 		{
 		{
 			glQueryCounter(mQueryStartObj, GL_TIMESTAMP);
 			glQueryCounter(mQueryStartObj, GL_TIMESTAMP);
+			BS_CHECK_GL_ERROR();
 
 
 			setActive(true);
 			setActive(true);
 			mEndIssued = false;
 			mEndIssued = false;
@@ -56,6 +59,7 @@ namespace bs { namespace ct
 		auto execute = [&]()
 		auto execute = [&]()
 		{
 		{
 			glQueryCounter(mQueryEndObj, GL_TIMESTAMP);
 			glQueryCounter(mQueryEndObj, GL_TIMESTAMP);
+			BS_CHECK_GL_ERROR();
 
 
 			mEndIssued = true;
 			mEndIssued = true;
 			mFinalized = false;
 			mFinalized = false;
@@ -77,6 +81,7 @@ namespace bs { namespace ct
 
 
 		GLint done = 0;
 		GLint done = 0;
 		glGetQueryObjectiv(mQueryEndObj, GL_QUERY_RESULT_AVAILABLE, &done);
 		glGetQueryObjectiv(mQueryEndObj, GL_QUERY_RESULT_AVAILABLE, &done);
+		BS_CHECK_GL_ERROR();
 
 
 		return done == GL_TRUE;
 		return done == GL_TRUE;
 	}
 	}
@@ -99,7 +104,10 @@ namespace bs { namespace ct
 		GLuint64 timeEnd;
 		GLuint64 timeEnd;
 
 
 		glGetQueryObjectui64v(mQueryStartObj, GL_QUERY_RESULT, &timeStart);
 		glGetQueryObjectui64v(mQueryStartObj, GL_QUERY_RESULT, &timeStart);
+		BS_CHECK_GL_ERROR();
+
 		glGetQueryObjectui64v(mQueryEndObj, GL_QUERY_RESULT, &timeEnd);
 		glGetQueryObjectui64v(mQueryEndObj, GL_QUERY_RESULT, &timeEnd);
+		BS_CHECK_GL_ERROR();
 
 
 		mTimeDelta = (timeEnd - timeStart) / 1000000.0f;
 		mTimeDelta = (timeEnd - timeStart) / 1000000.0f;
 	}
 	}

+ 13 - 2
Source/BansheeGLRenderAPI/BsGLVertexArrayObjectManager.cpp

@@ -128,7 +128,10 @@ namespace bs { namespace ct
 		const List<VertexElement>& inputAttributes = vertexProgram->getInputDeclaration()->getProperties().getElements();
 		const List<VertexElement>& inputAttributes = vertexProgram->getInputDeclaration()->getProperties().getElements();
 
 
 		glGenVertexArrays(1, &wantedVAO.mHandle);
 		glGenVertexArrays(1, &wantedVAO.mHandle);
+		BS_CHECK_GL_ERROR();
+
 		glBindVertexArray(wantedVAO.mHandle);
 		glBindVertexArray(wantedVAO.mHandle);
+		BS_CHECK_GL_ERROR();
 
 
 		for (auto& elem : decl)
 		for (auto& elem : decl)
 		{
 		{
@@ -159,6 +162,8 @@ namespace bs { namespace ct
 			const VertexBufferProperties& vbProps = vertexBuffer->getProperties();
 			const VertexBufferProperties& vbProps = vertexBuffer->getProperties();
 
 
 			glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer->getGLBufferId());
 			glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer->getGLBufferId());
+			BS_CHECK_GL_ERROR();
+
 			void* bufferData = VBO_BUFFER_OFFSET(elem.getOffset());
 			void* bufferData = VBO_BUFFER_OFFSET(elem.getOffset());
 
 
 			UINT16 typeCount = VertexElement::getTypeCount(elem.getType());
 			UINT16 typeCount = VertexElement::getTypeCount(elem.getType());
@@ -184,15 +189,19 @@ namespace bs { namespace ct
 			if(isInteger)
 			if(isInteger)
 			{
 			{
 				glVertexAttribIPointer(attribLocation, typeCount, glType, vertexSize, bufferData);
 				glVertexAttribIPointer(attribLocation, typeCount, glType, vertexSize, bufferData);
+				BS_CHECK_GL_ERROR();
 			}
 			}
 			else
 			else
 			{
 			{
-				glVertexAttribPointer(attribLocation, typeCount, glType, normalized,
-					vertexSize, bufferData);
+				glVertexAttribPointer(attribLocation, typeCount, glType, normalized, vertexSize, bufferData);
+				BS_CHECK_GL_ERROR();
 			}
 			}
 
 
 			glVertexAttribDivisor(attribLocation, elem.getInstanceStepRate());
 			glVertexAttribDivisor(attribLocation, elem.getInstanceStepRate());
+			BS_CHECK_GL_ERROR();
+
 			glEnableVertexAttribArray(attribLocation);
 			glEnableVertexAttribArray(attribLocation);
+			BS_CHECK_GL_ERROR();
 		}
 		}
 
 
 		wantedVAO.mAttachedBuffers = (GLVertexBuffer**)bs_alloc(numUsedBuffers * sizeof(GLVertexBuffer*));
 		wantedVAO.mAttachedBuffers = (GLVertexBuffer**)bs_alloc(numUsedBuffers * sizeof(GLVertexBuffer*));
@@ -222,6 +231,8 @@ namespace bs { namespace ct
 		}
 		}
 
 
 		glDeleteVertexArrays(1, &vao.mHandle);
 		glDeleteVertexArrays(1, &vao.mHandle);
+		BS_CHECK_GL_ERROR();
+
 		bs_free(vao.mAttachedBuffers);
 		bs_free(vao.mAttachedBuffers);
 
 
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_VertexArrayObject);
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_VertexArrayObject);

+ 3 - 3
Source/BansheeGLRenderAPI/GLSL/BsGLSLGpuProgram.h

@@ -12,8 +12,8 @@ namespace bs { namespace ct
 	 */
 	 */
 
 
 	/**	GPU program compiled from GLSL and usable by OpenGL. */
 	/**	GPU program compiled from GLSL and usable by OpenGL. */
-    class GLSLGpuProgram : public GpuProgram
-    {
+	class GLSLGpuProgram : public GpuProgram
+	{
 	public:
 	public:
 		~GLSLGpuProgram();
 		~GLSLGpuProgram();
 
 
@@ -44,7 +44,7 @@ namespace bs { namespace ct
 		static UINT32 mHullShaderCount;
 		static UINT32 mHullShaderCount;
 		static UINT32 mDomainShaderCount;
 		static UINT32 mDomainShaderCount;
 		static UINT32 mComputeShaderCount;
 		static UINT32 mComputeShaderCount;
-    };
+	};
 
 
 	/** @} */
 	/** @} */
 }}
 }}

+ 32 - 0
Source/BansheeGLRenderAPI/GLSL/BsGLSLParamParser.cpp

@@ -22,9 +22,11 @@ namespace bs { namespace ct
 	{
 	{
 		GLint numAttributes = 0;
 		GLint numAttributes = 0;
 		glGetProgramiv(glProgram, GL_ACTIVE_ATTRIBUTES, &numAttributes);
 		glGetProgramiv(glProgram, GL_ACTIVE_ATTRIBUTES, &numAttributes);
+		BS_CHECK_GL_ERROR();
 
 
 		GLint maxNameSize = 0;
 		GLint maxNameSize = 0;
 		glGetProgramiv(glProgram, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameSize);
 		glGetProgramiv(glProgram, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameSize);
+		BS_CHECK_GL_ERROR();
 
 
 		GLchar* attributeName = (GLchar*)bs_alloc(sizeof(GLchar)* maxNameSize);
 		GLchar* attributeName = (GLchar*)bs_alloc(sizeof(GLchar)* maxNameSize);
 
 
@@ -34,6 +36,7 @@ namespace bs { namespace ct
 			GLint attribSize = 0;
 			GLint attribSize = 0;
 			GLenum attribType = 0;
 			GLenum attribType = 0;
 			glGetActiveAttrib(glProgram, i, maxNameSize, nullptr, &attribSize, &attribType, attributeName);
 			glGetActiveAttrib(glProgram, i, maxNameSize, nullptr, &attribSize, &attribType, attributeName);
+			BS_CHECK_GL_ERROR();
 
 
 			VertexElementSemantic semantic = VES_POSITION;
 			VertexElementSemantic semantic = VES_POSITION;
 			UINT16 index = 0;
 			UINT16 index = 0;
@@ -41,6 +44,7 @@ namespace bs { namespace ct
 			{
 			{
 				VertexElementType type = glTypeToAttributeType(attribType);
 				VertexElementType type = glTypeToAttributeType(attribType);
 				UINT32 slot = glGetAttribLocation(glProgram, attributeName);
 				UINT32 slot = glGetAttribLocation(glProgram, attributeName);
+				BS_CHECK_GL_ERROR();
 
 
 				elementList.push_back(VertexElement(0, slot, type, semantic, index));
 				elementList.push_back(VertexElement(0, slot, type, semantic, index));
 			}
 			}
@@ -135,12 +139,15 @@ namespace bs { namespace ct
 		// Scan through the active uniform blocks
 		// Scan through the active uniform blocks
 		GLint maxBufferSize = 0;
 		GLint maxBufferSize = 0;
 		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxBufferSize);
 		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxBufferSize);
+		BS_CHECK_GL_ERROR();
 
 
 		GLint maxBlockNameBufferSize = 0;
 		GLint maxBlockNameBufferSize = 0;
 		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &maxBlockNameBufferSize);
 		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &maxBlockNameBufferSize);
+		BS_CHECK_GL_ERROR();
 
 
 		GLint maxStorageBlockNameBufferSize = 0;
 		GLint maxStorageBlockNameBufferSize = 0;
 		glGetProgramInterfaceiv(glProgram, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, &maxStorageBlockNameBufferSize);
 		glGetProgramInterfaceiv(glProgram, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, &maxStorageBlockNameBufferSize);
+		BS_CHECK_GL_ERROR();
 
 
 		maxBufferSize = std::max(maxBufferSize, maxBlockNameBufferSize);
 		maxBufferSize = std::max(maxBufferSize, maxBlockNameBufferSize);
 		maxBufferSize = std::max(maxBufferSize, maxStorageBlockNameBufferSize);
 		maxBufferSize = std::max(maxBufferSize, maxStorageBlockNameBufferSize);
@@ -159,6 +166,7 @@ namespace bs { namespace ct
 
 
 		GLint uniformBlockCount = 0;
 		GLint uniformBlockCount = 0;
 		glGetProgramInterfaceiv(glProgram, GL_UNIFORM_BLOCK, GL_ACTIVE_RESOURCES, &uniformBlockCount);
 		glGetProgramInterfaceiv(glProgram, GL_UNIFORM_BLOCK, GL_ACTIVE_RESOURCES, &uniformBlockCount);
+		BS_CHECK_GL_ERROR();
 
 
 		Map<UINT32, String> blockSlotToName;
 		Map<UINT32, String> blockSlotToName;
 		Set<String> blockNames;
 		Set<String> blockNames;
@@ -166,6 +174,7 @@ namespace bs { namespace ct
 		{
 		{
 			GLsizei unusedSize = 0;
 			GLsizei unusedSize = 0;
 			glGetProgramResourceName(glProgram, GL_UNIFORM_BLOCK, index, maxBufferSize, &unusedSize, uniformName);
 			glGetProgramResourceName(glProgram, GL_UNIFORM_BLOCK, index, maxBufferSize, &unusedSize, uniformName);
+			BS_CHECK_GL_ERROR();
 
 
 			GpuParamBlockDesc newBlockDesc;
 			GpuParamBlockDesc newBlockDesc;
 			newBlockDesc.slot = index + 1;
 			newBlockDesc.slot = index + 1;
@@ -182,11 +191,13 @@ namespace bs { namespace ct
 		// Scan through the shared storage blocks
 		// Scan through the shared storage blocks
 		GLint storageBlockCount = 0;
 		GLint storageBlockCount = 0;
 		glGetProgramInterfaceiv(glProgram, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &storageBlockCount);
 		glGetProgramInterfaceiv(glProgram, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &storageBlockCount);
+		BS_CHECK_GL_ERROR();
 
 
 		for (GLuint index = 0; index < (GLuint)storageBlockCount; index++)
 		for (GLuint index = 0; index < (GLuint)storageBlockCount; index++)
 		{
 		{
 			GLsizei unusedSize = 0;
 			GLsizei unusedSize = 0;
 			glGetProgramResourceName(glProgram, GL_SHADER_STORAGE_BLOCK, index, maxBufferSize, &unusedSize, uniformName);
 			glGetProgramResourceName(glProgram, GL_SHADER_STORAGE_BLOCK, index, maxBufferSize, &unusedSize, uniformName);
+			BS_CHECK_GL_ERROR();
 
 
 			GpuParamObjectDesc bufferParam;
 			GpuParamObjectDesc bufferParam;
 			bufferParam.name = uniformName;
 			bufferParam.name = uniformName;
@@ -203,6 +214,7 @@ namespace bs { namespace ct
 		// Get the number of active uniforms
 		// Get the number of active uniforms
 		GLint uniformCount = 0;
 		GLint uniformCount = 0;
 		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORMS, &uniformCount);
 		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORMS, &uniformCount);
+		BS_CHECK_GL_ERROR();
 
 
 		// Loop over each of the active uniforms, and add them to the reference container
 		// Loop over each of the active uniforms, and add them to the reference container
 		// only do this for user defined uniforms, ignore built in gl state uniforms
 		// only do this for user defined uniforms, ignore built in gl state uniforms
@@ -210,6 +222,7 @@ namespace bs { namespace ct
 		{
 		{
 			GLsizei arraySize = 0;
 			GLsizei arraySize = 0;
 			glGetActiveUniformName(glProgram, index, maxBufferSize, &arraySize, uniformName);
 			glGetActiveUniformName(glProgram, index, maxBufferSize, &arraySize, uniformName);
+			BS_CHECK_GL_ERROR();
 
 
 			String paramName = String(uniformName);
 			String paramName = String(uniformName);
 
 
@@ -311,6 +324,7 @@ namespace bs { namespace ct
 
 
 			GLint uniformType;
 			GLint uniformType;
 			glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_TYPE, &uniformType);
 			glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_TYPE, &uniformType);
+			BS_CHECK_GL_ERROR();
 
 
 			GpuParamObjectType samplerType = GPOT_UNKNOWN;
 			GpuParamObjectType samplerType = GPOT_UNKNOWN;
 			GpuParamObjectType textureType = GPOT_UNKNOWN;
 			GpuParamObjectType textureType = GPOT_UNKNOWN;
@@ -460,6 +474,8 @@ namespace bs { namespace ct
 
 
 				returnParamDesc.samplers.insert(std::make_pair(paramName, samplerParam));
 				returnParamDesc.samplers.insert(std::make_pair(paramName, samplerParam));
 				returnParamDesc.textures.insert(std::make_pair(paramName, textureParam));
 				returnParamDesc.textures.insert(std::make_pair(paramName, textureParam));
+
+				BS_CHECK_GL_ERROR();
 			}
 			}
 			else if (isImage)
 			else if (isImage)
 			{
 			{
@@ -470,6 +486,8 @@ namespace bs { namespace ct
 				textureParam.set = mapParameterToSet(type, ParamType::Image);
 				textureParam.set = mapParameterToSet(type, ParamType::Image);
 
 
 				returnParamDesc.loadStoreTextures.insert(std::make_pair(paramName, textureParam));
 				returnParamDesc.loadStoreTextures.insert(std::make_pair(paramName, textureParam));
+
+				BS_CHECK_GL_ERROR();
 			}
 			}
 			else if (isBuffer)
 			else if (isBuffer)
 			{
 			{
@@ -480,6 +498,8 @@ namespace bs { namespace ct
 				bufferParam.set = mapParameterToSet(type, ParamType::Texture);
 				bufferParam.set = mapParameterToSet(type, ParamType::Texture);
 
 
 				returnParamDesc.buffers.insert(std::make_pair(paramName, bufferParam));
 				returnParamDesc.buffers.insert(std::make_pair(paramName, bufferParam));
+
+				BS_CHECK_GL_ERROR();
 			}
 			}
 			else if(isRWBuffer)
 			else if(isRWBuffer)
 			{
 			{
@@ -490,6 +510,8 @@ namespace bs { namespace ct
 				bufferParam.set = mapParameterToSet(type, ParamType::Image);
 				bufferParam.set = mapParameterToSet(type, ParamType::Image);
 
 
 				returnParamDesc.buffers.insert(std::make_pair(paramName, bufferParam));
 				returnParamDesc.buffers.insert(std::make_pair(paramName, bufferParam));
+
+				BS_CHECK_GL_ERROR();
 			}
 			}
 			else
 			else
 			{
 			{
@@ -500,6 +522,7 @@ namespace bs { namespace ct
 
 
 				GLint blockIndex;
 				GLint blockIndex;
 				glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_BLOCK_INDEX, &blockIndex);
 				glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_BLOCK_INDEX, &blockIndex);
+				BS_CHECK_GL_ERROR();
 
 
 				GpuParamDataDesc gpuParam;
 				GpuParamDataDesc gpuParam;
 
 
@@ -514,6 +537,7 @@ namespace bs { namespace ct
 				{
 				{
 					GLint blockOffset;
 					GLint blockOffset;
 					glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_OFFSET, &blockOffset);
 					glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_OFFSET, &blockOffset);
+
 					blockOffset = blockOffset / 4;
 					blockOffset = blockOffset / 4;
 
 
 					gpuParam.gpuMemOffset = blockOffset;
 					gpuParam.gpuMemOffset = blockOffset;
@@ -525,6 +549,8 @@ namespace bs { namespace ct
 					gpuParam.paramBlockSet = mapParameterToSet(type, ParamType::UniformBlock);
 					gpuParam.paramBlockSet = mapParameterToSet(type, ParamType::UniformBlock);
 					gpuParam.cpuMemOffset = blockOffset;
 					gpuParam.cpuMemOffset = blockOffset;
 					curBlockDesc.blockSize = std::max(curBlockDesc.blockSize, gpuParam.cpuMemOffset + gpuParam.arrayElementStride * gpuParam.arraySize);
 					curBlockDesc.blockSize = std::max(curBlockDesc.blockSize, gpuParam.cpuMemOffset + gpuParam.arrayElementStride * gpuParam.arraySize);
+
+					BS_CHECK_GL_ERROR();
 				}
 				}
 				else
 				else
 				{
 				{
@@ -534,6 +560,8 @@ namespace bs { namespace ct
 					gpuParam.cpuMemOffset = globalBlockDesc.blockSize;
 					gpuParam.cpuMemOffset = globalBlockDesc.blockSize;
 
 
 					globalBlockDesc.blockSize = std::max(globalBlockDesc.blockSize, gpuParam.cpuMemOffset + gpuParam.arrayElementStride * gpuParam.arraySize);
 					globalBlockDesc.blockSize = std::max(globalBlockDesc.blockSize, gpuParam.cpuMemOffset + gpuParam.arrayElementStride * gpuParam.arraySize);
+
+					BS_CHECK_GL_ERROR();
 				}
 				}
 
 
 				// If parameter is not a part of a struct we're done
 				// If parameter is not a part of a struct we're done
@@ -605,6 +633,7 @@ namespace bs { namespace ct
 
 
 			GLint blockSize = 0;
 			GLint blockSize = 0;
 			glGetActiveUniformBlockiv(glProgram, blockIdx, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize);
 			glGetActiveUniformBlockiv(glProgram, blockIdx, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize);
+			BS_CHECK_GL_ERROR();
 
 
 			assert(blockSize % 4 == 0);
 			assert(blockSize % 4 == 0);
 			blockSize = blockSize / 4;
 			blockSize = blockSize / 4;
@@ -623,10 +652,12 @@ namespace bs { namespace ct
 	{
 	{
 		GLint arraySize;
 		GLint arraySize;
 		glGetActiveUniformsiv(programHandle, 1, &uniformIndex, GL_UNIFORM_SIZE, &arraySize);
 		glGetActiveUniformsiv(programHandle, 1, &uniformIndex, GL_UNIFORM_SIZE, &arraySize);
+		BS_CHECK_GL_ERROR();
 		desc.arraySize = arraySize;
 		desc.arraySize = arraySize;
 
 
 		GLint uniformType;
 		GLint uniformType;
 		glGetActiveUniformsiv(programHandle, 1, &uniformIndex, GL_UNIFORM_TYPE, &uniformType);
 		glGetActiveUniformsiv(programHandle, 1, &uniformIndex, GL_UNIFORM_TYPE, &uniformType);
+		BS_CHECK_GL_ERROR();
 
 
 		switch (uniformType)
 		switch (uniformType)
 		{
 		{
@@ -714,6 +745,7 @@ namespace bs { namespace ct
 		{
 		{
 			GLint arrayStride;
 			GLint arrayStride;
 			glGetActiveUniformsiv(programHandle, 1, &uniformIndex, GL_UNIFORM_ARRAY_STRIDE, &arrayStride);
 			glGetActiveUniformsiv(programHandle, 1, &uniformIndex, GL_UNIFORM_ARRAY_STRIDE, &arrayStride);
+			BS_CHECK_GL_ERROR();
 
 
 			if (arrayStride > 0)
 			if (arrayStride > 0)
 			{
 			{

+ 7 - 7
Source/BansheeGLRenderAPI/GLSL/BsGLSLProgramFactory.cpp

@@ -5,22 +5,22 @@
 
 
 namespace bs { namespace ct
 namespace bs { namespace ct
 {
 {
-    const String GLSLProgramFactory::LANGUAGE_NAME = "glsl";
+	const String GLSLProgramFactory::LANGUAGE_NAME = "glsl";
 
 
-    const String& GLSLProgramFactory::getLanguage() const
-    {
-        return LANGUAGE_NAME;
-    }
+	const String& GLSLProgramFactory::getLanguage() const
+	{
+		return LANGUAGE_NAME;
+	}
 
 
 	SPtr<GpuProgram> GLSLProgramFactory::create(const GPU_PROGRAM_DESC& desc, GpuDeviceFlags deviceMask)
 	SPtr<GpuProgram> GLSLProgramFactory::create(const GPU_PROGRAM_DESC& desc, GpuDeviceFlags deviceMask)
-    {
+	{
 		GLSLGpuProgram* prog = new (bs_alloc<GLSLGpuProgram>()) GLSLGpuProgram(desc, deviceMask);
 		GLSLGpuProgram* prog = new (bs_alloc<GLSLGpuProgram>()) GLSLGpuProgram(desc, deviceMask);
 
 
 		SPtr<GLSLGpuProgram> gpuProg = bs_shared_ptr<GLSLGpuProgram>(prog);
 		SPtr<GLSLGpuProgram> gpuProg = bs_shared_ptr<GLSLGpuProgram>(prog);
 		gpuProg->_setThisPtr(gpuProg);
 		gpuProg->_setThisPtr(gpuProg);
 
 
 		return gpuProg;
 		return gpuProg;
-    }
+	}
 
 
 	SPtr<GpuProgram> GLSLProgramFactory::create(GpuProgramType type, GpuDeviceFlags deviceMask)
 	SPtr<GpuProgram> GLSLProgramFactory::create(GpuProgramType type, GpuDeviceFlags deviceMask)
 	{
 	{

+ 4 - 4
Source/BansheeGLRenderAPI/GLSL/BsGLSLProgramFactory.h

@@ -12,9 +12,9 @@ namespace bs { namespace ct
 	 */
 	 */
 
 
 	/**	Factory class that deals with creating GLSL GPU programs. */
 	/**	Factory class that deals with creating GLSL GPU programs. */
-    class GLSLProgramFactory : public GpuProgramFactory
-    {
-    public:
+	class GLSLProgramFactory : public GpuProgramFactory
+	{
+	public:
 		/** @copydoc GpuProgramFactory::getLanguage */
 		/** @copydoc GpuProgramFactory::getLanguage */
 		const String& getLanguage() const override;
 		const String& getLanguage() const override;
 
 
@@ -26,7 +26,7 @@ namespace bs { namespace ct
 
 
 	protected:
 	protected:
 		static const String LANGUAGE_NAME;
 		static const String LANGUAGE_NAME;
-    };
+	};
 
 
 	/** @} */
 	/** @} */
 }}
 }}

+ 8 - 0
Source/BansheeGLRenderAPI/GLSL/BsGLSLProgramPipelineManager.cpp

@@ -31,6 +31,8 @@ namespace bs { namespace ct
 		for (auto& pipeline : mPipelines)
 		for (auto& pipeline : mPipelines)
 		{
 		{
 			glDeleteProgramPipelines(1, &pipeline.second.glHandle);
 			glDeleteProgramPipelines(1, &pipeline.second.glHandle);
+			BS_CHECK_GL_ERROR();
+
 			BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_PipelineObject);
 			BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_PipelineObject);
 		}
 		}
 	}
 	}
@@ -52,30 +54,36 @@ namespace bs { namespace ct
 			GLSLProgramPipeline newPipeline;
 			GLSLProgramPipeline newPipeline;
 
 
 			glGenProgramPipelines(1, &newPipeline.glHandle);
 			glGenProgramPipelines(1, &newPipeline.glHandle);
+			BS_CHECK_GL_ERROR();
 
 
 			if(vertexProgram != nullptr)
 			if(vertexProgram != nullptr)
 			{
 			{
 				glUseProgramStages(newPipeline.glHandle, GL_VERTEX_SHADER_BIT, vertexProgram->getGLHandle());
 				glUseProgramStages(newPipeline.glHandle, GL_VERTEX_SHADER_BIT, vertexProgram->getGLHandle());
+				BS_CHECK_GL_ERROR();
 			}
 			}
 
 
 			if(fragmentProgram != nullptr)
 			if(fragmentProgram != nullptr)
 			{
 			{
 				glUseProgramStages(newPipeline.glHandle, GL_FRAGMENT_SHADER_BIT, fragmentProgram->getGLHandle());
 				glUseProgramStages(newPipeline.glHandle, GL_FRAGMENT_SHADER_BIT, fragmentProgram->getGLHandle());
+				BS_CHECK_GL_ERROR();
 			}
 			}
 
 
 			if(geometryProgram != nullptr)
 			if(geometryProgram != nullptr)
 			{
 			{
 				glUseProgramStages(newPipeline.glHandle, GL_GEOMETRY_SHADER_BIT, geometryProgram->getGLHandle());
 				glUseProgramStages(newPipeline.glHandle, GL_GEOMETRY_SHADER_BIT, geometryProgram->getGLHandle());
+				BS_CHECK_GL_ERROR();
 			}
 			}
 
 
 			if(hullProgram != nullptr)
 			if(hullProgram != nullptr)
 			{
 			{
 				glUseProgramStages(newPipeline.glHandle, GL_TESS_CONTROL_SHADER_BIT, hullProgram->getGLHandle());
 				glUseProgramStages(newPipeline.glHandle, GL_TESS_CONTROL_SHADER_BIT, hullProgram->getGLHandle());
+				BS_CHECK_GL_ERROR();
 			}
 			}
 
 
 			if(domainProgram != nullptr)
 			if(domainProgram != nullptr)
 			{
 			{
 				glUseProgramStages(newPipeline.glHandle, GL_TESS_EVALUATION_SHADER_BIT, domainProgram->getGLHandle());
 				glUseProgramStages(newPipeline.glHandle, GL_TESS_EVALUATION_SHADER_BIT, domainProgram->getGLHandle());
+				BS_CHECK_GL_ERROR();
 			}
 			}
 
 
 			mPipelines[key] = newPipeline;
 			mPipelines[key] = newPipeline;

+ 7 - 3
Source/BansheeGLRenderAPI/Win32/BsWin32Context.cpp

@@ -22,19 +22,23 @@ namespace bs { namespace ct
 
 
 	void Win32Context::setCurrent(const RenderWindow& window)
 	void Win32Context::setCurrent(const RenderWindow& window)
 	{
 	{
-		wglMakeCurrent(mHDC, mGlrc);
+		if(wglMakeCurrent(mHDC, mGlrc) != TRUE)
+			BS_EXCEPT(RenderingAPIException, "wglMakeCurrent failed: " + translateWGLError());
 	}
 	}
 
 
 	void Win32Context::endCurrent()
 	void Win32Context::endCurrent()
 	{
 	{
-		wglMakeCurrent(0, 0);
+		if(wglMakeCurrent(0, 0) != TRUE)
+			BS_EXCEPT(RenderingAPIException, "wglMakeCurrent failed: " + translateWGLError());
 	}
 	}
 
 
 	void Win32Context::releaseContext()
 	void Win32Context::releaseContext()
 	{
 	{
 		if (mGlrc != 0)
 		if (mGlrc != 0)
 		{
 		{
-			wglDeleteContext(mGlrc);
+			if(wglDeleteContext(mGlrc) != TRUE)
+				BS_EXCEPT(RenderingAPIException, "wglDeleteContext failed: " + translateWGLError());
+
 			mGlrc = 0;
 			mGlrc = 0;
 			mHDC = 0;
 			mHDC = 0;
 		}
 		}

+ 3 - 3
Source/BansheeGLRenderAPI/Win32/BsWin32Context.h

@@ -33,9 +33,9 @@ namespace bs { namespace ct
 		void releaseContext() override;
 		void releaseContext() override;
 
 
 	protected:
 	protected:
-		HDC     mHDC;
-		HGLRC   mGlrc;
-		bool	mOwnsContext;
+		HDC mHDC;
+		HGLRC mGlrc;
+		bool mOwnsContext;
 	};
 	};
 
 
 	/** @} */
 	/** @} */

+ 39 - 31
Source/BansheeGLRenderAPI/Win32/BsWin32GLSupport.cpp

@@ -22,8 +22,8 @@ namespace bs { namespace ct
 	}
 	}
 
 
 	Win32GLSupport::Win32GLSupport()
 	Win32GLSupport::Win32GLSupport()
-		: mInitialWindow(nullptr), mHasPixelFormatARB(false), mHasMultisample(false), 
-		mHasHardwareGamma(false), mHasAdvancedContext(false)
+		: mInitialWindow(nullptr), mHasPixelFormatARB(false), mHasMultisample(false), mHasHardwareGamma(false)
+		, mHasAdvancedContext(false)
 	{
 	{
 		initialiseWGL();
 		initialiseWGL();
 	} 
 	} 
@@ -69,17 +69,17 @@ namespace bs { namespace ct
 		wglewContextInit(this);
 		wglewContextInit(this);
 
 
 		// Check for W32 specific extensions probe function
 		// Check for W32 specific extensions probe function
-		PFNWGLGETEXTENSIONSSTRINGARBPROC _wglGetExtensionsString = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsString");
+		auto _wglGetExtensionsString = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsString");
 		if(_wglGetExtensionsString == nullptr)
 		if(_wglGetExtensionsString == nullptr)
 			return;
 			return;
 
 
-		const char *wgl_extensions = _wglGetExtensionsString(mInitialWindow->_getHDC());
+		const char* wglExtensions = _wglGetExtensionsString(mInitialWindow->_getHDC());
 
 
 		// Parse them, and add them to the main list
 		// Parse them, and add them to the main list
 		StringStream ext;
 		StringStream ext;
-		String instr;
-		ext << wgl_extensions;
+		ext << wglExtensions;
 
 
+		String instr;
 		while (ext >> instr)
 		while (ext >> instr)
 			extensionList.insert(instr);
 			extensionList.insert(instr);
 	}
 	}
@@ -107,7 +107,7 @@ namespace bs { namespace ct
 					attribs[i++] = WGL_CONTEXT_PROFILE_MASK_ARB;
 					attribs[i++] = WGL_CONTEXT_PROFILE_MASK_ARB;
 					attribs[i++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
 					attribs[i++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
 
 
-#if BS_DEBUG_MODE
+#if (BS_DEBUG_MODE && (BS_OPENGL_4_3 || BS_OPENGLES_3_2))
 					attribs[i++] = WGL_CONTEXT_FLAGS_ARB;
 					attribs[i++] = WGL_CONTEXT_FLAGS_ARB;
 					attribs[i++] = WGL_CONTEXT_DEBUG_BIT_ARB;				
 					attribs[i++] = WGL_CONTEXT_DEBUG_BIT_ARB;				
 #endif
 #endif
@@ -139,9 +139,8 @@ namespace bs { namespace ct
 
 
 	void Win32GLSupport::initialiseWGL()
 	void Win32GLSupport::initialiseWGL()
 	{
 	{
-		// We need to create a dummy context in order to get functions
-		// that allow us to create a more advanced context. It seems
-		// hacky but that's the only way to do it.
+		// We need to create a dummy context in order to get functions that allow us to create a more advanced context. 
+		// It seems hacky but that's the only way to do it.
 		
 		
 		LPCSTR dummyText = "Dummy";
 		LPCSTR dummyText = "Dummy";
 #ifdef BS_STATIC_LIB
 #ifdef BS_STATIC_LIB
@@ -158,8 +157,18 @@ namespace bs { namespace ct
 		dummyClass.lpszClassName = dummyText;
 		dummyClass.lpszClassName = dummyText;
 		RegisterClass(&dummyClass);
 		RegisterClass(&dummyClass);
 
 
-		HWND hwnd = CreateWindow(dummyText, dummyText, WS_POPUP | WS_CLIPCHILDREN,
-			0, 0, 32, 32, 0, 0, hinst, 0);
+		HWND hwnd = CreateWindow(
+			dummyText, 
+			dummyText, 
+			WS_POPUP | WS_CLIPCHILDREN,
+			0, 
+			0, 
+			32, 
+			32, 
+			0, 
+			0, 
+			hinst, 
+			0);
 
 
 		if (hwnd == nullptr)
 		if (hwnd == nullptr)
 			BS_EXCEPT(RenderingAPIException, "CreateWindow() failed");
 			BS_EXCEPT(RenderingAPIException, "CreateWindow() failed");
@@ -184,14 +193,12 @@ namespace bs { namespace ct
 		{
 		{
 			HGLRC oldrc = wglGetCurrentContext();
 			HGLRC oldrc = wglGetCurrentContext();
 			HDC oldhdc = wglGetCurrentDC();
 			HDC oldhdc = wglGetCurrentDC();
-			// if wglMakeCurrent fails, wglGetProcAddress will return null
+
+			// If wglMakeCurrent fails, wglGetProcAddress will return null
 			wglMakeCurrent(hdc, hrc);
 			wglMakeCurrent(hdc, hrc);
 			
 			
-			PFNWGLGETEXTENSIONSSTRINGARBPROC _wglGetExtensionsStringARB =
-				(PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
-			
-			PFNWGLCREATECONTEXTATTRIBSARBPROC _wglCreateContextAttribsARB = 
-				(PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
+			auto _wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
+			auto _wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
 
 
 			if (_wglCreateContextAttribsARB != nullptr)
 			if (_wglCreateContextAttribsARB != nullptr)
 			{
 			{
@@ -235,7 +242,7 @@ namespace bs { namespace ct
 					(PFNWGLGETPIXELFORMATATTRIBIVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribivARB");
 					(PFNWGLGETPIXELFORMATATTRIBIVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribivARB");
 				if (WGLEW_GET_FUN(__wglewChoosePixelFormatARB)(hdc, iattr, 0, 256, formats, &count))
 				if (WGLEW_GET_FUN(__wglewChoosePixelFormatARB)(hdc, iattr, 0, 256, formats, &count))
 				{
 				{
-					// determine what multisampling levels are offered
+					// Determine what multisampling levels are offered
 					int query = WGL_SAMPLES_ARB, samples;
 					int query = WGL_SAMPLES_ARB, samples;
 					for (unsigned int i = 0; i < count; ++i)
 					for (unsigned int i = 0; i < count; ++i)
 					{
 					{
@@ -303,16 +310,14 @@ namespace bs { namespace ct
 			attribList.push_back(WGL_DEPTH_BITS_ARB); attribList.push_back(pfd.cDepthBits);
 			attribList.push_back(WGL_DEPTH_BITS_ARB); attribList.push_back(pfd.cDepthBits);
 			attribList.push_back(WGL_STENCIL_BITS_ARB); attribList.push_back(pfd.cStencilBits);
 			attribList.push_back(WGL_STENCIL_BITS_ARB); attribList.push_back(pfd.cStencilBits);
 			attribList.push_back(WGL_SAMPLES_ARB); attribList.push_back(multisample);
 			attribList.push_back(WGL_SAMPLES_ARB); attribList.push_back(multisample);
+
 			if (useHwGamma && checkExtension("WGL_EXT_framebuffer_sRGB"))
 			if (useHwGamma && checkExtension("WGL_EXT_framebuffer_sRGB"))
-			{
 				attribList.push_back(WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT); attribList.push_back(GL_TRUE);
 				attribList.push_back(WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT); attribList.push_back(GL_TRUE);
-			}
 
 
-			// terminator
-			attribList.push_back(0);
+			attribList.push_back(0); // Terminator
 
 
-			UINT nformats;
-			if (!WGLEW_GET_FUN(__wglewChoosePixelFormatARB)(hdc, &(attribList[0]), NULL, 1, &format, &nformats) || nformats <= 0)
+			UINT numFormats;
+			if (!WGLEW_GET_FUN(__wglewChoosePixelFormatARB)(hdc, &(attribList[0]), NULL, 1, &format, &numFormats) || numFormats <= 0)
 				return false;
 				return false;
 		}
 		}
 		else
 		else
@@ -320,7 +325,7 @@ namespace bs { namespace ct
 			format = ChoosePixelFormat(hdc, &pfd);
 			format = ChoosePixelFormat(hdc, &pfd);
 		}
 		}
 
 
-		return (format && SetPixelFormat(hdc, format, &pfd));
+		return format && SetPixelFormat(hdc, format, &pfd);
 	}
 	}
 
 
 	SPtr<VideoModeInfo> Win32GLSupport::getVideoModeInfo() const
 	SPtr<VideoModeInfo> Win32GLSupport::getVideoModeInfo() const
@@ -332,12 +337,15 @@ namespace bs { namespace ct
 	{
 	{
 		int winError = GetLastError();
 		int winError = GetLastError();
 		char errDesc[255];
 		char errDesc[255];
-		int i;
 
 
-		// Try windows errors first
-		i = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
-			NULL, winError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
-			(LPTSTR) errDesc, 255, NULL);
+		FormatMessage(
+			FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+			NULL, 
+			winError, 
+			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+			(LPTSTR) errDesc, 
+			255, 
+			NULL);
 
 
 		return String(errDesc);
 		return String(errDesc);
 	}
 	}

+ 7 - 7
Source/BansheeGLRenderAPI/Win32/BsWin32GLSupport.h

@@ -68,13 +68,13 @@ namespace bs { namespace ct
 		/**	Dummy window procedure used when creating the initial dummy OpenGL context. */
 		/**	Dummy window procedure used when creating the initial dummy OpenGL context. */
 		static LRESULT CALLBACK dummyWndProc(HWND hwnd, UINT umsg, WPARAM wp, LPARAM lp);
 		static LRESULT CALLBACK dummyWndProc(HWND hwnd, UINT umsg, WPARAM wp, LPARAM lp);
 
 
-		Vector<DEVMODE> mDevModes;
-		Win32RenderWindow *mInitialWindow;
-		Vector<int> mMultisampleLevels;
-		bool mHasPixelFormatARB;
-		bool mHasMultisample;
-		bool mHasHardwareGamma;
-		bool mHasAdvancedContext;
+		Vector<DEVMODE>    mDevModes;
+		Win32RenderWindow* mInitialWindow;
+		Vector<int>        mMultisampleLevels;
+		bool               mHasPixelFormatARB;
+		bool               mHasMultisample;
+		bool               mHasHardwareGamma;
+		bool               mHasAdvancedContext;
 	};
 	};
 
 
 	/** @} */
 	/** @} */

+ 2 - 2
Source/BansheeGLRenderAPI/Win32/BsWin32Prerequisites.h

@@ -11,8 +11,8 @@ namespace bs { namespace ct
 	 *  @{
 	 *  @{
 	 */
 	 */
 
 
-    class Win32GLSupport;
-    class Win32Context;
+	class Win32GLSupport;
+	class Win32Context;
 	class Win32RenderWindow;
 	class Win32RenderWindow;
 
 
 	/**	Retrieves last Windows API error and returns a description of it. */
 	/**	Retrieves last Windows API error and returns a description of it. */

+ 6 - 0
Source/BansheeGLRenderAPI/Win32/BsWin32RenderWindow.cpp

@@ -447,6 +447,7 @@ namespace bs
 	void Win32RenderWindow::setVSync(bool enabled, UINT32 interval)
 	void Win32RenderWindow::setVSync(bool enabled, UINT32 interval)
 	{
 	{
 		wglSwapIntervalEXT(interval);
 		wglSwapIntervalEXT(interval);
+		BS_CHECK_GL_ERROR();
 
 
 		mProperties.vsync = enabled;
 		mProperties.vsync = enabled;
 		mProperties.vsyncInterval = interval;
 		mProperties.vsyncInterval = interval;
@@ -496,14 +497,19 @@ namespace bs
 
 
 		// Must change the packing to ensure no overruns!
 		// Must change the packing to ensure no overruns!
 		glPixelStorei(GL_PACK_ALIGNMENT, 1);
 		glPixelStorei(GL_PACK_ALIGNMENT, 1);
+		BS_CHECK_GL_ERROR();
 
 
 		glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK);
 		glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK);
+		BS_CHECK_GL_ERROR();
+
 		glReadPixels((GLint)dst.getLeft(), (GLint)dst.getTop(),
 		glReadPixels((GLint)dst.getLeft(), (GLint)dst.getTop(),
 					 (GLsizei)dst.getWidth(), (GLsizei)dst.getHeight(),
 					 (GLsizei)dst.getWidth(), (GLsizei)dst.getHeight(),
 					 format, type, dst.getData());
 					 format, type, dst.getData());
+		BS_CHECK_GL_ERROR();
 
 
 		// restore default alignment
 		// restore default alignment
 		glPixelStorei(GL_PACK_ALIGNMENT, 4);
 		glPixelStorei(GL_PACK_ALIGNMENT, 4);
+		BS_CHECK_GL_ERROR();
 
 
 		//vertical flip
 		//vertical flip
 		{
 		{