From e3ecb91b919514e1608367cdff80780647562414 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 11 Jun 2016 17:43:53 +0100 Subject: [PATCH] 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)