Change OpenGL renderer to use command buffers

This commit is contained in:
Alexander Overvoorde 2016-07-20 03:25:00 +02:00
parent d8d39c1ade
commit e7626064f2
5 changed files with 248 additions and 36 deletions

View File

@ -383,6 +383,7 @@
<ClInclude Include="src\drawing\drawing.h" />
<ClInclude Include="src\drawing\engines\OpenGLAPI.h" />
<ClInclude Include="src\drawing\engines\opengl\CopyFramebufferShader.h" />
<ClInclude Include="src\drawing\engines\opengl\DrawCommands.h" />
<ClInclude Include="src\drawing\engines\opengl\DrawImageMaskedShader.h" />
<ClInclude Include="src\drawing\engines\opengl\DrawImageShader.h" />
<ClInclude Include="src\drawing\engines\opengl\DrawLineShader.h" />

View File

@ -0,0 +1,50 @@
#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"
#include "GLSLTypes.h"
struct DrawRectCommand {
uint32 flags;
GLuint sourceFramebuffer;
vec4f colours[2];
sint32 clip[4];
sint32 bounds[4];
};
struct DrawLineCommand {
vec4f colour;
sint32 clip[4];
sint32 pos[4];
};
struct DrawImageCommand {
uint32 flags;
vec4f colour;
sint32 clip[4];
GLuint texColour;
sint32 bounds[4];
};
struct DrawImageMaskedCommand {
sint32 clip[4];
GLuint texMask;
GLuint texColour;
sint32 bounds[4];
};

View File

@ -87,6 +87,7 @@ void FillRectShader::SetColour(int index, vec4f colour)
void FillRectShader::SetSourceFramebuffer(GLuint texture)
{
_sourceFramebuffer = texture;
OpenGLAPI::SetTexture2D(0, texture);
}
@ -98,4 +99,8 @@ void FillRectShader::Draw(sint32 left, sint32 top, sint32 right, sint32 bottom)
glDrawArrays(GL_TRIANGLES, 0, 6);
}
GLuint FillRectShader::GetSourceFramebuffer() const {
return _sourceFramebuffer;
}
#endif /* DISABLE_OPENGL */

View File

@ -36,6 +36,8 @@ private:
GLuint _vbo;
GLuint _vao;
GLuint _sourceFramebuffer = 0;
public:
FillRectShader();
~FillRectShader() override;
@ -49,6 +51,8 @@ public:
void Draw(sint32 left, sint32 top, sint32 right, sint32 bottom);
GLuint GetSourceFramebuffer() const;
private:
void GetLocations();
};

View File

