Add the ability to use mipmaps with RenderTargets.
Some checks failed
Run ReCI Build Test / Explore-Gitea-Actions (push) Failing after 50s
Some checks failed
Run ReCI Build Test / Explore-Gitea-Actions (push) Failing after 50s
This commit is contained in:
@@ -41,6 +41,24 @@ namespace JGL {
|
||||
MSAA_8X = 3
|
||||
};
|
||||
|
||||
enum class FilteringMode : u8 {
|
||||
NEAREST = 0, // Fastest for 2D, Sometimes causes graphical issues.
|
||||
BILINEAR = 1, // Fast and pretty, The best for 2D.
|
||||
|
||||
MIPMAP_NEAREST = 2, // Nearest with mipmaps. The fastest for 3D, Sometimes causes graphical issues. Uses more vram.
|
||||
MIPMAP_BILINEAR = 3, // Bilinear with mipmaps, Fast and pretty. Uses more vram.
|
||||
MIPMAP_TRILINEAR = 4 // The prettiest. Still decent speed. Uses more vram.
|
||||
};
|
||||
|
||||
enum class WrappingMode : u8 {
|
||||
REPEAT = 0,
|
||||
MIRRORED_REPEAT = 1,
|
||||
CLAMP_TO_EDGE = 2,
|
||||
CLAMP_TO_BORDER = 3 // Effectively the same as clamp_to_edge
|
||||
};
|
||||
|
||||
enum class ColorFormat : bool { RGB = false, RGBA = true };
|
||||
|
||||
static std::string to_string(const JGL::MSAA_SAMPLE_RATE& sample_rate) {
|
||||
switch (sample_rate) {
|
||||
case MSAA_SAMPLE_RATE::MSAA_NONE:
|
||||
|
@@ -47,6 +47,7 @@ public:
|
||||
/// If you're using MSAA and not using J2D || J3D Begin & End you must do this.
|
||||
void MSAABlit() const;
|
||||
|
||||
void RegenerateMipMaps();
|
||||
/// Copy one Render Target onto another. Will break if they're not the same size.
|
||||
// TODO support different sizes. If the destination is too small fix it for them but log a warning.
|
||||
static void Blit(const RenderTarget& source, RenderTarget* destination, const Vector2i& position = {0, 0});
|
||||
@@ -114,7 +115,8 @@ public:
|
||||
/// @param clear_color The color to be used if you want to clear the Render Target.
|
||||
/// @param use_depth Whether or not this Render Target will have depth information.
|
||||
/// @param sample_rate The MSAA sample rate this Render Target will use.
|
||||
explicit RenderTarget(const Vector2i& size, const Color4& clear_color = Colors::Transparent, bool use_depth = false, MSAA_SAMPLE_RATE sample_rate = MSAA_SAMPLE_RATE::MSAA_NONE);
|
||||
explicit RenderTarget(const Vector2i& size, const Color4& clear_color = Colors::Transparent, bool use_depth = false,
|
||||
MSAA_SAMPLE_RATE sample_rate = MSAA_SAMPLE_RATE::MSAA_NONE, FilteringMode filteirng_mode = FilteringMode::NEAREST);
|
||||
|
||||
/// Deletes this Render Target.
|
||||
/** @note If this Render Target was made with a Texture that already existed
|
||||
|
@@ -4,26 +4,10 @@
|
||||
#include <J3ML/LinearAlgebra/Vector2i.hpp>
|
||||
#include <Color3.hpp>
|
||||
#include <Color4.hpp>
|
||||
#include <JGL/types/Enums.h>
|
||||
|
||||
namespace JGL {
|
||||
using J3ML::LinearAlgebra::Vector2i;
|
||||
|
||||
enum class FilteringMode : u8 {
|
||||
NEAREST = 0, // Fastest for 2D, Sometimes causes graphical issues.
|
||||
BILINEAR = 1, // Fast and pretty, The best for 2D.
|
||||
|
||||
MIPMAP_NEAREST = 2, // Nearest with mipmaps. The fastest for 3D, Sometimes causes graphical issues. Uses more vram.
|
||||
MIPMAP_BILINEAR = 3, // Bilinear with mipmaps, Fast and pretty. Uses more vram.
|
||||
MIPMAP_TRILINEAR = 4 // The prettiest. Still decent speed. Uses more vram.
|
||||
};
|
||||
|
||||
enum class WrappingMode : u8 {
|
||||
REPEAT = 0,
|
||||
MIRRORED_REPEAT = 1,
|
||||
CLAMP_TO_EDGE = 2,
|
||||
CLAMP_TO_BORDER = 3 // Effectively the same as clamp_to_edge
|
||||
};
|
||||
enum class ColorFormat : bool { RGB = false, RGBA = true };
|
||||
class Texture;
|
||||
}
|
||||
|
||||
@@ -71,7 +55,7 @@ public:
|
||||
Texture(const Texture* textures, const size_t& texture_count);
|
||||
/// Initialize a texture filled with trash data.
|
||||
/// @see RenderTarget
|
||||
explicit Texture(const Vector2i& size);
|
||||
explicit Texture(const Vector2i& size, FilteringMode filtering_mode = FilteringMode::NEAREST);
|
||||
|
||||
Texture(const Texture& rhs);
|
||||
~Texture();
|
||||
|
3
main.cpp
3
main.cpp
@@ -130,7 +130,8 @@ public:
|
||||
glDepthMask(GL_TRUE);
|
||||
image = new Texture("assets/sprites/Re3D.png", FilteringMode::BILINEAR);
|
||||
image_mask = new Texture("assets/sprites/alpha_mask_2.png");
|
||||
j2d_render_target = new RenderTarget({540, 500}, {0,0,0,0}, false, MSAA_SAMPLE_RATE::MSAA_8X);
|
||||
j2d_render_target = new RenderTarget({540, 500}, {0,0,0,0}, false,
|
||||
MSAA_SAMPLE_RATE::MSAA_8X, FilteringMode::MIPMAP_TRILINEAR);
|
||||
|
||||
//Texture::MultiplyByAlphaMask(*image, *image_mask);
|
||||
}
|
||||
|
@@ -51,8 +51,15 @@ void J2D::Begin(RenderTarget* render_target, bool clear_buffers) {
|
||||
}
|
||||
|
||||
void J2D::End() {
|
||||
if (current_state.current_render_target)
|
||||
if (current_state.current_render_target) {
|
||||
current_state.current_render_target->MSAABlit();
|
||||
FilteringMode filtering_mode = current_state.current_render_target->GetTexture()->GetFilteringMode();
|
||||
|
||||
if (filtering_mode == FilteringMode::MIPMAP_NEAREST ||
|
||||
filtering_mode == FilteringMode::MIPMAP_BILINEAR ||
|
||||
filtering_mode == FilteringMode::MIPMAP_TRILINEAR)
|
||||
current_state.current_render_target->RegenerateMipMaps();
|
||||
}
|
||||
|
||||
//Change back to the previous projection.
|
||||
glPopMatrix();
|
||||
|
@@ -76,7 +76,7 @@ JGL::RenderTarget::RenderTarget(const JGL::Texture* texture, const Color4& clear
|
||||
texture_created_by_us = false;
|
||||
}
|
||||
|
||||
JGL::RenderTarget::RenderTarget(const Vector2i& size, const Color4& clear_color, bool use_depth, MSAA_SAMPLE_RATE sample_rate) {
|
||||
JGL::RenderTarget::RenderTarget(const Vector2i& size, const Color4& clear_color, bool use_depth, MSAA_SAMPLE_RATE sample_rate, FilteringMode filtering_mode) {
|
||||
if (size.x < 1 || size.y < 1)
|
||||
Logger::Fatal("Creating a render target where the color attachment is empty?");
|
||||
|
||||
@@ -85,7 +85,7 @@ JGL::RenderTarget::RenderTarget(const Vector2i& size, const Color4& clear_color,
|
||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
//Textures behave strangely if they're not square aaaaaaaaaaaaa.
|
||||
|
||||
texture = new Texture(size);
|
||||
texture = new Texture(size, filtering_mode);
|
||||
glGenFramebuffers(1, &framebuffer_object);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_object);
|
||||
glViewport(0,0, size.x, size.y);
|
||||
@@ -262,19 +262,6 @@ void JGL::RenderTarget::MSAABlit() const {
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_draw_fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, current_fbo);
|
||||
}
|
||||
|
||||
// Fixes using render targets on a texture that has mipmaps.
|
||||
if (GetTexture()->GetFilteringMode() == FilteringMode::MIPMAP_NEAREST
|
||||
|| GetTexture()->GetFilteringMode() == FilteringMode::MIPMAP_BILINEAR ||
|
||||
GetTexture()->GetFilteringMode() == FilteringMode::MIPMAP_TRILINEAR) {
|
||||
GLint current_texture = 0;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, GetTexture()->GetHandle());
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, current_texture);
|
||||
}
|
||||
}
|
||||
|
||||
void JGL::RenderTarget::Blit(const JGL::RenderTarget& source, JGL::RenderTarget* destination, const Vector2i& position) {
|
||||
@@ -364,3 +351,18 @@ JGL::RenderTarget::RenderTarget(const JGL::RenderTarget& rhs) {
|
||||
Vector2i JGL::RenderTarget::MaximumSize() {
|
||||
return Texture::MaximumSize();
|
||||
}
|
||||
|
||||
void JGL::RenderTarget::RegenerateMipMaps() {
|
||||
// Fixes using render targets on a texture that has mipmaps.
|
||||
if (GetTexture()->GetFilteringMode() == FilteringMode::MIPMAP_NEAREST
|
||||
|| GetTexture()->GetFilteringMode() == FilteringMode::MIPMAP_BILINEAR ||
|
||||
GetTexture()->GetFilteringMode() == FilteringMode::MIPMAP_TRILINEAR) {
|
||||
GLint current_texture = 0;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, GetTexture()->GetHandle());
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, current_texture);
|
||||
}
|
||||
}
|
||||
|
@@ -98,7 +98,7 @@ std::vector<unsigned char> Texture::bmp(const std::filesystem::path& file) {
|
||||
return result;
|
||||
}
|
||||
|
||||
Texture::Texture(const Vector2i& size) : invert_y(true), format(ColorFormat::RGBA), size(size), filtering_mode(FilteringMode::NEAREST), wrapping_mode(WrappingMode::CLAMP_TO_EDGE) {
|
||||
Texture::Texture(const Vector2i& size, FilteringMode filtering_mode) : invert_y(true), format(ColorFormat::RGBA), size(size), filtering_mode(filtering_mode), wrapping_mode(WrappingMode::CLAMP_TO_EDGE) {
|
||||
if (SizeExceedsMaximum(size))
|
||||
Logger::Error("Creating a texture where the size is bigger than the maximum for this system.");
|
||||
GLuint previous_texture;
|
||||
@@ -109,6 +109,27 @@ Texture::Texture(const Vector2i& size) : invert_y(true), format(ColorFormat::RGB
|
||||
//NEAREST
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
if (filtering_mode == FilteringMode::NEAREST)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
else if (filtering_mode == FilteringMode::BILINEAR)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
if (filtering_mode == FilteringMode::MIPMAP_NEAREST)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
else if (filtering_mode == FilteringMode::MIPMAP_BILINEAR)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
else if (filtering_mode == FilteringMode::MIPMAP_TRILINEAR)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
//Clamp
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
@@ -116,7 +137,6 @@ Texture::Texture(const Vector2i& size) : invert_y(true), format(ColorFormat::RGB
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.x, size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
glBindTexture(GL_TEXTURE_2D, previous_texture);
|
||||
}
|
||||
|
||||
void Texture::load(const unsigned char* pixels) {
|
||||
if (SizeExceedsMaximum(size))
|
||||
Logger::Error("Creating a texture where the size is bigger than the maximum for this system.");
|
||||
|
Reference in New Issue
Block a user