feat: render a subdivided grid as VAO (wrong UVs)

This commit is contained in:
Matias 2025-07-14 17:58:13 +02:00
parent c6e73ad94d
commit dbb4488c75
No known key found for this signature in database
GPG Key ID: ED35A6AC65A06B69

View File

@ -1,5 +1,7 @@
#include "globals.hpp" #include "globals.hpp"
#include <GLES3/gl32.h>
#include <algorithm>
#include <hyprgraphics/color/Color.hpp> #include <hyprgraphics/color/Color.hpp>
// version.hpp will be generated by meson // version.hpp will be generated by meson
#include "src/plugins/PluginAPI.hpp" #include "src/plugins/PluginAPI.hpp"
@ -23,6 +25,14 @@ APICALL EXPORT std::string PLUGIN_API_VERSION() {
return HYPRLAND_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 { class CBindOwnFramebufferPassElement final: public IPassElement {
public: public:
explicit CBindOwnFramebufferPassElement(CFramebuffer* pFramebuffer) : explicit CBindOwnFramebufferPassElement(CFramebuffer* pFramebuffer) :
@ -82,38 +92,55 @@ class CRenderWobblyWindowPassElement final: public IPassElement {
g_pHyprOpenGL->m_renderData.monitorProjection.projectBox(newBox, TRANSFORM, newBox.rot); g_pHyprOpenGL->m_renderData.monitorProjection.projectBox(newBox, TRANSFORM, newBox.rot);
Mat3x3 glMatrix = g_pHyprOpenGL->m_renderData.projection.copy().multiply(matrix); Mat3x3 glMatrix = g_pHyprOpenGL->m_renderData.projection.copy().multiply(matrix);
SShader* shader = &g_pHyprOpenGL->m_shaders->m_shRGBA; GLCALL(glActiveTexture(GL_TEXTURE0));
glActiveTexture(GL_TEXTURE0);
pWindowFB->getTexture()->bind(); pWindowFB->getTexture()->bind();
g_pHyprOpenGL->useProgram(shader->program); g_pHyprOpenGL->useProgram(g_shader->program);
shader->setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix()); g_shader->setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix());
shader->setUniformInt(SHADER_TEX, 0); // g_shader->setUniformFloat4(SHADER_COLOR, 1.f, 255.f, 1.f, 255.f);
glBindVertexArray(shader->uniformLocations[SHADER_SHADER_VAO]);
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 UVTopLeft = Vector2D {windowBox.x, windowBox.y} / pWindowFB->m_size;
const Vector2D UVBottomRight = const Vector2D UVBottomRight =
Vector2D {windowBox.x + windowBox.width, windowBox.y + windowBox.height} Vector2D {windowBox.x + windowBox.width, windowBox.y + windowBox.height}
/ pWindowFB->m_size; / pWindowFB->m_size;
const float UVs[] = { std::array<float, g_SUBDIVS * g_SUBDIVS * 3 * 2> 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,
};
glBindBuffer(GL_ARRAY_BUFFER, shader->uniformLocations[SHADER_SHADER_VBO_UV]); const auto step = (UVBottomRight - UVTopLeft) / (g_SUBDIVS - 1);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(UVs), UVs);
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(); pWindowFB->getTexture()->unbind();
} }
@ -195,7 +222,7 @@ void hkRenderWindow(
auto&& windowFB = g_windowFramebuffers.at(ref); 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.release();
windowFB.alloc(framebufferSize.x, framebufferSize.y); windowFB.alloc(framebufferSize.x, framebufferSize.y);
} }
@ -222,6 +249,118 @@ void hkRenderWindow(
} }
} }
void initGPUObjects() {
g_shader = &g_pHyprOpenGL->m_shaders->m_shRGBA;
std::vector<float> finalVerts;
{
const unsigned int vertsPerRow = g_SUBDIVS + 1;
std::vector<float> 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<unsigned int> 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) { APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
PHANDLE = handle; PHANDLE = handle;
@ -239,6 +378,8 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
throw std::runtime_error("[WiggleWobble] Version mismatch"); throw std::runtime_error("[WiggleWobble] Version mismatch");
} }
initGPUObjects();
g_openWindow = HyprlandAPI::registerCallbackDynamic( g_openWindow = HyprlandAPI::registerCallbackDynamic(
PHANDLE, PHANDLE,
"openWindow", "openWindow",