mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-04 13:42:55 +01:00
Stricter OpenGL error checking (#24419)
* Wrap OpenGL api calls to catch errors more easily * Default initialize members, use correct types, more error checking * Add missing include * Fix the build, hopefully * Ignore clang-tidy warning * Change the macro expansion
This commit is contained in:
@@ -34,30 +34,31 @@ ApplyPaletteShader::ApplyPaletteShader()
|
||||
{
|
||||
GetLocations();
|
||||
|
||||
glGenBuffers(1, &_vbo);
|
||||
glGenVertexArrays(1, &_vao);
|
||||
glCall(glGenBuffers, 1, &_vbo);
|
||||
glCall(glGenVertexArrays, 1, &_vao);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(kVertexData), kVertexData, GL_STATIC_DRAW);
|
||||
glCall(glBindBuffer, GL_ARRAY_BUFFER, _vbo);
|
||||
glCall(glBufferData, GL_ARRAY_BUFFER, sizeof(kVertexData), kVertexData, GL_STATIC_DRAW);
|
||||
|
||||
glBindVertexArray(_vao);
|
||||
glVertexAttribPointer(
|
||||
vPosition, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), reinterpret_cast<void*>(offsetof(VDStruct, position)));
|
||||
glVertexAttribPointer(
|
||||
vTextureCoordinate, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct),
|
||||
glCall(glBindVertexArray, _vao);
|
||||
glCall(
|
||||
glVertexAttribPointer, vPosition, 2, GL_FLOAT, GL_FALSE, glSizeOf<VDStruct>(),
|
||||
reinterpret_cast<void*>(offsetof(VDStruct, position)));
|
||||
glCall(
|
||||
glVertexAttribPointer, vTextureCoordinate, 2, GL_FLOAT, GL_FALSE, glSizeOf<VDStruct>(),
|
||||
reinterpret_cast<void*>(offsetof(VDStruct, texturecoordinate)));
|
||||
|
||||
glEnableVertexAttribArray(vPosition);
|
||||
glEnableVertexAttribArray(vTextureCoordinate);
|
||||
glCall(glEnableVertexAttribArray, vPosition);
|
||||
glCall(glEnableVertexAttribArray, vTextureCoordinate);
|
||||
|
||||
Use();
|
||||
glUniform1i(uTexture, 0);
|
||||
glCall(glUniform1i, uTexture, 0);
|
||||
}
|
||||
|
||||
ApplyPaletteShader::~ApplyPaletteShader()
|
||||
{
|
||||
glDeleteBuffers(1, &_vbo);
|
||||
glDeleteVertexArrays(1, &_vao);
|
||||
glCall(glDeleteBuffers, 1, &_vbo);
|
||||
glCall(glDeleteVertexArrays, 1, &_vao);
|
||||
}
|
||||
|
||||
void ApplyPaletteShader::GetLocations()
|
||||
@@ -76,12 +77,12 @@ void ApplyPaletteShader::SetTexture(GLuint texture)
|
||||
|
||||
void ApplyPaletteShader::SetPalette(const vec4* glPalette)
|
||||
{
|
||||
glUniform4fv(uPalette, 256, reinterpret_cast<const GLfloat*>(glPalette));
|
||||
glCall(glUniform4fv, uPalette, 256, reinterpret_cast<const GLfloat*>(glPalette));
|
||||
}
|
||||
|
||||
void ApplyPaletteShader::Draw()
|
||||
{
|
||||
glBindVertexArray(_vao);
|
||||
glCall(glBindVertexArray, _vao);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,14 +17,14 @@ namespace OpenRCT2::Ui
|
||||
class ApplyPaletteShader final : public OpenGLShaderProgram
|
||||
{
|
||||
private:
|
||||
GLuint uTexture;
|
||||
GLuint uPalette;
|
||||
GLint uTexture{ -1 };
|
||||
GLint uPalette{ -1 };
|
||||
|
||||
GLuint vPosition;
|
||||
GLuint vTextureCoordinate;
|
||||
GLint vPosition{ -1 };
|
||||
GLint vTextureCoordinate{ -1 };
|
||||
|
||||
GLuint _vbo;
|
||||
GLuint _vao;
|
||||
GLuint _vbo{};
|
||||
GLuint _vao{};
|
||||
|
||||
public:
|
||||
ApplyPaletteShader();
|
||||
|
||||
@@ -34,35 +34,36 @@ ApplyTransparencyShader::ApplyTransparencyShader()
|
||||
{
|
||||
GetLocations();
|
||||
|
||||
glGenBuffers(1, &_vbo);
|
||||
glGenVertexArrays(1, &_vao);
|
||||
glCall(glGenBuffers, 1, &_vbo);
|
||||
glCall(glGenVertexArrays, 1, &_vao);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(kVertexData), kVertexData, GL_STATIC_DRAW);
|
||||
glCall(glBindBuffer, GL_ARRAY_BUFFER, _vbo);
|
||||
glCall(glBufferData, GL_ARRAY_BUFFER, sizeof(kVertexData), kVertexData, GL_STATIC_DRAW);
|
||||
|
||||
glBindVertexArray(_vao);
|
||||
glVertexAttribPointer(
|
||||
vPosition, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), reinterpret_cast<void*>(offsetof(VDStruct, position)));
|
||||
glVertexAttribPointer(
|
||||
vTextureCoordinate, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct),
|
||||
glCall(glBindVertexArray, _vao);
|
||||
glCall(
|
||||
glVertexAttribPointer, vPosition, 2, GL_FLOAT, GL_FALSE, glSizeOf<VDStruct>(),
|
||||
reinterpret_cast<void*>(offsetof(VDStruct, position)));
|
||||
glCall(
|
||||
glVertexAttribPointer, vTextureCoordinate, 2, GL_FLOAT, GL_FALSE, glSizeOf<VDStruct>(),
|
||||
reinterpret_cast<void*>(offsetof(VDStruct, texturecoordinate)));
|
||||
|
||||
glEnableVertexAttribArray(vPosition);
|
||||
glEnableVertexAttribArray(vTextureCoordinate);
|
||||
glCall(glEnableVertexAttribArray, vPosition);
|
||||
glCall(glEnableVertexAttribArray, vTextureCoordinate);
|
||||
|
||||
Use();
|
||||
glUniform1i(uOpaqueTex, 0);
|
||||
glUniform1i(uOpaqueDepth, 1);
|
||||
glUniform1i(uTransparentTex, 2);
|
||||
glUniform1i(uTransparentDepth, 3);
|
||||
glUniform1i(uPaletteTex, 4);
|
||||
glUniform1i(uBlendPaletteTex, 5);
|
||||
glCall(glUniform1i, uOpaqueTex, 0);
|
||||
glCall(glUniform1i, uOpaqueDepth, 1);
|
||||
glCall(glUniform1i, uTransparentTex, 2);
|
||||
glCall(glUniform1i, uTransparentDepth, 3);
|
||||
glCall(glUniform1i, uPaletteTex, 4);
|
||||
glCall(glUniform1i, uBlendPaletteTex, 5);
|
||||
}
|
||||
|
||||
ApplyTransparencyShader::~ApplyTransparencyShader()
|
||||
{
|
||||
glDeleteBuffers(1, &_vbo);
|
||||
glDeleteVertexArrays(1, &_vao);
|
||||
glCall(glDeleteBuffers, 1, &_vbo);
|
||||
glCall(glDeleteVertexArrays, 1, &_vao);
|
||||
}
|
||||
|
||||
void ApplyTransparencyShader::GetLocations()
|
||||
@@ -92,7 +93,7 @@ void ApplyTransparencyShader::SetTextures(
|
||||
|
||||
void ApplyTransparencyShader::Draw()
|
||||
{
|
||||
glBindVertexArray(_vao);
|
||||
glCall(glBindVertexArray, _vao);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,18 +16,18 @@ namespace OpenRCT2::Ui
|
||||
class ApplyTransparencyShader final : public OpenGLShaderProgram
|
||||
{
|
||||
private:
|
||||
GLuint uOpaqueTex;
|
||||
GLuint uOpaqueDepth;
|
||||
GLuint uTransparentTex;
|
||||
GLuint uTransparentDepth;
|
||||
GLuint uPaletteTex;
|
||||
GLuint uBlendPaletteTex;
|
||||
GLint uOpaqueTex{ -1 };
|
||||
GLint uOpaqueDepth{ -1 };
|
||||
GLint uTransparentTex{ -1 };
|
||||
GLint uTransparentDepth{ -1 };
|
||||
GLint uPaletteTex{ -1 };
|
||||
GLint uBlendPaletteTex{ -1 };
|
||||
|
||||
GLuint vPosition;
|
||||
GLuint vTextureCoordinate;
|
||||
GLint vPosition{ -1 };
|
||||
GLint vTextureCoordinate{ -1 };
|
||||
|
||||
GLuint _vbo;
|
||||
GLuint _vao;
|
||||
GLuint _vbo{};
|
||||
GLuint _vao{};
|
||||
|
||||
public:
|
||||
ApplyTransparencyShader();
|
||||
|
||||
@@ -33,51 +33,57 @@ DrawLineShader::DrawLineShader()
|
||||
{
|
||||
GetLocations();
|
||||
|
||||
glGenBuffers(1, &_vbo);
|
||||
glGenBuffers(1, &_vboInstances);
|
||||
glGenVertexArrays(1, &_vao);
|
||||
glCall(glGenBuffers, 1, &_vbo);
|
||||
glCall(glGenBuffers, 1, &_vboInstances);
|
||||
glCall(glGenVertexArrays, 1, &_vao);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(kVertexData), kVertexData, GL_STATIC_DRAW);
|
||||
glCall(glBindBuffer, GL_ARRAY_BUFFER, _vbo);
|
||||
glCall(glBufferData, GL_ARRAY_BUFFER, sizeof(kVertexData), kVertexData, GL_STATIC_DRAW);
|
||||
glCall(glBindVertexArray, _vao);
|
||||
glCall(
|
||||
glVertexAttribPointer, vVertMat + 0, 2, GL_FLOAT, GL_FALSE, glSizeOf<VDStruct>(),
|
||||
reinterpret_cast<void*>(offsetof(VDStruct, mat[0])));
|
||||
glCall(
|
||||
glVertexAttribPointer, vVertMat + 1, 2, GL_FLOAT, GL_FALSE, glSizeOf<VDStruct>(),
|
||||
reinterpret_cast<void*>(offsetof(VDStruct, mat[1])));
|
||||
glCall(
|
||||
glVertexAttribPointer, vVertMat + 2, 2, GL_FLOAT, GL_FALSE, glSizeOf<VDStruct>(),
|
||||
reinterpret_cast<void*>(offsetof(VDStruct, mat[2])));
|
||||
glCall(
|
||||
glVertexAttribPointer, vVertMat + 3, 2, GL_FLOAT, GL_FALSE, glSizeOf<VDStruct>(),
|
||||
reinterpret_cast<void*>(offsetof(VDStruct, mat[3])));
|
||||
|
||||
glBindVertexArray(_vao);
|
||||
glVertexAttribPointer(
|
||||
vVertMat + 0, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), reinterpret_cast<void*>(offsetof(VDStruct, mat[0])));
|
||||
glVertexAttribPointer(
|
||||
vVertMat + 1, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), reinterpret_cast<void*>(offsetof(VDStruct, mat[1])));
|
||||
glVertexAttribPointer(
|
||||
vVertMat + 2, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), reinterpret_cast<void*>(offsetof(VDStruct, mat[2])));
|
||||
glVertexAttribPointer(
|
||||
vVertMat + 3, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), reinterpret_cast<void*>(offsetof(VDStruct, mat[3])));
|
||||
glCall(glBindBuffer, GL_ARRAY_BUFFER, _vboInstances);
|
||||
glCall(
|
||||
glVertexAttribIPointer, vBounds, 4, GL_INT, glSizeOf<DrawLineCommand>(),
|
||||
reinterpret_cast<void*>(offsetof(DrawLineCommand, bounds)));
|
||||
glCall(
|
||||
glVertexAttribIPointer, vColour, 1, GL_UNSIGNED_INT, glSizeOf<DrawLineCommand>(),
|
||||
reinterpret_cast<void*>(offsetof(DrawLineCommand, colour)));
|
||||
glCall(
|
||||
glVertexAttribIPointer, vDepth, 1, GL_INT, glSizeOf<DrawLineCommand>(),
|
||||
reinterpret_cast<void*>(offsetof(DrawLineCommand, depth)));
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboInstances);
|
||||
glVertexAttribIPointer(
|
||||
vBounds, 4, GL_INT, sizeof(DrawLineCommand), reinterpret_cast<void*>(offsetof(DrawLineCommand, bounds)));
|
||||
glVertexAttribIPointer(
|
||||
vColour, 1, GL_UNSIGNED_INT, sizeof(DrawLineCommand), reinterpret_cast<void*>(offsetof(DrawLineCommand, colour)));
|
||||
glVertexAttribIPointer(
|
||||
vDepth, 1, GL_INT, sizeof(DrawLineCommand), reinterpret_cast<void*>(offsetof(DrawLineCommand, depth)));
|
||||
glCall(glEnableVertexAttribArray, vVertMat + 0);
|
||||
glCall(glEnableVertexAttribArray, vVertMat + 1);
|
||||
glCall(glEnableVertexAttribArray, vVertMat + 2);
|
||||
glCall(glEnableVertexAttribArray, vVertMat + 3);
|
||||
|
||||
glEnableVertexAttribArray(vVertMat + 0);
|
||||
glEnableVertexAttribArray(vVertMat + 1);
|
||||
glEnableVertexAttribArray(vVertMat + 2);
|
||||
glEnableVertexAttribArray(vVertMat + 3);
|
||||
glCall(glEnableVertexAttribArray, vBounds);
|
||||
glCall(glEnableVertexAttribArray, vColour);
|
||||
glCall(glEnableVertexAttribArray, vDepth);
|
||||
|
||||
glEnableVertexAttribArray(vBounds);
|
||||
glEnableVertexAttribArray(vColour);
|
||||
glEnableVertexAttribArray(vDepth);
|
||||
|
||||
glVertexAttribDivisor(vBounds, 1);
|
||||
glVertexAttribDivisor(vColour, 1);
|
||||
glVertexAttribDivisor(vDepth, 1);
|
||||
glCall(glVertexAttribDivisor, vBounds, 1);
|
||||
glCall(glVertexAttribDivisor, vColour, 1);
|
||||
glCall(glVertexAttribDivisor, vDepth, 1);
|
||||
|
||||
Use();
|
||||
}
|
||||
|
||||
DrawLineShader::~DrawLineShader()
|
||||
{
|
||||
glDeleteBuffers(1, &_vbo);
|
||||
glDeleteVertexArrays(1, &_vao);
|
||||
glCall(glDeleteBuffers, 1, &_vbo);
|
||||
glCall(glDeleteVertexArrays, 1, &_vao);
|
||||
}
|
||||
|
||||
void DrawLineShader::GetLocations()
|
||||
@@ -93,17 +99,17 @@ void DrawLineShader::GetLocations()
|
||||
|
||||
void DrawLineShader::SetScreenSize(int32_t width, int32_t height)
|
||||
{
|
||||
glUniform2i(uScreenSize, width, height);
|
||||
glCall(glUniform2i, uScreenSize, width, height);
|
||||
}
|
||||
|
||||
void DrawLineShader::DrawInstances(const LineCommandBatch& instances)
|
||||
{
|
||||
glBindVertexArray(_vao);
|
||||
glCall(glBindVertexArray, _vao);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboInstances);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(DrawLineCommand) * instances.size(), instances.data(), GL_STREAM_DRAW);
|
||||
glCall(glBindBuffer, GL_ARRAY_BUFFER, _vboInstances);
|
||||
glCall(glBufferData, GL_ARRAY_BUFFER, sizeof(DrawLineCommand) * instances.size(), instances.data(), GL_STREAM_DRAW);
|
||||
|
||||
glDrawArraysInstanced(GL_LINES, 0, 2, static_cast<GLsizei>(instances.size()));
|
||||
glCall(glDrawArraysInstanced, GL_LINES, 0, 2, static_cast<GLsizei>(instances.size()));
|
||||
}
|
||||
|
||||
#endif /* DISABLE_OPENGL */
|
||||
|
||||
@@ -17,17 +17,17 @@ namespace OpenRCT2::Ui
|
||||
class DrawLineShader final : public OpenGLShaderProgram
|
||||
{
|
||||
private:
|
||||
GLuint uScreenSize;
|
||||
GLint uScreenSize{ -1 };
|
||||
|
||||
GLuint vBounds;
|
||||
GLuint vColour;
|
||||
GLuint vDepth;
|
||||
GLint vBounds{ -1 };
|
||||
GLint vColour{ -1 };
|
||||
GLint vDepth{ -1 };
|
||||
|
||||
GLuint vVertMat;
|
||||
GLint vVertMat{ -1 };
|
||||
|
||||
GLuint _vbo;
|
||||
GLuint _vboInstances;
|
||||
GLuint _vao;
|
||||
GLuint _vbo{};
|
||||
GLuint _vboInstances{};
|
||||
GLuint _vao{};
|
||||
|
||||
public:
|
||||
DrawLineShader();
|
||||
|
||||
@@ -37,96 +37,111 @@ DrawRectShader::DrawRectShader()
|
||||
{
|
||||
GetLocations();
|
||||
|
||||
glGenBuffers(1, &_vbo);
|
||||
glGenBuffers(1, &_vboInstances);
|
||||
glGenVertexArrays(1, &_vao);
|
||||
glCall(glGenBuffers, 1, &_vbo);
|
||||
glCall(glGenBuffers, 1, &_vboInstances);
|
||||
glCall(glGenVertexArrays, 1, &_vao);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(kVertexData), kVertexData, GL_STATIC_DRAW);
|
||||
glCall(glBindBuffer, GL_ARRAY_BUFFER, _vbo);
|
||||
glCall(glBufferData, GL_ARRAY_BUFFER, sizeof(kVertexData), kVertexData, GL_STATIC_DRAW);
|
||||
|
||||
glBindVertexArray(_vao);
|
||||
glCall(glBindVertexArray, _vao);
|
||||
|
||||
glVertexAttribPointer(
|
||||
vVertMat + 0, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), reinterpret_cast<void*>(offsetof(VDStruct, mat[0])));
|
||||
glVertexAttribPointer(
|
||||
vVertMat + 1, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), reinterpret_cast<void*>(offsetof(VDStruct, mat[1])));
|
||||
glVertexAttribPointer(
|
||||
vVertMat + 2, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), reinterpret_cast<void*>(offsetof(VDStruct, mat[2])));
|
||||
glVertexAttribPointer(
|
||||
vVertMat + 3, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), reinterpret_cast<void*>(offsetof(VDStruct, mat[3])));
|
||||
glVertexAttribPointer(vVertVec, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), reinterpret_cast<void*>(offsetof(VDStruct, vec)));
|
||||
glCall(
|
||||
glVertexAttribPointer, vVertMat + 0, 2, GL_FLOAT, GL_FALSE, glSizeOf<VDStruct>(),
|
||||
reinterpret_cast<void*>(offsetof(VDStruct, mat[0])));
|
||||
glCall(
|
||||
glVertexAttribPointer, vVertMat + 1, 2, GL_FLOAT, GL_FALSE, glSizeOf<VDStruct>(),
|
||||
reinterpret_cast<void*>(offsetof(VDStruct, mat[1])));
|
||||
glCall(
|
||||
glVertexAttribPointer, vVertMat + 2, 2, GL_FLOAT, GL_FALSE, glSizeOf<VDStruct>(),
|
||||
reinterpret_cast<void*>(offsetof(VDStruct, mat[2])));
|
||||
glCall(
|
||||
glVertexAttribPointer, vVertMat + 3, 2, GL_FLOAT, GL_FALSE, glSizeOf<VDStruct>(),
|
||||
reinterpret_cast<void*>(offsetof(VDStruct, mat[3])));
|
||||
glCall(
|
||||
glVertexAttribPointer, vVertVec, 2, GL_FLOAT, GL_FALSE, glSizeOf<VDStruct>(),
|
||||
reinterpret_cast<void*>(offsetof(VDStruct, vec)));
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboInstances);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(DrawRectCommand) * kInitialInstancesBufferSize, nullptr, GL_STREAM_DRAW);
|
||||
glCall(glBindBuffer, GL_ARRAY_BUFFER, _vboInstances);
|
||||
glCall(glBufferData, GL_ARRAY_BUFFER, sizeof(DrawRectCommand) * kInitialInstancesBufferSize, nullptr, GL_STREAM_DRAW);
|
||||
|
||||
glVertexAttribIPointer(vClip, 4, GL_INT, sizeof(DrawRectCommand), reinterpret_cast<void*>(offsetof(DrawRectCommand, clip)));
|
||||
glVertexAttribIPointer(
|
||||
vTexColourAtlas, 1, GL_INT, sizeof(DrawRectCommand),
|
||||
glCall(
|
||||
glVertexAttribIPointer, vClip, 4, GL_INT, glSizeOf<DrawRectCommand>(),
|
||||
reinterpret_cast<void*>(offsetof(DrawRectCommand, clip)));
|
||||
glCall(
|
||||
glVertexAttribIPointer, vTexColourAtlas, 1, GL_INT, glSizeOf<DrawRectCommand>(),
|
||||
reinterpret_cast<void*>(offsetof(DrawRectCommand, texColourAtlas)));
|
||||
glVertexAttribPointer(
|
||||
vTexColourCoords, 4, GL_FLOAT, GL_FALSE, sizeof(DrawRectCommand),
|
||||
glCall(
|
||||
glVertexAttribPointer, vTexColourCoords, 4, GL_FLOAT, GL_FALSE, glSizeOf<DrawRectCommand>(),
|
||||
reinterpret_cast<void*>(offsetof(DrawRectCommand, texColourBounds)));
|
||||
glVertexAttribIPointer(
|
||||
vTexMaskAtlas, 1, GL_INT, sizeof(DrawRectCommand), reinterpret_cast<void*>(offsetof(DrawRectCommand, texMaskAtlas)));
|
||||
glVertexAttribPointer(
|
||||
vTexMaskCoords, 4, GL_FLOAT, GL_FALSE, sizeof(DrawRectCommand),
|
||||
glCall(
|
||||
glVertexAttribIPointer, vTexMaskAtlas, 1, GL_INT, glSizeOf<DrawRectCommand>(),
|
||||
reinterpret_cast<void*>(offsetof(DrawRectCommand, texMaskAtlas)));
|
||||
glCall(
|
||||
glVertexAttribPointer, vTexMaskCoords, 4, GL_FLOAT, GL_FALSE, glSizeOf<DrawRectCommand>(),
|
||||
reinterpret_cast<void*>(offsetof(DrawRectCommand, texMaskBounds)));
|
||||
glVertexAttribIPointer(
|
||||
vPalettes, 3, GL_INT, sizeof(DrawRectCommand), reinterpret_cast<void*>(offsetof(DrawRectCommand, palettes)));
|
||||
glVertexAttribIPointer(
|
||||
vFlags, 1, GL_INT, sizeof(DrawRectCommand), reinterpret_cast<void*>(offsetof(DrawRectCommand, flags)));
|
||||
glVertexAttribIPointer(
|
||||
vColour, 1, GL_UNSIGNED_INT, sizeof(DrawRectCommand), reinterpret_cast<void*>(offsetof(DrawRectCommand, colour)));
|
||||
glVertexAttribIPointer(
|
||||
vBounds, 4, GL_INT, sizeof(DrawRectCommand), reinterpret_cast<void*>(offsetof(DrawRectCommand, bounds)));
|
||||
glVertexAttribIPointer(
|
||||
vDepth, 1, GL_INT, sizeof(DrawRectCommand), reinterpret_cast<void*>(offsetof(DrawRectCommand, depth)));
|
||||
glVertexAttribPointer(
|
||||
vZoom, 1, GL_FLOAT, GL_FALSE, sizeof(DrawRectCommand), reinterpret_cast<void*>(offsetof(DrawRectCommand, zoom)));
|
||||
glCall(
|
||||
glVertexAttribIPointer, vPalettes, 3, GL_INT, glSizeOf<DrawRectCommand>(),
|
||||
reinterpret_cast<void*>(offsetof(DrawRectCommand, palettes)));
|
||||
glCall(
|
||||
glVertexAttribIPointer, vFlags, 1, GL_INT, glSizeOf<DrawRectCommand>(),
|
||||
reinterpret_cast<void*>(offsetof(DrawRectCommand, flags)));
|
||||
glCall(
|
||||
glVertexAttribIPointer, vColour, 1, GL_UNSIGNED_INT, glSizeOf<DrawRectCommand>(),
|
||||
reinterpret_cast<void*>(offsetof(DrawRectCommand, colour)));
|
||||
glCall(
|
||||
glVertexAttribIPointer, vBounds, 4, GL_INT, glSizeOf<DrawRectCommand>(),
|
||||
reinterpret_cast<void*>(offsetof(DrawRectCommand, bounds)));
|
||||
glCall(
|
||||
glVertexAttribIPointer, vDepth, 1, GL_INT, glSizeOf<DrawRectCommand>(),
|
||||
reinterpret_cast<void*>(offsetof(DrawRectCommand, depth)));
|
||||
glCall(
|
||||
glVertexAttribPointer, vZoom, 1, GL_FLOAT, GL_FALSE, glSizeOf<DrawRectCommand>(),
|
||||
reinterpret_cast<void*>(offsetof(DrawRectCommand, zoom)));
|
||||
|
||||
glEnableVertexAttribArray(vVertMat + 0);
|
||||
glEnableVertexAttribArray(vVertMat + 1);
|
||||
glEnableVertexAttribArray(vVertMat + 2);
|
||||
glEnableVertexAttribArray(vVertMat + 3);
|
||||
glEnableVertexAttribArray(vVertVec);
|
||||
glCall(glEnableVertexAttribArray, vVertMat + 0);
|
||||
glCall(glEnableVertexAttribArray, vVertMat + 1);
|
||||
glCall(glEnableVertexAttribArray, vVertMat + 2);
|
||||
glCall(glEnableVertexAttribArray, vVertMat + 3);
|
||||
glCall(glEnableVertexAttribArray, vVertVec);
|
||||
|
||||
glEnableVertexAttribArray(vClip);
|
||||
glEnableVertexAttribArray(vTexColourAtlas);
|
||||
glEnableVertexAttribArray(vTexColourCoords);
|
||||
glEnableVertexAttribArray(vTexMaskAtlas);
|
||||
glEnableVertexAttribArray(vTexMaskCoords);
|
||||
glEnableVertexAttribArray(vPalettes);
|
||||
glEnableVertexAttribArray(vFlags);
|
||||
glEnableVertexAttribArray(vColour);
|
||||
glEnableVertexAttribArray(vBounds);
|
||||
glEnableVertexAttribArray(vDepth);
|
||||
glEnableVertexAttribArray(vZoom);
|
||||
glCall(glEnableVertexAttribArray, vClip);
|
||||
glCall(glEnableVertexAttribArray, vTexColourAtlas);
|
||||
glCall(glEnableVertexAttribArray, vTexColourCoords);
|
||||
glCall(glEnableVertexAttribArray, vTexMaskAtlas);
|
||||
glCall(glEnableVertexAttribArray, vTexMaskCoords);
|
||||
glCall(glEnableVertexAttribArray, vPalettes);
|
||||
glCall(glEnableVertexAttribArray, vFlags);
|
||||
glCall(glEnableVertexAttribArray, vColour);
|
||||
glCall(glEnableVertexAttribArray, vBounds);
|
||||
glCall(glEnableVertexAttribArray, vDepth);
|
||||
glCall(glEnableVertexAttribArray, vZoom);
|
||||
|
||||
glVertexAttribDivisor(vClip, 1);
|
||||
glVertexAttribDivisor(vTexColourAtlas, 1);
|
||||
glVertexAttribDivisor(vTexColourCoords, 1);
|
||||
glVertexAttribDivisor(vTexMaskAtlas, 1);
|
||||
glVertexAttribDivisor(vTexMaskCoords, 1);
|
||||
glVertexAttribDivisor(vPalettes, 1);
|
||||
glVertexAttribDivisor(vFlags, 1);
|
||||
glVertexAttribDivisor(vColour, 1);
|
||||
glVertexAttribDivisor(vBounds, 1);
|
||||
glVertexAttribDivisor(vDepth, 1);
|
||||
glVertexAttribDivisor(vZoom, 1);
|
||||
glCall(glVertexAttribDivisor, vClip, 1);
|
||||
glCall(glVertexAttribDivisor, vTexColourAtlas, 1);
|
||||
glCall(glVertexAttribDivisor, vTexColourCoords, 1);
|
||||
glCall(glVertexAttribDivisor, vTexMaskAtlas, 1);
|
||||
glCall(glVertexAttribDivisor, vTexMaskCoords, 1);
|
||||
glCall(glVertexAttribDivisor, vPalettes, 1);
|
||||
glCall(glVertexAttribDivisor, vFlags, 1);
|
||||
glCall(glVertexAttribDivisor, vColour, 1);
|
||||
glCall(glVertexAttribDivisor, vBounds, 1);
|
||||
glCall(glVertexAttribDivisor, vDepth, 1);
|
||||
glCall(glVertexAttribDivisor, vZoom, 1);
|
||||
|
||||
Use();
|
||||
glUniform1i(uTexture, 0);
|
||||
glUniform1i(uPaletteTex, 1);
|
||||
glCall(glUniform1i, uTexture, 0);
|
||||
glCall(glUniform1i, uPaletteTex, 1);
|
||||
|
||||
glUniform1i(uPeelingTex, 2);
|
||||
glUniform1i(uPeeling, 0);
|
||||
glCall(glUniform1i, uPeelingTex, 2);
|
||||
glCall(glUniform1i, uPeeling, 0);
|
||||
}
|
||||
|
||||
DrawRectShader::~DrawRectShader()
|
||||
{
|
||||
glDeleteBuffers(1, &_vbo);
|
||||
glDeleteBuffers(1, &_vboInstances);
|
||||
glDeleteVertexArrays(1, &_vao);
|
||||
glCall(glDeleteBuffers, 1, &_vbo);
|
||||
glCall(glDeleteBuffers, 1, &_vboInstances);
|
||||
glCall(glDeleteVertexArrays, 1, &_vao);
|
||||
}
|
||||
|
||||
void DrawRectShader::GetLocations()
|
||||
@@ -156,34 +171,34 @@ void DrawRectShader::GetLocations()
|
||||
|
||||
void DrawRectShader::SetScreenSize(int32_t width, int32_t height)
|
||||
{
|
||||
glUniform2i(uScreenSize, width, height);
|
||||
glCall(glUniform2i, uScreenSize, width, height);
|
||||
}
|
||||
|
||||
void DrawRectShader::EnablePeeling(GLuint peelingTex)
|
||||
{
|
||||
OpenGLAPI::SetTexture(2, GL_TEXTURE_2D, peelingTex);
|
||||
glUniform1i(uPeeling, 1);
|
||||
glCall(glUniform1i, uPeeling, 1);
|
||||
}
|
||||
|
||||
void DrawRectShader::DisablePeeling()
|
||||
{
|
||||
glUniform1i(uPeeling, 0);
|
||||
glCall(glUniform1i, uPeeling, 0);
|
||||
}
|
||||
|
||||
void DrawRectShader::SetInstances(const RectCommandBatch& instances)
|
||||
{
|
||||
glBindVertexArray(_vao);
|
||||
glCall(glBindVertexArray, _vao);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboInstances);
|
||||
glCall(glBindBuffer, GL_ARRAY_BUFFER, _vboInstances);
|
||||
|
||||
if (instances.size() > _maxInstancesBufferSize)
|
||||
{
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(DrawRectCommand) * instances.size(), instances.data(), GL_STREAM_DRAW);
|
||||
glCall(glBufferData, GL_ARRAY_BUFFER, sizeof(DrawRectCommand) * instances.size(), instances.data(), GL_STREAM_DRAW);
|
||||
_maxInstancesBufferSize = instances.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(DrawRectCommand) * instances.size(), instances.data());
|
||||
glCall(glBufferSubData, GL_ARRAY_BUFFER, 0, sizeof(DrawRectCommand) * instances.size(), instances.data());
|
||||
}
|
||||
|
||||
_instanceCount = static_cast<GLsizei>(instances.size());
|
||||
@@ -191,8 +206,8 @@ void DrawRectShader::SetInstances(const RectCommandBatch& instances)
|
||||
|
||||
void DrawRectShader::DrawInstances()
|
||||
{
|
||||
glBindVertexArray(_vao);
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, _instanceCount);
|
||||
glCall(glBindVertexArray, _vao);
|
||||
glCall(glDrawArraysInstanced, GL_TRIANGLE_STRIP, 0, 4, _instanceCount);
|
||||
}
|
||||
|
||||
#endif /* DISABLE_OPENGL */
|
||||
|
||||
@@ -19,31 +19,31 @@ namespace OpenRCT2::Ui
|
||||
class DrawRectShader final : public OpenGLShaderProgram
|
||||
{
|
||||
private:
|
||||
GLuint uScreenSize;
|
||||
GLuint uTexture;
|
||||
GLuint uPaletteTex;
|
||||
GLint uScreenSize{ -1 };
|
||||
GLint uTexture{ -1 };
|
||||
GLint uPaletteTex{ -1 };
|
||||
|
||||
GLuint uPeelingTex;
|
||||
GLuint uPeeling;
|
||||
GLint uPeelingTex{ -1 };
|
||||
GLint uPeeling{ -1 };
|
||||
|
||||
GLuint vVertMat;
|
||||
GLuint vVertVec;
|
||||
GLint vVertMat{ -1 };
|
||||
GLint vVertVec{ -1 };
|
||||
|
||||
GLuint vClip;
|
||||
GLuint vTexColourAtlas;
|
||||
GLuint vTexColourCoords;
|
||||
GLuint vTexMaskAtlas;
|
||||
GLuint vTexMaskCoords;
|
||||
GLuint vPalettes;
|
||||
GLuint vFlags;
|
||||
GLuint vColour;
|
||||
GLuint vBounds;
|
||||
GLuint vDepth;
|
||||
GLuint vZoom;
|
||||
GLint vClip{ -1 };
|
||||
GLint vTexColourAtlas{ -1 };
|
||||
GLint vTexColourCoords{ -1 };
|
||||
GLint vTexMaskAtlas{ -1 };
|
||||
GLint vTexMaskCoords{ -1 };
|
||||
GLint vPalettes{ -1 };
|
||||
GLint vFlags{ -1 };
|
||||
GLint vColour{ -1 };
|
||||
GLint vBounds{ -1 };
|
||||
GLint vDepth{ -1 };
|
||||
GLint vZoom{ -1 };
|
||||
|
||||
GLuint _vbo;
|
||||
GLuint _vboInstances;
|
||||
GLuint _vao;
|
||||
GLuint _vbo{ 0 };
|
||||
GLuint _vboInstances{ 0 };
|
||||
GLuint _vao{ 0 };
|
||||
|
||||
GLsizei _instanceCount = 0;
|
||||
size_t _maxInstancesBufferSize;
|
||||
|
||||
@@ -9,7 +9,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <openrct2/Diagnostic.h>
|
||||
#include <source_location>
|
||||
#include <string.h>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#ifdef OPENGL_NO_LINK
|
||||
|
||||
@@ -120,6 +125,53 @@ using PFNGLTEXSUBIMAGE2D = void(APIENTRYP)(
|
||||
|
||||
namespace OpenRCT2::Ui
|
||||
{
|
||||
template<typename TSrcLoc, typename TFn, typename... TArgs>
|
||||
inline auto glCallImpl(TSrcLoc&& srcLoc, TFn&& fn, TArgs&&... args) -> decltype(fn(std::forward<TArgs>(args)...))
|
||||
{
|
||||
const auto trimFilePath = [](const char* filePath) {
|
||||
const char* srcPos = strstr(filePath, "src/");
|
||||
if (srcPos == nullptr)
|
||||
{
|
||||
srcPos = strstr(filePath, "src\\");
|
||||
}
|
||||
if (srcPos != nullptr)
|
||||
{
|
||||
return srcPos;
|
||||
}
|
||||
return filePath;
|
||||
};
|
||||
|
||||
if constexpr (std::is_same_v<decltype(fn(std::forward<TArgs>(args)...)), void>)
|
||||
{
|
||||
std::invoke(std::forward<TFn>(fn), std::forward<TArgs>(args)...);
|
||||
GLenum error = glGetError();
|
||||
if (error != GL_NO_ERROR)
|
||||
{
|
||||
LOG_ERROR("OpenGL Error 0x%04X at %s:%d", error, trimFilePath(srcLoc.file_name()), srcLoc.line());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto result = std::invoke(std::forward<TFn>(fn), std::forward<TArgs>(args)...);
|
||||
GLenum error = glGetError();
|
||||
if (error != GL_NO_ERROR)
|
||||
{
|
||||
LOG_ERROR("OpenGL Error 0x%04X at %s:%d", error, trimFilePath(srcLoc.file_name()), srcLoc.line());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTBEGIN
|
||||
#define glCall(...) glCallImpl(std::source_location::current(), ##__VA_ARGS__)
|
||||
// NOLINTEND
|
||||
|
||||
template<typename T>
|
||||
GLsizei glSizeOf()
|
||||
{
|
||||
return static_cast<GLsizei>(sizeof(T));
|
||||
}
|
||||
|
||||
inline void CheckGLError()
|
||||
{
|
||||
GLenum error = glGetError();
|
||||
|
||||
@@ -1217,8 +1217,8 @@ void OpenGLDrawingContext::FlushCommandBuffers()
|
||||
{
|
||||
Guard::Assert(_inDraw == true);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
glCall(glEnable, GL_DEPTH_TEST);
|
||||
glCall(glDepthFunc, GL_LESS);
|
||||
|
||||
_swapFramebuffer->BindOpaque();
|
||||
_drawRectShader->Use();
|
||||
@@ -1271,8 +1271,8 @@ void OpenGLDrawingContext::HandleTransparency()
|
||||
{
|
||||
_swapFramebuffer->BindTransparent();
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_GREATER);
|
||||
glCall(glEnable, GL_DEPTH_TEST);
|
||||
glCall(glDepthFunc, GL_GREATER);
|
||||
_drawRectShader->Use();
|
||||
|
||||
if (i > 0)
|
||||
|
||||
@@ -27,9 +27,9 @@ OpenGLShader::OpenGLShader(const char* name, GLenum type)
|
||||
auto sourceCode = ReadSourceCode(path);
|
||||
auto sourceCodeStr = sourceCode.c_str();
|
||||
|
||||
_id = glCreateShader(type);
|
||||
glShaderSource(_id, 1, static_cast<const GLchar**>(&sourceCodeStr), nullptr);
|
||||
glCompileShader(_id);
|
||||
_id = glCall(glCreateShader, type);
|
||||
glCall(glShaderSource, _id, 1, static_cast<const GLchar**>(&sourceCodeStr), nullptr);
|
||||
glCall(glCompileShader, _id);
|
||||
|
||||
GLint status;
|
||||
glGetShaderiv(_id, GL_COMPILE_STATUS, &status);
|
||||
@@ -48,7 +48,7 @@ OpenGLShader::OpenGLShader(const char* name, GLenum type)
|
||||
|
||||
OpenGLShader::~OpenGLShader()
|
||||
{
|
||||
glDeleteShader(_id);
|
||||
glCall(glDeleteShader, _id);
|
||||
}
|
||||
|
||||
GLuint OpenGLShader::GetShaderId()
|
||||
@@ -92,10 +92,10 @@ OpenGLShaderProgram::OpenGLShaderProgram(const char* name)
|
||||
_vertexShader = std::make_unique<OpenGLShader>(name, GL_VERTEX_SHADER);
|
||||
_fragmentShader = std::make_unique<OpenGLShader>(name, GL_FRAGMENT_SHADER);
|
||||
|
||||
_id = glCreateProgram();
|
||||
glAttachShader(_id, _vertexShader->GetShaderId());
|
||||
glAttachShader(_id, _fragmentShader->GetShaderId());
|
||||
glBindFragDataLocation(_id, 0, "oColour");
|
||||
_id = glCall(glCreateProgram);
|
||||
glCall(glAttachShader, _id, _vertexShader->GetShaderId());
|
||||
glCall(glAttachShader, _id, _fragmentShader->GetShaderId());
|
||||
glCall(glBindFragDataLocation, _id, 0, "oColour");
|
||||
|
||||
if (!Link())
|
||||
{
|
||||
@@ -114,23 +114,33 @@ OpenGLShaderProgram::~OpenGLShaderProgram()
|
||||
{
|
||||
if (_vertexShader != nullptr)
|
||||
{
|
||||
glDetachShader(_id, _vertexShader->GetShaderId());
|
||||
glCall(glDetachShader, _id, _vertexShader->GetShaderId());
|
||||
}
|
||||
if (_fragmentShader != nullptr)
|
||||
{
|
||||
glDetachShader(_id, _fragmentShader->GetShaderId());
|
||||
glCall(glDetachShader, _id, _fragmentShader->GetShaderId());
|
||||
}
|
||||
glDeleteProgram(_id);
|
||||
glCall(glDeleteProgram, _id);
|
||||
}
|
||||
|
||||
GLuint OpenGLShaderProgram::GetAttributeLocation(const char* name)
|
||||
GLint OpenGLShaderProgram::GetAttributeLocation(const char* name)
|
||||
{
|
||||
return glGetAttribLocation(_id, name);
|
||||
auto res = glCall(glGetAttribLocation, _id, name);
|
||||
if (res == -1)
|
||||
{
|
||||
LOG_ERROR("Attribute \"%s\" not found in shader program", name);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
GLuint OpenGLShaderProgram::GetUniformLocation(const char* name)
|
||||
GLint OpenGLShaderProgram::GetUniformLocation(const char* name)
|
||||
{
|
||||
return glGetUniformLocation(_id, name);
|
||||
auto res = glCall(glGetUniformLocation, _id, name);
|
||||
if (res == -1)
|
||||
{
|
||||
LOG_ERROR("Uniform \"%s\" not found in shader program", name);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void OpenGLShaderProgram::Use()
|
||||
@@ -138,13 +148,13 @@ void OpenGLShaderProgram::Use()
|
||||
if (OpenGLState::CurrentProgram != _id)
|
||||
{
|
||||
OpenGLState::CurrentProgram = _id;
|
||||
glUseProgram(_id);
|
||||
glCall(glUseProgram, _id);
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenGLShaderProgram::Link()
|
||||
{
|
||||
glLinkProgram(_id);
|
||||
glCall(glLinkProgram, _id);
|
||||
|
||||
GLint linkStatus;
|
||||
glGetProgramiv(_id, GL_LINK_STATUS, &linkStatus);
|
||||
|
||||
@@ -47,8 +47,8 @@ namespace OpenRCT2::Ui
|
||||
explicit OpenGLShaderProgram(OpenGLShaderProgram&&) = default;
|
||||
virtual ~OpenGLShaderProgram();
|
||||
|
||||
GLuint GetAttributeLocation(const char* name);
|
||||
GLuint GetUniformLocation(const char* name);
|
||||
GLint GetAttributeLocation(const char* name);
|
||||
GLint GetUniformLocation(const char* name);
|
||||
void Use();
|
||||
|
||||
private:
|
||||
|
||||
@@ -26,18 +26,18 @@ SwapFramebuffer::SwapFramebuffer(int32_t width, int32_t height)
|
||||
, _backDepth(OpenGLFramebuffer::CreateDepthTexture(width, height))
|
||||
{
|
||||
_transparentFramebuffer.Bind();
|
||||
glClearBufferfv(GL_DEPTH, 0, kDepthValueTransparent);
|
||||
glCall(glClearBufferfv, GL_DEPTH, 0, kDepthValueTransparent);
|
||||
}
|
||||
|
||||
SwapFramebuffer::~SwapFramebuffer()
|
||||
{
|
||||
glDeleteTextures(1, &_backDepth);
|
||||
glCall(glDeleteTextures, 1, &_backDepth);
|
||||
}
|
||||
|
||||
void SwapFramebuffer::ApplyTransparency(ApplyTransparencyShader& shader, GLuint paletteTex, GLuint blendPaletteTex)
|
||||
{
|
||||
_mixFramebuffer.Bind();
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glCall(glDisable, GL_DEPTH_TEST);
|
||||
shader.Use();
|
||||
shader.SetTextures(
|
||||
_opaqueFramebuffer.GetTexture(), _opaqueFramebuffer.GetDepthTexture(), _transparentFramebuffer.GetTexture(),
|
||||
@@ -48,8 +48,8 @@ void SwapFramebuffer::ApplyTransparency(ApplyTransparencyShader& shader, GLuint
|
||||
|
||||
// Clear transparency buffers
|
||||
_transparentFramebuffer.Bind();
|
||||
glClearBufferuiv(GL_COLOR, 0, kIndexValue);
|
||||
glClearBufferfv(GL_DEPTH, 0, kDepthValueTransparent);
|
||||
glCall(glClearBufferuiv, GL_COLOR, 0, kIndexValue);
|
||||
glCall(glClearBufferfv, GL_DEPTH, 0, kDepthValueTransparent);
|
||||
|
||||
_opaqueFramebuffer.SwapColourBuffer(_mixFramebuffer);
|
||||
// Change binding to guarantee no undefined behavior
|
||||
@@ -59,7 +59,7 @@ void SwapFramebuffer::ApplyTransparency(ApplyTransparencyShader& shader, GLuint
|
||||
void SwapFramebuffer::Clear()
|
||||
{
|
||||
_opaqueFramebuffer.Bind();
|
||||
glClearBufferfv(GL_DEPTH, 0, kDepthValue);
|
||||
glCall(glClearBufferfv, GL_DEPTH, 0, kDepthValue);
|
||||
}
|
||||
|
||||
#endif /* DISABLE_OPENGL */
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace OpenRCT2::Ui
|
||||
OpenGLFramebuffer _opaqueFramebuffer;
|
||||
OpenGLFramebuffer _transparentFramebuffer;
|
||||
OpenGLFramebuffer _mixFramebuffer;
|
||||
GLuint _backDepth;
|
||||
GLuint _backDepth{};
|
||||
|
||||
public:
|
||||
SwapFramebuffer(int32_t width, int32_t height);
|
||||
|
||||
@@ -160,40 +160,41 @@ void TextureCache::CreateTextures()
|
||||
if (!_initialized)
|
||||
{
|
||||
// Determine width and height to use for texture atlases
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &_atlasesTextureDimensions);
|
||||
glCall(glGetIntegerv, GL_MAX_TEXTURE_SIZE, &_atlasesTextureDimensions);
|
||||
if (_atlasesTextureDimensions > kTextureCacheMaxAtlasSize)
|
||||
{
|
||||
_atlasesTextureDimensions = kTextureCacheMaxAtlasSize;
|
||||
}
|
||||
|
||||
// Determine maximum number of atlases (minimum of size and array limit)
|
||||
glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &_atlasesTextureIndicesLimit);
|
||||
glCall(glGetIntegerv, GL_MAX_ARRAY_TEXTURE_LAYERS, &_atlasesTextureIndicesLimit);
|
||||
if (_atlasesTextureDimensions < _atlasesTextureIndicesLimit)
|
||||
_atlasesTextureIndicesLimit = _atlasesTextureDimensions;
|
||||
|
||||
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);
|
||||
glCall(glGenTextures, 1, &_atlasesTexture);
|
||||
glCall(glBindTexture, GL_TEXTURE_2D_ARRAY, _atlasesTexture);
|
||||
glCall(glTexParameteri, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glCall(glTexParameteri, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glCall(glPixelStorei, GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
glGenTextures(1, &_paletteTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, _paletteTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glCall(glGenTextures, 1, &_paletteTexture);
|
||||
glCall(glBindTexture, GL_TEXTURE_2D, _paletteTexture);
|
||||
glCall(glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glCall(glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glCall(glPixelStorei, GL_UNPACK_ALIGNMENT, 1);
|
||||
GeneratePaletteTexture();
|
||||
|
||||
auto blendArray = GetBlendColourMap();
|
||||
if (blendArray != nullptr)
|
||||
{
|
||||
glGenTextures(1, &_blendPaletteTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, _blendPaletteTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D, 0, GL_R8UI, kGamePaletteSize, kGamePaletteSize, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, blendArray);
|
||||
glCall(glGenTextures, 1, &_blendPaletteTexture);
|
||||
glCall(glBindTexture, GL_TEXTURE_2D, _blendPaletteTexture);
|
||||
glCall(glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glCall(glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glCall(glPixelStorei, GL_UNPACK_ALIGNMENT, 1);
|
||||
glCall(
|
||||
glTexImage2D, GL_TEXTURE_2D, 0, GL_R8UI, kGamePaletteSize, kGamePaletteSize, 0, GL_RED_INTEGER,
|
||||
GL_UNSIGNED_BYTE, blendArray);
|
||||
}
|
||||
|
||||
_initialized = true;
|
||||
@@ -230,8 +231,8 @@ void TextureCache::GeneratePaletteTexture()
|
||||
}
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, _paletteTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8UI, width, height, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, rt.bits);
|
||||
glCall(glBindTexture, GL_TEXTURE_2D, _paletteTexture);
|
||||
glCall(glTexImage2D, GL_TEXTURE_2D, 0, GL_R8UI, width, height, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, rt.bits);
|
||||
DeleteDPI(rt);
|
||||
}
|
||||
|
||||
@@ -249,23 +250,23 @@ void TextureCache::EnlargeAtlasesTexture(GLuint newEntries)
|
||||
oldPixels.resize(_atlasesTextureDimensions * _atlasesTextureDimensions * _atlasesTextureCapacity);
|
||||
if (!oldPixels.empty())
|
||||
{
|
||||
glGetTexImage(GL_TEXTURE_2D_ARRAY, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, oldPixels.data());
|
||||
glCall(glGetTexImage, GL_TEXTURE_2D_ARRAY, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, oldPixels.data());
|
||||
}
|
||||
|
||||
// Initial capacity will be 12 which covers most cases of a fully visible park.
|
||||
_atlasesTextureCapacity = (_atlasesTextureCapacity + 6) << 1uL;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasesTexture);
|
||||
glTexImage3D(
|
||||
GL_TEXTURE_2D_ARRAY, 0, GL_R8UI, _atlasesTextureDimensions, _atlasesTextureDimensions, _atlasesTextureCapacity, 0,
|
||||
GL_RED_INTEGER, GL_UNSIGNED_BYTE, nullptr);
|
||||
glCall(glBindTexture, GL_TEXTURE_2D_ARRAY, _atlasesTexture);
|
||||
glCall(
|
||||
glTexImage3D, GL_TEXTURE_2D_ARRAY, 0, GL_R8UI, _atlasesTextureDimensions, _atlasesTextureDimensions,
|
||||
_atlasesTextureCapacity, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, nullptr);
|
||||
|
||||
// Restore old data
|
||||
if (!oldPixels.empty())
|
||||
{
|
||||
glTexSubImage3D(
|
||||
GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, _atlasesTextureDimensions, _atlasesTextureDimensions, _atlasesTextureIndices,
|
||||
GL_RED_INTEGER, GL_UNSIGNED_BYTE, oldPixels.data());
|
||||
glCall(
|
||||
glTexSubImage3D, GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, _atlasesTextureDimensions, _atlasesTextureDimensions,
|
||||
_atlasesTextureIndices, GL_RED_INTEGER, GL_UNSIGNED_BYTE, oldPixels.data());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,10 +280,10 @@ AtlasTextureInfo TextureCache::LoadImageTexture(const ImageId imageId)
|
||||
auto cacheInfo = AllocateImage(rt.width, rt.height);
|
||||
cacheInfo.image = imageId.GetIndex();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasesTexture);
|
||||
glTexSubImage3D(
|
||||
GL_TEXTURE_2D_ARRAY, 0, cacheInfo.bounds.x, cacheInfo.bounds.y, cacheInfo.index, rt.width, rt.height, 1, GL_RED_INTEGER,
|
||||
GL_UNSIGNED_BYTE, rt.bits);
|
||||
glCall(glBindTexture, GL_TEXTURE_2D_ARRAY, _atlasesTexture);
|
||||
glCall(
|
||||
glTexSubImage3D, GL_TEXTURE_2D_ARRAY, 0, cacheInfo.bounds.x, cacheInfo.bounds.y, cacheInfo.index, rt.width, rt.height,
|
||||
1, GL_RED_INTEGER, GL_UNSIGNED_BYTE, rt.bits);
|
||||
|
||||
DeleteDPI(rt);
|
||||
|
||||
@@ -296,10 +297,10 @@ AtlasTextureInfo TextureCache::LoadGlyphTexture(const ImageId imageId, const Pal
|
||||
auto cacheInfo = AllocateImage(rt.width, rt.height);
|
||||
cacheInfo.image = imageId.GetIndex();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasesTexture);
|
||||
glTexSubImage3D(
|
||||
GL_TEXTURE_2D_ARRAY, 0, cacheInfo.bounds.x, cacheInfo.bounds.y, cacheInfo.index, rt.width, rt.height, 1, GL_RED_INTEGER,
|
||||
GL_UNSIGNED_BYTE, rt.bits);
|
||||
glCall(glBindTexture, GL_TEXTURE_2D_ARRAY, _atlasesTexture);
|
||||
glCall(
|
||||
glTexSubImage3D, GL_TEXTURE_2D_ARRAY, 0, cacheInfo.bounds.x, cacheInfo.bounds.y, cacheInfo.index, rt.width, rt.height,
|
||||
1, GL_RED_INTEGER, GL_UNSIGNED_BYTE, rt.bits);
|
||||
|
||||
DeleteDPI(rt);
|
||||
|
||||
@@ -310,10 +311,10 @@ AtlasTextureInfo TextureCache::LoadBitmapTexture(ImageIndex image, const void* p
|
||||
{
|
||||
auto cacheInfo = AllocateImage(int32_t(width), int32_t(height));
|
||||
cacheInfo.image = image;
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasesTexture);
|
||||
glTexSubImage3D(
|
||||
GL_TEXTURE_2D_ARRAY, 0, cacheInfo.bounds.x, cacheInfo.bounds.y, cacheInfo.index, GLsizei(width), GLsizei(height), 1,
|
||||
GL_RED_INTEGER, GL_UNSIGNED_BYTE, reinterpret_cast<const GLvoid*>(pixels));
|
||||
glCall(glBindTexture, GL_TEXTURE_2D_ARRAY, _atlasesTexture);
|
||||
glCall(
|
||||
glTexSubImage3D, GL_TEXTURE_2D_ARRAY, 0, cacheInfo.bounds.x, cacheInfo.bounds.y, cacheInfo.index, GLsizei(width),
|
||||
GLsizei(height), 1, GL_RED_INTEGER, GL_UNSIGNED_BYTE, reinterpret_cast<const GLvoid*>(pixels));
|
||||
return cacheInfo;
|
||||
}
|
||||
|
||||
@@ -380,7 +381,7 @@ RenderTarget TextureCache::GetGlyphAsDPI(const ImageId imageId, const PaletteMap
|
||||
void TextureCache::FreeTextures()
|
||||
{
|
||||
// Free array texture
|
||||
glDeleteTextures(1, &_atlasesTexture);
|
||||
glCall(glDeleteTextures, 1, &_atlasesTexture);
|
||||
_textureCache.clear();
|
||||
std::fill(_indexMap.begin(), _indexMap.end(), kUnusedIndex);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user