Fixed background scaling (should improve #81)

Added some more debug information for renderdoc

Signed-off-by: Alexis Maiquez <almamu@almamu.com>
This commit is contained in:
Alexis Maiquez 2022-11-06 12:48:55 +01:00
parent 087a0976ae
commit f4ccf40e14
6 changed files with 121 additions and 68 deletions

View File

@ -126,7 +126,7 @@ void CContext::initializeViewports ()
crtc->x, crtc->y, crtc->width, crtc->height crtc->x, crtc->y, crtc->width, crtc->height
}; };
this->m_viewports.push_back (viewport); this->m_viewports.push_back ({viewport, *cur});
XRRFreeCrtcInfo (crtc); XRRFreeCrtcInfo (crtc);
} }
@ -141,7 +141,7 @@ void CContext::initializeViewports ()
this->m_fbo = new CFBO( this->m_fbo = new CFBO(
"_sc_FullFrameBuffer", "_sc_FullFrameBuffer",
ITexture::TextureFormat::ARGB8888, ITexture::TextureFormat::ARGB8888,
ITexture::TextureFlags::NoInterpolation, ITexture::TextureFlags::NoFlags,
1.0, 1.0,
fullWidth, fullHeight, fullWidth, fullHeight,
fullWidth, fullHeight fullWidth, fullHeight
@ -188,12 +188,22 @@ void CContext::render ()
for (; cur != end; cur ++) 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 // 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 // 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 // but videos should only be rendered once per group of viewports
firstFrame = false; firstFrame = false;
renderFrame = !this->m_wallpaper->is <CVideo> (); renderFrame = !this->m_wallpaper->is <CVideo> ();
if (DEBUG)
glPopDebugGroup ();
} }
// read the full texture into the image // read the full texture into the image
@ -214,7 +224,7 @@ void CContext::render ()
XFlush(this->m_display); XFlush(this->m_display);
} }
else else
this->m_wallpaper->render (this->m_defaultViewport); this->m_wallpaper->render (this->m_defaultViewport, true);
} }
void CContext::setWallpaper (CWallpaper* wallpaper) void CContext::setWallpaper (CWallpaper* wallpaper)
@ -225,12 +235,12 @@ void CContext::setWallpaper (CWallpaper* wallpaper)
if (this->m_screens.empty () == false) if (this->m_screens.empty () == false)
{ {
GLfloat texCoords [] = { GLfloat texCoords [] = {
0.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 0.0f 1.0f, 0.0f
}; };
this->m_wallpaper->updateTexCoord (texCoords, sizeof (texCoords)); this->m_wallpaper->updateTexCoord (texCoords, sizeof (texCoords));

View File

@ -32,6 +32,12 @@ namespace WallpaperEngine::Render
const ITexture* resolveTexture (const std::string& name); const ITexture* resolveTexture (const std::string& name);
private: private:
struct viewport
{
glm::ivec4 viewport;
std::string name;
};
Display* m_display; Display* m_display;
Pixmap m_pixmap; Pixmap m_pixmap;
GC m_gc; GC m_gc;
@ -40,7 +46,7 @@ namespace WallpaperEngine::Render
char* m_imageData; char* m_imageData;
CFBO* m_fbo; CFBO* m_fbo;
std::vector <std::string> m_screens; std::vector <std::string> m_screens;
std::vector <glm::ivec4> m_viewports; std::vector <viewport> m_viewports;
glm::vec4 m_defaultViewport; glm::vec4 m_defaultViewport;
CWallpaper* m_wallpaper; CWallpaper* m_wallpaper;
CMouseInput* m_mouse; CMouseInput* m_mouse;

View File

@ -101,8 +101,8 @@ CVideo::CVideo (Core::CVideo* video, CContext* context) :
// configure the texture // configure the texture
glBindTexture (GL_TEXTURE_2D, this->m_texture); glBindTexture (GL_TEXTURE_2D, this->m_texture);
// set filtering parameters, otherwise the texture is not rendered // 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_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 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_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// set texture basic data // set texture basic data

View File

@ -199,79 +199,97 @@ void CWallpaper::setDestinationFramebuffer (GLuint framebuffer)
this->m_destFramebuffer = 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) if (renderFrame == true)
this->renderFrame (viewport); this->renderFrame (viewport);
int windowWidth = 1920; int projectionWidth = 1920;
int windowHeight = 1080; int projectionHeight = 1080;
if (this->getWallpaperData ()->is <WallpaperEngine::Core::CScene> ()) if (this->getWallpaperData ()->is <WallpaperEngine::Core::CScene> ())
{ {
auto projection = this->getWallpaperData ()->as <WallpaperEngine::Core::CScene> ()->getOrthogonalProjection (); auto projection = this->getWallpaperData ()->as <WallpaperEngine::Core::CScene> ()->getOrthogonalProjection ();
windowWidth = projection->getWidth (); projectionWidth = projection->getWidth ();
windowHeight = projection->getHeight (); projectionHeight = projection->getHeight ();
} }
else if (this->is <WallpaperEngine::Render::CVideo> ()) else if (this->is <WallpaperEngine::Render::CVideo> ())
{ {
auto video = this->as <WallpaperEngine::Render::CVideo> (); auto video = this->as <WallpaperEngine::Render::CVideo> ();
windowWidth = video->getWidth (); projectionWidth = video->getWidth ();
windowHeight = video->getHeight (); projectionHeight = video->getHeight ();
} }
float widthRatio = windowWidth / (float) viewport.z; float ustart = 0.0f;
float heightRatio = windowHeight / (float) viewport.w; 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; int newWidth = viewport.w / (float) projectionHeight * projectionWidth;
heightRatio -= diff; 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; int newHeight = viewport.z / (float) projectionWidth * projectionHeight;
heightRatio -= diff; 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) GLfloat texCoords [] = {
{ ustart, vstart,
float diff = 1.0f - widthRatio; uend, vstart,
ustart, vend,
widthRatio += diff; ustart, vend,
heightRatio += diff; uend, vstart,
} uend, vend,
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
}; };
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); glViewport (viewport.x, viewport.y, viewport.z, viewport.w);
glBindFramebuffer (GL_FRAMEBUFFER, this->m_destFramebuffer); glBindFramebuffer (GL_FRAMEBUFFER, this->m_destFramebuffer);
@ -289,6 +307,7 @@ void CWallpaper::render (glm::ivec4 viewport, bool renderFrame, bool newFrame)
// set uniforms and attribs // set uniforms and attribs
glEnableVertexAttribArray (this->a_TexCoord); glEnableVertexAttribArray (this->a_TexCoord);
glBindBuffer (GL_ARRAY_BUFFER, this->m_texCoordBuffer); 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); glVertexAttribPointer (this->a_TexCoord, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray (this->a_Position); glEnableVertexAttribArray (this->a_Position);
@ -303,22 +322,22 @@ void CWallpaper::render (glm::ivec4 viewport, bool renderFrame, bool newFrame)
void CWallpaper::setupFramebuffers () void CWallpaper::setupFramebuffers ()
{ {
int windowWidth = 1920; int projectionWidth = 1920;
int windowHeight = 1080; int projectionHeight = 1080;
if (this->getWallpaperData ()->is <WallpaperEngine::Core::CScene> ()) if (this->getWallpaperData ()->is <WallpaperEngine::Core::CScene> ())
{ {
auto projection = this->getWallpaperData ()->as <WallpaperEngine::Core::CScene> ()->getOrthogonalProjection (); auto projection = this->getWallpaperData ()->as <WallpaperEngine::Core::CScene> ()->getOrthogonalProjection ();
windowWidth = projection->getWidth (); projectionWidth = projection->getWidth ();
windowHeight = projection->getHeight (); projectionHeight = projection->getHeight ();
} }
else if (this->is <WallpaperEngine::Render::CVideo> ()) else if (this->is <WallpaperEngine::Render::CVideo> ())
{ {
auto video = this->as <WallpaperEngine::Render::CVideo> (); auto video = this->as <WallpaperEngine::Render::CVideo> ();
windowWidth = video->getWidth (); projectionWidth = video->getWidth ();
windowHeight = video->getHeight (); projectionHeight = video->getHeight ();
} }
// create framebuffer for the scene // create framebuffer for the scene
@ -327,8 +346,8 @@ void CWallpaper::setupFramebuffers ()
ITexture::TextureFormat::ARGB8888, ITexture::TextureFormat::ARGB8888,
ITexture::TextureFlags::NoInterpolation, ITexture::TextureFlags::NoInterpolation,
1.0, 1.0,
windowWidth, windowHeight, projectionWidth, projectionHeight,
windowWidth, windowHeight projectionWidth, projectionHeight
); );
} }

View File

@ -31,7 +31,7 @@ namespace WallpaperEngine::Render
/** /**
* Performs a render pass of the wallpaper * 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 * @return The container to resolve files for this wallpaper

View File

@ -401,6 +401,21 @@ void CImage::render ()
if (this->getScene ()->getScene ()->isCameraParallax () == true) if (this->getScene ()->getScene ()->isCameraParallax () == true)
this->updateScreenSpacePosition (); 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 cur = this->m_passes.begin ();
auto end = this->m_passes.end (); auto end = this->m_passes.end ();
@ -411,6 +426,9 @@ void CImage::render ()
(*cur)->render (); (*cur)->render ();
} }
if (DEBUG)
glPopDebugGroup ();
} }
void CImage::updateScreenSpacePosition () void CImage::updateScreenSpacePosition ()