Texture filtering
All checks were successful
Run ReCI Build Test / Explore-Gitea-Actions (push) Successful in 1m46s
All checks were successful
Run ReCI Build Test / Explore-Gitea-Actions (push) Successful in 1m46s
This commit is contained in:
@@ -41,7 +41,7 @@ CPMAddPackage(
|
||||
|
||||
CPMAddPackage(
|
||||
NAME ReTexture
|
||||
URL https://git.redacted.cc/Redacted/ReTexture/archive/Release-1.zip
|
||||
URL https://git.redacted.cc/Redacted/ReTexture/archive/Release-1.1.zip
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
|
@@ -6,23 +6,33 @@
|
||||
#include <glad/glad.h>
|
||||
|
||||
namespace JGL {
|
||||
|
||||
enum class TextureFilteringMode {
|
||||
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.
|
||||
MIPMAP_TRILINEAR = 4 //The prettiest. Not much slower though.
|
||||
};
|
||||
|
||||
class Texture {
|
||||
private:
|
||||
GLuint texture = 0;
|
||||
Vector2 texture_size = {0, 0};
|
||||
ReTexture::TextureFlag texture_flags;
|
||||
ReTexture::TextureFormat texture_format;
|
||||
TextureFilteringMode texture_filtering_mode;
|
||||
void load(ReTexture::Texture* software_texture, const Vector2& size, const ReTexture::TextureFormat& format, TextureFilteringMode filtering_mode);
|
||||
public:
|
||||
Texture() = default;
|
||||
explicit Texture(const std::string& file);
|
||||
Texture(const std::string& file, const ReTexture::TextureFlag& flags);
|
||||
Texture(const std::vector<unsigned char>& pixel_data, const Vector2& size, const ReTexture::TextureFormat& format);
|
||||
Texture(const std::vector<Color4>& pixel_data, const Vector2& size, const ReTexture::TextureFormat& format);
|
||||
explicit Texture(const std::string& file, TextureFilteringMode filtering_mode = TextureFilteringMode::BILINEAR);
|
||||
Texture(const std::string& file, const ReTexture::TextureFlag& flags, TextureFilteringMode filtering_mode = TextureFilteringMode::BILINEAR);
|
||||
GLuint getTexture();
|
||||
Vector2 getSize();
|
||||
TextureFilteringMode getTextureFilteringMode();
|
||||
ReTexture::TextureFlag getFlags();
|
||||
ReTexture::TextureFormat getFormat();
|
||||
void eraseTexture();
|
||||
void erase();
|
||||
std::vector<Color4> getPixelData();
|
||||
};
|
||||
|
||||
|
2
main.cpp
2
main.cpp
@@ -88,7 +88,7 @@ public:
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
glDepthMask(GL_TRUE);
|
||||
image = new Texture("assets/sprites/Re3D.png");
|
||||
image = new Texture("assets/sprites/Re3D.png", TextureFilteringMode::MIPMAP_TRILINEAR);
|
||||
}
|
||||
|
||||
Vector3 textAngle = {0,0,0};
|
||||
|
@@ -1,51 +1,91 @@
|
||||
#include <JGL/Texture.h>
|
||||
#include <iostream>
|
||||
|
||||
JGL::Texture::Texture(const std::string &file, const ReTexture::TextureFlag &flags) {
|
||||
JGL::Texture::Texture(const std::string& file, const ReTexture::TextureFlag& flags, TextureFilteringMode filtering_mode) {
|
||||
auto* t = new ReTexture::Texture(file, flags);
|
||||
|
||||
*this = Texture(t->pixelData, {(float) t->getWidth(), (float) t->getHeight()}, t->getTextureFormat());
|
||||
load(t, {(float) t->getWidth(), (float) t->getHeight()}, t->getTextureFormat(), filtering_mode);
|
||||
texture_flags = flags;
|
||||
}
|
||||
|
||||
JGL::Texture::Texture(const std::string& file) {
|
||||
auto* t = new ReTexture::Texture(file);
|
||||
|
||||
*this = Texture(t->pixelData, {(float) t->getWidth(), (float) t->getHeight()}, t->getTextureFormat());
|
||||
|
||||
delete t;
|
||||
}
|
||||
|
||||
JGL::Texture::Texture(const std::vector<Color4>& pixel_data, const Vector2 &size, const ReTexture::TextureFormat &format) {
|
||||
std::vector<unsigned char> pixels(pixel_data.size());
|
||||
memcpy(pixels.data(), pixel_data.data(), pixels.size());
|
||||
JGL::Texture::Texture(const std::string& file, TextureFilteringMode filtering_mode) {
|
||||
auto* t = new ReTexture::Texture(file);
|
||||
|
||||
*this = Texture(pixels, size, format);
|
||||
load(t, {(float) t->getWidth(), (float) t->getHeight()}, t->getTextureFormat(), filtering_mode);
|
||||
texture_flags = ReTexture::TextureFlag::NONE;
|
||||
|
||||
delete t;
|
||||
}
|
||||
|
||||
JGL::Texture::Texture(const std::vector<unsigned char>& pixel_data, const Vector2& size, const ReTexture::TextureFormat& format) {
|
||||
void JGL::Texture::load(ReTexture::Texture* software_texture, const Vector2& size, const ReTexture::TextureFormat& format, TextureFilteringMode filtering_mode) {
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
if (format == ReTexture::TextureFormat::RGBA)
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (int) size.x, (int) size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel_data.data());
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (int) size.x, (int) size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, software_texture->pixelData.data());
|
||||
|
||||
else if (format == ReTexture::TextureFormat::RGB)
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (int) size.x, (int) size.y, 0, GL_RGB, GL_UNSIGNED_BYTE, pixel_data.data());
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (int) size.x, (int) size.y, 0, GL_RGB, GL_UNSIGNED_BYTE, software_texture->pixelData.data());
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
if (filtering_mode == TextureFilteringMode::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 == TextureFilteringMode::BILINEAR)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
else if (filtering_mode == TextureFilteringMode::MIPMAP_NEAREST || filtering_mode == TextureFilteringMode::MIPMAP_BILINEAR || filtering_mode == TextureFilteringMode::MIPMAP_TRILINEAR) {
|
||||
//3 mipmap levels.
|
||||
auto* m1 = new ReTexture::Texture(software_texture->downscale(2));
|
||||
auto* m2 = new ReTexture::Texture(software_texture->downscale(4));
|
||||
auto* m3 = new ReTexture::Texture(software_texture->downscale(8));
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 3);
|
||||
|
||||
if (format == ReTexture::TextureFormat::RGBA) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, m1->getWidth(), m1->getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, m1->pixelData.data());
|
||||
glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, m2->getWidth(), m2->getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, m2->pixelData.data());
|
||||
glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA, m3->getWidth(), m3->getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, m3->pixelData.data());
|
||||
}
|
||||
|
||||
if (format == ReTexture::TextureFormat::RGB) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGB, m1->getWidth(), m1->getHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, m1->pixelData.data());
|
||||
glTexImage2D(GL_TEXTURE_2D, 2, GL_RGB, m2->getWidth(), m2->getHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, m2->pixelData.data());
|
||||
glTexImage2D(GL_TEXTURE_2D, 3, GL_RGB, m3->getWidth(), m3->getHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, m3->pixelData.data());
|
||||
}
|
||||
|
||||
if (filtering_mode == TextureFilteringMode::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 == TextureFilteringMode::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 == TextureFilteringMode::MIPMAP_TRILINEAR)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
delete m1;
|
||||
delete m2;
|
||||
delete m3;
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
texture_size = size;
|
||||
texture_format = format;
|
||||
texture_filtering_mode = filtering_mode;
|
||||
}
|
||||
|
||||
std::vector<JGL::Color4> JGL::Texture::getPixelData() {
|
||||
std::vector<JGL::Color4> result((size_t) (texture_size.x * texture_size.y));
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
if (texture_format == ReTexture::TextureFormat::RGBA) {
|
||||
@@ -63,7 +103,7 @@ std::vector<JGL::Color4> JGL::Texture::getPixelData() {
|
||||
return result;
|
||||
}
|
||||
|
||||
void JGL::Texture::eraseTexture() {
|
||||
void JGL::Texture::erase() {
|
||||
if (texture != 0)
|
||||
glDeleteTextures(1, &texture);
|
||||
}
|
||||
@@ -83,3 +123,7 @@ ReTexture::TextureFlag JGL::Texture::getFlags() {
|
||||
ReTexture::TextureFormat JGL::Texture::getFormat() {
|
||||
return texture_format;
|
||||
}
|
||||
|
||||
JGL::TextureFilteringMode JGL::Texture::getTextureFilteringMode() {
|
||||
return texture_filtering_mode;
|
||||
}
|
||||
|
Reference in New Issue
Block a user