ADD: Hover effect for Buttons

This commit is contained in:
sebastian 2026-02-12 18:44:55 +01:00
parent fa85eaf116
commit d7ea3b7e3c
15 changed files with 86 additions and 15 deletions

View File

@ -6,6 +6,18 @@ out vec4 color;
uniform sampler2D guiTexture; uniform sampler2D guiTexture;
uniform float brightness; // 1.0 = normal
uniform vec3 tintColor; // (0,0,0) = kein Tint
uniform float tintStrength; // 0.0 = aus
void main(void) { void main(void) {
color = texture(guiTexture, textureCoords); vec4 textureColor = texture(guiTexture, textureCoords);
textureColor.rgb *= brightness;
//Tint (Overlay)
textureColor.rgb = mix(textureColor.rgb, tintColor, tintStrength);
color = textureColor;
} }

View File

@ -4,7 +4,7 @@
#ifndef DICEWARS_SIEDLER_DIMENSIONS_H #ifndef DICEWARS_SIEDLER_DIMENSIONS_H
#define DICEWARS_SIEDLER_DIMENSIONS_H #define DICEWARS_SIEDLER_DIMENSIONS_H
#include <cstdio>
struct Dimensions { struct Dimensions {
float x, y; float x, y;
float width, height; float width, height;
@ -17,6 +17,7 @@ struct Dimensions {
} }
[[nodiscard]] bool contains(const float testX, const float testY) const { [[nodiscard]] bool contains(const float testX, const float testY) const {
//printf("Mouse(%f, %f); Button(x=%f, y=%f, width=%f, height=%f\n", testX, testY, x, y, width, height);
return testX >= x && testX <= x + width && testY >= y && testY <= y + height; return testX >= x && testX <= x + width && testY >= y && testY <= y + height;
} }
}; };

View File

@ -15,6 +15,13 @@ void UiButton::onCollectRenderData(UiRenderBundle &uiRenderBundle) {
glm::vec2 position = glm::vec2(uiPositioner.screenSpace.x, uiPositioner.screenSpace.y); glm::vec2 position = glm::vec2(uiPositioner.screenSpace.x, uiPositioner.screenSpace.y);
glm::vec2 size = glm::vec2(uiPositioner.screenSpace.width, uiPositioner.screenSpace.height); glm::vec2 size = glm::vec2(uiPositioner.screenSpace.width, uiPositioner.screenSpace.height);
if (isHovered()) {
float brightness = 1.15f;
float tintStrength = 0.f;
uiRenderBundle.addGUITexture(std::make_shared<GUITexture>(textureID, position, size, brightness, glm::vec3(0.3, 0.6, 1.0), tintStrength));
} else {
uiRenderBundle.addGUITexture(std::make_shared<GUITexture>(textureID, position, size)); uiRenderBundle.addGUITexture(std::make_shared<GUITexture>(textureID, position, size));
}
uiRenderBundle.addGUIText(std::make_shared<GUIText>(font, text, uiPositioner.screenSpace)); uiRenderBundle.addGUIText(std::make_shared<GUIText>(font, text, uiPositioner.screenSpace));
} }

View File

@ -4,6 +4,8 @@
#include "UiComponent.h" #include "UiComponent.h"
#include "../../../platform/glfw/InputManager.h"
void UiComponent::addChild(std::unique_ptr<UiComponent> child) { void UiComponent::addChild(std::unique_ptr<UiComponent> child) {
child->parent = this; child->parent = this;
children.emplace_back(std::move(child)); children.emplace_back(std::move(child));
@ -41,3 +43,9 @@ bool UiComponent::isMouseOver(float mouseX, float mouseY) {
if (!visible) return false; if (!visible) return false;
return uiPositioner.screenSpace.contains(mouseX, mouseY); return uiPositioner.screenSpace.contains(mouseX, mouseY);
} }
void UiComponent::onUpdate(float) {
glm::vec2 mousePos = InputManager::getMousePositionNormalized();
hovered = isMouseOver(mousePos.x, mousePos.y);
}

View File

@ -33,12 +33,13 @@ public:
void setLayoutStyle(const LayoutStyle& style) { void setLayoutStyle(const LayoutStyle& style) {
uiPositioner.setLayout(style); uiPositioner.setLayout(style);
} }
[[nodiscard]] bool isHovered() const { return hovered; }
protected: protected:
bool visible = true; bool visible = true;
bool hovered = false;
virtual void onUpdate(float /*delta*/) {} virtual void onUpdate(float );
virtual void onCollectRenderData(UiRenderBundle& uiRenderBundle) {} virtual void onCollectRenderData(UiRenderBundle& uiRenderBundle) {}
}; };

View File

