1
0
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:
Matt
2025-05-17 23:54:28 +03:00
committed by GitHub
parent e20824d1fa
commit 5d31e30434
15 changed files with 359 additions and 273 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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