Skip to content

Commit

Permalink
Move global shader related variables to new ShaderCache singleton
Browse files Browse the repository at this point in the history
This fixes crash at exit now that SDL is a Singleton, too.
  • Loading branch information
jhasse committed Dec 11, 2024
1 parent 954b667 commit fa1a14d
Show file tree
Hide file tree
Showing 17 changed files with 266 additions and 228 deletions.
8 changes: 6 additions & 2 deletions src/App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,13 @@ void App::atExit(std::function<void()> f) {
void App::callAtExitFunctions() {
auto tmp = std::move(callAtExit);
assert(callAtExit.empty());
for (const auto& f : tmp) {
f();

// destroy Singletons in the reverse order that they were created:
const auto end = tmp.rend();
for (auto it = tmp.rbegin(); it != end; ++it) {
(*it)();
}

if (!callAtExit.empty()) {
internal::warn("The destructor of a Singleton caused the creation of another Singleton. "
"Use handleIfAlive inside of destructors of Singletons.");
Expand Down
119 changes: 119 additions & 0 deletions src/ShaderCache.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// Copyright 2024 Jan Niklas Hasse <[email protected]>
// For conditions of distribution and use, see copyright notice in LICENSE.txt
#include "ShaderCache.hpp"

#include "jngl/Shader.hpp"
#include "opengl.hpp"
#include "spriteimpl.hpp"

#include <cassert>

namespace jngl {

ShaderCache::ShaderCache() {
Shader vertexShader(R"(#version 300 es
in mediump vec2 position;
uniform highp mat3 modelview;
uniform mediump mat4 projection;
void main() {
vec3 tmp = modelview * vec3(position, 1);
gl_Position = projection * vec4(tmp.x, tmp.y, 0, 1);
})",
Shader::Type::VERTEX, R"(#version 100
attribute mediump vec2 position;
uniform highp mat3 modelview;
uniform mediump mat4 projection;
void main() {
vec3 tmp = modelview * vec3(position, 1);
gl_Position = projection * vec4(tmp.x, tmp.y, 0, 1);
})");
Shader fragmentShader(R"(#version 300 es
uniform lowp vec4 color;
out lowp vec4 outColor;
void main() {
outColor = color;
})",
Shader::Type::FRAGMENT, R"(#version 100
uniform lowp vec4 color;
void main() {
gl_FragColor = color;
})");
simpleShaderProgram = std::make_unique<ShaderProgram>(vertexShader, fragmentShader);
simpleModelviewUniform = simpleShaderProgram->getUniformLocation("modelview");
simpleColorUniform = simpleShaderProgram->getUniformLocation("color");

{
textureVertexShader = std::make_unique<Shader>(R"(#version 300 es
in mediump vec2 position;
in mediump vec2 inTexCoord;
uniform highp mat3 modelview;
uniform mediump mat4 projection;
out mediump vec2 texCoord;
void main() {
vec3 tmp = modelview * vec3(position, 1);
gl_Position = projection * vec4(tmp.x, tmp.y, 0, 1);
texCoord = inTexCoord;
})",
Shader::Type::VERTEX, R"(#version 100
attribute mediump vec2 position;
attribute mediump vec2 inTexCoord;
uniform highp mat3 modelview;
uniform mediump mat4 projection;
varying mediump vec2 texCoord;
void main() {
vec3 tmp = modelview * vec3(position, 1);
gl_Position = projection * vec4(tmp.x, tmp.y, 0, 1);
texCoord = inTexCoord;
})");
Shader fragmentShader(R"(#version 300 es
uniform sampler2D tex;
uniform lowp vec4 spriteColor;
in mediump vec2 texCoord;
out lowp vec4 outColor;
void main() {
outColor = texture(tex, texCoord) * spriteColor;
})",
Shader::Type::FRAGMENT, R"(#version 100
uniform sampler2D tex;
uniform lowp vec4 spriteColor;
varying mediump vec2 texCoord;
void main() {
gl_FragColor = texture2D(tex, texCoord) * spriteColor;
})");
textureShaderProgram =
std::make_unique<ShaderProgram>(*textureVertexShader, fragmentShader);
shaderSpriteColorUniform = textureShaderProgram->getUniformLocation("spriteColor");
modelviewUniform = textureShaderProgram->getUniformLocation("modelview");
}
}

ShaderCache::~ShaderCache() = default;

ShaderProgram::Context ShaderCache::useSimpleShaderProgram() {
return useSimpleShaderProgram(opengl::modelview, gShapeColor);
}

ShaderProgram::Context ShaderCache::useSimpleShaderProgram(const Mat3& modelview, Rgba color) {
auto context = simpleShaderProgram->use();
glUniform4f(simpleColorUniform, color.getRed(), color.getGreen(), color.getBlue(),
color.getAlpha());
glUniformMatrix3fv(simpleModelviewUniform, 1, GL_FALSE, modelview.data);

assert(simpleShaderProgram->getAttribLocation("position") == 0);
glEnableVertexAttribArray(0);

return context;
}

} // namespace jngl
32 changes: 32 additions & 0 deletions src/ShaderCache.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2024 Jan Niklas Hasse <[email protected]>
// For conditions of distribution and use, see copyright notice in LICENSE.txt
#pragma once

