#include "./opengl_renderer.hpp" #include #include #include #include #include #include #include #include "../opengl/res/default_texture.h" // data #include "../opengl/res/errig_texture.h" // data #include "mm/update_strategies/update_strategy.hpp" #include #ifndef MM_OPENGL_3_GLES #include #else #define TracyGpuContext #define TracyGpuCollect #endif //#define LOGRS_SDL(x) LOGRS(std::string(SDL_GetError()) + x) #include #define LOG_CRIT(...) __LOG_CRIT( "OpenGLRenderer", __VA_ARGS__) #define LOG_ERROR(...) __LOG_ERROR("OpenGLRenderer", __VA_ARGS__) #define LOG_WARN(...) __LOG_WARN( "OpenGLRenderer", __VA_ARGS__) #define LOG_INFO(...) __LOG_INFO( "OpenGLRenderer", __VA_ARGS__) #define LOG_DEBUG(...) __LOG_DEBUG("OpenGLRenderer", __VA_ARGS__) #define LOG_TRACE(...) __LOG_TRACE("OpenGLRenderer", __VA_ARGS__) namespace MM::Services { using namespace entt::literals; OpenGLRenderer::OpenGLRenderer(void) { MM::Logger::initSectionLogger("OpenGL"); MM::Logger::initSectionLogger("OpenGLRenderer"); } OpenGLRenderer::~OpenGLRenderer(void) { } bool OpenGLRenderer::enable(Engine& engine) { if (!engine.tryService()) { LOG_ERROR("OpenGLRenderer requires SDLService"); return false; } auto& sdl_s = engine.getService(); if (!sdl_s.win) { if (!sdl_s.createGLWindow("MushMachine (OpenGLRenderer)", 800, 600)) { LOG_ERROR("couldn't create window with gl context"); return false; } } else if (!sdl_s.gl_context) { if (!sdl_s.createGLContext()) { LOG_ERROR("couldn't create gl context"); return false; } } // "creating" display fbo { targets["display"].reset(new OpenGL::FrameBufferObject); targets["display"]->_fboID = 0; targets["display"]->_resize = false; // its done for us } _sdl_event_handle = sdl_s.addEventHandler([this, &engine](const SDL_Event& e) -> bool { if (e.type == SDL_WINDOWEVENT) { if (e.window.event == SDL_WINDOWEVENT_RESIZED || e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { auto& sdl = engine.getService(); auto new_window_size = sdl.getWindowSize(); glViewport(0, 0, new_window_size.first, new_window_size.second); // TODO: recreate fbos, dirvers seem to have problems otherwise //std::vector>> new_fbos; for (auto& map_entry : targets) { if (map_entry.second->_resize) { auto& fbo = map_entry.second; float new_width = fbo->_resize_factor_width * new_window_size.first; float new_height = fbo->_resize_factor_height * new_window_size.second; for (auto& tex : fbo->_texAttachments) { if (tex->height == new_height && tex->width == new_width) { continue; } tex->resize(static_cast(new_width), static_cast(new_height)); } //auto new_fbo = std::make_shared(); //auto new_fbo = OpenGL::FBOBuilder::start(). //new_fbos.emplace_back(map_entry.first, new_fbo); } } //if (!new_fbos.empty()) { //} } } return false; }); if (!_sdl_event_handle) { LOG_ERROR("couldn't add sdl event function!"); return false; } { // default texures auto& rm_t = MM::ResourceManager::ref(); if (!rm_t.contains("default"_hs)) { if (!rm_t.load("default", default_png, default_png_len)) { LOG_WARN("couldn't load 'default' texture!"); } } if (!rm_t.contains("errig"_hs)) { if (!rm_t.load("errig", errig_jpg, errig_jpg_len)) { LOG_WARN("couldn't load 'errig' texture!"); } } } return true; } void OpenGLRenderer::disable(Engine&) { // TODO: do we need this?? targets.clear(); render_tasks.clear(); // TODO: reallly? MM::ResourceManager::ref().clear(); } std::vector OpenGLRenderer::registerUpdates(void) { return { { "OpenGLRenderer::render"_hs, "OpenGLRenderer::render", [this](Engine& e){ this->render(e); }, UpdateStrategies::update_phase_t::POST } }; } void OpenGLRenderer::render(Engine& engine) { ZoneScopedN("MM::Services::OpenGLRenderer::render"); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); //targets["display"]->bind(FrameBufferObject::RW); //glClearColor(0.1f, 0.1f, 0.1f, 1.0f); //glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); targets["display"]->clear(0.1f, 0.1f, 0.1f, 1.0f, GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); for (auto& r : render_tasks) { r->render(*this, engine); } SDL_GL_SwapWindow(engine.getService().win); TracyGpuCollect; } } // namespace MM::Services