mirror of
https://github.com/Almamu/linux-wallpaperengine.git
synced 2025-09-14 13:56:48 +08:00
~ reorganized context initialization so opengl is ready
~ moved pixmap, gc and image creation to the initialization TODO: SUPPORT SCREEN SIZE CHANGES (THIS MIGHT NEED REINITIALIZATION OF THINGS) ~ moved fbo creation to initialization as it won't change anymore ~ reverted render code to the original loop as now the framebuffer is exactly as big as the whole display ~ moved glReadPixels off the wallpaper as that's code is exclusively used for screen rendering and not general rendering ~ XChangeProperty forces the update of the background, otherwise the compositor stops refreshing the screen and the background gets stuck ~ updated viewport variables to be integers instead of floats ~ reverted frame rendering code to be simpler and added the option to specify a framebuffer as target instead of screen Signed-off-by: Alexis Maiquez <almamu@almamu.com>
This commit is contained in:
parent
a2222b05ef
commit
5bc0525493
14
main.cpp
14
main.cpp
@ -231,8 +231,6 @@ int main (int argc, char* argv[])
|
|||||||
// parse the project.json file
|
// parse the project.json file
|
||||||
auto project = WallpaperEngine::Core::CProject::fromFile ("project.json", containers);
|
auto project = WallpaperEngine::Core::CProject::fromFile ("project.json", containers);
|
||||||
WallpaperEngine::Render::CWallpaper* wallpaper;
|
WallpaperEngine::Render::CWallpaper* wallpaper;
|
||||||
// initialize custom context class
|
|
||||||
WallpaperEngine::Render::CContext* context = new WallpaperEngine::Render::CContext (screens);
|
|
||||||
|
|
||||||
// auto projection = project->getWallpaper ()->as <WallpaperEngine::Core::CScene> ()->getOrthogonalProjection ();
|
// auto projection = project->getWallpaper ()->as <WallpaperEngine::Core::CScene> ()->getOrthogonalProjection ();
|
||||||
// create the window!
|
// create the window!
|
||||||
@ -250,8 +248,6 @@ int main (int argc, char* argv[])
|
|||||||
// initialize inputs
|
// initialize inputs
|
||||||
CMouseInput* mouseInput = new CMouseInput (window);
|
CMouseInput* mouseInput = new CMouseInput (window);
|
||||||
|
|
||||||
context->setMouse (mouseInput);
|
|
||||||
|
|
||||||
glfwMakeContextCurrent (window);
|
glfwMakeContextCurrent (window);
|
||||||
|
|
||||||
// TODO: FIGURE THESE OUT BASED ON THE SCREEN
|
// TODO: FIGURE THESE OUT BASED ON THE SCREEN
|
||||||
@ -260,9 +256,8 @@ int main (int argc, char* argv[])
|
|||||||
|
|
||||||
// get the real framebuffer size
|
// get the real framebuffer size
|
||||||
glfwGetFramebufferSize (window, &windowWidth, &windowHeight);
|
glfwGetFramebufferSize (window, &windowWidth, &windowHeight);
|
||||||
// set the default viewport
|
|
||||||
context->setDefaultViewport ({0, 0, windowWidth, windowHeight});
|
|
||||||
|
|
||||||
|
// initialize glew
|
||||||
if (glewInit () != GLEW_OK)
|
if (glewInit () != GLEW_OK)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Failed to initialize GLEW");
|
fprintf (stderr, "Failed to initialize GLEW");
|
||||||
@ -270,6 +265,13 @@ int main (int argc, char* argv[])
|
|||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initialize custom context class
|
||||||
|
WallpaperEngine::Render::CContext* context = new WallpaperEngine::Render::CContext (screens);
|
||||||
|
// initialize mouse support
|
||||||
|
context->setMouse (mouseInput);
|
||||||
|
// set the default viewport
|
||||||
|
context->setDefaultViewport ({0, 0, windowWidth, windowHeight});
|
||||||
|
|
||||||
if (project->getType () == "scene")
|
if (project->getType () == "scene")
|
||||||
{
|
{
|
||||||
WallpaperEngine::Core::CScene* scene = project->getWallpaper ()->as <WallpaperEngine::Core::CScene> ();
|
WallpaperEngine::Core::CScene* scene = project->getWallpaper ()->as <WallpaperEngine::Core::CScene> ();
|
||||||
|
@ -25,27 +25,34 @@ void CContext::initializeViewports ()
|
|||||||
if (this->m_isRootWindow == false || this->m_screens.empty () == true)
|
if (this->m_isRootWindow == false || this->m_screens.empty () == true)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Display* display = XOpenDisplay (nullptr);
|
this->m_display = XOpenDisplay (nullptr);
|
||||||
|
|
||||||
int xrandr_result, xrandr_error;
|
int xrandr_result, xrandr_error;
|
||||||
|
|
||||||
if (!XRRQueryExtension (display, &xrandr_result, &xrandr_error))
|
if (!XRRQueryExtension (this->m_display, &xrandr_result, &xrandr_error))
|
||||||
{
|
{
|
||||||
std::cerr << "XRandr is not present, cannot detect specified screens, running in window mode" << std::endl;
|
std::cerr << "XRandr is not present, cannot detect specified screens, running in window mode" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fullWidth = DisplayWidth (display, DefaultScreen (display));
|
Window root = DefaultRootWindow (this->m_display);
|
||||||
int fullHeight = DisplayHeight (display, DefaultScreen (display));
|
int fullWidth = DisplayWidth (this->m_display, DefaultScreen (this->m_display));
|
||||||
XRRScreenResources* screenResources = XRRGetScreenResources (display, DefaultRootWindow (display));
|
int fullHeight = DisplayHeight (this->m_display, DefaultScreen (this->m_display));
|
||||||
|
XRRScreenResources* screenResources = XRRGetScreenResources (this->m_display, DefaultRootWindow (this->m_display));
|
||||||
|
|
||||||
// there are some situations where xrandr returns null (like screen not using the extension)
|
// there are some situations where xrandr returns null (like screen not using the extension)
|
||||||
if (screenResources == nullptr)
|
if (screenResources == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// create the pixmap and gc used for this display, most situations only have one "display"
|
||||||
|
this->m_pixmap = XCreatePixmap (this->m_display, DefaultRootWindow (this->m_display), fullWidth, fullHeight, 24);
|
||||||
|
this->m_gc = XCreateGC (this->m_display, this->m_pixmap, 0, nullptr);
|
||||||
|
// fill the whole pixmap with black for now
|
||||||
|
XFillRectangle (this->m_display, this->m_pixmap, this->m_gc, 0, 0, fullWidth, fullHeight);
|
||||||
|
|
||||||
for (int i = 0; i < screenResources->noutput; i ++)
|
for (int i = 0; i < screenResources->noutput; i ++)
|
||||||
{
|
{
|
||||||
XRROutputInfo* info = XRRGetOutputInfo (display, screenResources, screenResources->outputs [i]);
|
XRROutputInfo* info = XRRGetOutputInfo (this->m_display, screenResources, screenResources->outputs [i]);
|
||||||
|
|
||||||
// there are some situations where xrandr returns null (like screen not using the extension)
|
// there are some situations where xrandr returns null (like screen not using the extension)
|
||||||
if (info == nullptr)
|
if (info == nullptr)
|
||||||
@ -58,11 +65,11 @@ void CContext::initializeViewports ()
|
|||||||
{
|
{
|
||||||
if (info->connection == RR_Connected && strcmp (info->name, (*cur).c_str ()) == 0)
|
if (info->connection == RR_Connected && strcmp (info->name, (*cur).c_str ()) == 0)
|
||||||
{
|
{
|
||||||
XRRCrtcInfo* crtc = XRRGetCrtcInfo (display, screenResources, info->crtc);
|
XRRCrtcInfo* crtc = XRRGetCrtcInfo (this->m_display, screenResources, info->crtc);
|
||||||
|
|
||||||
std::cout << "Found requested screen: " << info->name << " -> " << crtc->x << "x" << crtc->y << ":" << crtc->width << "x" << crtc->height << std::endl;
|
std::cout << "Found requested screen: " << info->name << " -> " << crtc->x << "x" << crtc->y << ":" << crtc->width << "x" << crtc->height << std::endl;
|
||||||
|
|
||||||
glm::vec4 viewport = {
|
glm::ivec4 viewport = {
|
||||||
crtc->x, fullHeight - (crtc->y + crtc->height), crtc->width, crtc->height
|
crtc->x, fullHeight - (crtc->y + crtc->height), crtc->width, crtc->height
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -77,6 +84,17 @@ void CContext::initializeViewports ()
|
|||||||
|
|
||||||
XRRFreeScreenResources (screenResources);
|
XRRFreeScreenResources (screenResources);
|
||||||
|
|
||||||
|
// create the fbo that will handle the screen
|
||||||
|
this->m_fbo = new CFBO("_sc_FullFrameBuffer", ITexture::TextureFormat::ARGB8888, 1.0, fullWidth, fullHeight, fullWidth, fullHeight);
|
||||||
|
|
||||||
|
// set the window background so the pixmap is drawn
|
||||||
|
XSetWindowBackgroundPixmap(this->m_display, root, this->m_pixmap);
|
||||||
|
|
||||||
|
this->m_imageData = new char [fullWidth * fullHeight * 4];
|
||||||
|
|
||||||
|
// create the image for X11 to be able to copy it over
|
||||||
|
this->m_image = XCreateImage (this->m_display, CopyFromParent, 24, ZPixmap, 0, this->m_imageData, fullWidth, fullHeight, 32, 0);
|
||||||
|
|
||||||
// Cause of issue for issue #59 origial issue
|
// 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)));
|
||||||
}
|
}
|
||||||
@ -88,43 +106,40 @@ void CContext::render ()
|
|||||||
|
|
||||||
if (this->m_viewports.empty () == false)
|
if (this->m_viewports.empty () == false)
|
||||||
{
|
{
|
||||||
static Display* display = XOpenDisplay (nullptr);
|
bool firstFrame = 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 ();
|
||||||
|
int fullWidth = DisplayWidth (this->m_display, DefaultScreen (this->m_display));
|
||||||
|
int fullHeight = DisplayHeight (this->m_display, DefaultScreen (this->m_display));
|
||||||
|
Window root = DefaultRootWindow (this->m_display);
|
||||||
|
|
||||||
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;
|
|
||||||
image_data = new char[windowWidth*windowHeight*4];
|
|
||||||
|
|
||||||
this->m_wallpaper->render (this->m_defaultViewport, true, image_data);
|
|
||||||
XImage* image = XCreateImage(display, CopyFromParent, 24, ZPixmap, 0, (char *)image_data, windowWidth, windowHeight, 32, 0);
|
|
||||||
for (; cur != end; cur ++)
|
for (; cur != end; cur ++)
|
||||||
{
|
{
|
||||||
XPutImage(display, pm, gc, image, 0, 0, (*cur).x, (*cur).y, windowWidth, windowHeight);
|
// render the background
|
||||||
|
this->m_wallpaper->render (*cur, 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 <CVideo> ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// read the full texture into the image
|
||||||
|
glReadPixels (0, 0, fullWidth, fullHeight, GL_BGRA, GL_UNSIGNED_BYTE, (void*) this->m_imageData);
|
||||||
|
|
||||||
|
// put the image back into the screen
|
||||||
|
XPutImage (this->m_display, this->m_pixmap, this->m_gc, this->m_image, 0, 0, 0, 0, fullWidth, fullHeight);
|
||||||
|
|
||||||
// _XROOTPMAP_ID & ESETROOT_PMAP_ID allow other programs (compositors) to
|
// _XROOTPMAP_ID & ESETROOT_PMAP_ID allow other programs (compositors) to
|
||||||
// edit the background. Without these, other programs will clear the screen.
|
// edit the background. Without these, other programs will clear the screen.
|
||||||
Atom prop_root = XInternAtom(display, "_XROOTPMAP_ID", False);
|
// it also forces the compositor to refresh the background (tested with picom)
|
||||||
Atom prop_esetroot = XInternAtom(display, "ESETROOT_PMAP_ID", False);
|
Atom prop_root = XInternAtom(this->m_display, "_XROOTPMAP_ID", False);
|
||||||
XChangeProperty(display, root, prop_root, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &pm, 1);
|
Atom prop_esetroot = XInternAtom(this->m_display, "ESETROOT_PMAP_ID", False);
|
||||||
XChangeProperty(display, root, prop_esetroot, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &pm, 1);
|
XChangeProperty(this->m_display, root, prop_root, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &this->m_pixmap, 1);
|
||||||
|
XChangeProperty(this->m_display, root, prop_esetroot, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &this->m_pixmap, 1);
|
||||||
|
|
||||||
XSetWindowBackgroundPixmap(display, root, pm);
|
XClearWindow(this->m_display, root);
|
||||||
XClearWindow(display, root);
|
XFlush(this->m_display);
|
||||||
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);
|
||||||
@ -133,6 +148,22 @@ void CContext::render ()
|
|||||||
void CContext::setWallpaper (CWallpaper* wallpaper)
|
void CContext::setWallpaper (CWallpaper* wallpaper)
|
||||||
{
|
{
|
||||||
this->m_wallpaper = wallpaper;
|
this->m_wallpaper = wallpaper;
|
||||||
|
|
||||||
|
// update the wallpaper's texcoords based on the mode we're running
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
this->m_wallpaper->updateTexCoord (texCoords, sizeof (texCoords));
|
||||||
|
this->m_wallpaper->setDestinationFramebuffer (this->m_fbo->getFramebuffer ());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CContext::setDefaultViewport (glm::vec4 defaultViewport)
|
void CContext::setDefaultViewport (glm::vec4 defaultViewport)
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "WallpaperEngine/Input/CMouseInput.h"
|
#include "WallpaperEngine/Input/CMouseInput.h"
|
||||||
#include "CWallpaper.h"
|
#include "CWallpaper.h"
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
using namespace WallpaperEngine::Input;
|
using namespace WallpaperEngine::Input;
|
||||||
|
|
||||||
@ -23,9 +24,16 @@ namespace WallpaperEngine::Render
|
|||||||
void setDefaultViewport (glm::vec4 defaultViewport);
|
void setDefaultViewport (glm::vec4 defaultViewport);
|
||||||
CMouseInput* getMouse () const;
|
CMouseInput* getMouse () const;
|
||||||
void setMouse (CMouseInput* mouse);
|
void setMouse (CMouseInput* mouse);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Display* m_display;
|
||||||
|
Pixmap m_pixmap;
|
||||||
|
GC m_gc;
|
||||||
|
XImage* m_image;
|
||||||
|
char* m_imageData;
|
||||||
|
CFBO* m_fbo;
|
||||||
std::vector <std::string> m_screens;
|
std::vector <std::string> m_screens;
|
||||||
std::vector <glm::vec4> m_viewports;
|
std::vector <glm::ivec4> m_viewports;
|
||||||
glm::vec4 m_defaultViewport;
|
glm::vec4 m_defaultViewport;
|
||||||
CWallpaper* m_wallpaper;
|
CWallpaper* m_wallpaper;
|
||||||
CMouseInput* m_mouse;
|
CMouseInput* m_mouse;
|
||||||
|
@ -56,7 +56,7 @@ CCamera* CScene::getCamera () const
|
|||||||
return this->m_camera;
|
return this->m_camera;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScene::renderFrame (glm::vec4 viewport)
|
void CScene::renderFrame (glm::ivec4 viewport)
|
||||||
{
|
{
|
||||||
auto projection = this->getScene ()->getOrthogonalProjection ();
|
auto projection = this->getScene ()->getOrthogonalProjection ();
|
||||||
auto cur = this->m_objects.begin ();
|
auto cur = this->m_objects.begin ();
|
||||||
@ -82,7 +82,7 @@ void CScene::renderFrame (glm::vec4 viewport)
|
|||||||
glViewport (0, 0, projection->getWidth (), projection->getHeight ());
|
glViewport (0, 0, projection->getWidth (), projection->getHeight ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScene::updateMouse (glm::vec4 viewport)
|
void CScene::updateMouse (glm::ivec4 viewport)
|
||||||
{
|
{
|
||||||
// projection also affects the mouse position
|
// projection also affects the mouse position
|
||||||
auto projection = this->getScene ()->getOrthogonalProjection ();
|
auto projection = this->getScene ()->getOrthogonalProjection ();
|
||||||
|
@ -24,8 +24,8 @@ namespace WallpaperEngine::Render
|
|||||||
glm::vec2* getMousePosition ();
|
glm::vec2* getMousePosition ();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void renderFrame (glm::vec4 viewport) override;
|
void renderFrame (glm::ivec4 viewport) override;
|
||||||
void updateMouse (glm::vec4 viewport);
|
void updateMouse (glm::ivec4 viewport);
|
||||||
|
|
||||||
friend class CWallpaper;
|
friend class CWallpaper;
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ void CVideo::setSize (int width, int height)
|
|||||||
SWS_BILINEAR, NULL, NULL, NULL);
|
SWS_BILINEAR, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVideo::renderFrame (glm::vec4 viewport)
|
void CVideo::renderFrame (glm::ivec4 viewport)
|
||||||
{
|
{
|
||||||
// do not render using the CWallpaper function, just use this one
|
// do not render using the CWallpaper function, just use this one
|
||||||
this->setSize (m_codecCtx->width, m_codecCtx->height);
|
this->setSize (m_codecCtx->width, m_codecCtx->height);
|
||||||
|
@ -25,7 +25,7 @@ namespace WallpaperEngine::Render
|
|||||||
int getHeight ();
|
int getHeight ();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void renderFrame (glm::vec4 viewport) override;
|
void renderFrame (glm::ivec4 viewport) override;
|
||||||
|
|
||||||
friend class CWallpaper;
|
friend class CWallpaper;
|
||||||
|
|
||||||
|
@ -12,7 +12,8 @@ CWallpaper::CWallpaper (Core::CWallpaper* wallpaperData, std::string type, CCont
|
|||||||
m_container (container),
|
m_container (container),
|
||||||
m_wallpaperData (wallpaperData),
|
m_wallpaperData (wallpaperData),
|
||||||
m_type (std::move(type)),
|
m_type (std::move(type)),
|
||||||
m_context (context)
|
m_context (context),
|
||||||
|
m_destFramebuffer (GL_NONE)
|
||||||
{
|
{
|
||||||
this->setupShaders ();
|
this->setupShaders ();
|
||||||
|
|
||||||
@ -185,8 +186,19 @@ void CWallpaper::setupShaders ()
|
|||||||
this->a_TexCoord = glGetAttribLocation (this->m_shader, "a_TexCoord");
|
this->a_TexCoord = glGetAttribLocation (this->m_shader, "a_TexCoord");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWallpaper::render (glm::vec4 viewport, bool drawToBackground, char* image_data)
|
void CWallpaper::updateTexCoord (GLfloat* texCoords, GLsizeiptr size) const
|
||||||
{
|
{
|
||||||
|
glBindBuffer (GL_ARRAY_BUFFER, this->m_texCoordBuffer);
|
||||||
|
glBufferData (GL_ARRAY_BUFFER, size, texCoords, GL_STATIC_DRAW);
|
||||||
|
}
|
||||||
|
void CWallpaper::setDestinationFramebuffer (GLuint framebuffer)
|
||||||
|
{
|
||||||
|
this->m_destFramebuffer = framebuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWallpaper::render (glm::ivec4 viewport, bool renderFrame, bool newFrame)
|
||||||
|
{
|
||||||
|
if (renderFrame == true)
|
||||||
this->renderFrame (viewport);
|
this->renderFrame (viewport);
|
||||||
|
|
||||||
int windowWidth = 1920;
|
int windowWidth = 1920;
|
||||||
@ -257,53 +269,13 @@ void CWallpaper::render (glm::vec4 viewport, bool drawToBackground, char* image_
|
|||||||
glBindBuffer (GL_ARRAY_BUFFER, this->m_positionBuffer);
|
glBindBuffer (GL_ARRAY_BUFFER, this->m_positionBuffer);
|
||||||
glBufferData (GL_ARRAY_BUFFER, sizeof (position), position, GL_STATIC_DRAW);
|
glBufferData (GL_ARRAY_BUFFER, sizeof (position), position, GL_STATIC_DRAW);
|
||||||
|
|
||||||
// we only want texCoords to be set once
|
|
||||||
static bool setTexCoords = true;
|
|
||||||
if (setTexCoords)
|
|
||||||
{
|
|
||||||
setTexCoords = false;
|
|
||||||
if (drawToBackground)
|
|
||||||
{
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GLfloat texCoords [] = {
|
|
||||||
0.0f, 0.0f,
|
|
||||||
1.0f, 0.0f,
|
|
||||||
0.0f, 1.0f,
|
|
||||||
0.0f, 1.0f,
|
|
||||||
1.0f, 0.0f,
|
|
||||||
1.0f, 1.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);
|
glViewport (viewport.x, viewport.y, viewport.z, viewport.w);
|
||||||
|
|
||||||
static CFBO* screen_fbo = new CFBO("_sc_FullFrameBuffer", ITexture::TextureFormat::ARGB8888, 1.0, windowWidth, windowHeight, windowWidth, windowHeight);
|
glBindFramebuffer (GL_FRAMEBUFFER, this->m_destFramebuffer);
|
||||||
|
|
||||||
if (drawToBackground)
|
|
||||||
// write to screen buffer
|
|
||||||
glBindFramebuffer (GL_FRAMEBUFFER, screen_fbo->getFramebuffer());
|
|
||||||
else
|
|
||||||
// write to default's framebuffer
|
|
||||||
glBindFramebuffer (GL_FRAMEBUFFER, GL_NONE);
|
|
||||||
|
|
||||||
|
|
||||||
|
if (newFrame)
|
||||||
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
glDisable (GL_BLEND);
|
glDisable (GL_BLEND);
|
||||||
glDisable (GL_DEPTH_TEST);
|
glDisable (GL_DEPTH_TEST);
|
||||||
// do not use any shader
|
// do not use any shader
|
||||||
@ -324,10 +296,6 @@ void CWallpaper::render (glm::vec4 viewport, bool drawToBackground, char* image_
|
|||||||
// write the framebuffer as is to the screen
|
// write the framebuffer as is to the screen
|
||||||
glBindBuffer (GL_ARRAY_BUFFER, this->m_texCoordBuffer);
|
glBindBuffer (GL_ARRAY_BUFFER, this->m_texCoordBuffer);
|
||||||
glDrawArrays (GL_TRIANGLES, 0, 6);
|
glDrawArrays (GL_TRIANGLES, 0, 6);
|
||||||
|
|
||||||
// Get FB data from OpenGL, X11 will free this pointer when it is created into an XImage.
|
|
||||||
if (image_data)
|
|
||||||
glReadPixels(0, 0, 1920, 1080, GL_BGRA, GL_UNSIGNED_BYTE, (void*)(image_data));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWallpaper::setupFramebuffers ()
|
void CWallpaper::setupFramebuffers ()
|
||||||
|
@ -31,7 +31,7 @@ namespace WallpaperEngine::Render
|
|||||||
/**
|
/**
|
||||||
* Performs a render pass of the wallpaper
|
* Performs a render pass of the wallpaper
|
||||||
*/
|
*/
|
||||||
void render (glm::vec4 viewport, bool drawToBackground = false, char* image_data = nullptr);
|
void render (glm::ivec4 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
|
||||||
@ -71,11 +71,22 @@ namespace WallpaperEngine::Render
|
|||||||
*/
|
*/
|
||||||
CFBO* getFBO () const;
|
CFBO* getFBO () const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the texcoord used for drawing to the used framebuffer
|
||||||
|
*/
|
||||||
|
void updateTexCoord (GLfloat* texCoords, GLsizeiptr size) const;
|
||||||
|
/**
|
||||||
|
* Updates the destination framebuffer for this wallpaper
|
||||||
|
*
|
||||||
|
* @param framebuffer
|
||||||
|
*/
|
||||||
|
void setDestinationFramebuffer (GLuint framebuffer);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Renders a frame of the wallpaper
|
* Renders a frame of the wallpaper
|
||||||
*/
|
*/
|
||||||
virtual void renderFrame (glm::vec4 viewport) = 0;
|
virtual void renderFrame (glm::ivec4 viewport) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setups OpenGL's framebuffers for ping-pong and scene rendering
|
* Setups OpenGL's framebuffers for ping-pong and scene rendering
|
||||||
@ -108,6 +119,10 @@ namespace WallpaperEngine::Render
|
|||||||
GLint g_Texture0;
|
GLint g_Texture0;
|
||||||
GLint a_Position;
|
GLint a_Position;
|
||||||
GLint a_TexCoord;
|
GLint a_TexCoord;
|
||||||
|
/**
|
||||||
|
* The framebuffer to draw the background to
|
||||||
|
*/
|
||||||
|
GLuint m_destFramebuffer;
|
||||||
/**
|
/**
|
||||||
* Setups OpenGL's shaders for this wallpaper backbuffer
|
* Setups OpenGL's shaders for this wallpaper backbuffer
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user