Skip to content
This repository was archived by the owner on Mar 15, 2025. It is now read-only.

Commit 2130a2d

Browse files
committed
Fix mipmap count calculation in Texture.h.
Also removed automatic mipmap generation in "generate".
1 parent 3ac67bd commit 2130a2d

File tree

2 files changed

+22
-33
lines changed

2 files changed

+22
-33
lines changed

dang-gl/include/dang-gl/Objects/ObjectType.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ enum class TextureTarget {
5454
Texture2DMultisampleArray,
5555
Texture3D,
5656
TextureCubeMap,
57+
TextureCubeMapArray,
5758
TextureRectangle,
5859

5960
COUNT
@@ -145,6 +146,7 @@ inline constexpr dutils::EnumArray<TextureTarget, GLenum> gl_constants<TextureTa
145146
GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
146147
GL_TEXTURE_3D,
147148
GL_TEXTURE_CUBE_MAP,
149+
GL_TEXTURE_CUBE_MAP_ARRAY,
148150
GL_TEXTURE_RECTANGLE};
149151

150152
/// @brief Maps from framebuffer targets to their respective constants, which need to be supplied to the

dang-gl/include/dang-gl/Objects/Texture.h

Lines changed: 20 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ class TextureBaseTyped : public TextureBase {
248248
subImage(std::make_index_sequence<v_dim>(), image, offset, mipmap_level);
249249
}
250250

251-
/// @brief Regenerates all mipmaps from the top level.
251+
/// @brief Generates all mipmaps from the top level using OpenGL's built-in glGenerateMipmap.
252252
void generateMipmap()
253253
{
254254
this->bind();
@@ -505,7 +505,7 @@ class TextureBaseRegular : public TextureBaseTyped<v_dim, v_target> {
505505
{}
506506

507507
/// @brief Initializes a new texture with the given size.
508-
/// @remark mipmap_levels defaults to generating a full mipmap down to 1x1.
508+
/// @remark mipmap_levels defaults to generating storage for a full mipmap down to 1x1.
509509
explicit TextureBaseRegular(svec<v_dim> size,
510510
std::optional<GLsizei> mipmap_levels = std::nullopt,
511511
PixelInternalFormat internal_format = PixelInternalFormat::RGBA8)
@@ -515,7 +515,7 @@ class TextureBaseRegular : public TextureBaseTyped<v_dim, v_target> {
515515
}
516516

517517
/// @brief Initializes a new texture with the given image data.
518-
/// @remark mipmap_levels defaults to generating a full mipmap down to 1x1.
518+
/// @remark mipmap_levels defaults to generating storage for a full mipmap down to 1x1.
519519
/// @remark internal_format defaults to being chosen, based on the format of the provided image.
520520
template <PixelFormat v_pixel_format, PixelType v_pixel_type, std::size_t v_row_alignment>
521521
explicit TextureBaseRegular(const Image<v_dim, v_pixel_format, v_pixel_type, v_row_alignment>& image,
@@ -532,7 +532,7 @@ class TextureBaseRegular : public TextureBaseTyped<v_dim, v_target> {
532532
TextureBaseRegular& operator=(const TextureBaseRegular&) = delete;
533533

534534
/// @brief Generates storage for the specified size.
535-
/// @remark mipmap_levels defaults to generating a full mipmap down to 1x1.
535+
/// @remark mipmap_levels defaults to generating storage for a full mipmap down to 1x1.
536536
void generate(svec<v_dim> size,
537537
std::optional<GLsizei> mipmap_levels = std::nullopt,
538538
PixelInternalFormat internal_format = PixelInternalFormat::RGBA8)
@@ -542,7 +542,7 @@ class TextureBaseRegular : public TextureBaseTyped<v_dim, v_target> {
542542
}
543543

544544
/// @brief Generates texture storage and fills it with the provided image.
545-
/// @remark mipmap_levels defaults to generating a full mipmap down to 1x1.
545+
/// @remark mipmap_levels defaults to generating storage for a full mipmap down to 1x1.
546546
/// @remark internal_format defaults to being chosen, based on the format of the provided image.
547547
template <PixelFormat v_pixel_format, PixelType v_pixel_type, std::size_t v_row_alignment>
548548
void generate(const Image<v_dim, v_pixel_format, v_pixel_type, v_row_alignment>& image,
@@ -554,38 +554,17 @@ class TextureBaseRegular : public TextureBaseTyped<v_dim, v_target> {
554554
storage(
555555
std::make_index_sequence<v_dim>(), static_cast<svec<v_dim>>(image.size()), mipmap_levels, internal_format);
556556
this->subImage(std::make_index_sequence<v_dim>(), image);
557-
glGenerateMipmap(toGLConstant(v_target));
558557
}
559558

560559
protected:
561560
TextureBaseRegular(TextureBaseRegular&&) = default;
562561
TextureBaseRegular& operator=(TextureBaseRegular&&) = default;
563562

564563
private:
565-
/// @brief Returns the biggest component of a given vector.
566-
template <std::size_t... v_indices>
567-
static GLsizei maxSize(svec<v_dim> size, std::index_sequence<v_indices...>)
568-
{
569-
GLsizei result = 0;
570-
((result = std::max(result, size[v_indices])), ...);
571-
return result;
572-
}
573-
574-
/// @brief Calculates the integer log2 plus one of the given value, which is the required mipmap count for a given
575-
/// size.
576-
static GLsizei mipmapCount(GLsizei value)
577-
{
578-
// TODO: C++20 use std::bit_width
579-
GLsizei result = 1;
580-
while (value >>= 1)
581-
result++;
582-
return result;
583-
}
584-
585-
/// @brief Returns the required count to generate a full mipmap down to 1x1 for the given size.
586-
GLsizei maxMipmapLevelsFor(svec<v_dim> size)
564+
/// @brief Calculates the required mipmap count for a given size.
565+
static constexpr GLsizei mipmapCount(GLsizei value)
587566
{
588-
return mipmapCount(maxSize(size, std::make_index_sequence<v_dim>()));
567+
return dutils::ilog2(static_cast<std::make_unsigned_t<GLsizei>>(value)) + 1;
589568
}
590569

591570
/// @brief Calls glTexStorage with the provided parameters and index sequence of the textures dimension.
@@ -595,10 +574,18 @@ class TextureBaseRegular : public TextureBaseTyped<v_dim, v_target> {
595574
std::optional<GLsizei> mipmap_levels = std::nullopt,
596575
PixelInternalFormat internal_format = PixelInternalFormat::RGBA8)
597576
{
598-
glTexStorage<v_dim>(toGLConstant(v_target),
599-
mipmap_levels.value_or(maxMipmapLevelsFor(size)),
600-
toGLConstant(internal_format),
601-
size[v_indices]...);
577+
if (!mipmap_levels) {
578+
if constexpr (v_target == TextureTarget::Texture1DArray)
579+
mipmap_levels = mipmapCount(size.x().maxValue());
580+
else if constexpr (v_target == TextureTarget::Texture2DArray ||
581+
v_target == TextureTarget::Texture2DMultisampleArray ||
582+
v_target == TextureTarget::TextureCubeMapArray)
583+
mipmap_levels = mipmapCount(size.xy().maxValue());
584+
else
585+
mipmap_levels = mipmapCount(size.maxValue());
586+
}
587+
588+
glTexStorage<v_dim>(toGLConstant(v_target), *mipmap_levels, toGLConstant(internal_format), size[v_indices]...);
602589
this->setSize(size);
603590
}
604591
};

0 commit comments

Comments
 (0)