diff --git a/Notes b/Notes new file mode 100644 index 00000000..938e1eaa --- /dev/null +++ b/Notes @@ -0,0 +1,8 @@ +Notes + +• GUI Texture: + +• Button: 200x20 (0;46, 0;66, 0;86) +• Hotbar: 182x22 +• Selection: 24x24 (0;22) + diff --git a/TODO b/TODO index 8cd02cb2..b86accbd 100644 --- a/TODO +++ b/TODO @@ -9,7 +9,7 @@ TODO • TODO: Remplacer les anciennes classes par leur upgrade: ◦ DONE: `ApplicationState` / `ApplicationStateStack` ◦ DONE: `GameClock` - ◦ TODO: `Window` (depuis `ZeldaOOL`) + ◦ TODO: `Window` et `Texture` (depuis `ZeldaOOL`) ◦ TODO: `Debug` / `Exception` ◦ TODO: Input system (Mouse + Keyboard) • TODO: Catch SDLLoader exception diff --git a/include/core/Rect.hpp b/include/core/Rect.hpp new file mode 100644 index 00000000..c44f6402 --- /dev/null +++ b/include/core/Rect.hpp @@ -0,0 +1,115 @@ +/* + * ===================================================================================== + * + * Filename: Rect.hpp + * + * Description: + * + * Created: 15/09/2014 22:13:37 + * + * Author: Quentin Bazin, + * + * ===================================================================================== + */ +#ifndef RECT_HPP_ +#define RECT_HPP_ + +#include + +// #include "Vector2.hpp" + +template +class Rect { + public: + Rect() = default; + + Rect(T _x, T _y, T _width, T _height) { + reset(_x, _y, _width, _height); + } + + // Rect(const Vector2 &_position, const Vector2 &_size) { + // reset(_position.x, _position.y, _size.x, _size.y); + // } + + template + Rect(const Rect &rect) + : Rect(rect.x, rect.y, rect.width, rect.height) {} + + void reset(T _x, T _y, T _width, T _height) { + x = _x; + y = _y; + width = _width; + height = _height; + } + + void reset(Rect rect) { reset(rect.x, rect.y, rect.width, rect.height); } + + void move(T _x, T _y) { x += _x; y += _y; } + // void move(Vector2 d) { move(d.x, d.y); } + + bool intersects(const Rect &rect) const { + T r1MinX = std::min(x, static_cast(x + width)); + T r1MaxX = std::max(x, static_cast(x + width)); + T r1MinY = std::min(y, static_cast(y + height)); + T r1MaxY = std::max(y, static_cast(y + height)); + + T r2MinX = std::min(rect.x, static_cast(rect.x + rect.width)); + T r2MaxX = std::max(rect.x, static_cast(rect.x + rect.width)); + T r2MinY = std::min(rect.y, static_cast(rect.y + rect.height)); + T r2MaxY = std::max(rect.y, static_cast(rect.y + rect.height)); + + T interLeft = std::max(r1MinX, r2MinX); + T interTop = std::max(r1MinY, r2MinY); + T interRight = std::min(r1MaxX, r2MaxX); + T interBottom = std::min(r1MaxY, r2MaxY); + + return interLeft < interRight && interTop < interBottom; + } + + T intersectionDirection(const Rect &rect) const { + T r1MinX = std::min(x, static_cast(x + width)); + T r1MaxX = std::max(x, static_cast(x + width)); + T r1MinY = std::min(y, static_cast(y + height)); + T r1MaxY = std::max(y, static_cast(y + height)); + + T r2MinX = std::min(rect.x, static_cast(rect.x + rect.width)); + T r2MaxX = std::max(rect.x, static_cast(rect.x + rect.width)); + T r2MinY = std::min(rect.y, static_cast(rect.y + rect.height)); + T r2MaxY = std::max(rect.y, static_cast(rect.y + rect.height)); + + T interLeft = std::max(r1MinX, r2MinX); + T interTop = std::max(r1MinY, r2MinY); + T interRight = std::min(r1MaxX, r2MaxX); + T interBottom = std::min(r1MaxY, r2MaxY); + + if(interLeft < interRight && interTop < interBottom) { + if(interRight - interLeft < interBottom - interTop) { + return 1; + } else { + return 2; + } + } else { + return 0; + } + } + + // Vector2 position() const { return {x, y}; } + + // void setPosition(Vector2 vector2) { x = vector2.x; y = vector2.y; } + + // Rect operator+(const Vector2 &vector2) const { return Rect{x + vector2.x, y + vector2.y, width, height}; } + // Rect operator-(const Vector2 &vector2) const { return Rect{x - vector2.x, y - vector2.y, width, height}; } + // + // Rect &operator+=(const Vector2 &vector2) { *this = operator+(vector2); return *this; } + // Rect &operator-=(const Vector2 &vector2) { *this = operator-(vector2); return *this; } + + T x = 0; + T y = 0; + T width = 0; + T height = 0; +}; + +using IntRect = Rect; +using FloatRect = Rect; + +#endif // RECT_HPP_ diff --git a/include/gl/Texture.hpp b/include/gl/Texture.hpp index 5246f7d3..8bd989df 100644 --- a/include/gl/Texture.hpp +++ b/include/gl/Texture.hpp @@ -21,9 +21,9 @@ class Texture { public: - Texture(); + Texture() = default; Texture(const std::string &filename); - ~Texture(); + ~Texture() noexcept; void load(const std::string &filename); diff --git a/include/hud/Hotbar.hpp b/include/hud/Hotbar.hpp new file mode 100644 index 00000000..5e239d6d --- /dev/null +++ b/include/hud/Hotbar.hpp @@ -0,0 +1,30 @@ +/* + * ===================================================================================== + * + * Filename: Hotbar.hpp + * + * Description: + * + * Created: 20/06/2018 05:40:05 + * + * Author: Quentin Bazin, + * + * ===================================================================================== + */ +#ifndef HOTBAR_HPP_ +#define HOTBAR_HPP_ + +#include "Image.hpp" + +class Hotbar : public IDrawable { + public: + Hotbar(); + + private: + void draw(RenderTarget &target, RenderStates states) const override; + + Texture m_texture; + Image m_background; +}; + +#endif // HOTBAR_HPP_ diff --git a/include/hud/Image.hpp b/include/hud/Image.hpp new file mode 100644 index 00000000..090fce1d --- /dev/null +++ b/include/hud/Image.hpp @@ -0,0 +1,51 @@ +/* + * ===================================================================================== + * + * Filename: Image.hpp + * + * Description: + * + * Created: 20/09/2014 16:21:56 + * + * Author: Quentin Bazin, + * + * ===================================================================================== + */ +#ifndef IMAGE_HPP_ +#define IMAGE_HPP_ + +#include "IDrawable.hpp" +#include "Rect.hpp" +#include "Texture.hpp" +#include "VertexBuffer.hpp" + +class Image : public IDrawable { + public: + Image() = default; + Image(const Texture &texture); + + void load(const Texture &texture); + + void setClipRect(float x, float y, u16 width, u16 height); + void setPosRect(float x, float y, u16 width, u16 height); + + u16 width() const { return m_width; } + u16 height() const { return m_height; } + + private: + void updateVertexBuffer() const; + + void draw(RenderTarget &target, RenderStates states) const override; + + const Texture *m_texture = nullptr; + + u16 m_width = 0; + u16 m_height = 0; + + FloatRect m_clipRect; + FloatRect m_posRect; + + VertexBuffer m_vbo; +}; + +#endif // IMAGE_HPP_ diff --git a/include/states/GameState.hpp b/include/states/GameState.hpp index 76cd5233..bc86e4f5 100644 --- a/include/states/GameState.hpp +++ b/include/states/GameState.hpp @@ -20,6 +20,7 @@ #include "BlockCursor.hpp" #include "Camera.hpp" #include "Crosshair.hpp" +#include "Hotbar.hpp" #include "Skybox.hpp" #include "World.hpp" @@ -54,6 +55,9 @@ class GameState : public ApplicationState { glm::vec4 m_selectedBlock{0, 0, 0, -1}; BlockCursor m_blockCursor{m_camera, m_world, m_viewMatrix, m_projectionMatrix}; Crosshair m_crosshair; + + Texture m_widgetTexture; + Hotbar m_hotbar; }; #endif // GAMESTATE_HPP_ diff --git a/shaders/game.f.glsl b/shaders/game.f.glsl index 7b46e39b..7e2b83ec 100644 --- a/shaders/game.f.glsl +++ b/shaders/game.f.glsl @@ -16,7 +16,7 @@ vec4 fog(vec4 color, float fogCoord, float fogStart, float fogEnd); void main() { // Discard if the pixel is too far away - if(v_dist > u_renderDistance) discard; + if(v_blockID != -1 && v_dist > u_renderDistance) discard; vec4 color = getColor(); if (v_blockID == 8) { diff --git a/source/gl/Texture.cpp b/source/gl/Texture.cpp index dcf61a56..4a581ca6 100644 --- a/source/gl/Texture.cpp +++ b/source/gl/Texture.cpp @@ -15,14 +15,12 @@ #include "SDLHeaders.hpp" #include "Texture.hpp" -Texture::Texture() { -} - Texture::Texture(const std::string &filename) { load(filename); } -Texture::~Texture() { +Texture::~Texture() noexcept { + glDeleteTextures(1, &m_texture); } void Texture::load(const std::string &filename) { diff --git a/source/hud/Hotbar.cpp b/source/hud/Hotbar.cpp new file mode 100644 index 00000000..b4c093cb --- /dev/null +++ b/source/hud/Hotbar.cpp @@ -0,0 +1,27 @@ +/* + * ===================================================================================== + * + * Filename: Hotbar.cpp + * + * Description: + * + * Created: 20/06/2018 05:40:47 + * + * Author: Quentin Bazin, + * + * ===================================================================================== + */ +#include "Config.hpp" +#include "Hotbar.hpp" + +Hotbar::Hotbar() { + m_texture.load("textures/widgets.png"); + m_background.load(m_texture); + m_background.setClipRect(0, 0, 182, 22); + m_background.setPosRect(SCREEN_WIDTH / 2 - 182 * 3 / 2, SCREEN_HEIGHT - 22 * 3, 182 * 3, 22 * 3); +} + +void Hotbar::draw(RenderTarget &target, RenderStates states) const { + target.draw(m_background, states); +} + diff --git a/source/hud/Image.cpp b/source/hud/Image.cpp new file mode 100644 index 00000000..0695f321 --- /dev/null +++ b/source/hud/Image.cpp @@ -0,0 +1,106 @@ +/* + * ===================================================================================== + * + * Filename: Image.cpp + * + * Description: + * + * Created: 20/09/2014 16:22:12 + * + * Author: Quentin Bazin, + * + * ===================================================================================== + */ +#define GLM_FORCE_RADIANS +#include + +#include "Application.hpp" +#include "Config.hpp" +#include "Image.hpp" +#include "Vertex.hpp" + +Image::Image(const Texture &texture) { + load(texture); +} + +void Image::load(const Texture &texture) { + m_texture = &texture; + + m_width = m_texture->width(); + m_height = m_texture->height(); + + m_posRect = FloatRect(0, 0, m_width, m_height); + m_clipRect = FloatRect(0, 0, m_width, m_height); + + updateVertexBuffer(); +} + +void Image::setClipRect(float x, float y, u16 width, u16 height) { + m_clipRect.reset(x, y, width, height); + + updateVertexBuffer(); +} + +void Image::setPosRect(float x, float y, u16 width, u16 height) { + m_posRect.reset(x, y, width, height); + + updateVertexBuffer(); +} + +void Image::updateVertexBuffer() const { + Vertex vertices[4] = { + {{m_posRect.width, 0, 0, -1}}, + {{0, 0, 0, -1}}, + {{0, m_posRect.height, 0, -1}}, + {{m_posRect.width, m_posRect.height, 0, -1}}, + }; + + FloatRect texRect = FloatRect( + m_clipRect.x / float(m_width), + m_clipRect.y / float(m_height), + m_clipRect.width / float(m_width), + m_clipRect.height / float(m_height) + ); + + vertices[0].texCoord[0] = texRect.x + texRect.width; + vertices[0].texCoord[1] = texRect.y; + vertices[1].texCoord[0] = texRect.x; + vertices[1].texCoord[1] = texRect.y; + vertices[2].texCoord[0] = texRect.x; + vertices[2].texCoord[1] = texRect.y + texRect.height; + vertices[3].texCoord[0] = texRect.x + texRect.width; + vertices[3].texCoord[1] = texRect.y + texRect.height; + + // GLubyte indices[] = { + // 0, 1, 3, + // 3, 1, 2 + // }; + + VertexBuffer::bind(&m_vbo); + m_vbo.setData(sizeof(vertices), vertices, GL_DYNAMIC_DRAW); + VertexBuffer::bind(nullptr); +} + +void Image::draw(RenderTarget &target, RenderStates states) const { + states.viewMatrix = nullptr; + + glm::mat4 projectionMatrix = glm::ortho(0.0f, (float)SCREEN_WIDTH, (float)SCREEN_HEIGHT, 0.0f); + states.projectionMatrix = &projectionMatrix; + + glm::mat4 modelMatrix = glm::translate(glm::mat4{1.0f}, glm::vec3{m_posRect.x, m_posRect.y, 0}); + states.modelMatrix = &modelMatrix; + + states.texture = m_texture; + + glDisable(GL_BLEND); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + + // glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices); + target.draw(m_vbo, GL_QUADS, 0, 4, states); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glEnable(GL_BLEND); +} + diff --git a/source/states/GameState.cpp b/source/states/GameState.cpp index 93e3320d..0963b696 100644 --- a/source/states/GameState.cpp +++ b/source/states/GameState.cpp @@ -82,5 +82,6 @@ void GameState::draw(RenderTarget &target, RenderStates states) const { target.draw(m_world, states); target.draw(m_crosshair, states); target.draw(m_blockCursor, states); + target.draw(m_hotbar, states); } diff --git a/textures/widgets.png b/textures/widgets.png new file mode 100644 index 00000000..e3c152c2 Binary files /dev/null and b/textures/widgets.png differ