diff --git a/src/WallpaperEngine/Render/CContext.cpp b/src/WallpaperEngine/Render/CContext.cpp index 8948cd5..d18b399 100644 --- a/src/WallpaperEngine/Render/CContext.cpp +++ b/src/WallpaperEngine/Render/CContext.cpp @@ -126,7 +126,7 @@ void CContext::initializeViewports () crtc->x, crtc->y, crtc->width, crtc->height }; - this->m_viewports.push_back (viewport); + this->m_viewports.push_back ({viewport, *cur}); XRRFreeCrtcInfo (crtc); } @@ -141,7 +141,7 @@ void CContext::initializeViewports () this->m_fbo = new CFBO( "_sc_FullFrameBuffer", ITexture::TextureFormat::ARGB8888, - ITexture::TextureFlags::NoInterpolation, + ITexture::TextureFlags::NoFlags, 1.0, fullWidth, fullHeight, fullWidth, fullHeight @@ -188,12 +188,22 @@ void CContext::render () for (; cur != end; cur ++) { + if (DEBUG) + { + std::string str = "Rendering to screen " + (*cur).name; + + glPushDebugGroup (GL_DEBUG_SOURCE_APPLICATION, 0, -1, str.c_str ()); + } + // render the background - this->m_wallpaper->render (*cur, renderFrame, firstFrame); + this->m_wallpaper->render ((*cur).viewport, false, renderFrame, firstFrame); // scenes need to render a new frame for each viewport as they produce different results // but videos should only be rendered once per group of viewports firstFrame = false; renderFrame = !this->m_wallpaper->is (); + + if (DEBUG) + glPopDebugGroup (); } // read the full texture into the image @@ -214,7 +224,7 @@ void CContext::render () XFlush(this->m_display); } else - this->m_wallpaper->render (this->m_defaultViewport); + this->m_wallpaper->render (this->m_defaultViewport, true); } void CContext::setWallpaper (CWallpaper* wallpaper) @@ -225,12 +235,12 @@ void CContext::setWallpaper (CWallpaper* wallpaper) if (this->m_screens.empty () == false) { GLfloat texCoords [] = { - 0.0f, 1.0f, - 1.0f, 1.0f, - 0.0f, 0.0f, - 0.0f, 0.0f, - 1.0f, 1.0f, - 1.0f, 0.0f + 0.0f, 1.0f, + 1.0f, 1.0f, + 0.0f, 0.0f, + 0.0f, 0.0f, + 1.0f, 1.0f, + 1.0f, 0.0f }; this->m_wallpaper->updateTexCoord (texCoords, sizeof (texCoords)); diff --git a/src/WallpaperEngine/Render/CContext.h b/src/WallpaperEngine/Render/CContext.h index d0547aa..786dd9d 100644 --- a/src/WallpaperEngine/Render/CContext.h +++ b/src/WallpaperEngine/Render/CContext.h @@ -32,6 +32,12 @@ namespace WallpaperEngine::Render const ITexture* resolveTexture (const std::string& name); private: + struct viewport + { + glm::ivec4 viewport; + std::string name; + }; + Display* m_display; Pixmap m_pixmap; GC m_gc; @@ -40,7 +46,7 @@ namespace WallpaperEngine::Render char* m_imageData; CFBO* m_fbo; std::vector m_screens; - std::vector m_viewports; + std::vector m_viewports; glm::vec4 m_defaultViewport; CWallpaper* m_wallpaper; CMouseInput* m_mouse; diff --git a/src/WallpaperEngine/Render/CVideo.cpp b/src/WallpaperEngine/Render/CVideo.cpp index dd73d80..756533c 100644 --- a/src/WallpaperEngine/Render/CVideo.cpp +++ b/src/WallpaperEngine/Render/CVideo.cpp @@ -101,8 +101,8 @@ CVideo::CVideo (Core::CVideo* video, CContext* context) : // configure the texture glBindTexture (GL_TEXTURE_2D, this->m_texture); // set filtering parameters, otherwise the texture is not rendered - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // set texture basic data diff --git a/src/WallpaperEngine/Render/CWallpaper.cpp b/src/WallpaperEngine/Render/CWallpaper.cpp index 1612f6a..2fb05f5 100644 --- a/src/WallpaperEngine/Render/CWallpaper.cpp +++ b/src/WallpaperEngine/Render/CWallpaper.cpp @@ -199,79 +199,97 @@ void CWallpaper::setDestinationFramebuffer (GLuint framebuffer) this->m_destFramebuffer = framebuffer; } -void CWallpaper::render (glm::ivec4 viewport, bool renderFrame, bool newFrame) +void CWallpaper::render (glm::ivec4 viewport, bool vflip, bool renderFrame, bool newFrame) { if (renderFrame == true) this->renderFrame (viewport); - int windowWidth = 1920; - int windowHeight = 1080; + int projectionWidth = 1920; + int projectionHeight = 1080; if (this->getWallpaperData ()->is ()) { auto projection = this->getWallpaperData ()->as ()->getOrthogonalProjection (); - windowWidth = projection->getWidth (); - windowHeight = projection->getHeight (); + projectionWidth = projection->getWidth (); + projectionHeight = projection->getHeight (); } else if (this->is ()) { auto video = this->as (); - windowWidth = video->getWidth (); - windowHeight = video->getHeight (); + projectionWidth = video->getWidth (); + projectionHeight = video->getHeight (); } - float widthRatio = windowWidth / (float) viewport.z; - float heightRatio = windowHeight / (float) viewport.w; + float ustart = 0.0f; + float uend = 0.0f; + float vstart = 0.0f; + float vend = 0.0f; - if (widthRatio > 1.0f) + if ( + (viewport.w > viewport.z && projectionWidth >= projectionHeight) || + (viewport.z > viewport.w && projectionHeight > projectionWidth) + ) { - float diff = widthRatio - 1.0f; + if (vflip) + { + vstart = 0.0f; + vend = 1.0f; + } + else + { + vstart = 1.0f; + vend = 0.0f; + } - widthRatio -= diff; - heightRatio -= diff; + int newWidth = viewport.w / (float) projectionHeight * projectionWidth; + float newCenter = newWidth / 2.0f; + float viewportCenter = viewport.z / 2.0; + + float left = newCenter - viewportCenter; + float right = newCenter + viewportCenter; + + ustart = left / newWidth; + uend = right / newWidth; } - if (heightRatio > 1.0f) + if ( + (viewport.z > viewport.w && projectionWidth >= projectionHeight) || + (viewport.w > viewport.z && projectionHeight > projectionWidth) + ) { - float diff = heightRatio - 1.0f; + ustart = 0.0f; + uend = 1.0f; - widthRatio -= diff; - heightRatio -= diff; + int newHeight = viewport.z / (float) projectionWidth * projectionHeight; + float newCenter = newHeight / 2.0f; + float viewportCenter = viewport.w / 2.0; + + float down = newCenter - viewportCenter; + float up = newCenter + viewportCenter; + + if (vflip) + { + vstart = down / newHeight; + vend = up / newHeight; + } + else + { + vstart = up / newHeight; + vend = down / newHeight; + } } - if (widthRatio < 1.0f) - { - float diff = 1.0f - widthRatio; - - widthRatio += diff; - heightRatio += diff; - } - - if (heightRatio < 1.0f) - { - float diff = 1.0f - heightRatio; - - widthRatio += diff; - heightRatio += diff; - } - - if (widthRatio < 0.0f) widthRatio = -widthRatio; - if (heightRatio < 0.0f) heightRatio = -heightRatio; - - GLfloat position [] = { - -widthRatio, heightRatio, 0.0f, - widthRatio, heightRatio, 0.0f, - -widthRatio, -heightRatio, 0.0f, - -widthRatio, -heightRatio, 0.0f, - widthRatio, heightRatio, 0.0f, - widthRatio, -heightRatio, 0.0f + GLfloat texCoords [] = { + ustart, vstart, + uend, vstart, + ustart, vend, + ustart, vend, + uend, vstart, + uend, vend, }; - glBindBuffer (GL_ARRAY_BUFFER, this->m_positionBuffer); - glBufferData (GL_ARRAY_BUFFER, sizeof (position), position, GL_STATIC_DRAW); - glViewport (viewport.x, viewport.y, viewport.z, viewport.w); glBindFramebuffer (GL_FRAMEBUFFER, this->m_destFramebuffer); @@ -289,6 +307,7 @@ void CWallpaper::render (glm::ivec4 viewport, bool renderFrame, bool newFrame) // set uniforms and attribs glEnableVertexAttribArray (this->a_TexCoord); glBindBuffer (GL_ARRAY_BUFFER, this->m_texCoordBuffer); + glBufferData (GL_ARRAY_BUFFER, sizeof (texCoords), texCoords, GL_STATIC_DRAW); glVertexAttribPointer (this->a_TexCoord, 2, GL_FLOAT, GL_FALSE, 0, nullptr); glEnableVertexAttribArray (this->a_Position); @@ -303,22 +322,22 @@ void CWallpaper::render (glm::ivec4 viewport, bool renderFrame, bool newFrame) void CWallpaper::setupFramebuffers () { - int windowWidth = 1920; - int windowHeight = 1080; + int projectionWidth = 1920; + int projectionHeight = 1080; if (this->getWallpaperData ()->is ()) { auto projection = this->getWallpaperData ()->as ()->getOrthogonalProjection (); - windowWidth = projection->getWidth (); - windowHeight = projection->getHeight (); + projectionWidth = projection->getWidth (); + projectionHeight = projection->getHeight (); } else if (this->is ()) { auto video = this->as (); - windowWidth = video->getWidth (); - windowHeight = video->getHeight (); + projectionWidth = video->getWidth (); + projectionHeight = video->getHeight (); } // create framebuffer for the scene @@ -327,8 +346,8 @@ void CWallpaper::setupFramebuffers () ITexture::TextureFormat::ARGB8888, ITexture::TextureFlags::NoInterpolation, 1.0, - windowWidth, windowHeight, - windowWidth, windowHeight + projectionWidth, projectionHeight, + projectionWidth, projectionHeight ); } diff --git a/src/WallpaperEngine/Render/CWallpaper.h b/src/WallpaperEngine/Render/CWallpaper.h index dfa7471..b6329a7 100644 --- a/src/WallpaperEngine/Render/CWallpaper.h +++ b/src/WallpaperEngine/Render/CWallpaper.h @@ -31,7 +31,7 @@ namespace WallpaperEngine::Render /** * Performs a render pass of the wallpaper */ - void render (glm::ivec4 viewport, bool renderFrame = true, bool newFrame = true); + void render (glm::ivec4 viewport, bool vflip, bool renderFrame = true, bool newFrame = true); /** * @return The container to resolve files for this wallpaper diff --git a/src/WallpaperEngine/Render/Objects/CImage.cpp b/src/WallpaperEngine/Render/Objects/CImage.cpp index 61ce853..ab5e2b2 100644 --- a/src/WallpaperEngine/Render/Objects/CImage.cpp +++ b/src/WallpaperEngine/Render/Objects/CImage.cpp @@ -401,6 +401,21 @@ void CImage::render () if (this->getScene ()->getScene ()->isCameraParallax () == true) this->updateScreenSpacePosition (); + if (DEBUG) + { + std::string str = "Rendering "; + + if (this->getScene ()->getScene ()->isBloom () && this->getId () == 0xFFFFFFFF) + str += "bloom"; + else + { + str += this->getImage ()->getName () + + " (" + std::to_string (this->getId ()) + ", " + this->getImage ()->getMaterial ()->getName () + ")"; + } + + glPushDebugGroup (GL_DEBUG_SOURCE_APPLICATION, 0, -1, str.c_str ()); + } + auto cur = this->m_passes.begin (); auto end = this->m_passes.end (); @@ -411,6 +426,9 @@ void CImage::render () (*cur)->render (); } + + if (DEBUG) + glPopDebugGroup (); } void CImage::updateScreenSpacePosition ()