summaryrefslogtreecommitdiff
path: root/gfx/models
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/models')
-rw-r--r--gfx/models/lights.cpp11
-rw-r--r--gfx/models/lights.h29
-rw-r--r--gfx/models/mesh.cpp43
-rw-r--r--gfx/models/mesh.h69
-rw-r--r--gfx/models/texture.cpp129
-rw-r--r--gfx/models/texture.h25
-rw-r--r--gfx/models/tga.h9
-rw-r--r--gfx/models/vertex.cpp8
8 files changed, 190 insertions, 133 deletions
diff --git a/gfx/models/lights.cpp b/gfx/models/lights.cpp
new file mode 100644
index 0000000..8c0e9e6
--- /dev/null
+++ b/gfx/models/lights.cpp
@@ -0,0 +1,11 @@
+#include "lights.h"
+
+SpotLightVertex::SpotLightVertex(const SpotLightDef & light, uint32_t parentObjectIdx) :
+ SpotLightDef {light}, LightCommonVertex {parentObjectIdx}
+{
+}
+
+PointLightVertex::PointLightVertex(const PointLightDef & light, uint32_t parentObjectIdx) :
+ PointLightDef {light}, LightCommonVertex {parentObjectIdx}
+{
+}
diff --git a/gfx/models/lights.h b/gfx/models/lights.h
new file mode 100644
index 0000000..586b3ef
--- /dev/null
+++ b/gfx/models/lights.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#include "config/types.h"
+
+struct LightCommon {
+ RelativePosition3D position;
+ RGB colour;
+ RelativeDistance kq;
+};
+
+struct LightCommonVertex {
+ uint32_t parentObject;
+};
+
+struct SpotLightDef : LightCommon {
+ Direction3D direction;
+ Angle arc;
+};
+
+struct PointLightDef : LightCommon { };
+
+struct SpotLightVertex : SpotLightDef, LightCommonVertex {
+ SpotLightVertex(const SpotLightDef &, uint32_t);
+};
+
+struct PointLightVertex : PointLightDef, LightCommonVertex {
+ PointLightVertex(const PointLightDef &, uint32_t);
+};
+
diff --git a/gfx/models/mesh.cpp b/gfx/models/mesh.cpp
index e7474ca..6a53f52 100644
--- a/gfx/models/mesh.cpp
+++ b/gfx/models/mesh.cpp
@@ -1,23 +1,54 @@
#include "mesh.h"
-MeshBase::MeshBase(GLsizei m_numIndices, GLenum mode) : m_numIndices {m_numIndices}, mode {mode} { }
+MeshBase::MeshBase(
+ GLsizei m_numIndices, GLenum mode, const std::vector<RelativePosition3D> & positions, GLsizei vertexStride) :
+ vertexStride {vertexStride}, numIndices {m_numIndices}, mode {mode}, dimensions {positions}
+{
+}
+
+MeshBase::Dimensions::Dimensions(const std::span<const RelativePosition3D> positions) :
+ Dimensions {positions, {extents(positions, 0), extents(positions, 1), extents(positions, 2)}}
+{
+}
+
+MeshBase::Dimensions::Dimensions(
+ const std::span<const RelativePosition3D> positions, const std::array<Extents1D, 3> & extents1ds) :
+ minExtent(extents1ds[0].min, extents1ds[1].min, extents1ds[2].min),
+ maxExtent(extents1ds[0].max, extents1ds[1].max, extents1ds[2].max), centre {(minExtent + maxExtent) / 2.0F},
+ size {std::ranges::max(positions | std::views::transform([this](const auto & v) {
+ return glm::distance(v, centre);
+ }))}
+{
+}
+
+MeshBase::Dimensions::Extents1D
+MeshBase::Dimensions::extents(const std::span<const RelativePosition3D> positions, glm::length_t D)
+{
+ return std::ranges::minmax(positions | std::views::transform([D](const auto & v) {
+ return v[D];
+ }));
+}
void
-MeshBase::Draw() const
+MeshBase::draw() const
{
- glBindVertexArray(m_vertexArrayObject);
+ glBindVertexArray(*vertexArrayObject);
+ glVertexArrayVertexBuffer(*vertexArrayObject, 0, vertexArrayBuffers[0], 0, vertexStride);
+ glVertexArrayElementBuffer(*vertexArrayObject, vertexArrayBuffers[1]);
- glDrawElements(mode, m_numIndices, GL_UNSIGNED_INT, nullptr);
+ glDrawElements(mode, numIndices, GL_UNSIGNED_INT, nullptr);
glBindVertexArray(0);
}
void
-MeshBase::DrawInstanced(GLuint vao, GLsizei count, GLuint base) const
+MeshBase::drawInstanced(GLuint vao, GLsizei count, GLuint base) const
{
glBindVertexArray(vao);
+ glVertexArrayVertexBuffer(vao, 0, vertexArrayBuffers[0], 0, vertexStride);
+ glVertexArrayElementBuffer(vao, vertexArrayBuffers[1]);
- glDrawElementsInstancedBaseInstance(mode, m_numIndices, GL_UNSIGNED_INT, nullptr, count, base);
+ glDrawElementsInstancedBaseInstance(mode, numIndices, GL_UNSIGNED_INT, nullptr, count, base);
glBindVertexArray(0);
}
diff --git a/gfx/models/mesh.h b/gfx/models/mesh.h
index 248cb8f..fa12ae8 100644
--- a/gfx/models/mesh.h
+++ b/gfx/models/mesh.h
@@ -1,8 +1,11 @@
#pragma once
-#include "gfx/gl/vertexArrayObject.h"
-#include <glArrays.h>
+#include "config/types.h"
+#include "gfx/gl/glBuffer.h"
+#include "gfx/gl/gldebug.h"
+#include <gfx/gl/glVertexArray.h>
#include <glad/gl.h>
+#include <ranges>
#include <span>
#include <stdTypeDefs.h>
@@ -10,33 +13,69 @@ class Vertex;
class MeshBase {
public:
- void Draw() const;
- void DrawInstanced(GLuint vao, GLsizei count, GLuint base = 0) const;
+ class Dimensions {
+ public:
+ using Extents1D = std::ranges::minmax_result<RelativeDistance>;
+ explicit Dimensions(std::span<const RelativePosition3D>);
+
+ RelativePosition3D minExtent, maxExtent;
+ RelativePosition3D centre;
+ RelativeDistance size;
+
+ private:
+ Dimensions(std::span<const RelativePosition3D>, const std::array<Extents1D, 3> &);
+ static Extents1D extents(std::span<const RelativePosition3D>, glm::length_t);
+ };
+
+ void draw() const;
+ void drawInstanced(GLuint vao, GLsizei count, GLuint base = 0) const;
+
+ [[nodiscard]] const Dimensions &
+ getDimensions() const
+ {
+ return dimensions;
+ }
protected:
- MeshBase(GLsizei m_numIndices, GLenum mode);
+ MeshBase(GLsizei numIndices, GLenum mode, const std::vector<RelativePosition3D> &, GLsizei vertexStride);
- glVertexArray m_vertexArrayObject;
- glBuffers<2> m_vertexArrayBuffers;
- GLsizei m_numIndices;
+ std::shared_ptr<glVertexArray> vertexArrayObject;
+ glBuffers<2> vertexArrayBuffers;
+ GLsizei vertexStride;
+ GLsizei numIndices;
GLenum mode;
+ Dimensions dimensions;
};
template<typename V> class MeshT : public MeshBase, public ConstTypeDefs<MeshT<V>> {
public:
MeshT(const std::span<const V> vertices, const std::span<const unsigned int> indices, GLenum mode = GL_TRIANGLES) :
- MeshBase {static_cast<GLsizei>(indices.size()), mode}
+ MeshBase {static_cast<GLsizei>(indices.size()), mode,
+ materializeRange(vertices | std::views::transform([](const auto & vertex) {
+ return static_cast<RelativePosition3D>(vertex.pos);
+ })),
+ sizeof(V)}
{
- VertexArrayObject::data(vertices, m_vertexArrayBuffers[0], GL_ARRAY_BUFFER);
- VertexArrayObject::data(indices, m_vertexArrayBuffers[1], GL_ARRAY_BUFFER);
- configureVAO(m_vertexArrayObject);
+ glDebugScope _ {0};
+ vertexArrayBuffers[0].storage(vertices, 0);
+ vertexArrayBuffers[1].storage(indices, 0);
+ if (!(vertexArrayObject = commonVertexArrayObject.lock())) {
+ commonVertexArrayObject = vertexArrayObject = std::make_shared<glVertexArray>();
+ configureVAO(*vertexArrayObject, 0);
+ }
}
- VertexArrayObject &
- configureVAO(VertexArrayObject && vao) const
+ auto
+ configureVAO(glVertexArray & vao, GLuint divisor) const
{
- return vao.addAttribsFor<V>(m_vertexArrayBuffers[0]).addIndices(m_vertexArrayBuffers[1]);
+ glDebugScope _ {0};
+ return vao.configure().addAttribsFor<V>(divisor);
}
+
+protected:
+ static std::weak_ptr<glVertexArray> commonVertexArrayObject;
};
+template<typename T> std::weak_ptr<glVertexArray> MeshT<T>::commonVertexArrayObject;
+
using Mesh = MeshT<Vertex>;
diff --git a/gfx/models/texture.cpp b/gfx/models/texture.cpp
index 51223aa..5a104be 100644
--- a/gfx/models/texture.cpp
+++ b/gfx/models/texture.cpp
@@ -1,7 +1,5 @@
#include "texture.h"
#include "config/types.h"
-#include "glArrays.h"
-#include "tga.h"
#include <fcntl.h>
#include <filesystem.h>
#include <gfx/image.h>
@@ -12,6 +10,8 @@
#include <stb/stb_image.h>
#include <sys/mman.h>
+using std::ceil;
+
GLint
TextureOptions::glMapMode(TextureOptions::MapMode mm)
{
@@ -33,117 +33,66 @@ Texture::Texture(const std::filesystem::path & fileName, TextureOptions to) :
}
Texture::Texture(const Image & tex, TextureOptions to) :
- Texture {static_cast<GLsizei>(tex.width), static_cast<GLsizei>(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);
-
- glTexParameter(type, GL_TEXTURE_WRAP_S, TextureOptions::glMapMode(to.wrapU));
- glTexParameter(type, GL_TEXTURE_WRAP_T, TextureOptions::glMapMode(to.wrapV));
-
- glTexParameter(type, GL_TEXTURE_MIN_FILTER, to.minFilter);
- glTexParameter(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
+ Texture {static_cast<GLsizei>(tex.width), static_cast<GLsizei>(tex.height), GL_RGBA, GL_UNSIGNED_BYTE,
+ tex.data.data(), to}
{
- glActiveTexture(unit);
- glBindTexture(type, m_texture);
}
-TextureAbsCoord
-Texture::getSize(const glTexture & texture)
+Texture::Texture(GLsizei width, GLsizei height, TextureOptions to)
{
- TextureAbsCoord size;
- glGetTextureLevelParameteriv(texture, 0, GL_TEXTURE_WIDTH, &size.x);
- glGetTextureLevelParameteriv(texture, 0, GL_TEXTURE_HEIGHT, &size.y);
- return size;
+ const auto levels = static_cast<GLsizei>(ceil(std::log2(std::max(width, height))));
+ m_texture.storage(levels, GL_RGBA8, {width, height});
+ m_texture.parameter(GL_TEXTURE_WRAP_S, TextureOptions::glMapMode(to.wrapU));
+ m_texture.parameter(GL_TEXTURE_WRAP_T, TextureOptions::glMapMode(to.wrapV));
+ m_texture.parameter(GL_TEXTURE_MIN_FILTER, to.minFilter);
+ m_texture.parameter(GL_TEXTURE_MAG_FILTER, to.magFilter);
}
-void
-Texture::save(
- const glTexture & texture, GLenum format, GLenum type, uint8_t channels, const char * path, uint8_t tgaFormat)
+Texture::Texture(GLsizei width, GLsizei height, GLenum pixelFormat, GLenum PixelType, const void * pixels,
+ TextureOptions to) : Texture {width, height, to}
{
- const auto size = getSize(texture);
- const size_t dataSize = (static_cast<size_t>(size.x * size.y * channels));
- const size_t fileSize = dataSize + sizeof(TGAHead);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- filesystem::fh out {path, O_RDWR | O_CREAT, 0660};
- out.truncate(fileSize);
- auto tga = out.mmap(fileSize, 0, PROT_WRITE, MAP_SHARED);
- *tga.get<TGAHead>() = {
- .format = tgaFormat,
- .size = size,
- .pixelDepth = static_cast<uint8_t>(8 * channels),
+ m_texture.image({width, height}, pixelFormat, PixelType, pixels);
+ auto isMimmap = [](auto value) {
+ auto eqAnyOf = [value](auto... test) {
+ return (... || (value == test));
+ };
+ return eqAnyOf(
+ GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
};
- glPixelStorei(GL_PACK_ALIGNMENT, 1);
- glGetTextureImage(texture, 0, format, type, static_cast<GLsizei>(dataSize), tga.get<TGAHead>() + 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::savePosition(const glTexture & texture, const char * path)
-{
- save(texture, GL_BGR_INTEGER, 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);
+ const auto levels = static_cast<GLsizei>(ceil(std::log2(std::max(width, height))));
+ if (levels > 1 && (isMimmap(to.minFilter) || isMimmap(to.magFilter))) {
+ m_texture.generateMipmap();
+ }
}
void
-Texture::saveNormal(const glTexture & texture, const char * path)
+Texture::bind(GLenum unit) const
{
- save(texture, GL_BGR, GL_BYTE, 3, path, 2);
+ m_texture.bind(unit);
}
-TextureAtlas::TextureAtlas(GLsizei width, GLsizei height, GLuint count) : Texture(width, height, nullptr, {})
+TextureAtlas::TextureAtlas(GLsizei width, GLsizei height, GLuint count) : Texture(width, height)
{
- glBindTexture(GL_TEXTURE_RECTANGLE, m_atlas);
-
- glTexParameter(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameter(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- glTexParameter(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameter(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA16UI, 2, static_cast<GLsizei>(count), 0, GL_RGBA_INTEGER,
- GL_UNSIGNED_BYTE, nullptr);
+ m_atlas.parameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ m_atlas.parameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ m_atlas.parameter(GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ m_atlas.parameter(GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ m_atlas.storage(1, GL_RGBA16UI, {2, count});
}
void
TextureAtlas::bind(GLenum unit) const
{
Texture::bind(unit);
- glActiveTexture(unit + 1);
- glBindTexture(GL_TEXTURE_RECTANGLE, m_atlas);
+ m_atlas.bind(unit + 1);
}
GLuint
TextureAtlas::add(TextureAbsCoord position, TextureAbsCoord size, void * data, TextureOptions to)
{
- glTextureSubImage2D(m_texture, 0, position.x, position.y, size.x, size.y, GL_RGBA, GL_UNSIGNED_BYTE, data);
+ m_texture.subImage(position, size, GL_RGBA, GL_UNSIGNED_BYTE, data);
struct Material {
glm::vec<2, uint16_t> position, size;
@@ -152,6 +101,12 @@ TextureAtlas::add(TextureAbsCoord position, TextureAbsCoord size, void * data, T
} material {position, size, to.wrapU, to.wrapV};
static_assert(sizeof(Material) <= 32);
- glTextureSubImage2D(m_atlas, 0, 0, static_cast<GLsizei>(used), 2, 1, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, &material);
+ m_atlas.subImage({0, used}, {2, 1}, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, &material);
return ++used;
}
+
+void
+TextureAtlas::complete()
+{
+ m_texture.generateMipmap();
+}
diff --git a/gfx/models/texture.h b/gfx/models/texture.h
index 8cb8128..9c67ae1 100644
--- a/gfx/models/texture.h
+++ b/gfx/models/texture.h
@@ -1,7 +1,7 @@
#pragma once
#include "config/types.h"
-#include "glArrays.h"
+#include "gfx/gl/glTexture.h"
#include "stdTypeDefs.h"
#include <filesystem>
#include <glm/fwd.hpp>
@@ -17,7 +17,6 @@ struct TextureOptions {
};
MapMode wrapU {MapMode::Repeat}, wrapV {MapMode::Repeat};
GLint minFilter {GL_LINEAR}, magFilter {GL_LINEAR};
- GLenum type {GL_TEXTURE_2D};
static GLint glMapMode(MapMode);
};
@@ -29,32 +28,24 @@ public:
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 = {});
+ explicit Texture(GLsizei width, GLsizei height, GLenum pixelFormat, GLenum PixelType, const void * pixels,
+ TextureOptions = {});
- 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);
- static void savePosition(const glTexture &, const char * path);
+ virtual void bind(GLuint unit) const;
protected:
- static void save(const glTexture &, GLenum, GLenum, uint8_t channels, const char * path, uint8_t tgaFormat);
- static TextureAbsCoord getSize(const glTexture &);
-
- glTexture m_texture;
- GLenum type;
+ glTexture<GL_TEXTURE_2D> m_texture;
};
class TextureAtlas : public Texture {
public:
TextureAtlas(GLsizei width, GLsizei height, GLuint count);
- void bind(GLenum unit = GL_TEXTURE0) const override;
+ void bind(GLuint unit) const override;
GLuint add(TextureAbsCoord position, TextureAbsCoord size, void * data, TextureOptions = {});
+ void complete();
private:
- glTexture m_atlas;
+ glTexture<GL_TEXTURE_RECTANGLE> m_atlas;
GLuint used {};
};
diff --git a/gfx/models/tga.h b/gfx/models/tga.h
index 3d072fb..955e5e1 100644
--- a/gfx/models/tga.h
+++ b/gfx/models/tga.h
@@ -3,14 +3,15 @@
#include <cstdint>
#include <glm/vec2.hpp>
-struct TGAHead {
+template<glm::length_t Channels> struct TGAHead {
using XY = glm::vec<2, uint16_t>;
+ using PixelType = glm::vec<Channels, uint8_t>;
+
uint8_t idLength {}, colorMapType {}, format {};
uint16_t __attribute__((packed)) colorMapFirst {}, colorMapLength {};
uint8_t colorMapEntrySize {};
XY origin {}, size {};
- uint8_t pixelDepth {};
+ uint8_t pixelDepth {8 * Channels};
uint8_t descriptor {};
+ PixelType data[1] {};
};
-
-static_assert(sizeof(TGAHead) == 18);
diff --git a/gfx/models/vertex.cpp b/gfx/models/vertex.cpp
index c144db3..4b5ce54 100644
--- a/gfx/models/vertex.cpp
+++ b/gfx/models/vertex.cpp
@@ -1,10 +1,10 @@
#include "vertex.h"
-#include "gfx/gl/vertexArrayObject.h"
+#include "gfx/gl/glVertexArray.h"
template<>
-VertexArrayObject &
-VertexArrayObject::addAttribsFor<Vertex>(const GLuint arrayBuffer, const GLuint divisor)
+Impl::VertexArrayConfigurator &
+Impl::VertexArrayConfigurator::addAttribsFor<Vertex>(const GLuint divisor)
{
return addAttribs<Vertex, &Vertex::pos, &Vertex::texCoord, &Vertex::normal, &Vertex::colour, &Vertex::material>(
- arrayBuffer, divisor);
+ divisor);
}