bool app::process_events(i_event_processing_context&) { bool didSome = false; try { didSome = pump_messages(); didSome = (do_io(neolib::yield_type::Sleep) || didSome); didSome = (do_process_events() || didSome); rendering_engine().render_now(); } catch (std::exception& e) { if (!halted()) { halt(); std::cerr << "neogfx::app::process_events: terminating with exception: " << e.what() << std::endl; iSurfaceManager->display_error_message(iName.empty() ? "Abnormal Program Termination" : "Abnormal Program Termination - " + iName, std::string("neogfx::app::process_events: terminating with exception: ") + e.what()); std::exit(EXIT_FAILURE); } } catch (...) { if (!halted()) { halt(); std::cerr << "neogfx::app::process_events: terminating with unknown exception" << std::endl; iSurfaceManager->display_error_message(iName.empty() ? "Abnormal Program Termination" : "Abnormal Program Termination - " + iName, "neogfx::app::process_events: terminating with unknown exception"); std::exit(EXIT_FAILURE); } } return didSome; }
app::~app() { rendering_engine().texture_manager().clear_textures(); iKeyboard->ungrab_keyboard(*this); iSystemCache.reset(); app* tp = this; app* np = nullptr; sFirstInstance.compare_exchange_strong(tp, np); }
sdl_window::~sdl_window() { close(); rendering_engine().destroy_context(*this); }
std::unique_ptr<i_native_graphics_context> sdl_window::create_graphics_context(const i_widget& aWidget) const { return std::unique_ptr<i_native_graphics_context>(new sdl_graphics_context(rendering_engine(), *this, aWidget)); }
void opengl_window::render() { if (iRendering || processing_event()) return; uint64_t now = app::instance().program_elapsed_ms(); if (iFrameRate != boost::none && now - iLastFrameTime < 1000 / *iFrameRate) return; if (!iEventHandler.native_window_ready_to_render()) return; rendering_check.trigger(); if (iInvalidatedRects.empty()) return; ++iFrameCounter; iRendering = true; iLastFrameTime = now; rendering.trigger(); rect invalidatedRect = *iInvalidatedRects.begin(); for (const auto& ir : iInvalidatedRects) { invalidatedRect = invalidatedRect.combine(ir); } iInvalidatedRects.clear(); invalidatedRect.cx = std::min(invalidatedRect.cx, surface_size().cx - invalidatedRect.x); invalidatedRect.cy = std::min(invalidatedRect.cy, surface_size().cy - invalidatedRect.y); static bool initialized = false; if (!initialized) { rendering_engine().initialize(); initialized = true; } activate_context(); glCheck(glViewport(0, 0, static_cast<GLsizei>(extents().cx), static_cast<GLsizei>(extents().cy))); glCheck(glMatrixMode(GL_PROJECTION)); glCheck(glLoadIdentity()); glCheck(glScalef(1.0, 1.0, 1.0)); glCheck(glMatrixMode(GL_MODELVIEW)); glCheck(glLoadIdentity()); const auto& logicalCoordinates = logical_coordinates(); glCheck(glOrtho(logicalCoordinates[0], logicalCoordinates[2], logicalCoordinates[1], logicalCoordinates[3], -1.0, 1.0)); glCheck(glEnableClientState(GL_VERTEX_ARRAY)); glCheck(glEnableClientState(GL_COLOR_ARRAY)); glCheck(glEnableClientState(GL_TEXTURE_COORD_ARRAY)); glCheck(glEnable(GL_TEXTURE_2D)); glCheck(glEnable(GL_MULTISAMPLE)); glCheck(glEnable(GL_BLEND)); if (iFrameBufferSize.cx < static_cast<double>(extents().cx) || iFrameBufferSize.cy < static_cast<double>(extents().cy)) { if (iFrameBufferSize != size{}) { glCheck(glDeleteRenderbuffers(1, &iDepthStencilBuffer)); glCheck(glDeleteTextures(1, &iFrameBufferTexture)); glCheck(glDeleteFramebuffers(1, &iFrameBuffer)); } iFrameBufferSize = size( iFrameBufferSize.cx < extents().cx ? extents().cx * 1.5f : iFrameBufferSize.cx, iFrameBufferSize.cy < extents().cy ? extents().cy * 1.5f : iFrameBufferSize.cy); glCheck(glGenFramebuffers(1, &iFrameBuffer)); glCheck(glBindFramebuffer(GL_FRAMEBUFFER, iFrameBuffer)); glCheck(glGenTextures(1, &iFrameBufferTexture)); glCheck(glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, iFrameBufferTexture)); glCheck(glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, static_cast<GLsizei>(iFrameBufferSize.cx), static_cast<GLsizei>(iFrameBufferSize.cy), true)); glCheck(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, iFrameBufferTexture, 0)); glCheck(glGenRenderbuffers(1, &iDepthStencilBuffer)); glCheck(glBindRenderbuffer(GL_RENDERBUFFER, iDepthStencilBuffer)); glCheck(glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, static_cast<GLsizei>(iFrameBufferSize.cx), static_cast<GLsizei>(iFrameBufferSize.cy))); glCheck(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, iDepthStencilBuffer)); glCheck(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, iDepthStencilBuffer)); } else { glCheck(glBindFramebuffer(GL_FRAMEBUFFER, iFrameBuffer)); glCheck(glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, iFrameBufferTexture)); glCheck(glBindRenderbuffer(GL_RENDERBUFFER, iDepthStencilBuffer)); } GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_NO_ERROR && status != GL_FRAMEBUFFER_COMPLETE) throw failed_to_create_framebuffer(status); glCheck(glBindFramebuffer(GL_FRAMEBUFFER, iFrameBuffer)); GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0 }; glCheck(glDrawBuffers(sizeof(drawBuffers) / sizeof(drawBuffers[0]), drawBuffers)); glCheck(iEventHandler.native_window_render(invalidatedRect)); glCheck(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0)); glCheck(glBindFramebuffer(GL_READ_FRAMEBUFFER, iFrameBuffer)); glCheck(glBlitFramebuffer(0, 0, static_cast<GLint>(extents().cx), static_cast<GLint>(extents().cy), 0, 0, static_cast<GLint>(extents().cx), static_cast<GLint>(extents().cy), GL_COLOR_BUFFER_BIT, GL_NEAREST)); display(); deactivate_context(); iRendering = false; rendering_finished.trigger(); }