#include "jngl/Rgba.hpp"
#include "jngl/ShaderProgram.hpp"
#include "jngl/Singleton.hpp"

namespace jngl {

class Mat3;

class ShaderCache : public Singleton<ShaderCache> {
public:
ShaderCache();
~ShaderCache();

ShaderProgram::Context useSimpleShaderProgram();
ShaderProgram::Context useSimpleShaderProgram(const Mat3& modelview, Rgba color);

std::unique_ptr<Shader> textureVertexShader;
std::unique_ptr<ShaderProgram> textureShaderProgram;
int shaderSpriteColorUniform;
int modelviewUniform;

private:
std::unique_ptr<ShaderProgram> simpleShaderProgram;
int simpleModelviewUniform;
int simpleColorUniform;
};

} // namespace jngl
3 changes: 3 additions & 0 deletions src/TextureCache.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

namespace jngl {

class Sprite;
class Texture;

class TextureCache : public Singleton<TextureCache> {
Expand All @@ -16,6 +17,8 @@ class TextureCache : public Singleton<TextureCache> {
void insert(std::string_view filename, std::shared_ptr<Texture>);
void remove(std::string_view filename);

std::unordered_map<std::string, std::shared_ptr<Sprite>> sprites;

private:
// https://www.cppstories.com/2021/heterogeneous-access-cpp20/
struct string_hash {
Expand Down
13 changes: 7 additions & 6 deletions src/freetype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#define _LIBCPP_DISABLE_DEPRECATION_WARNINGS
#include "freetype.hpp"

#include "ShaderCache.hpp"
#include "helper.hpp"
#include "jngl/ScaleablePixels.hpp"
#include "jngl/matrix.hpp"
Expand Down Expand Up @@ -92,7 +93,7 @@ Character::Character(const char32_t ch, const unsigned int fontHeight, FT_Face f

void Character::draw(Mat3& modelview) const {
if (texture_) {
glUniformMatrix3fv(Texture::modelviewUniform, 1, GL_FALSE,
glUniformMatrix3fv(ShaderCache::handle().modelviewUniform, 1, GL_FALSE,
Mat3(modelview).translate(left_, top_).data);
texture_->draw();
}
Expand Down Expand Up @@ -241,8 +242,8 @@ void FontImpl::setLineHeight(Pixels h) {
}

void FontImpl::print(Mat3 modelview, const std::string& text, Rgba color) {
auto context = Texture::textureShaderProgram->use();
glUniform4f(Texture::shaderSpriteColorUniform, color.getRed(), color.getGreen(),
auto context = ShaderCache::handle().textureShaderProgram->use();
glUniform4f(ShaderCache::handle().shaderSpriteColorUniform, color.getRed(), color.getGreen(),
color.getBlue(), color.getAlpha());
std::vector<std::string> lines(splitlines(text));

Expand All @@ -262,9 +263,9 @@ void FontImpl::print(Mat3 modelview, const std::string& text, Rgba color) {
}

void FontImpl::print(const ScaleablePixels x, const ScaleablePixels y, const std::string& text) {
auto context = Texture::textureShaderProgram->use();
glUniform4f(Texture::shaderSpriteColorUniform, gFontColor.getRed(), gFontColor.getGreen(),
gFontColor.getBlue(), gFontColor.getAlpha());
auto context = ShaderCache::handle().textureShaderProgram->use();
glUniform4f(ShaderCache::handle().shaderSpriteColorUniform, gFontColor.getRed(),
gFontColor.getGreen(), gFontColor.getBlue(), gFontColor.getAlpha());
const int xRounded = static_cast<int>(std::lround(static_cast<double>(Pixels{ x })));
const int yRounded = static_cast<int>(std::lround(static_cast<double>(Pixels{ y })));
std::vector<std::string> lines(splitlines(text));
Expand Down
4 changes: 3 additions & 1 deletion src/freetype.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright 2007-2024 Jan Niklas Hasse <[email protected]>
// For conditions of distribution and use, see copyright notice in LICENSE.txt

#pragma once

#include "jngl/Pixels.hpp"
Expand All @@ -12,9 +11,12 @@
#include FT_STROKER_H

#include <map>
#include <memory>

namespace jngl {

class Finally;

constexpr double LINE_HEIGHT_FACOTR = 1. / .63;
extern Rgba gFontColor;

Expand Down
24 changes: 15 additions & 9 deletions src/jngl/FrameBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "FrameBuffer.hpp"

#include "../ShaderCache.hpp"
#include "../main.hpp"
#include "../spriteimpl.hpp"
#include "../texture.hpp"
Expand Down Expand Up @@ -105,31 +106,34 @@ void FrameBuffer::draw(const Vec2 position, const ShaderProgram* const shaderPro
jngl::translate(position);
opengl::scale(1, -1);
jngl::translate(0, -impl->height / getScaleFactor());
auto context = shaderProgram ? shaderProgram->use() : Texture::textureShaderProgram->use();
auto context =
shaderProgram ? shaderProgram->use() : ShaderCache::handle().textureShaderProgram->use();
if (shaderProgram) {
glUniformMatrix3fv(shaderProgram->getUniformLocation("modelview"), 1, GL_FALSE,
opengl::modelview.data);
} else {
glUniform4f(Texture::shaderSpriteColorUniform, gSpriteColor.getRed(),
glUniform4f(ShaderCache::handle().shaderSpriteColorUniform, gSpriteColor.getRed(),
gSpriteColor.getGreen(), gSpriteColor.getBlue(), gSpriteColor.getAlpha());
glUniformMatrix3fv(Texture::modelviewUniform, 1, GL_FALSE, opengl::modelview.data);
glUniformMatrix3fv(ShaderCache::handle().modelviewUniform, 1, GL_FALSE,
opengl::modelview.data);
}
impl->texture.draw();
popMatrix();
}

void FrameBuffer::draw(Mat3 modelview, const ShaderProgram* const shaderProgram) const {
auto context = shaderProgram ? shaderProgram->use() : Texture::textureShaderProgram->use();
auto context =
shaderProgram ? shaderProgram->use() : ShaderCache::handle().textureShaderProgram->use();
if (shaderProgram) {
glUniformMatrix3fv(shaderProgram->getUniformLocation("modelview"), 1, GL_FALSE,
modelview.scale(1, -1)
.translate({ -impl->width / getScaleFactor() / 2,
-impl->height / getScaleFactor() / 2 })
.data);
} else {
glUniform4f(Texture::shaderSpriteColorUniform, gSpriteColor.getRed(),
glUniform4f(ShaderCache::handle().shaderSpriteColorUniform, gSpriteColor.getRed(),
gSpriteColor.getGreen(), gSpriteColor.getBlue(), gSpriteColor.getAlpha());
glUniformMatrix3fv(Texture::modelviewUniform, 1, GL_FALSE,
glUniformMatrix3fv(ShaderCache::handle().modelviewUniform, 1, GL_FALSE,
modelview.scale(1, -1)
.translate({ -impl->width / getScaleFactor() / 2,
-impl->height / getScaleFactor() / 2 })
Expand All @@ -142,14 +146,16 @@ void FrameBuffer::drawMesh(const std::vector<Vertex>& vertexes,
const ShaderProgram* const shaderProgram) const {
pushMatrix();
scale(getScaleFactor());
auto context = shaderProgram ? shaderProgram->use() : Texture::textureShaderProgram->use();
auto context =
shaderProgram ? shaderProgram->use() : ShaderCache::handle().textureShaderProgram->use();
if (shaderProgram) {
glUniformMatrix3fv(shaderProgram->getUniformLocation("modelview"), 1, GL_FALSE,
opengl::modelview.data);
} else {
glUniform4f(Texture::shaderSpriteColorUniform, gSpriteColor.getRed(),
glUniform4f(ShaderCache::handle().shaderSpriteColorUniform, gSpriteColor.getRed(),
gSpriteColor.getGreen(), gSpriteColor.getBlue(), gSpriteColor.getAlpha());
glUniformMatrix3fv(Texture::modelviewUniform, 1, GL_FALSE, opengl::modelview.data);
glUniformMatrix3fv(ShaderCache::handle().modelviewUniform, 1, GL_FALSE,
opengl::modelview.data);
}
impl->texture.drawMesh(vertexes);
popMatrix();
Expand Down
5 changes: 3 additions & 2 deletions src/jngl/ImageData.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// Copyright 2021-2023 Jan Niklas Hasse <[email protected]>
// Copyright 2021-2024 Jan Niklas Hasse <[email protected]>
// For conditions of distribution and use, see copyright notice in LICENSE.txt
#include "ImageData.hpp"

#include "../helper.hpp"
#include "../jngl/debug.hpp"
#include "../main.hpp"
#include "Finally.hpp"
#include "debug.hpp"

#ifdef ANDROID
#include "../android/fopen.hpp"
Expand Down
2 changes: 1 addition & 1 deletion src/jngl/Video.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright 2018-2024 Jan Niklas Hasse <[email protected]>
// For conditions of distribution and use, see copyright notice in LICENSE.txt

#include "Video.hpp"

#include <stdexcept>
Expand All @@ -16,6 +15,7 @@
#include "../theoraplay/theoraplay.h"
#include "Channel.hpp"
#include "Shader.hpp"
#include "ShaderProgram.hpp"
#include "screen.hpp"
#include "time.hpp"

Expand Down
10 changes: 5 additions & 5 deletions src/jngl/shapes.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// Copyright 2012-2024 Jan Niklas Hasse <[email protected]>
// For conditions of distribution and use, see copyright notice in LICENSE.txt

#include "shapes.hpp"

#include "../main.hpp"
#include "../ShaderCache.hpp"
#include "../opengl.hpp"
#include "../spriteimpl.hpp"
#include "Alpha.hpp"
Expand Down Expand Up @@ -65,8 +64,8 @@ void drawEllipse(const Vec2 position, const float width, const float height,

void drawEllipse(Mat3 modelview, float width, float height, float startAngle) {
glBindVertexArray(opengl::vaoStream);
auto tmp =
useSimpleShaderProgram(modelview.scale(static_cast<float>(getScaleFactor())), gShapeColor);
auto tmp = ShaderCache::handle().useSimpleShaderProgram(
modelview.scale(static_cast<float>(getScaleFactor())), gShapeColor);
std::vector<float> vertexes;
vertexes.push_back(0.f);
vertexes.push_back(0.f);
Expand Down Expand Up @@ -101,7 +100,8 @@ void drawCircle(Mat3 modelview, const float radius, const Rgba color) {

void drawCircle(Mat3 modelview, const Rgba color) {
glBindVertexArray(opengl::vaoStream);
auto tmp = useSimpleShaderProgram(modelview.scale(static_cast<float>(getScaleFactor())), color);
auto tmp = ShaderCache::handle().useSimpleShaderProgram(
modelview.scale(static_cast<float>(getScaleFactor())), color);
// clang-format off
const static float vertexes[] = {
1.f, 0.f, 0.9951847f, 0.09801714f, 0.9807853f, 0.1950903f, 0.9569403f, 0.2902847f,
Expand Down
Loading

0 comments on commit fa1a14d

Please sign in to comment.