mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-20 13:33:02 +01:00
OpenGL: Improve Shaders
This commit is contained in:
committed by
Michał Janiszewski
parent
f105237a2e
commit
6bf2e0157b
@@ -18,6 +18,20 @@
|
||||
|
||||
#include "CopyFramebufferShader.h"
|
||||
|
||||
struct VDStruct
|
||||
{
|
||||
GLfloat position[2];
|
||||
GLfloat texturecoordinate[2];
|
||||
};
|
||||
|
||||
constexpr VDStruct VertexData[4] =
|
||||
{
|
||||
{ -1.0f, -1.0f, 0.0f, 0.0f },
|
||||
{ 1.0f, -1.0f, 1.0f, 0.0f },
|
||||
{ -1.0f, 1.0f, 0.0f, 1.0f },
|
||||
{ 1.0f, 1.0f, 1.0f, 1.0f },
|
||||
};
|
||||
|
||||
CopyFramebufferShader::CopyFramebufferShader() : OpenGLShaderProgram("copyframebuffer")
|
||||
{
|
||||
GetLocations();
|
||||
@@ -25,16 +39,17 @@ CopyFramebufferShader::CopyFramebufferShader() : OpenGLShaderProgram("copyframeb
|
||||
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);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData), VertexData, GL_STATIC_DRAW);
|
||||
|
||||
glBindVertexArray(_vao);
|
||||
glEnableVertexAttribArray(vIndex);
|
||||
glVertexAttribIPointer(vIndex, 1, GL_INT, 0, nullptr);
|
||||
glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, position));
|
||||
glVertexAttribPointer(vTextureCoordinate, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, texturecoordinate));
|
||||
|
||||
glEnableVertexAttribArray(vPosition);
|
||||
glEnableVertexAttribArray(vTextureCoordinate);
|
||||
|
||||
Use();
|
||||
SetTextureCoordinates(0, 0, 1, 1);
|
||||
glUniform1i(uTexture, 0);
|
||||
}
|
||||
|
||||
@@ -46,28 +61,11 @@ CopyFramebufferShader::~CopyFramebufferShader()
|
||||
|
||||
void CopyFramebufferShader::GetLocations()
|
||||
{
|
||||
uScreenSize = GetUniformLocation("uScreenSize");
|
||||
uBounds = GetUniformLocation("uBounds");
|
||||
uTextureCoordinates = GetUniformLocation("uTextureCoordinates");
|
||||
uTexture = GetUniformLocation("uTexture");
|
||||
uPalette = GetUniformLocation("uPalette");
|
||||
|
||||
vIndex = GetAttributeLocation("vIndex");
|
||||
}
|
||||
|
||||
void CopyFramebufferShader::SetScreenSize(sint32 width, sint32 height)
|
||||
{
|
||||
glUniform2i(uScreenSize, width, height);
|
||||
}
|
||||
|
||||
void CopyFramebufferShader::SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom)
|
||||
{
|
||||
glUniform4i(uBounds, left, top, right, bottom);
|
||||
}
|
||||
|
||||
void CopyFramebufferShader::SetTextureCoordinates(sint32 left, sint32 top, sint32 right, sint32 bottom)
|
||||
{
|
||||
glUniform4i(uTextureCoordinates, left, top, right, bottom);
|
||||
vPosition = GetAttributeLocation("vPosition");
|
||||
vTextureCoordinate = GetAttributeLocation("vTextureCoordinate");
|
||||
}
|
||||
|
||||
void CopyFramebufferShader::SetTexture(GLuint texture)
|
||||
@@ -82,7 +80,7 @@ void CopyFramebufferShader::SetPalette(const vec4f * glPalette) {
|
||||
void CopyFramebufferShader::Draw()
|
||||
{
|
||||
glBindVertexArray(_vao);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
#endif /* DISABLE_OPENGL */
|
||||
|
||||
@@ -22,13 +22,11 @@
|
||||
class CopyFramebufferShader final : public OpenGLShaderProgram
|
||||
{
|
||||
private:
|
||||
GLuint uScreenSize;
|
||||
GLuint uBounds;
|
||||
GLuint uTextureCoordinates;
|
||||
GLuint uTexture;
|
||||
GLuint uPalette;
|
||||
|
||||
GLuint vIndex;
|
||||
GLuint vPosition;
|
||||
GLuint vTextureCoordinate;
|
||||
|
||||
GLuint _vbo;
|
||||
GLuint _vao;
|
||||
@@ -37,9 +35,6 @@ public:
|
||||
CopyFramebufferShader();
|
||||
~CopyFramebufferShader() override;
|
||||
|
||||
void SetScreenSize(sint32 width, sint32 height);
|
||||
void SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom);
|
||||
void SetTextureCoordinates(sint32 left, sint32 top, sint32 right, sint32 bottom);
|
||||
void SetTexture(GLuint texture);
|
||||
void SetPalette(const vec4f * glPalette);
|
||||
|
||||
|
||||
@@ -64,43 +64,33 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct DrawRectCommand {
|
||||
uint32 flags;
|
||||
GLuint sourceFramebuffer;
|
||||
sint32 clip[4];
|
||||
sint32 bounds[4];
|
||||
GLuint paletteRemap[256];
|
||||
};
|
||||
|
||||
struct DrawLineCommand {
|
||||
struct DrawLineCommand
|
||||
{
|
||||
uint8 colour;
|
||||
sint32 clip[4];
|
||||
vec4i clip;
|
||||
sint32 pos[4];
|
||||
};
|
||||
|
||||
// Per-instance data for images
|
||||
struct DrawImageCommand {
|
||||
struct DrawRectCommand
|
||||
{
|
||||
vec4i clip;
|
||||
sint32 texColourAtlas;
|
||||
vec4f texColourBounds;
|
||||
sint32 texMaskAtlas;
|
||||
vec4f texMaskBounds;
|
||||
sint32 texPaletteAtlas;
|
||||
vec4f texPaletteBounds;
|
||||
vec3i palettes;
|
||||
sint32 flags;
|
||||
uint8 colour;
|
||||
uint32 colour;
|
||||
vec4i bounds;
|
||||
sint32 mask;
|
||||
|
||||
enum
|
||||
{
|
||||
FLAG_COLOUR = (1 << 0),
|
||||
FLAG_REMAP = (1 << 1),
|
||||
FLAG_TRANSPARENT = (1 << 2),
|
||||
FLAG_TRANSPARENT_SPECIAL = (1 << 3),
|
||||
FLAG_NO_TEXTURE = (1 << 2),
|
||||
FLAG_MASK = (1 << 3),
|
||||
FLAG_CROSS_HATCH = (1 << 4),
|
||||
};
|
||||
};
|
||||
|
||||
typedef CommandBatch<DrawImageCommand> ImageCommandBatch;
|
||||
typedef CommandBatch<DrawLineCommand> LineCommandBatch;
|
||||
typedef CommandBatch<DrawRectCommand> RectCommandBatch;
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
#pragma region Copyright (c) 2014-2017 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 "DrawImageShader.h"
|
||||
|
||||
DrawImageShader::DrawImageShader() : OpenGLShaderProgram("drawimage")
|
||||
{
|
||||
GetLocations();
|
||||
|
||||
glGenBuffers(1, &_vbo);
|
||||
glGenBuffers(1, &_vboInstances);
|
||||
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);
|
||||
|
||||
glVertexAttribIPointer(vIndex, 1, GL_INT, 0, nullptr);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboInstances);
|
||||
glVertexAttribIPointer(vClip, 4, GL_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, clip));
|
||||
glVertexAttribIPointer(vTexColourAtlas, 1, GL_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, texColourAtlas));
|
||||
glVertexAttribPointer(vTexColourBounds, 4, GL_FLOAT, GL_FALSE, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, texColourBounds));
|
||||
glVertexAttribIPointer(vTexMaskAtlas, 1, GL_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, texMaskAtlas));
|
||||
glVertexAttribPointer(vTexMaskBounds, 4, GL_FLOAT, GL_FALSE, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, texMaskBounds));
|
||||
glVertexAttribIPointer(vTexPaletteAtlas, 1, GL_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, texPaletteAtlas));
|
||||
glVertexAttribPointer(vTexPaletteBounds, 4, GL_FLOAT, GL_FALSE, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, texPaletteBounds));
|
||||
glVertexAttribIPointer(vFlags, 1, GL_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, flags));
|
||||
glVertexAttribIPointer(vColour, 1, GL_UNSIGNED_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, colour));
|
||||
glVertexAttribIPointer(vBounds, 4, GL_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, bounds));
|
||||
glVertexAttribIPointer(vMask, 1, GL_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, mask));
|
||||
|
||||
glEnableVertexAttribArray(vIndex);
|
||||
glEnableVertexAttribArray(vClip);
|
||||
glEnableVertexAttribArray(vTexColourAtlas);
|
||||
glEnableVertexAttribArray(vTexColourBounds);
|
||||
glEnableVertexAttribArray(vTexMaskAtlas);
|
||||
glEnableVertexAttribArray(vTexMaskBounds);
|
||||
glEnableVertexAttribArray(vTexPaletteAtlas);
|
||||
glEnableVertexAttribArray(vTexPaletteBounds);
|
||||
glEnableVertexAttribArray(vFlags);
|
||||
glEnableVertexAttribArray(vColour);
|
||||
glEnableVertexAttribArray(vBounds);
|
||||
glEnableVertexAttribArray(vMask);
|
||||
|
||||
glVertexAttribDivisor(vClip, 1);
|
||||
glVertexAttribDivisor(vTexColourAtlas, 1);
|
||||
glVertexAttribDivisor(vTexColourBounds, 1);
|
||||
glVertexAttribDivisor(vTexMaskAtlas, 1);
|
||||
glVertexAttribDivisor(vTexMaskBounds, 1);
|
||||
glVertexAttribDivisor(vTexPaletteAtlas, 1);
|
||||
glVertexAttribDivisor(vTexPaletteBounds, 1);
|
||||
glVertexAttribDivisor(vFlags, 1);
|
||||
glVertexAttribDivisor(vColour, 1);
|
||||
glVertexAttribDivisor(vBounds, 1);
|
||||
glVertexAttribDivisor(vMask, 1);
|
||||
|
||||
Use();
|
||||
glUniform1i(uTexture, 0);
|
||||
}
|
||||
|
||||
DrawImageShader::~DrawImageShader()
|
||||
{
|
||||
glDeleteBuffers(1, &_vbo);
|
||||
glDeleteBuffers(1, &_vboInstances);
|
||||
glDeleteVertexArrays(1, &_vao);
|
||||
}
|
||||
|
||||
void DrawImageShader::GetLocations()
|
||||
{
|
||||
uScreenSize = GetUniformLocation("uScreenSize");
|
||||
uTexture = GetUniformLocation("uTexture");
|
||||
|
||||
vIndex = GetAttributeLocation("vIndex");
|
||||
vClip = GetAttributeLocation("ivClip");
|
||||
vTexColourAtlas = GetAttributeLocation("ivTexColourAtlas");
|
||||
vTexColourBounds = GetAttributeLocation("ivTexColourBounds");
|
||||
vTexMaskAtlas = GetAttributeLocation("ivTexMaskAtlas");
|
||||
vTexMaskBounds = GetAttributeLocation("ivTexMaskBounds");
|
||||
vTexPaletteAtlas = GetAttributeLocation("ivTexPaletteAtlas");
|
||||
vTexPaletteBounds = GetAttributeLocation("ivTexPaletteBounds");
|
||||
vFlags = GetAttributeLocation("ivFlags");
|
||||
vColour = GetAttributeLocation("ivColour");
|
||||
vBounds = GetAttributeLocation("ivBounds");
|
||||
vMask = GetAttributeLocation("ivMask");
|
||||
}
|
||||
|
||||
void DrawImageShader::SetScreenSize(sint32 width, sint32 height)
|
||||
{
|
||||
glUniform2i(uScreenSize, width, height);
|
||||
}
|
||||
|
||||
void DrawImageShader::DrawInstances(const ImageCommandBatch& instances)
|
||||
{
|
||||
glBindVertexArray(_vao);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboInstances);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(DrawImageCommand) * instances.size(), instances.data(), GL_STREAM_DRAW);
|
||||
|
||||
glDrawArraysInstanced(GL_TRIANGLES, 0, 6, (GLsizei)instances.size());
|
||||
}
|
||||
|
||||
#endif /* DISABLE_OPENGL */
|
||||
@@ -19,6 +19,17 @@
|
||||
#include "DrawLineShader.h"
|
||||
#include "OpenGLFramebuffer.h"
|
||||
|
||||
struct VDStruct
|
||||
{
|
||||
GLfloat mat[4][2];
|
||||
};
|
||||
|
||||
constexpr VDStruct VertexData[2] =
|
||||
{
|
||||
{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
|
||||
};
|
||||
|
||||
DrawLineShader::DrawLineShader() : OpenGLShaderProgram("drawline")
|
||||
{
|
||||
GetLocations();
|
||||
@@ -26,13 +37,19 @@ DrawLineShader::DrawLineShader() : OpenGLShaderProgram("drawline")
|
||||
glGenBuffers(1, &_vbo);
|
||||
glGenVertexArrays(1, &_vao);
|
||||
|
||||
GLuint vertices[] = { 0, 1 };
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData), VertexData, GL_STATIC_DRAW);
|
||||
|
||||
glBindVertexArray(_vao);
|
||||
glEnableVertexAttribArray(vIndex);
|
||||
glVertexAttribIPointer(vIndex, 1, GL_INT, 0, nullptr);
|
||||
glVertexAttribPointer(vVertMat+0, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[0]));
|
||||
glVertexAttribPointer(vVertMat+1, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[1]));
|
||||
glVertexAttribPointer(vVertMat+2, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[2]));
|
||||
glVertexAttribPointer(vVertMat+3, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[3]));
|
||||
|
||||
glEnableVertexAttribArray(vVertMat+0);
|
||||
glEnableVertexAttribArray(vVertMat+1);
|
||||
glEnableVertexAttribArray(vVertMat+2);
|
||||
glEnableVertexAttribArray(vVertMat+3);
|
||||
|
||||
Use();
|
||||
}
|
||||
@@ -50,7 +67,7 @@ void DrawLineShader::GetLocations()
|
||||
uBounds = GetUniformLocation("uBounds");
|
||||
uColour = GetUniformLocation("uColour");
|
||||
|
||||
vIndex = GetAttributeLocation("vIndex");
|
||||
vVertMat = GetAttributeLocation("vVertMat");
|
||||
}
|
||||
|
||||
void DrawLineShader::SetScreenSize(sint32 width, sint32 height)
|
||||
|
||||
@@ -27,7 +27,7 @@ private:
|
||||
GLuint uBounds;
|
||||
GLuint uColour;
|
||||
|
||||
GLuint vIndex;
|
||||
GLuint vVertMat;
|
||||
|
||||
GLuint _vbo;
|
||||
GLuint _vao;
|
||||
|
||||
138
src/openrct2-ui/drawing/engines/opengl/DrawRectShader.cpp
Normal file
138
src/openrct2-ui/drawing/engines/opengl/DrawRectShader.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
#pragma region Copyright (c) 2014-2017 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 "DrawRectShader.h"
|
||||
|
||||
struct VDStruct
|
||||
{
|
||||
GLfloat mat[4][2];
|
||||
GLfloat vec[2];
|
||||
};
|
||||
|
||||
constexpr VDStruct VertexData[4] =
|
||||
{
|
||||
{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f },
|
||||
{ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f },
|
||||
};
|
||||
|
||||
DrawRectShader::DrawRectShader() : OpenGLShaderProgram("drawrect")
|
||||
{
|
||||
GetLocations();
|
||||
|
||||
glGenBuffers(1, &_vbo);
|
||||
glGenBuffers(1, &_vboInstances);
|
||||
glGenVertexArrays(1, &_vao);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData), VertexData, GL_STATIC_DRAW);
|
||||
|
||||
glBindVertexArray(_vao);
|
||||
|
||||
glVertexAttribPointer(vVertMat+0, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[0]));
|
||||
glVertexAttribPointer(vVertMat+1, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[1]));
|
||||
glVertexAttribPointer(vVertMat+2, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[2]));
|
||||
glVertexAttribPointer(vVertMat+3, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[3]));
|
||||
glVertexAttribPointer(vVertVec, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, vec) );
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboInstances);
|
||||
glVertexAttribIPointer(vClip, 4, GL_INT, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, clip));
|
||||
glVertexAttribIPointer(vTexColourAtlas, 1, GL_INT, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, texColourAtlas));
|
||||
glVertexAttribPointer(vTexColourBounds, 4, GL_FLOAT, GL_FALSE, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, texColourBounds));
|
||||
glVertexAttribIPointer(vTexMaskAtlas, 1, GL_INT, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, texMaskAtlas));
|
||||
glVertexAttribPointer(vTexMaskBounds, 4, GL_FLOAT, GL_FALSE, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, texMaskBounds));
|
||||
glVertexAttribIPointer(vPalettes, 3, GL_INT, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, palettes));
|
||||
glVertexAttribIPointer(vFlags, 1, GL_INT, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, flags));
|
||||
glVertexAttribIPointer(vColour, 1, GL_UNSIGNED_INT, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, colour));
|
||||
glVertexAttribIPointer(vBounds, 4, GL_INT, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, bounds));
|
||||
|
||||
glEnableVertexAttribArray(vVertMat+0);
|
||||
glEnableVertexAttribArray(vVertMat+1);
|
||||
glEnableVertexAttribArray(vVertMat+2);
|
||||
glEnableVertexAttribArray(vVertMat+3);
|
||||
glEnableVertexAttribArray(vVertVec);
|
||||
|
||||
glEnableVertexAttribArray(vClip);
|
||||
glEnableVertexAttribArray(vTexColourAtlas);
|
||||
glEnableVertexAttribArray(vTexColourBounds);
|
||||
glEnableVertexAttribArray(vTexMaskAtlas);
|
||||
glEnableVertexAttribArray(vTexMaskBounds);
|
||||
glEnableVertexAttribArray(vPalettes);
|
||||
glEnableVertexAttribArray(vFlags);
|
||||
glEnableVertexAttribArray(vColour);
|
||||
glEnableVertexAttribArray(vBounds);
|
||||
|
||||
glVertexAttribDivisor(vClip, 1);
|
||||
glVertexAttribDivisor(vTexColourAtlas, 1);
|
||||
glVertexAttribDivisor(vTexColourBounds, 1);
|
||||
glVertexAttribDivisor(vTexMaskAtlas, 1);
|
||||
glVertexAttribDivisor(vTexMaskBounds, 1);
|
||||
glVertexAttribDivisor(vPalettes, 1);
|
||||
glVertexAttribDivisor(vFlags, 1);
|
||||
glVertexAttribDivisor(vColour, 1);
|
||||
glVertexAttribDivisor(vBounds, 1);
|
||||
|
||||
Use();
|
||||
glUniform1i(uTexture, 0);
|
||||
glUniform1i(uPaletteTex, 1);
|
||||
}
|
||||
|
||||
DrawRectShader::~DrawRectShader()
|
||||
{
|
||||
glDeleteBuffers(1, &_vbo);
|
||||
glDeleteBuffers(1, &_vboInstances);
|
||||
glDeleteVertexArrays(1, &_vao);
|
||||
}
|
||||
|
||||
void DrawRectShader::GetLocations()
|
||||
{
|
||||
uScreenSize = GetUniformLocation("uScreenSize");
|
||||
uTexture = GetUniformLocation("uTexture");
|
||||
uPaletteTex = GetUniformLocation("uPaletteTex");
|
||||
|
||||
vClip = GetAttributeLocation("vClip");
|
||||
vTexColourAtlas = GetAttributeLocation("vTexColourAtlas");
|
||||
vTexColourBounds = GetAttributeLocation("vTexColourBounds");
|
||||
vTexMaskAtlas = GetAttributeLocation("vTexMaskAtlas");
|
||||
vTexMaskBounds = GetAttributeLocation("vTexMaskBounds");
|
||||
vPalettes = GetAttributeLocation("vPalettes");
|
||||
vFlags = GetAttributeLocation("vFlags");
|
||||
vColour = GetAttributeLocation("vColour");
|
||||
vBounds = GetAttributeLocation("vBounds");
|
||||
|
||||
vVertMat = GetAttributeLocation("vVertMat");
|
||||
vVertVec = GetAttributeLocation("vVertVec");
|
||||
}
|
||||
|
||||
void DrawRectShader::SetScreenSize(sint32 width, sint32 height)
|
||||
{
|
||||
glUniform2i(uScreenSize, width, height);
|
||||
}
|
||||
|
||||
void DrawRectShader::DrawInstances(const RectCommandBatch& instances)
|
||||
{
|
||||
glBindVertexArray(_vao);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboInstances);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(DrawRectCommand) * instances.size(), instances.data(), GL_STREAM_DRAW);
|
||||
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, (GLsizei)instances.size());
|
||||
}
|
||||
|
||||
#endif /* DISABLE_OPENGL */
|
||||
@@ -22,35 +22,36 @@
|
||||
#include <SDL_pixels.h>
|
||||
#include <vector>
|
||||
|
||||
class DrawImageShader final : public OpenGLShaderProgram
|
||||
class DrawRectShader final : public OpenGLShaderProgram
|
||||
{
|
||||
private:
|
||||
GLuint uScreenSize;
|
||||
GLuint uTexture;
|
||||
GLuint uPaletteTex;
|
||||
|
||||
GLuint vVertMat;
|
||||
GLuint vVertVec;
|
||||
|
||||
GLuint vIndex;
|
||||
GLuint vClip;
|
||||
GLuint vTexColourAtlas;
|
||||
GLuint vTexColourBounds;
|
||||
GLuint vTexMaskAtlas;
|
||||
GLuint vTexMaskBounds;
|
||||
GLuint vTexPaletteAtlas;
|
||||
GLuint vTexPaletteBounds;
|
||||
GLuint vPalettes;
|
||||
GLuint vFlags;
|
||||
GLuint vColour;
|
||||
GLuint vBounds;
|
||||
GLuint vMask;
|
||||
|
||||
GLuint _vbo;
|
||||
GLuint _vboInstances;
|
||||
GLuint _vao;
|
||||
|
||||
public:
|
||||
DrawImageShader();
|
||||
~DrawImageShader() override;
|
||||
DrawRectShader();
|
||||
~DrawRectShader() override;
|
||||
|
||||
void SetScreenSize(sint32 width, sint32 height);
|
||||
void DrawInstances(const ImageCommandBatch& instances);
|
||||
void DrawInstances(const RectCommandBatch& instances);
|
||||
|
||||
private:
|
||||
void GetLocations();
|
||||
@@ -1,104 +0,0 @@
|
||||
#pragma region Copyright (c) 2014-2017 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 "FillRectShader.h"
|
||||
#include "OpenGLFramebuffer.h"
|
||||
|
||||
FillRectShader::FillRectShader() : OpenGLShaderProgram("fillrect")
|
||||
{
|
||||
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();
|
||||
SetFlags(0);
|
||||
glUniform1i(uSourceFramebuffer, 0);
|
||||
}
|
||||
|
||||
FillRectShader::~FillRectShader()
|
||||
{
|
||||
glDeleteBuffers(1, &_vbo);
|
||||
glDeleteVertexArrays(1, &_vao);
|
||||
}
|
||||
|
||||
void FillRectShader::GetLocations()
|
||||
{
|
||||
uScreenSize = GetUniformLocation("uScreenSize");
|
||||
uClip = GetUniformLocation("uClip");
|
||||
uBounds = GetUniformLocation("uBounds");
|
||||
uFlags = GetUniformLocation("uFlags");
|
||||
uSourceFramebuffer = GetUniformLocation("uSourceFramebuffer");
|
||||
uPaletteRemap = GetUniformLocation("uPaletteRemap");
|
||||
|
||||
vIndex = GetAttributeLocation("vIndex");
|
||||
}
|
||||
|
||||
void FillRectShader::SetScreenSize(sint32 width, sint32 height)
|
||||
{
|
||||
glUniform2i(uScreenSize, width, height);
|
||||
}
|
||||
|
||||
void FillRectShader::SetClip(sint32 left, sint32 top, sint32 right, sint32 bottom)
|
||||
{
|
||||
glUniform4i(uClip, left, top, right, bottom);
|
||||
}
|
||||
|
||||
void FillRectShader::SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom)
|
||||
{
|
||||
glUniform4i(uBounds, left, top, right, bottom);
|
||||
}
|
||||
|
||||
void FillRectShader::SetFlags(uint32 flags)
|
||||
{
|
||||
glUniform1i(uFlags, flags);
|
||||
}
|
||||
|
||||
void FillRectShader::SetSourceFramebuffer(GLuint texture)
|
||||
{
|
||||
_sourceFramebuffer = texture;
|
||||
OpenGLAPI::SetTexture(0, GL_TEXTURE_2D, texture);
|
||||
}
|
||||
|
||||
void FillRectShader::SetPaletteRemap(const GLuint * paletteRemap)
|
||||
{
|
||||
glUniform1uiv(uPaletteRemap, 256, paletteRemap);
|
||||
}
|
||||
|
||||
void FillRectShader::Draw(sint32 left, sint32 top, sint32 right, sint32 bottom)
|
||||
{
|
||||
SetBounds(left, top, right, bottom);
|
||||
|
||||
glBindVertexArray(_vao);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
|
||||
GLuint FillRectShader::GetSourceFramebuffer() const
|
||||
{
|
||||
return _sourceFramebuffer;
|
||||
}
|
||||
|
||||
#endif /* DISABLE_OPENGL */
|
||||
@@ -1,58 +0,0 @@
|
||||
#pragma region Copyright (c) 2014-2017 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 OpenGLFramebuffer;
|
||||
|
||||
class FillRectShader final : public OpenGLShaderProgram
|
||||
{
|
||||
private:
|
||||
GLuint uScreenSize;
|
||||
GLuint uClip;
|
||||
GLuint uBounds;
|
||||
GLuint uFlags;
|
||||
GLuint uSourceFramebuffer;
|
||||
GLuint uPaletteRemap;
|
||||
|
||||
GLuint vIndex;
|
||||
|
||||
GLuint _vbo;
|
||||
GLuint _vao;
|
||||
|
||||
GLuint _sourceFramebuffer = 0;
|
||||
|
||||
public:
|
||||
FillRectShader();
|
||||
~FillRectShader() 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 SetFlags(uint32 flags);
|
||||
void SetSourceFramebuffer(GLuint texture);
|
||||
void SetPaletteRemap(const GLuint * filterMap);
|
||||
|
||||
void Draw(sint32 left, sint32 top, sint32 right, sint32 bottom);
|
||||
|
||||
GLuint GetSourceFramebuffer() const;
|
||||
|
||||
private:
|
||||
void GetLocations();
|
||||
};
|
||||
@@ -32,6 +32,13 @@ struct vec2f
|
||||
union { float y; float t; float g; };
|
||||
};
|
||||
|
||||
struct vec3i
|
||||
{
|
||||
union { sint32 x; sint32 s; sint32 r; };
|
||||
union { sint32 y; sint32 t; sint32 g; };
|
||||
union { sint32 z; sint32 p; sint32 b; };
|
||||
};
|
||||
|
||||
struct vec3f
|
||||
{
|
||||
union { float x; float s; float r; };
|
||||
|
||||
@@ -41,9 +41,8 @@
|
||||
#include "OpenGLAPI.h"
|
||||
#include "OpenGLFramebuffer.h"
|
||||
#include "CopyFramebufferShader.h"
|
||||
#include "DrawImageShader.h"
|
||||
#include "DrawLineShader.h"
|
||||
#include "FillRectShader.h"
|
||||
#include "DrawRectShader.h"
|
||||
#include "SwapFramebuffer.h"
|
||||
#include "TextureCache.h"
|
||||
#include "DrawCommands.h"
|
||||
@@ -68,9 +67,8 @@ private:
|
||||
OpenGLDrawingEngine * _engine = nullptr;
|
||||
rct_drawpixelinfo * _dpi = nullptr;
|
||||
|
||||
DrawImageShader * _drawImageShader = nullptr;
|
||||
DrawLineShader * _drawLineShader = nullptr;
|
||||
FillRectShader * _fillRectShader = nullptr;
|
||||
DrawRectShader * _drawRectShader = nullptr;
|
||||
|
||||
TextureCache * _textureCache = nullptr;
|
||||
|
||||
@@ -82,9 +80,8 @@ private:
|
||||
sint32 _clipBottom = 0;
|
||||
|
||||
struct {
|
||||
RectCommandBatch rectangles;
|
||||
LineCommandBatch lines;
|
||||
ImageCommandBatch images;
|
||||
RectCommandBatch rects;
|
||||
} _commandBuffers;
|
||||
|
||||
public:
|
||||
@@ -109,9 +106,8 @@ public:
|
||||
|
||||
void FlushCommandBuffers();
|
||||
|
||||
void FlushRectangles();
|
||||
void FlushLines();
|
||||
void FlushImages();
|
||||
void FlushRectangles();
|
||||
|
||||
void SetDPI(rct_drawpixelinfo * dpi);
|
||||
};
|
||||
@@ -383,9 +379,6 @@ private:
|
||||
_swapFramebuffer = new SwapFramebuffer(_width, _height);
|
||||
|
||||
_copyFramebufferShader->Use();
|
||||
_copyFramebufferShader->SetScreenSize(_width, _height);
|
||||
_copyFramebufferShader->SetBounds(0, 0, _width, _height);
|
||||
_copyFramebufferShader->SetTextureCoordinates(0, 1, 1, 0);
|
||||
}
|
||||
|
||||
void Display()
|
||||
@@ -406,9 +399,8 @@ OpenGLDrawingContext::OpenGLDrawingContext(OpenGLDrawingEngine * engine)
|
||||
|
||||
OpenGLDrawingContext::~OpenGLDrawingContext()
|
||||
{
|
||||
delete _drawImageShader;
|
||||
delete _drawLineShader;
|
||||
delete _fillRectShader;
|
||||
delete _drawRectShader;
|
||||
|
||||
delete _textureCache;
|
||||
}
|
||||
@@ -421,82 +413,67 @@ IDrawingEngine * OpenGLDrawingContext::GetEngine()
|
||||
void OpenGLDrawingContext::Initialise()
|
||||
{
|
||||
_textureCache = new TextureCache();
|
||||
_drawImageShader = new DrawImageShader();
|
||||
_drawRectShader = new DrawRectShader();
|
||||
_drawLineShader = new DrawLineShader();
|
||||
_fillRectShader = new FillRectShader();
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::Resize(sint32 width, sint32 height)
|
||||
{
|
||||
FlushCommandBuffers();
|
||||
|
||||
_drawImageShader->Use();
|
||||
_drawImageShader->SetScreenSize(width, height);
|
||||
_drawRectShader->Use();
|
||||
_drawRectShader->SetScreenSize(width, height);
|
||||
_drawLineShader->Use();
|
||||
_drawLineShader->SetScreenSize(width, height);
|
||||
_fillRectShader->Use();
|
||||
_fillRectShader->SetScreenSize(width, height);
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::ResetPalette()
|
||||
{
|
||||
//FlushCommandBuffers();
|
||||
|
||||
_textureCache->SetPalette(_engine->Palette);
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::Clear(uint8 paletteIndex)
|
||||
{
|
||||
FillRect(paletteIndex, _clipLeft - _offsetX, _clipTop - _offsetY, _clipRight, _clipBottom);
|
||||
FillRect(paletteIndex, _clipLeft - _offsetX, _clipTop - _offsetY, _clipRight - _offsetX, _clipBottom - _offsetY);
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::FillRect(uint32 colour, sint32 left, sint32 top, sint32 right, sint32 bottom)
|
||||
{
|
||||
// Must be rendered in order, depends on already rendered contents
|
||||
FlushCommandBuffers();
|
||||
|
||||
left += _offsetX;
|
||||
top += _offsetY;
|
||||
right += _offsetX;
|
||||
bottom += _offsetY;
|
||||
|
||||
DrawRectCommand& command = _commandBuffers.rectangles.allocate();
|
||||
DrawRectCommand& command = _commandBuffers.rects.allocate();
|
||||
|
||||
command.sourceFramebuffer = _fillRectShader->GetSourceFramebuffer();
|
||||
command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom };
|
||||
command.texColourAtlas = 0;
|
||||
command.texColourBounds = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
command.texMaskAtlas = 0;
|
||||
command.texMaskBounds = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
command.palettes = { 0, 0, 0 };
|
||||
command.colour = colour & 0xFF;
|
||||
command.bounds = { left + _offsetX, top + _offsetY, right + 1, bottom + 1 };
|
||||
command.flags = DrawRectCommand::FLAG_NO_TEXTURE;
|
||||
|
||||
if (colour & 0x1000000)
|
||||
{
|
||||
// cross-pattern
|
||||
command.flags = 1;
|
||||
command.flags = DrawRectCommand::FLAG_CROSS_HATCH;
|
||||
}
|
||||
else if (colour & 0x2000000)
|
||||
{
|
||||
assert(false);
|
||||
// Should be FilterRect
|
||||
}
|
||||
else
|
||||
{
|
||||
command.flags = 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 256; i++)
|
||||
{
|
||||
command.paletteRemap[i] = colour & 0xFF;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::FilterRect(FILTER_PALETTE_ID palette, sint32 left, sint32 top, sint32 right, sint32 bottom)
|
||||
{
|
||||
// ignore transparency TODO
|
||||
return;
|
||||
|
||||
/*
|
||||
// Must be rendered in order, depends on already rendered contents
|
||||
FlushCommandBuffers();
|
||||
|
||||
@@ -524,15 +501,13 @@ void OpenGLDrawingContext::FilterRect(FILTER_PALETTE_ID palette, sint32 left, si
|
||||
|
||||
// END FILTER
|
||||
|
||||
command.clip[0] = _clipLeft;
|
||||
command.clip[1] = _clipTop;
|
||||
command.clip[2] = _clipRight;
|
||||
command.clip[3] = _clipBottom;
|
||||
command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom };
|
||||
|
||||
command.bounds[0] = left;
|
||||
command.bounds[1] = top;
|
||||
command.bounds[2] = right + 1;
|
||||
command.bounds[3] = bottom + 1;
|
||||
*/
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32 x2, sint32 y2)
|
||||
@@ -546,10 +521,7 @@ void OpenGLDrawingContext::DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32
|
||||
|
||||
command.colour = colour & 0xFF;
|
||||
|
||||
command.clip[0] = _clipLeft;
|
||||
command.clip[1] = _clipTop;
|
||||
command.clip[2] = _clipRight;
|
||||
command.clip[3] = _clipBottom;
|
||||
command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom };
|
||||
|
||||
command.pos[0] = x1;
|
||||
command.pos[1] = y1;
|
||||
@@ -589,13 +561,8 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t
|
||||
|
||||
uint8 zoomLevel = (1 << _dpi->zoom_level);
|
||||
|
||||
sint32 drawOffsetX = g1Element->x_offset;
|
||||
sint32 drawOffsetY = g1Element->y_offset;
|
||||
sint32 drawWidth = g1Element->width;
|
||||
sint32 drawHeight = g1Element->height;
|
||||
|
||||
sint32 left = x + drawOffsetX;
|
||||
sint32 top = y + drawOffsetY;
|
||||
sint32 left = x + g1Element->x_offset;
|
||||
sint32 top = y + g1Element->y_offset;
|
||||
|
||||
sint32 zoom_mask = 0xFFFFFFFF << _dpi->zoom_level;
|
||||
if (_dpi->zoom_level && g1Element->flags & G1_FLAG_RLE_COMPRESSION){
|
||||
@@ -609,8 +576,8 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t
|
||||
|
||||
left &= zoom_mask;
|
||||
|
||||
sint32 right = left + drawWidth;
|
||||
sint32 bottom = top + drawHeight;
|
||||
sint32 right = left + g1Element->width;
|
||||
sint32 bottom = top + g1Element->height;
|
||||
|
||||
if (_dpi->zoom_level && g1Element->flags & G1_FLAG_RLE_COMPRESSION) {
|
||||
bottom += top & ~zoom_mask;
|
||||
@@ -642,46 +609,54 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t
|
||||
|
||||
auto texture = _textureCache->GetOrLoadImageTexture(image);
|
||||
|
||||
int paletteCount;
|
||||
vec3i palettes{};
|
||||
bool special = false;
|
||||
if (!(image & IMAGE_TYPE_REMAP_2_PLUS) && (image & IMAGE_TYPE_REMAP)) {
|
||||
if (((image >> 19) & 0x7F) == 32) {
|
||||
if (image & IMAGE_TYPE_REMAP_2_PLUS)
|
||||
{
|
||||
palettes.x = TextureCache::PaletteToY((image >> 19) & 0x1F);
|
||||
palettes.y = TextureCache::PaletteToY((image >> 24) & 0x1F);
|
||||
if (image & IMAGE_TYPE_REMAP)
|
||||
{
|
||||
paletteCount = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
paletteCount = 3;
|
||||
palettes.z = TextureCache::PaletteToY(tertiaryColour & 0xFF);
|
||||
}
|
||||
}
|
||||
else if (image & IMAGE_TYPE_REMAP)
|
||||
{
|
||||
paletteCount = 1;
|
||||
palettes.x = TextureCache::PaletteToY((image >> 19) & 0xFF);
|
||||
if (palettes.x == 32)
|
||||
{
|
||||
special = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!((image & IMAGE_TYPE_REMAP_2_PLUS) && !(image & IMAGE_TYPE_REMAP))) {
|
||||
tertiaryColour = 0;
|
||||
else
|
||||
{
|
||||
paletteCount = 0;
|
||||
}
|
||||
|
||||
auto texture2 = _textureCache->GetOrLoadPaletteTexture(image, tertiaryColour, special);
|
||||
if (special || (image & IMAGE_TYPE_TRANSPARENT))
|
||||
{
|
||||
// ignore transparecy TODO
|
||||
return;
|
||||
}
|
||||
|
||||
DrawImageCommand& command = _commandBuffers.images.allocate();
|
||||
DrawRectCommand& command = _commandBuffers.rects.allocate();
|
||||
|
||||
command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom };
|
||||
command.texColourAtlas = texture->index;
|
||||
command.texColourBounds = texture->normalizedBounds;
|
||||
command.texMaskAtlas = 0;
|
||||
command.texMaskBounds = { 0.0f, 0.0f, 0.0f };
|
||||
command.texPaletteAtlas = texture2->index;
|
||||
command.texPaletteBounds = texture2->computedBounds;
|
||||
command.texMaskBounds = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
command.palettes = palettes;
|
||||
command.colour = 0;
|
||||
command.bounds = { left, top, right, bottom };
|
||||
command.mask = 0;
|
||||
command.flags = 0;
|
||||
|
||||
if (special)
|
||||
{
|
||||
command.flags |= DrawImageCommand::FLAG_TRANSPARENT_SPECIAL;
|
||||
}
|
||||
|
||||
if (image & IMAGE_TYPE_TRANSPARENT)
|
||||
{
|
||||
command.flags |= DrawImageCommand::FLAG_TRANSPARENT;
|
||||
}
|
||||
else if (image & (IMAGE_TYPE_REMAP_2_PLUS | IMAGE_TYPE_REMAP))
|
||||
{
|
||||
command.flags |= DrawImageCommand::FLAG_REMAP;
|
||||
}
|
||||
command.flags = paletteCount;
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage)
|
||||
@@ -728,23 +703,23 @@ void OpenGLDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskIm
|
||||
right += _clipLeft;
|
||||
bottom += _clipTop;
|
||||
|
||||
DrawImageCommand& command = _commandBuffers.images.allocate();
|
||||
DrawRectCommand& command = _commandBuffers.rects.allocate();
|
||||
|
||||
command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom };
|
||||
command.texColourAtlas = textureColour->index;
|
||||
command.texColourBounds = textureColour->normalizedBounds;
|
||||
command.texMaskAtlas = textureMask->index;
|
||||
command.texMaskBounds = textureMask->normalizedBounds;
|
||||
command.texPaletteAtlas = 0;
|
||||
command.texPaletteBounds = {0.0f, 0.0f, 0.0f};
|
||||
command.flags = 0;
|
||||
command.palettes = { 0, 0, 0 };
|
||||
command.flags = DrawRectCommand::FLAG_MASK;
|
||||
command.colour = 0;
|
||||
command.bounds = { left, top, right, bottom };
|
||||
command.mask = 1;
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour)
|
||||
{
|
||||
assert((colour & 0xFF) > 0u);
|
||||
|
||||
sint32 g1Id = image & 0x7FFFF;
|
||||
rct_g1_element * g1Element = gfx_get_g1_element(g1Id);
|
||||
|
||||
@@ -774,19 +749,17 @@ void OpenGLDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uin
|
||||
right += _offsetX;
|
||||
bottom += _offsetY;
|
||||
|
||||
DrawImageCommand& command = _commandBuffers.images.allocate();
|
||||
DrawRectCommand& command = _commandBuffers.rects.allocate();
|
||||
|
||||
command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom };
|
||||
command.texColourAtlas = texture->index;
|
||||
command.texColourBounds = texture->normalizedBounds;
|
||||
command.texMaskAtlas = 0;
|
||||
command.texMaskBounds = { 0.0f, 0.0f, 0.0f };
|
||||
command.texPaletteAtlas = texture->index;
|
||||
command.texPaletteBounds = texture->computedBounds;
|
||||
command.flags = DrawImageCommand::FLAG_COLOUR;
|
||||
command.texColourAtlas = 0;
|
||||
command.texColourBounds = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
command.texMaskAtlas = texture->index;
|
||||
command.texMaskBounds = texture->normalizedBounds;
|
||||
command.palettes = { 0, 0, 0 };
|
||||
command.flags = DrawRectCommand::FLAG_NO_TEXTURE | DrawRectCommand::FLAG_MASK;
|
||||
command.colour = colour & 0xFF;
|
||||
command.bounds = { left, top, right, bottom };
|
||||
command.mask = 0;
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * palette)
|
||||
@@ -820,43 +793,23 @@ void OpenGLDrawingContext::DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * p
|
||||
right += _offsetX;
|
||||
bottom += _offsetY;
|
||||
|
||||
DrawImageCommand& command = _commandBuffers.images.allocate();
|
||||
DrawRectCommand& command = _commandBuffers.rects.allocate();
|
||||
|
||||
command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom };
|
||||
command.texColourAtlas = texture.index;
|
||||
command.texColourBounds = texture.normalizedBounds;
|
||||
command.texMaskAtlas = 0;
|
||||
command.texMaskBounds = { 0.0f, 0.0f, 0.0f };
|
||||
command.texPaletteAtlas = 0;
|
||||
command.texPaletteBounds = { 0.0f, 0.0f, 0.0f};
|
||||
command.texMaskBounds = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
command.palettes = { 0, 0, 0 };
|
||||
command.flags = 0;
|
||||
command.colour = 0;
|
||||
command.bounds = { left, top, right, bottom };
|
||||
command.mask = 0;
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::FlushCommandBuffers()
|
||||
{
|
||||
FlushRectangles();
|
||||
FlushLines();
|
||||
FlushImages();
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::FlushRectangles()
|
||||
{
|
||||
for(size_t n = 0; n < _commandBuffers.rectangles.size(); n++)
|
||||
{
|
||||
const auto& command = _commandBuffers.rectangles[n];
|
||||
|
||||
_fillRectShader->Use();
|
||||
_fillRectShader->SetFlags(command.flags);
|
||||
_fillRectShader->SetSourceFramebuffer(command.sourceFramebuffer);
|
||||
_fillRectShader->SetClip(command.clip[0], command.clip[1], command.clip[2], command.clip[3]);
|
||||
_fillRectShader->SetPaletteRemap(command.paletteRemap);
|
||||
_fillRectShader->Draw(command.bounds[0], command.bounds[1], command.bounds[2], command.bounds[3]);
|
||||
}
|
||||
|
||||
_commandBuffers.rectangles.reset();
|
||||
FlushRectangles();
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::FlushLines()
|
||||
@@ -867,23 +820,24 @@ void OpenGLDrawingContext::FlushLines()
|
||||
|
||||
_drawLineShader->Use();
|
||||
_drawLineShader->SetColour(command.colour);
|
||||
_drawLineShader->SetClip(command.clip[0], command.clip[1], command.clip[2], command.clip[3]);
|
||||
_drawLineShader->SetClip(command.clip.x, command.clip.y, command.clip.z, command.clip.w);
|
||||
_drawLineShader->Draw(command.pos[0], command.pos[1], command.pos[2], command.pos[3]);
|
||||
}
|
||||
|
||||
_commandBuffers.lines.reset();
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::FlushImages()
|
||||
void OpenGLDrawingContext::FlushRectangles()
|
||||
{
|
||||
if (_commandBuffers.images.size() == 0) return;
|
||||
if (_commandBuffers.rects.size() == 0) return;
|
||||
|
||||
OpenGLAPI::SetTexture(0, GL_TEXTURE_2D_ARRAY, _textureCache->GetAtlasesTexture());
|
||||
OpenGLAPI::SetTexture(1, GL_TEXTURE_RECTANGLE, _textureCache->GetPaletteTexture());
|
||||
|
||||
_drawImageShader->Use();
|
||||
_drawImageShader->DrawInstances(_commandBuffers.images);
|
||||
_drawRectShader->Use();
|
||||
_drawRectShader->DrawInstances(_commandBuffers.rects);
|
||||
|
||||
_commandBuffers.images.reset();
|
||||
_commandBuffers.rects.reset();
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::SetDPI(rct_drawpixelinfo * dpi)
|
||||
|
||||
@@ -28,11 +28,6 @@ TextureCache::~TextureCache()
|
||||
FreeTextures();
|
||||
}
|
||||
|
||||
void TextureCache::SetPalette(const SDL_Color * palette)
|
||||
{
|
||||
Memory::CopyArray(_palette, palette, 256);
|
||||
}
|
||||
|
||||
void TextureCache::InvalidateImage(uint32 image)
|
||||
{
|
||||
auto kvp = _imageTextureMap.find(image);
|
||||
@@ -59,42 +54,6 @@ const CachedTextureInfo* TextureCache::GetOrLoadImageTexture(uint32 image)
|
||||
return &(cacheItr.first->second);
|
||||
}
|
||||
|
||||
const CachedTextureInfo* TextureCache::GetOrLoadPaletteTexture(uint32 image, uint32 tertiaryColour, bool special)
|
||||
{
|
||||
if ((image & (IMAGE_TYPE_REMAP | IMAGE_TYPE_REMAP_2_PLUS | IMAGE_TYPE_TRANSPARENT)) == 0)
|
||||
{
|
||||
static CachedTextureInfo invalidEntry{ 0 };
|
||||
return &invalidEntry;
|
||||
}
|
||||
|
||||
uint32 uniquePaletteId = image & (IMAGE_TYPE_REMAP | IMAGE_TYPE_REMAP_2_PLUS | IMAGE_TYPE_TRANSPARENT);
|
||||
if (!(image & IMAGE_TYPE_REMAP_2_PLUS)) {
|
||||
uniquePaletteId = (image >> 19) & 0xFF;
|
||||
if (!(image & IMAGE_TYPE_TRANSPARENT)) {
|
||||
uniquePaletteId &= 0x7F;
|
||||
}
|
||||
}
|
||||
else {
|
||||
uniquePaletteId |= ((image >> 19) & 0x1F);
|
||||
uniquePaletteId |= ((image >> 24) & 0x1F) << 8;
|
||||
|
||||
if (!(image & IMAGE_TYPE_REMAP)) {
|
||||
uniquePaletteId |= tertiaryColour << 16;
|
||||
}
|
||||
}
|
||||
|
||||
auto kvp = _paletteTextureMap.find(uniquePaletteId);
|
||||
if (kvp != _paletteTextureMap.end())
|
||||
{
|
||||
return &kvp->second;
|
||||
}
|
||||
|
||||
auto cacheInfo = LoadPaletteTexture(image, tertiaryColour, special);
|
||||
auto cacheItr = _paletteTextureMap.insert(std::make_pair(uniquePaletteId, cacheInfo));
|
||||
|
||||
return &(cacheItr.first->second);
|
||||
}
|
||||
|
||||
CachedTextureInfo TextureCache::GetOrLoadGlyphTexture(uint32 image, uint8 * palette)
|
||||
{
|
||||
GlyphId glyphId;
|
||||
@@ -113,9 +72,9 @@ CachedTextureInfo TextureCache::GetOrLoadGlyphTexture(uint32 image, uint8 * pale
|
||||
return cacheInfo;
|
||||
}
|
||||
|
||||
void TextureCache::CreateAtlasesTexture()
|
||||
void TextureCache::CreateTextures()
|
||||
{
|
||||
if (!_atlasesTextureInitialised)
|
||||
if (!_initialized)
|
||||
{
|
||||
// Determine width and height to use for texture atlases
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &_atlasesTextureDimensions);
|
||||
@@ -127,26 +86,50 @@ void TextureCache::CreateAtlasesTexture()
|
||||
glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &_atlasesTextureIndicesLimit);
|
||||
if (_atlasesTextureDimensions < _atlasesTextureIndicesLimit) _atlasesTextureIndicesLimit = _atlasesTextureDimensions;
|
||||
|
||||
AllocateAtlasesTexture();
|
||||
glGenTextures(1, &_atlasesTexture);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasesTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
_atlasesTextureInitialised = true;
|
||||
glGenTextures(1, &_paletteTexture);
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE, _paletteTexture);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
GeneratePaletteTexture();
|
||||
|
||||
_initialized = true;
|
||||
_atlasesTextureIndices = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void TextureCache::AllocateAtlasesTexture()
|
||||
void TextureCache::GeneratePaletteTexture()
|
||||
{
|
||||
// Create an array texture to hold all of the atlases
|
||||
glGenTextures(1, &_atlasesTexture);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasesTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
rct_drawpixelinfo dpi = CreateDPI(256, PALETTE_TO_G1_OFFSET_COUNT + 5);
|
||||
|
||||
// Init no-op palette
|
||||
for (int i=0; i < 256; ++i)
|
||||
{
|
||||
dpi.bits[i] = i;
|
||||
}
|
||||
|
||||
for (int i=0; i < PALETTE_TO_G1_OFFSET_COUNT; ++i)
|
||||
{
|
||||
GLint y = PaletteToY(i);
|
||||
uint16 image = palette_to_g1_offset[i];
|
||||
const rct_g1_element &element = g1Elements[image];
|
||||
gfx_draw_sprite_software(&dpi, image, -element.x_offset, y - element.y_offset, 0);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE, _paletteTexture);
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_R8UI, 256, PALETTE_TO_G1_OFFSET_COUNT + 5, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, dpi.bits);
|
||||
DeleteDPI(dpi);
|
||||
}
|
||||
|
||||
void TextureCache::EnlargeAtlasesTexture(GLuint newEntries)
|
||||
{
|
||||
CreateAtlasesTexture();
|
||||
CreateTextures();
|
||||
|
||||
GLuint newIndices = _atlasesTextureIndices + newEntries;
|
||||
|
||||
@@ -157,9 +140,7 @@ void TextureCache::EnlargeAtlasesTexture(GLuint newEntries)
|
||||
glGetTexImage(GL_TEXTURE_2D_ARRAY, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, oldPixels.data());
|
||||
}
|
||||
|
||||
// Delete old texture, allocate a new one, then define the new format on the newly created texture
|
||||
glDeleteTextures(1, &_atlasesTexture);
|
||||
AllocateAtlasesTexture();
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasesTexture);
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_R8UI, _atlasesTextureDimensions, _atlasesTextureDimensions, newIndices, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, nullptr);
|
||||
|
||||
// Restore old data
|
||||
@@ -170,12 +151,12 @@ void TextureCache::EnlargeAtlasesTexture(GLuint newEntries)
|
||||
|
||||
CachedTextureInfo TextureCache::LoadImageTexture(uint32 image)
|
||||
{
|
||||
rct_drawpixelinfo * dpi = GetImageAsDPI(image, 0);
|
||||
rct_drawpixelinfo dpi = GetImageAsDPI(image, 0);
|
||||
|
||||
auto cacheInfo = AllocateImage(dpi->width, dpi->height);
|
||||
auto cacheInfo = AllocateImage(dpi.width, dpi.height);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasesTexture);
|
||||
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, cacheInfo.bounds.x, cacheInfo.bounds.y, cacheInfo.index, dpi->width, dpi->height, 1, GL_RED_INTEGER, GL_UNSIGNED_BYTE, dpi->bits);
|
||||
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, cacheInfo.bounds.x, cacheInfo.bounds.y, cacheInfo.index, dpi.width, dpi.height, 1, GL_RED_INTEGER, GL_UNSIGNED_BYTE, dpi.bits);
|
||||
|
||||
DeleteDPI(dpi);
|
||||
|
||||
@@ -190,61 +171,23 @@ CachedTextureInfo TextureCache::LoadImageTexture(uint32 image)
|
||||
return cacheInfo;
|
||||
}
|
||||
|
||||
CachedTextureInfo TextureCache::LoadPaletteTexture(uint32 image, uint32 tertiaryColour, bool special)
|
||||
CachedTextureInfo TextureCache::LoadGlyphTexture(uint32 image, uint8 * palette)
|
||||
{
|
||||
rct_drawpixelinfo dpi;
|
||||
dpi.bits = gfx_draw_sprite_get_palette(image, tertiaryColour);
|
||||
dpi.width = 256;
|
||||
dpi.height = special ? 5 : 1;
|
||||
rct_drawpixelinfo dpi = GetGlyphAsDPI(image, palette);
|
||||
|
||||
auto cacheInfo = AllocateImage(dpi.width, dpi.height);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasesTexture);
|
||||
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, cacheInfo.bounds.x, cacheInfo.bounds.y, cacheInfo.index, dpi.width, dpi.height, 1, GL_RED_INTEGER, GL_UNSIGNED_BYTE, dpi.bits);
|
||||
|
||||
cacheInfo.computedBounds =
|
||||
{
|
||||
cacheInfo.normalizedBounds.x,
|
||||
cacheInfo.normalizedBounds.y,
|
||||
(cacheInfo.normalizedBounds.z - cacheInfo.normalizedBounds.x) / (float)(cacheInfo.bounds.z - cacheInfo.bounds.x),
|
||||
(cacheInfo.normalizedBounds.w - cacheInfo.normalizedBounds.y) / (float)(cacheInfo.bounds.w - cacheInfo.bounds.y)
|
||||
};
|
||||
|
||||
return cacheInfo;
|
||||
}
|
||||
|
||||
CachedTextureInfo TextureCache::LoadGlyphTexture(uint32 image, uint8 * palette)
|
||||
{
|
||||
rct_drawpixelinfo * dpi = GetGlyphAsDPI(image, palette);
|
||||
|
||||
auto cacheInfo = AllocateImage(dpi->width, dpi->height);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasesTexture);
|
||||
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, cacheInfo.bounds.x, cacheInfo.bounds.y, cacheInfo.index, dpi->width, dpi->height, 1, GL_RED_INTEGER, GL_UNSIGNED_BYTE, dpi->bits);
|
||||
|
||||
DeleteDPI(dpi);
|
||||
|
||||
return cacheInfo;
|
||||
}
|
||||
|
||||
void * TextureCache::GetImageAsARGB(uint32 image, uint32 tertiaryColour, uint32 * outWidth, uint32 * outHeight)
|
||||
{
|
||||
rct_g1_element * g1Element = gfx_get_g1_element(image & 0x7FFFF);
|
||||
sint32 width = g1Element->width;
|
||||
sint32 height = g1Element->height;
|
||||
|
||||
rct_drawpixelinfo * dpi = CreateDPI(width, height);
|
||||
gfx_draw_sprite_software(dpi, image, -g1Element->x_offset, -g1Element->y_offset, tertiaryColour);
|
||||
void * pixels32 = ConvertDPIto32bpp(dpi);
|
||||
DeleteDPI(dpi);
|
||||
|
||||
*outWidth = width;
|
||||
*outHeight = height;
|
||||
return pixels32;
|
||||
}
|
||||
|
||||
CachedTextureInfo TextureCache::AllocateImage(sint32 imageWidth, sint32 imageHeight)
|
||||
{
|
||||
CreateAtlasesTexture();
|
||||
CreateTextures();
|
||||
|
||||
// Find an atlas that fits this image
|
||||
for (Atlas& atlas : _atlases)
|
||||
@@ -278,73 +221,28 @@ CachedTextureInfo TextureCache::AllocateImage(sint32 imageWidth, sint32 imageHei
|
||||
return _atlases.back().Allocate(imageWidth, imageHeight);
|
||||
}
|
||||
|
||||
rct_drawpixelinfo * TextureCache::GetImageAsDPI(uint32 image, uint32 tertiaryColour)
|
||||
rct_drawpixelinfo TextureCache::GetImageAsDPI(uint32 image, uint32 tertiaryColour)
|
||||
{
|
||||
rct_g1_element * g1Element = gfx_get_g1_element(image & 0x7FFFF);
|
||||
sint32 width = g1Element->width;
|
||||
sint32 height = g1Element->height;
|
||||
|
||||
rct_drawpixelinfo * dpi = CreateDPI(width, height);
|
||||
gfx_draw_sprite_software(dpi, image, -g1Element->x_offset, -g1Element->y_offset, tertiaryColour);
|
||||
rct_drawpixelinfo dpi = CreateDPI(width, height);
|
||||
gfx_draw_sprite_software(&dpi, image, -g1Element->x_offset, -g1Element->y_offset, tertiaryColour);
|
||||
return dpi;
|
||||
}
|
||||
|
||||
void * TextureCache::GetGlyphAsARGB(uint32 image, uint8 * palette, uint32 * outWidth, uint32 * outHeight)
|
||||
rct_drawpixelinfo TextureCache::GetGlyphAsDPI(uint32 image, uint8 * palette)
|
||||
{
|
||||
rct_g1_element * g1Element = gfx_get_g1_element(image & 0x7FFFF);
|
||||
sint32 width = g1Element->width;
|
||||
sint32 height = g1Element->height;
|
||||
|
||||
rct_drawpixelinfo * dpi = CreateDPI(width, height);
|
||||
gfx_draw_sprite_palette_set_software(dpi, image, -g1Element->x_offset, -g1Element->y_offset, palette, nullptr);
|
||||
void * pixels32 = ConvertDPIto32bpp(dpi);
|
||||
DeleteDPI(dpi);
|
||||
|
||||
*outWidth = width;
|
||||
*outHeight = height;
|
||||
return pixels32;
|
||||
}
|
||||
|
||||
rct_drawpixelinfo * TextureCache::GetGlyphAsDPI(uint32 image, uint8 * palette)
|
||||
{
|
||||
rct_g1_element * g1Element = gfx_get_g1_element(image & 0x7FFFF);
|
||||
sint32 width = g1Element->width;
|
||||
sint32 height = g1Element->height;
|
||||
|
||||
rct_drawpixelinfo * dpi = CreateDPI(width, height);
|
||||
gfx_draw_sprite_palette_set_software(dpi, image, -g1Element->x_offset, -g1Element->y_offset, palette, nullptr);
|
||||
rct_drawpixelinfo dpi = CreateDPI(width, height);
|
||||
gfx_draw_sprite_palette_set_software(&dpi, image, -g1Element->x_offset, -g1Element->y_offset, palette, nullptr);
|
||||
return dpi;
|
||||
}
|
||||
|
||||
void * TextureCache::ConvertDPIto32bpp(const rct_drawpixelinfo * dpi)
|
||||
{
|
||||
size_t numPixels = dpi->width * dpi->height;
|
||||
uint8 * pixels32 = Memory::Allocate<uint8>(numPixels * 4);
|
||||
uint8 * src = dpi->bits;
|
||||
uint8 * dst = pixels32;
|
||||
for (size_t i = 0; i < numPixels; i++)
|
||||
{
|
||||
uint8 paletteIndex = *src++;
|
||||
if (paletteIndex == 0)
|
||||
{
|
||||
// Transparent
|
||||
*dst++ = 0;
|
||||
*dst++ = 0;
|
||||
*dst++ = 0;
|
||||
*dst++ = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_Color colour = _palette[paletteIndex];
|
||||
*dst++ = colour.r;
|
||||
*dst++ = colour.g;
|
||||
*dst++ = colour.b;
|
||||
*dst++ = colour.a;
|
||||
}
|
||||
}
|
||||
return pixels32;
|
||||
}
|
||||
|
||||
void TextureCache::FreeTextures()
|
||||
{
|
||||
// Free array texture
|
||||
@@ -352,27 +250,26 @@ void TextureCache::FreeTextures()
|
||||
_imageTextureMap.clear();
|
||||
}
|
||||
|
||||
rct_drawpixelinfo * TextureCache::CreateDPI(sint32 width, sint32 height)
|
||||
rct_drawpixelinfo TextureCache::CreateDPI(sint32 width, sint32 height)
|
||||
{
|
||||
size_t numPixels = width * height;
|
||||
uint8 * pixels8 = Memory::Allocate<uint8>(numPixels);
|
||||
Memory::Set(pixels8, 0, numPixels);
|
||||
|
||||
rct_drawpixelinfo * dpi = new rct_drawpixelinfo();
|
||||
dpi->bits = pixels8;
|
||||
dpi->pitch = 0;
|
||||
dpi->x = 0;
|
||||
dpi->y = 0;
|
||||
dpi->width = width;
|
||||
dpi->height = height;
|
||||
dpi->zoom_level = 0;
|
||||
rct_drawpixelinfo dpi;
|
||||
dpi.bits = pixels8;
|
||||
dpi.pitch = 0;
|
||||
dpi.x = 0;
|
||||
dpi.y = 0;
|
||||
dpi.width = width;
|
||||
dpi.height = height;
|
||||
dpi.zoom_level = 0;
|
||||
return dpi;
|
||||
}
|
||||
|
||||
void TextureCache::DeleteDPI(rct_drawpixelinfo* dpi)
|
||||
void TextureCache::DeleteDPI(rct_drawpixelinfo dpi)
|
||||
{
|
||||
Memory::Free(dpi->bits);
|
||||
delete dpi;
|
||||
Memory::Free(dpi.bits);
|
||||
}
|
||||
|
||||
GLuint TextureCache::GetAtlasesTexture()
|
||||
@@ -380,4 +277,14 @@ GLuint TextureCache::GetAtlasesTexture()
|
||||
return _atlasesTexture;
|
||||
}
|
||||
|
||||
GLuint TextureCache::GetPaletteTexture()
|
||||
{
|
||||
return _paletteTexture;
|
||||
}
|
||||
|
||||
GLint TextureCache::PaletteToY(uint32 palette)
|
||||
{
|
||||
return palette > PALETTE_WATER ? palette + 5 : palette + 1;
|
||||
}
|
||||
|
||||
#endif /* DISABLE_OPENGL */
|
||||
|
||||
@@ -188,7 +188,7 @@ private:
|
||||
class TextureCache final
|
||||
{
|
||||
private:
|
||||
bool _atlasesTextureInitialised = false;
|
||||
bool _initialized = false;
|
||||
|
||||
GLuint _atlasesTexture = 0;
|
||||
GLint _atlasesTextureDimensions = 0;
|
||||
@@ -200,34 +200,30 @@ private:
|
||||
std::unordered_map<uint32, CachedTextureInfo> _imageTextureMap;
|
||||
std::unordered_map<uint32, CachedTextureInfo> _paletteTextureMap;
|
||||
|
||||
SDL_Color _palette[256];
|
||||
GLuint _paletteTexture = 0;
|
||||
|
||||
public:
|
||||
TextureCache() = default;
|
||||
~TextureCache();
|
||||
void SetPalette(const SDL_Color * palette);
|
||||
void InvalidateImage(uint32 image);
|
||||
const CachedTextureInfo* GetOrLoadImageTexture(uint32 image);
|
||||
CachedTextureInfo GetOrLoadGlyphTexture(uint32 image, uint8 * palette);
|
||||
const CachedTextureInfo* GetOrLoadPaletteTexture(uint32 image, uint32 tertiaryColour, bool special);
|
||||
|
||||
GLuint GetAtlasesTexture();
|
||||
GLuint GetPaletteTexture();
|
||||
static GLint PaletteToY(uint32 palette);
|
||||
|
||||
private:
|
||||
void CreateAtlasesTexture();
|
||||
void AllocateAtlasesTexture();
|
||||
void CreateTextures();
|
||||
void GeneratePaletteTexture();
|
||||
void EnlargeAtlasesTexture(GLuint newEntries);
|
||||
CachedTextureInfo LoadImageTexture(uint32 image);
|
||||
CachedTextureInfo LoadGlyphTexture(uint32 image, uint8 * palette);
|
||||
CachedTextureInfo LoadPaletteTexture(uint32 image, uint32 tertiaryColour, bool special);
|
||||
CachedTextureInfo AllocateImage(sint32 imageWidth, sint32 imageHeight);
|
||||
void * GetImageAsARGB(uint32 image, uint32 tertiaryColour, uint32 * outWidth, uint32 * outHeight);
|
||||
rct_drawpixelinfo * GetImageAsDPI(uint32 image, uint32 tertiaryColour);
|
||||
void * GetGlyphAsARGB(uint32 image, uint8 * palette, uint32 * outWidth, uint32 * outHeight);
|
||||
rct_drawpixelinfo * GetGlyphAsDPI(uint32 image, uint8 * palette);
|
||||
void * ConvertDPIto32bpp(const rct_drawpixelinfo * dpi);
|
||||
rct_drawpixelinfo GetImageAsDPI(uint32 image, uint32 tertiaryColour);
|
||||
rct_drawpixelinfo GetGlyphAsDPI(uint32 image, uint8 * palette);
|
||||
void FreeTextures();
|
||||
|
||||
static rct_drawpixelinfo * CreateDPI(sint32 width, sint32 height);
|
||||
static void DeleteDPI(rct_drawpixelinfo * dpi);
|
||||
static rct_drawpixelinfo CreateDPI(sint32 width, sint32 height);
|
||||
static void DeleteDPI(rct_drawpixelinfo dpi);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user