From dbb4488c750ff1dfa8b40365c1a91b5a6f5f86e3 Mon Sep 17 00:00:00 2001 From: Matias Date: Mon, 14 Jul 2025 17:58:13 +0200 Subject: [PATCH] feat: render a subdivided grid as VAO (wrong UVs) --- src/main.cpp | 185 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 163 insertions(+), 22 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 1a42e63..438613e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,7 @@ #include "globals.hpp" +#include +#include #include // version.hpp will be generated by meson #include "src/plugins/PluginAPI.hpp" @@ -23,6 +25,14 @@ APICALL EXPORT std::string PLUGIN_API_VERSION() { return HYPRLAND_API_VERSION; } +SShader* g_shader {}; + +constexpr unsigned int g_SUBDIVS = 2; +static_assert(g_SUBDIVS > 0); + +GLuint g_VAO, g_VBO, g_VBO_UVs; +unsigned int g_vertCount = 0; + class CBindOwnFramebufferPassElement final: public IPassElement { public: explicit CBindOwnFramebufferPassElement(CFramebuffer* pFramebuffer) : @@ -82,38 +92,55 @@ class CRenderWobblyWindowPassElement final: public IPassElement { g_pHyprOpenGL->m_renderData.monitorProjection.projectBox(newBox, TRANSFORM, newBox.rot); Mat3x3 glMatrix = g_pHyprOpenGL->m_renderData.projection.copy().multiply(matrix); - SShader* shader = &g_pHyprOpenGL->m_shaders->m_shRGBA; - - glActiveTexture(GL_TEXTURE0); + GLCALL(glActiveTexture(GL_TEXTURE0)); pWindowFB->getTexture()->bind(); - g_pHyprOpenGL->useProgram(shader->program); - shader->setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix()); - shader->setUniformInt(SHADER_TEX, 0); - glBindVertexArray(shader->uniformLocations[SHADER_SHADER_VAO]); + g_pHyprOpenGL->useProgram(g_shader->program); + g_shader->setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix()); + // g_shader->setUniformFloat4(SHADER_COLOR, 1.f, 255.f, 1.f, 255.f); + + g_shader->setUniformInt(SHADER_TEX, 0); + GLCALL(glBindVertexArray(g_VAO)); + GLCALL(glBindBuffer(GL_ARRAY_BUFFER, g_VBO)); const Vector2D UVTopLeft = Vector2D {windowBox.x, windowBox.y} / pWindowFB->m_size; const Vector2D UVBottomRight = Vector2D {windowBox.x + windowBox.width, windowBox.y + windowBox.height} / pWindowFB->m_size; - const float UVs[] = { - (float)UVBottomRight.x, - (float)UVTopLeft.y, - (float)UVTopLeft.x, - (float)UVTopLeft.y, - (float)UVBottomRight.x, - (float)UVBottomRight.y, - (float)UVTopLeft.x, - (float)UVBottomRight.y, - }; + std::array UVs; - glBindBuffer(GL_ARRAY_BUFFER, shader->uniformLocations[SHADER_SHADER_VBO_UV]); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(UVs), UVs); + const auto step = (UVBottomRight - UVTopLeft) / (g_SUBDIVS - 1); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + std::generate(UVs.begin(), UVs.end(), [UVTopLeft, step, index = 0]() mutable { + int x = index % g_SUBDIVS; + int y = index / g_SUBDIVS; - glBindVertexArray(0); + const float u = UVTopLeft.x + x * step.x; + const float v = UVTopLeft.y + y * step.y; + index++; + return (index % 2 == 0) ? v : u; + }); + + glBindBuffer(GL_ARRAY_BUFFER, g_VBO_UVs); + glBufferSubData(GL_ARRAY_BUFFER, 0, UVs.size(), UVs.data()); + + GLCALL(glDisable(GL_CULL_FACE)); + GLCALL(glDrawArrays(GL_TRIANGLES, 0, g_vertCount)); + + int nBufferSize = 0; + glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &nBufferSize); + int originalVertexArraySize = (nBufferSize / sizeof(float)); + std::println( + "Drew {} verts, from VBO that has {} floats", + g_vertCount, + originalVertexArraySize + ); + + // GLCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_EBO)); + // GLCALL(glDrawElements(GL_TRIANGLE_STRIP, g_indicesCount, GL_UNSIGNED_INT, 0)); + + GLCALL(glBindVertexArray(0)); pWindowFB->getTexture()->unbind(); } @@ -195,7 +222,7 @@ void hkRenderWindow( auto&& windowFB = g_windowFramebuffers.at(ref); - if (windowSize != windowFB.m_size) { + if (framebufferSize.x > windowFB.m_size.x or framebufferSize.y > windowFB.m_size.y) { windowFB.release(); windowFB.alloc(framebufferSize.x, framebufferSize.y); } @@ -222,6 +249,118 @@ void hkRenderWindow( } } +void initGPUObjects() { + g_shader = &g_pHyprOpenGL->m_shaders->m_shRGBA; + + std::vector finalVerts; + { + const unsigned int vertsPerRow = g_SUBDIVS + 1; + std::vector verts; + verts.reserve(vertsPerRow * vertsPerRow * 2); + + const float step = 1.f / (g_SUBDIVS); + for (unsigned int y = 0; y < vertsPerRow; ++y) { + for (unsigned int x = 0; x < vertsPerRow; ++x) { + verts.push_back(x * step); + verts.push_back(y * step); + } + } + + verts[4 * 2] = 0.7f; + + for (unsigned int i = 0; i < verts.size(); i += 2) { + std::println("Created vert ({}, {})", verts[i], verts[i + 1]); + } + + std::vector indices; + g_vertCount = 3 * 2 * g_SUBDIVS * g_SUBDIVS; + indices.reserve(g_vertCount); + + for (int y = 0; y < g_SUBDIVS; ++y) { + for (int x = 0; x < g_SUBDIVS; ++x) { + indices.push_back(y * vertsPerRow + x + 1); // top right + indices.push_back(y * vertsPerRow + x); // top left + indices.push_back((y + 1) * vertsPerRow + x + 1); // bottom right + + indices.push_back(y * vertsPerRow + x); // top left + indices.push_back((y + 1) * vertsPerRow + x); // bottom left + indices.push_back((y + 1) * vertsPerRow + x + 1); // bottom right + } + } + + finalVerts.reserve(g_vertCount); + for (auto&& index : indices) { + finalVerts.push_back(verts[index * 2]); + finalVerts.push_back(verts[index * 2 + 1]); + } + + for (unsigned int i = 0; i < finalVerts.size(); i += 6) { + std::println( + "Created tri <({}, {}), ({}, {}), ({}, {})>", + finalVerts[i], + finalVerts[i + 1], + finalVerts[i + 2], + finalVerts[i + 3], + finalVerts[i + 4], + finalVerts[i + 5] + ); + } + } + + GLCALL(glGenVertexArrays(1, &g_VAO)); + GLCALL(glGenBuffers(1, &g_VBO)); + GLCALL(glGenBuffers(1, &g_VBO_UVs)); + // GLCALL(glGenBuffers(1, &g_EBO)); + + GLCALL(glBindVertexArray(g_VAO)); + + // GLCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_EBO)); + // GLCALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size(), indices.data(), GL_STATIC_DRAW)); + + GLCALL(glBindBuffer(GL_ARRAY_BUFFER, g_VBO)); + { + std::println("Number of vertices in VBO: {}/2", finalVerts.size()); + GLCALL(glBufferData( + GL_ARRAY_BUFFER, + finalVerts.size() * sizeof(float), + finalVerts.data(), + GL_DYNAMIC_DRAW + )); + + GLCALL(glEnableVertexAttribArray(g_shader->uniformLocations[SHADER_POS_ATTRIB])); + GLCALL(glVertexAttribPointer( + g_shader->uniformLocations[SHADER_POS_ATTRIB], + 2, + GL_FLOAT, + GL_FALSE, + 0, + nullptr + )); + } + + GLCALL(glBindBuffer(GL_ARRAY_BUFFER, g_VBO_UVs)); + { + GLCALL(glBufferData( + GL_ARRAY_BUFFER, + finalVerts.size() * sizeof(float), + finalVerts.data(), + GL_DYNAMIC_DRAW + )); // Initial dummy UVs + GLCALL(glEnableVertexAttribArray(g_shader->uniformLocations[SHADER_TEX_ATTRIB])); + GLCALL(glVertexAttribPointer( + g_shader->uniformLocations[SHADER_TEX_ATTRIB], + 2, + GL_FLOAT, + GL_FALSE, + 0, + nullptr + )); + } + + GLCALL(glBindVertexArray(0)); + GLCALL(glBindBuffer(GL_ARRAY_BUFFER, 0)); +} + APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { PHANDLE = handle; @@ -239,6 +378,8 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { throw std::runtime_error("[WiggleWobble] Version mismatch"); } + initGPUObjects(); + g_openWindow = HyprlandAPI::registerCallbackDynamic( PHANDLE, "openWindow",