From 374491ee63807147a8333ee415428303f99aa466 Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Mon, 4 Apr 2022 19:44:25 +0200 Subject: [PATCH 1/5] progress --- src/Compositor.cpp | 9 ++- src/Compositor.hpp | 2 + src/debug/HyprCtl.cpp | 13 ---- src/debug/HyprCtl.hpp | 1 + src/defines.hpp | 6 +- src/events/Monitors.cpp | 18 +++-- src/helpers/MiscFunctions.cpp | 13 ++++ src/helpers/MiscFunctions.hpp | 3 +- src/render/OpenGL.cpp | 130 ++++++++++++++++++++++++++++++++++ src/render/OpenGL.hpp | 48 +++++++++++++ src/render/Shader.cpp | 0 src/render/Shader.hpp | 20 ++++++ src/render/Shaders.hpp | 69 ++++++++++++++++++ 13 files changed, 306 insertions(+), 26 deletions(-) create mode 100644 src/render/OpenGL.cpp create mode 100644 src/render/OpenGL.hpp create mode 100644 src/render/Shader.cpp create mode 100644 src/render/Shader.hpp create mode 100644 src/render/Shaders.hpp diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 5d9cfd54..0bf2ffcf 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -17,14 +17,14 @@ CCompositor::CCompositor() { return; } - const auto DRMFD = wlr_backend_get_drm_fd(m_sWLRBackend); - if (DRMFD < 0) { + m_iDRMFD = wlr_backend_get_drm_fd(m_sWLRBackend); + if (m_iDRMFD < 0) { Debug::log(CRIT, "Couldn't query the DRM FD!"); RIP("DRMFD NULL!"); return; } - m_sWLRRenderer = wlr_gles2_renderer_create_with_drm_fd(DRMFD); + m_sWLRRenderer = wlr_gles2_renderer_create_with_drm_fd(m_iDRMFD); if (!m_sWLRRenderer) { Debug::log(CRIT, "m_sWLRRenderer was NULL!"); @@ -133,6 +133,9 @@ void CCompositor::startCompositor() { Debug::log(LOG, "Creating the InputManager!"); g_pInputManager = std::make_unique(); + Debug::log(LOG, "Creating the CHyprOpenGLImpl!"); + g_pHyprOpenGL = std::make_unique(); + Debug::log(LOG, "Creating the HyprRenderer!"); g_pHyprRenderer = std::make_unique(); diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 06daa6f9..1c9a691f 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -18,6 +18,7 @@ #include "helpers/Workspace.hpp" #include "Window.hpp" #include "render/Renderer.hpp" +#include "render/OpenGL.hpp" class CCompositor { public: @@ -46,6 +47,7 @@ public: wlr_input_inhibit_manager* m_sWLRInhibitMgr; wlr_keyboard_shortcuts_inhibit_manager_v1* m_sWLRKbShInhibitMgr; wlr_egl* m_sWLREGL; + int m_iDRMFD; // ------------------------------------------------- // diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index 3a19fd19..c9ab5e30 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -12,19 +12,6 @@ #include -std::string getFormat(const char* fmt, ...) { - char buf[2048] = ""; - - va_list args; - va_start(args, fmt); - - vsprintf(buf, fmt , args); - - va_end(args); - - return std::string(buf); -} - std::string monitorsRequest() { std::string result = ""; for (auto& m : g_pCompositor->m_lMonitors) { diff --git a/src/debug/HyprCtl.hpp b/src/debug/HyprCtl.hpp index 1a8851c7..1efe468f 100644 --- a/src/debug/HyprCtl.hpp +++ b/src/debug/HyprCtl.hpp @@ -2,6 +2,7 @@ #include "../Compositor.hpp" #include +#include "../helpers/MiscFunctions.hpp" namespace HyprCtl { void startHyprCtlSocket(); diff --git a/src/defines.hpp b/src/defines.hpp index 004b8121..7eb1b56a 100644 --- a/src/defines.hpp +++ b/src/defines.hpp @@ -31,13 +31,13 @@ #define HYPRATOM(name) {name, 0} #ifndef __INTELLISENSE__ -#define RASSERT(expr, reason) \ +#define RASSERT(expr, reason, ...) \ if (!expr) { \ - Debug::log(CRIT, "\n==========================================================================================\nASSERTION FAILED! \n\n%s\n\nat: line %d in %s", std::string(reason).c_str(), __LINE__, ([]() constexpr->std::string { return std::string(__FILE__).substr(std::string(__FILE__).find_last_of('/') + 1); })().c_str()); \ + Debug::log(CRIT, "\n==========================================================================================\nASSERTION FAILED! \n\n%s\n\nat: line %d in %s", getFormat(reason, ##__VA_ARGS__).c_str(), __LINE__, ([]() constexpr->std::string { return std::string(__FILE__).substr(std::string(__FILE__).find_last_of('/') + 1); })().c_str()); \ RIP("Assertion failed! See the log in /tmp/hypr/hyprland.log for more info."); \ } #else -#define RASSERT(expr, reason) +#define RASSERT(expr, reason, ...) #endif #define ASSERT(expr) RASSERT(expr, "?") \ No newline at end of file diff --git a/src/events/Monitors.cpp b/src/events/Monitors.cpp index da336106..2bb09941 100644 --- a/src/events/Monitors.cpp +++ b/src/events/Monitors.cpp @@ -108,19 +108,25 @@ void Events::listener_monitorFrame(void* owner, void* data) { timespec now; clock_gettime(CLOCK_MONOTONIC, &now); - const float bgcol[4] = {0.1f, 0.1f, 0.1f, 1.f}; if (!wlr_output_attach_render(PMONITOR->output, nullptr)) return; - wlr_renderer_begin(g_pCompositor->m_sWLRRenderer, PMONITOR->vecSize.x, PMONITOR->vecSize.y); - wlr_renderer_clear(g_pCompositor->m_sWLRRenderer, bgcol); + g_pHyprOpenGL->begin(PMONITOR); + g_pHyprOpenGL->clear(CColor(11, 11, 11, 255)); - g_pHyprRenderer->renderAllClientsForMonitor(PMONITOR->ID, &now); + - wlr_output_render_software_cursors(PMONITOR->output, NULL); + g_pHyprOpenGL->end(); - wlr_renderer_end(g_pCompositor->m_sWLRRenderer); + // wlr_renderer_begin(g_pCompositor->m_sWLRRenderer, PMONITOR->vecSize.x, PMONITOR->vecSize.y); + // wlr_renderer_clear(g_pCompositor->m_sWLRRenderer, bgcol); + + // g_pHyprRenderer->renderAllClientsForMonitor(PMONITOR->ID, &now); + + // wlr_output_render_software_cursors(PMONITOR->output, NULL); + + // wlr_renderer_end(g_pCompositor->m_sWLRRenderer); wlr_output_commit(PMONITOR->output); } diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp index 9974ab46..ceb457c4 100644 --- a/src/helpers/MiscFunctions.cpp +++ b/src/helpers/MiscFunctions.cpp @@ -42,3 +42,16 @@ void wlr_signal_emit_safe(struct wl_signal *signal, void *data) { wl_list_remove(&cursor.link); wl_list_remove(&end.link); } + +std::string getFormat(const char *fmt, ...) { + char buf[2048] = ""; + + va_list args; + va_start(args, fmt); + + vsprintf(buf, fmt, args); + + va_end(args); + + return std::string(buf); +} \ No newline at end of file diff --git a/src/helpers/MiscFunctions.hpp b/src/helpers/MiscFunctions.hpp index acbd6d25..c71df0b1 100644 --- a/src/helpers/MiscFunctions.hpp +++ b/src/helpers/MiscFunctions.hpp @@ -3,4 +3,5 @@ #include "../includes.hpp" void addWLSignal(wl_signal*, wl_listener*, void* pOwner, std::string ownerString); -void wlr_signal_emit_safe(struct wl_signal *signal, void *data); \ No newline at end of file +void wlr_signal_emit_safe(struct wl_signal *signal, void *data); +std::string getFormat(const char *fmt, ...); // Basically Debug::log to a string \ No newline at end of file diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp new file mode 100644 index 00000000..e4f07512 --- /dev/null +++ b/src/render/OpenGL.cpp @@ -0,0 +1,130 @@ +#include "OpenGL.hpp" +#include "../Compositor.hpp" + +CHyprOpenGLImpl::CHyprOpenGLImpl() { + RASSERT(eglMakeCurrent(g_pCompositor->m_sWLREGL->display, EGL_NO_SURFACE, EGL_NO_SURFACE, g_pCompositor->m_sWLREGL->context), "Couldn't make the EGL current!"); + + auto *const EXTENSIONS = (const char*)glGetString(GL_EXTENSIONS); + + RASSERT(EXTENSIONS, "Couldn't retrieve openGL extensions!"); + + m_iDRMFD = g_pCompositor->m_iDRMFD; + + m_szExtensions = EXTENSIONS; + + Debug::log(LOG, "Creating the Hypr OpenGL Renderer!"); + Debug::log(LOG, "Using: %s", glGetString(GL_VERSION)); + Debug::log(LOG, "Vendor: %s", glGetString(GL_VENDOR)); + Debug::log(LOG, "Renderer: %s", glGetString(GL_RENDERER)); + Debug::log(LOG, "Supported extensions size: %d", std::count(m_szExtensions.begin(), m_szExtensions.end(), ' ')); + + // Init shaders + + GLuint prog = createProgram(QUADVERTSRC, QUADFRAGSRC); + m_qShaderQuad.program = prog; + m_qShaderQuad.proj = glGetUniformLocation(prog, "proj"); + m_qShaderQuad.color = glGetUniformLocation(prog, "color"); + m_qShaderQuad.posAttrib = glGetUniformLocation(prog, "pos"); + + prog = createProgram(TEXVERTSRC, TEXFRAGSRCRGBA); + m_shRGBA.program = prog; + m_shRGBA.proj = glGetUniformLocation(prog, "proj"); + m_shRGBA.tex = glGetUniformLocation(prog, "tex"); + m_shRGBA.alpha = glGetUniformLocation(prog, "alpha"); + m_shRGBA.texAttrib = glGetUniformLocation(prog, "texcoord"); + m_shRGBA.posAttrib = glGetUniformLocation(prog, "pos"); + + prog = createProgram(TEXVERTSRC, TEXFRAGSRCRGBX); + m_shRGBX.program = prog; + m_shRGBX.tex = glGetUniformLocation(prog, "tex"); + m_shRGBX.proj = glGetUniformLocation(prog, "proj"); + m_shRGBX.alpha = glGetUniformLocation(prog, "alpha"); + m_shRGBX.texAttrib = glGetUniformLocation(prog, "texcoord"); + m_shRGBX.posAttrib = glGetUniformLocation(prog, "pos"); + + prog = createProgram(TEXVERTSRC, TEXFRAGSRCEXT); + m_shEXT.program = prog; + m_shEXT.tex = glGetUniformLocation(prog, "tex"); + m_shEXT.proj = glGetUniformLocation(prog, "proj"); + m_shEXT.alpha = glGetUniformLocation(prog, "alpha"); + m_shEXT.posAttrib = glGetUniformLocation(prog, "pos"); + m_shEXT.texAttrib = glGetUniformLocation(prog, "texcoord"); + + Debug::log(LOG, "Shaders initialized successfully."); + + // End shaders + + RASSERT(eglMakeCurrent(g_pCompositor->m_sWLREGL->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT), "Couldn't unset current EGL!"); + + // Done! +} + +GLuint CHyprOpenGLImpl::createProgram(const std::string& vert, const std::string& frag) { + auto vertCompiled = compileShader(GL_VERTEX_SHADER, vert); + RASSERT(vertCompiled, "Compiling shader failed. VERTEX NULL! Shader source:\n\n%s", vert.c_str()); + + auto fragCompiled = compileShader(GL_FRAGMENT_SHADER, frag); + RASSERT(fragCompiled, "Compiling shader failed. FRAGMENT NULL! Shader source:\n\n%s", frag.c_str()); + + auto prog = glCreateProgram(); + glAttachShader(prog, vertCompiled); + glAttachShader(prog, fragCompiled); + glLinkProgram(prog); + + glDetachShader(prog, vertCompiled); + glDetachShader(prog, fragCompiled); + glDeleteShader(vertCompiled); + glDeleteShader(fragCompiled); + + GLint ok; + glGetProgramiv(prog, GL_LINK_STATUS, &ok); + RASSERT(ok != GL_FALSE, "createProgram() failed! GL_LINK_STATUS not OK!"); + + return prog; +} + +GLuint CHyprOpenGLImpl::compileShader(const GLuint& type, std::string src) { + auto shader = glCreateShader(type); + + auto shaderSource = src.c_str(); + + glShaderSource(shader, 1, (const GLchar**)&shaderSource, nullptr); + glCompileShader(shader); + + GLint ok; + glGetShaderiv(shader, GL_COMPILE_STATUS, &ok); + RASSERT(ok != GL_FALSE, "compileShader() failed! GL_COMPILE_STATUS not OK!"); + + return shader; +} + +void CHyprOpenGLImpl::begin(SMonitor* pMonitor) { + m_RenderData.pMonitor = pMonitor; + + glViewport(0, 0, pMonitor->vecSize.x, pMonitor->vecSize.y); + + wlr_matrix_projection(m_RenderData.projection, pMonitor->vecSize.x, pMonitor->vecSize.y, WL_OUTPUT_TRANSFORM_NORMAL); + + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); +} + +void CHyprOpenGLImpl::end() { + m_RenderData.pMonitor = nullptr; +} + +void CHyprOpenGLImpl::clear(const CColor& color) { + RASSERT(m_RenderData.pMonitor, "Tried to render without begin()!"); + + glClearColor(color.r / 255.f, color.g / 255.f, color.b / 255.f, color.a / 255.f); + glClear(GL_COLOR_BUFFER_BIT); +} + +void CHyprOpenGLImpl::scissor(const wlr_box* pBox) { + if (!pBox) { + glDisable(GL_SCISSOR_TEST); + return; + } + + glScissor(pBox->x, pBox->y, pBox->width, pBox->height); + glEnable(GL_SCISSOR_TEST); +} \ No newline at end of file diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp new file mode 100644 index 00000000..ad6f8d95 --- /dev/null +++ b/src/render/OpenGL.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include "../defines.hpp" +#include "../helpers/Monitor.hpp" +#include "../helpers/Color.hpp" +#include +#include + +#include "Shaders.hpp" +#include "Shader.hpp" + +struct SCurrentRenderData { + SMonitor* pMonitor = nullptr; + float projection[9]; +}; + +class CHyprOpenGLImpl { +public: + + CHyprOpenGLImpl(); + + void begin(SMonitor*); + void end(); + + void clear(const CColor&); + void scissor(const wlr_box*); + + SCurrentRenderData m_RenderData; + +private: + std::list m_lBuffers; + std::list m_lTextures; + + int m_iDRMFD; + std::string m_szExtensions; + + // Shaders + SQuad m_qShaderQuad; + CShader m_shRGBA; + CShader m_shRGBX; + CShader m_shEXT; + // + + GLuint createProgram(const std::string&, const std::string&); + GLuint compileShader(const GLuint&, std::string); +}; + +inline std::unique_ptr g_pHyprOpenGL; \ No newline at end of file diff --git a/src/render/Shader.cpp b/src/render/Shader.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/render/Shader.hpp b/src/render/Shader.hpp new file mode 100644 index 00000000..630dd32f --- /dev/null +++ b/src/render/Shader.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include "../defines.hpp" + +struct SQuad { + GLuint program; + GLint proj; + GLint color; + GLint posAttrib; +}; + +class CShader { +public: + GLuint program; + GLint proj; + GLint tex; + GLint alpha; + GLint posAttrib; + GLint texAttrib; +}; \ No newline at end of file diff --git a/src/render/Shaders.hpp b/src/render/Shaders.hpp new file mode 100644 index 00000000..a9140aca --- /dev/null +++ b/src/render/Shaders.hpp @@ -0,0 +1,69 @@ +#pragma once + +#include + +inline const std::string QUADVERTSRC = R"#( +uniform mat3 proj; +uniform vec4 color; +attribute vec2 pos; +attribute vec2 texcoord; +varying vec4 v_color; +varying vec2 v_texcoord; + +void main() { + gl_Position = vec4(proj * vec3(pos, 1.0), 1.0); + v_color = color; + v_texcoord = texcoord; +})#"; + +inline const std::string QUADFRAGSRC = R"#( +precision mediump float; +varying vec4 v_color; +varying vec2 v_texcoord; + +void main() { + gl_FragColor = v_color; +})#"; + +inline const std::string TEXVERTSRC = R"#( +uniform mat3 proj; +attribute vec2 pos; +attribute vec2 texcoord; +varying vec2 v_texcoord; + +void main() { + gl_Position = vec4(proj * vec3(pos, 1.0), 1.0); + v_texcoord = texcoord; +})#"; + +inline const std::string TEXFRAGSRCRGBA = R"#( +precision mediump float; +varying vec2 v_texcoord; +uniform sampler2D tex; +uniform float alpha; + +void main() { + gl_FragColor = texture2D(tex, v_texcoord) * alpha; +})#"; + +inline const std::string TEXFRAGSRCRGBX = R"#( +precision mediump float; +varying vec2 v_texcoord; +uniform sampler2D tex; +uniform float alpha; + +void main() { + gl_FragColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0) * alpha; +})#"; + +inline const std::string TEXFRAGSRCEXT = R"#( +#extension GL_OES_EGL_image_external : require + +precision mediump float; +varying vec2 v_texcoord; +uniform samplerExternalOES texture0; +uniform float alpha; + +void main() { + gl_FragColor = texture2D(texture0, v_texcoord) * alpha; +})#"; From 334f5a59b07c890418ec28630e428e1e02e5f51e Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Mon, 4 Apr 2022 21:45:35 +0200 Subject: [PATCH 2/5] added broken rect renderer --- src/events/Monitors.cpp | 5 ++-- src/render/OpenGL.cpp | 56 +++++++++++++++++++++++++++++++++-------- src/render/OpenGL.hpp | 16 +++++++++++- 3 files changed, 63 insertions(+), 14 deletions(-) diff --git a/src/events/Monitors.cpp b/src/events/Monitors.cpp index 2bb09941..032825a6 100644 --- a/src/events/Monitors.cpp +++ b/src/events/Monitors.cpp @@ -113,9 +113,10 @@ void Events::listener_monitorFrame(void* owner, void* data) { return; g_pHyprOpenGL->begin(PMONITOR); - g_pHyprOpenGL->clear(CColor(11, 11, 11, 255)); + g_pHyprOpenGL->clear(CColor(11, 55, 11, 255)); - + wlr_box box = {1,1,100,300}; + g_pHyprOpenGL->renderRect(&box, CColor(255,0,255,255)); // THIS FUCKING SHIT DOESNT WORK!!!!!! g_pHyprOpenGL->end(); diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index e4f07512..f7c7fa13 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -21,34 +21,34 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() { // Init shaders GLuint prog = createProgram(QUADVERTSRC, QUADFRAGSRC); - m_qShaderQuad.program = prog; - m_qShaderQuad.proj = glGetUniformLocation(prog, "proj"); - m_qShaderQuad.color = glGetUniformLocation(prog, "color"); - m_qShaderQuad.posAttrib = glGetUniformLocation(prog, "pos"); + m_shQUAD.program = prog; + m_shQUAD.proj = glGetUniformLocation(prog, "proj"); + m_shQUAD.color = glGetUniformLocation(prog, "color"); + m_shQUAD.posAttrib = glGetAttribLocation(prog, "pos"); prog = createProgram(TEXVERTSRC, TEXFRAGSRCRGBA); m_shRGBA.program = prog; m_shRGBA.proj = glGetUniformLocation(prog, "proj"); m_shRGBA.tex = glGetUniformLocation(prog, "tex"); m_shRGBA.alpha = glGetUniformLocation(prog, "alpha"); - m_shRGBA.texAttrib = glGetUniformLocation(prog, "texcoord"); - m_shRGBA.posAttrib = glGetUniformLocation(prog, "pos"); + m_shRGBA.texAttrib = glGetAttribLocation(prog, "texcoord"); + m_shRGBA.posAttrib = glGetAttribLocation(prog, "pos"); prog = createProgram(TEXVERTSRC, TEXFRAGSRCRGBX); m_shRGBX.program = prog; m_shRGBX.tex = glGetUniformLocation(prog, "tex"); m_shRGBX.proj = glGetUniformLocation(prog, "proj"); m_shRGBX.alpha = glGetUniformLocation(prog, "alpha"); - m_shRGBX.texAttrib = glGetUniformLocation(prog, "texcoord"); - m_shRGBX.posAttrib = glGetUniformLocation(prog, "pos"); + m_shRGBX.texAttrib = glGetAttribLocation(prog, "texcoord"); + m_shRGBX.posAttrib = glGetAttribLocation(prog, "pos"); prog = createProgram(TEXVERTSRC, TEXFRAGSRCEXT); m_shEXT.program = prog; m_shEXT.tex = glGetUniformLocation(prog, "tex"); m_shEXT.proj = glGetUniformLocation(prog, "proj"); m_shEXT.alpha = glGetUniformLocation(prog, "alpha"); - m_shEXT.posAttrib = glGetUniformLocation(prog, "pos"); - m_shEXT.texAttrib = glGetUniformLocation(prog, "texcoord"); + m_shEXT.posAttrib = glGetAttribLocation(prog, "pos"); + m_shEXT.texAttrib = glGetAttribLocation(prog, "texcoord"); Debug::log(LOG, "Shaders initialized successfully."); @@ -103,7 +103,7 @@ void CHyprOpenGLImpl::begin(SMonitor* pMonitor) { glViewport(0, 0, pMonitor->vecSize.x, pMonitor->vecSize.y); - wlr_matrix_projection(m_RenderData.projection, pMonitor->vecSize.x, pMonitor->vecSize.y, WL_OUTPUT_TRANSFORM_NORMAL); + wlr_matrix_projection(m_RenderData.projection, pMonitor->vecSize.x, pMonitor->vecSize.y, WL_OUTPUT_TRANSFORM_NORMAL); // TODO: this is deprecated glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } @@ -120,6 +120,8 @@ void CHyprOpenGLImpl::clear(const CColor& color) { } void CHyprOpenGLImpl::scissor(const wlr_box* pBox) { + RASSERT(m_RenderData.pMonitor, "Tried to scissor without begin()!"); + if (!pBox) { glDisable(GL_SCISSOR_TEST); return; @@ -127,4 +129,36 @@ void CHyprOpenGLImpl::scissor(const wlr_box* pBox) { glScissor(pBox->x, pBox->y, pBox->width, pBox->height); glEnable(GL_SCISSOR_TEST); +} + +void CHyprOpenGLImpl::renderRect(wlr_box* box, const CColor& col) { + RASSERT((box->width > 0 && box->height > 0), "Tried to render rect with width/height < 0!"); + RASSERT(m_RenderData.pMonitor, "Tried to render rect without begin()!"); + + float matrix[9]; + wlr_matrix_project_box(matrix, box, WL_OUTPUT_TRANSFORM_NORMAL, 0, m_RenderData.projection); // TODO: write own, don't use WLR here + + float glMatrix[9]; + wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix); + wlr_matrix_multiply(glMatrix, matrixFlip180, glMatrix); + + wlr_matrix_transpose(glMatrix, glMatrix); + + if (col.a == 255.f) + glDisable(GL_BLEND); + else + glEnable(GL_BLEND); + + glUseProgram(m_shQUAD.program); + + glUniformMatrix3fv(m_shQUAD.proj, 1, GL_FALSE, glMatrix); + glUniform4f(m_shQUAD.color, 0.1f, 0.1f, 0.1f, 1.f); + + glVertexAttribPointer(m_shQUAD.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts); + + glEnableVertexAttribArray(m_shQUAD.posAttrib); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glDisableVertexAttribArray(m_shQUAD.posAttrib); } \ No newline at end of file diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index ad6f8d95..dd380658 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -9,6 +9,18 @@ #include "Shaders.hpp" #include "Shader.hpp" +inline const float matrixFlip180[] = { + 1.0f, 0.0f, 0.0f, + 0.0f, -1.0f, 0.0f, + 0.0f, 0.0f, 1.0f, +}; +inline const float fullVerts[] = { + 1, 0, // top right + 0, 0, // top left + 1, 1, // bottom right + 0, 1, // bottom left +}; + struct SCurrentRenderData { SMonitor* pMonitor = nullptr; float projection[9]; @@ -22,6 +34,8 @@ public: void begin(SMonitor*); void end(); + void renderRect(wlr_box*, const CColor&); + void clear(const CColor&); void scissor(const wlr_box*); @@ -35,7 +49,7 @@ private: std::string m_szExtensions; // Shaders - SQuad m_qShaderQuad; + SQuad m_shQUAD; CShader m_shRGBA; CShader m_shRGBX; CShader m_shEXT; From 67343898ff881bbbc767025a033005f45db32a09 Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Mon, 4 Apr 2022 22:06:57 +0200 Subject: [PATCH 3/5] fixed rendering rects --- src/events/Monitors.cpp | 2 +- src/render/OpenGL.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/events/Monitors.cpp b/src/events/Monitors.cpp index 032825a6..65016f61 100644 --- a/src/events/Monitors.cpp +++ b/src/events/Monitors.cpp @@ -116,7 +116,7 @@ void Events::listener_monitorFrame(void* owner, void* data) { g_pHyprOpenGL->clear(CColor(11, 55, 11, 255)); wlr_box box = {1,1,100,300}; - g_pHyprOpenGL->renderRect(&box, CColor(255,0,255,255)); // THIS FUCKING SHIT DOESNT WORK!!!!!! + g_pHyprOpenGL->renderRect(&box, CColor(255,0,255,255)); g_pHyprOpenGL->end(); diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index f7c7fa13..5a7f11d2 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -136,7 +136,7 @@ void CHyprOpenGLImpl::renderRect(wlr_box* box, const CColor& col) { RASSERT(m_RenderData.pMonitor, "Tried to render rect without begin()!"); float matrix[9]; - wlr_matrix_project_box(matrix, box, WL_OUTPUT_TRANSFORM_NORMAL, 0, m_RenderData.projection); // TODO: write own, don't use WLR here + wlr_matrix_project_box(matrix, box, WL_OUTPUT_TRANSFORM_NORMAL, 0, m_RenderData.pMonitor->output->transform_matrix); // TODO: write own, don't use WLR here float glMatrix[9]; wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix); @@ -152,7 +152,7 @@ void CHyprOpenGLImpl::renderRect(wlr_box* box, const CColor& col) { glUseProgram(m_shQUAD.program); glUniformMatrix3fv(m_shQUAD.proj, 1, GL_FALSE, glMatrix); - glUniform4f(m_shQUAD.color, 0.1f, 0.1f, 0.1f, 1.f); + glUniform4f(m_shQUAD.color, col.r / 255.f, col.g / 255.f, col.r / 255.f, col.a / 255.f); glVertexAttribPointer(m_shQUAD.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts); From 19d946504239e3df1b8afb26d2053fb80dfff19e Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Tue, 5 Apr 2022 14:33:54 +0200 Subject: [PATCH 4/5] Rendering textures --- src/events/Monitors.cpp | 20 ++++++------- src/includes.hpp | 1 + src/render/OpenGL.cpp | 63 ++++++++++++++++++++++++++++++++++++++++- src/render/OpenGL.hpp | 3 ++ src/render/Renderer.cpp | 18 ++++++------ src/render/Texture.cpp | 22 ++++++++++++++ src/render/Texture.hpp | 21 ++++++++++++++ 7 files changed, 125 insertions(+), 23 deletions(-) create mode 100644 src/render/Texture.cpp create mode 100644 src/render/Texture.hpp diff --git a/src/events/Monitors.cpp b/src/events/Monitors.cpp index 65016f61..118b54a6 100644 --- a/src/events/Monitors.cpp +++ b/src/events/Monitors.cpp @@ -113,22 +113,18 @@ void Events::listener_monitorFrame(void* owner, void* data) { return; g_pHyprOpenGL->begin(PMONITOR); - g_pHyprOpenGL->clear(CColor(11, 55, 11, 255)); + g_pHyprOpenGL->clear(CColor(11, 11, 11, 255)); - wlr_box box = {1,1,100,300}; - g_pHyprOpenGL->renderRect(&box, CColor(255,0,255,255)); + g_pHyprRenderer->renderAllClientsForMonitor(PMONITOR->ID, &now); + + wlr_renderer_begin(g_pCompositor->m_sWLRRenderer, PMONITOR->vecSize.x, PMONITOR->vecSize.y); + + wlr_output_render_software_cursors(PMONITOR->output, NULL); + + wlr_renderer_end(g_pCompositor->m_sWLRRenderer); g_pHyprOpenGL->end(); - // wlr_renderer_begin(g_pCompositor->m_sWLRRenderer, PMONITOR->vecSize.x, PMONITOR->vecSize.y); - // wlr_renderer_clear(g_pCompositor->m_sWLRRenderer, bgcol); - - // g_pHyprRenderer->renderAllClientsForMonitor(PMONITOR->ID, &now); - - // wlr_output_render_software_cursors(PMONITOR->output, NULL); - - // wlr_renderer_end(g_pCompositor->m_sWLRRenderer); - wlr_output_commit(PMONITOR->output); } diff --git a/src/includes.hpp b/src/includes.hpp index 6b8c723b..bc25a74a 100644 --- a/src/includes.hpp +++ b/src/includes.hpp @@ -84,5 +84,6 @@ extern "C" { #endif #include +#include #include "helpers/Vector2D.hpp" diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 5a7f11d2..b86a69d7 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -152,7 +152,7 @@ void CHyprOpenGLImpl::renderRect(wlr_box* box, const CColor& col) { glUseProgram(m_shQUAD.program); glUniformMatrix3fv(m_shQUAD.proj, 1, GL_FALSE, glMatrix); - glUniform4f(m_shQUAD.color, col.r / 255.f, col.g / 255.f, col.r / 255.f, col.a / 255.f); + glUniform4f(m_shQUAD.color, col.r / 255.f, col.g / 255.f, col.b / 255.f, col.a / 255.f); glVertexAttribPointer(m_shQUAD.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts); @@ -161,4 +161,65 @@ void CHyprOpenGLImpl::renderRect(wlr_box* box, const CColor& col) { glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisableVertexAttribArray(m_shQUAD.posAttrib); +} + +void CHyprOpenGLImpl::renderTexture(wlr_texture* tex,float matrix[9], float alpha) { + RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); + + renderTexture(CTexture(tex), matrix, alpha); +} + +void CHyprOpenGLImpl::renderTexture(const CTexture& tex, float matrix[9], float alpha) { + RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); + RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!"); + + float glMatrix[9]; + wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix); + wlr_matrix_multiply(glMatrix, matrixFlip180, glMatrix); + + wlr_matrix_transpose(glMatrix, glMatrix); + + CShader* shader = nullptr; + + switch (tex.m_iType) { + case TEXTURE_RGBA: + shader = &m_shRGBA; + glEnable(GL_BLEND); + break; + case TEXTURE_RGBX: + shader = &m_shRGBX; + if (alpha == 255.f) + glDisable(GL_BLEND); + break; + case TEXTURE_EXTERNAL: + shader = &m_shEXT; + glEnable(GL_BLEND); + break; + default: + RASSERT(false, "tex.m_iTarget unsupported!"); + } + + glActiveTexture(GL_TEXTURE0); + glBindTexture(tex.m_iTarget, tex.m_iTexID); + + glTexParameteri(tex.m_iTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + glUseProgram(shader->program); + + glUniformMatrix3fv(shader->proj, 1, GL_FALSE, glMatrix); + glUniform1i(shader->tex, 0); + glUniform1f(shader->alpha, alpha / 255.f); + + glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts); + glVertexAttribPointer(shader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts); + + glEnableVertexAttribArray(shader->posAttrib); + glEnableVertexAttribArray(shader->texAttrib); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glDisableVertexAttribArray(shader->posAttrib); + glDisableVertexAttribArray(shader->texAttrib); + + glBindTexture(tex.m_iTarget, 0); } \ No newline at end of file diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index dd380658..c3e1b987 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -8,6 +8,7 @@ #include "Shaders.hpp" #include "Shader.hpp" +#include "Texture.hpp" inline const float matrixFlip180[] = { 1.0f, 0.0f, 0.0f, @@ -35,6 +36,8 @@ public: void end(); void renderRect(wlr_box*, const CColor&); + void renderTexture(wlr_texture*, float matrix[9], float a); + void renderTexture(const CTexture&, float matrix[9], float a); void clear(const CColor&); void scissor(const wlr_box*); diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 974ab663..864a678e 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -21,7 +21,7 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) { wlr_box windowBox; if (RDATA->surface && surface == RDATA->surface) { windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, RDATA->w, RDATA->h}; - wlr_renderer_scissor(g_pCompositor->m_sWLRRenderer, &windowBox); + g_pHyprOpenGL->scissor(&windowBox); } else { windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, surface->current.width, surface->current.height}; } @@ -31,13 +31,13 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) { float matrix[9]; wlr_matrix_project_box(matrix, &windowBox, TRANSFORM, 0, RDATA->output->transform_matrix); - wlr_render_texture_with_matrix(g_pCompositor->m_sWLRRenderer, TEXTURE, matrix, 1); // TODO: fadein/out + g_pHyprOpenGL->renderTexture(TEXTURE, matrix, 255.f); // TODO: fadeinout wlr_surface_send_frame_done(surface, RDATA->when); wlr_presentation_surface_sampled_on_output(g_pCompositor->m_sWLRPresentation, surface, RDATA->output); - wlr_renderer_scissor(g_pCompositor->m_sWLRRenderer, nullptr); + g_pHyprOpenGL->scissor(nullptr); } bool shouldRenderWindow(CWindow* pWindow, SMonitor* pMonitor) { @@ -395,29 +395,27 @@ void CHyprRenderer::arrangeLayersForMonitor(const int& monitor) { void CHyprRenderer::drawBorderForWindow(CWindow* pWindow, SMonitor* pMonitor) { const auto BORDERSIZE = g_pConfigManager->getInt("general:border_size"); - const auto BORDERCOL = pWindow->m_cRealBorderColor.getAsHex(); - - const float BORDERWLRCOL[4] = {RED(BORDERCOL), GREEN(BORDERCOL), BLUE(BORDERCOL), ALPHA(BORDERCOL)}; + const auto BORDERCOL = pWindow->m_cRealBorderColor; Vector2D correctPos = pWindow->m_vRealPosition - pMonitor->vecPosition; // top wlr_box border = {correctPos.x - BORDERSIZE, correctPos.y - BORDERSIZE, pWindow->m_vRealSize.x + 2 * BORDERSIZE, BORDERSIZE}; - wlr_render_rect(g_pCompositor->m_sWLRRenderer, &border, BORDERWLRCOL, pMonitor->output->transform_matrix); + g_pHyprOpenGL->renderRect(&border, BORDERCOL); // bottom border.y = correctPos.y + pWindow->m_vRealSize.y; - wlr_render_rect(g_pCompositor->m_sWLRRenderer, &border, BORDERWLRCOL, pMonitor->output->transform_matrix); + g_pHyprOpenGL->renderRect(&border, BORDERCOL); // left border.y = correctPos.y; border.width = BORDERSIZE; border.height = pWindow->m_vRealSize.y; - wlr_render_rect(g_pCompositor->m_sWLRRenderer, &border, BORDERWLRCOL, pMonitor->output->transform_matrix); + g_pHyprOpenGL->renderRect(&border, BORDERCOL); // right border.x = correctPos.x + pWindow->m_vRealSize.x; - wlr_render_rect(g_pCompositor->m_sWLRRenderer, &border, BORDERWLRCOL, pMonitor->output->transform_matrix); + g_pHyprOpenGL->renderRect(&border, BORDERCOL); } void damageSurfaceIter(struct wlr_surface* surface, int x, int y, void* data) { diff --git a/src/render/Texture.cpp b/src/render/Texture.cpp new file mode 100644 index 00000000..6d47c4a8 --- /dev/null +++ b/src/render/Texture.cpp @@ -0,0 +1,22 @@ +#include "Texture.hpp" + +CTexture::CTexture() { + // naffin' +} + +CTexture::CTexture(wlr_texture* tex) { + RASSERT(wlr_texture_is_gles2(tex), "wlr_texture provided to CTexture that isn't GLES2!"); + wlr_gles2_texture_attribs attrs; + wlr_gles2_texture_get_attribs(tex, &attrs); + + m_iTarget = attrs.target; + m_iTexID = attrs.tex; + + if (m_iTarget == GL_TEXTURE_2D) { + m_iType = attrs.has_alpha ? TEXTURE_RGBA : TEXTURE_RGBX; + } else { + m_iType = TEXTURE_EXTERNAL; + } + + m_vSize = Vector2D(tex->width, tex->height); +} \ No newline at end of file diff --git a/src/render/Texture.hpp b/src/render/Texture.hpp new file mode 100644 index 00000000..dbdf715a --- /dev/null +++ b/src/render/Texture.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "../defines.hpp" + +enum TEXTURETYPE { + TEXTURE_INVALID, // Invalid + TEXTURE_RGBA, // 4 channels + TEXTURE_RGBX, // discard A + TEXTURE_EXTERNAL, // EGLImage +}; + +class CTexture { +public: + CTexture(); + CTexture(wlr_texture*); + + TEXTURETYPE m_iType = TEXTURE_RGBA; + GLenum m_iTarget = GL_TEXTURE_2D; + GLuint m_iTexID = 0; + Vector2D m_vSize; +}; \ No newline at end of file From bd5c056a601842c41816448b82cf5367e21ea0ad Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Tue, 5 Apr 2022 14:36:28 +0200 Subject: [PATCH 5/5] Updated readme --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 395e00d3..d58aed08 100644 --- a/README.md +++ b/README.md @@ -30,10 +30,11 @@ Nevertheless, REPORT any you find! Make an issue! - Moving/resizing windows # Major to-dos - - Switch to fully custom OpenGL rendering - Damage tracking - Animations (better) - Rounded corners + - Fix XWayland focus + - Fix GDK popups on multimon - Blur - Fadein/out - Fix electron rendering issues