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] 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