@ -39,6 +39,7 @@ IDrawingEngine * DrawingEngineFactory::CreateOpenGL()
#include "FillRectShader.h"
#include "SwapFramebuffer.h"
#include "TextureCache.h"
#include "DrawCommands.h"
#include "../../../core/Console.hpp"
#include "../../../core/Exception.hpp"
@ -191,6 +192,13 @@ private:
sint32 _clipRight;
sint32 _clipBottom;
struct {
std::vector<DrawRectCommand> rectangles;
std::vector<DrawLineCommand> lines;
std::vector<DrawImageCommand> images;
std::vector<DrawImageMaskedCommand> maskedImages;
} _commandBuffers;
public:
explicit OpenGLDrawingContext(OpenGLDrawingEngine * engine);
~OpenGLDrawingContext() override;
@ -210,6 +218,13 @@ public:
void DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour) override;
void DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * palette) override;
void FlushCommandBuffers();
void FlushRectangles();
void FlushLines();
void FlushImages();
void FlushMaskedImages();
void SetDPI(rct_drawpixelinfo * dpi);
};
@ -325,11 +340,14 @@ public:
gfx_draw_pickedup_peep(&_bitsDPI);
_drawingContext->FlushCommandBuffers();
_swapFramebuffer->SwapCopy();
rct2_draw(&_bitsDPI);
}
_drawingContext->FlushCommandBuffers();
// Scale up to window
_screenFramebuffer->Bind();
_copyFramebufferShader->Use();
@ -512,6 +530,8 @@ void OpenGLDrawingContext::Initialise()
void OpenGLDrawingContext::Resize(sint32 width, sint32 height)
{
FlushCommandBuffers();
_drawImageShader->Use();
_drawImageShader->SetScreenSize(width, height);
_drawImageMaskedShader->Use();
@ -524,6 +544,8 @@ void OpenGLDrawingContext::Resize(sint32 width, sint32 height)
void OpenGLDrawingContext::ResetPalette()
{
FlushCommandBuffers();
_textureCache->SetPalette(_engine->Palette);
_drawImageShader->Use();
_drawImageShader->SetPalette(_engine->GLPalette);
@ -543,6 +565,9 @@ void OpenGLDrawingContext::FillRect(uint32 colour, sint32 left, sint32 top, sint
right += _offsetX;
bottom += _offsetY;
DrawRectCommand command = {};
command.sourceFramebuffer = _fillRectShader->GetSourceFramebuffer();
vec4f paletteColour[2];
paletteColour[0] = _engine->GLPalette[(colour >> 0) & 0xFF];
paletteColour[1] = paletteColour[0];
@ -550,8 +575,7 @@ void OpenGLDrawingContext::FillRect(uint32 colour, sint32 left, sint32 top, sint
{
paletteColour[1].a = 0;
_fillRectShader->Use();
_fillRectShader->SetFlags(0);
command.flags = 0;
}
else if (colour & 0x2000000)
{
@ -568,20 +592,29 @@ void OpenGLDrawingContext::FillRect(uint32 colour, sint32 left, sint32 top, sint
paletteColour[1] = paletteColour[0];
GLuint srcTexture = _engine->SwapCopyReturningSourceTexture();
_fillRectShader->Use();
_fillRectShader->SetFlags(1);
_fillRectShader->SetSourceFramebuffer(srcTexture);
command.flags = 1;
command.sourceFramebuffer = srcTexture;
}
else
{
_fillRectShader->Use();
_fillRectShader->SetFlags(0);
command.flags = 0;
}
_fillRectShader->SetColour(0, paletteColour[0]);
_fillRectShader->SetColour(1, paletteColour[1]);
_fillRectShader->SetClip(_clipLeft, _clipTop, _clipRight, _clipBottom);
_fillRectShader->Draw(left, top, right + 1, bottom + 1);
command.colours[0] = paletteColour[0];
command.colours[1] = paletteColour[1];
command.clip[0] = _clipLeft;
command.clip[1] = _clipTop;
command.clip[2] = _clipRight;
command.clip[3] = _clipBottom;
command.bounds[0] = left;
command.bounds[1] = top;
command.bounds[2] = right + 1;
command.bounds[3] = bottom + 1;
_commandBuffers.rectangles.push_back(command);
FlushCommandBuffers();
}
void OpenGLDrawingContext::DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32 x2, sint32 y2)
@ -592,11 +625,22 @@ void OpenGLDrawingContext::DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32
y2 += _offsetY;
vec4f paletteColour = _engine->GLPalette[colour & 0xFF];
DrawLineCommand command = {};
command.colour = paletteColour;
_drawLineShader->Use();
_drawLineShader->SetClip(_clipLeft, _clipTop, _clipRight, _clipBottom);
_drawLineShader->SetColour(paletteColour);
_drawLineShader->Draw(x1, y1, x2, y2);
command.clip[0] = _clipLeft;
command.clip[1] = _clipTop;
command.clip[2] = _clipRight;
command.clip[3] = _clipBottom;
command.pos[0] = x1;
command.pos[1] = y1;
command.pos[2] = x2;
command.pos[3] = y2;
_commandBuffers.lines.push_back(command);
FlushCommandBuffers();
}
void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 tertiaryColour)
@ -664,10 +708,24 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t
right += _clipLeft;
bottom += _clipTop;
_drawImageShader->Use();
_drawImageShader->SetClip(_clipLeft, _clipTop, _clipRight, _clipBottom);
_drawImageShader->SetTexture(texture);
_drawImageShader->Draw(left, top, right, bottom);
DrawImageCommand command = {};
command.flags = 0;
command.clip[0] = _clipLeft;
command.clip[1] = _clipTop;
command.clip[2] = _clipRight;
command.clip[3] = _clipBottom;
command.texColour = texture;
command.bounds[0] = left;
command.bounds[1] = top;
command.bounds[2] = right;
command.bounds[3] = bottom;
_commandBuffers.images.push_back(command);
FlushCommandBuffers();
}
void OpenGLDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage)
@ -714,11 +772,23 @@ void OpenGLDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskIm
right += _clipLeft;
bottom += _clipTop;
_drawImageMaskedShader->Use();
_drawImageMaskedShader->SetClip(_clipLeft, _clipTop, _clipRight, _clipBottom);
_drawImageMaskedShader->SetTextureMask(textureMask);
_drawImageMaskedShader->SetTextureColour(textureColour);
_drawImageMaskedShader->Draw(left, top, right, bottom);
DrawImageMaskedCommand command = {};
command.clip[0] = _clipLeft;
command.clip[1] = _clipTop;
command.clip[2] = _clipRight;
command.clip[3] = _clipBottom;
command.texMask = textureMask;
command.texColour = textureColour;
command.bounds[0] = left;
command.bounds[1] = top;
command.bounds[2] = right;
command.bounds[3] = bottom;
_commandBuffers.maskedImages.push_back(command);
FlushCommandBuffers();
}
void OpenGLDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour)
@ -754,13 +824,25 @@ void OpenGLDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uin
right += _offsetX;
bottom += _offsetY;
_drawImageShader->Use();
_drawImageShader->SetClip(_clipLeft, _clipTop, _clipRight, _clipBottom);
_drawImageShader->SetTexture(texture);
_drawImageShader->SetFlags(1);
_drawImageShader->SetColour(paletteColour);
_drawImageShader->Draw(left, top, right, bottom);
_drawImageShader->SetFlags(0);
DrawImageCommand command = {};
command.flags = 1;
command.colour = paletteColour;
command.clip[0] = _clipLeft;
command.clip[1] = _clipTop;
command.clip[2] = _clipRight;
command.clip[3] = _clipBottom;
command.texColour = texture;
command.bounds[0] = left;
command.bounds[1] = top;
command.bounds[2] = right;
command.bounds[3] = bottom;
_commandBuffers.images.push_back(command);
FlushCommandBuffers();
}
void OpenGLDrawingContext::DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * palette)
@ -794,11 +876,81 @@ void OpenGLDrawingContext::DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * p
right += _offsetX;
bottom += _offsetY;
_drawImageShader->Use();
_drawImageShader->SetClip(_clipLeft, _clipTop, _clipRight, _clipBottom);
_drawImageShader->SetTexture(texture);
_drawImageShader->Draw(left, top, right, bottom);
_drawImageShader->SetFlags(0);
DrawImageCommand command = {};
command.flags = 0;
command.clip[0] = _clipLeft;
command.clip[1] = _clipTop;
command.clip[2] = _clipRight;
command.clip[3] = _clipBottom;
command.texColour = texture;
command.bounds[0] = left;
command.bounds[1] = top;
command.bounds[2] = right;
command.bounds[3] = bottom;
_commandBuffers.images.push_back(command);
FlushCommandBuffers();
}
void OpenGLDrawingContext::FlushCommandBuffers() {
FlushRectangles();
FlushLines();
FlushImages();
FlushMaskedImages();
}
void OpenGLDrawingContext::FlushRectangles() {
for (const auto& command : _commandBuffers.rectangles) {
_fillRectShader->Use();
_fillRectShader->SetFlags(command.flags);
_fillRectShader->SetSourceFramebuffer(command.sourceFramebuffer);
_fillRectShader->SetColour(0, command.colours[0]);
_fillRectShader->SetColour(1, command.colours[1]);
_fillRectShader->SetClip(command.clip[0], command.clip[1], command.clip[2], command.clip[3]);
_fillRectShader->Draw(command.bounds[0], command.bounds[1], command.bounds[2], command.bounds[3]);
}
_commandBuffers.rectangles.clear();
}
void OpenGLDrawingContext::FlushLines() {
for (const auto& command : _commandBuffers.lines) {
_drawLineShader->Use();
_drawLineShader->SetColour(command.colour);
_drawLineShader->SetClip(command.clip[0], command.clip[1], command.clip[2], command.clip[3]);
_drawLineShader->Draw(command.pos[0], command.pos[1], command.pos[2], command.pos[3]);
}
_commandBuffers.lines.clear();
}
void OpenGLDrawingContext::FlushImages() {
for (const auto& command : _commandBuffers.images) {
_drawImageShader->Use();
_drawImageShader->SetClip(_clipLeft, _clipTop, _clipRight, _clipBottom);
_drawImageShader->SetTexture(command.texColour);
_drawImageShader->SetFlags(command.flags);
_drawImageShader->SetColour(command.colour);
_drawImageShader->Draw(command.bounds[0], command.bounds[1], command.bounds[2], command.bounds[3]);
}
_commandBuffers.images.clear();
}
void OpenGLDrawingContext::FlushMaskedImages() {
for (const auto& command : _commandBuffers.maskedImages) {
_drawImageMaskedShader->Use();
_drawImageMaskedShader->SetClip(command.clip[0], command.clip[1], command.clip[2], command.clip[3]);
_drawImageMaskedShader->SetTextureMask(command.texMask);
_drawImageMaskedShader->SetTextureColour(command.texColour);
_drawImageMaskedShader->Draw(command.bounds[0], command.bounds[1], command.bounds[2], command.bounds[3]);
}
_commandBuffers.maskedImages.clear();
}
void OpenGLDrawingContext::SetDPI(rct_drawpixelinfo * dpi)