@ -48,10 +48,6 @@ void UiPositioner::compute(const Dimensions &parent) {
float remainingSpace = ((style.flexDirection == FlexDirection::Column) ? screenSpace.height : screenSpace.width) - totalChildrenMainSize; float remainingSpace = ((style.flexDirection == FlexDirection::Column) ? screenSpace.height : screenSpace.width) - totalChildrenMainSize;
float gap =0.0f; float gap =0.0f;
if (uiComponent.parent == nullptr) {
printf("Test");
}
float justifyOffset = 0.0f; float justifyOffset = 0.0f;
switch (style.justifyContent) { switch (style.justifyContent) {
case JustifyContent::Start: justifyOffset = 0.0f; break; case JustifyContent::Start: justifyOffset = 0.0f; break;

View File

@ -24,6 +24,12 @@ glm::vec2 InputManager::getMousePosition() {
return {xpos, ypos}; return {xpos, ypos};
} }
glm::vec2 InputManager::getMousePositionNormalized() {
glm::vec2 mousePos = getMousePosition();
glm::vec2 windowSize = glm::vec2(Application::getInstance().getWindow().GetWidth(), Application::getInstance().getWindow().GetHeight());
return mousePos / windowSize;
}
glm::vec2 InputManager::getMouseDelta() { glm::vec2 InputManager::getMouseDelta() {
static double lastX = 0, lastY = 0; static double lastX = 0, lastY = 0;
double xpos, ypos; double xpos, ypos;

View File

@ -13,6 +13,7 @@ public:
static bool isMouseButtonPressed(int button); static bool isMouseButtonPressed(int button);
static glm::vec2 getMousePosition(); static glm::vec2 getMousePosition();
static glm::vec2 getMousePositionNormalized();
glm::vec2 getMouseDelta(); glm::vec2 getMouseDelta();
}; };

View File

@ -29,6 +29,7 @@ void GUIRenderer::render(std::vector<std::shared_ptr<GUITexture>>& gui_textures)
glBindTexture(GL_TEXTURE_2D, texture->getTextureID()); glBindTexture(GL_TEXTURE_2D, texture->getTextureID());
glm::mat4 transformationMatrix = MathUtils::createTransformationMatrix(texture->getPosition(), texture->getScale()); glm::mat4 transformationMatrix = MathUtils::createTransformationMatrix(texture->getPosition(), texture->getScale());
guiShader.loadTransformationMatrix(transformationMatrix); guiShader.loadTransformationMatrix(transformationMatrix);
guiShader.loadShaderEffect(texture->getBrightness(), texture->getTintColor(), texture->getTintStrength());
glDrawArrays(GL_TRIANGLE_STRIP, 0, rawModel->vertexCount); glDrawArrays(GL_TRIANGLE_STRIP, 0, rawModel->vertexCount);
} }
//render //render

View File

