From dc7b8b4d3b1843e44ea10603b85bc24438762e72 Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 6 Jun 2016 23:57:01 +0100 Subject: [PATCH 01/27] 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(); +}; + From e7e92f02c12e7019b60ff7c3adc8bb94eb24b477 Mon Sep 17 00:00:00 2001 From: Ted John Date: Wed, 8 Jun 2016 18:28:32 +0100 Subject: [PATCH 02/27] re-enable OpenGL --- .travis.yml | 4 ---- OpenRCT2.xcodeproj/project.pbxproj | 6 +----- openrct2.vcxproj | 4 ++-- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index e16ccd2f44..2acf08e6f4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,10 +35,6 @@ matrix: env: OPENRCT2_CMAKE_OPTS="-DDISABLE_NETWORK=ON -DDISABLE_HTTP_TWITCH=ON" TARGET=docker32 services: - docker - - os: linux - env: OPENRCT2_CMAKE_OPTS="-DDISABLE_OPENGL=ON" TARGET=docker32 - services: - - docker - os: osx osx_image: xcode7.3 env: diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index e4cd72b85b..9cd2aaf596 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -2328,7 +2328,6 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", OPENGL_NO_LINK, - DISABLE_OPENGL ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -2371,10 +2370,7 @@ GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - OPENGL_NO_LINK, - DISABLE_OPENGL - ); + GCC_PREPROCESSOR_DEFINITIONS = OPENGL_NO_LINK; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; diff --git a/openrct2.vcxproj b/openrct2.vcxproj index 57c0ba13e3..e37fbba796 100644 --- a/openrct2.vcxproj +++ b/openrct2.vcxproj @@ -502,7 +502,7 @@ Level3 Disabled true - $(OpenRCT2_DEFINES);DEBUG;DISABLE_OPENGL;OPENGL_NO_LINK;_CRT_SECURE_NO_WARNINGS;_USE_MATH_DEFINES;CURL_STATICLIB;SDL_MAIN_HANDLED;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions) + $(OpenRCT2_DEFINES);DEBUG;OPENGL_NO_LINK;_CRT_SECURE_NO_WARNINGS;_USE_MATH_DEFINES;CURL_STATICLIB;SDL_MAIN_HANDLED;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions) MultiThreaded true $(IntDir)\%(RelativeDir) @@ -529,7 +529,7 @@ 4013 false - $(OpenRCT2_DEFINES);DISABLE_OPENGL;OPENGL_NO_LINK;_CRT_SECURE_NO_WARNINGS;_USE_MATH_DEFINES;CURL_STATICLIB;SDL_MAIN_HANDLED;%(PreprocessorDefinitions) + $(OpenRCT2_DEFINES);OPENGL_NO_LINK;_CRT_SECURE_NO_WARNINGS;_USE_MATH_DEFINES;CURL_STATICLIB;SDL_MAIN_HANDLED;%(PreprocessorDefinitions) $(IntDir)\%(RelativeDir) true Speed From c48031581b08aee5194ac507fad3b15f5e0d31ab Mon Sep 17 00:00:00 2001 From: Ted John Date: Wed, 8 Jun 2016 21:24:39 +0100 Subject: [PATCH 03/27] get the fillrect shader working --- data/shaders/fillrect.frag | 4 +- data/shaders/fillrect.vert | 6 +- src/drawing/engines/opengl/FillRectShader.cpp | 4 +- src/drawing/engines/opengl/OpenGLAPI.cpp | 6 +- src/drawing/engines/opengl/OpenGLAPI.h | 55 +++++++++++-------- .../engines/opengl/OpenGLDrawingEngine.cpp | 32 +++++++---- .../engines/opengl/OpenGLShaderProgram.cpp | 24 +++++++- .../engines/opengl/OpenGLShaderProgram.h | 3 + 8 files changed, 91 insertions(+), 43 deletions(-) diff --git a/data/shaders/fillrect.frag b/data/shaders/fillrect.frag index 629ed8f840..d61e07d719 100644 --- a/data/shaders/fillrect.frag +++ b/data/shaders/fillrect.frag @@ -5,7 +5,7 @@ uniform ivec4 uClip; uniform int uFlags; uniform vec4 uColour; -in ivec2 fPosition; +flat in ivec2 fPosition; layout (location = 0) out vec4 oColour; @@ -16,6 +16,6 @@ void main() { discard; } - + oColour = uColour; } diff --git a/data/shaders/fillrect.vert b/data/shaders/fillrect.vert index 347c9ffd21..1437b1ff59 100644 --- a/data/shaders/fillrect.vert +++ b/data/shaders/fillrect.vert @@ -4,17 +4,17 @@ uniform ivec2 uScreenSize; in ivec2 vPosition; -out ivec2 fPosition; +flat out ivec2 fPosition; void main() { fPosition = vPosition; // Transform screen coordinates to viewport - vec2 pos = vPosition; + vec2 pos = vec2(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); + gl_Position = vec4(pos, 0.0, 1.0); } diff --git a/src/drawing/engines/opengl/FillRectShader.cpp b/src/drawing/engines/opengl/FillRectShader.cpp index 842f2bef83..4eee172f90 100644 --- a/src/drawing/engines/opengl/FillRectShader.cpp +++ b/src/drawing/engines/opengl/FillRectShader.cpp @@ -26,8 +26,10 @@ FillRectShader::FillRectShader() : OpenGLShaderProgram("fillrect") glGenVertexArrays(1, &_vao); Use(); - glVertexAttribPointer(vPosition, 2, GL_INT, GL_FALSE, 0, 0); + glBindBuffer(GL_ARRAY_BUFFER, _vbo); + glBindVertexArray(_vao); glEnableVertexAttribArray(vPosition); + glVertexAttribIPointer(vPosition, 2, GL_INT, 0, 0); } FillRectShader::~FillRectShader() diff --git a/src/drawing/engines/opengl/OpenGLAPI.cpp b/src/drawing/engines/opengl/OpenGLAPI.cpp index 8ff65f1e82..cedc4613e1 100644 --- a/src/drawing/engines/opengl/OpenGLAPI.cpp +++ b/src/drawing/engines/opengl/OpenGLAPI.cpp @@ -62,6 +62,7 @@ static const char * TryLoadAllProcAddresses() SetupOpenGLFunction(glEnable); SetupOpenGLFunction(glEnd); SetupOpenGLFunction(glGenTextures); + SetupOpenGLFunction(glGetError); SetupOpenGLFunction(glLoadIdentity); SetupOpenGLFunction(glMatrixMode); SetupOpenGLFunction(glOrtho); @@ -76,6 +77,7 @@ static const char * TryLoadAllProcAddresses() // 2.0+ functions SetupOpenGLFunction(glAttachShader); SetupOpenGLFunction(glBindBuffer); + SetupOpenGLFunction(glBindFragDataLocation); SetupOpenGLFunction(glBindVertexArray); SetupOpenGLFunction(glBufferData); SetupOpenGLFunction(glCompileShader); @@ -89,6 +91,8 @@ static const char * TryLoadAllProcAddresses() SetupOpenGLFunction(glEnableVertexAttribArray); SetupOpenGLFunction(glGetAttribLocation); SetupOpenGLFunction(glGenBuffers); + SetupOpenGLFunction(glGetProgramInfoLog); + SetupOpenGLFunction(glGetProgramiv); SetupOpenGLFunction(glGetShaderInfoLog); SetupOpenGLFunction(glGetShaderiv); SetupOpenGLFunction(glGetUniformLocation); @@ -100,7 +104,7 @@ static const char * TryLoadAllProcAddresses() SetupOpenGLFunction(glUniform4f); SetupOpenGLFunction(glUniform4i); SetupOpenGLFunction(glUseProgram); - SetupOpenGLFunction(glVertexAttribPointer); + SetupOpenGLFunction(glVertexAttribIPointer); return nullptr; } diff --git a/src/drawing/engines/opengl/OpenGLAPI.h b/src/drawing/engines/opengl/OpenGLAPI.h index 0fd692a352..9fe5ea7c67 100644 --- a/src/drawing/engines/opengl/OpenGLAPI.h +++ b/src/drawing/engines/opengl/OpenGLAPI.h @@ -32,6 +32,7 @@ #define glEnable __static__glEnable #define glEnd __static__glEnd #define glGenTextures __static__glGenTextures +#define glGetError __static__glGetError #define glLoadIdentity __static__glLoadIdentity #define glMatrixMode __static__glMatrixMode #define glOrtho __static__glOrtho @@ -63,6 +64,7 @@ #undef glEnable #undef glEnd #undef glGenTextures +#undef glGetError #undef glLoadIdentity #undef glMatrixMode #undef glOrtho @@ -75,29 +77,30 @@ #undef glViewport // 1.1 function signatures -typedef void (APIENTRYP PFNGLBEGINPROC )(GLenum mode); -typedef void (APIENTRYP PFNGLBINDTEXTUREPROC )(GLenum target, GLuint texture); -typedef void (APIENTRYP PFNGLBLENDFUNCPROC )(GLenum sfactor, GLenum dfactor); -typedef void (APIENTRYP PFNGLCLEARPROC )(GLbitfield mask); -typedef void (APIENTRYP PFNGLCLEARCOLORPROC )(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); -typedef void (APIENTRYP PFNGLCOLOR3FPROC )(GLfloat red, GLfloat green, GLfloat blue); -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); -typedef void (APIENTRYP PFNGLLOADIDENTITYPROC )(void); -typedef void (APIENTRYP PFNGLMATRIXMODEPROC )(GLenum mode); -typedef void (APIENTRYP PFNGLORTHOPROC )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val); -typedef void (APIENTRYP PFNGLSCALEFPROC )(GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FPROC )(GLfloat s, GLfloat t); -typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC )(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC )(GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLTRANSLATEFPROC )(GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLVERTEX2IPROC )(GLint x, GLint y); -typedef void (APIENTRYP PFNGLVIEWPORTPROC )(GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLBEGINPROC )(GLenum mode); +typedef void (APIENTRYP PFNGLBINDTEXTUREPROC )(GLenum target, GLuint texture); +typedef void (APIENTRYP PFNGLBLENDFUNCPROC )(GLenum sfactor, GLenum dfactor); +typedef void (APIENTRYP PFNGLCLEARPROC )(GLbitfield mask); +typedef void (APIENTRYP PFNGLCLEARCOLORPROC )(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +typedef void (APIENTRYP PFNGLCOLOR3FPROC )(GLfloat red, GLfloat green, GLfloat blue); +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 GLenum (APIENTRYP PFNGLGETERRORPROC )(void); +typedef void (APIENTRYP PFNGLGENTEXTURESPROC )(GLsizei n, GLuint *textures); +typedef void (APIENTRYP PFNGLLOADIDENTITYPROC )(void); +typedef void (APIENTRYP PFNGLMATRIXMODEPROC )(GLenum mode); +typedef void (APIENTRYP PFNGLORTHOPROC )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val); +typedef void (APIENTRYP PFNGLSCALEFPROC )(GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FPROC )(GLfloat s, GLfloat t); +typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC )(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC )(GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLTRANSLATEFPROC )(GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEX2IPROC )(GLint x, GLint y); +typedef void (APIENTRYP PFNGLVIEWPORTPROC )(GLint x, GLint y, GLsizei width, GLsizei height); #ifdef NO_EXTERN_GLAPI // Defines the function pointers @@ -137,6 +140,7 @@ GLAPI_DECL PFNGLVIEWPORTPROC glViewport GLAP // 2.0+ function pointers GLAPI_DECL PFNGLATTACHSHADERPROC glAttachShader GLAPI_SET; GLAPI_DECL PFNGLBINDBUFFERPROC glBindBuffer GLAPI_SET; +GLAPI_DECL PFNGLBINDFRAGDATALOCATIONPROC glBindFragDataLocation GLAPI_SET; GLAPI_DECL PFNGLBINDVERTEXARRAYPROC glBindVertexArray GLAPI_SET; GLAPI_DECL PFNGLBUFFERDATAPROC glBufferData GLAPI_SET; GLAPI_DECL PFNGLCOMPILESHADERPROC glCompileShader GLAPI_SET; @@ -150,6 +154,9 @@ GLAPI_DECL PFNGLDETACHSHADERPROC glDetachShader GLAP GLAPI_DECL PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray GLAPI_SET; GLAPI_DECL PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation GLAPI_SET; GLAPI_DECL PFNGLGENBUFFERSPROC glGenBuffers GLAPI_SET; +GLAPI_DECL PFNGLGETERRORPROC glGetError GLAPI_SET; +GLAPI_DECL PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog GLAPI_SET; +GLAPI_DECL PFNGLGETPROGRAMIVPROC glGetProgramiv GLAPI_SET; GLAPI_DECL PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog GLAPI_SET; GLAPI_DECL PFNGLGETSHADERIVPROC glGetShaderiv GLAPI_SET; GLAPI_DECL PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation GLAPI_SET; @@ -161,7 +168,7 @@ GLAPI_DECL PFNGLUNIFORM2IPROC glUniform2i GLAP GLAPI_DECL PFNGLUNIFORM4FPROC glUniform4f GLAPI_SET; GLAPI_DECL PFNGLUNIFORM4IPROC glUniform4i GLAPI_SET; GLAPI_DECL PFNGLUSEPROGRAMPROC glUseProgram GLAPI_SET; -GLAPI_DECL PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer GLAPI_SET; +GLAPI_DECL PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer GLAPI_SET; #endif /* OPENGL_NO_LINK */ diff --git a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp index 270fc2e8a9..d5e5c8fe9d 100644 --- a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -142,8 +142,8 @@ public: _drawingContext->Initialise(); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + // glEnable(GL_BLEND); + // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } void Resize(uint32 width, uint32 height) override @@ -175,15 +175,15 @@ public: glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); - glMatrixMode(GL_PROJECTION_MATRIX); - glLoadIdentity(); - glOrtho(0, _width, _height, 0, -1.0, 1.0); + // glMatrixMode(GL_PROJECTION_MATRIX); + // glLoadIdentity(); + // glOrtho(0, _width, _height, 0, -1.0, 1.0); - glMatrixMode(GL_MODELVIEW_MATRIX); - glLoadIdentity(); - glScalef(1, -1.0f, 0); - glTranslatef(-1.0f, -1.0f, 0); - glScalef(2.0f / _width, 2.0f / _height, 0); + // glMatrixMode(GL_MODELVIEW_MATRIX); + // glLoadIdentity(); + // glScalef(1, -1.0f, 0); + // glTranslatef(-1.0f, -1.0f, 0); + // glScalef(2.0f / _width, 2.0f / _height, 0); if (gIntroState != INTRO_STATE_NONE) { intro_draw(&_bitsDPI); @@ -328,6 +328,14 @@ void OpenGLDrawingContext::FillRect(uint32 colour, sint32 left, sint32 top, sint { vec4f paletteColour = _engine->GLPalette[colour & 0xFF]; + _fillRectShader->Use(); + _fillRectShader->SetScreenSize(gScreenWidth, gScreenHeight); + _fillRectShader->SetColour(paletteColour); + _fillRectShader->SetClip(_clipLeft, _clipTop, _clipRight, _clipBottom); + _fillRectShader->Draw(left, top, right, bottom); + + return; + if (left > right) { left ^= right; @@ -377,6 +385,8 @@ void OpenGLDrawingContext::FillRect(uint32 colour, sint32 left, sint32 top, sint void OpenGLDrawingContext::DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32 x2, sint32 y2) { + return; + vec4f paletteColour = _engine->GLPalette[colour & 0xFF]; glColor3f(paletteColour.r, paletteColour.g, paletteColour.b); glBegin(GL_LINES); @@ -387,6 +397,8 @@ void OpenGLDrawingContext::DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32 void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 tertiaryColour) { + return; + int g1Id = image & 0x7FFFF; rct_g1_element * g1Element = gfx_get_g1_element(g1Id); diff --git a/src/drawing/engines/opengl/OpenGLShaderProgram.cpp b/src/drawing/engines/opengl/OpenGLShaderProgram.cpp index 29b2720adf..f51dc5beda 100644 --- a/src/drawing/engines/opengl/OpenGLShaderProgram.cpp +++ b/src/drawing/engines/opengl/OpenGLShaderProgram.cpp @@ -103,11 +103,22 @@ OpenGLShaderProgram::OpenGLShaderProgram(const char * name) { _vertexShader = new OpenGLShader(name, GL_VERTEX_SHADER); _fragmentShader = new OpenGLShader(name, GL_FRAGMENT_SHADER); - _id = glCreateProgram(); + _id = glCreateProgram(); glAttachShader(_id, _vertexShader->GetShaderId()); glAttachShader(_id, _fragmentShader->GetShaderId()); - glLinkProgram(_id); + + if (!Link()) + { + char buffer[512]; + GLsizei length; + glGetProgramInfoLog(_id, sizeof(buffer), &length, buffer); + + Console::Error::WriteFormat("Error linking %s\n", name); + Console::Error::WriteLine(buffer); + + throw Exception("Failed to link OpenGL shader."); + } } OpenGLShaderProgram::~OpenGLShaderProgram() @@ -140,4 +151,13 @@ void OpenGLShaderProgram::Use() glUseProgram(_id); } +bool OpenGLShaderProgram::Link() +{ + glLinkProgram(_id); + + GLint linkStatus; + glGetProgramiv(_id, GL_LINK_STATUS, &linkStatus); + return linkStatus == GL_TRUE; +} + #endif /* DISABLE_OPENGL */ diff --git a/src/drawing/engines/opengl/OpenGLShaderProgram.h b/src/drawing/engines/opengl/OpenGLShaderProgram.h index 2bdcf7a34a..e2a19ac8f2 100644 --- a/src/drawing/engines/opengl/OpenGLShaderProgram.h +++ b/src/drawing/engines/opengl/OpenGLShaderProgram.h @@ -52,5 +52,8 @@ public: GLuint GetAttributeLocation(const char * name); GLuint GetUniformLocation(const char * name); void Use(); + +private: + bool Link(); }; From a9d49838fa1fffbe4d87b67aee370fdecc123111 Mon Sep 17 00:00:00 2001 From: Ted John Date: Wed, 8 Jun 2016 22:05:20 +0100 Subject: [PATCH 04/27] add cross pattern support for fillrect shader --- data/shaders/fillrect.frag | 16 +++-- data/shaders/fillrect.vert | 4 +- src/drawing/engines/opengl/FillRectShader.cpp | 7 +- src/drawing/engines/opengl/FillRectShader.h | 4 +- .../engines/opengl/OpenGLDrawingEngine.cpp | 67 ++++--------------- 5 files changed, 34 insertions(+), 64 deletions(-) diff --git a/data/shaders/fillrect.frag b/data/shaders/fillrect.frag index d61e07d719..5f25f15eb7 100644 --- a/data/shaders/fillrect.frag +++ b/data/shaders/fillrect.frag @@ -3,9 +3,9 @@ uniform ivec4 uClip; uniform int uFlags; -uniform vec4 uColour; +uniform vec4 uColour[2]; -flat in ivec2 fPosition; +in vec2 fPosition; layout (location = 0) out vec4 oColour; @@ -16,6 +16,14 @@ void main() { discard; } - - oColour = uColour; + + int posSum = int(fPosition.x) + int(fPosition.y); + if ((posSum % 2) == 0) + { + oColour = uColour[0]; + } + else + { + oColour = uColour[1]; + } } diff --git a/data/shaders/fillrect.vert b/data/shaders/fillrect.vert index 1437b1ff59..997f383fc5 100644 --- a/data/shaders/fillrect.vert +++ b/data/shaders/fillrect.vert @@ -4,14 +4,14 @@ uniform ivec2 uScreenSize; in ivec2 vPosition; -flat out ivec2 fPosition; +out vec2 fPosition; void main() { fPosition = vPosition; // Transform screen coordinates to viewport - vec2 pos = vec2(vPosition); + 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; diff --git a/src/drawing/engines/opengl/FillRectShader.cpp b/src/drawing/engines/opengl/FillRectShader.cpp index 4eee172f90..20828af765 100644 --- a/src/drawing/engines/opengl/FillRectShader.cpp +++ b/src/drawing/engines/opengl/FillRectShader.cpp @@ -45,7 +45,8 @@ void FillRectShader::GetLocations() uScreenSize = GetUniformLocation("uScreenSize"); uClip = GetUniformLocation("uClip"); uFlags = GetUniformLocation("uFlags"); - uColour = GetUniformLocation("uColour"); + uColour[0] = GetUniformLocation("uColour[0]"); + uColour[1] = GetUniformLocation("uColour[1]"); vPosition = GetAttributeLocation("vPosition"); } @@ -65,9 +66,9 @@ void FillRectShader::SetFlags(uint32 flags) glUniform1i(uFlags, flags); } -void FillRectShader::SetColour(vec4f colour) +void FillRectShader::SetColour(int index, vec4f colour) { - glUniform4f(uColour, colour.r, colour.g, colour.b, colour.a); + glUniform4f(uColour[index], colour.r, colour.g, colour.b, colour.a); } void FillRectShader::Draw(sint32 left, sint32 top, sint32 right, sint32 bottom) diff --git a/src/drawing/engines/opengl/FillRectShader.h b/src/drawing/engines/opengl/FillRectShader.h index 0f82d8a68c..2d99ba6d71 100644 --- a/src/drawing/engines/opengl/FillRectShader.h +++ b/src/drawing/engines/opengl/FillRectShader.h @@ -25,7 +25,7 @@ private: GLuint uScreenSize; GLuint uClip; GLuint uFlags; - GLuint uColour; + GLuint uColour[2]; GLuint vPosition; @@ -39,7 +39,7 @@ public: 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 SetColour(int index, vec4f colour); void Draw(sint32 left, sint32 top, sint32 right, sint32 bottom); diff --git a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp index d5e5c8fe9d..314d69ab4f 100644 --- a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -142,8 +142,8 @@ public: _drawingContext->Initialise(); - // glEnable(GL_BLEND); - // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } void Resize(uint32 width, uint32 height) override @@ -158,6 +158,8 @@ public: for (int i = 0; i < 256; i++) { SDL_Color colour = palette[i]; + colour.a = 255; + Palette[i] = colour; GLPalette[i] = { colour.r / 255.0f, colour.g / 255.0f, @@ -326,61 +328,20 @@ void OpenGLDrawingContext::Clear(uint32 colour) void OpenGLDrawingContext::FillRect(uint32 colour, sint32 left, sint32 top, sint32 right, sint32 bottom) { - vec4f paletteColour = _engine->GLPalette[colour & 0xFF]; + vec4f paletteColour[2]; + paletteColour[0] = _engine->GLPalette[(colour >> 0) & 0xFF]; + paletteColour[1] = paletteColour[0]; + if (colour & 0x1000000) + { + paletteColour[1].a = 0; + } _fillRectShader->Use(); _fillRectShader->SetScreenSize(gScreenWidth, gScreenHeight); - _fillRectShader->SetColour(paletteColour); + _fillRectShader->SetColour(0, paletteColour[0]); + _fillRectShader->SetColour(1, paletteColour[1]); _fillRectShader->SetClip(_clipLeft, _clipTop, _clipRight, _clipBottom); - _fillRectShader->Draw(left, top, right, bottom); - - return; - - if (left > right) - { - left ^= right; - right ^= left; - left ^= right; - } - if (top > bottom) - { - top ^= bottom; - bottom ^= top; - top ^= bottom; - } - - left += _offsetX; - top += _offsetY; - right += _offsetX; - bottom += _offsetY; - - left = Math::Max(left, _clipLeft); - top = Math::Max(top, _clipTop); - right = Math::Min(right, _clipRight); - bottom = Math::Min(bottom, _clipBottom); - - if (right < left || bottom < top) - { - return; - } - - glDisable(GL_TEXTURE_2D); - - if (colour & 0x2000000) - { - glColor4f(paletteColour.r, paletteColour.g, paletteColour.b, 0.4f); - } - else - { - glColor3f(paletteColour.r, paletteColour.g, paletteColour.b); - } - - glBegin(GL_QUADS); - glVertex2i(left, top); - glVertex2i(left, bottom + 1); - glVertex2i(right + 1, bottom + 1); - glVertex2i(right + 1, top); - glEnd(); + _fillRectShader->Draw(left, top, right + 1, bottom + 1); } void OpenGLDrawingContext::DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32 x2, sint32 y2) From 808afe0a81c00f2b2c11830c188018b290ea4a37 Mon Sep 17 00:00:00 2001 From: Ted John Date: Wed, 8 Jun 2016 23:13:49 +0100 Subject: [PATCH 05/27] add drawimage shader and optimise --- data/shaders/drawimage.frag | 20 +++ data/shaders/drawimage.vert | 41 +++++++ data/shaders/fillrect.frag | 1 - data/shaders/fillrect.vert | 22 +++- openrct2.vcxproj | 4 + .../engines/opengl/DrawImageShader.cpp | 85 +++++++++++++ src/drawing/engines/opengl/DrawImageShader.h | 48 ++++++++ src/drawing/engines/opengl/FillRectShader.cpp | 26 ++-- src/drawing/engines/opengl/FillRectShader.h | 4 +- src/drawing/engines/opengl/OpenGLAPI.cpp | 2 + src/drawing/engines/opengl/OpenGLAPI.h | 6 +- .../engines/opengl/OpenGLDrawingEngine.cpp | 114 +++++++++--------- 12 files changed, 299 insertions(+), 74 deletions(-) create mode 100644 data/shaders/drawimage.frag create mode 100644 data/shaders/drawimage.vert create mode 100644 src/drawing/engines/opengl/DrawImageShader.cpp create mode 100644 src/drawing/engines/opengl/DrawImageShader.h diff --git a/data/shaders/drawimage.frag b/data/shaders/drawimage.frag new file mode 100644 index 0000000000..7e6fb568f3 --- /dev/null +++ b/data/shaders/drawimage.frag @@ -0,0 +1,20 @@ +#version 330 + +uniform ivec4 uClip; +uniform sampler2D uTexture; + +in vec2 fPosition; +in vec2 fTextureCoordinate; + +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 = texture(uTexture, fTextureCoordinate); +} diff --git a/data/shaders/drawimage.vert b/data/shaders/drawimage.vert new file mode 100644 index 0000000000..4cd77cc1bc --- /dev/null +++ b/data/shaders/drawimage.vert @@ -0,0 +1,41 @@ +#version 330 + +uniform ivec2 uScreenSize; +uniform ivec4 uBounds; + +in int vIndex; + +out vec2 fPosition; +out vec2 fTextureCoordinate; + +void main() +{ + vec2 pos; + switch (vIndex) { + case 0: + pos = uBounds.xy; + fTextureCoordinate = vec2(0, 0); + break; + case 1: + pos = uBounds.zy; + fTextureCoordinate = vec2(1, 0); + break; + case 2: + pos = uBounds.zw; + fTextureCoordinate = vec2(1, 1); + break; + case 3: + pos = uBounds.xw; + fTextureCoordinate = vec2(0, 1); + break; + } + + fPosition = pos; + + // Transform screen coordinates to viewport + 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.0, 1.0); +} diff --git a/data/shaders/fillrect.frag b/data/shaders/fillrect.frag index 5f25f15eb7..c233dfb009 100644 --- a/data/shaders/fillrect.frag +++ b/data/shaders/fillrect.frag @@ -1,7 +1,6 @@ #version 330 uniform ivec4 uClip; - uniform int uFlags; uniform vec4 uColour[2]; diff --git a/data/shaders/fillrect.vert b/data/shaders/fillrect.vert index 997f383fc5..066225c359 100644 --- a/data/shaders/fillrect.vert +++ b/data/shaders/fillrect.vert @@ -1,17 +1,33 @@ #version 330 uniform ivec2 uScreenSize; +uniform ivec4 uBounds; -in ivec2 vPosition; +in int vIndex; out vec2 fPosition; void main() { - fPosition = vPosition; + vec2 pos; + switch (vIndex) { + case 0: + pos = uBounds.xy; + break; + case 1: + pos = uBounds.zy; + break; + case 2: + pos = uBounds.zw; + break; + case 3: + pos = uBounds.xw; + break; + } + + fPosition = pos; // 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; diff --git a/openrct2.vcxproj b/openrct2.vcxproj index e37fbba796..0851f2a1f6 100644 --- a/openrct2.vcxproj +++ b/openrct2.vcxproj @@ -16,6 +16,8 @@ + + @@ -44,6 +46,7 @@ + @@ -342,6 +345,7 @@ + diff --git a/src/drawing/engines/opengl/DrawImageShader.cpp b/src/drawing/engines/opengl/DrawImageShader.cpp new file mode 100644 index 0000000000..7dae83152e --- /dev/null +++ b/src/drawing/engines/opengl/DrawImageShader.cpp @@ -0,0 +1,85 @@ +#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 "DrawImageShader.h" + +DrawImageShader::DrawImageShader() : OpenGLShaderProgram("drawimage") +{ + GetLocations(); + + glGenBuffers(1, &_vbo); + glGenVertexArrays(1, &_vao); + + vec2i vertices[] = { 0, 1, 2, 3 }; + glBindBuffer(GL_ARRAY_BUFFER, _vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STREAM_DRAW); + + glBindVertexArray(_vao); + glEnableVertexAttribArray(vIndex); + glVertexAttribIPointer(vIndex, 1, GL_INT, 0, 0); +} + +DrawImageShader::~DrawImageShader() +{ + glDeleteBuffers(1, &_vbo); + glDeleteVertexArrays(1, &_vao); + + glBindVertexArray(_vao); +} + +void DrawImageShader::GetLocations() +{ + uScreenSize = GetUniformLocation("uScreenSize"); + uClip = GetUniformLocation("uClip"); + uBounds = GetUniformLocation("uBounds"); + uTexture = GetUniformLocation("uTexture"); + + vIndex = GetAttributeLocation("vIndex"); +} + +void DrawImageShader::SetScreenSize(sint32 width, sint32 height) +{ + glUniform2i(uScreenSize, width, height); +} + +void DrawImageShader::SetClip(sint32 left, sint32 top, sint32 right, sint32 bottom) +{ + glUniform4i(uClip, left, top, right, bottom); +} + +void DrawImageShader::SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom) +{ + glUniform4i(uBounds, left, top, right, bottom); +} + +void DrawImageShader::SetTexture(GLuint texture) +{ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture); + glUniform1i(uTexture, 0); +} + +void DrawImageShader::Draw(sint32 left, sint32 top, sint32 right, sint32 bottom) +{ + SetBounds(left, top, right, bottom); + + glBindVertexArray(_vao); + glDrawArrays(GL_QUADS, 0, 4); +} + +#endif /* DISABLE_OPENGL */ diff --git a/src/drawing/engines/opengl/DrawImageShader.h b/src/drawing/engines/opengl/DrawImageShader.h new file mode 100644 index 0000000000..99f9e5c8a5 --- /dev/null +++ b/src/drawing/engines/opengl/DrawImageShader.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 DrawImageShader : public OpenGLShaderProgram +{ +private: + GLuint uScreenSize; + GLuint uClip; + GLuint uBounds; + GLuint uTexture; + + GLuint vIndex; + + GLuint _vbo; + GLuint _vao; + +public: + DrawImageShader(); + ~DrawImageShader() override; + + void SetScreenSize(sint32 width, sint32 height); + void SetClip(sint32 left, sint32 top, sint32 right, sint32 bottom); + void SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom); + void SetTexture(GLuint texture); + + void Draw(sint32 left, sint32 top, sint32 right, sint32 bottom); + +private: + void GetLocations(); +}; diff --git a/src/drawing/engines/opengl/FillRectShader.cpp b/src/drawing/engines/opengl/FillRectShader.cpp index 20828af765..a24b98b2ca 100644 --- a/src/drawing/engines/opengl/FillRectShader.cpp +++ b/src/drawing/engines/opengl/FillRectShader.cpp @@ -25,11 +25,13 @@ FillRectShader::FillRectShader() : OpenGLShaderProgram("fillrect") glGenBuffers(1, &_vbo); glGenVertexArrays(1, &_vao); - Use(); + vec2i vertices[] = { 0, 1, 2, 3 }; glBindBuffer(GL_ARRAY_BUFFER, _vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STREAM_DRAW); + glBindVertexArray(_vao); - glEnableVertexAttribArray(vPosition); - glVertexAttribIPointer(vPosition, 2, GL_INT, 0, 0); + glEnableVertexAttribArray(vIndex); + glVertexAttribIPointer(vIndex, 1, GL_INT, 0, 0); } FillRectShader::~FillRectShader() @@ -44,11 +46,12 @@ void FillRectShader::GetLocations() { uScreenSize = GetUniformLocation("uScreenSize"); uClip = GetUniformLocation("uClip"); + uBounds = GetUniformLocation("uBounds"); uFlags = GetUniformLocation("uFlags"); uColour[0] = GetUniformLocation("uColour[0]"); uColour[1] = GetUniformLocation("uColour[1]"); - vPosition = GetAttributeLocation("vPosition"); + vIndex = GetAttributeLocation("vIndex"); } void FillRectShader::SetScreenSize(sint32 width, sint32 height) @@ -61,6 +64,11 @@ void FillRectShader::SetClip(sint32 left, sint32 top, sint32 right, sint32 botto glUniform4i(uClip, left, top, right, bottom); } +void FillRectShader::SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom) +{ + glUniform4i(uBounds, left, top, right, bottom); +} + void FillRectShader::SetFlags(uint32 flags) { glUniform1i(uFlags, flags); @@ -73,15 +81,7 @@ void FillRectShader::SetColour(int index, vec4f colour) 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); + SetBounds(left, top, right, bottom); glBindVertexArray(_vao); glDrawArrays(GL_QUADS, 0, 4); diff --git a/src/drawing/engines/opengl/FillRectShader.h b/src/drawing/engines/opengl/FillRectShader.h index 2d99ba6d71..c47e9a9315 100644 --- a/src/drawing/engines/opengl/FillRectShader.h +++ b/src/drawing/engines/opengl/FillRectShader.h @@ -24,10 +24,11 @@ class FillRectShader : public OpenGLShaderProgram private: GLuint uScreenSize; GLuint uClip; + GLuint uBounds; GLuint uFlags; GLuint uColour[2]; - GLuint vPosition; + GLuint vIndex; GLuint _vbo; GLuint _vao; @@ -38,6 +39,7 @@ public: void SetScreenSize(sint32 width, sint32 height); void SetClip(sint32 left, sint32 top, sint32 right, sint32 bottom); + void SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom); void SetFlags(uint32 flags); void SetColour(int index, vec4f colour); diff --git a/src/drawing/engines/opengl/OpenGLAPI.cpp b/src/drawing/engines/opengl/OpenGLAPI.cpp index cedc4613e1..2bb2f05ff6 100644 --- a/src/drawing/engines/opengl/OpenGLAPI.cpp +++ b/src/drawing/engines/opengl/OpenGLAPI.cpp @@ -49,6 +49,7 @@ static inline bool SetProc(T * func, const char * name) static const char * TryLoadAllProcAddresses() { // 1.1 functions + SetupOpenGLFunction(glActiveTexture); SetupOpenGLFunction(glBegin); SetupOpenGLFunction(glBindTexture); SetupOpenGLFunction(glBlendFunc); @@ -105,6 +106,7 @@ static const char * TryLoadAllProcAddresses() SetupOpenGLFunction(glUniform4i); SetupOpenGLFunction(glUseProgram); SetupOpenGLFunction(glVertexAttribIPointer); + SetupOpenGLFunction(glVertexAttribPointer); return nullptr; } diff --git a/src/drawing/engines/opengl/OpenGLAPI.h b/src/drawing/engines/opengl/OpenGLAPI.h index 9fe5ea7c67..3cc1e947b9 100644 --- a/src/drawing/engines/opengl/OpenGLAPI.h +++ b/src/drawing/engines/opengl/OpenGLAPI.h @@ -19,6 +19,7 @@ #if OPENGL_NO_LINK // BEGIN [Do not define 1.1 function signatures] +#define glActiveTexture __static__glActiveTexture #define glBegin __static__glBegin #define glBindTexture __static__glBindTexture #define glBlendFunc __static__glBlendFunc @@ -51,6 +52,7 @@ #if OPENGL_NO_LINK // END [Do not define 1.1 function signatures] +#undef glActiveTexture #undef glBegin #undef glBindTexture #undef glBlendFunc @@ -113,6 +115,7 @@ typedef void (APIENTRYP PFNGLVIEWPORTPROC )(GLint x, GLint y, GLsizei wid #endif // 1.1 function pointers +GLAPI_DECL PFNGLACTIVETEXTUREPROC glActiveTexture GLAPI_SET; GLAPI_DECL PFNGLBEGINPROC glBegin GLAPI_SET; GLAPI_DECL PFNGLBINDTEXTUREPROC glBindTexture GLAPI_SET; GLAPI_DECL PFNGLBLENDFUNCPROC glBlendFunc GLAPI_SET; @@ -126,6 +129,7 @@ GLAPI_DECL PFNGLDRAWARRAYSPROC glDrawArrays GLAP GLAPI_DECL PFNGLENABLEPROC glEnable GLAPI_SET; GLAPI_DECL PFNGLENDPROC glEnd GLAPI_SET; GLAPI_DECL PFNGLGENTEXTURESPROC glGenTextures GLAPI_SET; +GLAPI_DECL PFNGLGETERRORPROC glGetError GLAPI_SET; GLAPI_DECL PFNGLLOADIDENTITYPROC glLoadIdentity GLAPI_SET; GLAPI_DECL PFNGLMATRIXMODEPROC glMatrixMode GLAPI_SET; GLAPI_DECL PFNGLORTHOPROC glOrtho GLAPI_SET; @@ -154,7 +158,6 @@ GLAPI_DECL PFNGLDETACHSHADERPROC glDetachShader GLAP GLAPI_DECL PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray GLAPI_SET; GLAPI_DECL PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation GLAPI_SET; GLAPI_DECL PFNGLGENBUFFERSPROC glGenBuffers GLAPI_SET; -GLAPI_DECL PFNGLGETERRORPROC glGetError GLAPI_SET; GLAPI_DECL PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog GLAPI_SET; GLAPI_DECL PFNGLGETPROGRAMIVPROC glGetProgramiv GLAPI_SET; GLAPI_DECL PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog GLAPI_SET; @@ -169,6 +172,7 @@ GLAPI_DECL PFNGLUNIFORM4FPROC glUniform4f GLAP GLAPI_DECL PFNGLUNIFORM4IPROC glUniform4i GLAPI_SET; GLAPI_DECL PFNGLUSEPROGRAMPROC glUseProgram GLAPI_SET; GLAPI_DECL PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer GLAPI_SET; +GLAPI_DECL PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer GLAPI_SET; #endif /* OPENGL_NO_LINK */ diff --git a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp index 314d69ab4f..22fc325911 100644 --- a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -31,6 +31,7 @@ IDrawingEngine * DrawingEngineFactory::CreateOpenGL() #include "GLSLTypes.h" #include "OpenGLAPI.h" +#include "DrawImageShader.h" #include "FillRectShader.h" #include "../../../core/Console.hpp" @@ -57,6 +58,7 @@ private: OpenGLDrawingEngine * _engine; rct_drawpixelinfo * _dpi; + DrawImageShader * _drawImageShader = nullptr; FillRectShader * _fillRectShader = nullptr; GLuint _vbo; @@ -308,6 +310,7 @@ OpenGLDrawingContext::OpenGLDrawingContext(OpenGLDrawingEngine * engine) OpenGLDrawingContext::~OpenGLDrawingContext() { + delete _drawImageShader; delete _fillRectShader; } @@ -318,6 +321,7 @@ IDrawingEngine * OpenGLDrawingContext::GetEngine() void OpenGLDrawingContext::Initialise() { + _drawImageShader = new DrawImageShader(); _fillRectShader = new FillRectShader(); } @@ -358,8 +362,6 @@ void OpenGLDrawingContext::DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32 void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 tertiaryColour) { - return; - int g1Id = image & 0x7FFFF; rct_g1_element * g1Element = gfx_get_g1_element(g1Id); @@ -416,61 +418,63 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t right += _offsetX; bottom += _offsetY; - vec2f texCoords[4] = { { 0, 0 }, - { 0, 1 }, - { 1, 1 }, - { 1, 0 } }; + _drawImageShader->Use(); + _drawImageShader->SetScreenSize(gScreenWidth, gScreenHeight); + _drawImageShader->SetClip(_clipLeft, _clipTop, _clipRight, _clipBottom); + _drawImageShader->SetTexture(texture); + _drawImageShader->Draw(left, top, right, bottom); - sint32 leftChop = _clipLeft - left; - if (leftChop > 0) - { - left += leftChop; - texCoords[0].x = - texCoords[1].x = (float)leftChop / g1Element->width; - } - sint32 rightChop = right - _clipRight; - if (rightChop > 0) - { - right -= rightChop; - texCoords[2].x = - texCoords[3].x = 1.0f - ((float)rightChop / g1Element->width); - } - - sint32 topChop = _clipTop - top; - if (topChop > 0) - { - top += topChop; - texCoords[0].y = - texCoords[3].y = (float)topChop / g1Element->height; - } - - sint32 bottomChop = bottom - _clipBottom; - if (bottomChop > 0) - { - bottom -= bottomChop; - texCoords[1].y = - texCoords[2].y = 1.0f - ((float)bottomChop / g1Element->height); - } - - if (right < left || bottom < top) - { - return; - } - - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, texture); - glColor3f(1, 1, 1); - glBegin(GL_QUADS); - glTexCoord2f(texCoords[0].s, texCoords[0].t); - glVertex2i(left, top); - glTexCoord2f(texCoords[1].s, texCoords[1].t); - glVertex2i(left, bottom); - glTexCoord2f(texCoords[2].s, texCoords[2].t); - glVertex2i(right, bottom); - glTexCoord2f(texCoords[3].s, texCoords[3].t); - glVertex2i(right, top); - glEnd(); + // sint32 leftChop = _clipLeft - left; + // if (leftChop > 0) + // { + // left += leftChop; + // texCoords[0].x = + // texCoords[1].x = (float)leftChop / g1Element->width; + // } + // + // sint32 rightChop = right - _clipRight; + // if (rightChop > 0) + // { + // right -= rightChop; + // texCoords[2].x = + // texCoords[3].x = 1.0f - ((float)rightChop / g1Element->width); + // } + // + // sint32 topChop = _clipTop - top; + // if (topChop > 0) + // { + // top += topChop; + // texCoords[0].y = + // texCoords[3].y = (float)topChop / g1Element->height; + // } + // + // sint32 bottomChop = bottom - _clipBottom; + // if (bottomChop > 0) + // { + // bottom -= bottomChop; + // texCoords[1].y = + // texCoords[2].y = 1.0f - ((float)bottomChop / g1Element->height); + // } + // + // if (right < left || bottom < top) + // { + // return; + // } + // + // glEnable(GL_TEXTURE_2D); + // glBindTexture(GL_TEXTURE_2D, texture); + // glColor3f(1, 1, 1); + // glBegin(GL_QUADS); + // glTexCoord2f(texCoords[0].s, texCoords[0].t); + // glVertex2i(left, top); + // glTexCoord2f(texCoords[1].s, texCoords[1].t); + // glVertex2i(left, bottom); + // glTexCoord2f(texCoords[2].s, texCoords[2].t); + // glVertex2i(right, bottom); + // glTexCoord2f(texCoords[3].s, texCoords[3].t); + // glVertex2i(right, top); + // glEnd(); } void OpenGLDrawingContext::DrawSpritePaletteSet(uint32 image, sint32 x, sint32 y, uint8 * palette, uint8 * unknown) From 84ca31a2404c8fd755c5c68c16bb23c21a308106 Mon Sep 17 00:00:00 2001 From: Ted John Date: Fri, 10 Jun 2016 20:17:00 +0100 Subject: [PATCH 06/27] implement masked image shader --- data/shaders/drawimagemasked.frag | 23 ++++ data/shaders/drawimagemasked.vert | 41 +++++++ openrct2.vcxproj | 4 + .../engines/opengl/DrawImageMaskedShader.cpp | 93 ++++++++++++++++ .../engines/opengl/DrawImageMaskedShader.h | 49 ++++++++ .../engines/opengl/OpenGLDrawingEngine.cpp | 105 ++++++++---------- 6 files changed, 254 insertions(+), 61 deletions(-) create mode 100644 data/shaders/drawimagemasked.frag create mode 100644 data/shaders/drawimagemasked.vert create mode 100644 src/drawing/engines/opengl/DrawImageMaskedShader.cpp create mode 100644 src/drawing/engines/opengl/DrawImageMaskedShader.h diff --git a/data/shaders/drawimagemasked.frag b/data/shaders/drawimagemasked.frag new file mode 100644 index 0000000000..7910547ed6 --- /dev/null +++ b/data/shaders/drawimagemasked.frag @@ -0,0 +1,23 @@ +#version 330 + +uniform ivec4 uClip; +uniform sampler2D uTextureMask; +uniform sampler2D uTextureColour; + +in vec2 fPosition; +in vec2 fTextureCoordinate; + +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; + } + + vec4 mask = texture(uTextureMask, fTextureCoordinate); + vec4 colour = texture(uTextureColour, fTextureCoordinate); + oColour = colour * mask; +} diff --git a/data/shaders/drawimagemasked.vert b/data/shaders/drawimagemasked.vert new file mode 100644 index 0000000000..4cd77cc1bc --- /dev/null +++ b/data/shaders/drawimagemasked.vert @@ -0,0 +1,41 @@ +#version 330 + +uniform ivec2 uScreenSize; +uniform ivec4 uBounds; + +in int vIndex; + +out vec2 fPosition; +out vec2 fTextureCoordinate; + +void main() +{ + vec2 pos; + switch (vIndex) { + case 0: + pos = uBounds.xy; + fTextureCoordinate = vec2(0, 0); + break; + case 1: + pos = uBounds.zy; + fTextureCoordinate = vec2(1, 0); + break; + case 2: + pos = uBounds.zw; + fTextureCoordinate = vec2(1, 1); + break; + case 3: + pos = uBounds.xw; + fTextureCoordinate = vec2(0, 1); + break; + } + + fPosition = pos; + + // Transform screen coordinates to viewport + 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.0, 1.0); +} diff --git a/openrct2.vcxproj b/openrct2.vcxproj index 0851f2a1f6..131061159e 100644 --- a/openrct2.vcxproj +++ b/openrct2.vcxproj @@ -18,6 +18,8 @@ + + @@ -46,6 +48,7 @@ + @@ -345,6 +348,7 @@ + diff --git a/src/drawing/engines/opengl/DrawImageMaskedShader.cpp b/src/drawing/engines/opengl/DrawImageMaskedShader.cpp new file mode 100644 index 0000000000..c548110fed --- /dev/null +++ b/src/drawing/engines/opengl/DrawImageMaskedShader.cpp @@ -0,0 +1,93 @@ +#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 "DrawImageMaskedShader.h" + +DrawImageMaskedShader::DrawImageMaskedShader() : OpenGLShaderProgram("drawimagemasked") +{ + GetLocations(); + + glGenBuffers(1, &_vbo); + glGenVertexArrays(1, &_vao); + + vec2i vertices[] = { 0, 1, 2, 3 }; + glBindBuffer(GL_ARRAY_BUFFER, _vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STREAM_DRAW); + + glBindVertexArray(_vao); + glEnableVertexAttribArray(vIndex); + glVertexAttribIPointer(vIndex, 1, GL_INT, 0, 0); +} + +DrawImageMaskedShader::~DrawImageMaskedShader() +{ + glDeleteBuffers(1, &_vbo); + glDeleteVertexArrays(1, &_vao); + + glBindVertexArray(_vao); +} + +void DrawImageMaskedShader::GetLocations() +{ + uScreenSize = GetUniformLocation("uScreenSize"); + uClip = GetUniformLocation("uClip"); + uBounds = GetUniformLocation("uBounds"); + uTextureMask = GetUniformLocation("uTextureMask"); + uTextureColour = GetUniformLocation("uTextureColour"); + + vIndex = GetAttributeLocation("vIndex"); +} + +void DrawImageMaskedShader::SetScreenSize(sint32 width, sint32 height) +{ + glUniform2i(uScreenSize, width, height); +} + +void DrawImageMaskedShader::SetClip(sint32 left, sint32 top, sint32 right, sint32 bottom) +{ + glUniform4i(uClip, left, top, right, bottom); +} + +void DrawImageMaskedShader::SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom) +{ + glUniform4i(uBounds, left, top, right, bottom); +} + +void DrawImageMaskedShader::SetTextureMask(GLuint texture) +{ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture); + glUniform1i(uTextureMask, 0); +} + +void DrawImageMaskedShader::SetTextureColour(GLuint texture) +{ + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texture); + glUniform1i(uTextureColour, 1); +} + +void DrawImageMaskedShader::Draw(sint32 left, sint32 top, sint32 right, sint32 bottom) +{ + SetBounds(left, top, right, bottom); + + glBindVertexArray(_vao); + glDrawArrays(GL_QUADS, 0, 4); +} + +#endif /* DISABLE_OPENGL */ diff --git a/src/drawing/engines/opengl/DrawImageMaskedShader.h b/src/drawing/engines/opengl/DrawImageMaskedShader.h new file mode 100644 index 0000000000..f1081b4a5c --- /dev/null +++ b/src/drawing/engines/opengl/DrawImageMaskedShader.h @@ -0,0 +1,49 @@ +#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 DrawImageMaskedShader : public OpenGLShaderProgram +{ +private: + GLuint uScreenSize; + GLuint uClip; + GLuint uBounds; + GLuint uTextureMask; + GLuint uTextureColour; + + GLuint vIndex; + + GLuint _vbo; + GLuint _vao; + +public: + DrawImageMaskedShader(); + ~DrawImageMaskedShader() override; + + void SetScreenSize(sint32 width, sint32 height); + void SetClip(sint32 left, sint32 top, sint32 right, sint32 bottom); + void SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom); + void SetTextureMask(GLuint texture); + void SetTextureColour(GLuint texture); + void Draw(sint32 left, sint32 top, sint32 right, sint32 bottom); + +private: + void GetLocations(); +}; diff --git a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp index 22fc325911..5266879b7b 100644 --- a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -32,6 +32,7 @@ IDrawingEngine * DrawingEngineFactory::CreateOpenGL() #include "GLSLTypes.h" #include "OpenGLAPI.h" #include "DrawImageShader.h" +#include "DrawImageMaskedShader.h" #include "FillRectShader.h" #include "../../../core/Console.hpp" @@ -58,8 +59,9 @@ private: OpenGLDrawingEngine * _engine; rct_drawpixelinfo * _dpi; - DrawImageShader * _drawImageShader = nullptr; - FillRectShader * _fillRectShader = nullptr; + DrawImageShader * _drawImageShader = nullptr; + DrawImageMaskedShader * _drawImageMaskedShader = nullptr; + FillRectShader * _fillRectShader = nullptr; GLuint _vbo; sint32 _offsetX; @@ -311,6 +313,7 @@ OpenGLDrawingContext::OpenGLDrawingContext(OpenGLDrawingEngine * engine) OpenGLDrawingContext::~OpenGLDrawingContext() { delete _drawImageShader; + delete _drawImageMaskedShader; delete _fillRectShader; } @@ -322,6 +325,7 @@ IDrawingEngine * OpenGLDrawingContext::GetEngine() void OpenGLDrawingContext::Initialise() { _drawImageShader = new DrawImageShader(); + _drawImageMaskedShader = new DrawImageMaskedShader(); _fillRectShader = new FillRectShader(); } @@ -398,19 +402,14 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t sint32 top = y + drawOffsetY; sint32 right = left + drawWidth; sint32 bottom = top + drawHeight; - // FillRect(g1Id & 0xFF, left, top, right, bottom); if (left > right) { - left ^= right; - right ^= left; - left ^= right; + std::swap(left, right); } if (top > bottom) { - top ^= bottom; - bottom ^= top; - top ^= bottom; + std::swap(top, bottom); } left += _offsetX; @@ -423,58 +422,6 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t _drawImageShader->SetClip(_clipLeft, _clipTop, _clipRight, _clipBottom); _drawImageShader->SetTexture(texture); _drawImageShader->Draw(left, top, right, bottom); - - - // sint32 leftChop = _clipLeft - left; - // if (leftChop > 0) - // { - // left += leftChop; - // texCoords[0].x = - // texCoords[1].x = (float)leftChop / g1Element->width; - // } - // - // sint32 rightChop = right - _clipRight; - // if (rightChop > 0) - // { - // right -= rightChop; - // texCoords[2].x = - // texCoords[3].x = 1.0f - ((float)rightChop / g1Element->width); - // } - // - // sint32 topChop = _clipTop - top; - // if (topChop > 0) - // { - // top += topChop; - // texCoords[0].y = - // texCoords[3].y = (float)topChop / g1Element->height; - // } - // - // sint32 bottomChop = bottom - _clipBottom; - // if (bottomChop > 0) - // { - // bottom -= bottomChop; - // texCoords[1].y = - // texCoords[2].y = 1.0f - ((float)bottomChop / g1Element->height); - // } - // - // if (right < left || bottom < top) - // { - // return; - // } - // - // glEnable(GL_TEXTURE_2D); - // glBindTexture(GL_TEXTURE_2D, texture); - // glColor3f(1, 1, 1); - // glBegin(GL_QUADS); - // glTexCoord2f(texCoords[0].s, texCoords[0].t); - // glVertex2i(left, top); - // glTexCoord2f(texCoords[1].s, texCoords[1].t); - // glVertex2i(left, bottom); - // glTexCoord2f(texCoords[2].s, texCoords[2].t); - // glVertex2i(right, bottom); - // glTexCoord2f(texCoords[3].s, texCoords[3].t); - // glVertex2i(right, top); - // glEnd(); } void OpenGLDrawingContext::DrawSpritePaletteSet(uint32 image, sint32 x, sint32 y, uint8 * palette, uint8 * unknown) @@ -484,6 +431,42 @@ void OpenGLDrawingContext::DrawSpritePaletteSet(uint32 image, sint32 x, sint32 y void OpenGLDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage) { + rct_g1_element * g1ElementMask = gfx_get_g1_element(maskImage & 0x7FFFF); + rct_g1_element * g1ElementColour = gfx_get_g1_element(colourImage & 0x7FFFF); + + GLuint textureMask = GetOrLoadImageTexture(maskImage); + GLuint textureColour = GetOrLoadImageTexture(colourImage); + + sint32 drawOffsetX = g1ElementMask->x_offset; + sint32 drawOffsetY = g1ElementMask->y_offset; + sint32 drawWidth = Math::Min(g1ElementMask->width, g1ElementColour->width); + sint32 drawHeight = Math::Min(g1ElementMask->height, g1ElementColour->height); + + sint32 left = x + drawOffsetX; + sint32 top = y + drawOffsetY; + sint32 right = left + drawWidth; + sint32 bottom = top + drawHeight; + + if (left > right) + { + std::swap(left, right); + } + if (top > bottom) + { + std::swap(top, bottom); + } + + left += _offsetX; + top += _offsetY; + right += _offsetX; + bottom += _offsetY; + + _drawImageMaskedShader->Use(); + _drawImageMaskedShader->SetScreenSize(gScreenWidth, gScreenHeight); + _drawImageMaskedShader->SetClip(_clipLeft, _clipTop, _clipRight, _clipBottom); + _drawImageMaskedShader->SetTextureMask(textureMask); + _drawImageMaskedShader->SetTextureColour(textureColour); + _drawImageMaskedShader->Draw(left, top, right, bottom); } void OpenGLDrawingContext::SetDPI(rct_drawpixelinfo * dpi) From 36c71c139860533d8e1896e79c1ca16132e66ac9 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 11 Jun 2016 00:04:13 +0100 Subject: [PATCH 07/27] implement FillRect transparancy --- src/drawing/engines/opengl/GLSLTypes.h | 7 ++ .../engines/opengl/OpenGLDrawingEngine.cpp | 118 ++++++++++++++++++ 2 files changed, 125 insertions(+) diff --git a/src/drawing/engines/opengl/GLSLTypes.h b/src/drawing/engines/opengl/GLSLTypes.h index ac6b47db3d..301bfe5389 100644 --- a/src/drawing/engines/opengl/GLSLTypes.h +++ b/src/drawing/engines/opengl/GLSLTypes.h @@ -32,6 +32,13 @@ struct vec2f union { float y; float t; float g; }; }; +struct vec3f +{ + union { float x; float s; float r; }; + union { float y; float t; float g; }; + union { float z; float p; float b; }; +}; + struct vec4i { union { sint32 x; sint32 s; sint32 r; }; diff --git a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp index 5266879b7b..359dfbc7c1 100644 --- a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -51,6 +51,110 @@ extern "C" #include "../../drawing.h" } +static const vec3f TransparentColourTable[144 - 44] = +{ + { 0.7f, 0.8f, 0.8f }, // 44 + { 0.7f, 0.8f, 0.8f }, + { 0.3f, 0.4f, 0.4f }, + { 0.2f, 0.3f, 0.3f }, + { 0.1f, 0.2f, 0.2f }, + { 0.4f, 0.5f, 0.5f }, + { 0.3f, 0.4f, 0.4f }, + { 0.4f, 0.5f, 0.5f }, + { 0.4f, 0.5f, 0.5f }, + { 0.3f, 0.4f, 0.4f }, + { 0.6f, 0.7f, 0.7f }, + { 0.3f, 0.5f, 0.9f }, + { 0.1f, 0.3f, 0.8f }, + { 0.5f, 0.7f, 0.9f }, + { 0.6f, 0.2f, 0.2f }, + { 0.5f, 0.1f, 0.1f }, + { 0.8f, 0.4f, 0.4f }, + { 0.3f, 0.5f, 0.4f }, + { 0.2f, 0.4f, 0.2f }, + { 0.5f, 0.7f, 0.5f }, + { 0.5f, 0.5f, 0.7f }, + { 0.3f, 0.3f, 0.5f }, + { 0.6f, 0.6f, 0.8f }, + { 0.5f, 0.5f, 0.2f }, + { 0.4f, 0.4f, 0.1f }, + { 0.7f, 0.7f, 0.4f }, + { 0.7f, 0.5f, 0.3f }, + { 0.6f, 0.4f, 0.2f }, + { 0.8f, 0.7f, 0.4f }, + { 0.8f, 0.7f, 0.1f }, + { 0.7f, 0.4f, 0.0f }, + { 1.0f, 0.9f, 0.2f }, + { 0.4f, 0.6f, 0.2f }, + { 0.3f, 0.4f, 0.2f }, + { 0.5f, 0.7f, 0.3f }, + { 0.5f, 0.6f, 0.4f }, + { 0.4f, 0.4f, 0.3f }, + { 0.7f, 0.8f, 0.5f }, + { 0.3f, 0.7f, 0.2f }, + { 0.2f, 0.6f, 0.0f }, + { 0.4f, 0.8f, 0.3f }, + { 0.8f, 0.5f, 0.4f }, + { 0.7f, 0.4f, 0.3f }, + { 0.9f, 0.7f, 0.5f }, + { 0.5f, 0.3f, 0.7f }, + { 0.4f, 0.2f, 0.6f }, + { 0.7f, 0.5f, 0.8f }, + { 0.9f, 0.0f, 0.0f }, + { 0.7f, 0.0f, 0.0f }, + { 1.0f, 0.3f, 0.3f }, + { 1.0f, 0.4f, 0.1f }, + { 0.9f, 0.3f, 0.0f }, + { 1.0f, 0.6f, 0.3f }, + { 0.2f, 0.6f, 0.6f }, + { 0.0f, 0.4f, 0.4f }, + { 0.4f, 0.7f, 0.7f }, + { 0.9f, 0.2f, 0.6f }, + { 0.6f, 0.1f, 0.4f }, + { 1.0f, 0.5f, 0.7f }, + { 0.6f, 0.5f, 0.4f }, + { 0.4f, 0.3f, 0.2f }, + { 0.7f, 0.7f, 0.6f }, + { 0.9f, 0.6f, 0.6f }, + { 0.8f, 0.5f, 0.5f }, + { 1.0f, 0.7f, 0.7f }, + { 0.7f, 0.8f, 0.8f }, + { 0.5f, 0.6f, 0.6f }, + { 0.9f, 1.0f, 1.0f }, + { 0.2f, 0.3f, 0.3f }, + { 0.4f, 0.5f, 0.5f }, + { 0.7f, 0.8f, 0.8f }, + { 0.2f, 0.3f, 0.5f }, + { 0.5f, 0.5f, 0.7f }, + { 0.5f, 0.3f, 0.7f }, + { 0.1f, 0.3f, 0.7f }, + { 0.3f, 0.5f, 0.9f }, + { 0.6f, 0.8f, 1.0f }, + { 0.2f, 0.6f, 0.6f }, + { 0.5f, 0.8f, 0.8f }, + { 0.1f, 0.5f, 0.0f }, + { 0.3f, 0.5f, 0.4f }, + { 0.4f, 0.6f, 0.2f }, + { 0.3f, 0.7f, 0.2f }, + { 0.5f, 0.6f, 0.4f }, + { 0.5f, 0.5f, 0.2f }, + { 1.0f, 0.9f, 0.2f }, + { 0.8f, 0.7f, 0.1f }, + { 0.6f, 0.3f, 0.0f }, + { 1.0f, 0.4f, 0.1f }, + { 0.7f, 0.3f, 0.0f }, + { 0.7f, 0.5f, 0.3f }, + { 0.5f, 0.3f, 0.1f }, + { 0.5f, 0.4f, 0.3f }, + { 0.8f, 0.5f, 0.4f }, + { 0.6f, 0.2f, 0.2f }, + { 0.6f, 0.0f, 0.0f }, + { 0.9f, 0.0f, 0.0f }, + { 0.6f, 0.1f, 0.3f }, + { 0.9f, 0.2f, 0.6f }, + { 0.9f, 0.6f, 0.6f }, +}; + class OpenGLDrawingEngine; class OpenGLDrawingContext : public IDrawingContext @@ -343,6 +447,20 @@ void OpenGLDrawingContext::FillRect(uint32 colour, sint32 left, sint32 top, sint { paletteColour[1].a = 0; } + else if (colour & 0x2000000) + { + uint8 tableIndex = colour & 0xFF; + if (tableIndex < 44) return; + if (tableIndex >= 144) return; + tableIndex -= 44; + + vec3f transformColour = TransparentColourTable[tableIndex]; + paletteColour[0].r = transformColour.r; + paletteColour[0].g = transformColour.g; + paletteColour[0].b = transformColour.b; + paletteColour[0].a = 0.5f; + paletteColour[1] = paletteColour[0]; + } _fillRectShader->Use(); _fillRectShader->SetScreenSize(gScreenWidth, gScreenHeight); From b0b0b82fd186c7639874151e580c76a6f4a408c5 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 11 Jun 2016 02:24:39 +0100 Subject: [PATCH 08/27] implement scaling for OpenGL --- data/shaders/drawimage.vert | 9 +-- openrct2.vcxproj | 2 + .../engines/opengl/DrawImageShader.cpp | 21 ++++-- src/drawing/engines/opengl/DrawImageShader.h | 2 + src/drawing/engines/opengl/OpenGLAPI.cpp | 6 ++ src/drawing/engines/opengl/OpenGLAPI.h | 12 ++++ .../engines/opengl/OpenGLDrawingEngine.cpp | 64 ++++++++++++++----- .../engines/opengl/OpenGLFramebuffer.cpp | 58 +++++++++++++++++ .../engines/opengl/OpenGLFramebuffer.h | 42 ++++++++++++ 9 files changed, 190 insertions(+), 26 deletions(-) create mode 100644 src/drawing/engines/opengl/OpenGLFramebuffer.cpp create mode 100644 src/drawing/engines/opengl/OpenGLFramebuffer.h diff --git a/data/shaders/drawimage.vert b/data/shaders/drawimage.vert index 4cd77cc1bc..577ec0ef2b 100644 --- a/data/shaders/drawimage.vert +++ b/data/shaders/drawimage.vert @@ -2,6 +2,7 @@ uniform ivec2 uScreenSize; uniform ivec4 uBounds; +uniform ivec4 uTextureCoordinates; in int vIndex; @@ -14,19 +15,19 @@ void main() switch (vIndex) { case 0: pos = uBounds.xy; - fTextureCoordinate = vec2(0, 0); + fTextureCoordinate = uTextureCoordinates.xy; break; case 1: pos = uBounds.zy; - fTextureCoordinate = vec2(1, 0); + fTextureCoordinate = uTextureCoordinates.zy; break; case 2: pos = uBounds.zw; - fTextureCoordinate = vec2(1, 1); + fTextureCoordinate = uTextureCoordinates.zw; break; case 3: pos = uBounds.xw; - fTextureCoordinate = vec2(0, 1); + fTextureCoordinate = uTextureCoordinates.xw; break; } diff --git a/openrct2.vcxproj b/openrct2.vcxproj index 131061159e..c048c39194 100644 --- a/openrct2.vcxproj +++ b/openrct2.vcxproj @@ -53,6 +53,7 @@ + @@ -353,6 +354,7 @@ + diff --git a/src/drawing/engines/opengl/DrawImageShader.cpp b/src/drawing/engines/opengl/DrawImageShader.cpp index 7dae83152e..6a42fa6e09 100644 --- a/src/drawing/engines/opengl/DrawImageShader.cpp +++ b/src/drawing/engines/opengl/DrawImageShader.cpp @@ -31,7 +31,10 @@ DrawImageShader::DrawImageShader() : OpenGLShaderProgram("drawimage") glBindVertexArray(_vao); glEnableVertexAttribArray(vIndex); - glVertexAttribIPointer(vIndex, 1, GL_INT, 0, 0); + glVertexAttribIPointer(vIndex, 1, GL_INT, 0, nullptr); + + Use(); + SetTextureCoordinates(0, 0, 1, 1); } DrawImageShader::~DrawImageShader() @@ -44,12 +47,13 @@ DrawImageShader::~DrawImageShader() void DrawImageShader::GetLocations() { - uScreenSize = GetUniformLocation("uScreenSize"); - uClip = GetUniformLocation("uClip"); - uBounds = GetUniformLocation("uBounds"); - uTexture = GetUniformLocation("uTexture"); + uScreenSize = GetUniformLocation("uScreenSize"); + uClip = GetUniformLocation("uClip"); + uBounds = GetUniformLocation("uBounds"); + uTextureCoordinates = GetUniformLocation("uTextureCoordinates"); + uTexture = GetUniformLocation("uTexture"); - vIndex = GetAttributeLocation("vIndex"); + vIndex = GetAttributeLocation("vIndex"); } void DrawImageShader::SetScreenSize(sint32 width, sint32 height) @@ -67,6 +71,11 @@ void DrawImageShader::SetBounds(sint32 left, sint32 top, sint32 right, sint32 bo glUniform4i(uBounds, left, top, right, bottom); } +void DrawImageShader::SetTextureCoordinates(sint32 left, sint32 top, sint32 right, sint32 bottom) +{ + glUniform4i(uTextureCoordinates, left, top, right, bottom); +} + void DrawImageShader::SetTexture(GLuint texture) { glActiveTexture(GL_TEXTURE0); diff --git a/src/drawing/engines/opengl/DrawImageShader.h b/src/drawing/engines/opengl/DrawImageShader.h index 99f9e5c8a5..534d3efa02 100644 --- a/src/drawing/engines/opengl/DrawImageShader.h +++ b/src/drawing/engines/opengl/DrawImageShader.h @@ -25,6 +25,7 @@ private: GLuint uScreenSize; GLuint uClip; GLuint uBounds; + GLuint uTextureCoordinates; GLuint uTexture; GLuint vIndex; @@ -39,6 +40,7 @@ public: void SetScreenSize(sint32 width, sint32 height); void SetClip(sint32 left, sint32 top, sint32 right, sint32 bottom); void SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom); + void SetTextureCoordinates(sint32 left, sint32 top, sint32 right, sint32 bottom); void SetTexture(GLuint texture); void Draw(sint32 left, sint32 top, sint32 right, sint32 bottom); diff --git a/src/drawing/engines/opengl/OpenGLAPI.cpp b/src/drawing/engines/opengl/OpenGLAPI.cpp index 2bb2f05ff6..b95c3bf954 100644 --- a/src/drawing/engines/opengl/OpenGLAPI.cpp +++ b/src/drawing/engines/opengl/OpenGLAPI.cpp @@ -57,6 +57,7 @@ static const char * TryLoadAllProcAddresses() SetupOpenGLFunction(glClearColor); SetupOpenGLFunction(glColor3f); SetupOpenGLFunction(glColor4f); + SetupOpenGLFunction(glCullFace); SetupOpenGLFunction(glDeleteTextures); SetupOpenGLFunction(glDisable); SetupOpenGLFunction(glDrawArrays); @@ -67,6 +68,7 @@ static const char * TryLoadAllProcAddresses() SetupOpenGLFunction(glLoadIdentity); SetupOpenGLFunction(glMatrixMode); SetupOpenGLFunction(glOrtho); + SetupOpenGLFunction(glReadPixels); SetupOpenGLFunction(glScalef); SetupOpenGLFunction(glTexCoord2f); SetupOpenGLFunction(glTexImage2D); @@ -79,19 +81,23 @@ static const char * TryLoadAllProcAddresses() SetupOpenGLFunction(glAttachShader); SetupOpenGLFunction(glBindBuffer); SetupOpenGLFunction(glBindFragDataLocation); + SetupOpenGLFunction(glBindFramebuffer); SetupOpenGLFunction(glBindVertexArray); SetupOpenGLFunction(glBufferData); SetupOpenGLFunction(glCompileShader); SetupOpenGLFunction(glCreateProgram); SetupOpenGLFunction(glCreateShader); SetupOpenGLFunction(glDeleteBuffers); + SetupOpenGLFunction(glDeleteFramebuffers); SetupOpenGLFunction(glDeleteProgram); SetupOpenGLFunction(glDeleteShader); SetupOpenGLFunction(glDeleteVertexArrays); SetupOpenGLFunction(glDetachShader); SetupOpenGLFunction(glEnableVertexAttribArray); + SetupOpenGLFunction(glFramebufferTexture2D); SetupOpenGLFunction(glGetAttribLocation); SetupOpenGLFunction(glGenBuffers); + SetupOpenGLFunction(glGenFramebuffers); SetupOpenGLFunction(glGetProgramInfoLog); SetupOpenGLFunction(glGetProgramiv); SetupOpenGLFunction(glGetShaderInfoLog); diff --git a/src/drawing/engines/opengl/OpenGLAPI.h b/src/drawing/engines/opengl/OpenGLAPI.h index 3cc1e947b9..dc5163b5ef 100644 --- a/src/drawing/engines/opengl/OpenGLAPI.h +++ b/src/drawing/engines/opengl/OpenGLAPI.h @@ -27,6 +27,7 @@ #define glClearColor __static__glClearColor #define glColor3f __static__glColor3f #define glColor4f __static__glColor4f +#define glCullFace __static__glCullFace #define glDeleteTextures __static__glDeleteTextures #define glDisable __static__glDisable #define glDrawArrays __static__glDrawArrays @@ -37,6 +38,7 @@ #define glLoadIdentity __static__glLoadIdentity #define glMatrixMode __static__glMatrixMode #define glOrtho __static__glOrtho +#define glReadPixels __static__glReadPixels #define glScalef __static__glScalef #define glTexCoord2f __static__glTexCoord2f #define glTexImage2D __static__glTexImage2D @@ -60,6 +62,7 @@ #undef glClearColor #undef glColor3f #undef glColor4f +#undef glCullFace #undef glDeleteTextures #undef glDisable #undef glDrawArrays @@ -70,6 +73,7 @@ #undef glLoadIdentity #undef glMatrixMode #undef glOrtho +#undef glReadPixels #undef glScalef #undef glTexCoord2f #undef glTexImage2D @@ -86,6 +90,7 @@ typedef void (APIENTRYP PFNGLCLEARPROC )(GLbitfield mask); typedef void (APIENTRYP PFNGLCLEARCOLORPROC )(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); typedef void (APIENTRYP PFNGLCOLOR3FPROC )(GLfloat red, GLfloat green, GLfloat blue); typedef void (APIENTRYP PFNGLCOLOR4FPROC )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (APIENTRYP PFNGLCULLFACEPROC )(GLenum mode); 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); @@ -96,6 +101,7 @@ typedef void (APIENTRYP PFNGLGENTEXTURESPROC )(GLsizei n, GLuint *textures); typedef void (APIENTRYP PFNGLLOADIDENTITYPROC )(void); typedef void (APIENTRYP PFNGLMATRIXMODEPROC )(GLenum mode); typedef void (APIENTRYP PFNGLORTHOPROC )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val); +typedef void (APIENTRYP PFNGLREADPIXELSPROC )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid * pixels); typedef void (APIENTRYP PFNGLSCALEFPROC )(GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLTEXCOORD2FPROC )(GLfloat s, GLfloat t); typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC )(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); @@ -123,6 +129,7 @@ GLAPI_DECL PFNGLCLEARPROC glClear GLAP GLAPI_DECL PFNGLCLEARCOLORPROC glClearColor GLAPI_SET; GLAPI_DECL PFNGLCOLOR3FPROC glColor3f GLAPI_SET; GLAPI_DECL PFNGLCOLOR4FPROC glColor4f GLAPI_SET; +GLAPI_DECL PFNGLCULLFACEPROC glCullFace GLAPI_SET; GLAPI_DECL PFNGLDELETETEXTURESPROC glDeleteTextures GLAPI_SET; GLAPI_DECL PFNGLDISABLEPROC glDisable GLAPI_SET; GLAPI_DECL PFNGLDRAWARRAYSPROC glDrawArrays GLAPI_SET; @@ -133,6 +140,7 @@ GLAPI_DECL PFNGLGETERRORPROC glGetError GLAP GLAPI_DECL PFNGLLOADIDENTITYPROC glLoadIdentity GLAPI_SET; GLAPI_DECL PFNGLMATRIXMODEPROC glMatrixMode GLAPI_SET; GLAPI_DECL PFNGLORTHOPROC glOrtho GLAPI_SET; +GLAPI_DECL PFNGLREADPIXELSPROC glReadPixels GLAPI_SET; GLAPI_DECL PFNGLSCALEFPROC glScalef GLAPI_SET; GLAPI_DECL PFNGLTEXCOORD2FPROC glTexCoord2f GLAPI_SET; GLAPI_DECL PFNGLTEXIMAGE2DPROC glTexImage2D GLAPI_SET; @@ -145,19 +153,23 @@ GLAPI_DECL PFNGLVIEWPORTPROC glViewport GLAP GLAPI_DECL PFNGLATTACHSHADERPROC glAttachShader GLAPI_SET; GLAPI_DECL PFNGLBINDBUFFERPROC glBindBuffer GLAPI_SET; GLAPI_DECL PFNGLBINDFRAGDATALOCATIONPROC glBindFragDataLocation GLAPI_SET; +GLAPI_DECL PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer 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 PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers 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 PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D GLAPI_SET; GLAPI_DECL PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation GLAPI_SET; GLAPI_DECL PFNGLGENBUFFERSPROC glGenBuffers GLAPI_SET; +GLAPI_DECL PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers GLAPI_SET; GLAPI_DECL PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog GLAPI_SET; GLAPI_DECL PFNGLGETPROGRAMIVPROC glGetProgramiv GLAPI_SET; GLAPI_DECL PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog GLAPI_SET; diff --git a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp index 359dfbc7c1..fc1bd08188 100644 --- a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -31,6 +31,7 @@ IDrawingEngine * DrawingEngineFactory::CreateOpenGL() #include "GLSLTypes.h" #include "OpenGLAPI.h" +#include "OpenGLFramebuffer.h" #include "DrawImageShader.h" #include "DrawImageMaskedShader.h" #include "FillRectShader.h" @@ -219,6 +220,10 @@ private: OpenGLDrawingContext * _drawingContext; + DrawImageShader * _drawImageShader = nullptr; + OpenGLFramebuffer * _screenFramebuffer = nullptr; + OpenGLFramebuffer * _canvasFramebuffer = nullptr; + public: SDL_Color Palette[256]; vec4f GLPalette[256]; @@ -230,6 +235,8 @@ public: ~OpenGLDrawingEngine() override { + delete _drawImageShader; + delete _drawingContext; delete [] _bits; @@ -252,13 +259,18 @@ public: glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // Do not draw the unseen side of the primitives + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + + _drawImageShader = new DrawImageShader(); } void Resize(uint32 width, uint32 height) override { ConfigureBits(width, height, width); - - glViewport(0, 0, (GLsizei)width, (GLsizei)height); + ConfigureCanvas(); } void SetPalette(SDL_Color * palette) override @@ -282,18 +294,10 @@ public: void Draw() override { - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT); + assert(_screenFramebuffer != nullptr); + assert(_canvasFramebuffer != nullptr); - // glMatrixMode(GL_PROJECTION_MATRIX); - // glLoadIdentity(); - // glOrtho(0, _width, _height, 0, -1.0, 1.0); - - // glMatrixMode(GL_MODELVIEW_MATRIX); - // glLoadIdentity(); - // glScalef(1, -1.0f, 0); - // glTranslatef(-1.0f, -1.0f, 0); - // glScalef(2.0f / _width, 2.0f / _height, 0); + _canvasFramebuffer->Bind(); if (gIntroState != INTRO_STATE_NONE) { intro_draw(&_bitsDPI); @@ -301,11 +305,24 @@ public: window_update_all_viewports(); window_draw_all(&_bitsDPI, 0, 0, _width, _height); window_update_all(); - + gfx_draw_pickedup_peep(&_bitsDPI); - + rct2_draw(&_bitsDPI); } + + // Scale up to window + _screenFramebuffer->Bind(); + + sint32 width = _screenFramebuffer->GetWidth(); + sint32 height = _screenFramebuffer->GetHeight(); + _drawImageShader->Use(); + _drawImageShader->SetScreenSize(width, height); + _drawImageShader->SetClip(0, 0, width, height); + _drawImageShader->SetTexture(_canvasFramebuffer->GetTexture()); + _drawImageShader->SetTextureCoordinates(0, 1, 1, 0); + _drawImageShader->Draw(0, 0, width, height); + Display(); } @@ -347,7 +364,6 @@ public: } private: - void ConfigureBits(uint32 width, uint32 height, uint32 pitch) { size_t newBitsSize = pitch * height; @@ -398,6 +414,22 @@ private: dpi->pitch = _pitch - width; } + void ConfigureCanvas() + { + // Re-create screen framebuffer + delete _screenFramebuffer; + _screenFramebuffer = new OpenGLFramebuffer(_window); + + // Re-create canvas framebuffer + delete _canvasFramebuffer; + _canvasFramebuffer = new OpenGLFramebuffer(_width, _height); + + _drawImageShader->Use(); + _drawImageShader->SetScreenSize(_width, _height); + _drawImageShader->SetClip(0, 0, _width, _height); + _drawImageShader->SetTexture(_canvasFramebuffer->GetTexture()); + } + void Display() { SDL_GL_SwapWindow(_window); diff --git a/src/drawing/engines/opengl/OpenGLFramebuffer.cpp b/src/drawing/engines/opengl/OpenGLFramebuffer.cpp new file mode 100644 index 0000000000..9f5315349e --- /dev/null +++ b/src/drawing/engines/opengl/OpenGLFramebuffer.cpp @@ -0,0 +1,58 @@ +#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 + +#include +#include "OpenGLFramebuffer.h" + +constexpr GLuint BACKBUFFER_ID = 0; + +OpenGLFramebuffer::OpenGLFramebuffer(SDL_Window * window) +{ + _id = BACKBUFFER_ID; + _texture = 0; + SDL_GetWindowSize(window, &_width, &_height); +} + +OpenGLFramebuffer::OpenGLFramebuffer(sint32 width, sint32 height) +{ + _width = width; + _height = height; + + glGenTextures(1, &_texture); + glBindTexture(GL_TEXTURE_2D, _texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glGenFramebuffers(1, &_id); + glBindFramebuffer(GL_FRAMEBUFFER, _id); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture, 0); +} + +OpenGLFramebuffer::~OpenGLFramebuffer() +{ + if (_id != BACKBUFFER_ID) + { + glDeleteTextures(1, &_texture); + glDeleteFramebuffers(1, &_id); + } +} + +void OpenGLFramebuffer::Bind() +{ + glBindFramebuffer(GL_FRAMEBUFFER, _id); + glViewport(0, 0, (GLsizei)_width, (GLsizei)_height); +} diff --git a/src/drawing/engines/opengl/OpenGLFramebuffer.h b/src/drawing/engines/opengl/OpenGLFramebuffer.h new file mode 100644 index 0000000000..cd27d02076 --- /dev/null +++ b/src/drawing/engines/opengl/OpenGLFramebuffer.h @@ -0,0 +1,42 @@ +#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" + +struct SDL_Window; + +class OpenGLFramebuffer +{ +private: + GLuint _id; + GLuint _texture; + sint32 _width; + sint32 _height; + +public: + explicit OpenGLFramebuffer(SDL_Window * window); + OpenGLFramebuffer(sint32 width, sint32 height); + ~OpenGLFramebuffer(); + + GLuint GetWidth() const { return _width; } + GLuint GetHeight() const { return _height; } + GLuint GetTexture() const { return _texture; } + + void Bind(); +}; From db01547ae65dbf04d93ac93a526573c3f819bd5b Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 11 Jun 2016 03:06:30 +0100 Subject: [PATCH 09/27] implement OpenGL screenshot --- .../engines/opengl/OpenGLDrawingEngine.cpp | 8 ++- .../engines/opengl/OpenGLFramebuffer.cpp | 22 +++++++ .../engines/opengl/OpenGLFramebuffer.h | 1 + src/image_io.c | 61 +++++++++++++++++++ src/image_io.h | 1 + src/interface/screenshot.c | 16 +++++ src/interface/screenshot.h | 1 + 7 files changed, 108 insertions(+), 2 deletions(-) diff --git a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp index fc1bd08188..8b0fd9dfe7 100644 --- a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -47,6 +47,7 @@ IDrawingEngine * DrawingEngineFactory::CreateOpenGL() extern "C" { #include "../../../config.h" + #include "../../../interface/screenshot.h" #include "../../../interface/window.h" #include "../../../intro.h" #include "../../drawing.h" @@ -328,8 +329,11 @@ public: sint32 Screenshot() override { - // Not implemented - return -1; + _canvasFramebuffer->Bind(); + void * pixels = _canvasFramebuffer->GetPixels(); + int result = screenshot_dump_png_32bpp(_width, _height, pixels); + Memory::Free(pixels); + return result; } void CopyRect(sint32 x, sint32 y, sint32 width, sint32 height, sint32 dx, sint32 dy) override diff --git a/src/drawing/engines/opengl/OpenGLFramebuffer.cpp b/src/drawing/engines/opengl/OpenGLFramebuffer.cpp index 9f5315349e..5cab9df4ae 100644 --- a/src/drawing/engines/opengl/OpenGLFramebuffer.cpp +++ b/src/drawing/engines/opengl/OpenGLFramebuffer.cpp @@ -15,6 +15,7 @@ #pragma endregion #include +#include "../../../core/Memory.hpp" #include "OpenGLFramebuffer.h" constexpr GLuint BACKBUFFER_ID = 0; @@ -56,3 +57,24 @@ void OpenGLFramebuffer::Bind() glBindFramebuffer(GL_FRAMEBUFFER, _id); glViewport(0, 0, (GLsizei)_width, (GLsizei)_height); } + +void * OpenGLFramebuffer::GetPixels() const +{ + void * pixels = Memory::Allocate(_width * _height * 4); + glReadPixels(0, 0, _width, _height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Flip pixels vertically + void * flippedPixels = Memory::Allocate(_width * _height * 4); + size_t stride = _width * 4; + uint8 * src = (uint8 *)pixels + ((_height - 1) * stride); + uint8 * dst = (uint8 *)flippedPixels; + for (sint32 y = 0; y < _height; y++) + { + Memory::Copy(dst, src, stride); + src -= stride; + dst += stride; + } + Memory::Free(pixels); + + return flippedPixels; +} diff --git a/src/drawing/engines/opengl/OpenGLFramebuffer.h b/src/drawing/engines/opengl/OpenGLFramebuffer.h index cd27d02076..bab36dd67d 100644 --- a/src/drawing/engines/opengl/OpenGLFramebuffer.h +++ b/src/drawing/engines/opengl/OpenGLFramebuffer.h @@ -39,4 +39,5 @@ public: GLuint GetTexture() const { return _texture; } void Bind(); + void * GetPixels() const; }; diff --git a/src/image_io.c b/src/image_io.c index f897a20c88..b1909308b0 100644 --- a/src/image_io.c +++ b/src/image_io.c @@ -171,6 +171,67 @@ bool image_io_png_write(const rct_drawpixelinfo *dpi, const rct_palette *palette return true; } +static void image_io_png_warning(png_structp png_ptr, const char *b) +{ + log_warning(b); +} + +static void image_io_png_error(png_structp png_ptr, const char *b) +{ + log_error(b); +} + +bool image_io_png_write_32bpp(sint32 width, sint32 height, const void *pixels, const utf8 *path) +{ + // Setup PNG + png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, image_io_png_error, image_io_png_warning); + if (png_ptr == NULL) { + return false; + } + + png_infop info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) { + png_destroy_write_struct(&png_ptr, (png_infopp)NULL); + return false; + } + + // Open file for writing + SDL_RWops *file = SDL_RWFromFile(path, "wb"); + if (file == NULL) { + png_destroy_write_struct(&png_ptr, (png_infopp)NULL); + return false; + } + png_set_write_fn(png_ptr, file, my_png_write_data, my_png_flush); + + // Set error handler + if (setjmp(png_jmpbuf(png_ptr))) { + png_destroy_write_struct(&png_ptr, &info_ptr); + SDL_RWclose(file); + return false; + } + + // Write header + png_set_IHDR( + png_ptr, info_ptr, width, height, 8, + PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT + ); + png_write_info(png_ptr, info_ptr); + + // Write pixels + uint8 *bits = (uint8*)pixels; + for (int y = 0; y < height; y++) { + png_write_row(png_ptr, (png_byte *)bits); + bits += width * 4; + } + + // Finish + png_write_end(png_ptr, NULL); + SDL_RWclose(file); + + png_destroy_write_struct(&png_ptr, &info_ptr); + return true; +} + static void my_png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { SDL_RWops *file = (SDL_RWops*)png_get_io_ptr(png_ptr); diff --git a/src/image_io.h b/src/image_io.h index 6e920963fc..82a45a91b4 100644 --- a/src/image_io.h +++ b/src/image_io.h @@ -23,5 +23,6 @@ bool image_io_png_read(uint8 **pixels, uint32 *width, uint32 *height, const utf8 *path); bool image_io_png_write(const rct_drawpixelinfo *dpi, const rct_palette *palette, const utf8 *path); +bool image_io_png_write_32bpp(sint32 width, sint32 height, const void *pixels, const utf8 *path); #endif diff --git a/src/interface/screenshot.c b/src/interface/screenshot.c index 7ba9a5bc02..19ed7ff9bd 100644 --- a/src/interface/screenshot.c +++ b/src/interface/screenshot.c @@ -115,6 +115,22 @@ int screenshot_dump_png(rct_drawpixelinfo *dpi) } } +int screenshot_dump_png_32bpp(sint32 width, sint32 height, const void *pixels) +{ + // Get a free screenshot path + int index; + char path[MAX_PATH] = ""; + if ((index = screenshot_get_next_path(path)) == -1) { + return -1; + } + + if (image_io_png_write_32bpp(width, height, pixels, path)) { + return index; + } else { + return -1; + } +} + void screenshot_giant() { int originalRotation = get_current_rotation(); diff --git a/src/interface/screenshot.h b/src/interface/screenshot.h index 5b14a788d8..f29d54515c 100644 --- a/src/interface/screenshot.h +++ b/src/interface/screenshot.h @@ -22,6 +22,7 @@ void screenshot_check(); int screenshot_dump(); int screenshot_dump_png(rct_drawpixelinfo *dpi); +int screenshot_dump_png_32bpp(sint32 width, sint32 height, const void *pixels); void screenshot_giant(); int cmdline_for_screenshot(const char **argv, int argc); From 2a569dc062fe24ceea52f5a275e59aaefcea3d1d Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 11 Jun 2016 15:18:31 +0100 Subject: [PATCH 10/27] implement a ping-pong framebuffer --- data/shaders/copyframebuffer.frag | 13 +++ data/shaders/copyframebuffer.vert | 42 +++++++++ openrct2.vcxproj | 6 ++ .../engines/opengl/CopyFramebufferShader.cpp | 86 +++++++++++++++++++ .../engines/opengl/CopyFramebufferShader.h | 48 +++++++++++ .../engines/opengl/DrawImageMaskedShader.cpp | 2 +- .../engines/opengl/DrawImageShader.cpp | 2 +- src/drawing/engines/opengl/FillRectShader.cpp | 2 +- .../engines/opengl/OpenGLDrawingEngine.cpp | 46 +++++----- .../engines/opengl/OpenGLFramebuffer.cpp | 2 +- .../engines/opengl/OpenGLFramebuffer.h | 2 +- .../engines/opengl/SwapFramebuffer.cpp | 68 +++++++++++++++ src/drawing/engines/opengl/SwapFramebuffer.h | 70 +++++++++++++++ 13 files changed, 363 insertions(+), 26 deletions(-) create mode 100644 data/shaders/copyframebuffer.frag create mode 100644 data/shaders/copyframebuffer.vert create mode 100644 src/drawing/engines/opengl/CopyFramebufferShader.cpp create mode 100644 src/drawing/engines/opengl/CopyFramebufferShader.h create mode 100644 src/drawing/engines/opengl/SwapFramebuffer.cpp create mode 100644 src/drawing/engines/opengl/SwapFramebuffer.h diff --git a/data/shaders/copyframebuffer.frag b/data/shaders/copyframebuffer.frag new file mode 100644 index 0000000000..65071fff10 --- /dev/null +++ b/data/shaders/copyframebuffer.frag @@ -0,0 +1,13 @@ +#version 330 + +uniform sampler2D uTexture; + +in vec2 fPosition; +in vec2 fTextureCoordinate; + +layout (location = 0) out vec4 oColour; + +void main() +{ + oColour = texture(uTexture, fTextureCoordinate); +} diff --git a/data/shaders/copyframebuffer.vert b/data/shaders/copyframebuffer.vert new file mode 100644 index 0000000000..577ec0ef2b --- /dev/null +++ b/data/shaders/copyframebuffer.vert @@ -0,0 +1,42 @@ +#version 330 + +uniform ivec2 uScreenSize; +uniform ivec4 uBounds; +uniform ivec4 uTextureCoordinates; + +in int vIndex; + +out vec2 fPosition; +out vec2 fTextureCoordinate; + +void main() +{ + vec2 pos; + switch (vIndex) { + case 0: + pos = uBounds.xy; + fTextureCoordinate = uTextureCoordinates.xy; + break; + case 1: + pos = uBounds.zy; + fTextureCoordinate = uTextureCoordinates.zy; + break; + case 2: + pos = uBounds.zw; + fTextureCoordinate = uTextureCoordinates.zw; + break; + case 3: + pos = uBounds.xw; + fTextureCoordinate = uTextureCoordinates.xw; + break; + } + + fPosition = pos; + + // Transform screen coordinates to viewport + 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.0, 1.0); +} diff --git a/openrct2.vcxproj b/openrct2.vcxproj index c048c39194..d9475594b5 100644 --- a/openrct2.vcxproj +++ b/openrct2.vcxproj @@ -16,6 +16,8 @@ + + @@ -48,6 +50,7 @@ + @@ -55,6 +58,7 @@ + @@ -349,6 +353,7 @@ + @@ -356,6 +361,7 @@ + diff --git a/src/drawing/engines/opengl/CopyFramebufferShader.cpp b/src/drawing/engines/opengl/CopyFramebufferShader.cpp new file mode 100644 index 0000000000..943ab6bdcc --- /dev/null +++ b/src/drawing/engines/opengl/CopyFramebufferShader.cpp @@ -0,0 +1,86 @@ +#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 "CopyFramebufferShader.h" + +CopyFramebufferShader::CopyFramebufferShader() : OpenGLShaderProgram("copyframebuffer") +{ + GetLocations(); + + glGenBuffers(1, &_vbo); + glGenVertexArrays(1, &_vao); + + vec2i vertices[] = { 0, 1, 2, 3 }; + glBindBuffer(GL_ARRAY_BUFFER, _vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + glBindVertexArray(_vao); + glEnableVertexAttribArray(vIndex); + glVertexAttribIPointer(vIndex, 1, GL_INT, 0, nullptr); + + Use(); + SetTextureCoordinates(0, 0, 1, 1); +} + +CopyFramebufferShader::~CopyFramebufferShader() +{ + glDeleteBuffers(1, &_vbo); + glDeleteVertexArrays(1, &_vao); + + glBindVertexArray(_vao); +} + +void CopyFramebufferShader::GetLocations() +{ + uScreenSize = GetUniformLocation("uScreenSize"); + uBounds = GetUniformLocation("uBounds"); + uTextureCoordinates = GetUniformLocation("uTextureCoordinates"); + uTexture = GetUniformLocation("uTexture"); + + vIndex = GetAttributeLocation("vIndex"); +} + +void CopyFramebufferShader::SetScreenSize(sint32 width, sint32 height) +{ + glUniform2i(uScreenSize, width, height); +} + +void CopyFramebufferShader::SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom) +{ + glUniform4i(uBounds, left, top, right, bottom); +} + +void CopyFramebufferShader::SetTextureCoordinates(sint32 left, sint32 top, sint32 right, sint32 bottom) +{ + glUniform4i(uTextureCoordinates, left, top, right, bottom); +} + +void CopyFramebufferShader::SetTexture(GLuint texture) +{ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture); + glUniform1i(uTexture, 0); +} + +void CopyFramebufferShader::Draw() +{ + glBindVertexArray(_vao); + glDrawArrays(GL_QUADS, 0, 4); +} + +#endif /* DISABLE_OPENGL */ diff --git a/src/drawing/engines/opengl/CopyFramebufferShader.h b/src/drawing/engines/opengl/CopyFramebufferShader.h new file mode 100644 index 0000000000..2ba4cb3887 --- /dev/null +++ b/src/drawing/engines/opengl/CopyFramebufferShader.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 CopyFramebufferShader : public OpenGLShaderProgram +{ +private: + GLuint uScreenSize; + GLuint uBounds; + GLuint uTextureCoordinates; + GLuint uTexture; + + GLuint vIndex; + + GLuint _vbo; + GLuint _vao; + +public: + CopyFramebufferShader(); + ~CopyFramebufferShader() override; + + void SetScreenSize(sint32 width, sint32 height); + void SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom); + void SetTextureCoordinates(sint32 left, sint32 top, sint32 right, sint32 bottom); + void SetTexture(GLuint texture); + + void Draw(); + +private: + void GetLocations(); +}; diff --git a/src/drawing/engines/opengl/DrawImageMaskedShader.cpp b/src/drawing/engines/opengl/DrawImageMaskedShader.cpp index c548110fed..f7a1f1187a 100644 --- a/src/drawing/engines/opengl/DrawImageMaskedShader.cpp +++ b/src/drawing/engines/opengl/DrawImageMaskedShader.cpp @@ -27,7 +27,7 @@ DrawImageMaskedShader::DrawImageMaskedShader() : OpenGLShaderProgram("drawimagem vec2i vertices[] = { 0, 1, 2, 3 }; glBindBuffer(GL_ARRAY_BUFFER, _vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STREAM_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindVertexArray(_vao); glEnableVertexAttribArray(vIndex); diff --git a/src/drawing/engines/opengl/DrawImageShader.cpp b/src/drawing/engines/opengl/DrawImageShader.cpp index 6a42fa6e09..b45a52d0e8 100644 --- a/src/drawing/engines/opengl/DrawImageShader.cpp +++ b/src/drawing/engines/opengl/DrawImageShader.cpp @@ -27,7 +27,7 @@ DrawImageShader::DrawImageShader() : OpenGLShaderProgram("drawimage") vec2i vertices[] = { 0, 1, 2, 3 }; glBindBuffer(GL_ARRAY_BUFFER, _vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STREAM_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindVertexArray(_vao); glEnableVertexAttribArray(vIndex); diff --git a/src/drawing/engines/opengl/FillRectShader.cpp b/src/drawing/engines/opengl/FillRectShader.cpp index a24b98b2ca..417a35cb2e 100644 --- a/src/drawing/engines/opengl/FillRectShader.cpp +++ b/src/drawing/engines/opengl/FillRectShader.cpp @@ -27,7 +27,7 @@ FillRectShader::FillRectShader() : OpenGLShaderProgram("fillrect") vec2i vertices[] = { 0, 1, 2, 3 }; glBindBuffer(GL_ARRAY_BUFFER, _vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STREAM_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindVertexArray(_vao); glEnableVertexAttribArray(vIndex); diff --git a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp index 8b0fd9dfe7..6f03fa3f07 100644 --- a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -32,9 +32,11 @@ IDrawingEngine * DrawingEngineFactory::CreateOpenGL() #include "GLSLTypes.h" #include "OpenGLAPI.h" #include "OpenGLFramebuffer.h" +#include "CopyFramebufferShader.h" #include "DrawImageShader.h" #include "DrawImageMaskedShader.h" #include "FillRectShader.h" +#include "SwapFramebuffer.h" #include "../../../core/Console.hpp" #include "../../../core/Exception.hpp" @@ -221,9 +223,9 @@ private: OpenGLDrawingContext * _drawingContext; - DrawImageShader * _drawImageShader = nullptr; - OpenGLFramebuffer * _screenFramebuffer = nullptr; - OpenGLFramebuffer * _canvasFramebuffer = nullptr; + CopyFramebufferShader * _copyFramebufferShader = nullptr; + OpenGLFramebuffer * _screenFramebuffer = nullptr; + SwapFramebuffer * _swapFramebuffer = nullptr; public: SDL_Color Palette[256]; @@ -236,7 +238,7 @@ public: ~OpenGLDrawingEngine() override { - delete _drawImageShader; + delete _copyFramebufferShader; delete _drawingContext; delete [] _bits; @@ -265,7 +267,7 @@ public: glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); - _drawImageShader = new DrawImageShader(); + _copyFramebufferShader = new CopyFramebufferShader(); } void Resize(uint32 width, uint32 height) override @@ -296,9 +298,9 @@ public: void Draw() override { assert(_screenFramebuffer != nullptr); - assert(_canvasFramebuffer != nullptr); + assert(_swapFramebuffer != nullptr); - _canvasFramebuffer->Bind(); + _swapFramebuffer->Bind(); if (gIntroState != INTRO_STATE_NONE) { intro_draw(&_bitsDPI); @@ -308,6 +310,8 @@ public: window_update_all(); gfx_draw_pickedup_peep(&_bitsDPI); + + _swapFramebuffer->SwapCopy(); rct2_draw(&_bitsDPI); } @@ -317,20 +321,20 @@ public: sint32 width = _screenFramebuffer->GetWidth(); sint32 height = _screenFramebuffer->GetHeight(); - _drawImageShader->Use(); - _drawImageShader->SetScreenSize(width, height); - _drawImageShader->SetClip(0, 0, width, height); - _drawImageShader->SetTexture(_canvasFramebuffer->GetTexture()); - _drawImageShader->SetTextureCoordinates(0, 1, 1, 0); - _drawImageShader->Draw(0, 0, width, height); + _copyFramebufferShader->Use(); + _copyFramebufferShader->SetTexture(_swapFramebuffer->GetTargetFramebuffer() + ->GetTexture()); + _copyFramebufferShader->Draw(); Display(); } sint32 Screenshot() override { - _canvasFramebuffer->Bind(); - void * pixels = _canvasFramebuffer->GetPixels(); + const OpenGLFramebuffer * framebuffer = _swapFramebuffer->GetTargetFramebuffer(); + framebuffer->Bind(); + void * pixels = framebuffer->GetPixels(); + int result = screenshot_dump_png_32bpp(_width, _height, pixels); Memory::Free(pixels); return result; @@ -425,13 +429,13 @@ private: _screenFramebuffer = new OpenGLFramebuffer(_window); // Re-create canvas framebuffer - delete _canvasFramebuffer; - _canvasFramebuffer = new OpenGLFramebuffer(_width, _height); + delete _swapFramebuffer; + _swapFramebuffer = new SwapFramebuffer(_width, _height); - _drawImageShader->Use(); - _drawImageShader->SetScreenSize(_width, _height); - _drawImageShader->SetClip(0, 0, _width, _height); - _drawImageShader->SetTexture(_canvasFramebuffer->GetTexture()); + _copyFramebufferShader->Use(); + _copyFramebufferShader->SetScreenSize(_width, _height); + _copyFramebufferShader->SetBounds(0, 0, _width, _height); + _copyFramebufferShader->SetTextureCoordinates(0, 1, 1, 0); } void Display() diff --git a/src/drawing/engines/opengl/OpenGLFramebuffer.cpp b/src/drawing/engines/opengl/OpenGLFramebuffer.cpp index 5cab9df4ae..c1e21e433c 100644 --- a/src/drawing/engines/opengl/OpenGLFramebuffer.cpp +++ b/src/drawing/engines/opengl/OpenGLFramebuffer.cpp @@ -52,7 +52,7 @@ OpenGLFramebuffer::~OpenGLFramebuffer() } } -void OpenGLFramebuffer::Bind() +void OpenGLFramebuffer::Bind() const { glBindFramebuffer(GL_FRAMEBUFFER, _id); glViewport(0, 0, (GLsizei)_width, (GLsizei)_height); diff --git a/src/drawing/engines/opengl/OpenGLFramebuffer.h b/src/drawing/engines/opengl/OpenGLFramebuffer.h index bab36dd67d..9e5c5054d3 100644 --- a/src/drawing/engines/opengl/OpenGLFramebuffer.h +++ b/src/drawing/engines/opengl/OpenGLFramebuffer.h @@ -38,6 +38,6 @@ public: GLuint GetHeight() const { return _height; } GLuint GetTexture() const { return _texture; } - void Bind(); + void Bind() const; void * GetPixels() const; }; diff --git a/src/drawing/engines/opengl/SwapFramebuffer.cpp b/src/drawing/engines/opengl/SwapFramebuffer.cpp new file mode 100644 index 0000000000..259733f241 --- /dev/null +++ b/src/drawing/engines/opengl/SwapFramebuffer.cpp @@ -0,0 +1,68 @@ +#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 "CopyFramebufferShader.h" +#include "OpenGLFramebuffer.h" +#include "SwapFramebuffer.h" + +SwapFramebuffer::SwapFramebuffer(sint32 width, sint32 height) +{ + _width = width; + _height = height; + _targetFramebufferIndex = 0; + _framebuffer[0] = new OpenGLFramebuffer(width, height); + _framebuffer[1] = new OpenGLFramebuffer(width, height); + _targetFramebuffer = _framebuffer[0]; + + _copyFramebufferShader = new CopyFramebufferShader(); + _copyFramebufferShader->Use(); + _copyFramebufferShader->SetScreenSize(_width, _height); + _copyFramebufferShader->SetBounds(0, 0, _width, _height); + _copyFramebufferShader->SetTextureCoordinates(0, 1, 1, 0); +} + +SwapFramebuffer::~SwapFramebuffer() +{ + delete _framebuffer[0]; + delete _framebuffer[1]; + delete _copyFramebufferShader; +} + +GLuint SwapFramebuffer::GetSourceTexture() const +{ + return _sourceFramebuffer->GetTexture(); +} + +void SwapFramebuffer::SwapCopy() +{ + _sourceFramebuffer = _targetFramebuffer; + _targetFramebufferIndex = (_targetFramebufferIndex + 1) & 1; + _targetFramebuffer = _framebuffer[_targetFramebufferIndex]; + _targetFramebuffer->Bind(); + + _copyFramebufferShader->Use(); + _copyFramebufferShader->SetTexture(GetSourceTexture()); + _copyFramebufferShader->Draw(); +} + +void SwapFramebuffer::Bind() +{ + _targetFramebuffer->Bind(); +} + +#endif /* DISABLE_OPENGL */ diff --git a/src/drawing/engines/opengl/SwapFramebuffer.h b/src/drawing/engines/opengl/SwapFramebuffer.h new file mode 100644 index 0000000000..68b638cd53 --- /dev/null +++ b/src/drawing/engines/opengl/SwapFramebuffer.h @@ -0,0 +1,70 @@ +#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 CopyFramebufferShader; +class OpenGLFramebuffer; + +/** + * Class to maintain two different framebuffers where the active framebuffer + * will swap between the two, copying the other's pixels in the process for + * performing pre-processing filters. + * + * When you need to bind the current frame to a shader, call SwapCopy and + * then bind the value of GetSourceTexture to your shader. + */ +class SwapFramebuffer +{ +private: + sint32 _width; + sint32 _height; + uint8 _targetFramebufferIndex; + OpenGLFramebuffer * _targetFramebuffer; + OpenGLFramebuffer * _sourceFramebuffer; + OpenGLFramebuffer * _framebuffer[2]; + + CopyFramebufferShader * _copyFramebufferShader = nullptr; + +public: + SwapFramebuffer(sint32 width, sint32 height); + ~SwapFramebuffer(); + + /** + * Gets the current target framebuffer. + */ + const OpenGLFramebuffer * GetTargetFramebuffer() const { return _targetFramebuffer; } + + /** + * Gets the texture ID for the source framebuffer. + */ + GLuint GetSourceTexture() const; + + /** + * Swaps the target framebuffer, binds it and then draws the previous + * framebuffer resulting in the two buffers matching and ready for + * pre-processing. + */ + void SwapCopy(); + + /** + * Binds the current target framebuffer. + */ + void Bind(); +}; From e34ee157384a5a6cce583b4426e923477071bef2 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 11 Jun 2016 16:46:24 +0100 Subject: [PATCH 11/27] implement overlay transparency for FillRect --- data/shaders/fillrect.frag | 43 ++++++++++++++++--- src/drawing/engines/opengl/FillRectShader.cpp | 11 +++++ src/drawing/engines/opengl/FillRectShader.h | 4 ++ .../engines/opengl/OpenGLDrawingEngine.cpp | 26 +++++++++-- 4 files changed, 75 insertions(+), 9 deletions(-) diff --git a/data/shaders/fillrect.frag b/data/shaders/fillrect.frag index c233dfb009..7860eaba2f 100644 --- a/data/shaders/fillrect.frag +++ b/data/shaders/fillrect.frag @@ -1,13 +1,23 @@ #version 330 -uniform ivec4 uClip; -uniform int uFlags; -uniform vec4 uColour[2]; +uniform ivec2 uScreenSize; +uniform ivec4 uClip; +uniform int uFlags; +uniform vec4 uColour[2]; +uniform sampler2D uSourceFramebuffer; +uniform ivec4 uBounds; in vec2 fPosition; layout (location = 0) out vec4 oColour; +float getluma(vec3 colour) +{ + return (colour.r * 0.2126) + + (colour.g * 0.7152) + + (colour.b * 0.0722); +} + void main() { if (fPosition.x < uClip.x || fPosition.x > uClip.z || @@ -16,13 +26,36 @@ void main() discard; } + vec4 targetColour; int posSum = int(fPosition.x) + int(fPosition.y); if ((posSum % 2) == 0) { - oColour = uColour[0]; + targetColour = uColour[0]; } else { - oColour = uColour[1]; + targetColour = uColour[1]; + } + + if ((uFlags & 1) != 0) + { + vec2 textureCoordinates = (fPosition / vec2(uScreenSize)) * vec2(1, -1); + vec4 sourceColour = texture(uSourceFramebuffer, textureCoordinates); + + float luma = getluma(sourceColour.rgb); + sourceColour = vec4(vec3(luma), 1); + + if (luma < 0.5) + { + oColour = 2.0 * sourceColour * targetColour; + } + else + { + oColour = 1.0 - 2.0 * (1.0 - sourceColour) * (1.0 - targetColour); + } + } + else + { + oColour = targetColour; } } diff --git a/src/drawing/engines/opengl/FillRectShader.cpp b/src/drawing/engines/opengl/FillRectShader.cpp index 417a35cb2e..7e8cd654a9 100644 --- a/src/drawing/engines/opengl/FillRectShader.cpp +++ b/src/drawing/engines/opengl/FillRectShader.cpp @@ -17,6 +17,7 @@ #ifndef DISABLE_OPENGL #include "FillRectShader.h" +#include "OpenGLFramebuffer.h" FillRectShader::FillRectShader() : OpenGLShaderProgram("fillrect") { @@ -32,6 +33,9 @@ FillRectShader::FillRectShader() : OpenGLShaderProgram("fillrect") glBindVertexArray(_vao); glEnableVertexAttribArray(vIndex); glVertexAttribIPointer(vIndex, 1, GL_INT, 0, 0); + + Use(); + SetFlags(0); } FillRectShader::~FillRectShader() @@ -79,6 +83,13 @@ void FillRectShader::SetColour(int index, vec4f colour) glUniform4f(uColour[index], colour.r, colour.g, colour.b, colour.a); } +void FillRectShader::SetSourceFramebuffer(GLuint texture) +{ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture); + glUniform1i(uSourceFramebuffer, 0); +} + void FillRectShader::Draw(sint32 left, sint32 top, sint32 right, sint32 bottom) { SetBounds(left, top, right, bottom); diff --git a/src/drawing/engines/opengl/FillRectShader.h b/src/drawing/engines/opengl/FillRectShader.h index c47e9a9315..d96c33c705 100644 --- a/src/drawing/engines/opengl/FillRectShader.h +++ b/src/drawing/engines/opengl/FillRectShader.h @@ -19,6 +19,8 @@ #include "GLSLTypes.h" #include "OpenGLShaderProgram.h" +class OpenGLFramebuffer; + class FillRectShader : public OpenGLShaderProgram { private: @@ -27,6 +29,7 @@ private: GLuint uBounds; GLuint uFlags; GLuint uColour[2]; + GLuint uSourceFramebuffer; GLuint vIndex; @@ -42,6 +45,7 @@ public: void SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom); void SetFlags(uint32 flags); void SetColour(int index, vec4f colour); + void SetSourceFramebuffer(GLuint texture); void Draw(sint32 left, sint32 top, sint32 right, sint32 bottom); diff --git a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp index 6f03fa3f07..7059dac76a 100644 --- a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -281,7 +281,7 @@ public: for (int i = 0; i < 256; i++) { SDL_Color colour = palette[i]; - colour.a = 255; + colour.a = i == 0 ? 0 : 255; Palette[i] = colour; GLPalette[i] = { colour.r / 255.0f, @@ -371,6 +371,12 @@ public: return &_bitsDPI; } + GLuint SwapCopyReturningSourceTexture() + { + _swapFramebuffer->SwapCopy(); + return _swapFramebuffer->GetSourceTexture(); + } + private: void ConfigureBits(uint32 width, uint32 height, uint32 pitch) { @@ -486,6 +492,9 @@ void OpenGLDrawingContext::FillRect(uint32 colour, sint32 left, sint32 top, sint if (colour & 0x1000000) { paletteColour[1].a = 0; + + _fillRectShader->Use(); + _fillRectShader->SetFlags(0); } else if (colour & 0x2000000) { @@ -498,11 +507,20 @@ void OpenGLDrawingContext::FillRect(uint32 colour, sint32 left, sint32 top, sint paletteColour[0].r = transformColour.r; paletteColour[0].g = transformColour.g; paletteColour[0].b = transformColour.b; - paletteColour[0].a = 0.5f; + paletteColour[0].a = 1; paletteColour[1] = paletteColour[0]; + + GLuint srcTexture = _engine->SwapCopyReturningSourceTexture(); + _fillRectShader->Use(); + _fillRectShader->SetFlags(1); + _fillRectShader->SetSourceFramebuffer(srcTexture); + } + else + { + _fillRectShader->Use(); + _fillRectShader->SetFlags(0); } - _fillRectShader->Use(); _fillRectShader->SetScreenSize(gScreenWidth, gScreenHeight); _fillRectShader->SetColour(0, paletteColour[0]); _fillRectShader->SetColour(1, paletteColour[1]); @@ -726,7 +744,7 @@ void * OpenGLDrawingContext::GetImageAsARGB(uint32 image, uint32 tertiaryColour, *dst++ = colour.r; *dst++ = colour.g; *dst++ = colour.b; - *dst++ = 255; + *dst++ = colour.a; } } From e3ecb91b919514e1608367cdff80780647562414 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 11 Jun 2016 17:43:53 +0100 Subject: [PATCH 12/27] implement DrawLine with shader --- data/shaders/drawline.frag | 20 +++++ data/shaders/drawline.vert | 30 +++++++ openrct2.vcxproj | 4 + src/drawing/engines/opengl/DrawLineShader.cpp | 86 +++++++++++++++++++ src/drawing/engines/opengl/DrawLineShader.h | 48 +++++++++++ .../engines/opengl/OpenGLDrawingEngine.cpp | 17 ++-- 6 files changed, 198 insertions(+), 7 deletions(-) create mode 100644 data/shaders/drawline.frag create mode 100644 data/shaders/drawline.vert create mode 100644 src/drawing/engines/opengl/DrawLineShader.cpp create mode 100644 src/drawing/engines/opengl/DrawLineShader.h diff --git a/data/shaders/drawline.frag b/data/shaders/drawline.frag new file mode 100644 index 0000000000..3e1ef5f151 --- /dev/null +++ b/data/shaders/drawline.frag @@ -0,0 +1,20 @@ +#version 330 + +uniform ivec2 uScreenSize; +uniform ivec4 uClip; +uniform vec4 uColour; + +in vec2 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/drawline.vert b/data/shaders/drawline.vert new file mode 100644 index 0000000000..5bfb974472 --- /dev/null +++ b/data/shaders/drawline.vert @@ -0,0 +1,30 @@ +#version 330 + +uniform ivec2 uScreenSize; +uniform ivec4 uBounds; + +in int vIndex; + +out vec2 fPosition; + +void main() +{ + vec2 pos; + if (vIndex == 0) + { + pos = uBounds.xy; + } + else + { + pos = uBounds.zw; + } + + fPosition = pos; + + // Transform screen coordinates to viewport + 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.0, 1.0); +} diff --git a/openrct2.vcxproj b/openrct2.vcxproj index d9475594b5..e55b959f7f 100644 --- a/openrct2.vcxproj +++ b/openrct2.vcxproj @@ -22,6 +22,8 @@ + + @@ -53,6 +55,7 @@ + @@ -356,6 +359,7 @@ + diff --git a/src/drawing/engines/opengl/DrawLineShader.cpp b/src/drawing/engines/opengl/DrawLineShader.cpp new file mode 100644 index 0000000000..5f220ee6c9 --- /dev/null +++ b/src/drawing/engines/opengl/DrawLineShader.cpp @@ -0,0 +1,86 @@ +#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 "DrawLineShader.h" +#include "OpenGLFramebuffer.h" + +DrawLineShader::DrawLineShader() : OpenGLShaderProgram("drawline") +{ + GetLocations(); + + glGenBuffers(1, &_vbo); + glGenVertexArrays(1, &_vao); + + vec2i vertices[] = { 0, 1 }; + glBindBuffer(GL_ARRAY_BUFFER, _vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + glBindVertexArray(_vao); + glEnableVertexAttribArray(vIndex); + glVertexAttribIPointer(vIndex, 1, GL_INT, 0, nullptr); + + Use(); +} + +DrawLineShader::~DrawLineShader() +{ + glDeleteBuffers(1, &_vbo); + glDeleteVertexArrays(1, &_vao); + + glBindVertexArray(_vao); +} + +void DrawLineShader::GetLocations() +{ + uScreenSize = GetUniformLocation("uScreenSize"); + uClip = GetUniformLocation("uClip"); + uBounds = GetUniformLocation("uBounds"); + uColour = GetUniformLocation("uColour"); + + vIndex = GetAttributeLocation("vIndex"); +} + +void DrawLineShader::SetScreenSize(sint32 width, sint32 height) +{ + glUniform2i(uScreenSize, width, height); +} + +void DrawLineShader::SetClip(sint32 left, sint32 top, sint32 right, sint32 bottom) +{ + glUniform4i(uClip, left, top, right, bottom); +} + +void DrawLineShader::SetBounds(sint32 x0, sint32 y0, sint32 x1, sint32 y1) +{ + glUniform4i(uBounds, x0, y0, x1, y1); +} + +void DrawLineShader::SetColour(vec4f colour) +{ + glUniform4f(uColour, colour.r, colour.g, colour.b, colour.a); +} + +void DrawLineShader::Draw(sint32 x0, sint32 y0, sint32 x1, sint32 y1) +{ + SetBounds(x0, y0, x1, y1); + + glBindVertexArray(_vao); + glDrawArrays(GL_LINES, 0, 2); +} + +#endif /* DISABLE_OPENGL */ diff --git a/src/drawing/engines/opengl/DrawLineShader.h b/src/drawing/engines/opengl/DrawLineShader.h new file mode 100644 index 0000000000..f8473b8dd9 --- /dev/null +++ b/src/drawing/engines/opengl/DrawLineShader.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 DrawLineShader : public OpenGLShaderProgram +{ +private: + GLuint uScreenSize; + GLuint uClip; + GLuint uBounds; + GLuint uColour; + + GLuint vIndex; + + GLuint _vbo; + GLuint _vao; + +public: + DrawLineShader(); + ~DrawLineShader() override; + + void SetScreenSize(sint32 width, sint32 height); + void SetClip(sint32 left, sint32 top, sint32 right, sint32 bottom); + void SetBounds(sint32 x0, sint32 y0, sint32 x1, sint32 y1); + void SetColour(vec4f colour); + + void Draw(sint32 x0, sint32 y0, sint32 x1, sint32 y1); + +private: + void GetLocations(); +}; diff --git a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp index 7059dac76a..8ce77e2cda 100644 --- a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -35,6 +35,7 @@ IDrawingEngine * DrawingEngineFactory::CreateOpenGL() #include "CopyFramebufferShader.h" #include "DrawImageShader.h" #include "DrawImageMaskedShader.h" +#include "DrawLineShader.h" #include "FillRectShader.h" #include "SwapFramebuffer.h" @@ -169,6 +170,7 @@ private: DrawImageShader * _drawImageShader = nullptr; DrawImageMaskedShader * _drawImageMaskedShader = nullptr; + DrawLineShader * _drawLineShader = nullptr; FillRectShader * _fillRectShader = nullptr; GLuint _vbo; @@ -464,6 +466,7 @@ OpenGLDrawingContext::~OpenGLDrawingContext() { delete _drawImageShader; delete _drawImageMaskedShader; + delete _drawLineShader; delete _fillRectShader; } @@ -476,6 +479,7 @@ void OpenGLDrawingContext::Initialise() { _drawImageShader = new DrawImageShader(); _drawImageMaskedShader = new DrawImageMaskedShader(); + _drawLineShader = new DrawLineShader(); _fillRectShader = new FillRectShader(); } @@ -530,14 +534,13 @@ void OpenGLDrawingContext::FillRect(uint32 colour, sint32 left, sint32 top, sint void OpenGLDrawingContext::DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32 x2, sint32 y2) { - return; - vec4f paletteColour = _engine->GLPalette[colour & 0xFF]; - glColor3f(paletteColour.r, paletteColour.g, paletteColour.b); - glBegin(GL_LINES); - glVertex2i(x1, y1); - glVertex2i(x2, y2); - glEnd(); + + _drawLineShader->Use(); + _drawLineShader->SetScreenSize(gScreenWidth, gScreenHeight); + _drawLineShader->SetClip(_clipLeft, _clipTop, _clipRight, _clipBottom); + _drawLineShader->SetColour(paletteColour); + _drawLineShader->Draw(x1, y1, x2, y2); } void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 tertiaryColour) From 33799d2ab9af89c3c0553b70c43d743fc9ea8bab Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 11 Jun 2016 17:46:54 +0100 Subject: [PATCH 13/27] remove deprecated OpenGL functions --- src/drawing/engines/opengl/OpenGLAPI.cpp | 9 ------ src/drawing/engines/opengl/OpenGLAPI.h | 36 ------------------------ 2 files changed, 45 deletions(-) diff --git a/src/drawing/engines/opengl/OpenGLAPI.cpp b/src/drawing/engines/opengl/OpenGLAPI.cpp index b95c3bf954..f8f1a680b5 100644 --- a/src/drawing/engines/opengl/OpenGLAPI.cpp +++ b/src/drawing/engines/opengl/OpenGLAPI.cpp @@ -55,8 +55,6 @@ static const char * TryLoadAllProcAddresses() SetupOpenGLFunction(glBlendFunc); SetupOpenGLFunction(glClear); SetupOpenGLFunction(glClearColor); - SetupOpenGLFunction(glColor3f); - SetupOpenGLFunction(glColor4f); SetupOpenGLFunction(glCullFace); SetupOpenGLFunction(glDeleteTextures); SetupOpenGLFunction(glDisable); @@ -65,16 +63,9 @@ static const char * TryLoadAllProcAddresses() SetupOpenGLFunction(glEnd); SetupOpenGLFunction(glGenTextures); SetupOpenGLFunction(glGetError); - SetupOpenGLFunction(glLoadIdentity); - SetupOpenGLFunction(glMatrixMode); - SetupOpenGLFunction(glOrtho); SetupOpenGLFunction(glReadPixels); - SetupOpenGLFunction(glScalef); - SetupOpenGLFunction(glTexCoord2f); SetupOpenGLFunction(glTexImage2D); SetupOpenGLFunction(glTexParameteri); - SetupOpenGLFunction(glTranslatef); - SetupOpenGLFunction(glVertex2i); SetupOpenGLFunction(glViewport); // 2.0+ functions diff --git a/src/drawing/engines/opengl/OpenGLAPI.h b/src/drawing/engines/opengl/OpenGLAPI.h index dc5163b5ef..4c4890ecdd 100644 --- a/src/drawing/engines/opengl/OpenGLAPI.h +++ b/src/drawing/engines/opengl/OpenGLAPI.h @@ -25,8 +25,6 @@ #define glBlendFunc __static__glBlendFunc #define glClear __static__glClear #define glClearColor __static__glClearColor -#define glColor3f __static__glColor3f -#define glColor4f __static__glColor4f #define glCullFace __static__glCullFace #define glDeleteTextures __static__glDeleteTextures #define glDisable __static__glDisable @@ -35,16 +33,9 @@ #define glEnd __static__glEnd #define glGenTextures __static__glGenTextures #define glGetError __static__glGetError -#define glLoadIdentity __static__glLoadIdentity -#define glMatrixMode __static__glMatrixMode -#define glOrtho __static__glOrtho #define glReadPixels __static__glReadPixels -#define glScalef __static__glScalef -#define glTexCoord2f __static__glTexCoord2f #define glTexImage2D __static__glTexImage2D #define glTexParameteri __static__glTexParameteri -#define glTranslatef __static__glTranslatef -#define glVertex2i __static__glVertex2i #define glViewport __static__glViewport #endif @@ -60,8 +51,6 @@ #undef glBlendFunc #undef glClear #undef glClearColor -#undef glColor3f -#undef glColor4f #undef glCullFace #undef glDeleteTextures #undef glDisable @@ -70,16 +59,9 @@ #undef glEnd #undef glGenTextures #undef glGetError -#undef glLoadIdentity -#undef glMatrixMode -#undef glOrtho #undef glReadPixels -#undef glScalef -#undef glTexCoord2f #undef glTexImage2D #undef glTexParameteri -#undef glTranslatef -#undef glVertex2i #undef glViewport // 1.1 function signatures @@ -88,8 +70,6 @@ typedef void (APIENTRYP PFNGLBINDTEXTUREPROC )(GLenum target, GLuint texture typedef void (APIENTRYP PFNGLBLENDFUNCPROC )(GLenum sfactor, GLenum dfactor); typedef void (APIENTRYP PFNGLCLEARPROC )(GLbitfield mask); typedef void (APIENTRYP PFNGLCLEARCOLORPROC )(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); -typedef void (APIENTRYP PFNGLCOLOR3FPROC )(GLfloat red, GLfloat green, GLfloat blue); -typedef void (APIENTRYP PFNGLCOLOR4FPROC )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); typedef void (APIENTRYP PFNGLCULLFACEPROC )(GLenum mode); typedef void (APIENTRYP PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint *textures); typedef void (APIENTRYP PFNGLDISABLEPROC )(GLenum cap); @@ -98,16 +78,9 @@ typedef void (APIENTRYP PFNGLENABLEPROC )(GLenum cap); typedef void (APIENTRYP PFNGLENDPROC )(void); typedef GLenum (APIENTRYP PFNGLGETERRORPROC )(void); typedef void (APIENTRYP PFNGLGENTEXTURESPROC )(GLsizei n, GLuint *textures); -typedef void (APIENTRYP PFNGLLOADIDENTITYPROC )(void); -typedef void (APIENTRYP PFNGLMATRIXMODEPROC )(GLenum mode); -typedef void (APIENTRYP PFNGLORTHOPROC )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val); typedef void (APIENTRYP PFNGLREADPIXELSPROC )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid * pixels); -typedef void (APIENTRYP PFNGLSCALEFPROC )(GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FPROC )(GLfloat s, GLfloat t); typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC )(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC )(GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLTRANSLATEFPROC )(GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLVERTEX2IPROC )(GLint x, GLint y); typedef void (APIENTRYP PFNGLVIEWPORTPROC )(GLint x, GLint y, GLsizei width, GLsizei height); #ifdef NO_EXTERN_GLAPI @@ -127,8 +100,6 @@ GLAPI_DECL PFNGLBINDTEXTUREPROC glBindTexture GLAP 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 PFNGLCULLFACEPROC glCullFace GLAPI_SET; GLAPI_DECL PFNGLDELETETEXTURESPROC glDeleteTextures GLAPI_SET; GLAPI_DECL PFNGLDISABLEPROC glDisable GLAPI_SET; @@ -137,16 +108,9 @@ GLAPI_DECL PFNGLENABLEPROC glEnable GLAP GLAPI_DECL PFNGLENDPROC glEnd GLAPI_SET; GLAPI_DECL PFNGLGENTEXTURESPROC glGenTextures GLAPI_SET; GLAPI_DECL PFNGLGETERRORPROC glGetError GLAPI_SET; -GLAPI_DECL PFNGLLOADIDENTITYPROC glLoadIdentity GLAPI_SET; -GLAPI_DECL PFNGLMATRIXMODEPROC glMatrixMode GLAPI_SET; -GLAPI_DECL PFNGLORTHOPROC glOrtho GLAPI_SET; GLAPI_DECL PFNGLREADPIXELSPROC glReadPixels 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 From 8185a88e47eda0b34c9811ba1b5775e44f34685e Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 11 Jun 2016 18:28:03 +0100 Subject: [PATCH 14/27] implement drawing solid coloured sprites --- data/shaders/drawimage.frag | 12 ++++- src/drawing/IDrawingContext.h | 1 + src/drawing/NewDrawing.cpp | 9 ++++ src/drawing/drawing.h | 1 + src/drawing/engines/SoftwareDrawingEngine.cpp | 12 +++++ .../engines/opengl/DrawImageShader.cpp | 13 ++++++ src/drawing/engines/opengl/DrawImageShader.h | 4 ++ .../engines/opengl/OpenGLDrawingEngine.cpp | 44 +++++++++++++++++++ src/interface/widget.c | 15 +------ 9 files changed, 97 insertions(+), 14 deletions(-) diff --git a/data/shaders/drawimage.frag b/data/shaders/drawimage.frag index 7e6fb568f3..a18e81433d 100644 --- a/data/shaders/drawimage.frag +++ b/data/shaders/drawimage.frag @@ -1,6 +1,8 @@ #version 330 uniform ivec4 uClip; +uniform int uFlags; +uniform vec4 uColour; uniform sampler2D uTexture; in vec2 fPosition; @@ -16,5 +18,13 @@ void main() discard; } - oColour = texture(uTexture, fTextureCoordinate); + vec4 texel = texture(uTexture, fTextureCoordinate); + if ((uFlags & 1) != 0) + { + oColour = vec4(uColour.rgb, uColour.a * texel.a); + } + else + { + oColour = texel; + } } diff --git a/src/drawing/IDrawingContext.h b/src/drawing/IDrawingContext.h index 9fecefbe6f..17bfb84505 100644 --- a/src/drawing/IDrawingContext.h +++ b/src/drawing/IDrawingContext.h @@ -32,4 +32,5 @@ interface IDrawingContext virtual void DrawSprite(uint32 image, sint32 x, sint32 y, uint32 tertiaryColour) abstract; virtual void DrawSpritePaletteSet(uint32 image, sint32 x, sint32 y, uint8 * palette, uint8 * unknown) abstract; virtual void DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage) abstract; + virtual void DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour) abstract; }; diff --git a/src/drawing/NewDrawing.cpp b/src/drawing/NewDrawing.cpp index 3e0b9795e5..acc84b6647 100644 --- a/src/drawing/NewDrawing.cpp +++ b/src/drawing/NewDrawing.cpp @@ -227,6 +227,15 @@ extern "C" } } + void FASTCALL gfx_draw_sprite_solid(rct_drawpixelinfo * dpi, int image, int x, int y, uint8 colour) + { + if (_drawingEngine != nullptr) + { + IDrawingContext * dc = _drawingEngine->GetDrawingContext(dpi); + dc->DrawSpriteSolid(image, x, y, colour); + } + } + int screenshot_dump() { if (_drawingEngine != nullptr) diff --git a/src/drawing/drawing.h b/src/drawing/drawing.h index 9e4f311611..4c0bbc0110 100644 --- a/src/drawing/drawing.h +++ b/src/drawing/drawing.h @@ -148,6 +148,7 @@ void FASTCALL gfx_rle_sprite_to_buffer(const uint8* RESTRICT source_bits_pointer void FASTCALL gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint32 tertiary_colour); void FASTCALL gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, uint8* unknown_pointer); void FASTCALL gfx_draw_sprite_raw_masked(rct_drawpixelinfo *dpi, int x, int y, int maskImage, int colourImage); +void FASTCALL gfx_draw_sprite_solid(rct_drawpixelinfo * dpi, int image, int x, int y, uint8 colour); void FASTCALL gfx_draw_sprite_software(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint32 tertiary_colour); void FASTCALL gfx_draw_sprite_palette_set_software(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, uint8* unknown_pointer); diff --git a/src/drawing/engines/SoftwareDrawingEngine.cpp b/src/drawing/engines/SoftwareDrawingEngine.cpp index 7efa5b3ceb..abb3423579 100644 --- a/src/drawing/engines/SoftwareDrawingEngine.cpp +++ b/src/drawing/engines/SoftwareDrawingEngine.cpp @@ -172,6 +172,7 @@ public: void DrawSprite(uint32 image, sint32 x, sint32 y, uint32 tertiaryColour) override; void DrawSpritePaletteSet(uint32 image, sint32 x, sint32 y, uint8 * palette, uint8 * unknown) override; void DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage) override; + void DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour); void SetDPI(rct_drawpixelinfo * dpi); }; @@ -1016,6 +1017,17 @@ void SoftwareDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 mask gfx_draw_sprite_raw_masked_software(_dpi, x, y, maskImage, colourImage); } +void SoftwareDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour) +{ + uint8 palette[256]; + memset(palette, colour, 256); + palette[0] = 0; + + RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; + image &= 0x7FFFF; + gfx_draw_sprite_palette_set_software(_dpi, image | 0x20000000, x, y, palette, nullptr); +} + void SoftwareDrawingContext::SetDPI(rct_drawpixelinfo * dpi) { _dpi = dpi; diff --git a/src/drawing/engines/opengl/DrawImageShader.cpp b/src/drawing/engines/opengl/DrawImageShader.cpp index b45a52d0e8..8c2487ea96 100644 --- a/src/drawing/engines/opengl/DrawImageShader.cpp +++ b/src/drawing/engines/opengl/DrawImageShader.cpp @@ -34,6 +34,7 @@ DrawImageShader::DrawImageShader() : OpenGLShaderProgram("drawimage") glVertexAttribIPointer(vIndex, 1, GL_INT, 0, nullptr); Use(); + SetFlags(0); SetTextureCoordinates(0, 0, 1, 1); } @@ -52,6 +53,8 @@ void DrawImageShader::GetLocations() uBounds = GetUniformLocation("uBounds"); uTextureCoordinates = GetUniformLocation("uTextureCoordinates"); uTexture = GetUniformLocation("uTexture"); + uColour = GetUniformLocation("uColour"); + uFlags = GetUniformLocation("uFlags"); vIndex = GetAttributeLocation("vIndex"); } @@ -83,6 +86,16 @@ void DrawImageShader::SetTexture(GLuint texture) glUniform1i(uTexture, 0); } +void DrawImageShader::SetColour(vec4f colour) +{ + glUniform4f(uColour, colour.r, colour.g, colour.b, colour.a); +} + +void DrawImageShader::SetFlags(uint32 flags) +{ + glUniform1i(uFlags, flags); +} + void DrawImageShader::Draw(sint32 left, sint32 top, sint32 right, sint32 bottom) { SetBounds(left, top, right, bottom); diff --git a/src/drawing/engines/opengl/DrawImageShader.h b/src/drawing/engines/opengl/DrawImageShader.h index 534d3efa02..8c9b2756b0 100644 --- a/src/drawing/engines/opengl/DrawImageShader.h +++ b/src/drawing/engines/opengl/DrawImageShader.h @@ -27,6 +27,8 @@ private: GLuint uBounds; GLuint uTextureCoordinates; GLuint uTexture; + GLuint uColour; + GLuint uFlags; GLuint vIndex; @@ -42,6 +44,8 @@ public: void SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom); void SetTextureCoordinates(sint32 left, sint32 top, sint32 right, sint32 bottom); void SetTexture(GLuint texture); + void SetColour(vec4f colour); + void SetFlags(uint32 flags); void Draw(sint32 left, sint32 top, sint32 right, sint32 bottom); diff --git a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp index 8ce77e2cda..abfcf329c1 100644 --- a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -198,6 +198,7 @@ public: void DrawSprite(uint32 image, sint32 x, sint32 y, uint32 tertiaryColour) override; void DrawSpritePaletteSet(uint32 image, sint32 x, sint32 y, uint8 * palette, uint8 * unknown) override; void DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage) override; + void DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour) override; void SetDPI(rct_drawpixelinfo * dpi); void InvalidateImage(uint32 image); @@ -648,6 +649,49 @@ void OpenGLDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskIm _drawImageMaskedShader->Draw(left, top, right, bottom); } +void OpenGLDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour) +{ + vec4f paletteColour = _engine->GLPalette[colour & 0xFF]; + + int g1Id = image & 0x7FFFF; + rct_g1_element * g1Element = gfx_get_g1_element(g1Id); + + GLuint texture = GetOrLoadImageTexture(image); + + sint32 drawOffsetX = g1Element->x_offset; + sint32 drawOffsetY = g1Element->y_offset; + sint32 drawWidth = (uint16)g1Element->width; + sint32 drawHeight = (uint16)g1Element->height; + + sint32 left = x + drawOffsetX; + sint32 top = y + drawOffsetY; + sint32 right = left + drawWidth; + sint32 bottom = top + drawHeight; + + if (left > right) + { + std::swap(left, right); + } + if (top > bottom) + { + std::swap(top, bottom); + } + + left += _offsetX; + top += _offsetY; + right += _offsetX; + bottom += _offsetY; + + _drawImageShader->Use(); + _drawImageShader->SetScreenSize(gScreenWidth, gScreenHeight); + _drawImageShader->SetClip(_clipLeft, _clipTop, _clipRight, _clipBottom); + _drawImageShader->SetTexture(texture); + _drawImageShader->SetFlags(1); + _drawImageShader->SetColour(paletteColour); + _drawImageShader->Draw(left, top, right, bottom); + _drawImageShader->SetFlags(0); +} + void OpenGLDrawingContext::SetDPI(rct_drawpixelinfo * dpi) { rct_drawpixelinfo * screenDPI = _engine->GetDPI(); diff --git a/src/interface/widget.c b/src/interface/widget.c index eac3ecc77b..f1298846bc 100644 --- a/src/interface/widget.c +++ b/src/interface/widget.c @@ -859,23 +859,12 @@ static void widget_draw_image(rct_drawpixelinfo *dpi, rct_window *w, int widgetI // Draw greyed out (light border bottom right shadow) colour = w->colours[widget->colour]; colour = ColourMapA[colour & 0x7F].lighter; - - uint8 palette[256]; - memset(palette, colour, 256); - palette[0] = 0; - - RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; - image &= 0x7FFFF; - gfx_draw_sprite_palette_set(dpi, image | 0x20000000, l + 1, t + 1, palette, NULL); + gfx_draw_sprite_solid(dpi, image, l + 1, t + 1, colour); // Draw greyed out (dark) colour = w->colours[widget->colour]; colour = ColourMapA[colour & 0x7F].mid_light; - memset(palette, colour, 256); - palette[0] = 0; - - RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; - gfx_draw_sprite_palette_set(dpi, image | 0x20000000, l, t, palette, NULL); + gfx_draw_sprite_solid(dpi, image, l, t, colour); } else { if (image & 0x80000000) { // ? From 4896d14940d65e97593400e09db8d5ba151d816c Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 11 Jun 2016 19:13:18 +0100 Subject: [PATCH 15/27] extract texture generation code to new class --- openrct2.vcxproj | 2 + .../engines/opengl/OpenGLDrawingEngine.cpp | 141 ++-------------- src/drawing/engines/opengl/TextureCache.cpp | 151 ++++++++++++++++++ src/drawing/engines/opengl/TextureCache.h | 41 +++++ src/drawing/sprite.c | 2 +- 5 files changed, 212 insertions(+), 125 deletions(-) create mode 100644 src/drawing/engines/opengl/TextureCache.cpp create mode 100644 src/drawing/engines/opengl/TextureCache.h diff --git a/openrct2.vcxproj b/openrct2.vcxproj index e55b959f7f..ec0c401011 100644 --- a/openrct2.vcxproj +++ b/openrct2.vcxproj @@ -62,6 +62,7 @@ + @@ -366,6 +367,7 @@ + diff --git a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp index abfcf329c1..eb7d88c0cb 100644 --- a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -38,6 +38,7 @@ IDrawingEngine * DrawingEngineFactory::CreateOpenGL() #include "DrawLineShader.h" #include "FillRectShader.h" #include "SwapFramebuffer.h" +#include "TextureCache.h" #include "../../../core/Console.hpp" #include "../../../core/Exception.hpp" @@ -172,6 +173,9 @@ private: DrawImageMaskedShader * _drawImageMaskedShader = nullptr; DrawLineShader * _drawLineShader = nullptr; FillRectShader * _fillRectShader = nullptr; + + TextureCache * _textureCache = nullptr; + GLuint _vbo; sint32 _offsetX; @@ -181,14 +185,12 @@ private: sint32 _clipRight; sint32 _clipBottom; - std::vector _textures; - std::unordered_map _imageTextureMap; - public: - OpenGLDrawingContext(OpenGLDrawingEngine * engine); + explicit OpenGLDrawingContext(OpenGLDrawingEngine * engine); ~OpenGLDrawingContext() override; IDrawingEngine * GetEngine() override; + TextureCache * GetTextureCache() const { return _textureCache; } void Initialise(); @@ -201,13 +203,6 @@ public: void DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour) override; void SetDPI(rct_drawpixelinfo * dpi); - void InvalidateImage(uint32 image); - -private: - GLuint GetOrLoadImageTexture(uint32 image); - GLuint LoadImageTexture(uint32 image); - void * GetImageAsARGB(uint32 image, uint32 tertiaryColour, uint32 * outWidth, uint32 * outHeight); - void FreeTextures(); }; class OpenGLDrawingEngine : public IDrawingEngine @@ -292,6 +287,8 @@ public: colour.b / 255.0f, colour.a / 255.0f }; } + _drawingContext->GetTextureCache() + ->SetPalette(Palette); } void Invalidate(sint32 left, sint32 top, sint32 right, sint32 bottom) override @@ -366,7 +363,8 @@ public: void InvalidateImage(uint32 image) override { - _drawingContext->InvalidateImage(image); + _drawingContext->GetTextureCache() + ->InvalidateImage(image); } rct_drawpixelinfo * GetDPI() @@ -461,6 +459,7 @@ IDrawingEngine * DrawingEngineFactory::CreateOpenGL() OpenGLDrawingContext::OpenGLDrawingContext(OpenGLDrawingEngine * engine) { _engine = engine; + _textureCache = new TextureCache(); } OpenGLDrawingContext::~OpenGLDrawingContext() @@ -469,6 +468,8 @@ OpenGLDrawingContext::~OpenGLDrawingContext() delete _drawImageMaskedShader; delete _drawLineShader; delete _fillRectShader; + + delete _textureCache; } IDrawingEngine * OpenGLDrawingContext::GetEngine() @@ -571,7 +572,7 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t } } - GLuint texture = GetOrLoadImageTexture(image); + GLuint texture = _textureCache->GetOrLoadImageTexture(image); sint32 drawOffsetX = g1Element->x_offset; sint32 drawOffsetY = g1Element->y_offset; @@ -614,8 +615,8 @@ void OpenGLDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskIm rct_g1_element * g1ElementMask = gfx_get_g1_element(maskImage & 0x7FFFF); rct_g1_element * g1ElementColour = gfx_get_g1_element(colourImage & 0x7FFFF); - GLuint textureMask = GetOrLoadImageTexture(maskImage); - GLuint textureColour = GetOrLoadImageTexture(colourImage); + GLuint textureMask = _textureCache->GetOrLoadImageTexture(maskImage); + GLuint textureColour = _textureCache->GetOrLoadImageTexture(colourImage); sint32 drawOffsetX = g1ElementMask->x_offset; sint32 drawOffsetY = g1ElementMask->y_offset; @@ -656,7 +657,7 @@ void OpenGLDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uin int g1Id = image & 0x7FFFF; rct_g1_element * g1Element = gfx_get_g1_element(g1Id); - GLuint texture = GetOrLoadImageTexture(image); + GLuint texture = _textureCache->GetOrLoadImageTexture(image); sint32 drawOffsetX = g1Element->x_offset; sint32 drawOffsetY = g1Element->y_offset; @@ -711,112 +712,4 @@ void OpenGLDrawingContext::SetDPI(rct_drawpixelinfo * dpi) _dpi = dpi; } -GLuint OpenGLDrawingContext::GetOrLoadImageTexture(uint32 image) -{ - auto kvp = _imageTextureMap.find(image); - if (kvp != _imageTextureMap.end()) - { - return kvp->second; - } - - GLuint texture = LoadImageTexture(image); - _textures.push_back(texture); - _imageTextureMap[image] = texture; - - // if ((_textures.size() % 100) == 0) - // { - // printf("Textures: %d\n", _textures.size()); - // } - - return texture; -} - -GLuint OpenGLDrawingContext::LoadImageTexture(uint32 image) -{ - GLuint texture; - glGenTextures(1, &texture); - - uint32 width, height; - void * pixels32 = GetImageAsARGB(image, 0, &width, &height); - - glBindTexture(GL_TEXTURE_2D, texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels32); - - delete [] (uint8 *) pixels32; - - return texture; -} - -void * OpenGLDrawingContext::GetImageAsARGB(uint32 image, uint32 tertiaryColour, uint32 * outWidth, uint32 * outHeight) -{ - int g1Id = image & 0x7FFFF; - rct_g1_element * g1Element = gfx_get_g1_element(g1Id); - - uint32 width = (uint32)g1Element->width; - uint32 height = (uint32)g1Element->height; - - size_t numPixels = width * height; - uint8 * pixels8 = new uint8[numPixels]; - Memory::Set(pixels8, 0, numPixels); - - rct_drawpixelinfo dpi; - dpi.bits = pixels8; - dpi.pitch = 0; - dpi.x = 0; - dpi.y = 0; - dpi.width = width; - dpi.height = height; - dpi.zoom_level = 0; - gfx_draw_sprite_software(&dpi, image, -g1Element->x_offset, -g1Element->y_offset, tertiaryColour); - - uint8 * pixels32 = new uint8[width * height * 4]; - uint8 * src = pixels8; - uint8 * dst = pixels32; - for (size_t i = 0; i < numPixels; i++) - { - uint8 paletteIndex = *src++; - if (paletteIndex == 0) - { - // Transparent - *dst++ = 0; - *dst++ = 0; - *dst++ = 0; - *dst++ = 0; - } - else - { - SDL_Color colour = _engine->Palette[paletteIndex]; - *dst++ = colour.r; - *dst++ = colour.g; - *dst++ = colour.b; - *dst++ = colour.a; - } - } - - delete[] pixels8; - - *outWidth = width; - *outHeight = height; - return pixels32; -} - -void OpenGLDrawingContext::InvalidateImage(uint32 image) -{ - auto kvp = _imageTextureMap.find(image); - if (kvp != _imageTextureMap.end()) - { - GLuint texture = kvp->second; - glDeleteTextures(1, &texture); - - _imageTextureMap.erase(kvp); - } -} - -void OpenGLDrawingContext::FreeTextures() -{ - glDeleteTextures(_textures.size(), _textures.data()); -} - #endif /* DISABLE_OPENGL */ diff --git a/src/drawing/engines/opengl/TextureCache.cpp b/src/drawing/engines/opengl/TextureCache.cpp new file mode 100644 index 0000000000..9f94bc916c --- /dev/null +++ b/src/drawing/engines/opengl/TextureCache.cpp @@ -0,0 +1,151 @@ +#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 + +#include "../../../core/Memory.hpp" +#include "TextureCache.h" + +extern "C" +{ + #include "../../drawing.h" +} + +TextureCache::TextureCache() +{ +} + +TextureCache::~TextureCache() +{ + FreeTextures(); +} + +void TextureCache::SetPalette(const SDL_Color * palette) +{ + Memory::CopyArray(_palette, palette, 256); +} + +void TextureCache::InvalidateImage(uint32 image) +{ + auto kvp = _imageTextureMap.find(image); + if (kvp != _imageTextureMap.end()) + { + GLuint texture = kvp->second; + glDeleteTextures(1, &texture); + + _imageTextureMap.erase(kvp); + } +} + +GLuint TextureCache::GetOrLoadImageTexture(uint32 image) +{ + auto kvp = _imageTextureMap.find(image); + if (kvp != _imageTextureMap.end()) + { + return kvp->second; + } + + GLuint texture = LoadImageTexture(image); + _imageTextureMap[image] = texture; + + // if ((_textures.size() % 100) == 0) + // { + // printf("Textures: %d\n", _textures.size()); + // } + + return texture; +} + +GLuint TextureCache::LoadImageTexture(uint32 image) +{ + GLuint texture; + glGenTextures(1, &texture); + + uint32 width, height; + void * pixels32 = GetImageAsARGB(image, 0, &width, &height); + + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels32); + + delete [] (uint8 *) pixels32; + + return texture; +} + +void * TextureCache::GetImageAsARGB(uint32 image, uint32 tertiaryColour, uint32* outWidth, uint32* outHeight) +{ + int g1Id = image & 0x7FFFF; + rct_g1_element * g1Element = gfx_get_g1_element(g1Id); + + uint32 width = (uint32)g1Element->width; + uint32 height = (uint32)g1Element->height; + + size_t numPixels = width * height; + uint8 * pixels8 = new uint8[numPixels]; + Memory::Set(pixels8, 0, numPixels); + + rct_drawpixelinfo dpi; + dpi.bits = pixels8; + dpi.pitch = 0; + dpi.x = 0; + dpi.y = 0; + dpi.width = width; + dpi.height = height; + dpi.zoom_level = 0; + gfx_draw_sprite_software(&dpi, image, -g1Element->x_offset, -g1Element->y_offset, tertiaryColour); + + uint8 * pixels32 = new uint8[width * height * 4]; + uint8 * src = pixels8; + uint8 * dst = pixels32; + for (size_t i = 0; i < numPixels; i++) + { + uint8 paletteIndex = *src++; + if (paletteIndex == 0) + { + // Transparent + *dst++ = 0; + *dst++ = 0; + *dst++ = 0; + *dst++ = 0; + } + else + { + SDL_Color colour = _palette[paletteIndex]; + *dst++ = colour.r; + *dst++ = colour.g; + *dst++ = colour.b; + *dst++ = colour.a; + } + } + + delete[] pixels8; + + *outWidth = width; + *outHeight = height; + return pixels32; +} + +void TextureCache::FreeTextures() +{ + size_t numTextures = _imageTextureMap.size(); + auto textures = std::vector(numTextures); + for (auto kvp : _imageTextureMap) + { + textures.push_back(kvp.second); + } + + glDeleteTextures(textures.size(), textures.data()); +} diff --git a/src/drawing/engines/opengl/TextureCache.h b/src/drawing/engines/opengl/TextureCache.h new file mode 100644 index 0000000000..d0e9f54b8e --- /dev/null +++ b/src/drawing/engines/opengl/TextureCache.h @@ -0,0 +1,41 @@ +#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 +#include +#include "../../../common.h" +#include "OpenGLAPI.h" + +class TextureCache +{ +private: + std::unordered_map _imageTextureMap; + SDL_Color _palette[256]; + +public: + TextureCache(); + ~TextureCache(); + void SetPalette(const SDL_Color * palette); + void InvalidateImage(uint32 image); + GLuint GetOrLoadImageTexture(uint32 image); + +private: + GLuint LoadImageTexture(uint32 image); + void * GetImageAsARGB(uint32 image, uint32 tertiaryColour, uint32 * outWidth, uint32 * outHeight); + void FreeTextures(); +}; diff --git a/src/drawing/sprite.c b/src/drawing/sprite.c index 3fb9dfed32..f04cd9a5cf 100644 --- a/src/drawing/sprite.c +++ b/src/drawing/sprite.c @@ -383,7 +383,7 @@ void FASTCALL gfx_draw_sprite_palette_set_software(rct_drawpixelinfo *dpi, int i .pitch = dpi->pitch, .zoom_level = dpi->zoom_level - 1 }; - gfx_draw_sprite_palette_set(&zoomed_dpi, (image_type << 28) | (image_element - g1_source->zoomed_offset), x >> 1, y >> 1, palette_pointer, unknown_pointer); + gfx_draw_sprite_palette_set_software(&zoomed_dpi, (image_type << 28) | (image_element - g1_source->zoomed_offset), x >> 1, y >> 1, palette_pointer, unknown_pointer); return; } From f796ef5122229cc4d43b6431caac6916af8a08fb Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 11 Jun 2016 23:14:22 +0100 Subject: [PATCH 16/27] fix drawing of text --- src/drawing/IDrawingContext.h | 2 +- src/drawing/NewDrawing.cpp | 4 +- src/drawing/drawing.h | 2 +- src/drawing/engines/SoftwareDrawingEngine.cpp | 14 +- .../engines/opengl/OpenGLDrawingEngine.cpp | 48 +++++-- src/drawing/engines/opengl/TextureCache.cpp | 130 ++++++++++++++---- src/drawing/engines/opengl/TextureCache.h | 37 +++++ src/drawing/string.c | 2 +- 8 files changed, 190 insertions(+), 49 deletions(-) diff --git a/src/drawing/IDrawingContext.h b/src/drawing/IDrawingContext.h index 17bfb84505..5c83258fcb 100644 --- a/src/drawing/IDrawingContext.h +++ b/src/drawing/IDrawingContext.h @@ -30,7 +30,7 @@ interface IDrawingContext virtual void FillRect(uint32 colour, sint32 left, sint32 top, sint32 right, sint32 bottom) abstract; virtual void DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32 x2, sint32 y2) abstract; virtual void DrawSprite(uint32 image, sint32 x, sint32 y, uint32 tertiaryColour) abstract; - virtual void DrawSpritePaletteSet(uint32 image, sint32 x, sint32 y, uint8 * palette, uint8 * unknown) abstract; virtual void DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage) abstract; virtual void DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour) abstract; + virtual void DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * palette) abstract; }; diff --git a/src/drawing/NewDrawing.cpp b/src/drawing/NewDrawing.cpp index acc84b6647..b3dd0b00a0 100644 --- a/src/drawing/NewDrawing.cpp +++ b/src/drawing/NewDrawing.cpp @@ -209,12 +209,12 @@ extern "C" } } - void FASTCALL gfx_draw_sprite_palette_set(rct_drawpixelinfo * dpi, int image, int x, int y, uint8 * palette, uint8 * unknown) + void FASTCALL gfx_draw_glpyh(rct_drawpixelinfo * dpi, int image, int x, int y, uint8 * palette) { if (_drawingEngine != nullptr) { IDrawingContext * dc = _drawingEngine->GetDrawingContext(dpi); - dc->DrawSpritePaletteSet(image, x, y, palette, unknown); + dc->DrawGlyph(image, x, y, palette); } } diff --git a/src/drawing/drawing.h b/src/drawing/drawing.h index 4c0bbc0110..4cd3576b28 100644 --- a/src/drawing/drawing.h +++ b/src/drawing/drawing.h @@ -146,7 +146,7 @@ rct_g1_element* gfx_get_g1_element(int image_id); void sub_68371D(); void FASTCALL gfx_rle_sprite_to_buffer(const uint8* RESTRICT source_bits_pointer, uint8* RESTRICT dest_bits_pointer, const uint8* RESTRICT palette_pointer, const rct_drawpixelinfo * RESTRICT dpi, int image_type, int source_y_start, int height, int source_x_start, int width); void FASTCALL gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint32 tertiary_colour); -void FASTCALL gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, uint8* unknown_pointer); +void FASTCALL gfx_draw_glpyh(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8 * palette); void FASTCALL gfx_draw_sprite_raw_masked(rct_drawpixelinfo *dpi, int x, int y, int maskImage, int colourImage); void FASTCALL gfx_draw_sprite_solid(rct_drawpixelinfo * dpi, int image, int x, int y, uint8 colour); diff --git a/src/drawing/engines/SoftwareDrawingEngine.cpp b/src/drawing/engines/SoftwareDrawingEngine.cpp index abb3423579..6bf113c305 100644 --- a/src/drawing/engines/SoftwareDrawingEngine.cpp +++ b/src/drawing/engines/SoftwareDrawingEngine.cpp @@ -170,9 +170,9 @@ public: 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; void DrawSprite(uint32 image, sint32 x, sint32 y, uint32 tertiaryColour) override; - void DrawSpritePaletteSet(uint32 image, sint32 x, sint32 y, uint8 * palette, uint8 * unknown) override; void DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage) override; - void DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour); + void DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour) override; + void DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * palette) override; void SetDPI(rct_drawpixelinfo * dpi); }; @@ -1007,11 +1007,6 @@ void SoftwareDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 gfx_draw_sprite_software(_dpi, image, x, y, tertiaryColour); } -void SoftwareDrawingContext::DrawSpritePaletteSet(uint32 image, sint32 x, sint32 y, uint8 * palette, uint8 * unknown) -{ - gfx_draw_sprite_palette_set_software(_dpi, image, x, y, palette, unknown); -} - void SoftwareDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage) { gfx_draw_sprite_raw_masked_software(_dpi, x, y, maskImage, colourImage); @@ -1028,6 +1023,11 @@ void SoftwareDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, u gfx_draw_sprite_palette_set_software(_dpi, image | 0x20000000, x, y, palette, nullptr); } +void SoftwareDrawingContext::DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * palette) +{ + gfx_draw_sprite_palette_set_software(_dpi, image, x, y, palette, nullptr); +} + void SoftwareDrawingContext::SetDPI(rct_drawpixelinfo * dpi) { _dpi = dpi; diff --git a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp index eb7d88c0cb..07a02d0a9e 100644 --- a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -176,8 +176,6 @@ private: TextureCache * _textureCache = nullptr; - GLuint _vbo; - sint32 _offsetX; sint32 _offsetY; sint32 _clipLeft; @@ -198,9 +196,9 @@ public: 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; void DrawSprite(uint32 image, sint32 x, sint32 y, uint32 tertiaryColour) override; - void DrawSpritePaletteSet(uint32 image, sint32 x, sint32 y, uint8 * palette, uint8 * unknown) override; void DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage) override; void DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour) override; + void DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * palette) override; void SetDPI(rct_drawpixelinfo * dpi); }; @@ -605,11 +603,6 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t _drawImageShader->Draw(left, top, right, bottom); } -void OpenGLDrawingContext::DrawSpritePaletteSet(uint32 image, sint32 x, sint32 y, uint8 * palette, uint8 * unknown) -{ - DrawSprite(image, x, y, 0); -} - void OpenGLDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage) { rct_g1_element * g1ElementMask = gfx_get_g1_element(maskImage & 0x7FFFF); @@ -693,6 +686,45 @@ void OpenGLDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uin _drawImageShader->SetFlags(0); } +void OpenGLDrawingContext::DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * palette) +{ + int g1Id = image & 0x7FFFF; + rct_g1_element * g1Element = gfx_get_g1_element(g1Id); + + GLuint texture = _textureCache->GetOrLoadGlyphTexture(image, palette); + + sint32 drawOffsetX = g1Element->x_offset; + sint32 drawOffsetY = g1Element->y_offset; + sint32 drawWidth = (uint16)g1Element->width; + sint32 drawHeight = (uint16)g1Element->height; + + sint32 left = x + drawOffsetX; + sint32 top = y + drawOffsetY; + sint32 right = left + drawWidth; + sint32 bottom = top + drawHeight; + + if (left > right) + { + std::swap(left, right); + } + if (top > bottom) + { + std::swap(top, bottom); + } + + left += _offsetX; + top += _offsetY; + right += _offsetX; + bottom += _offsetY; + + _drawImageShader->Use(); + _drawImageShader->SetScreenSize(gScreenWidth, gScreenHeight); + _drawImageShader->SetClip(_clipLeft, _clipTop, _clipRight, _clipBottom); + _drawImageShader->SetTexture(texture); + _drawImageShader->Draw(left, top, right, bottom); + _drawImageShader->SetFlags(0); +} + void OpenGLDrawingContext::SetDPI(rct_drawpixelinfo * dpi) { rct_drawpixelinfo * screenDPI = _engine->GetDPI(); diff --git a/src/drawing/engines/opengl/TextureCache.cpp b/src/drawing/engines/opengl/TextureCache.cpp index 9f94bc916c..bb73ed16a1 100644 --- a/src/drawing/engines/opengl/TextureCache.cpp +++ b/src/drawing/engines/opengl/TextureCache.cpp @@ -59,10 +59,23 @@ GLuint TextureCache::GetOrLoadImageTexture(uint32 image) GLuint texture = LoadImageTexture(image); _imageTextureMap[image] = texture; - // if ((_textures.size() % 100) == 0) - // { - // printf("Textures: %d\n", _textures.size()); - // } + return texture; +} + +GLuint TextureCache::GetOrLoadGlyphTexture(uint32 image, uint8 * palette) +{ + GlyphId glyphId; + glyphId.Image = image; + Memory::Copy(&glyphId.Palette, palette, sizeof(glyphId.Palette)); + + auto kvp = _glyphTextureMap.find(glyphId); + if (kvp != _glyphTextureMap.end()) + { + return kvp->second; + } + + GLuint texture = LoadGlyphTexture(image, palette); + _glyphTextureMap[glyphId] = texture; return texture; } @@ -80,35 +93,66 @@ GLuint TextureCache::LoadImageTexture(uint32 image) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels32); - delete [] (uint8 *) pixels32; + Memory::Free(pixels32); return texture; } -void * TextureCache::GetImageAsARGB(uint32 image, uint32 tertiaryColour, uint32* outWidth, uint32* outHeight) +GLuint TextureCache::LoadGlyphTexture(uint32 image, uint8 * palette) { - int g1Id = image & 0x7FFFF; - rct_g1_element * g1Element = gfx_get_g1_element(g1Id); + GLuint texture; + glGenTextures(1, &texture); - uint32 width = (uint32)g1Element->width; - uint32 height = (uint32)g1Element->height; + uint32 width, height; + void * pixels32 = GetGlyphAsARGB(image, palette, &width, &height); - size_t numPixels = width * height; - uint8 * pixels8 = new uint8[numPixels]; - Memory::Set(pixels8, 0, numPixels); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels32); - rct_drawpixelinfo dpi; - dpi.bits = pixels8; - dpi.pitch = 0; - dpi.x = 0; - dpi.y = 0; - dpi.width = width; - dpi.height = height; - dpi.zoom_level = 0; - gfx_draw_sprite_software(&dpi, image, -g1Element->x_offset, -g1Element->y_offset, tertiaryColour); + Memory::Free(pixels32); - uint8 * pixels32 = new uint8[width * height * 4]; - uint8 * src = pixels8; + return texture; +} + +void * TextureCache::GetImageAsARGB(uint32 image, uint32 tertiaryColour, uint32 * outWidth, uint32 * outHeight) +{ + rct_g1_element * g1Element = gfx_get_g1_element(image & 0x7FFFF); + sint32 width = g1Element->width; + sint32 height = g1Element->height; + + rct_drawpixelinfo * dpi = CreateDPI(width, height); + gfx_draw_sprite_software(dpi, image, -g1Element->x_offset, -g1Element->y_offset, tertiaryColour); + void * pixels32 = ConvertDPIto32bpp(dpi); + DeleteDPI(dpi); + + *outWidth = width; + *outHeight = height; + return pixels32; +} + +void * TextureCache::GetGlyphAsARGB(uint32 image, uint8 * palette, uint32 * outWidth, uint32 * outHeight) +{ + rct_g1_element * g1Element = gfx_get_g1_element(image & 0x7FFFF); + sint32 width = g1Element->width; + sint32 height = g1Element->height; + + rct_drawpixelinfo * dpi = CreateDPI(width, height); + gfx_draw_sprite_palette_set_software(dpi, image, -g1Element->x_offset, -g1Element->y_offset, palette, nullptr); + void * pixels32 = ConvertDPIto32bpp(dpi); + DeleteDPI(dpi); + + *outWidth = width; + *outHeight = height; + return pixels32; +} + +void * TextureCache::ConvertDPIto32bpp(const rct_drawpixelinfo * dpi) +{ + size_t numPixels = dpi->width * dpi->height; + uint8 * pixels32 = Memory::Allocate(numPixels * 4); + uint8 * src = dpi->bits; uint8 * dst = pixels32; for (size_t i = 0; i < numPixels; i++) { @@ -130,22 +174,50 @@ void * TextureCache::GetImageAsARGB(uint32 image, uint32 tertiaryColour, uint32* *dst++ = colour.a; } } - - delete[] pixels8; - - *outWidth = width; - *outHeight = height; return pixels32; } void TextureCache::FreeTextures() { + // Free images size_t numTextures = _imageTextureMap.size(); auto textures = std::vector(numTextures); for (auto kvp : _imageTextureMap) { textures.push_back(kvp.second); } + glDeleteTextures(textures.size(), textures.data()); + // Free glyphs + numTextures = _glyphTextureMap.size(); + textures.clear(); + textures.reserve(numTextures); + for (auto kvp : _glyphTextureMap) + { + textures.push_back(kvp.second); + } glDeleteTextures(textures.size(), textures.data()); } + +rct_drawpixelinfo * TextureCache::CreateDPI(sint32 width, sint32 height) +{ + size_t numPixels = width * height; + uint8 * pixels8 = Memory::Allocate(numPixels); + Memory::Set(pixels8, 0, numPixels); + + rct_drawpixelinfo * dpi = new rct_drawpixelinfo(); + dpi->bits = pixels8; + dpi->pitch = 0; + dpi->x = 0; + dpi->y = 0; + dpi->width = width; + dpi->height = height; + dpi->zoom_level = 0; + return dpi; +} + +void TextureCache::DeleteDPI(rct_drawpixelinfo* dpi) +{ + Memory::Free(dpi->bits); + delete dpi; +} diff --git a/src/drawing/engines/opengl/TextureCache.h b/src/drawing/engines/opengl/TextureCache.h index d0e9f54b8e..3f5e36673c 100644 --- a/src/drawing/engines/opengl/TextureCache.h +++ b/src/drawing/engines/opengl/TextureCache.h @@ -21,10 +21,40 @@ #include "../../../common.h" #include "OpenGLAPI.h" +struct rct_drawpixelinfo; + +struct GlyphId +{ + uint32 Image; + uint64 Palette; + + struct Hash + { + size_t operator()(const GlyphId &k) const + { + size_t hash = 0x3154A85E; + hash = k.Image * 7; + hash += (k.Palette & 0xFFFFFFFF) * 13; + hash += (k.Palette >> 32) * 23; + return hash; + } + }; + + struct Equal + { + bool operator()(const GlyphId &lhs, const GlyphId &rhs) const + { + return lhs.Image == rhs.Image && + lhs.Palette == rhs.Palette; + } + }; +}; + class TextureCache { private: std::unordered_map _imageTextureMap; + std::unordered_map _glyphTextureMap; SDL_Color _palette[256]; public: @@ -33,9 +63,16 @@ public: void SetPalette(const SDL_Color * palette); void InvalidateImage(uint32 image); GLuint GetOrLoadImageTexture(uint32 image); + GLuint GetOrLoadGlyphTexture(uint32 image, uint8 * palette); private: GLuint LoadImageTexture(uint32 image); + GLuint LoadGlyphTexture(uint32 image, uint8 * palette); void * GetImageAsARGB(uint32 image, uint32 tertiaryColour, uint32 * outWidth, uint32 * outHeight); + void * GetGlyphAsARGB(uint32 image, uint8 * palette, uint32 * outWidth, uint32 * outHeight); + void * ConvertDPIto32bpp(const rct_drawpixelinfo * dpi); void FreeTextures(); + + static rct_drawpixelinfo * CreateDPI(sint32 width, sint32 height); + static void DeleteDPI(rct_drawpixelinfo * dpi); }; diff --git a/src/drawing/string.c b/src/drawing/string.c index 12ee28304a..bf50c33535 100644 --- a/src/drawing/string.c +++ b/src/drawing/string.c @@ -924,7 +924,7 @@ static void ttf_draw_character_sprite(rct_drawpixelinfo *dpi, int codepoint, tex if (info->flags & TEXT_DRAW_FLAG_Y_OFFSET_EFFECT) { y += *info->y_offset++; } - gfx_draw_sprite_palette_set(dpi, sprite, x, y, info->palette, NULL); + gfx_draw_glpyh(dpi, sprite, x, y, info->palette); } info->x += characterWidth; From e771834b87419faca47ee600189deebaaef341f3 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 11 Jun 2016 23:24:19 +0100 Subject: [PATCH 17/27] fix offset of FillRect and DrawLine --- src/drawing/engines/opengl/OpenGLDrawingEngine.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp index 07a02d0a9e..00c1b0c2fa 100644 --- a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -485,11 +485,16 @@ void OpenGLDrawingContext::Initialise() void OpenGLDrawingContext::Clear(uint32 colour) { - FillRect(colour, _clipLeft, _clipTop, _clipRight, _clipBottom); + FillRect(colour, _clipLeft - _offsetX, _clipTop - _offsetY, _clipRight, _clipBottom); } void OpenGLDrawingContext::FillRect(uint32 colour, sint32 left, sint32 top, sint32 right, sint32 bottom) { + left += _offsetX; + top += _offsetY; + right += _offsetX; + bottom += _offsetY; + vec4f paletteColour[2]; paletteColour[0] = _engine->GLPalette[(colour >> 0) & 0xFF]; paletteColour[1] = paletteColour[0]; @@ -534,6 +539,11 @@ void OpenGLDrawingContext::FillRect(uint32 colour, sint32 left, sint32 top, sint void OpenGLDrawingContext::DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32 x2, sint32 y2) { + x1 += _offsetX; + y1 += _offsetY; + x2 += _offsetX; + y2 += _offsetY; + vec4f paletteColour = _engine->GLPalette[colour & 0xFF]; _drawLineShader->Use(); From 3c96171801d0550bcc92d5300b1c78791a769161 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 12 Jun 2016 00:07:01 +0100 Subject: [PATCH 18/27] reduce redundant state changes --- .../engines/opengl/CopyFramebufferShader.cpp | 5 ++--- .../engines/opengl/DrawImageMaskedShader.cpp | 12 +++++------ .../engines/opengl/DrawImageShader.cpp | 5 ++--- src/drawing/engines/opengl/FillRectShader.cpp | 5 ++--- src/drawing/engines/opengl/OpenGLAPI.cpp | 15 ++++++++++++++ src/drawing/engines/opengl/OpenGLAPI.h | 9 +++++++++ .../engines/opengl/OpenGLDrawingEngine.cpp | 20 +++++++++++++------ .../engines/opengl/OpenGLShaderProgram.cpp | 6 +++++- 8 files changed, 55 insertions(+), 22 deletions(-) diff --git a/src/drawing/engines/opengl/CopyFramebufferShader.cpp b/src/drawing/engines/opengl/CopyFramebufferShader.cpp index 943ab6bdcc..69ab07300d 100644 --- a/src/drawing/engines/opengl/CopyFramebufferShader.cpp +++ b/src/drawing/engines/opengl/CopyFramebufferShader.cpp @@ -35,6 +35,7 @@ CopyFramebufferShader::CopyFramebufferShader() : OpenGLShaderProgram("copyframeb Use(); SetTextureCoordinates(0, 0, 1, 1); + glUniform1i(uTexture, 0); } CopyFramebufferShader::~CopyFramebufferShader() @@ -72,9 +73,7 @@ void CopyFramebufferShader::SetTextureCoordinates(sint32 left, sint32 top, sint3 void CopyFramebufferShader::SetTexture(GLuint texture) { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texture); - glUniform1i(uTexture, 0); + OpenGLAPI::SetTexture2D(0, texture); } void CopyFramebufferShader::Draw() diff --git a/src/drawing/engines/opengl/DrawImageMaskedShader.cpp b/src/drawing/engines/opengl/DrawImageMaskedShader.cpp index f7a1f1187a..ac3bcb1035 100644 --- a/src/drawing/engines/opengl/DrawImageMaskedShader.cpp +++ b/src/drawing/engines/opengl/DrawImageMaskedShader.cpp @@ -32,6 +32,10 @@ DrawImageMaskedShader::DrawImageMaskedShader() : OpenGLShaderProgram("drawimagem glBindVertexArray(_vao); glEnableVertexAttribArray(vIndex); glVertexAttribIPointer(vIndex, 1, GL_INT, 0, 0); + + Use(); + glUniform1i(uTextureMask, 0); + glUniform1i(uTextureColour, 1); } DrawImageMaskedShader::~DrawImageMaskedShader() @@ -70,16 +74,12 @@ void DrawImageMaskedShader::SetBounds(sint32 left, sint32 top, sint32 right, sin void DrawImageMaskedShader::SetTextureMask(GLuint texture) { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texture); - glUniform1i(uTextureMask, 0); + OpenGLAPI::SetTexture2D(0, texture); } void DrawImageMaskedShader::SetTextureColour(GLuint texture) { - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, texture); - glUniform1i(uTextureColour, 1); + OpenGLAPI::SetTexture2D(1, texture); } void DrawImageMaskedShader::Draw(sint32 left, sint32 top, sint32 right, sint32 bottom) diff --git a/src/drawing/engines/opengl/DrawImageShader.cpp b/src/drawing/engines/opengl/DrawImageShader.cpp index 8c2487ea96..d423f9cde3 100644 --- a/src/drawing/engines/opengl/DrawImageShader.cpp +++ b/src/drawing/engines/opengl/DrawImageShader.cpp @@ -36,6 +36,7 @@ DrawImageShader::DrawImageShader() : OpenGLShaderProgram("drawimage") Use(); SetFlags(0); SetTextureCoordinates(0, 0, 1, 1); + glUniform1i(uTexture, 0); } DrawImageShader::~DrawImageShader() @@ -81,9 +82,7 @@ void DrawImageShader::SetTextureCoordinates(sint32 left, sint32 top, sint32 righ void DrawImageShader::SetTexture(GLuint texture) { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texture); - glUniform1i(uTexture, 0); + OpenGLAPI::SetTexture2D(0, texture); } void DrawImageShader::SetColour(vec4f colour) diff --git a/src/drawing/engines/opengl/FillRectShader.cpp b/src/drawing/engines/opengl/FillRectShader.cpp index 7e8cd654a9..c3be9b20cc 100644 --- a/src/drawing/engines/opengl/FillRectShader.cpp +++ b/src/drawing/engines/opengl/FillRectShader.cpp @@ -36,6 +36,7 @@ FillRectShader::FillRectShader() : OpenGLShaderProgram("fillrect") Use(); SetFlags(0); + glUniform1i(uSourceFramebuffer, 0); } FillRectShader::~FillRectShader() @@ -85,9 +86,7 @@ void FillRectShader::SetColour(int index, vec4f colour) void FillRectShader::SetSourceFramebuffer(GLuint texture) { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texture); - glUniform1i(uSourceFramebuffer, 0); + OpenGLAPI::SetTexture2D(0, texture); } void FillRectShader::Draw(sint32 left, sint32 top, sint32 right, sint32 bottom) diff --git a/src/drawing/engines/opengl/OpenGLAPI.cpp b/src/drawing/engines/opengl/OpenGLAPI.cpp index f8f1a680b5..659b081920 100644 --- a/src/drawing/engines/opengl/OpenGLAPI.cpp +++ b/src/drawing/engines/opengl/OpenGLAPI.cpp @@ -108,6 +108,21 @@ static const char * TryLoadAllProcAddresses() return nullptr; } +namespace OpenGLState +{ + uint16 ActiveTexture = UINT16_MAX; + GLuint CurrentProgram = UINT32_MAX; +} + +void OpenGLAPI::SetTexture2D(uint16 index, GLuint texture) +{ + if (OpenGLState::ActiveTexture != index) + { + glActiveTexture(GL_TEXTURE0 + index); + } + glBindTexture(GL_TEXTURE_2D, texture); +} + #endif /* #if OPENGL_NO_LINK */ bool OpenGLAPI::Initialise() diff --git a/src/drawing/engines/opengl/OpenGLAPI.h b/src/drawing/engines/opengl/OpenGLAPI.h index 4c4890ecdd..470bf18053 100644 --- a/src/drawing/engines/opengl/OpenGLAPI.h +++ b/src/drawing/engines/opengl/OpenGLAPI.h @@ -16,6 +16,8 @@ #pragma once +#include "../../../common.h" + #if OPENGL_NO_LINK // BEGIN [Do not define 1.1 function signatures] @@ -155,4 +157,11 @@ GLAPI_DECL PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer GLAP namespace OpenGLAPI { bool Initialise(); + void SetTexture2D(uint16 index, GLuint texture); +} + +namespace OpenGLState +{ + extern uint16 ActiveTexture; + extern GLuint CurrentProgram; } diff --git a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp index 00c1b0c2fa..cb1c75391b 100644 --- a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -191,6 +191,7 @@ public: TextureCache * GetTextureCache() const { return _textureCache; } void Initialise(); + void Resize(sint32 width, sint32 height); void Clear(uint32 colour) override; void FillRect(uint32 colour, sint32 x, sint32 y, sint32 w, sint32 h) override; @@ -270,6 +271,7 @@ public: { ConfigureBits(width, height, width); ConfigureCanvas(); + _drawingContext->Resize(width, height); } void SetPalette(SDL_Color * palette) override @@ -483,6 +485,18 @@ void OpenGLDrawingContext::Initialise() _fillRectShader = new FillRectShader(); } +void OpenGLDrawingContext::Resize(sint32 width, sint32 height) +{ + _drawImageShader->Use(); + _drawImageShader->SetScreenSize(width, height); + _drawImageMaskedShader->Use(); + _drawImageMaskedShader->SetScreenSize(width, height); + _drawLineShader->Use(); + _drawLineShader->SetScreenSize(width, height); + _fillRectShader->Use(); + _fillRectShader->SetScreenSize(width, height); +} + void OpenGLDrawingContext::Clear(uint32 colour) { FillRect(colour, _clipLeft - _offsetX, _clipTop - _offsetY, _clipRight, _clipBottom); @@ -530,7 +544,6 @@ void OpenGLDrawingContext::FillRect(uint32 colour, sint32 left, sint32 top, sint _fillRectShader->SetFlags(0); } - _fillRectShader->SetScreenSize(gScreenWidth, gScreenHeight); _fillRectShader->SetColour(0, paletteColour[0]); _fillRectShader->SetColour(1, paletteColour[1]); _fillRectShader->SetClip(_clipLeft, _clipTop, _clipRight, _clipBottom); @@ -547,7 +560,6 @@ void OpenGLDrawingContext::DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32 vec4f paletteColour = _engine->GLPalette[colour & 0xFF]; _drawLineShader->Use(); - _drawLineShader->SetScreenSize(gScreenWidth, gScreenHeight); _drawLineShader->SetClip(_clipLeft, _clipTop, _clipRight, _clipBottom); _drawLineShader->SetColour(paletteColour); _drawLineShader->Draw(x1, y1, x2, y2); @@ -607,7 +619,6 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t bottom += _offsetY; _drawImageShader->Use(); - _drawImageShader->SetScreenSize(gScreenWidth, gScreenHeight); _drawImageShader->SetClip(_clipLeft, _clipTop, _clipRight, _clipBottom); _drawImageShader->SetTexture(texture); _drawImageShader->Draw(left, top, right, bottom); @@ -646,7 +657,6 @@ void OpenGLDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskIm bottom += _offsetY; _drawImageMaskedShader->Use(); - _drawImageMaskedShader->SetScreenSize(gScreenWidth, gScreenHeight); _drawImageMaskedShader->SetClip(_clipLeft, _clipTop, _clipRight, _clipBottom); _drawImageMaskedShader->SetTextureMask(textureMask); _drawImageMaskedShader->SetTextureColour(textureColour); @@ -687,7 +697,6 @@ void OpenGLDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uin bottom += _offsetY; _drawImageShader->Use(); - _drawImageShader->SetScreenSize(gScreenWidth, gScreenHeight); _drawImageShader->SetClip(_clipLeft, _clipTop, _clipRight, _clipBottom); _drawImageShader->SetTexture(texture); _drawImageShader->SetFlags(1); @@ -728,7 +737,6 @@ void OpenGLDrawingContext::DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * p bottom += _offsetY; _drawImageShader->Use(); - _drawImageShader->SetScreenSize(gScreenWidth, gScreenHeight); _drawImageShader->SetClip(_clipLeft, _clipTop, _clipRight, _clipBottom); _drawImageShader->SetTexture(texture); _drawImageShader->Draw(left, top, right, bottom); diff --git a/src/drawing/engines/opengl/OpenGLShaderProgram.cpp b/src/drawing/engines/opengl/OpenGLShaderProgram.cpp index f51dc5beda..0fe706d399 100644 --- a/src/drawing/engines/opengl/OpenGLShaderProgram.cpp +++ b/src/drawing/engines/opengl/OpenGLShaderProgram.cpp @@ -148,7 +148,11 @@ GLuint OpenGLShaderProgram::GetUniformLocation(const char * name) void OpenGLShaderProgram::Use() { - glUseProgram(_id); + if (OpenGLState::CurrentProgram != _id) + { + OpenGLState::CurrentProgram = _id; + glUseProgram(_id); + } } bool OpenGLShaderProgram::Link() From f6665a188a87c1b255c555f43b62ca1bc268aedb Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 12 Jun 2016 15:47:51 +0100 Subject: [PATCH 19/27] add missing DISABLE_OPENGL guards --- src/drawing/engines/opengl/OpenGLFramebuffer.cpp | 4 ++++ src/drawing/engines/opengl/TextureCache.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/drawing/engines/opengl/OpenGLFramebuffer.cpp b/src/drawing/engines/opengl/OpenGLFramebuffer.cpp index c1e21e433c..f60ce7d384 100644 --- a/src/drawing/engines/opengl/OpenGLFramebuffer.cpp +++ b/src/drawing/engines/opengl/OpenGLFramebuffer.cpp @@ -14,6 +14,8 @@ *****************************************************************************/ #pragma endregion +#ifndef DISABLE_OPENGL + #include #include "../../../core/Memory.hpp" #include "OpenGLFramebuffer.h" @@ -78,3 +80,5 @@ void * OpenGLFramebuffer::GetPixels() const return flippedPixels; } + +#endif /* DISABLE_OPENGL */ diff --git a/src/drawing/engines/opengl/TextureCache.cpp b/src/drawing/engines/opengl/TextureCache.cpp index bb73ed16a1..eb7344dd5d 100644 --- a/src/drawing/engines/opengl/TextureCache.cpp +++ b/src/drawing/engines/opengl/TextureCache.cpp @@ -14,6 +14,8 @@ *****************************************************************************/ #pragma endregion +#ifndef DISABLE_OPENGL + #include "../../../core/Memory.hpp" #include "TextureCache.h" @@ -221,3 +223,5 @@ void TextureCache::DeleteDPI(rct_drawpixelinfo* dpi) Memory::Free(dpi->bits); delete dpi; } + +#endif /* DISABLE_OPENGL */ From fa4662be42fb9679a400669c2e188f0a6d4234da Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 12 Jun 2016 17:44:58 +0100 Subject: [PATCH 20/27] add missing include --- src/drawing/engines/opengl/OpenGLAPI.cpp | 4 ++-- src/drawing/engines/opengl/TextureCache.cpp | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/drawing/engines/opengl/OpenGLAPI.cpp b/src/drawing/engines/opengl/OpenGLAPI.cpp index 659b081920..af07c6c566 100644 --- a/src/drawing/engines/opengl/OpenGLAPI.cpp +++ b/src/drawing/engines/opengl/OpenGLAPI.cpp @@ -108,6 +108,8 @@ static const char * TryLoadAllProcAddresses() return nullptr; } +#endif /* #if OPENGL_NO_LINK */ + namespace OpenGLState { uint16 ActiveTexture = UINT16_MAX; @@ -123,8 +125,6 @@ void OpenGLAPI::SetTexture2D(uint16 index, GLuint texture) glBindTexture(GL_TEXTURE_2D, texture); } -#endif /* #if OPENGL_NO_LINK */ - bool OpenGLAPI::Initialise() { #ifdef OPENGL_NO_LINK diff --git a/src/drawing/engines/opengl/TextureCache.cpp b/src/drawing/engines/opengl/TextureCache.cpp index eb7344dd5d..10d80e261e 100644 --- a/src/drawing/engines/opengl/TextureCache.cpp +++ b/src/drawing/engines/opengl/TextureCache.cpp @@ -16,6 +16,7 @@ #ifndef DISABLE_OPENGL +#include #include "../../../core/Memory.hpp" #include "TextureCache.h" From 0ac5c3698b3e0e26ba5d01d3cd4500b43c734b4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sun, 12 Jun 2016 18:49:26 +0200 Subject: [PATCH 21/27] Fix CMake projects, restore testing with OpenGL disabled --- .travis.yml | 4 ++++ CMakeLists.txt | 3 +++ 2 files changed, 7 insertions(+) diff --git a/.travis.yml b/.travis.yml index 2acf08e6f4..e16ccd2f44 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,6 +35,10 @@ matrix: env: OPENRCT2_CMAKE_OPTS="-DDISABLE_NETWORK=ON -DDISABLE_HTTP_TWITCH=ON" TARGET=docker32 services: - docker + - os: linux + env: OPENRCT2_CMAKE_OPTS="-DDISABLE_OPENGL=ON" TARGET=docker32 + services: + - docker - os: osx osx_image: xcode7.3 env: diff --git a/CMakeLists.txt b/CMakeLists.txt index 66966e7756..e40ce41ff6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,6 +58,9 @@ endif () if (DISABLE_OPENGL) add_definitions(-DDISABLE_OPENGL) +else (DISABLE_OPENGL) + # Makes OpenGL function get queried in run-time rather than linked-in + add_definitions(-DOPENGL_NO_LINK) endif (DISABLE_OPENGL) if (DISABLE_NETWORK) From 0503b88071696309c61cdb2a0d450dea8e0a9cc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sun, 12 Jun 2016 19:17:40 +0200 Subject: [PATCH 22/27] Cast shader program --- src/drawing/engines/opengl/OpenGLShaderProgram.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drawing/engines/opengl/OpenGLShaderProgram.cpp b/src/drawing/engines/opengl/OpenGLShaderProgram.cpp index 0fe706d399..606df1e4b9 100644 --- a/src/drawing/engines/opengl/OpenGLShaderProgram.cpp +++ b/src/drawing/engines/opengl/OpenGLShaderProgram.cpp @@ -38,7 +38,7 @@ OpenGLShader::OpenGLShader(const char * name, GLenum type) char * sourceCode = ReadSourceCode(path); _id = glCreateShader(type); - glShaderSource(_id, 1, &sourceCode, nullptr); + glShaderSource(_id, 1, (const GLchar**)&sourceCode, nullptr); glCompileShader(_id); Memory::Free(sourceCode); From f5604c6b69dd1791d396d85ea26e020a67209495 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 12 Jun 2016 22:37:44 +0100 Subject: [PATCH 23/27] add missing GetUniformLocation --- src/drawing/engines/opengl/FillRectShader.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/drawing/engines/opengl/FillRectShader.cpp b/src/drawing/engines/opengl/FillRectShader.cpp index c3be9b20cc..ca14750188 100644 --- a/src/drawing/engines/opengl/FillRectShader.cpp +++ b/src/drawing/engines/opengl/FillRectShader.cpp @@ -49,14 +49,15 @@ FillRectShader::~FillRectShader() void FillRectShader::GetLocations() { - uScreenSize = GetUniformLocation("uScreenSize"); - uClip = GetUniformLocation("uClip"); - uBounds = GetUniformLocation("uBounds"); - uFlags = GetUniformLocation("uFlags"); - uColour[0] = GetUniformLocation("uColour[0]"); - uColour[1] = GetUniformLocation("uColour[1]"); + uScreenSize = GetUniformLocation("uScreenSize"); + uClip = GetUniformLocation("uClip"); + uBounds = GetUniformLocation("uBounds"); + uFlags = GetUniformLocation("uFlags"); + uColour[0] = GetUniformLocation("uColour[0]"); + uColour[1] = GetUniformLocation("uColour[1]"); + uSourceFramebuffer = GetUniformLocation("uSourceFramebuffer"); - vIndex = GetAttributeLocation("vIndex"); + vIndex = GetAttributeLocation("vIndex"); } void FillRectShader::SetScreenSize(sint32 width, sint32 height) From f96c595502ed66d92ddc5104515ef6ab7803e012 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 12 Jun 2016 23:42:53 +0100 Subject: [PATCH 24/27] copy data/shaders to bin --- scripts/ps/build.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/ps/build.ps1 b/scripts/ps/build.ps1 index 3fba811aed..3a908184e2 100644 --- a/scripts/ps/build.ps1 +++ b/scripts/ps/build.ps1 @@ -37,6 +37,7 @@ function Build-Data() # Create symlinks Symlink-or-Copy "$binDataPath\language" "$dataPath\language" > $null + Symlink-or-Copy "$binDataPath\shaders" "$dataPath\shaders" > $null Symlink-or-Copy "$binDataPath\title" "$dataPath\title" > $null return 0 From e0bb89d1d665bf0841df914dcd5be6f409d9ddd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sun, 12 Jun 2016 19:12:54 +0200 Subject: [PATCH 25/27] Explicitly request OpenGL 3.3 context --- src/drawing/engines/opengl/OpenGLDrawingEngine.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp index cb1c75391b..418b7a1b8c 100644 --- a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -247,6 +247,10 @@ public: { _window = window; + + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); _context = SDL_GL_CreateContext(_window); SDL_GL_MakeCurrent(_window, _context); From 3db558f23616965a2d96550a80a128cab2539ee8 Mon Sep 17 00:00:00 2001 From: LRFLEW Date: Sun, 12 Jun 2016 17:42:44 -0500 Subject: [PATCH 26/27] Updated Xcode Project --- OpenRCT2.xcodeproj/project.pbxproj | 88 ++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 10 deletions(-) diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index 9cd2aaf596..6a0f0dad32 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -117,6 +117,18 @@ D41B73EF1C2101890080A7B9 /* libcurl.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D41B73EE1C2101890080A7B9 /* libcurl.tbd */; }; D41B741D1C210A7A0080A7B9 /* libiconv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D41B741C1C210A7A0080A7B9 /* libiconv.tbd */; }; D41B74731C2125E50080A7B9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D41B74721C2125E50080A7B9 /* Assets.xcassets */; }; + D43407D61D0E14BE00C2B3D4 /* CopyFramebufferShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D43407C01D0E14BE00C2B3D4 /* CopyFramebufferShader.cpp */; }; + D43407D71D0E14BE00C2B3D4 /* DrawImageMaskedShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D43407C21D0E14BE00C2B3D4 /* DrawImageMaskedShader.cpp */; }; + D43407D81D0E14BE00C2B3D4 /* DrawImageShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D43407C41D0E14BE00C2B3D4 /* DrawImageShader.cpp */; }; + D43407D91D0E14BE00C2B3D4 /* DrawLineShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D43407C61D0E14BE00C2B3D4 /* DrawLineShader.cpp */; }; + D43407DA1D0E14BE00C2B3D4 /* FillRectShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D43407C81D0E14BE00C2B3D4 /* FillRectShader.cpp */; }; + D43407DB1D0E14BE00C2B3D4 /* OpenGLAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D43407CB1D0E14BE00C2B3D4 /* OpenGLAPI.cpp */; }; + D43407DC1D0E14BE00C2B3D4 /* OpenGLDrawingEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D43407CD1D0E14BE00C2B3D4 /* OpenGLDrawingEngine.cpp */; }; + D43407DD1D0E14BE00C2B3D4 /* OpenGLFramebuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D43407CE1D0E14BE00C2B3D4 /* OpenGLFramebuffer.cpp */; }; + D43407DE1D0E14BE00C2B3D4 /* OpenGLShaderProgram.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D43407D01D0E14BE00C2B3D4 /* OpenGLShaderProgram.cpp */; }; + D43407DF1D0E14BE00C2B3D4 /* SwapFramebuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D43407D21D0E14BE00C2B3D4 /* SwapFramebuffer.cpp */; }; + D43407E01D0E14BE00C2B3D4 /* TextureCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D43407D41D0E14BE00C2B3D4 /* TextureCache.cpp */; }; + D43407E21D0E14CE00C2B3D4 /* shaders in Resources */ = {isa = PBXBuildFile; fileRef = D43407E11D0E14CE00C2B3D4 /* shaders */; }; D44271F51CC81B3200D84D28 /* addresses.c in Sources */ = {isa = PBXBuildFile; fileRef = D44270CD1CC81B3200D84D28 /* addresses.c */; }; D44271F61CC81B3200D84D28 /* audio.c in Sources */ = {isa = PBXBuildFile; fileRef = D44270D01CC81B3200D84D28 /* audio.c */; }; D44271F71CC81B3200D84D28 /* mixer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D44270D21CC81B3200D84D28 /* mixer.cpp */; }; @@ -307,10 +319,8 @@ D45A395D1CF300AF00659A24 /* libSDL2_ttf.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D45A38B71CF3006400659A24 /* libSDL2_ttf.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; D45A395E1CF300AF00659A24 /* libSDL2.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D45A38B81CF3006400659A24 /* libSDL2.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; D45A395F1CF300AF00659A24 /* libspeexdsp.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D45A38B91CF3006400659A24 /* libspeexdsp.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; - D45F046B1D07733900CBA2BA /* OpenGLAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D45F04691D07733900CBA2BA /* OpenGLAPI.cpp */; }; D47304D51C4FF8250015C0EA /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D47304D41C4FF8250015C0EA /* libz.tbd */; }; D48A8D831D00272F00649DA7 /* TcpSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D48A8D811D00272F00649DA7 /* TcpSocket.cpp */; }; - D49766821D03B9FE002222CD /* OpenGLDrawingEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D49766801D03B9FE002222CD /* OpenGLDrawingEngine.cpp */; }; D49766831D03B9FE002222CD /* SoftwareDrawingEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D49766811D03B9FE002222CD /* SoftwareDrawingEngine.cpp */; }; D49766861D03BAA5002222CD /* NewDrawing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D49766841D03BAA5002222CD /* NewDrawing.cpp */; }; D49766891D03BABB002222CD /* rain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D49766871D03BABB002222CD /* rain.cpp */; }; @@ -468,6 +478,29 @@ D41B73EE1C2101890080A7B9 /* libcurl.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcurl.tbd; path = usr/lib/libcurl.tbd; sourceTree = SDKROOT; }; D41B741C1C210A7A0080A7B9 /* libiconv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.tbd; path = usr/lib/libiconv.tbd; sourceTree = SDKROOT; }; D41B74721C2125E50080A7B9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = distribution/osx/Assets.xcassets; sourceTree = SOURCE_ROOT; }; + D43407C01D0E14BE00C2B3D4 /* CopyFramebufferShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CopyFramebufferShader.cpp; sourceTree = ""; }; + D43407C11D0E14BE00C2B3D4 /* CopyFramebufferShader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopyFramebufferShader.h; sourceTree = ""; }; + D43407C21D0E14BE00C2B3D4 /* DrawImageMaskedShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DrawImageMaskedShader.cpp; sourceTree = ""; }; + D43407C31D0E14BE00C2B3D4 /* DrawImageMaskedShader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawImageMaskedShader.h; sourceTree = ""; }; + D43407C41D0E14BE00C2B3D4 /* DrawImageShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DrawImageShader.cpp; sourceTree = ""; }; + D43407C51D0E14BE00C2B3D4 /* DrawImageShader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawImageShader.h; sourceTree = ""; }; + D43407C61D0E14BE00C2B3D4 /* DrawLineShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DrawLineShader.cpp; sourceTree = ""; }; + D43407C71D0E14BE00C2B3D4 /* DrawLineShader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawLineShader.h; sourceTree = ""; }; + D43407C81D0E14BE00C2B3D4 /* FillRectShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FillRectShader.cpp; sourceTree = ""; }; + D43407C91D0E14BE00C2B3D4 /* FillRectShader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FillRectShader.h; sourceTree = ""; }; + D43407CA1D0E14BE00C2B3D4 /* GLSLTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLSLTypes.h; sourceTree = ""; }; + D43407CB1D0E14BE00C2B3D4 /* OpenGLAPI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenGLAPI.cpp; sourceTree = ""; }; + D43407CC1D0E14BE00C2B3D4 /* OpenGLAPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenGLAPI.h; sourceTree = ""; }; + D43407CD1D0E14BE00C2B3D4 /* OpenGLDrawingEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenGLDrawingEngine.cpp; sourceTree = ""; }; + D43407CE1D0E14BE00C2B3D4 /* OpenGLFramebuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenGLFramebuffer.cpp; sourceTree = ""; }; + D43407CF1D0E14BE00C2B3D4 /* OpenGLFramebuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenGLFramebuffer.h; sourceTree = ""; }; + D43407D01D0E14BE00C2B3D4 /* OpenGLShaderProgram.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenGLShaderProgram.cpp; sourceTree = ""; }; + D43407D11D0E14BE00C2B3D4 /* OpenGLShaderProgram.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenGLShaderProgram.h; sourceTree = ""; }; + D43407D21D0E14BE00C2B3D4 /* SwapFramebuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SwapFramebuffer.cpp; sourceTree = ""; }; + D43407D31D0E14BE00C2B3D4 /* SwapFramebuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SwapFramebuffer.h; sourceTree = ""; }; + D43407D41D0E14BE00C2B3D4 /* TextureCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextureCache.cpp; sourceTree = ""; }; + D43407D51D0E14BE00C2B3D4 /* TextureCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextureCache.h; sourceTree = ""; }; + D43407E11D0E14CE00C2B3D4 /* shaders */ = {isa = PBXFileReference; lastKnownFileType = folder; name = shaders; path = data/shaders; sourceTree = SOURCE_ROOT; }; D44270CD1CC81B3200D84D28 /* addresses.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = addresses.c; path = src/addresses.c; sourceTree = ""; }; D44270CE1CC81B3200D84D28 /* addresses.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = addresses.h; path = src/addresses.h; sourceTree = ""; }; D44270D01CC81B3200D84D28 /* audio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = audio.c; sourceTree = ""; }; @@ -900,13 +933,10 @@ D45A39561CF3007A00659A24 /* speex_resampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = speex_resampler.h; sourceTree = ""; }; D45A39571CF3007A00659A24 /* speexdsp_config_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = speexdsp_config_types.h; sourceTree = ""; }; D45A39581CF3007A00659A24 /* speexdsp_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = speexdsp_types.h; sourceTree = ""; }; - D45F04691D07733900CBA2BA /* OpenGLAPI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenGLAPI.cpp; sourceTree = ""; }; - D45F046A1D07733900CBA2BA /* OpenGLAPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenGLAPI.h; sourceTree = ""; }; D47304D41C4FF8250015C0EA /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; D4895D321C23EFDD000CD788 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = distribution/osx/Info.plist; sourceTree = SOURCE_ROOT; }; D48A8D811D00272F00649DA7 /* TcpSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TcpSocket.cpp; sourceTree = ""; }; D48A8D821D00272F00649DA7 /* TcpSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TcpSocket.h; sourceTree = ""; }; - D49766801D03B9FE002222CD /* OpenGLDrawingEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenGLDrawingEngine.cpp; sourceTree = ""; }; D49766811D03B9FE002222CD /* SoftwareDrawingEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SoftwareDrawingEngine.cpp; sourceTree = ""; }; D49766841D03BAA5002222CD /* NewDrawing.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NewDrawing.cpp; sourceTree = ""; }; D49766851D03BAA5002222CD /* NewDrawing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NewDrawing.h; sourceTree = ""; }; @@ -1201,6 +1231,35 @@ path = libxc; sourceTree = ""; }; + D43407BF1D0E14BE00C2B3D4 /* opengl */ = { + isa = PBXGroup; + children = ( + D43407C01D0E14BE00C2B3D4 /* CopyFramebufferShader.cpp */, + D43407C11D0E14BE00C2B3D4 /* CopyFramebufferShader.h */, + D43407C21D0E14BE00C2B3D4 /* DrawImageMaskedShader.cpp */, + D43407C31D0E14BE00C2B3D4 /* DrawImageMaskedShader.h */, + D43407C41D0E14BE00C2B3D4 /* DrawImageShader.cpp */, + D43407C51D0E14BE00C2B3D4 /* DrawImageShader.h */, + D43407C61D0E14BE00C2B3D4 /* DrawLineShader.cpp */, + D43407C71D0E14BE00C2B3D4 /* DrawLineShader.h */, + D43407C81D0E14BE00C2B3D4 /* FillRectShader.cpp */, + D43407C91D0E14BE00C2B3D4 /* FillRectShader.h */, + D43407CA1D0E14BE00C2B3D4 /* GLSLTypes.h */, + D43407CB1D0E14BE00C2B3D4 /* OpenGLAPI.cpp */, + D43407CC1D0E14BE00C2B3D4 /* OpenGLAPI.h */, + D43407CD1D0E14BE00C2B3D4 /* OpenGLDrawingEngine.cpp */, + D43407CE1D0E14BE00C2B3D4 /* OpenGLFramebuffer.cpp */, + D43407CF1D0E14BE00C2B3D4 /* OpenGLFramebuffer.h */, + D43407D01D0E14BE00C2B3D4 /* OpenGLShaderProgram.cpp */, + D43407D11D0E14BE00C2B3D4 /* OpenGLShaderProgram.h */, + D43407D21D0E14BE00C2B3D4 /* SwapFramebuffer.cpp */, + D43407D31D0E14BE00C2B3D4 /* SwapFramebuffer.h */, + D43407D41D0E14BE00C2B3D4 /* TextureCache.cpp */, + D43407D51D0E14BE00C2B3D4 /* TextureCache.h */, + ); + path = opengl; + sourceTree = ""; + }; D44270CF1CC81B3200D84D28 /* audio */ = { isa = PBXGroup; children = ( @@ -1761,9 +1820,7 @@ D497667F1D03B9FE002222CD /* engines */ = { isa = PBXGroup; children = ( - D45F04691D07733900CBA2BA /* OpenGLAPI.cpp */, - D45F046A1D07733900CBA2BA /* OpenGLAPI.h */, - D49766801D03B9FE002222CD /* OpenGLDrawingEngine.cpp */, + D43407BF1D0E14BE00C2B3D4 /* opengl */, D49766811D03B9FE002222CD /* SoftwareDrawingEngine.cpp */, ); path = engines; @@ -1804,6 +1861,7 @@ children = ( D4EC48E31C2637710024B507 /* g2.dat */, D4EC48E41C2637710024B507 /* language */, + D43407E11D0E14CE00C2B3D4 /* shaders */, D4EC48E51C2637710024B507 /* title */, ); name = data; @@ -1913,6 +1971,7 @@ D41B74731C2125E50080A7B9 /* Assets.xcassets in Resources */, D4EC48E61C2637710024B507 /* g2.dat in Resources */, D4EC48E71C2637710024B507 /* language in Resources */, + D43407E21D0E14CE00C2B3D4 /* shaders in Resources */, D45A38BB1CF3006400659A24 /* engines in Resources */, D4EC48E81C2637710024B507 /* title in Resources */, ); @@ -2062,6 +2121,7 @@ C686F9421CDBC3B7009F9BFC /* magic_carpet.c in Sources */, D44272021CC81B3200D84D28 /* Json.cpp in Sources */, D44272591CC81B3200D84D28 /* dropdown.c in Sources */, + D43407DF1D0E14BE00C2B3D4 /* SwapFramebuffer.cpp in Sources */, C686F8AF1CDBC37E009F9BFC /* map_element.c in Sources */, D44272081CC81B3200D84D28 /* diagnostic.c in Sources */, D44272A51CC81B3200D84D28 /* particle.c in Sources */, @@ -2082,6 +2142,7 @@ D442725A1CC81B3200D84D28 /* editor_bottom_toolbar.c in Sources */, D442729D1CC81B3200D84D28 /* footpath.c in Sources */, D44272501CC81B3200D84D28 /* title.c in Sources */, + D43407DD1D0E14BE00C2B3D4 /* OpenGLFramebuffer.cpp in Sources */, D442721D1CC81B3200D84D28 /* screenshot.c in Sources */, D44272381CC81B3200D84D28 /* openrct2.c in Sources */, C686F92C1CDBC3B7009F9BFC /* circus_show.c in Sources */, @@ -2090,7 +2151,6 @@ C686F9321CDBC3B7009F9BFC /* haunted_house.c in Sources */, D442720A1CC81B3200D84D28 /* drawing_fast.cpp in Sources */, C686F9521CDBC3B7009F9BFC /* river_rapids.c in Sources */, - D45F046B1D07733900CBA2BA /* OpenGLAPI.cpp in Sources */, 008BF72C1CDAA5C30019A2AD /* track_design.c in Sources */, C61FB7241CF86356004CE991 /* NetworkUser.cpp in Sources */, D44272191CC81B3200D84D28 /* colour.c in Sources */, @@ -2116,8 +2176,10 @@ C686F93C1CDBC3B7009F9BFC /* misc.c in Sources */, D442723A1CC81B3200D84D28 /* staff.c in Sources */, D44272931CC81B3200D84D28 /* top_toolbar.c in Sources */, + D43407DA1D0E14BE00C2B3D4 /* FillRectShader.cpp in Sources */, D44271F61CC81B3200D84D28 /* audio.c in Sources */, D442728A1CC81B3200D84D28 /* tile_inspector.c in Sources */, + D43407D91D0E14BE00C2B3D4 /* DrawLineShader.cpp in Sources */, C686F9411CDBC3B7009F9BFC /* launched_freefall.c in Sources */, D44272571CC81B3200D84D28 /* clear_scenery.c in Sources */, D442727D1CC81B3200D84D28 /* ride_list.c in Sources */, @@ -2185,6 +2247,7 @@ D442725B1CC81B3200D84D28 /* editor_inventions_list.c in Sources */, D44272311CC81B3200D84D28 /* news_item.c in Sources */, D44272011CC81B3200D84D28 /* Guard.cpp in Sources */, + D43407E01D0E14BE00C2B3D4 /* TextureCache.cpp in Sources */, D44272951CC81B3200D84D28 /* track_manage.c in Sources */, D44272851CC81B3200D84D28 /* staff.c in Sources */, D442725F1CC81B3200D84D28 /* editor_scenario_options.c in Sources */, @@ -2207,14 +2270,15 @@ D44272031CC81B3200D84D28 /* Path.cpp in Sources */, C686F9301CDBC3B7009F9BFC /* flying_saucers.c in Sources */, D44272401CC81B3200D84D28 /* windows.c in Sources */, - D49766821D03B9FE002222CD /* OpenGLDrawingEngine.cpp in Sources */, D44272881CC81B3200D84D28 /* text_input.c in Sources */, D442720F1CC81B3200D84D28 /* scrolling_text.c in Sources */, D44271F51CC81B3200D84D28 /* addresses.c in Sources */, D44272041CC81B3200D84D28 /* Stopwatch.cpp in Sources */, + D43407D81D0E14BE00C2B3D4 /* DrawImageShader.cpp in Sources */, 007A05D01CFB2C8B00F419C3 /* NetworkGroup.cpp in Sources */, C686F9491CDBC3B7009F9BFC /* chairlift.c in Sources */, C686F9501CDBC3B7009F9BFC /* log_flume.c in Sources */, + D43407D61D0E14BE00C2B3D4 /* CopyFramebufferShader.cpp in Sources */, D44272241CC81B3200D84D28 /* intro.c in Sources */, D44272631CC81B3200D84D28 /* game_bottom_toolbar.c in Sources */, 008BF72A1CDAA5C30019A2AD /* track_design_index.c in Sources */, @@ -2227,6 +2291,7 @@ C686F9311CDBC3B7009F9BFC /* ghost_train.c in Sources */, D44272821CC81B3200D84D28 /* shortcut_key_change.c in Sources */, D442722A1CC81B3200D84D28 /* localisation.c in Sources */, + D43407D71D0E14BE00C2B3D4 /* DrawImageMaskedShader.cpp in Sources */, D44272731CC81B3200D84D28 /* new_ride.c in Sources */, D442721A1CC81B3200D84D28 /* console.c in Sources */, D44271FB1CC81B3200D84D28 /* ScreenshotCommands.cpp in Sources */, @@ -2238,6 +2303,8 @@ C686F9351CDBC3B7009F9BFC /* mini_golf.c in Sources */, D44272541CC81B3200D84D28 /* banner.c in Sources */, D44272A31CC81B3200D84D28 /* money_effect.c in Sources */, + D43407DE1D0E14BE00C2B3D4 /* OpenGLShaderProgram.cpp in Sources */, + D43407DC1D0E14BE00C2B3D4 /* OpenGLDrawingEngine.cpp in Sources */, D44272761CC81B3200D84D28 /* options.c in Sources */, C686F93D1CDBC3B7009F9BFC /* shop.c in Sources */, C686F8AD1CDBC37E009F9BFC /* entrance.c in Sources */, @@ -2282,6 +2349,7 @@ D44272301CC81B3200D84D28 /* marketing.c in Sources */, D44272321CC81B3200D84D28 /* research.c in Sources */, D442725D1CC81B3200D84D28 /* editor_object_selection.c in Sources */, + D43407DB1D0E14BE00C2B3D4 /* OpenGLAPI.cpp in Sources */, D44272981CC81B3200D84D28 /* water.c in Sources */, D442726C1CC81B3200D84D28 /* map_tooltip.c in Sources */, C686F9281CDBC3B7009F9BFC /* wild_mouse.c in Sources */, From 0311fdd35cce9fcb665225d65595fa1161916340 Mon Sep 17 00:00:00 2001 From: LRFLEW Date: Sun, 12 Jun 2016 17:43:13 -0500 Subject: [PATCH 27/27] Fixed Depricated Enum Drawing Errors --- src/drawing/engines/opengl/CopyFramebufferShader.cpp | 4 +--- src/drawing/engines/opengl/DrawImageMaskedShader.cpp | 2 +- src/drawing/engines/opengl/DrawImageShader.cpp | 2 +- src/drawing/engines/opengl/FillRectShader.cpp | 2 +- src/drawing/engines/opengl/OpenGLAPI.h | 10 ++++++++++ src/drawing/engines/opengl/OpenGLDrawingEngine.cpp | 1 + 6 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/drawing/engines/opengl/CopyFramebufferShader.cpp b/src/drawing/engines/opengl/CopyFramebufferShader.cpp index 69ab07300d..a5520099a5 100644 --- a/src/drawing/engines/opengl/CopyFramebufferShader.cpp +++ b/src/drawing/engines/opengl/CopyFramebufferShader.cpp @@ -42,8 +42,6 @@ CopyFramebufferShader::~CopyFramebufferShader() { glDeleteBuffers(1, &_vbo); glDeleteVertexArrays(1, &_vao); - - glBindVertexArray(_vao); } void CopyFramebufferShader::GetLocations() @@ -79,7 +77,7 @@ void CopyFramebufferShader::SetTexture(GLuint texture) void CopyFramebufferShader::Draw() { glBindVertexArray(_vao); - glDrawArrays(GL_QUADS, 0, 4); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } #endif /* DISABLE_OPENGL */ diff --git a/src/drawing/engines/opengl/DrawImageMaskedShader.cpp b/src/drawing/engines/opengl/DrawImageMaskedShader.cpp index ac3bcb1035..3566c02cfc 100644 --- a/src/drawing/engines/opengl/DrawImageMaskedShader.cpp +++ b/src/drawing/engines/opengl/DrawImageMaskedShader.cpp @@ -87,7 +87,7 @@ void DrawImageMaskedShader::Draw(sint32 left, sint32 top, sint32 right, sint32 b SetBounds(left, top, right, bottom); glBindVertexArray(_vao); - glDrawArrays(GL_QUADS, 0, 4); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } #endif /* DISABLE_OPENGL */ diff --git a/src/drawing/engines/opengl/DrawImageShader.cpp b/src/drawing/engines/opengl/DrawImageShader.cpp index d423f9cde3..d8000fe5ce 100644 --- a/src/drawing/engines/opengl/DrawImageShader.cpp +++ b/src/drawing/engines/opengl/DrawImageShader.cpp @@ -100,7 +100,7 @@ void DrawImageShader::Draw(sint32 left, sint32 top, sint32 right, sint32 bottom) SetBounds(left, top, right, bottom); glBindVertexArray(_vao); - glDrawArrays(GL_QUADS, 0, 4); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } #endif /* DISABLE_OPENGL */ diff --git a/src/drawing/engines/opengl/FillRectShader.cpp b/src/drawing/engines/opengl/FillRectShader.cpp index ca14750188..9c02a00148 100644 --- a/src/drawing/engines/opengl/FillRectShader.cpp +++ b/src/drawing/engines/opengl/FillRectShader.cpp @@ -95,7 +95,7 @@ void FillRectShader::Draw(sint32 left, sint32 top, sint32 right, sint32 bottom) SetBounds(left, top, right, bottom); glBindVertexArray(_vao); - glDrawArrays(GL_QUADS, 0, 4); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } #endif /* DISABLE_OPENGL */ diff --git a/src/drawing/engines/opengl/OpenGLAPI.h b/src/drawing/engines/opengl/OpenGLAPI.h index 470bf18053..8ee1713f64 100644 --- a/src/drawing/engines/opengl/OpenGLAPI.h +++ b/src/drawing/engines/opengl/OpenGLAPI.h @@ -154,6 +154,16 @@ GLAPI_DECL PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer GLAP #endif /* OPENGL_NO_LINK */ +inline void CheckGLError() +{ + GLenum error = glGetError(); + while (error != GL_NO_ERROR) + { + log_error("OpenGL Error 0x%04X", error); + error = glGetError(); + } +} + namespace OpenGLAPI { bool Initialise(); diff --git a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp index 418b7a1b8c..a9f7c6f239 100644 --- a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -330,6 +330,7 @@ public: ->GetTexture()); _copyFramebufferShader->Draw(); + CheckGLError(); Display(); }