From dc7b8b4d3b1843e44ea10603b85bc24438762e72 Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 6 Jun 2016 23:57:01 +0100 Subject: [PATCH] add initial shader code --- data/shaders/fillrect.frag | 21 +++ data/shaders/fillrect.vert | 20 +++ openrct2.vcxproj | 12 +- src/drawing/engines/opengl/FillRectShader.cpp | 87 +++++++++++ src/drawing/engines/opengl/FillRectShader.h | 48 ++++++ src/drawing/engines/opengl/GLSLTypes.h | 51 +++++++ .../engines/{ => opengl}/OpenGLAPI.cpp | 28 +++- src/drawing/engines/{ => opengl}/OpenGLAPI.h | 77 +++++++--- .../{ => opengl}/OpenGLDrawingEngine.cpp | 53 +++---- .../engines/opengl/OpenGLShaderProgram.cpp | 143 ++++++++++++++++++ .../engines/opengl/OpenGLShaderProgram.h | 56 +++++++ 11 files changed, 543 insertions(+), 53 deletions(-) create mode 100644 data/shaders/fillrect.frag create mode 100644 data/shaders/fillrect.vert create mode 100644 src/drawing/engines/opengl/FillRectShader.cpp create mode 100644 src/drawing/engines/opengl/FillRectShader.h create mode 100644 src/drawing/engines/opengl/GLSLTypes.h rename src/drawing/engines/{ => opengl}/OpenGLAPI.cpp (71%) rename src/drawing/engines/{ => opengl}/OpenGLAPI.h (51%) rename src/drawing/engines/{ => opengl}/OpenGLDrawingEngine.cpp (95%) create mode 100644 src/drawing/engines/opengl/OpenGLShaderProgram.cpp create mode 100644 src/drawing/engines/opengl/OpenGLShaderProgram.h 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(); +}; +