Texture Atlas constructors.
This commit is contained in:
@@ -53,13 +53,11 @@ public:
|
||||
/// Load a texture from raw pixels.
|
||||
Texture(const Color3* pixels, const Vector2i& size, FilteringMode filtering_mode = FilteringMode::BILINEAR,
|
||||
SampleRate anisotropy = SampleRate::NONE, WrappingMode wrapping_mode = WrappingMode::CLAMP_TO_EDGE);
|
||||
/// Construct a Texture Atlas from many different textures.
|
||||
/// @note THIS IS UNFINISHED.
|
||||
Texture(const Texture* textures, const size_t& texture_count);
|
||||
/// Initialize a texture filled with trash data.
|
||||
/// @see RenderTarget
|
||||
explicit Texture(const Vector2i& size, FilteringMode filtering_mode = FilteringMode::NEAREST);
|
||||
Texture(const Texture& rhs);
|
||||
Texture() = default;
|
||||
~Texture();
|
||||
public:
|
||||
/// @returns True if this system supports anisotropy.
|
||||
|
36
include/JGL/types/TextureAtlas.h
Normal file
36
include/JGL/types/TextureAtlas.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <JGL/types/Texture.h>
|
||||
|
||||
// A texture which actually contains multiple such that you can pass it in to draw sprite or draw partial sprite.
|
||||
// It also makes for more efficient sprite batch because you don't have to swap textures between.
|
||||
|
||||
namespace JGL {
|
||||
struct AtlasRegion {
|
||||
Vector2i position = { 0, 0 };
|
||||
Vector2i size = { 0, 0 };
|
||||
};
|
||||
|
||||
class TextureAtlas;
|
||||
}
|
||||
|
||||
class JGL::TextureAtlas : public Texture {
|
||||
protected:
|
||||
std::vector<AtlasRegion> regions;
|
||||
public:
|
||||
unsigned int RegionCount() { return regions.size(); }
|
||||
[[nodiscard]] AtlasRegion GetRegion(unsigned int region) const;
|
||||
public:
|
||||
/// Create a texture atlas from multiple separate images.
|
||||
/// @param pixels The array(s) of pixels.
|
||||
/// @param sizes The size of each image.
|
||||
/// @param texture_count The number of textures this atlas will contain.
|
||||
TextureAtlas(const Color4** pixels, const Vector2i** sizes, unsigned int texture_count, FilteringMode filtering_mode = FilteringMode::NEAREST);
|
||||
|
||||
/// Create a texture atlas from a single image
|
||||
/// @param pixels The array of pixels.
|
||||
/// @param size The size of the image.
|
||||
/// @param regions The individual regions that will make up your atlas.
|
||||
/// @param region_count The number of regions there are.
|
||||
TextureAtlas(const Color4* pixels, const Vector2i& size, AtlasRegion** regions, unsigned int region_count, FilteringMode filtering_mode = FilteringMode::NEAREST);
|
||||
};
|
@@ -61,7 +61,7 @@ namespace JGL {
|
||||
}
|
||||
|
||||
namespace JGL::J2D {
|
||||
inline State default_state
|
||||
inline constexpr State default_state
|
||||
{
|
||||
{0, 0, 0, 1},
|
||||
{1, 1, 1, 1},
|
||||
|
@@ -288,7 +288,7 @@ void JGL::RenderTarget::Blit(const JGL::RenderTarget& source, JGL::RenderTarget*
|
||||
|
||||
void JGL::RenderTarget::Blit(const Texture* source, RenderTarget* destination, const Vector2i& position) {
|
||||
auto temp = new RenderTarget(source);
|
||||
Blit(*temp, destination);
|
||||
Blit(*temp, destination, position);
|
||||
delete temp;
|
||||
}
|
||||
|
||||
|
@@ -293,26 +293,6 @@ Texture::Texture(const Texture& rhs) {
|
||||
operator delete(this_texture);
|
||||
}
|
||||
|
||||
Texture::Texture(const Texture* textures, const size_t& texture_count) {
|
||||
int length = 0;
|
||||
int biggest_y = 0;
|
||||
|
||||
for (int i = 0; i < texture_count; i++) {
|
||||
if (biggest_y < textures[i].size.y)
|
||||
biggest_y = textures[i].size.y;
|
||||
length += textures[i].size.x;
|
||||
}
|
||||
|
||||
auto* result = new Texture(Vector2i(length, biggest_y));
|
||||
auto render_target = RenderTarget(result);
|
||||
|
||||
int next_x = 0;
|
||||
for (int i = 0; i < texture_count; i++) {
|
||||
RenderTarget::Blit(&textures[i], &render_target, Vector2i(next_x, 0));
|
||||
next_x += textures[i].GetDimensions().x;
|
||||
}
|
||||
}
|
||||
|
||||
bool Texture::SizeExceedsMaximum(const Vector2i& s) {
|
||||
|
||||
auto max_size = Texture::MaxSize();
|
||||
|
63
src/types/TextureAtlas.cpp
Normal file
63
src/types/TextureAtlas.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#include <JGL/types/TextureAtlas.h>
|
||||
#include <JGL/types/RenderTarget.h>
|
||||
#include <JGL/logger/logger.h>
|
||||
|
||||
using namespace JGL;
|
||||
AtlasRegion TextureAtlas::GetRegion(unsigned int region) const {
|
||||
if (region >= regions.size()) {
|
||||
Logger::Error("Requesting region " + std::to_string(region) + "but it's outside of the texture atlas?");
|
||||
return { {0, 0},{0, 0} };
|
||||
}
|
||||
return regions[region];
|
||||
}
|
||||
|
||||
TextureAtlas::TextureAtlas(const Color4** pixels, const Vector2i** sizes, unsigned int texture_count, FilteringMode filtering_mode) {
|
||||
std::vector<Texture> textures(texture_count);
|
||||
|
||||
int x_length = 0; int largest_height = 0;
|
||||
for (unsigned int i = 0; i < texture_count; i++) {
|
||||
textures[i] = Texture(pixels[i], *sizes[i], FilteringMode::NEAREST);
|
||||
x_length += sizes[i]->x;
|
||||
|
||||
if (sizes[i]->y > largest_height)
|
||||
largest_height = sizes[i]->y;
|
||||
}
|
||||
|
||||
int rows = 1;
|
||||
while (x_length > Texture::MaxSize().x)
|
||||
x_length /= 2, rows += 1;
|
||||
|
||||
auto* result = new Texture(Vector2i(x_length, largest_height * rows), filtering_mode);
|
||||
auto* render_target = new RenderTarget(result);
|
||||
|
||||
int current_x = 0; int current_y = 0;
|
||||
for (unsigned int i = 0; i < texture_count; i++) {
|
||||
if (current_x + sizes[i]->x > x_length)
|
||||
current_x = 0, current_y += largest_height;
|
||||
|
||||
RenderTarget::Blit(&textures[i], render_target, Vector2i(current_x, current_y));
|
||||
regions.emplace_back(AtlasRegion({ current_x, current_y }, { sizes[i]->x, sizes[i]->y }));
|
||||
current_x += sizes[i]->x;
|
||||
}
|
||||
|
||||
render_target->RegenerateMipMaps();
|
||||
delete render_target;
|
||||
|
||||
this->texture_handle = result->GetHandle();
|
||||
this->size = result->GetDimensions();
|
||||
this->invert_y = result->Inverted();
|
||||
this->filtering_mode = result->GetFilteringMode();
|
||||
this->wrapping_mode = result->GetWrappingMode();
|
||||
this->anisotropy = result->GetAnisotropySampleRate();
|
||||
this->format = result->GetFormat();
|
||||
|
||||
// Don't call destructor so the v-ram isn't cleared.
|
||||
operator delete(result);
|
||||
}
|
||||
|
||||
TextureAtlas::TextureAtlas(const Color4* pixels, const Vector2i& size, AtlasRegion** regions, unsigned int region_count, FilteringMode filtering_mode) : Texture(pixels, size, filtering_mode) {
|
||||
this->regions.resize(region_count);
|
||||
for (unsigned int i = 0; i < region_count; ++i)
|
||||
this->regions[i] = *regions[i];
|
||||
}
|
||||
|
Reference in New Issue
Block a user