Files
eiifwhrn-game-engine-edition/Gui.h
T
2026-06-08 17:07:34 -04:00

222 lines
7.1 KiB
C++

#ifndef BOX_CLASS
#define BOX_CLASS
#include <iostream>
#include "common.h"
#include "VAO.h"
#include "VBO.h"
#include "QuadVertices.h"
#include "shaderClass.h"
#include "texture.h"
#include "t2d.h"
#include "font.h"
#include "RenderSystem.h"
#include "Object.h"
class Box : public Renderable, public Object {
public:
VAO boxVAO;
VBO boxVBO;
glm::vec3 Color = { 1.0f, 1.0f, 1.0f };
float Opacity = 1.0f;
t2d_package t2d;
float z = 0.0f;
float rotation = 0.0f;
float rounding = 0.0f;
Box() {
shadertype = ShaderType::BoxShader;
boxVBO.GenerateID();
boxVAO.GenerateID();
boxVAO.Bind();
boxVBO.BufferData(&quadVertices, sizeof(quadVertices));
boxVAO.LinkVBO(boxVBO, 0, 2, GL_FLOAT, 4 * sizeof(float), (void*)0);
boxVAO.LinkVBO(boxVBO, 1, 2, GL_FLOAT, 4 * sizeof(float), (void*)(2 * sizeof(float)));
}
virtual void Render(Shader& ShaderProgram) override {
if (Opacity <= 0.0f) return;
ShaderProgram.Activate();
t2d.Recalculate();
ShaderProgram.Set4F("Color", { Color, Opacity });
ShaderProgram.Set2F("normalizedCenterScale", t2d.NormalizedCenterScale);
ShaderProgram.Set2F("normalizedCenterPos", t2d.NormalizedCenterPos);
ShaderProgram.Set1F("z", z);
ShaderProgram.Set1F("rotation", rotation);
ShaderProgram.Set2F("pixelScale", t2d.pixelsize);
ShaderProgram.Set2F("pixelPos", t2d.pixelposition);
ShaderProgram.Set1F("rounding", rounding);
boxVAO.Bind();
glDrawArrays(GL_TRIANGLES, 0, 6);
boxVAO.Unbind();
}
};
class BoxButton : public Box {
public:
bool clicked = false;
void UpdateClicked(float mousex, float mousey) {
if (mousex > t2d.pixelposition.x && mousey > t2d.pixelposition.y &&
mousex < t2d.pixelposition.x + t2d.pixelsize.x &&
mousey < t2d.pixelposition.y + t2d.pixelsize.y)
{
clicked = true;
std::cout << "CLICKED\n";
}
else {
clicked = false;
}
}
BoxButton() {}
};
class TextBox : public Box {
public:
Font* font = nullptr;
std::string text;
float fontsize = 1.0f;
// textCenter: 0,0 = text top-left anchored to box top-left
// 0.5,0.5 = text centered in box
// 1,1 = text bottom-right anchored to box bottom-right
glm::vec2 textCenter = { 0.0f, 0.0f };
TextBox() {
shadertype = ShaderType::TextShader;
}
virtual void Render(Shader& ShaderProgram) override {
if (!font || Opacity <= 0.0f) return;
t2d.Recalculate();
// Box bounds in pixels
const float boxLeft = t2d.pixelposition.x;
const float boxTop = t2d.pixelposition.y;
const float boxRight = boxLeft + t2d.pixelsize.x;
const float boxBottom = boxTop + t2d.pixelsize.y;
// Split text into lines
std::vector<std::string> lines;
std::string current;
for (char c : text) {
if (c == '\n') { lines.push_back(current); current.clear(); }
else current += c;
}
lines.push_back(current);
// Measure line height
float lineHeight = 0.0f;
for (auto& [key, ch] : font->Characters)
lineHeight = glm::max(lineHeight, (float)ch.Size.y * fontsize);
const float lineSpacing = lineHeight * 1.2f;
const float totalBlockH = lineSpacing * (float)lines.size();
// Vertical start: textCenter.y controls where the block sits inside the box
// 0 = top, 0.5 = center, 1 = bottom
float blockTop = boxTop + (t2d.pixelsize.y - totalBlockH) * textCenter.y;
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Scissor to clip text to box bounds
glEnable(GL_SCISSOR_TEST);
glScissor(
(GLint)boxLeft,
(GLint)(window->height - boxBottom), // OpenGL scissor Y is from bottom
(GLsizei)t2d.pixelsize.x,
(GLsizei)t2d.pixelsize.y
);
ShaderProgram.Activate();
ShaderProgram.Set4F("textColor", { Color, Opacity });
ShaderProgram.Set2F("screenSize", glm::vec2(window->width, window->height));
ShaderProgram.SetInt("text", 0);
glActiveTexture(GL_TEXTURE0);
font->vao.Bind();
for (int i = 0; i < (int)lines.size(); i++) {
// Measure this line's width
float lineWidth = 0.0f;
for (char c : lines[i])
lineWidth += (float)(font->Characters[(unsigned char)c].Advance >> 6) * fontsize;
// Horizontal start: textCenter.x controls where the line sits inside the box
float x = boxLeft + (t2d.pixelsize.x - lineWidth) * textCenter.x;
float y = blockTop + lineSpacing * (float)i;
for (char c : lines[i]) {
TextCharacter ch = font->Characters[(unsigned char)c];
if (ch.Size.x == 0 || ch.Size.y == 0) {
x += (float)(ch.Advance >> 6) * fontsize;
continue;
}
float x0 = x + ch.Bearing.x * fontsize;
float y0 = y + (ch.Size.y - ch.Bearing.y) * fontsize;
float x1 = x0 + ch.Size.x * fontsize;
float y1 = y0 - ch.Size.y * fontsize;
float vertices[6][4] = {
{ x0, y1, 0.0f, 0.0f },
{ x0, y0, 0.0f, 1.0f },
{ x1, y0, 1.0f, 1.0f },
{ x0, y1, 0.0f, 0.0f },
{ x1, y0, 1.0f, 1.0f },
{ x1, y1, 1.0f, 0.0f }
};
glBindTexture(GL_TEXTURE_2D, ch.TextureID);
font->vbo.Bind();
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
font->vbo.Unbind();
glDrawArrays(GL_TRIANGLES, 0, 6);
x += (float)(ch.Advance >> 6) * fontsize;
}
}
font->vao.Unbind();
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_SCISSOR_TEST);
}
};
class ImageBox : public Box {
public:
Texture* tex = nullptr;
ImageBox() {
shadertype = ShaderType::ImageBoxShader;
}
virtual void Render(Shader& ShaderProgram) override {
if (Opacity <= 0.0f) return;
ShaderProgram.Activate();
t2d.Recalculate();
ShaderProgram.Set4F("Color", { Color, Opacity });
ShaderProgram.Set2F("normalizedCenterScale", t2d.NormalizedCenterScale);
ShaderProgram.Set2F("normalizedCenterPos", t2d.NormalizedCenterPos);
ShaderProgram.Set1F("z", z);
ShaderProgram.Set1F("rotation", rotation);
ShaderProgram.Set2F("pixelScale", t2d.pixelsize);
ShaderProgram.Set2F("pixelPos", t2d.pixelposition);
ShaderProgram.Set1F("rounding", rounding);
glActiveTexture(GL_TEXTURE0);
if (tex) {
glBindTexture(GL_TEXTURE_2D, tex->ID);
ShaderProgram.SetInt("tex", 0);
}
else {
glBindTexture(GL_TEXTURE_2D, 0);
}
boxVAO.Bind();
glDrawArrays(GL_TRIANGLES, 0, 6);
boxVAO.Unbind();
}
};
#endif