Merge draw image and draw masked image shaders

This commit is contained in:
Alexander Overvoorde 2016-07-23 02:30:13 +02:00
parent fbb7029de4
commit 360a92e906
11 changed files with 52 additions and 267 deletions

View File

@ -7,7 +7,9 @@ flat in ivec4 fClip;
flat in int fFlags;
in vec4 fColour;
in vec2 fTexCoordScale;
flat in int fTexSlot;
flat in int fTexColourSlot;
flat in int fTexMaskSlot;
flat in int fMask;
in vec2 fPosition;
in vec2 fTextureCoordinate;
@ -22,13 +24,22 @@ void main()
discard;
}
vec4 texel = uPalette[texture(uTexture, vec3(fTextureCoordinate * fTexCoordScale, float(fTexSlot))).r];
if ((fFlags & 1) != 0)
vec4 mask = uPalette[texture(uTexture, vec3(fTextureCoordinate * fTexCoordScale, float(fTexMaskSlot))).r];
vec4 texel = uPalette[texture(uTexture, vec3(fTextureCoordinate * fTexCoordScale, float(fTexColourSlot))).r];
if (fMask)
{
oColour = vec4(fColour.rgb, fColour.a * texel.a);
oColour = texel * mask;
}
else
{
oColour = texel;
if ((fFlags & 1) != 0)
{
oColour = vec4(fColour.rgb, fColour.a * texel.a);
}
else
{
oColour = texel;
}
}
}

View File

@ -5,10 +5,12 @@ uniform ivec4 uTextureCoordinates;
in ivec4 ivClip;
in vec2 ivTexCoordScale;
in int ivTexSlot;
in int ivTexColourSlot;
in int ivTexMaskSlot;
in int ivFlags;
in vec4 ivColour;
in ivec4 ivBounds;
in int ivMask;
in uint vIndex;
@ -18,7 +20,9 @@ flat out ivec4 fClip;
flat out int fFlags;
out vec4 fColour;
out vec2 fTexCoordScale;
flat out int fTexSlot;
flat out int fTexColourSlot;
flat out int fTexMaskSlot;
flat out int fMask;
void main()
{
@ -53,7 +57,9 @@ void main()
fFlags = ivFlags;
fColour = ivColour;
fTexCoordScale = ivTexCoordScale;
fTexSlot = ivTexSlot;
fTexColourSlot = ivTexColourSlot;
fTexMaskSlot = ivTexMaskSlot;
fMask = ivMask;
gl_Position = vec4(pos, 0.0, 1.0);
}

View File

@ -1,24 +0,0 @@
#version 150
uniform ivec4 uClip;
uniform usampler2D uTextureMask;
uniform usampler2D uTextureColour;
uniform vec4 uPalette[256];
in vec2 fPosition;
in vec2 fTextureCoordinate;
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 = uPalette[texture(uTextureMask, fTextureCoordinate).r];
vec4 colour = uPalette[texture(uTextureColour, fTextureCoordinate).r];
oColour = colour * mask;
}

View File

