mirror of https://github.com/OpenRCT2/OpenRCT2.git
Change OpenGL renderer to use command buffers
This commit is contained in:
parent
d8d39c1ade
commit
e7626064f2
|
@ -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" />
|
||||
|
|
|
@ -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];
|
||||
};
|
|
@ -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 */
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue