#include #include #include #include namespace scwx { namespace qt { namespace gl { static const std::string logPrefix_ = "scwx::qt::gl::gl_context"; class GlContext::Impl { public: explicit Impl() : gl_ {}, shaderProgramMap_ {}, shaderProgramMutex_ {}, textureAtlas_ {GL_INVALID_INDEX}, textureMutex_ {} { } ~Impl() {} gl::OpenGLFunctions gl_; std::unordered_map, std::shared_ptr, scwx::util::hash>> shaderProgramMap_; std::mutex shaderProgramMutex_; GLuint textureAtlas_; std::mutex textureMutex_; }; GlContext::GlContext() : p(std::make_unique()) {} GlContext::~GlContext() = default; GlContext::GlContext(GlContext&&) noexcept = default; GlContext& GlContext::operator=(GlContext&&) noexcept = default; gl::OpenGLFunctions& GlContext::gl() { return p->gl_; } std::shared_ptr GlContext::GetShaderProgram(const std::string& vertexPath, const std::string& fragmentPath) { const std::pair key {vertexPath, fragmentPath}; std::shared_ptr shaderProgram; std::unique_lock lock(p->shaderProgramMutex_); auto it = p->shaderProgramMap_.find(key); if (it == p->shaderProgramMap_.end()) { shaderProgram = std::make_shared(p->gl_); shaderProgram->Load(vertexPath, fragmentPath); p->shaderProgramMap_[key] = shaderProgram; } else { shaderProgram = it->second; } return shaderProgram; } GLuint GlContext::GetTextureAtlas() { std::unique_lock lock(p->textureMutex_); auto& textureAtlas = util::TextureAtlas::Instance(); if (p->textureAtlas_ == GL_INVALID_INDEX || textureAtlas.NeedsBuffered()) { p->textureAtlas_ = textureAtlas.BufferAtlas(p->gl_); } return p->textureAtlas_; } } // namespace gl } // namespace qt } // namespace scwx