@ -1,41 +0,0 @@
#version 150
uniform ivec2 uScreenSize;
uniform ivec4 uBounds;
in uint vIndex;
out vec2 fPosition;
out vec2 fTextureCoordinate;
void main()
{
vec2 pos;
switch (vIndex) {
case 0u:
pos = uBounds.xy;
fTextureCoordinate = vec2(0, 0);
break;
case 1u:
pos = uBounds.zy;
fTextureCoordinate = vec2(1, 0);
break;
case 2u:
pos = uBounds.xw;
fTextureCoordinate = vec2(0, 1);
break;
case 3u:
pos = uBounds.zw;
fTextureCoordinate = vec2(1, 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);
}

View File

@ -56,7 +56,6 @@
<ClCompile Include="src\drawing\drawing.c" />
<ClCompile Include="src\drawing\drawing_fast.cpp" />
<ClCompile Include="src\drawing\engines\opengl\CopyFramebufferShader.cpp" />
<ClCompile Include="src\drawing\engines\opengl\DrawImageMaskedShader.cpp" />
<ClCompile Include="src\drawing\engines\opengl\DrawImageShader.cpp" />
<ClCompile Include="src\drawing\engines\opengl\DrawLineShader.cpp" />
<ClCompile Include="src\drawing\engines\opengl\FillRectShader.cpp" />
@ -384,7 +383,6 @@
<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" />
<ClInclude Include="src\drawing\engines\opengl\FillRectShader.h" />

View File

@ -37,14 +37,9 @@ struct DrawLineCommand {
struct DrawImageCommand {
uint32 flags;
vec4f colour;
sint32 clip[4];
CachedTextureInfo texColour;
sint32 bounds[4];
};
struct DrawImageMaskedCommand {
sint32 clip[4];
CachedTextureInfo texMask;
CachedTextureInfo texColour;
sint32 bounds[4];
bool mask;
};

View File

@ -1,99 +0,0 @@
#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);
GLuint vertices[] = { 0, 1, 2, 2, 1, 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, 0);
Use();
glUniform1i(uTextureMask, 0);
glUniform1i(uTextureColour, 1);
}
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");
uPalette = GetUniformLocation("uPalette");
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)
{
OpenGLAPI::SetTexture(0, GL_TEXTURE_2D, texture);
}
void DrawImageMaskedShader::SetTextureColour(GLuint texture)
{
OpenGLAPI::SetTexture(1, GL_TEXTURE_2D, texture);
}
void DrawImageMaskedShader::SetPalette(const vec4f *glPalette)
{
glUniform4fv(uPalette, 256, (const GLfloat *) glPalette);
}
void DrawImageMaskedShader::Draw(sint32 left, sint32 top, sint32 right, sint32 bottom)
{
SetBounds(left, top, right, bottom);
glBindVertexArray(_vao);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
#endif /* DISABLE_OPENGL */

View File

@ -1,52 +0,0 @@
#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"
#include <SDL_pixels.h>
class DrawImageMaskedShader : public OpenGLShaderProgram
{
private:
GLuint uScreenSize;
GLuint uClip;
GLuint uBounds;
GLuint uTextureMask;
GLuint uTextureColour;
GLuint uPalette;
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 SetPalette(const vec4f *glPalette);
void Draw(sint32 left, sint32 top, sint32 right, sint32 bottom);
private:
void GetLocations();
};

View File

@ -84,24 +84,30 @@ void DrawImageShader::DrawInstances(const std::vector<DrawImageInstance>& instan
glVertexAttribIPointer(GetAttributeLocation("ivClip"), 4, GL_INT, sizeof(DrawImageInstance), (void*) offsetof(DrawImageInstance, clip));
glVertexAttribPointer(GetAttributeLocation("ivTexCoordScale"), 2, GL_FLOAT, GL_FALSE, sizeof(DrawImageInstance), (void*) offsetof(DrawImageInstance, texCoordScale));
glVertexAttribIPointer(GetAttributeLocation("ivTexSlot"), 1, GL_INT, sizeof(DrawImageInstance), (void*) offsetof(DrawImageInstance, texSlot));
glVertexAttribIPointer(GetAttributeLocation("ivTexColourSlot"), 1, GL_INT, sizeof(DrawImageInstance), (void*) offsetof(DrawImageInstance, texColourSlot));
glVertexAttribIPointer(GetAttributeLocation("ivTexMaskSlot"), 1, GL_INT, sizeof(DrawImageInstance), (void*) offsetof(DrawImageInstance, texMaskSlot));
glVertexAttribIPointer(GetAttributeLocation("ivFlags"), 1, GL_INT, sizeof(DrawImageInstance), (void*) offsetof(DrawImageInstance, flags));
glVertexAttribPointer(GetAttributeLocation("ivColour"), 4, GL_FLOAT, GL_FALSE, sizeof(DrawImageInstance), (void*) offsetof(DrawImageInstance, colour));
glVertexAttribIPointer(GetAttributeLocation("ivBounds"), 4, GL_INT, sizeof(DrawImageInstance), (void*) offsetof(DrawImageInstance, bounds));
glVertexAttribIPointer(GetAttributeLocation("ivMask"), 1, GL_INT, sizeof(DrawImageInstance), (void*) offsetof(DrawImageInstance, mask));
glEnableVertexAttribArray(GetAttributeLocation("ivClip"));
glEnableVertexAttribArray(GetAttributeLocation("ivTexCoordScale"));
glEnableVertexAttribArray(GetAttributeLocation("ivTexSlot"));
glEnableVertexAttribArray(GetAttributeLocation("ivTexColourSlot"));
glEnableVertexAttribArray(GetAttributeLocation("ivTexMaskSlot"));
glEnableVertexAttribArray(GetAttributeLocation("ivFlags"));
glEnableVertexAttribArray(GetAttributeLocation("ivColour"));
glEnableVertexAttribArray(GetAttributeLocation("ivBounds"));
glEnableVertexAttribArray(GetAttributeLocation("ivMask"));
glVertexAttribDivisor(GetAttributeLocation("ivClip"), 1);
glVertexAttribDivisor(GetAttributeLocation("ivTexCoordScale"), 1);
glVertexAttribDivisor(GetAttributeLocation("ivTexSlot"), 1);
glVertexAttribDivisor(GetAttributeLocation("ivTexColourSlot"), 1);
glVertexAttribDivisor(GetAttributeLocation("ivTexMaskSlot"), 1);
glVertexAttribDivisor(GetAttributeLocation("ivFlags"), 1);
glVertexAttribDivisor(GetAttributeLocation("ivColour"), 1);
glVertexAttribDivisor(GetAttributeLocation("ivBounds"), 1);
glVertexAttribDivisor(GetAttributeLocation("ivMask"), 1);
// Draw instances
glDrawArraysInstanced(GL_TRIANGLES, 0, 6, instances.size());

View File

@ -25,10 +25,12 @@
struct DrawImageInstance {
vec4i clip;
vec2f texCoordScale;
int texSlot;
int texColourSlot;
int texMaskSlot;
int flags;
vec4f colour;
vec4i bounds;
int mask;
};
class DrawImageShader : public OpenGLShaderProgram

View File

@ -34,7 +34,6 @@ IDrawingEngine * DrawingEngineFactory::CreateOpenGL()
#include "OpenGLFramebuffer.h"
#include "CopyFramebufferShader.h"
#include "DrawImageShader.h"
#include "DrawImageMaskedShader.h"
#include "DrawLineShader.h"
#include "FillRectShader.h"
#include "SwapFramebuffer.h"
@ -179,7 +178,6 @@ private:
rct_drawpixelinfo * _dpi;
DrawImageShader * _drawImageShader = nullptr;
DrawImageMaskedShader * _drawImageMaskedShader = nullptr;
DrawLineShader * _drawLineShader = nullptr;
FillRectShader * _fillRectShader = nullptr;
@ -196,7 +194,6 @@ private:
std::vector<DrawRectCommand> rectangles;
std::vector<DrawLineCommand> lines;
std::vector<DrawImageCommand> images;
std::vector<DrawImageMaskedCommand> maskedImages;
} _commandBuffers;
public:
@ -223,7 +220,6 @@ public:
void FlushRectangles();
void FlushLines();
void FlushImages();
void FlushMaskedImages();
void SetDPI(rct_drawpixelinfo * dpi);
};
@ -294,6 +290,9 @@ public:
throw Exception("Unable to initialise OpenGL.");
}
// TODO: Remove when OpenGL optimization is done
SDL_GL_SetSwapInterval(0);
#ifdef DEBUG
glDebugMessageCallback(OpenGLAPI::DebugCallback, nullptr);
#endif
@ -517,7 +516,6 @@ OpenGLDrawingContext::OpenGLDrawingContext(OpenGLDrawingEngine * engine)
OpenGLDrawingContext::~OpenGLDrawingContext()
{
delete _drawImageShader;
delete _drawImageMaskedShader;
delete _drawLineShader;
delete _fillRectShader;
@ -532,7 +530,6 @@ IDrawingEngine * OpenGLDrawingContext::GetEngine()
void OpenGLDrawingContext::Initialise()
{
_drawImageShader = new DrawImageShader();
_drawImageMaskedShader = new DrawImageMaskedShader();
_drawLineShader = new DrawLineShader();
_fillRectShader = new FillRectShader();
}
@ -543,8 +540,6 @@ 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();
@ -558,8 +553,6 @@ void OpenGLDrawingContext::ResetPalette()
_textureCache->SetPalette(_engine->Palette);
_drawImageShader->Use();
_drawImageShader->SetPalette(_engine->GLPalette);
_drawImageMaskedShader->Use();
_drawImageMaskedShader->SetPalette(_engine->GLPalette);
}
void OpenGLDrawingContext::Clear(uint32 colour)
@ -724,6 +717,7 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t
DrawImageCommand command = {};
command.flags = 0;
command.mask = false;
command.clip[0] = _clipLeft;
command.clip[1] = _clipTop;
@ -785,7 +779,9 @@ void OpenGLDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskIm
right += _clipLeft;
bottom += _clipTop;
DrawImageMaskedCommand command = {};
DrawImageCommand command = {};
command.mask = true;
command.clip[0] = _clipLeft;
command.clip[1] = _clipTop;
@ -800,11 +796,7 @@ void OpenGLDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskIm
command.bounds[2] = right;
command.bounds[3] = bottom;
_commandBuffers.maskedImages.push_back(command);
// Currently not properly ordered with regular images yet
// TODO: uncomment once masked images are mixed with normal images using depth sorting
//FlushCommandBuffers();
_commandBuffers.images.push_back(command);
}
void OpenGLDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour)
@ -843,6 +835,7 @@ void OpenGLDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uin
DrawImageCommand command = {};
command.flags = 1;
command.mask = false;
command.colour = paletteColour;
command.clip[0] = _clipLeft;
@ -894,6 +887,7 @@ void OpenGLDrawingContext::DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * p
DrawImageCommand command = {};
command.flags = 0;
command.mask = false;
command.clip[0] = _clipLeft;
command.clip[1] = _clipTop;
@ -915,7 +909,6 @@ void OpenGLDrawingContext::FlushCommandBuffers() {
FlushLines();
FlushImages();
FlushMaskedImages();
}
void OpenGLDrawingContext::FlushRectangles() {
@ -956,10 +949,13 @@ void OpenGLDrawingContext::FlushImages() {
instance.clip = {command.clip[0], command.clip[1], command.clip[2], command.clip[3]};
instance.texCoordScale = command.texColour.dimensions;
instance.texSlot = command.texColour.slot;
instance.texColourSlot = command.texColour.slot;
instance.texMaskSlot = command.texMask.slot;
if (!command.mask) instance.texMaskSlot = instance.texColourSlot;
instance.flags = command.flags;
instance.colour = command.colour;
instance.bounds = {command.bounds[0], command.bounds[1], command.bounds[2], command.bounds[3]};
instance.mask = command.mask;
instances.push_back(instance);
}
@ -970,19 +966,6 @@ void OpenGLDrawingContext::FlushImages() {
_commandBuffers.images.clear();
}
void OpenGLDrawingContext::FlushMaskedImages() {
// DEBUG: disabled until new array based texture cache is finished
/*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)
{
rct_drawpixelinfo * screenDPI = _engine->GetDPI();