implement masked image shader

This commit is contained in:
Ted John 2016-06-10 20:17:00 +01:00
parent 808afe0a81
commit 84ca31a240
6 changed files with 254 additions and 61 deletions

View File

@ -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;
}

View File

@ -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);
}

View File

@ -18,6 +18,8 @@
<None Include="curl-ca-bundle.crt" />
<None Include="data\shaders\drawimage.frag" />
<None Include="data\shaders\drawimage.vert" />
<None Include="data\shaders\drawimagemasked.frag" />
<None Include="data\shaders\drawimagemasked.vert" />
<None Include="data\shaders\fillrect.frag" />
<None Include="data\shaders\fillrect.vert" />
<None Include="openrct2.exe" />
@ -46,6 +48,7 @@
<ClCompile Include="src\diagnostic.c" />
<ClCompile Include="src\drawing\drawing.c" />
<ClCompile Include="src\drawing\drawing_fast.cpp" />
<ClCompile Include="src\drawing\engines\opengl\DrawImageMaskedShader.cpp" />
<ClCompile Include="src\drawing\engines\opengl\DrawImageShader.cpp" />
<ClCompile Include="src\drawing\engines\opengl\FillRectShader.cpp" />
<ClCompile Include="src\drawing\engines\opengl\OpenGLAPI.cpp" />
@ -345,6 +348,7 @@
<ClInclude Include="src\diagnostic.h" />
<ClInclude Include="src\drawing\drawing.h" />
<ClInclude Include="src\drawing\engines\OpenGLAPI.h" />
<ClInclude Include="src\drawing\engines\opengl\DrawImageMaskedShader.h" />
<ClInclude Include="src\drawing\engines\opengl\DrawImageShader.h" />
<ClInclude Include="src\drawing\engines\opengl\FillRectShader.h" />
<ClInclude Include="src\drawing\engines\opengl\GLSLTypes.h" />

View File

@ -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 */

View File

@ -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();
};

View File

@ -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)