@ -92,18 +92,27 @@ void TextRenderer::renderGuiText(const GUIText &text) {
const Font& font = text.getFont(); const Font& font = text.getFont();
float scale = 1.0f; float scale = 1.0f;
float screenWidth = Application::getInstance().getWindow().GetWidth(); const auto screenWidth = static_cast<float>(Application::getInstance().getWindow().GetWidth());
float screenHeight = Application::getInstance().getWindow().GetHeight(); const auto screenHeight = static_cast<float>(Application::getInstance().getWindow().GetHeight());
float x = text.getPosition().x * screenWidth; float x = text.getPosition().x * screenWidth;
float y = (1.f - text.getPosition().y) * screenHeight; float y = (1.f - text.getPosition().y) * screenHeight;
float textWidth = font.getTextWidth(text.getText(), scale); const float textWidth = font.getTextWidth(text.getText(), scale);
float textHeight = font.getLineHeight();
const float buttonHeightPx = text.getSize().y * screenHeight;
const float ascent = font.getAscent();
const float descent = font.getDescent(); // negativ!
const float textVisualHeight = ascent - descent;
// Button-Mitte
const float buttonCenterY = y - buttonHeightPx * 0.5f;
// Zentrieren // Zentrieren
x += (text.getSize().x * screenWidth - textWidth) * 0.5f; x += (text.getSize().x * screenWidth - textWidth) * 0.5f;
y -= (text.getSize().y * screenHeight - textHeight) * 0.5f; y -= buttonCenterY + textVisualHeight * 0.5f - descent;
shader.loadTextColor(glm::vec3(1.0f)); shader.loadTextColor(glm::vec3(1.0f));

View File

@ -6,3 +6,7 @@
GUITexture::GUITexture(GLuint textureID, glm::vec2 position, glm::vec2 scale) : textureID(textureID), position(position), scale(scale){ GUITexture::GUITexture(GLuint textureID, glm::vec2 position, glm::vec2 scale) : textureID(textureID), position(position), scale(scale){
} }
GUITexture::GUITexture(GLuint textureID, glm::vec2 position, glm::vec2 scale, float brightness, glm::vec3 tintColor,
float tintStrength) : textureID(textureID), position(position), scale(scale), brightness(brightness), tintColor(tintColor), tintStrength(tintStrength){
}

View File

@ -6,6 +6,7 @@
#define GUITEXTURE_H #define GUITEXTURE_H
#include "glad/glad.h" #include "glad/glad.h"
#include "glm/vec2.hpp" #include "glm/vec2.hpp"
#include "glm/vec3.hpp"
class GUITexture { class GUITexture {
@ -14,12 +15,20 @@ private:
const glm::vec2 position; const glm::vec2 position;
const glm::vec2 scale; const glm::vec2 scale;
float brightness = 1.0f;
float tintStrength = 0.0f;
glm::vec3 tintColor = glm::vec3(0.3, 0.6, 1.0);
public: public:
GUITexture(GLuint textureID, glm::vec2 position, glm::vec2 scale); GUITexture(GLuint textureID, glm::vec2 position, glm::vec2 scale);
GUITexture(GLuint textureID, glm::vec2 position, glm::vec2 scale, float brightness, glm::vec3 tintColor, float tintStrength);
[[nodiscard]] GLuint getTextureID() const {return textureID;} [[nodiscard]] GLuint getTextureID() const {return textureID;}
[[nodiscard]] glm::vec2 getPosition() const {return position;} [[nodiscard]] glm::vec2 getPosition() const {return position;}
[[nodiscard]] glm::vec2 getScale() const {return scale;} [[nodiscard]] glm::vec2 getScale() const {return scale;}
[[nodiscard]] float getBrightness() const {return brightness;}
[[nodiscard]] glm::vec3 getTintColor() const {return tintColor;}
[[nodiscard]] float getTintStrength() const {return tintStrength;}
}; };

View File

@ -8,8 +8,18 @@ void GUIShader::loadTransformationMatrix(glm::mat4 matrix) {
ShaderProgram::loadMatrix(location_transformationMatrix, matrix); ShaderProgram::loadMatrix(location_transformationMatrix, matrix);
} }
void GUIShader::loadShaderEffect(float brightness, glm::vec3 tintColor, float tintStrength) {
ShaderProgram::loadFloat(location_brightness, brightness);
ShaderProgram::loadVector(location_tintColor, tintColor);
ShaderProgram::loadFloat(location_tintStrength, tintStrength);
}
void GUIShader::getAllUniformLocations() { void GUIShader::getAllUniformLocations() {
location_transformationMatrix = ShaderProgram::getUniformLocation("transformationMatrix"); location_transformationMatrix = ShaderProgram::getUniformLocation("transformationMatrix");
location_brightness = ShaderProgram::getUniformLocation("brightness");
location_tintColor = ShaderProgram::getUniformLocation("tintColor");
location_tintStrength = ShaderProgram::getUniformLocation("tintStrength");
} }
void GUIShader::bindAttributes() const { void GUIShader::bindAttributes() const {

View File

@ -14,12 +14,17 @@ public:
GUIShader::getAllUniformLocations(); GUIShader::getAllUniformLocations();
}; };
void loadTransformationMatrix(glm::mat4 matrix); void loadTransformationMatrix(glm::mat4 matrix);
void loadShaderEffect(float brightness, glm::vec3 tintColor, float tintStrength);
private: private:
inline static const std::string VERTEX_FILE = "assets/shaders/guiVertexShader.glsl"; inline static const std::string VERTEX_FILE = "assets/shaders/guiVertexShader.glsl";
inline static const std::string FRAGMENT_FILE = "assets/shaders/guiFragmentShader.glsl"; inline static const std::string FRAGMENT_FILE = "assets/shaders/guiFragmentShader.glsl";
int location_transformationMatrix; int location_transformationMatrix;
int location_brightness;
int location_tintColor;
int location_tintStrength;
protected: protected:
void getAllUniformLocations() override; void getAllUniformLocations() override;
void bindAttributes() const override; void bindAttributes() const override;

View File

@ -59,6 +59,7 @@ void UILayer::onUpdate() {
Layer::onUpdate(); Layer::onUpdate();
Dimensions rootParent {0.0, 0.0, 1.0, 1.0f}; Dimensions rootParent {0.0, 0.0, 1.0, 1.0f};
rootContainer->uiPositioner.compute(rootParent); rootContainer->uiPositioner.compute(rootParent);
rootContainer->update(0.f); //Todo: Determine frame time
UiRenderBundle renderBundle; UiRenderBundle renderBundle;
if (rootContainer) { if (rootContainer) {