void opengl_window::destroying() { activate_context(); if (iFrameBufferSize != size{}) { glCheck(glDeleteRenderbuffers(1, &iDepthStencilBuffer)); glCheck(glDeleteTextures(1, &iFrameBufferTexture)); glCheck(glDeleteFramebuffers(1, &iFrameBuffer)); } deactivate_context(); }
void sdl_window::destroyed() { if (!iDestroyed) { iDestroyed = true; opengl_window::destroyed(); iNativeHandle = 0; } bool activateDefaultContext = true; while (!context_activation_stack().empty() && context_activation_stack().back() == this) { activateDefaultContext = false; deactivate_context(); } if (activateDefaultContext) do_activate_default_context(); }
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(); }