mirror of
https://github.com/Almamu/linux-wallpaperengine.git
synced 2025-07-16 14:22:24 +08:00
Fixes issue #59's origial issue
This commit is contained in:
parent
131801b7f0
commit
c11c6928ea
@ -1,5 +1,6 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xatom.h>
|
||||||
#include <X11/extensions/Xrandr.h>
|
#include <X11/extensions/Xrandr.h>
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
@ -76,8 +77,8 @@ void CContext::initializeViewports ()
|
|||||||
|
|
||||||
XRRFreeScreenResources (screenResources);
|
XRRFreeScreenResources (screenResources);
|
||||||
|
|
||||||
// set the
|
// Cause of issue for issue #59 origial issue
|
||||||
glfwWindowHintPointer (GLFW_NATIVE_PARENT_HANDLE, reinterpret_cast <void*> (DefaultRootWindow (display)));
|
// glfwWindowHintPointer (GLFW_NATIVE_PARENT_HANDLE, reinterpret_cast <void*> (DefaultRootWindow (display)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CContext::render ()
|
void CContext::render ()
|
||||||
@ -87,19 +88,35 @@ void CContext::render ()
|
|||||||
|
|
||||||
if (this->m_viewports.empty () == false)
|
if (this->m_viewports.empty () == false)
|
||||||
{
|
{
|
||||||
|
static Display* display = XOpenDisplay (nullptr);
|
||||||
bool firstFrame = true;
|
bool firstFrame = true;
|
||||||
bool renderFrame = true;
|
bool renderFrame = true;
|
||||||
auto cur = this->m_viewports.begin ();
|
auto cur = this->m_viewports.begin ();
|
||||||
auto end = this->m_viewports.end ();
|
auto end = this->m_viewports.end ();
|
||||||
|
|
||||||
|
Window root = DefaultRootWindow(display);
|
||||||
|
int windowWidth = 1920, windowHeight = 1080;
|
||||||
|
int fullWidth = DisplayWidth (display, DefaultScreen (display));
|
||||||
|
int fullHeight = DisplayHeight (display, DefaultScreen (display));
|
||||||
|
|
||||||
|
Pixmap pm = XCreatePixmap(display, root, fullWidth, fullHeight, 24);
|
||||||
|
GC gc = XCreateGC(display, pm, 0, NULL);
|
||||||
|
XFillRectangle(display, pm, gc, 0, 0, fullWidth, fullHeight);
|
||||||
|
|
||||||
|
char* image_data = this->m_wallpaper->renderImage (*cur, renderFrame, firstFrame);
|
||||||
|
XImage* image = XCreateImage(display, CopyFromParent, 24, ZPixmap, 0, (char *)image_data, windowWidth, windowHeight, 32, 0);
|
||||||
for (; cur != end; cur ++)
|
for (; cur != end; cur ++)
|
||||||
{
|
{
|
||||||
this->m_wallpaper->render (*cur, renderFrame, firstFrame);
|
XPutImage(display, pm, gc, image, 0, 0, (*cur).x, (*cur).y, windowWidth, windowHeight);
|
||||||
// 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 <CVideo> ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XSetWindowBackgroundPixmap(display, root, pm);
|
||||||
|
XClearWindow(display, root);
|
||||||
|
XFlush(display);
|
||||||
|
|
||||||
|
XDestroyImage(image);
|
||||||
|
XFreePixmap(display, pm);
|
||||||
|
XFreeGC(display, gc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
this->m_wallpaper->render (this->m_defaultViewport);
|
this->m_wallpaper->render (this->m_defaultViewport);
|
||||||
|
@ -287,6 +287,131 @@ void CWallpaper::render (glm::vec4 viewport, bool renderFrame, bool newFrame)
|
|||||||
glDrawArrays (GL_TRIANGLES, 0, 6);
|
glDrawArrays (GL_TRIANGLES, 0, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* CWallpaper::renderImage (glm::vec4 viewport, bool renderFrame, bool newFrame)
|
||||||
|
{
|
||||||
|
if (renderFrame == true)
|
||||||
|
this->renderFrame (viewport);
|
||||||
|
|
||||||
|
int windowWidth = 1920;
|
||||||
|
int windowHeight = 1080;
|
||||||
|
|
||||||
|
if (this->getWallpaperData ()->is <WallpaperEngine::Core::CScene> ())
|
||||||
|
{
|
||||||
|
auto projection = this->getWallpaperData ()->as <WallpaperEngine::Core::CScene> ()->getOrthogonalProjection ();
|
||||||
|
|
||||||
|
windowWidth = projection->getWidth ();
|
||||||
|
windowHeight = projection->getHeight ();
|
||||||
|
}
|
||||||
|
else if (this->is <WallpaperEngine::Render::CVideo> ())
|
||||||
|
{
|
||||||
|
auto video = this->as <WallpaperEngine::Render::CVideo> ();
|
||||||
|
|
||||||
|
windowWidth = video->getWidth ();
|
||||||
|
windowHeight = video->getHeight ();
|
||||||
|
}
|
||||||
|
|
||||||
|
float widthRatio = windowWidth / viewport.z;
|
||||||
|
float heightRatio = windowHeight / viewport.w;
|
||||||
|
|
||||||
|
if (widthRatio > 1.0f)
|
||||||
|
{
|
||||||
|
float diff = widthRatio - 1.0f;
|
||||||
|
|
||||||
|
widthRatio -= diff;
|
||||||
|
heightRatio -= diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (heightRatio > 1.0f)
|
||||||
|
{
|
||||||
|
float diff = heightRatio - 1.0f;
|
||||||
|
|
||||||
|
widthRatio -= diff;
|
||||||
|
heightRatio -= diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
glBindBuffer (GL_ARRAY_BUFFER, this->m_positionBuffer);
|
||||||
|
glBufferData (GL_ARRAY_BUFFER, sizeof (position), position, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
// Need to flip the image (FB stores the image upside down)
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
glBindBuffer (GL_ARRAY_BUFFER, this->m_texCoordBuffer);
|
||||||
|
glBufferData (GL_ARRAY_BUFFER, sizeof (texCoords), texCoords, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glViewport (viewport.x, viewport.y, viewport.z, viewport.w);
|
||||||
|
|
||||||
|
// A fbo for flipping the image. Without this call the image will be flipped.
|
||||||
|
static CFBO* screen_fbo = this->createFBO ("_sc_FullFrameBuffer", ITexture::TextureFormat::ARGB8888, 1.0, windowWidth, windowHeight, windowWidth, windowHeight);
|
||||||
|
|
||||||
|
glBindFramebuffer (GL_FRAMEBUFFER, screen_fbo->getFramebuffer());
|
||||||
|
|
||||||
|
if (newFrame == true)
|
||||||
|
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
glDisable (GL_BLEND);
|
||||||
|
glDisable (GL_DEPTH_TEST);
|
||||||
|
// do not use any shader
|
||||||
|
glUseProgram (this->m_shader);
|
||||||
|
// activate scene texture
|
||||||
|
glActiveTexture (GL_TEXTURE0);
|
||||||
|
glBindTexture (GL_TEXTURE_2D, this->getWallpaperTexture ());
|
||||||
|
// set uniforms and attribs
|
||||||
|
glEnableVertexAttribArray (this->a_TexCoord);
|
||||||
|
glBindBuffer (GL_ARRAY_BUFFER, this->m_texCoordBuffer);
|
||||||
|
glVertexAttribPointer (this->a_TexCoord, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray (this->a_Position);
|
||||||
|
glBindBuffer (GL_ARRAY_BUFFER, this->m_positionBuffer);
|
||||||
|
glVertexAttribPointer (this->a_Position, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||||
|
|
||||||
|
glUniform1i (this->g_Texture0, 0);
|
||||||
|
// write the framebuffer as is to the screen
|
||||||
|
glBindBuffer (GL_ARRAY_BUFFER, this->m_texCoordBuffer);
|
||||||
|
glDrawArrays (GL_TRIANGLES, 0, 6);
|
||||||
|
|
||||||
|
glBindTexture (GL_TEXTURE_2D, screen_fbo->getTextureID ());
|
||||||
|
|
||||||
|
// Get FB data from OpenGL, X11 will free this pointer when it is created into an XImage.
|
||||||
|
char* image;
|
||||||
|
image = (char*)malloc(windowWidth*windowHeight*4);
|
||||||
|
glReadPixels(0, 0, 1920, 1080, GL_BGRA, GL_UNSIGNED_BYTE, (void*)(image));
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
void CWallpaper::setupFramebuffers ()
|
void CWallpaper::setupFramebuffers ()
|
||||||
{
|
{
|
||||||
int windowWidth = 1920;
|
int windowWidth = 1920;
|
||||||
|
@ -33,6 +33,11 @@ namespace WallpaperEngine::Render
|
|||||||
*/
|
*/
|
||||||
void render (glm::vec4 viewport, bool renderFrame = true, bool newFrame = true);
|
void render (glm::vec4 viewport, bool renderFrame = true, bool newFrame = true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a render pass of the wallpaper and returns the char* of the image
|
||||||
|
*/
|
||||||
|
char* renderImage (glm::vec4 viewport, bool renderFrame = true, bool newFrame = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The container to resolve files for this wallpaper
|
* @return The container to resolve files for this wallpaper
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user