diff --git a/data/shaders/fillrect.frag b/data/shaders/fillrect.frag
new file mode 100644
index 0000000000..629ed8f840
--- /dev/null
+++ b/data/shaders/fillrect.frag
@@ -0,0 +1,21 @@
+#version 330
+
+uniform ivec4 uClip;
+
+uniform int uFlags;
+uniform vec4 uColour;
+
+in ivec2 fPosition;
+
+layout (location = 0) out vec4 oColour;
+
+void main()
+{
+ if (fPosition.x < uClip.x || fPosition.x > uClip.z ||
+ fPosition.y < uClip.y || fPosition.y > uClip.w)
+ {
+ discard;
+ }
+
+ oColour = uColour;
+}
diff --git a/data/shaders/fillrect.vert b/data/shaders/fillrect.vert
new file mode 100644
index 0000000000..347c9ffd21
--- /dev/null
+++ b/data/shaders/fillrect.vert
@@ -0,0 +1,20 @@
+#version 330
+
+uniform ivec2 uScreenSize;
+
+in ivec2 vPosition;
+
+out ivec2 fPosition;
+
+void main()
+{
+ fPosition = vPosition;
+
+ // Transform screen coordinates to viewport
+ vec2 pos = vPosition;
+ pos.x = (pos.x * (2.0 / uScreenSize.x)) - 1.0;
+ pos.y = (pos.y * (2.0 / uScreenSize.y)) - 1.0;
+ pos.y *= -1;
+
+ gl_Position = vec4(pos, 0, 1);
+}
diff --git a/openrct2.vcxproj b/openrct2.vcxproj
index 7dbb67b984..57c0ba13e3 100644
--- a/openrct2.vcxproj
+++ b/openrct2.vcxproj
@@ -16,6 +16,8 @@
+
+
@@ -42,8 +44,10 @@
-
-
+
+
+
+
@@ -338,6 +342,10 @@
+
+
+
+
diff --git a/src/drawing/engines/opengl/FillRectShader.cpp b/src/drawing/engines/opengl/FillRectShader.cpp
new file mode 100644
index 0000000000..842f2bef83
--- /dev/null
+++ b/src/drawing/engines/opengl/FillRectShader.cpp
@@ -0,0 +1,87 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+ * For more information, visit https://github.com/OpenRCT2/OpenRCT2
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * A full copy of the GNU General Public License can be found in licence.txt
+ *****************************************************************************/
+#pragma endregion
+
+#ifndef DISABLE_OPENGL
+
+#include "FillRectShader.h"
+
+FillRectShader::FillRectShader() : OpenGLShaderProgram("fillrect")
+{
+ GetLocations();
+
+ glGenBuffers(1, &_vbo);
+ glGenVertexArrays(1, &_vao);
+
+ Use();
+ glVertexAttribPointer(vPosition, 2, GL_INT, GL_FALSE, 0, 0);
+ glEnableVertexAttribArray(vPosition);
+}
+
+FillRectShader::~FillRectShader()
+{
+ glDeleteBuffers(1, &_vbo);
+ glDeleteVertexArrays(1, &_vao);
+
+ glBindVertexArray(_vao);
+}
+
+void FillRectShader::GetLocations()
+{
+ uScreenSize = GetUniformLocation("uScreenSize");
+ uClip = GetUniformLocation("uClip");
+ uFlags = GetUniformLocation("uFlags");
+ uColour = GetUniformLocation("uColour");
+
+ vPosition = GetAttributeLocation("vPosition");
+}
+
+void FillRectShader::SetScreenSize(sint32 width, sint32 height)
+{
+ glUniform2i(uScreenSize, width, height);
+}
+
+void FillRectShader::SetClip(sint32 left, sint32 top, sint32 right, sint32 bottom)
+{
+ glUniform4i(uClip, left, top, right, bottom);
+}
+
+void FillRectShader::SetFlags(uint32 flags)
+{
+ glUniform1i(uFlags, flags);
+}
+
+void FillRectShader::SetColour(vec4f colour)
+{
+ glUniform4f(uColour, colour.r, colour.g, colour.b, colour.a);
+}
+
+void FillRectShader::Draw(sint32 left, sint32 top, sint32 right, sint32 bottom)
+{
+ vec2i vertices[] = {
+ { left, top },
+ { right, top },
+ { right, bottom },
+ { left, bottom },
+ };
+
+ glBindBuffer(GL_ARRAY_BUFFER, _vbo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STREAM_DRAW);
+
+ glBindVertexArray(_vao);
+ glDrawArrays(GL_QUADS, 0, 4);
+}
+
+#endif /* DISABLE_OPENGL */
diff --git a/src/drawing/engines/opengl/FillRectShader.h b/src/drawing/engines/opengl/FillRectShader.h
new file mode 100644
index 0000000000..0f82d8a68c
--- /dev/null
+++ b/src/drawing/engines/opengl/FillRectShader.h
@@ -0,0 +1,48 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+ * For more information, visit https://github.com/OpenRCT2/OpenRCT2
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * A full copy of the GNU General Public License can be found in licence.txt
+ *****************************************************************************/
+#pragma endregion
+
+#pragma once
+
+#include "GLSLTypes.h"
+#include "OpenGLShaderProgram.h"
+
+class FillRectShader : public OpenGLShaderProgram
+{
+private:
+ GLuint uScreenSize;
+ GLuint uClip;
+ GLuint uFlags;
+ GLuint uColour;
+
+ GLuint vPosition;
+
+ GLuint _vbo;
+ GLuint _vao;
+
+public:
+ FillRectShader();
+ ~FillRectShader() override;
+
+ void SetScreenSize(sint32 width, sint32 height);
+ void SetClip(sint32 left, sint32 top, sint32 right, sint32 bottom);
+ void SetFlags(uint32 flags);
+ void SetColour(vec4f colour);
+
+ void Draw(sint32 left, sint32 top, sint32 right, sint32 bottom);
+
+private:
+ void GetLocations();
+};
diff --git a/src/drawing/engines/opengl/GLSLTypes.h b/src/drawing/engines/opengl/GLSLTypes.h
new file mode 100644
index 0000000000..ac6b47db3d
--- /dev/null
+++ b/src/drawing/engines/opengl/GLSLTypes.h
@@ -0,0 +1,51 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+ * For more information, visit https://github.com/OpenRCT2/OpenRCT2
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * A full copy of the GNU General Public License can be found in licence.txt
+ *****************************************************************************/
+#pragma endregion
+
+#pragma once
+
+#include "../../../common.h"
+
+#pragma pack(push, 1)
+
+struct vec2i
+{
+ union { sint32 x; sint32 s; sint32 r; };
+ union { sint32 y; sint32 t; sint32 g; };
+};
+
+struct vec2f
+{
+ union { float x; float s; float r; };
+ union { float y; float t; float g; };
+};
+
+struct vec4i
+{
+ union { sint32 x; sint32 s; sint32 r; };
+ union { sint32 y; sint32 t; sint32 g; };
+ union { sint32 z; sint32 p; sint32 b; };
+ union { sint32 w; sint32 q; sint32 a; };
+};
+
+struct vec4f
+{
+ union { float x; float s; float r; };
+ union { float y; float t; float g; };
+ union { float z; float p; float b; };
+ union { float w; float q; float a; };
+};
+
+#pragma pack(pop)
diff --git a/src/drawing/engines/OpenGLAPI.cpp b/src/drawing/engines/opengl/OpenGLAPI.cpp
similarity index 71%
rename from src/drawing/engines/OpenGLAPI.cpp
rename to src/drawing/engines/opengl/OpenGLAPI.cpp
index 9be06343ce..8ff65f1e82 100644
--- a/src/drawing/engines/OpenGLAPI.cpp
+++ b/src/drawing/engines/opengl/OpenGLAPI.cpp
@@ -23,7 +23,7 @@
#include
-#include "../../core/Console.hpp"
+#include "../../../core/Console.hpp"
template
static inline bool SetProc(T * func, const char * name)
@@ -58,6 +58,7 @@ static const char * TryLoadAllProcAddresses()
SetupOpenGLFunction(glColor4f);
SetupOpenGLFunction(glDeleteTextures);
SetupOpenGLFunction(glDisable);
+ SetupOpenGLFunction(glDrawArrays);
SetupOpenGLFunction(glEnable);
SetupOpenGLFunction(glEnd);
SetupOpenGLFunction(glGenTextures);
@@ -73,8 +74,33 @@ static const char * TryLoadAllProcAddresses()
SetupOpenGLFunction(glViewport);
// 2.0+ functions
+ SetupOpenGLFunction(glAttachShader);
+ SetupOpenGLFunction(glBindBuffer);
+ SetupOpenGLFunction(glBindVertexArray);
+ SetupOpenGLFunction(glBufferData);
+ SetupOpenGLFunction(glCompileShader);
+ SetupOpenGLFunction(glCreateProgram);
SetupOpenGLFunction(glCreateShader);
+ SetupOpenGLFunction(glDeleteBuffers);
+ SetupOpenGLFunction(glDeleteProgram);
SetupOpenGLFunction(glDeleteShader);
+ SetupOpenGLFunction(glDeleteVertexArrays);
+ SetupOpenGLFunction(glDetachShader);
+ SetupOpenGLFunction(glEnableVertexAttribArray);
+ SetupOpenGLFunction(glGetAttribLocation);
+ SetupOpenGLFunction(glGenBuffers);
+ SetupOpenGLFunction(glGetShaderInfoLog);
+ SetupOpenGLFunction(glGetShaderiv);
+ SetupOpenGLFunction(glGetUniformLocation);
+ SetupOpenGLFunction(glGenVertexArrays);
+ SetupOpenGLFunction(glLinkProgram);
+ SetupOpenGLFunction(glShaderSource);
+ SetupOpenGLFunction(glUniform1i);
+ SetupOpenGLFunction(glUniform2i);
+ SetupOpenGLFunction(glUniform4f);
+ SetupOpenGLFunction(glUniform4i);
+ SetupOpenGLFunction(glUseProgram);
+ SetupOpenGLFunction(glVertexAttribPointer);
return nullptr;
}
diff --git a/src/drawing/engines/OpenGLAPI.h b/src/drawing/engines/opengl/OpenGLAPI.h
similarity index 51%
rename from src/drawing/engines/OpenGLAPI.h
rename to src/drawing/engines/opengl/OpenGLAPI.h
index 30191c7400..0fd692a352 100644
--- a/src/drawing/engines/OpenGLAPI.h
+++ b/src/drawing/engines/opengl/OpenGLAPI.h
@@ -28,6 +28,7 @@
#define glColor4f __static__glColor4f
#define glDeleteTextures __static__glDeleteTextures
#define glDisable __static__glDisable
+#define glDrawArrays __static__glDrawArrays
#define glEnable __static__glEnable
#define glEnd __static__glEnd
#define glGenTextures __static__glGenTextures
@@ -58,6 +59,7 @@
#undef glColor4f
#undef glDeleteTextures
#undef glDisable
+#undef glDrawArrays
#undef glEnable
#undef glEnd
#undef glGenTextures
@@ -82,6 +84,7 @@ typedef void (APIENTRYP PFNGLCOLOR3FPROC )(GLfloat red, GLfloat green, GLf
typedef void (APIENTRYP PFNGLCOLOR4FPROC )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
typedef void (APIENTRYP PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint *textures);
typedef void (APIENTRYP PFNGLDISABLEPROC )(GLenum cap);
+typedef void (APIENTRYP PFNGLDRAWARRAYSPROC )(GLenum mode, GLint first, GLsizei count);
typedef void (APIENTRYP PFNGLENABLEPROC )(GLenum cap);
typedef void (APIENTRYP PFNGLENDPROC )(void);
typedef void (APIENTRYP PFNGLGENTEXTURESPROC )(GLsizei n, GLuint *textures);
@@ -107,32 +110,58 @@ typedef void (APIENTRYP PFNGLVIEWPORTPROC )(GLint x, GLint y, GLsizei width
#endif
// 1.1 function pointers
-GLAPI_DECL PFNGLBEGINPROC glBegin GLAPI_SET;
-GLAPI_DECL PFNGLBINDTEXTUREPROC glBindTexture GLAPI_SET;
-GLAPI_DECL PFNGLBLENDFUNCPROC glBlendFunc GLAPI_SET;
-GLAPI_DECL PFNGLCLEARPROC glClear GLAPI_SET;
-GLAPI_DECL PFNGLCLEARCOLORPROC glClearColor GLAPI_SET;
-GLAPI_DECL PFNGLCOLOR3FPROC glColor3f GLAPI_SET;
-GLAPI_DECL PFNGLCOLOR4FPROC glColor4f GLAPI_SET;
-GLAPI_DECL PFNGLDELETETEXTURESPROC glDeleteTextures GLAPI_SET;
-GLAPI_DECL PFNGLDISABLEPROC glDisable GLAPI_SET;
-GLAPI_DECL PFNGLENABLEPROC glEnable GLAPI_SET;
-GLAPI_DECL PFNGLENDPROC glEnd GLAPI_SET;
-GLAPI_DECL PFNGLGENTEXTURESPROC glGenTextures GLAPI_SET;
-GLAPI_DECL PFNGLLOADIDENTITYPROC glLoadIdentity GLAPI_SET;
-GLAPI_DECL PFNGLMATRIXMODEPROC glMatrixMode GLAPI_SET;
-GLAPI_DECL PFNGLORTHOPROC glOrtho GLAPI_SET;
-GLAPI_DECL PFNGLSCALEFPROC glScalef GLAPI_SET;
-GLAPI_DECL PFNGLTEXCOORD2FPROC glTexCoord2f GLAPI_SET;
-GLAPI_DECL PFNGLTEXIMAGE2DPROC glTexImage2D GLAPI_SET;
-GLAPI_DECL PFNGLTEXPARAMETERIPROC glTexParameteri GLAPI_SET;
-GLAPI_DECL PFNGLTRANSLATEFPROC glTranslatef GLAPI_SET;
-GLAPI_DECL PFNGLVERTEX2IPROC glVertex2i GLAPI_SET;
-GLAPI_DECL PFNGLVIEWPORTPROC glViewport GLAPI_SET;
+GLAPI_DECL PFNGLBEGINPROC glBegin GLAPI_SET;
+GLAPI_DECL PFNGLBINDTEXTUREPROC glBindTexture GLAPI_SET;
+GLAPI_DECL PFNGLBLENDFUNCPROC glBlendFunc GLAPI_SET;
+GLAPI_DECL PFNGLCLEARPROC glClear GLAPI_SET;
+GLAPI_DECL PFNGLCLEARCOLORPROC glClearColor GLAPI_SET;
+GLAPI_DECL PFNGLCOLOR3FPROC glColor3f GLAPI_SET;
+GLAPI_DECL PFNGLCOLOR4FPROC glColor4f GLAPI_SET;
+GLAPI_DECL PFNGLDELETETEXTURESPROC glDeleteTextures GLAPI_SET;
+GLAPI_DECL PFNGLDISABLEPROC glDisable GLAPI_SET;
+GLAPI_DECL PFNGLDRAWARRAYSPROC glDrawArrays GLAPI_SET;
+GLAPI_DECL PFNGLENABLEPROC glEnable GLAPI_SET;
+GLAPI_DECL PFNGLENDPROC glEnd GLAPI_SET;
+GLAPI_DECL PFNGLGENTEXTURESPROC glGenTextures GLAPI_SET;
+GLAPI_DECL PFNGLLOADIDENTITYPROC glLoadIdentity GLAPI_SET;
+GLAPI_DECL PFNGLMATRIXMODEPROC glMatrixMode GLAPI_SET;
+GLAPI_DECL PFNGLORTHOPROC glOrtho GLAPI_SET;
+GLAPI_DECL PFNGLSCALEFPROC glScalef GLAPI_SET;
+GLAPI_DECL PFNGLTEXCOORD2FPROC glTexCoord2f GLAPI_SET;
+GLAPI_DECL PFNGLTEXIMAGE2DPROC glTexImage2D GLAPI_SET;
+GLAPI_DECL PFNGLTEXPARAMETERIPROC glTexParameteri GLAPI_SET;
+GLAPI_DECL PFNGLTRANSLATEFPROC glTranslatef GLAPI_SET;
+GLAPI_DECL PFNGLVERTEX2IPROC glVertex2i GLAPI_SET;
+GLAPI_DECL PFNGLVIEWPORTPROC glViewport GLAPI_SET;
// 2.0+ function pointers
-GLAPI_DECL PFNGLCREATESHADERPROC glCreateShader GLAPI_SET;
-GLAPI_DECL PFNGLDELETESHADERPROC glDeleteShader GLAPI_SET;
+GLAPI_DECL PFNGLATTACHSHADERPROC glAttachShader GLAPI_SET;
+GLAPI_DECL PFNGLBINDBUFFERPROC glBindBuffer GLAPI_SET;
+GLAPI_DECL PFNGLBINDVERTEXARRAYPROC glBindVertexArray GLAPI_SET;
+GLAPI_DECL PFNGLBUFFERDATAPROC glBufferData GLAPI_SET;
+GLAPI_DECL PFNGLCOMPILESHADERPROC glCompileShader GLAPI_SET;
+GLAPI_DECL PFNGLCREATEPROGRAMPROC glCreateProgram GLAPI_SET;
+GLAPI_DECL PFNGLCREATESHADERPROC glCreateShader GLAPI_SET;
+GLAPI_DECL PFNGLDELETEBUFFERSPROC glDeleteBuffers GLAPI_SET;
+GLAPI_DECL PFNGLDELETEPROGRAMPROC glDeleteProgram GLAPI_SET;
+GLAPI_DECL PFNGLDELETESHADERPROC glDeleteShader GLAPI_SET;
+GLAPI_DECL PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays GLAPI_SET;
+GLAPI_DECL PFNGLDETACHSHADERPROC glDetachShader GLAPI_SET;
+GLAPI_DECL PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray GLAPI_SET;
+GLAPI_DECL PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation GLAPI_SET;
+GLAPI_DECL PFNGLGENBUFFERSPROC glGenBuffers GLAPI_SET;
+GLAPI_DECL PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog GLAPI_SET;
+GLAPI_DECL PFNGLGETSHADERIVPROC glGetShaderiv GLAPI_SET;
+GLAPI_DECL PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation GLAPI_SET;
+GLAPI_DECL PFNGLGENVERTEXARRAYSPROC glGenVertexArrays GLAPI_SET;
+GLAPI_DECL PFNGLLINKPROGRAMPROC glLinkProgram GLAPI_SET;
+GLAPI_DECL PFNGLSHADERSOURCEPROC glShaderSource GLAPI_SET;
+GLAPI_DECL PFNGLUNIFORM1IPROC glUniform1i GLAPI_SET;
+GLAPI_DECL PFNGLUNIFORM2IPROC glUniform2i GLAPI_SET;
+GLAPI_DECL PFNGLUNIFORM4FPROC glUniform4f GLAPI_SET;
+GLAPI_DECL PFNGLUNIFORM4IPROC glUniform4i GLAPI_SET;
+GLAPI_DECL PFNGLUSEPROGRAMPROC glUseProgram GLAPI_SET;
+GLAPI_DECL PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer GLAPI_SET;
#endif /* OPENGL_NO_LINK */
diff --git a/src/drawing/engines/OpenGLDrawingEngine.cpp b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp
similarity index 95%
rename from src/drawing/engines/OpenGLDrawingEngine.cpp
rename to src/drawing/engines/opengl/OpenGLDrawingEngine.cpp
index 06781286b6..270fc2e8a9 100644
--- a/src/drawing/engines/OpenGLDrawingEngine.cpp
+++ b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp
@@ -16,7 +16,7 @@
#ifdef DISABLE_OPENGL
-#include "../IDrawingEngine.h"
+#include "../../IDrawingEngine.h"
IDrawingEngine * DrawingEngineFactory::CreateOpenGL()
{
@@ -29,45 +29,37 @@ IDrawingEngine * DrawingEngineFactory::CreateOpenGL()
#include
#include
+#include "GLSLTypes.h"
#include "OpenGLAPI.h"
+#include "FillRectShader.h"
-#include "../../core/Exception.hpp"
-#include "../../core/Math.hpp"
-#include "../../core/Memory.hpp"
-#include "../IDrawingContext.h"
-#include "../IDrawingEngine.h"
-#include "../Rain.h"
+#include "../../../core/Console.hpp"
+#include "../../../core/Exception.hpp"
+#include "../../../core/Math.hpp"
+#include "../../../core/Memory.hpp"
+#include "../../IDrawingContext.h"
+#include "../../IDrawingEngine.h"
+#include "../../Rain.h"
extern "C"
{
- #include "../../config.h"
- #include "../../interface/window.h"
- #include "../../intro.h"
- #include "../drawing.h"
+ #include "../../../config.h"
+ #include "../../../interface/window.h"
+ #include "../../../intro.h"
+ #include "../../drawing.h"
}
class OpenGLDrawingEngine;
-struct vec2f
-{
- union { float x; float s; float r; };
- union { float y; float t; float g; };
-};
-
-struct vec4f
-{
- union { float x; float s; float r; };
- union { float y; float t; float g; };
- union { float z; float p; float b; };
- union { float w; float q; float a; };
-};
-
class OpenGLDrawingContext : public IDrawingContext
{
private:
OpenGLDrawingEngine * _engine;
rct_drawpixelinfo * _dpi;
+ FillRectShader * _fillRectShader = nullptr;
+ GLuint _vbo;
+
sint32 _offsetX;
sint32 _offsetY;
sint32 _clipLeft;
@@ -84,6 +76,8 @@ public:
IDrawingEngine * GetEngine() override;
+ void Initialise();
+
void Clear(uint32 colour) override;
void FillRect(uint32 colour, sint32 x, sint32 y, sint32 w, sint32 h) override;
void DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32 x2, sint32 y2) override;
@@ -146,6 +140,8 @@ public:
throw Exception("Unable to initialise OpenGL.");
}
+ _drawingContext->Initialise();
+
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
@@ -310,7 +306,7 @@ OpenGLDrawingContext::OpenGLDrawingContext(OpenGLDrawingEngine * engine)
OpenGLDrawingContext::~OpenGLDrawingContext()
{
-
+ delete _fillRectShader;
}
IDrawingEngine * OpenGLDrawingContext::GetEngine()
@@ -318,6 +314,11 @@ IDrawingEngine * OpenGLDrawingContext::GetEngine()
return _engine;
}
+void OpenGLDrawingContext::Initialise()
+{
+ _fillRectShader = new FillRectShader();
+}
+
void OpenGLDrawingContext::Clear(uint32 colour)
{
FillRect(colour, _clipLeft, _clipTop, _clipRight, _clipBottom);
diff --git a/src/drawing/engines/opengl/OpenGLShaderProgram.cpp b/src/drawing/engines/opengl/OpenGLShaderProgram.cpp
new file mode 100644
index 0000000000..29b2720adf
--- /dev/null
+++ b/src/drawing/engines/opengl/OpenGLShaderProgram.cpp
@@ -0,0 +1,143 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+ * For more information, visit https://github.com/OpenRCT2/OpenRCT2
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * A full copy of the GNU General Public License can be found in licence.txt
+ *****************************************************************************/
+#pragma endregion
+
+#ifndef DISABLE_OPENGL
+
+#include "../../../core/Console.hpp"
+#include "../../../core/Exception.hpp"
+#include "../../../core/FileStream.hpp"
+#include "../../../core/Memory.hpp"
+#include "../../../core/Path.hpp"
+#include "../../../core/String.hpp"
+#include "OpenGLShaderProgram.h"
+
+extern "C"
+{
+ #include "../../../platform/platform.h"
+}
+
+OpenGLShader::OpenGLShader(const char * name, GLenum type)
+{
+ _type = type;
+
+ utf8 path[MAX_PATH];
+ GetPath(path, sizeof(path), name);
+ char * sourceCode = ReadSourceCode(path);
+
+ _id = glCreateShader(type);
+ glShaderSource(_id, 1, &sourceCode, nullptr);
+ glCompileShader(_id);
+
+ Memory::Free(sourceCode);
+
+ GLint status;
+ glGetShaderiv(_id, GL_COMPILE_STATUS, &status);
+ if (status != GL_TRUE)
+ {
+ char buffer[512];
+ glGetShaderInfoLog(_id, sizeof(buffer), nullptr, buffer);
+ glDeleteShader(_id);
+
+ Console::Error::WriteFormat("Error compiling %s\n", path);
+ Console::Error::WriteLine(buffer);
+
+ throw Exception("Error compiling shader.");
+ }
+}
+
+OpenGLShader::~OpenGLShader()
+{
+ glDeleteShader(_id);
+}
+
+GLuint OpenGLShader::GetShaderId()
+{
+ return _id;
+}
+
+void OpenGLShader::GetPath(char * buffer, size_t bufferSize, const char * name)
+{
+ platform_get_openrct_data_path(buffer);
+ Path::Append(buffer, bufferSize, "shaders");
+ Path::Append(buffer, bufferSize, name);
+ if (_type == GL_VERTEX_SHADER)
+ {
+ String::Append(buffer, bufferSize, ".vert");
+ }
+ else
+ {
+ String::Append(buffer, bufferSize, ".frag");
+ }
+}
+
+char * OpenGLShader::ReadSourceCode(const utf8 * path)
+{
+ auto fs = FileStream(path, FILE_MODE_OPEN);
+
+ uint64 fileLength = fs.GetLength();
+ if (fileLength > MaxSourceSize)
+ {
+ throw IOException("Shader source too large.");
+ }
+
+ utf8 * fileData = Memory::Allocate((size_t)fileLength + 1);
+ fs.Read(fileData, fileLength);
+ fileData[fileLength] = '\0';
+ return fileData;
+}
+
+OpenGLShaderProgram::OpenGLShaderProgram(const char * name)
+{
+ _vertexShader = new OpenGLShader(name, GL_VERTEX_SHADER);
+ _fragmentShader = new OpenGLShader(name, GL_FRAGMENT_SHADER);
+ _id = glCreateProgram();
+
+ glAttachShader(_id, _vertexShader->GetShaderId());
+ glAttachShader(_id, _fragmentShader->GetShaderId());
+ glLinkProgram(_id);
+}
+
+OpenGLShaderProgram::~OpenGLShaderProgram()
+{
+ if (_vertexShader != nullptr)
+ {
+ glDetachShader(_id, _vertexShader->GetShaderId());
+ delete _vertexShader;
+ }
+ if (_fragmentShader != nullptr)
+ {
+ glDetachShader(_id, _fragmentShader->GetShaderId());
+ delete _fragmentShader;
+ }
+ glDeleteProgram(_id);
+}
+
+GLuint OpenGLShaderProgram::GetAttributeLocation(const char * name)
+{
+ return glGetAttribLocation(_id, name);
+}
+
+GLuint OpenGLShaderProgram::GetUniformLocation(const char * name)
+{
+ return glGetUniformLocation(_id, name);
+}
+
+void OpenGLShaderProgram::Use()
+{
+ glUseProgram(_id);
+}
+
+#endif /* DISABLE_OPENGL */
diff --git a/src/drawing/engines/opengl/OpenGLShaderProgram.h b/src/drawing/engines/opengl/OpenGLShaderProgram.h
new file mode 100644
index 0000000000..2bdcf7a34a
--- /dev/null
+++ b/src/drawing/engines/opengl/OpenGLShaderProgram.h
@@ -0,0 +1,56 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+ * For more information, visit https://github.com/OpenRCT2/OpenRCT2
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * A full copy of the GNU General Public License can be found in licence.txt
+ *****************************************************************************/
+#pragma endregion
+
+#pragma once
+
+#include "../../../common.h"
+#include "OpenGLAPI.h"
+
+class OpenGLShader
+{
+private:
+ static constexpr uint64 MaxSourceSize = 8 * 1024 * 1024; // 8 MiB
+
+ GLenum _type;
+ GLuint _id = 0;
+
+public:
+ OpenGLShader(const char * name, GLenum type);
+ virtual ~OpenGLShader();
+
+ GLuint GetShaderId();
+
+private:
+ void GetPath(char * buffer, size_t bufferSize, const char * name);
+ static char * ReadSourceCode(const utf8 * path);
+};
+
+class OpenGLShaderProgram
+{
+private:
+ GLuint _id = 0;
+ OpenGLShader * _vertexShader = nullptr;
+ OpenGLShader * _fragmentShader = nullptr;
+
+public:
+ OpenGLShaderProgram(const char * name);
+ virtual ~OpenGLShaderProgram();
+
+ GLuint GetAttributeLocation(const char * name);
+ GLuint GetUniformLocation(const char * name);
+ void Use();
+};
+