From 4fb3a5ae0f53a6fa3f4901f92e64f1de8d2dbb17 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 29 Apr 2023 18:50:02 +0100 Subject: Dunno how, but some DOS new lines got in here! --- gfx/gl/camera.h | 156 ++++++++++++------------- gfx/models/mesh.cpp | 84 +++++++------- gfx/models/mesh.h | 50 ++++----- gfx/models/texture.cpp | 300 ++++++++++++++++++++++++------------------------- gfx/models/texture.h | 122 ++++++++++---------- ui/icon.cpp | 60 +++++----- ui/icon.h | 38 +++---- ui/window.cpp | 166 +++++++++++++-------------- ui/window.h | 88 +++++++-------- 9 files changed, 532 insertions(+), 532 deletions(-) diff --git a/gfx/gl/camera.h b/gfx/gl/camera.h index b5611f8..5c168e7 100644 --- a/gfx/gl/camera.h +++ b/gfx/gl/camera.h @@ -1,78 +1,78 @@ -#pragma once - -#include -#include -#include - -class Camera { -public: - Camera(glm::vec3 pos, float fov, float aspect, float zNear, float zFar); - - [[nodiscard]] glm::mat4 - getViewProjection() const - { - return viewProjection; - } - [[nodiscard]] Ray unProject(const glm::vec2 &) const; - - void - setPosition(const glm::vec3 & p) - { - position = p; - updateView(); - } - void - setForward(const glm::vec3 & f) - { - setForward(f, upFromForward(f)); - } - void - setForward(const glm::vec3 & f, const glm::vec3 & u) - { - forward = f; - up = u; - updateView(); - } - void - setView(const glm::vec3 & p, const glm::vec3 & f) - { - position = p; - setForward(f); - } - void - setView(const glm::vec3 & p, const glm::vec3 & f, const glm::vec3 & u) - { - position = p; - setView(f, u); - } - void - lookAt(const glm::vec3 & target) - { - setForward(glm::normalize(target - position)); - } - [[nodiscard]] auto - getForward() const - { - return forward; - } - [[nodiscard]] auto - getPosition() const - { - return position; - } - - [[nodiscard]] std::array extentsAtDist(float) const; - - [[nodiscard]] static glm::vec3 upFromForward(const glm::vec3 & forward); - -private: - void updateView(); - - glm::vec3 position; - glm::vec3 forward; - glm::vec3 up; - - float near, far; - glm::mat4 projection; - glm::mat4 viewProjection, inverseViewProjection; -}; +#pragma once + +#include +#include +#include + +class Camera { +public: + Camera(glm::vec3 pos, float fov, float aspect, float zNear, float zFar); + + [[nodiscard]] glm::mat4 + getViewProjection() const + { + return viewProjection; + } + [[nodiscard]] Ray unProject(const glm::vec2 &) const; + + void + setPosition(const glm::vec3 & p) + { + position = p; + updateView(); + } + void + setForward(const glm::vec3 & f) + { + setForward(f, upFromForward(f)); + } + void + setForward(const glm::vec3 & f, const glm::vec3 & u) + { + forward = f; + up = u; + updateView(); + } + void + setView(const glm::vec3 & p, const glm::vec3 & f) + { + position = p; + setForward(f); + } + void + setView(const glm::vec3 & p, const glm::vec3 & f, const glm::vec3 & u) + { + position = p; + setView(f, u); + } + void + lookAt(const glm::vec3 & target) + { + setForward(glm::normalize(target - position)); + } + [[nodiscard]] auto + getForward() const + { + return forward; + } + [[nodiscard]] auto + getPosition() const + { + return position; + } + + [[nodiscard]] std::array extentsAtDist(float) const; + + [[nodiscard]] static glm::vec3 upFromForward(const glm::vec3 & forward); + +private: + void updateView(); + + glm::vec3 position; + glm::vec3 forward; + glm::vec3 up; + + float near, far; + glm::mat4 projection; + glm::mat4 viewProjection, inverseViewProjection; +}; diff --git a/gfx/models/mesh.cpp b/gfx/models/mesh.cpp index 52c9275..7c5ddd4 100644 --- a/gfx/models/mesh.cpp +++ b/gfx/models/mesh.cpp @@ -1,42 +1,42 @@ -#include "mesh.h" -#include "gfx/gl/vertexArrayObject.hpp" -#include "glArrays.h" -#include "vertex.hpp" -#include - -Mesh::Mesh(const std::span vertices, const std::span indices, GLenum m) : - m_numIndices {static_cast(indices.size())}, mode {m} -{ - VertexArrayObject::data(vertices, m_vertexArrayBuffers[0], GL_ARRAY_BUFFER); - VertexArrayObject::data(indices, m_vertexArrayBuffers[1], GL_ARRAY_BUFFER); - configureVAO(m_vertexArrayObject); -} - -VertexArrayObject & -Mesh::configureVAO(VertexArrayObject && vao) const -{ - return vao - .addAttribs( - m_vertexArrayBuffers[0]) - .addIndices(m_vertexArrayBuffers[1]); -} - -void -Mesh::Draw() const -{ - glBindVertexArray(m_vertexArrayObject); - - glDrawElements(mode, m_numIndices, GL_UNSIGNED_INT, nullptr); - - glBindVertexArray(0); -} - -void -Mesh::DrawInstanced(GLuint vao, GLsizei count) const -{ - glBindVertexArray(vao); - - glDrawElementsInstanced(mode, m_numIndices, GL_UNSIGNED_INT, nullptr, count); - - glBindVertexArray(0); -} +#include "mesh.h" +#include "gfx/gl/vertexArrayObject.hpp" +#include "glArrays.h" +#include "vertex.hpp" +#include + +Mesh::Mesh(const std::span vertices, const std::span indices, GLenum m) : + m_numIndices {static_cast(indices.size())}, mode {m} +{ + VertexArrayObject::data(vertices, m_vertexArrayBuffers[0], GL_ARRAY_BUFFER); + VertexArrayObject::data(indices, m_vertexArrayBuffers[1], GL_ARRAY_BUFFER); + configureVAO(m_vertexArrayObject); +} + +VertexArrayObject & +Mesh::configureVAO(VertexArrayObject && vao) const +{ + return vao + .addAttribs( + m_vertexArrayBuffers[0]) + .addIndices(m_vertexArrayBuffers[1]); +} + +void +Mesh::Draw() const +{ + glBindVertexArray(m_vertexArrayObject); + + glDrawElements(mode, m_numIndices, GL_UNSIGNED_INT, nullptr); + + glBindVertexArray(0); +} + +void +Mesh::DrawInstanced(GLuint vao, GLsizei count) const +{ + glBindVertexArray(vao); + + glDrawElementsInstanced(mode, m_numIndices, GL_UNSIGNED_INT, nullptr, count); + + glBindVertexArray(0); +} diff --git a/gfx/models/mesh.h b/gfx/models/mesh.h index 538c57a..9b22b02 100644 --- a/gfx/models/mesh.h +++ b/gfx/models/mesh.h @@ -1,25 +1,25 @@ -#pragma once - -#include -#include -#include -#include -#include - -class Vertex; -class VertexArrayObject; - -class Mesh : public ConstTypeDefs { -public: - Mesh(const std::span vertices, const std::span indices, GLenum = GL_TRIANGLES); - - void Draw() const; - void DrawInstanced(GLuint vao, GLsizei count) const; - VertexArrayObject & configureVAO(VertexArrayObject &&) const; - -private: - glVertexArray m_vertexArrayObject; - glBuffers<2> m_vertexArrayBuffers; - GLsizei m_numIndices; - GLenum mode; -}; +#pragma once + +#include +#include +#include +#include +#include + +class Vertex; +class VertexArrayObject; + +class Mesh : public ConstTypeDefs { +public: + Mesh(const std::span vertices, const std::span indices, GLenum = GL_TRIANGLES); + + void Draw() const; + void DrawInstanced(GLuint vao, GLsizei count) const; + VertexArrayObject & configureVAO(VertexArrayObject &&) const; + +private: + glVertexArray m_vertexArrayObject; + glBuffers<2> m_vertexArrayBuffers; + GLsizei m_numIndices; + GLenum mode; +}; diff --git a/gfx/models/texture.cpp b/gfx/models/texture.cpp index e014f80..3003319 100644 --- a/gfx/models/texture.cpp +++ b/gfx/models/texture.cpp @@ -1,150 +1,150 @@ -#include "texture.h" -#include "glArrays.h" -#include "tga.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -Cache Texture::cachedTexture; - -GLint -TextureOptions::glMapMode(TextureOptions::MapMode mm) -{ - switch (mm) { - case MapMode::Repeat: - return GL_REPEAT; - case MapMode::Clamp: - return GL_CLAMP_TO_EDGE; - case MapMode::Mirror: - return GL_MIRRORED_REPEAT; - default: - throw std::domain_error("Invalid MapMode value"); - } -} - -Texture::Texture(const std::filesystem::path & fileName, TextureOptions to) : - Texture {Image {Resource::mapPath(fileName).c_str(), STBI_rgb_alpha}, to} -{ -} - -Texture::Texture(const Image & tex, TextureOptions to) : - Texture {static_cast(tex.width), static_cast(tex.height), tex.data.data(), to} -{ -} - -Texture::Texture(GLsizei width, GLsizei height, TextureOptions to) : Texture {width, height, nullptr, to} { } - -Texture::Texture(GLsizei width, GLsizei height, const void * data, TextureOptions to) : type {to.type} -{ - glBindTexture(type, m_texture); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - glTexParameteri(type, GL_TEXTURE_WRAP_S, TextureOptions::glMapMode(to.wrapU)); - glTexParameteri(type, GL_TEXTURE_WRAP_T, TextureOptions::glMapMode(to.wrapV)); - - glTexParameteri(type, GL_TEXTURE_MIN_FILTER, to.minFilter); - glTexParameteri(type, GL_TEXTURE_MAG_FILTER, to.magFilter); - glTexImage2D(type, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); -} - -void -Texture::bind(GLenum unit) const -{ - glActiveTexture(unit); - glBindTexture(type, m_texture); -} - -glm::ivec2 -Texture::getSize(const glTexture & texture) -{ - glm::ivec2 size; - glGetTextureLevelParameteriv(texture, 0, GL_TEXTURE_WIDTH, &size.x); - glGetTextureLevelParameteriv(texture, 0, GL_TEXTURE_HEIGHT, &size.y); - return size; -} - -void -Texture::save( - const glTexture & texture, GLenum format, GLenum type, uint8_t channels, const char * path, uint8_t tgaFormat) -{ - const auto size = getSize(texture); - const size_t dataSize = (static_cast(size.x * size.y * channels)); - const size_t fileSize = dataSize + sizeof(TGAHead); - - filesystem::fh out {path, O_RDWR | O_CREAT, 0660}; - out.truncate(fileSize); - auto tga = out.mmap(fileSize, 0, PROT_WRITE, MAP_SHARED); - *tga.get() = { - .format = tgaFormat, - .size = size, - .pixelDepth = static_cast(8 * channels), - }; - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glGetTextureImage(texture, 0, format, type, static_cast(dataSize), tga.get() + 1); - tga.msync(MS_ASYNC); -} - -void -Texture::save(const char * path) const -{ - save(m_texture, GL_BGR, GL_UNSIGNED_BYTE, 3, path, 2); -} - -void -Texture::save(const glTexture & texture, const char * path) -{ - save(texture, GL_BGR, GL_UNSIGNED_BYTE, 3, path, 2); -} - -void -Texture::saveDepth(const glTexture & texture, const char * path) -{ - save(texture, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 1, path, 3); -} - -void -Texture::saveNormal(const glTexture & texture, const char * path) -{ - save(texture, GL_BGR, GL_BYTE, 3, path, 2); -} - -TextureAtlas::TextureAtlas(GLsizei width, GLsizei height, GLuint count) : Texture(width, height, nullptr, {}) -{ - glBindTexture(GL_TEXTURE_RECTANGLE, m_atlas); - - glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA16UI, 2, static_cast(count), 0, GL_RGBA_INTEGER, - GL_UNSIGNED_BYTE, nullptr); -} - -void -TextureAtlas::bind(GLenum unit) const -{ - Texture::bind(unit); - glActiveTexture(unit + 1); - glBindTexture(GL_TEXTURE_RECTANGLE, m_atlas); -} - -GLuint -TextureAtlas::add(glm::ivec2 position, glm::ivec2 size, void * data, TextureOptions to) -{ - glTextureSubImage2D(m_texture, 0, position.x, position.y, size.x, size.y, GL_RGBA, GL_UNSIGNED_BYTE, data); - struct Material { - glm::vec<2, uint16_t> position, size; - TextureOptions::MapMode wrapU; - TextureOptions::MapMode wrapV; - } material {position, size, to.wrapU, to.wrapV}; - static_assert(sizeof(Material) <= 32); - glTextureSubImage2D(m_atlas, 0, 0, static_cast(used), 2, 1, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, &material); - return ++used; -} +#include "texture.h" +#include "glArrays.h" +#include "tga.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +Cache Texture::cachedTexture; + +GLint +TextureOptions::glMapMode(TextureOptions::MapMode mm) +{ + switch (mm) { + case MapMode::Repeat: + return GL_REPEAT; + case MapMode::Clamp: + return GL_CLAMP_TO_EDGE; + case MapMode::Mirror: + return GL_MIRRORED_REPEAT; + default: + throw std::domain_error("Invalid MapMode value"); + } +} + +Texture::Texture(const std::filesystem::path & fileName, TextureOptions to) : + Texture {Image {Resource::mapPath(fileName).c_str(), STBI_rgb_alpha}, to} +{ +} + +Texture::Texture(const Image & tex, TextureOptions to) : + Texture {static_cast(tex.width), static_cast(tex.height), tex.data.data(), to} +{ +} + +Texture::Texture(GLsizei width, GLsizei height, TextureOptions to) : Texture {width, height, nullptr, to} { } + +Texture::Texture(GLsizei width, GLsizei height, const void * data, TextureOptions to) : type {to.type} +{ + glBindTexture(type, m_texture); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glTexParameteri(type, GL_TEXTURE_WRAP_S, TextureOptions::glMapMode(to.wrapU)); + glTexParameteri(type, GL_TEXTURE_WRAP_T, TextureOptions::glMapMode(to.wrapV)); + + glTexParameteri(type, GL_TEXTURE_MIN_FILTER, to.minFilter); + glTexParameteri(type, GL_TEXTURE_MAG_FILTER, to.magFilter); + glTexImage2D(type, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); +} + +void +Texture::bind(GLenum unit) const +{ + glActiveTexture(unit); + glBindTexture(type, m_texture); +} + +glm::ivec2 +Texture::getSize(const glTexture & texture) +{ + glm::ivec2 size; + glGetTextureLevelParameteriv(texture, 0, GL_TEXTURE_WIDTH, &size.x); + glGetTextureLevelParameteriv(texture, 0, GL_TEXTURE_HEIGHT, &size.y); + return size; +} + +void +Texture::save( + const glTexture & texture, GLenum format, GLenum type, uint8_t channels, const char * path, uint8_t tgaFormat) +{ + const auto size = getSize(texture); + const size_t dataSize = (static_cast(size.x * size.y * channels)); + const size_t fileSize = dataSize + sizeof(TGAHead); + + filesystem::fh out {path, O_RDWR | O_CREAT, 0660}; + out.truncate(fileSize); + auto tga = out.mmap(fileSize, 0, PROT_WRITE, MAP_SHARED); + *tga.get() = { + .format = tgaFormat, + .size = size, + .pixelDepth = static_cast(8 * channels), + }; + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glGetTextureImage(texture, 0, format, type, static_cast(dataSize), tga.get() + 1); + tga.msync(MS_ASYNC); +} + +void +Texture::save(const char * path) const +{ + save(m_texture, GL_BGR, GL_UNSIGNED_BYTE, 3, path, 2); +} + +void +Texture::save(const glTexture & texture, const char * path) +{ + save(texture, GL_BGR, GL_UNSIGNED_BYTE, 3, path, 2); +} + +void +Texture::saveDepth(const glTexture & texture, const char * path) +{ + save(texture, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 1, path, 3); +} + +void +Texture::saveNormal(const glTexture & texture, const char * path) +{ + save(texture, GL_BGR, GL_BYTE, 3, path, 2); +} + +TextureAtlas::TextureAtlas(GLsizei width, GLsizei height, GLuint count) : Texture(width, height, nullptr, {}) +{ + glBindTexture(GL_TEXTURE_RECTANGLE, m_atlas); + + glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA16UI, 2, static_cast(count), 0, GL_RGBA_INTEGER, + GL_UNSIGNED_BYTE, nullptr); +} + +void +TextureAtlas::bind(GLenum unit) const +{ + Texture::bind(unit); + glActiveTexture(unit + 1); + glBindTexture(GL_TEXTURE_RECTANGLE, m_atlas); +} + +GLuint +TextureAtlas::add(glm::ivec2 position, glm::ivec2 size, void * data, TextureOptions to) +{ + glTextureSubImage2D(m_texture, 0, position.x, position.y, size.x, size.y, GL_RGBA, GL_UNSIGNED_BYTE, data); + struct Material { + glm::vec<2, uint16_t> position, size; + TextureOptions::MapMode wrapU; + TextureOptions::MapMode wrapV; + } material {position, size, to.wrapU, to.wrapV}; + static_assert(sizeof(Material) <= 32); + glTextureSubImage2D(m_atlas, 0, 0, static_cast(used), 2, 1, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, &material); + return ++used; +} diff --git a/gfx/models/texture.h b/gfx/models/texture.h index 86e76a0..1b66c64 100644 --- a/gfx/models/texture.h +++ b/gfx/models/texture.h @@ -1,61 +1,61 @@ -#pragma once - -#include -#include -#include -#include - -// IWYU pragma: no_forward_declare Cache -class Image; - -struct TextureOptions { - enum class MapMode { - Repeat, - Clamp, - Mirror, - Decal, - }; - MapMode wrapU {MapMode::Repeat}, wrapV {MapMode::Repeat}; - GLint minFilter {GL_LINEAR}, magFilter {GL_LINEAR}; - GLenum type {GL_TEXTURE_2D}; - static GLint glMapMode(MapMode); -}; - -class Texture { -public: - virtual ~Texture() = default; - DEFAULT_MOVE_NO_COPY(Texture); - - explicit Texture(const std::filesystem::path & fileName, TextureOptions = {}); - explicit Texture(const Image & image, TextureOptions = {}); - explicit Texture(GLsizei width, GLsizei height, TextureOptions = {}); - explicit Texture(GLsizei width, GLsizei height, const void * data, TextureOptions = {}); - - static Cache cachedTexture; - - virtual void bind(GLenum unit = GL_TEXTURE0) const; - - void save(const char * path) const; - static void save(const glTexture &, const char * path); - static void saveDepth(const glTexture &, const char * path); - static void saveNormal(const glTexture &, const char * path); - -protected: - static void save(const glTexture &, GLenum, GLenum, uint8_t channels, const char * path, uint8_t tgaFormat); - static glm::ivec2 getSize(const glTexture &); - - glTexture m_texture; - GLenum type; -}; - -class TextureAtlas : public Texture { -public: - TextureAtlas(GLsizei width, GLsizei height, GLuint count); - - void bind(GLenum unit = GL_TEXTURE0) const override; - GLuint add(glm::ivec2 position, glm::ivec2 size, void * data, TextureOptions = {}); - -private: - glTexture m_atlas; - GLuint used {}; -}; +#pragma once + +#include +#include +#include +#include + +// IWYU pragma: no_forward_declare Cache +class Image; + +struct TextureOptions { + enum class MapMode { + Repeat, + Clamp, + Mirror, + Decal, + }; + MapMode wrapU {MapMode::Repeat}, wrapV {MapMode::Repeat}; + GLint minFilter {GL_LINEAR}, magFilter {GL_LINEAR}; + GLenum type {GL_TEXTURE_2D}; + static GLint glMapMode(MapMode); +}; + +class Texture { +public: + virtual ~Texture() = default; + DEFAULT_MOVE_NO_COPY(Texture); + + explicit Texture(const std::filesystem::path & fileName, TextureOptions = {}); + explicit Texture(const Image & image, TextureOptions = {}); + explicit Texture(GLsizei width, GLsizei height, TextureOptions = {}); + explicit Texture(GLsizei width, GLsizei height, const void * data, TextureOptions = {}); + + static Cache cachedTexture; + + virtual void bind(GLenum unit = GL_TEXTURE0) const; + + void save(const char * path) const; + static void save(const glTexture &, const char * path); + static void saveDepth(const glTexture &, const char * path); + static void saveNormal(const glTexture &, const char * path); + +protected: + static void save(const glTexture &, GLenum, GLenum, uint8_t channels, const char * path, uint8_t tgaFormat); + static glm::ivec2 getSize(const glTexture &); + + glTexture m_texture; + GLenum type; +}; + +class TextureAtlas : public Texture { +public: + TextureAtlas(GLsizei width, GLsizei height, GLuint count); + + void bind(GLenum unit = GL_TEXTURE0) const override; + GLuint add(glm::ivec2 position, glm::ivec2 size, void * data, TextureOptions = {}); + +private: + glTexture m_atlas; + GLuint used {}; +}; diff --git a/ui/icon.cpp b/ui/icon.cpp index ee88317..be1a63c 100644 --- a/ui/icon.cpp +++ b/ui/icon.cpp @@ -1,30 +1,30 @@ -#include "icon.h" -#include "glArrays.h" -#include -#include -#include -#include - -Icon::Icon(const std::filesystem::path & fileName) : Icon {Image {Resource::mapPath(fileName).c_str(), STBI_rgb_alpha}} -{ -} - -Icon::Icon(const Image & tex) : size {tex.width, tex.height} -{ - glBindTexture(GL_TEXTURE_2D, m_texture); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, static_cast(tex.width), static_cast(tex.height), 0, - GL_RGBA, GL_UNSIGNED_BYTE, tex.data.data()); -} - -void -Icon::Bind() const -{ - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, m_texture); -} +#include "icon.h" +#include "glArrays.h" +#include +#include +#include +#include + +Icon::Icon(const std::filesystem::path & fileName) : Icon {Image {Resource::mapPath(fileName).c_str(), STBI_rgb_alpha}} +{ +} + +Icon::Icon(const Image & tex) : size {tex.width, tex.height} +{ + glBindTexture(GL_TEXTURE_2D, m_texture); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, static_cast(tex.width), static_cast(tex.height), 0, + GL_RGBA, GL_UNSIGNED_BYTE, tex.data.data()); +} + +void +Icon::Bind() const +{ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_texture); +} diff --git a/ui/icon.h b/ui/icon.h index 961c11b..76cd3ae 100644 --- a/ui/icon.h +++ b/ui/icon.h @@ -1,19 +1,19 @@ -#pragma once - -#include -#include -#include - -class Image; - -class Icon { -public: - explicit Icon(const std::filesystem::path & fileName); - explicit Icon(const Image & image); - - void Bind() const; - const glm::vec2 size; - -private: - glTexture m_texture; -}; +#pragma once + +#include +#include +#include + +class Image; + +class Icon { +public: + explicit Icon(const std::filesystem::path & fileName); + explicit Icon(const Image & image); + + void Bind() const; + const glm::vec2 size; + +private: + glTexture m_texture; +}; diff --git a/ui/window.cpp b/ui/window.cpp index 5930292..ad071bb 100644 --- a/ui/window.cpp +++ b/ui/window.cpp @@ -1,83 +1,83 @@ -#include "window.h" -#include "uiComponent.h" -#include "worldOverlay.h" -#include -#include -#include -#include -#include - -Window::GlewInitHelper::GlewInitHelper() -{ - [[maybe_unused]] static auto init = []() { - if (const auto r = glewInit(); r != GLEW_OK) { - throw std::runtime_error {reinterpret_cast(glewGetErrorString(r))}; - } - else { - return r; - } - }(); -} - -Window::Window(size_t width, size_t height, const std::string & title, Uint32 flags) : - size {static_cast(width), static_cast(height)}, m_window {title.c_str(), - static_cast(SDL_WINDOWPOS_CENTERED), - static_cast(SDL_WINDOWPOS_CENTERED), size.x, - size.y, flags}, - glContext {m_window}, uiShader {width, height} -{ -} - -void -Window::clear(float r, float g, float b, float a) const -{ - glClearColor(r, g, b, a); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); -} - -void -Window::swapBuffers() const -{ - SDL_GL_SwapWindow(m_window); -} - -bool -Window::handleInput(const SDL_Event & e) -{ - if (SDL_GetWindowID(m_window) == e.window.windowID) { - SDL_Event eAdjusted {e}; - switch (e.type) { - // SDL and OpenGL have coordinates that are vertically opposed. - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - eAdjusted.button.y = size.y - e.button.y; - break; - case SDL_MOUSEMOTION: - eAdjusted.motion.y = size.y - e.motion.y; - break; - } - uiComponents.rapplyOne(&UIComponent::handleInput, eAdjusted, UIComponent::Position {{}, size}); - return true; - } - return false; -} - -void -Window::refresh() const -{ - SDL_GL_MakeCurrent(m_window, glContext); - clear(0.0F, 0.0F, 0.0F, 1.0F); - - render(); - - swapBuffers(); -} - -void -Window::render() const -{ - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_DEPTH_TEST); - uiComponents.apply(&UIComponent::render, uiShader, UIComponent::Position {}); -} +#include "window.h" +#include "uiComponent.h" +#include "worldOverlay.h" +#include +#include +#include +#include +#include + +Window::GlewInitHelper::GlewInitHelper() +{ + [[maybe_unused]] static auto init = []() { + if (const auto r = glewInit(); r != GLEW_OK) { + throw std::runtime_error {reinterpret_cast(glewGetErrorString(r))}; + } + else { + return r; + } + }(); +} + +Window::Window(size_t width, size_t height, const std::string & title, Uint32 flags) : + size {static_cast(width), static_cast(height)}, m_window {title.c_str(), + static_cast(SDL_WINDOWPOS_CENTERED), + static_cast(SDL_WINDOWPOS_CENTERED), size.x, + size.y, flags}, + glContext {m_window}, uiShader {width, height} +{ +} + +void +Window::clear(float r, float g, float b, float a) const +{ + glClearColor(r, g, b, a); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} + +void +Window::swapBuffers() const +{ + SDL_GL_SwapWindow(m_window); +} + +bool +Window::handleInput(const SDL_Event & e) +{ + if (SDL_GetWindowID(m_window) == e.window.windowID) { + SDL_Event eAdjusted {e}; + switch (e.type) { + // SDL and OpenGL have coordinates that are vertically opposed. + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + eAdjusted.button.y = size.y - e.button.y; + break; + case SDL_MOUSEMOTION: + eAdjusted.motion.y = size.y - e.motion.y; + break; + } + uiComponents.rapplyOne(&UIComponent::handleInput, eAdjusted, UIComponent::Position {{}, size}); + return true; + } + return false; +} + +void +Window::refresh() const +{ + SDL_GL_MakeCurrent(m_window, glContext); + clear(0.0F, 0.0F, 0.0F, 1.0F); + + render(); + + swapBuffers(); +} + +void +Window::render() const +{ + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_DEPTH_TEST); + uiComponents.apply(&UIComponent::render, uiShader, UIComponent::Position {}); +} diff --git a/ui/window.h b/ui/window.h index cb0118a..8b7d870 100644 --- a/ui/window.h +++ b/ui/window.h @@ -1,44 +1,44 @@ -#pragma once - -#include "chronology.hpp" -#include "collection.hpp" -#include "gfx/gl/uiShader.h" -#include "ptr.hpp" -#include "uiComponent.h" // IWYU pragma: keep -#include -#include -#include -#include - -using SDL_WindowPtr = wrapped_ptrt; -using GL_Context = std::remove_pointer_t; -using SDL_GLContextPtr = wrapped_ptrt; - -class Window { -public: - Window(size_t width, size_t height, const std::string & title, Uint32 flags); - virtual ~Window() = default; - - NO_COPY(Window); - NO_MOVE(Window); - - virtual void tick(TickDuration elapsed) = 0; - void refresh() const; - bool handleInput(const SDL_Event & e); - - void clear(float r, float g, float b, float a) const; - void swapBuffers() const; - -protected: - virtual void render() const; - struct GlewInitHelper { - GlewInitHelper(); - }; - - const glm::ivec2 size; - SDL_WindowPtr m_window; - SDL_GLContextPtr glContext; - GlewInitHelper glewinithelper; - Collection uiComponents; - UIShader uiShader; -}; +#pragma once + +#include "chronology.hpp" +#include "collection.hpp" +#include "gfx/gl/uiShader.h" +#include "ptr.hpp" +#include "uiComponent.h" // IWYU pragma: keep +#include +#include +#include +#include + +using SDL_WindowPtr = wrapped_ptrt; +using GL_Context = std::remove_pointer_t; +using SDL_GLContextPtr = wrapped_ptrt; + +class Window { +public: + Window(size_t width, size_t height, const std::string & title, Uint32 flags); + virtual ~Window() = default; + + NO_COPY(Window); + NO_MOVE(Window); + + virtual void tick(TickDuration elapsed) = 0; + void refresh() const; + bool handleInput(const SDL_Event & e); + + void clear(float r, float g, float b, float a) const; + void swapBuffers() const; + +protected: + virtual void render() const; + struct GlewInitHelper { + GlewInitHelper(); + }; + + const glm::ivec2 size; + SDL_WindowPtr m_window; + SDL_GLContextPtr glContext; + GlewInitHelper glewinithelper; + Collection uiComponents; + UIShader uiShader; +}; -- cgit v1.2.3