From 9aa09c55b0af4b8c4c14a4ac50fcb21f7eba492d Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 10 Apr 2023 18:36:53 +0100 Subject: Support loading textures from an in memory buffer --- gfx/image.cpp | 16 ++++++++++++++++ gfx/image.h | 1 + 2 files changed, 17 insertions(+) (limited to 'gfx') diff --git a/gfx/image.cpp b/gfx/image.cpp index e3e3b01..fb86cb6 100644 --- a/gfx/image.cpp +++ b/gfx/image.cpp @@ -19,6 +19,22 @@ Image::Image(const char * fileName, int flags) : width {}, height {}, numCompone data = {bytes, static_cast(width * height * numComponents)}; } +Image::Image(std::span buffer, int flags) +{ + stbi_set_flip_vertically_on_load(1); + int w, h, nc; + unsigned char * bytes = stbi_load_from_memory(buffer.data(), static_cast(buffer.size()), &w, &h, &nc, flags); + width = static_cast(w); + height = static_cast(h); + numComponents = static_cast(nc); + + if (!bytes) { + throw std::runtime_error {"Unable to load image from memory buffer "}; + } + + data = {bytes, static_cast(width * height * numComponents)}; +} + Image::~Image() { stbi_image_free(data.data()); diff --git a/gfx/image.h b/gfx/image.h index 47437ca..97c2731 100644 --- a/gfx/image.h +++ b/gfx/image.h @@ -8,6 +8,7 @@ class Image { public: Image(const char * fileName, int flags); Image(const std::string & fileName, int flags) : Image(fileName.c_str(), flags) { } + Image(std::span data, int flags); ~Image(); NO_COPY(Image); -- cgit v1.2.3 From 43d8fdb3f6aeb88762c68179d7bb1dc58507bb60 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 11 Apr 2023 18:54:41 +0100 Subject: Move lots of common glsl interface to include files --- gfx/gl/shaders/basicShader.fs | 5 +---- gfx/gl/shaders/basicShader.vs | 6 +----- gfx/gl/shaders/geometryOut.glsl | 3 +++ gfx/gl/shaders/landmassShader.fs | 5 +---- gfx/gl/shaders/landmassShader.vs | 6 +----- gfx/gl/shaders/meshIn.glsl | 4 ++++ gfx/gl/shaders/shadowDynamicPoint.vs | 2 +- gfx/gl/shaders/shadowFixedPoint.vs | 2 +- gfx/gl/shaders/waterShader.fs | 5 +---- gfx/gl/shaders/waterShader.vs | 5 +---- 10 files changed, 15 insertions(+), 28 deletions(-) create mode 100644 gfx/gl/shaders/geometryOut.glsl create mode 100644 gfx/gl/shaders/meshIn.glsl (limited to 'gfx') diff --git a/gfx/gl/shaders/basicShader.fs b/gfx/gl/shaders/basicShader.fs index 24b2791..0d0b904 100644 --- a/gfx/gl/shaders/basicShader.fs +++ b/gfx/gl/shaders/basicShader.fs @@ -4,10 +4,7 @@ in vec3 FragPos; in vec2 TexCoords; in vec3 Normal; in vec4 Colour; - -out vec4 gPosition; -out vec4 gNormal; -out vec4 gAlbedoSpec; +include(`geometryOut.glsl') uniform sampler2D texture0; diff --git a/gfx/gl/shaders/basicShader.vs b/gfx/gl/shaders/basicShader.vs index ff9a401..a96d478 100644 --- a/gfx/gl/shaders/basicShader.vs +++ b/gfx/gl/shaders/basicShader.vs @@ -1,10 +1,6 @@ #version 330 core -in vec3 position; -in vec2 texCoord; -in vec3 normal; -in vec4 colour; - +include(`meshIn.glsl') out vec3 FragPos; out vec2 TexCoords; out vec3 Normal; diff --git a/gfx/gl/shaders/geometryOut.glsl b/gfx/gl/shaders/geometryOut.glsl new file mode 100644 index 0000000..dc5f8e8 --- /dev/null +++ b/gfx/gl/shaders/geometryOut.glsl @@ -0,0 +1,3 @@ +layout(location = 0) out vec4 gPosition; +layout(location = 1) out vec4 gNormal; +layout(location = 2) out vec4 gAlbedoSpec; diff --git a/gfx/gl/shaders/landmassShader.fs b/gfx/gl/shaders/landmassShader.fs index 7c08e8e..5daeeb6 100644 --- a/gfx/gl/shaders/landmassShader.fs +++ b/gfx/gl/shaders/landmassShader.fs @@ -3,10 +3,7 @@ in vec3 FragPos; in vec2 TexCoords; in vec3 Normal; - -layout(location = 0) out vec4 gPosition; -layout(location = 1) out vec4 gNormal; -layout(location = 2) out vec4 gAlbedoSpec; +include(`geometryOut.glsl') uniform sampler2D texture0; diff --git a/gfx/gl/shaders/landmassShader.vs b/gfx/gl/shaders/landmassShader.vs index 30c4ef4..3eb9aa3 100644 --- a/gfx/gl/shaders/landmassShader.vs +++ b/gfx/gl/shaders/landmassShader.vs @@ -1,10 +1,6 @@ #version 330 core -in vec3 position; -in vec2 texCoord; -in vec3 normal; -in vec4 colour; - +include(`meshIn.glsl') out vec3 FragPos; out vec2 TexCoords; out vec3 Normal; diff --git a/gfx/gl/shaders/meshIn.glsl b/gfx/gl/shaders/meshIn.glsl new file mode 100644 index 0000000..2b244c1 --- /dev/null +++ b/gfx/gl/shaders/meshIn.glsl @@ -0,0 +1,4 @@ +layout(location = 0) in vec3 position; +layout(location = 1) in vec2 texCoord; +layout(location = 2) in vec3 normal; +layout(location = 3) in vec4 colour; diff --git a/gfx/gl/shaders/shadowDynamicPoint.vs b/gfx/gl/shaders/shadowDynamicPoint.vs index 6ea352f..531d8de 100644 --- a/gfx/gl/shaders/shadowDynamicPoint.vs +++ b/gfx/gl/shaders/shadowDynamicPoint.vs @@ -1,6 +1,6 @@ #version 330 core -in vec3 position; +include(`meshIn.glsl') uniform mat4 viewProjection; uniform mat4 model; diff --git a/gfx/gl/shaders/shadowFixedPoint.vs b/gfx/gl/shaders/shadowFixedPoint.vs index 246890c..c9fa19b 100644 --- a/gfx/gl/shaders/shadowFixedPoint.vs +++ b/gfx/gl/shaders/shadowFixedPoint.vs @@ -1,6 +1,6 @@ #version 330 core -layout(location = 0) in vec3 position; +include(`meshIn.glsl') uniform mat4 viewProjection; diff --git a/gfx/gl/shaders/waterShader.fs b/gfx/gl/shaders/waterShader.fs index d242566..d457f27 100644 --- a/gfx/gl/shaders/waterShader.fs +++ b/gfx/gl/shaders/waterShader.fs @@ -4,10 +4,7 @@ in vec3 FragPos; in vec2 TexCoords; in vec3 Normal; - -out vec4 gPosition; -out vec4 gNormal; -out vec4 gAlbedoSpec; +include(`geometryOut.glsl') uniform sampler2D texture0; uniform vec3 waves; diff --git a/gfx/gl/shaders/waterShader.vs b/gfx/gl/shaders/waterShader.vs index fe9206f..6f96c19 100644 --- a/gfx/gl/shaders/waterShader.vs +++ b/gfx/gl/shaders/waterShader.vs @@ -1,9 +1,6 @@ #version 330 core -in vec3 position; -in vec2 texCoord; -in vec3 normal; - +include(`meshIn.glsl') out vec3 FragPos; out vec2 TexCoords; out vec3 Normal; -- cgit v1.2.3 From d0186d81127056ac2647807dcf05b454e234a7cb Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 11 Apr 2023 22:54:44 +0100 Subject: Move the vertex/fragment shader interface for materials into an include --- gfx/gl/shaders/basicShader.fs | 5 +---- gfx/gl/shaders/basicShader.vs | 5 +---- gfx/gl/shaders/landmassShader.fs | 4 +--- gfx/gl/shaders/landmassShader.vs | 5 +---- gfx/gl/shaders/materialInterface.glsl | 4 ++++ gfx/gl/shaders/waterShader.fs | 4 +--- gfx/gl/shaders/waterShader.vs | 4 +--- 7 files changed, 10 insertions(+), 21 deletions(-) create mode 100644 gfx/gl/shaders/materialInterface.glsl (limited to 'gfx') diff --git a/gfx/gl/shaders/basicShader.fs b/gfx/gl/shaders/basicShader.fs index 0d0b904..8bb6350 100644 --- a/gfx/gl/shaders/basicShader.fs +++ b/gfx/gl/shaders/basicShader.fs @@ -1,9 +1,6 @@ #version 330 core -in vec3 FragPos; -in vec2 TexCoords; -in vec3 Normal; -in vec4 Colour; +include(`materialInterface.glsl') include(`geometryOut.glsl') uniform sampler2D texture0; diff --git a/gfx/gl/shaders/basicShader.vs b/gfx/gl/shaders/basicShader.vs index a96d478..4d648f3 100644 --- a/gfx/gl/shaders/basicShader.vs +++ b/gfx/gl/shaders/basicShader.vs @@ -1,10 +1,7 @@ #version 330 core include(`meshIn.glsl') -out vec3 FragPos; -out vec2 TexCoords; -out vec3 Normal; -out vec4 Colour; +include(`materialInterface.glsl') uniform mat4 viewProjection; uniform mat4 model; diff --git a/gfx/gl/shaders/landmassShader.fs b/gfx/gl/shaders/landmassShader.fs index 5daeeb6..f3cc3e8 100644 --- a/gfx/gl/shaders/landmassShader.fs +++ b/gfx/gl/shaders/landmassShader.fs @@ -1,8 +1,6 @@ #version 330 core -in vec3 FragPos; -in vec2 TexCoords; -in vec3 Normal; +include(`materialInterface.glsl') include(`geometryOut.glsl') uniform sampler2D texture0; diff --git a/gfx/gl/shaders/landmassShader.vs b/gfx/gl/shaders/landmassShader.vs index 3eb9aa3..cabe39f 100644 --- a/gfx/gl/shaders/landmassShader.vs +++ b/gfx/gl/shaders/landmassShader.vs @@ -1,10 +1,7 @@ #version 330 core include(`meshIn.glsl') -out vec3 FragPos; -out vec2 TexCoords; -out vec3 Normal; -out vec4 Colour; +include(`materialInterface.glsl') uniform mat4 viewProjection; diff --git a/gfx/gl/shaders/materialInterface.glsl b/gfx/gl/shaders/materialInterface.glsl new file mode 100644 index 0000000..3e09c85 --- /dev/null +++ b/gfx/gl/shaders/materialInterface.glsl @@ -0,0 +1,4 @@ +ifelse(TYPE, .fs, in, out) vec3 FragPos; +ifelse(TYPE, .fs, in, out) vec2 TexCoords; +ifelse(TYPE, .fs, in, out) vec3 Normal; +ifelse(TYPE, .fs, in, out) vec4 Colour; diff --git a/gfx/gl/shaders/waterShader.fs b/gfx/gl/shaders/waterShader.fs index d457f27..5936da4 100644 --- a/gfx/gl/shaders/waterShader.fs +++ b/gfx/gl/shaders/waterShader.fs @@ -1,9 +1,7 @@ #version 330 core #extension GL_ARB_shading_language_420pack : enable -in vec3 FragPos; -in vec2 TexCoords; -in vec3 Normal; +include(`materialInterface.glsl') include(`geometryOut.glsl') uniform sampler2D texture0; diff --git a/gfx/gl/shaders/waterShader.vs b/gfx/gl/shaders/waterShader.vs index 6f96c19..a21b49f 100644 --- a/gfx/gl/shaders/waterShader.vs +++ b/gfx/gl/shaders/waterShader.vs @@ -1,9 +1,7 @@ #version 330 core include(`meshIn.glsl') -out vec3 FragPos; -out vec2 TexCoords; -out vec3 Normal; +include(`materialInterface.glsl') uniform mat4 viewProjection; uniform vec3 waves; -- cgit v1.2.3 From 936f54e86f71d8e4af4784ebb32b6518c6fc3a01 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 13 Apr 2023 00:44:20 +0100 Subject: Fix submitting of integer values via vertex arrays --- gfx/gl/shaders/lightingShader.vs | 2 +- gfx/gl/vertexArrayObject.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'gfx') diff --git a/gfx/gl/shaders/lightingShader.vs b/gfx/gl/shaders/lightingShader.vs index 2271d2e..e07cd0a 100644 --- a/gfx/gl/shaders/lightingShader.vs +++ b/gfx/gl/shaders/lightingShader.vs @@ -1,6 +1,6 @@ #version 330 core -in vec4 position; +in ivec4 position; out vec2 TexCoords; diff --git a/gfx/gl/vertexArrayObject.hpp b/gfx/gl/vertexArrayObject.hpp index c0273c0..5b9fc60 100644 --- a/gfx/gl/vertexArrayObject.hpp +++ b/gfx/gl/vertexArrayObject.hpp @@ -61,7 +61,7 @@ private: { glEnableVertexAttribArray(vertexArrayId); using traits = gl_traits; - glVertexAttribPointer(vertexArrayId, traits::size, traits::type, GL_FALSE, sizeof(Vertex), ptr); + traits::vertexAttribFunc(vertexArrayId, traits::size, traits::type, sizeof(Vertex), ptr); } template -- cgit v1.2.3 From 1529d37d585ec38aee475519e444d2718a81fda5 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 13 Apr 2023 02:10:44 +0100 Subject: Add TextureAtlas class as an extension of Texture --- gfx/models/texture.cpp | 32 ++++++++++++++++++++++++++++++++ gfx/models/texture.h | 19 +++++++++++++++++-- 2 files changed, 49 insertions(+), 2 deletions(-) (limited to 'gfx') diff --git a/gfx/models/texture.cpp b/gfx/models/texture.cpp index efc76e1..a500fed 100644 --- a/gfx/models/texture.cpp +++ b/gfx/models/texture.cpp @@ -85,3 +85,35 @@ Texture::saveNormal(const glTexture & texture, const glm::ivec2 & size, const ch { save(texture, GL_BGR, GL_BYTE, size, 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) +{ + 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, unused1 {}, unused2 {}; + } material {position, size}; + 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 ffc9a4a..7900f17 100644 --- a/gfx/models/texture.h +++ b/gfx/models/texture.h @@ -16,6 +16,9 @@ struct TextureOptions { 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 = {}); @@ -23,17 +26,29 @@ public: static Cache cachedTexture; - void bind(GLenum unit = GL_TEXTURE0) const; + virtual void bind(GLenum unit = GL_TEXTURE0) const; void save(const glm::ivec2 & size, const char * path) const; static void save(const glTexture &, const glm::ivec2 & size, const char * path); static void saveDepth(const glTexture &, const glm::ivec2 & size, const char * path); static void saveNormal(const glTexture &, const glm::ivec2 & size, const char * path); -private: +protected: static void save(const glTexture &, GLenum, GLenum, const glm::ivec2 & size, unsigned short channels, const char * path, short tgaFormat); 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 {}; +}; -- cgit v1.2.3 From 259444e842ac4ec546948a8e828b62bec734f659 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 13 Apr 2023 02:13:20 +0100 Subject: Add material field to vertex and configure it in mesh --- gfx/models/mesh.cpp | 3 ++- gfx/models/vertex.hpp | 9 ++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'gfx') diff --git a/gfx/models/mesh.cpp b/gfx/models/mesh.cpp index 3db1ad5..2719211 100644 --- a/gfx/models/mesh.cpp +++ b/gfx/models/mesh.cpp @@ -7,7 +7,8 @@ Mesh::Mesh(const std::span vertices, const std::span indices, GLenum m) : m_numIndices {static_cast(indices.size())}, mode {m} { - VertexArrayObject::configure<&Vertex::pos, &Vertex::texCoord, &Vertex::normal, &Vertex::colour>( + VertexArrayObject::configure<&Vertex::pos, &Vertex::texCoord, &Vertex::normal, &Vertex::colour, + &Vertex::material>( m_vertexArrayObject, m_vertexArrayBuffers[0], m_vertexArrayBuffers[1], vertices, indices); } diff --git a/gfx/models/vertex.hpp b/gfx/models/vertex.hpp index 64ec3d0..181e7e7 100644 --- a/gfx/models/vertex.hpp +++ b/gfx/models/vertex.hpp @@ -1,12 +1,14 @@ #pragma once +#include #include class Vertex { public: #ifndef __cpp_aggregate_paren_init - constexpr Vertex(glm::vec3 pos, glm::vec2 texCoord, glm::vec3 normal, glm::vec4 colour = {}) : - pos {std::move(pos)}, texCoord {std::move(texCoord)}, normal {std::move(normal)}, colour {std::move(colour)} + constexpr Vertex(glm::vec3 pos, glm::vec2 texCoord, glm::vec3 normal, glm::vec4 colour = {}, GLuint material = 0) : + pos {std::move(pos)}, texCoord {std::move(texCoord)}, normal {std::move(normal)}, colour {std::move(colour)}, + material {material} { } #endif @@ -16,5 +18,6 @@ public: glm::vec3 pos; glm::vec2 texCoord; glm::vec3 normal; - glm::vec4 colour; + glm::vec4 colour {}; + GLuint material {}; }; -- cgit v1.2.3 From f16a7df6135262c91fee2a2f6c46ad2f3caa7157 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 13 Apr 2023 02:15:41 +0100 Subject: Update shaders to use material to conditionally lookup sub-texture in the atlas --- gfx/gl/shaders/basicShader.fs | 16 ++++++++++++++-- gfx/gl/shaders/basicShader.vs | 1 + gfx/gl/shaders/landmassShader.vs | 1 + gfx/gl/shaders/materialInterface.glsl | 3 +++ gfx/gl/shaders/meshIn.glsl | 1 + 5 files changed, 20 insertions(+), 2 deletions(-) (limited to 'gfx') diff --git a/gfx/gl/shaders/basicShader.fs b/gfx/gl/shaders/basicShader.fs index 8bb6350..ab5e58b 100644 --- a/gfx/gl/shaders/basicShader.fs +++ b/gfx/gl/shaders/basicShader.fs @@ -1,14 +1,26 @@ #version 330 core +#extension GL_ARB_shading_language_420pack : enable include(`materialInterface.glsl') include(`geometryOut.glsl') -uniform sampler2D texture0; +layout(binding = 0) uniform sampler2D texture0; +layout(binding = 1) uniform usampler2DRect material; + +vec4 getTextureColour(uint midx, vec2 uv) +{ + if (midx > 0u) { + const vec2 tSize = textureSize(texture0, 0); + const vec4 sPosSize = texture(material, uvec2(0, midx - 1u)); + uv = (sPosSize.xy + sPosSize.zw * fract(uv)) / tSize; + } + return texture(texture0, uv); +} void main() { - vec4 textureColour = texture(texture0, TexCoords); + vec4 textureColour = getTextureColour(Material, TexCoords); float clear = round(mix(textureColour.a, 1, Colour.a)); gPosition = vec4(FragPos, clear); gNormal = vec4(Normal, clear); diff --git a/gfx/gl/shaders/basicShader.vs b/gfx/gl/shaders/basicShader.vs index 4d648f3..e1701ed 100644 --- a/gfx/gl/shaders/basicShader.vs +++ b/gfx/gl/shaders/basicShader.vs @@ -15,6 +15,7 @@ main() TexCoords = texCoord; Normal = (model * vec4(normal, 0.0)).xyz; Colour = colour; + Material = material; gl_Position = viewProjection * worldPos; } diff --git a/gfx/gl/shaders/landmassShader.vs b/gfx/gl/shaders/landmassShader.vs index cabe39f..0cc8153 100644 --- a/gfx/gl/shaders/landmassShader.vs +++ b/gfx/gl/shaders/landmassShader.vs @@ -12,6 +12,7 @@ main() TexCoords = texCoord; Normal = normal; Colour = colour; + Material = material; gl_Position = viewProjection * vec4(position, 1.0); } diff --git a/gfx/gl/shaders/materialInterface.glsl b/gfx/gl/shaders/materialInterface.glsl index 3e09c85..5735cf9 100644 --- a/gfx/gl/shaders/materialInterface.glsl +++ b/gfx/gl/shaders/materialInterface.glsl @@ -2,3 +2,6 @@ ifelse(TYPE, .fs, in, out) vec3 FragPos; ifelse(TYPE, .fs, in, out) vec2 TexCoords; ifelse(TYPE, .fs, in, out) vec3 Normal; ifelse(TYPE, .fs, in, out) vec4 Colour; +flat +ifelse(TYPE, .fs, in, out) +uint Material; diff --git a/gfx/gl/shaders/meshIn.glsl b/gfx/gl/shaders/meshIn.glsl index 2b244c1..dd84a10 100644 --- a/gfx/gl/shaders/meshIn.glsl +++ b/gfx/gl/shaders/meshIn.glsl @@ -2,3 +2,4 @@ layout(location = 0) in vec3 position; layout(location = 1) in vec2 texCoord; layout(location = 2) in vec3 normal; layout(location = 3) in vec4 colour; +layout(location = 4) in uint material; -- cgit v1.2.3 From 2f5a53d9dfec54bd33609dbe5a0af44c565d8069 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 13 Apr 2023 17:53:38 +0100 Subject: Adjust gl_FragDepth according to texel opacity --- gfx/gl/shaders/basicShader.fs | 1 + 1 file changed, 1 insertion(+) (limited to 'gfx') diff --git a/gfx/gl/shaders/basicShader.fs b/gfx/gl/shaders/basicShader.fs index ab5e58b..ff1c822 100644 --- a/gfx/gl/shaders/basicShader.fs +++ b/gfx/gl/shaders/basicShader.fs @@ -24,5 +24,6 @@ main() float clear = round(mix(textureColour.a, 1, Colour.a)); gPosition = vec4(FragPos, clear); gNormal = vec4(Normal, clear); + gl_FragDepth = mix(1.0, gl_FragCoord.z, clear); gAlbedoSpec = mix(textureColour, vec4(Colour.rgb, 1), Colour.a); } -- cgit v1.2.3 From 31e2bd9b5738498be3d13dc96cc78f48825a8601 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 13 Apr 2023 18:02:28 +0100 Subject: Rename clear to opaque as its 1 for solid --- gfx/gl/shaders/basicShader.fs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'gfx') diff --git a/gfx/gl/shaders/basicShader.fs b/gfx/gl/shaders/basicShader.fs index ff1c822..8a72e6d 100644 --- a/gfx/gl/shaders/basicShader.fs +++ b/gfx/gl/shaders/basicShader.fs @@ -21,9 +21,9 @@ void main() { vec4 textureColour = getTextureColour(Material, TexCoords); - float clear = round(mix(textureColour.a, 1, Colour.a)); - gPosition = vec4(FragPos, clear); - gNormal = vec4(Normal, clear); - gl_FragDepth = mix(1.0, gl_FragCoord.z, clear); + float opaque = step(0.5, mix(textureColour.a, 1, Colour.a)); + gPosition = vec4(FragPos, opaque); + gNormal = vec4(Normal, opaque); + gl_FragDepth = mix(1.0, gl_FragCoord.z, opaque); gAlbedoSpec = mix(textureColour, vec4(Colour.rgb, 1), Colour.a); } -- cgit v1.2.3 From 0638aaaf2a60efae95a1b404d7eee29e894047bc Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Fri, 14 Apr 2023 01:54:19 +0100 Subject: No need to pass size around, we can get it back from the texture --- gfx/models/texture.cpp | 30 ++++++++++++++++++++---------- gfx/models/texture.h | 12 ++++++------ 2 files changed, 26 insertions(+), 16 deletions(-) (limited to 'gfx') diff --git a/gfx/models/texture.cpp b/gfx/models/texture.cpp index a500fed..ab256d5 100644 --- a/gfx/models/texture.cpp +++ b/gfx/models/texture.cpp @@ -44,12 +44,22 @@ Texture::bind(GLenum unit) const 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, const glm::ivec2 & size, unsigned short channels, - const char * path, short tgaFormat) +Texture::save(const glTexture & texture, GLenum format, GLenum type, unsigned short channels, const char * path, + short tgaFormat) { using TGAHead = std::array; + const auto size = getSize(texture); const size_t dataSize = (static_cast(size.x * size.y * channels)); const size_t fileSize = dataSize + sizeof(TGAHead); @@ -63,27 +73,27 @@ Texture::save(const glTexture & texture, GLenum format, GLenum type, const glm:: } void -Texture::save(const glm::ivec2 & size, const char * path) const +Texture::save(const char * path) const { - save(m_texture, GL_BGR, GL_UNSIGNED_BYTE, size, 3, path, 2); + save(m_texture, GL_BGR, GL_UNSIGNED_BYTE, 3, path, 2); } void -Texture::save(const glTexture & texture, const glm::ivec2 & size, const char * path) +Texture::save(const glTexture & texture, const char * path) { - save(texture, GL_BGR, GL_UNSIGNED_BYTE, size, 3, path, 2); + save(texture, GL_BGR, GL_UNSIGNED_BYTE, 3, path, 2); } void -Texture::saveDepth(const glTexture & texture, const glm::ivec2 & size, const char * path) +Texture::saveDepth(const glTexture & texture, const char * path) { - save(texture, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, size, 1, path, 3); + save(texture, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 1, path, 3); } void -Texture::saveNormal(const glTexture & texture, const glm::ivec2 & size, const char * path) +Texture::saveNormal(const glTexture & texture, const char * path) { - save(texture, GL_BGR, GL_BYTE, size, 3, path, 2); + save(texture, GL_BGR, GL_BYTE, 3, path, 2); } TextureAtlas::TextureAtlas(GLsizei width, GLsizei height, GLuint count) : Texture(width, height, nullptr, {}) diff --git a/gfx/models/texture.h b/gfx/models/texture.h index 7900f17..f4e1476 100644 --- a/gfx/models/texture.h +++ b/gfx/models/texture.h @@ -28,14 +28,14 @@ public: virtual void bind(GLenum unit = GL_TEXTURE0) const; - void save(const glm::ivec2 & size, const char * path) const; - static void save(const glTexture &, const glm::ivec2 & size, const char * path); - static void saveDepth(const glTexture &, const glm::ivec2 & size, const char * path); - static void saveNormal(const glTexture &, const glm::ivec2 & size, const char * path); + 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, const glm::ivec2 & size, unsigned short channels, - const char * path, short tgaFormat); + static void save(const glTexture &, GLenum, GLenum, unsigned short channels, const char * path, short tgaFormat); + static glm::ivec2 getSize(const glTexture &); glTexture m_texture; GLenum type; -- cgit v1.2.3 From c44e7537d027cba66abe564b247549040426ebfe Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Fri, 14 Apr 2023 02:56:33 +0100 Subject: Externalise a neater definition of TGAHead --- gfx/models/texture.cpp | 14 ++++++++------ gfx/models/texture.h | 2 +- gfx/models/tga.h | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 gfx/models/tga.h (limited to 'gfx') diff --git a/gfx/models/texture.cpp b/gfx/models/texture.cpp index ab256d5..3b27e77 100644 --- a/gfx/models/texture.cpp +++ b/gfx/models/texture.cpp @@ -1,5 +1,6 @@ #include "texture.h" #include "glArrays.h" +#include "tga.h" #include #include #include @@ -54,11 +55,9 @@ Texture::getSize(const glTexture & texture) } void -Texture::save(const glTexture & texture, GLenum format, GLenum type, unsigned short channels, const char * path, - short tgaFormat) +Texture::save( + const glTexture & texture, GLenum format, GLenum type, uint8_t channels, const char * path, uint8_t tgaFormat) { - using TGAHead = std::array; - const auto size = getSize(texture); const size_t dataSize = (static_cast(size.x * size.y * channels)); const size_t fileSize = dataSize + sizeof(TGAHead); @@ -66,8 +65,11 @@ Texture::save(const glTexture & texture, GLenum format, GLenum type, unsigned sh filesystem::fh out {path, O_RDWR | O_CREAT, 0660}; out.truncate(fileSize); auto tga = out.mmap(fileSize, 0, PROT_WRITE, MAP_SHARED); - *tga.get() = {0, tgaFormat, 0, 0, 0, 0, static_cast(size.x), static_cast(size.y), - static_cast(8 * channels)}; + *tga.get() = { + .format = tgaFormat, + .size = size, + .pixelDepth = static_cast(8 * channels), + }; glGetTextureImage(texture, 0, format, type, static_cast(dataSize), tga.get() + 1); tga.msync(MS_ASYNC); } diff --git a/gfx/models/texture.h b/gfx/models/texture.h index f4e1476..68ec649 100644 --- a/gfx/models/texture.h +++ b/gfx/models/texture.h @@ -34,7 +34,7 @@ public: static void saveNormal(const glTexture &, const char * path); protected: - static void save(const glTexture &, GLenum, GLenum, unsigned short channels, const char * path, short tgaFormat); + 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; diff --git a/gfx/models/tga.h b/gfx/models/tga.h new file mode 100644 index 0000000..1f400ef --- /dev/null +++ b/gfx/models/tga.h @@ -0,0 +1,14 @@ +#pragma once + +#include +#include + +struct TGAHead { + uint8_t idLength {}, colorMapType {}, format {}; + uint16_t __attribute__((packed)) colorMapFirst {}, colorMapLength {}; + uint8_t colorMapEntrySize {}; + glm::vec<2, uint16_t> origin {}, size {}; + uint8_t pixelDepth {}; + uint8_t descriptor {}; +}; +static_assert(sizeof(TGAHead) == 18); -- cgit v1.2.3 From 59733c3c3de7aa6dee5fde8e2a60b80b4c706583 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Fri, 14 Apr 2023 15:21:36 +0100 Subject: Set GL_PACK_ALIGNMENT before saving texture to fit buffer correctly --- gfx/models/texture.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'gfx') diff --git a/gfx/models/texture.cpp b/gfx/models/texture.cpp index 3b27e77..6319eb8 100644 --- a/gfx/models/texture.cpp +++ b/gfx/models/texture.cpp @@ -70,6 +70,7 @@ Texture::save( .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); } -- cgit v1.2.3 From b4ede2fd89d0effb44ebae15862427de9a147476 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Fri, 14 Apr 2023 16:34:56 +0100 Subject: Define our own enum for texture mapmode --- gfx/models/texture.cpp | 19 +++++++++++++++++-- gfx/models/texture.h | 9 ++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) (limited to 'gfx') diff --git a/gfx/models/texture.cpp b/gfx/models/texture.cpp index 6319eb8..e29fd6c 100644 --- a/gfx/models/texture.cpp +++ b/gfx/models/texture.cpp @@ -13,6 +13,21 @@ 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} { @@ -30,8 +45,8 @@ Texture::Texture(GLsizei width, GLsizei height, const void * data, TextureOption glBindTexture(type, m_texture); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glTexParameteri(type, GL_TEXTURE_WRAP_S, to.wrap); - glTexParameteri(type, GL_TEXTURE_WRAP_T, to.wrap); + 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); diff --git a/gfx/models/texture.h b/gfx/models/texture.h index 68ec649..86e76a0 100644 --- a/gfx/models/texture.h +++ b/gfx/models/texture.h @@ -9,9 +9,16 @@ class Image; struct TextureOptions { - GLint wrap {GL_REPEAT}; + 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 { -- cgit v1.2.3 From be9a796e68a25f7567b7c16e00d9b42f5e0d9528 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Fri, 14 Apr 2023 16:39:27 +0100 Subject: Write applicable Texture Options into texture atlas texture data --- gfx/models/texture.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'gfx') diff --git a/gfx/models/texture.cpp b/gfx/models/texture.cpp index e29fd6c..e014f80 100644 --- a/gfx/models/texture.cpp +++ b/gfx/models/texture.cpp @@ -136,12 +136,15 @@ TextureAtlas::bind(GLenum unit) const } GLuint -TextureAtlas::add(glm::ivec2 position, glm::ivec2 size, void * data, TextureOptions) +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, unused1 {}, unused2 {}; - } material {position, size}; + 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; } -- cgit v1.2.3 From 4a7cff8f634122314d0bb4766795ea2d1e652ed4 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Fri, 14 Apr 2023 16:39:57 +0100 Subject: Handle different mapmodes in basic shader --- gfx/gl/shaders/basicShader.fs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'gfx') diff --git a/gfx/gl/shaders/basicShader.fs b/gfx/gl/shaders/basicShader.fs index 8a72e6d..57eaba2 100644 --- a/gfx/gl/shaders/basicShader.fs +++ b/gfx/gl/shaders/basicShader.fs @@ -7,12 +7,37 @@ include(`geometryOut.glsl') layout(binding = 0) uniform sampler2D texture0; layout(binding = 1) uniform usampler2DRect material; +float map(uint mapmode, float value) +{ + switch (mapmode) { + case 0u: // Repeat + return fract(value); + case 1u: // Clamp to edge + return clamp(0.0, 1.0, value); + case 2u: // Mirror + discard; + case 3u: // Decal + if (value != clamp(0.0, 1.0, value)) { + discard; + } + } + return 0; +} + +vec2 map(uint mapmodeU, uint mapmodeV, vec2 value) +{ + return vec2(map(mapmodeU, value.x), map(mapmodeV, value.y)); +} + vec4 getTextureColour(uint midx, vec2 uv) { if (midx > 0u) { const vec2 tSize = textureSize(texture0, 0); const vec4 sPosSize = texture(material, uvec2(0, midx - 1u)); - uv = (sPosSize.xy + sPosSize.zw * fract(uv)) / tSize; + const uvec4 sMode = texture(material, uvec2(1, midx - 1u)); + const uint mapmodeU = sMode.x & 0xFu; + const uint mapmodeV = (sMode.x & 0xF0u) >> 1; + uv = (sPosSize.xy + sPosSize.zw * map(mapmodeU, mapmodeV, uv)) / tSize; } return texture(texture0, uv); } -- cgit v1.2.3 From 66da4f83c1b5bb6f3ceda880820e01c2f8e23e43 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Fri, 14 Apr 2023 17:45:31 +0100 Subject: Remove the old .obj load, assets and supporting stuff --- gfx/models/obj.h | 38 ---------------- gfx/models/obj.impl.cpp | 77 -------------------------------- gfx/models/obj.ll | 116 ------------------------------------------------ 3 files changed, 231 deletions(-) delete mode 100644 gfx/models/obj.h delete mode 100644 gfx/models/obj.impl.cpp delete mode 100644 gfx/models/obj.ll (limited to 'gfx') diff --git a/gfx/models/obj.h b/gfx/models/obj.h deleted file mode 100644 index e28f7de..0000000 --- a/gfx/models/obj.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#ifndef yyFlexLexer -# define yyFlexLexer objbaseFlexLexer -# include -#endif -#include -#include -#include -#include -#include -#include - -class Mesh; -class Vertex; - -class ObjParser : yyFlexLexer { -public: - explicit ObjParser(const std::filesystem::path & fileName); - explicit ObjParser(std::unique_ptr in); - - int yylex() override; - - std::vector vertices; - std::vector texCoords; - std::vector normals; - using FaceElement = glm::vec<3, unsigned int>; - using Face = std::vector; - using Faces = std::vector; - using Object = std::pair; - std::vector objects; - glm::length_t axis {0}; - - using NamedMeshesData = std::map, std::vector>>; - [[nodiscard]] NamedMeshesData createMeshData() const; - using NamedMeshes = std::map>; - [[nodiscard]] NamedMeshes createMeshes() const; -}; diff --git a/gfx/models/obj.impl.cpp b/gfx/models/obj.impl.cpp deleted file mode 100644 index 205abc8..0000000 --- a/gfx/models/obj.impl.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include "obj.h" -#include -#include -#include -#include -#include // IWYU pragma: keep -#include -#include -#include -#include -#include -#include -#include - -ObjParser::ObjParser(const std::filesystem::path & fileName) : ObjParser {std::make_unique(fileName)} { } - -ObjParser::ObjParser(std::unique_ptr in) : yyFlexLexer(in.get()) -{ - assert(in); - ObjParser::yylex(); - assert(in->good()); - constexpr const glm::mat4 obj2ilt { - -1, 0, 0, 0, // x - 0, 0, 1, 0, // y - 0, 1, 0, 0, // z - 0, 0, 0, 0, // w - }; - std::for_each(vertices.begin(), vertices.end(), [&obj2ilt](auto & v) { - v = v * obj2ilt; - }); - std::for_each(normals.begin(), normals.end(), [&obj2ilt](auto & v) { - v = glm::vec4 {v, 0} * obj2ilt; - }); -} - -ObjParser::NamedMeshes -ObjParser::createMeshes() const -{ - NamedMeshes out; - const auto data {createMeshData()}; - std::transform(data.begin(), data.end(), std::inserter(out, out.end()), [](auto && obj) { - return std::make_pair(obj.first, std::make_shared(obj.second.first, obj.second.second)); - }); - return out; -} - -ObjParser::NamedMeshesData -ObjParser::createMeshData() const -{ - NamedMeshesData out; - std::transform(objects.begin(), objects.end(), std::inserter(out, out.end()), [this](auto && obj) { - std::vector overtices; - std::vector vertexOrder; - std::vector indices; - for (const auto & face : obj.second) { - for (auto idx = 2U; idx < face.size(); idx += 1) { - auto f = [&](auto idx) { - const auto & fe {face[idx]}; - if (const auto existing = std::find(vertexOrder.begin(), vertexOrder.end(), fe); - existing != vertexOrder.end()) { - indices.push_back(static_cast(std::distance(vertexOrder.begin(), existing))); - } - else { - indices.push_back(static_cast(overtices.size())); - overtices.emplace_back(vertices[fe.x - 1], texCoords[fe.y - 1], -normals[fe.z - 1]); - vertexOrder.emplace_back(fe); - } - }; - f(0U); - f(idx); - f(idx - 1); - } - } - return std::make_pair(obj.first, std::make_pair(overtices, indices)); - }); - return out; -} diff --git a/gfx/models/obj.ll b/gfx/models/obj.ll deleted file mode 100644 index 84884fe..0000000 --- a/gfx/models/obj.ll +++ /dev/null @@ -1,116 +0,0 @@ -%option batch -%option c++ -%option noyywrap -%option 8bit -%option stack -%option yyclass="ObjParser" -%option prefix="objbase" - -%{ -#include -#include -#include -#include -#include -class objbaseFlexLexer; -%} - -comment #.* -float -?[0-9.]+ -index -?[0-9]+ -linestring [^\r\n]* -truthy (1|on) -falsey (0|off) - -%x FACE -%x MTLLIB -%x OBJECT -%x SMOOTH -%x USEMTL -%x VERTEX -%x NORMAL -%x TEXCOORD - -%% - -{comment} { - // fprintf(stderr, "COMMENT %s\n", YYText()); -} -"f " { - BEGIN(FACE); - objects.back().second.emplace_back(); - objects.back().second.back().emplace_back(); - axis = 0; -} -"mtllib " { - BEGIN(MTLLIB); -} -"o " { - BEGIN(OBJECT); -} -"s " { - BEGIN(SMOOTH); -} -"usemtl " { - BEGIN(USEMTL); -} -"v " { - BEGIN(VERTEX); - vertices.emplace_back(0, 0, 0, 1); - axis = 0; -} -"vn " { - BEGIN(NORMAL); - normals.emplace_back(0, 0, 0); - axis = 0; -} -"vt " { - BEGIN(TEXCOORD); - texCoords.emplace_back(0, 1, 1); - axis = 0; -} -{linestring} { - // fprintf(stderr, "USEMTL <%s>\n", YYText()); -} -{linestring} { - // fprintf(stderr, "MTLLIB <%s>\n", YYText()); -} -{linestring} { - objects.emplace_back(YYText(), Faces{}); -} -{truthy} { - // fprintf(stderr, "Set smooth\n"); -} -{falsey} { - // fprintf(stderr, "Set flat\n"); -} -{float} { - vertices.back()[axis++] = std::stof(YYText()); -} -{float} { - normals.back()[axis++] = std::stof(YYText()); -} -{float} { - texCoords.back()[axis++] = std::stof(YYText()); -} -{index} { - objects.back().second.back().back()[axis] = std::stoi(YYText()); -} -\/ { - axis++; -} -[ \t] { - objects.back().second.back().emplace_back(); - axis = 0; -} - -<*>[ \t] { -} -<*>[\r\n\f] { - BEGIN(INITIAL); -} - -%% - -// Make iwyu think unistd.h is required -[[maybe_unused]]static auto x=getpid; -- cgit v1.2.3