mirror of
https://github.com/Relintai/sfw.git
synced 2024-11-08 07:52:09 +01:00
Moved image loading from Texture to Image and made textures use Images.
This commit is contained in:
parent
1480d36a6e
commit
fe18833bc6
@ -54,18 +54,18 @@ ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/core -Isfw/object -c sfw/render_cor
|
||||
ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/core -Isfw/object -c sfw/render_core/texture.cpp -o sfw/render_core/texture.o
|
||||
ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/core -Isfw/object -c sfw/render_core/image.cpp -o sfw/render_core/image.o
|
||||
|
||||
ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/core -Isfw/render_core -Isfw/render_objects -c sfw/render_objects/camera_3d.cpp -o sfw/render_objects/camera_3d.o
|
||||
ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/core -Isfw/render_core -Isfw/render_objects -c sfw/render_objects/object_3d.cpp -o sfw/render_objects/object_3d.o
|
||||
ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/core -Isfw/render_core -Isfw/render_objects -c sfw/render_objects/mesh_instance_3d.cpp -o sfw/render_objects/mesh_instance_3d.o
|
||||
ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/core -Isfw/object -Isfw/render_core -Isfw/render_objects -c sfw/render_objects/camera_3d.cpp -o sfw/render_objects/camera_3d.o
|
||||
ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/core -Isfw/object -Isfw/render_core -Isfw/render_objects -c sfw/render_objects/object_3d.cpp -o sfw/render_objects/object_3d.o
|
||||
ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/core -Isfw/object -Isfw/render_core -Isfw/render_objects -c sfw/render_objects/mesh_instance_3d.cpp -o sfw/render_objects/mesh_instance_3d.o
|
||||
|
||||
ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/core -Isfw/render_core -Isfw/render_objects -c sfw/render_objects/camera_2d.cpp -o sfw/render_objects/camera_2d.o
|
||||
ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/core -Isfw/render_core -Isfw/render_objects -c sfw/render_objects/mesh_instance_2d.cpp -o sfw/render_objects/mesh_instance_2d.o
|
||||
ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/core -Isfw/render_core -Isfw/render_objects -c sfw/render_objects/object_2d.cpp -o sfw/render_objects/object_2d.o
|
||||
ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/core -Isfw/render_core -Isfw/render_objects -c sfw/render_objects/sprite.cpp -o sfw/render_objects/sprite.o
|
||||
ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/core -Isfw/render_core -Isfw/render_objects -c sfw/render_objects/tile_map.cpp -o sfw/render_objects/tile_map.o
|
||||
ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/core -Isfw/object -Isfw/render_core -Isfw/render_objects -c sfw/render_objects/camera_2d.cpp -o sfw/render_objects/camera_2d.o
|
||||
ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/core -Isfw/object -Isfw/render_core -Isfw/render_objects -c sfw/render_objects/mesh_instance_2d.cpp -o sfw/render_objects/mesh_instance_2d.o
|
||||
ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/core -Isfw/object -Isfw/render_core -Isfw/render_objects -c sfw/render_objects/object_2d.cpp -o sfw/render_objects/object_2d.o
|
||||
ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/core -Isfw/object -Isfw/render_core -Isfw/render_objects -c sfw/render_objects/sprite.cpp -o sfw/render_objects/sprite.o
|
||||
ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/core -Isfw/object -Isfw/render_core -Isfw/render_objects -c sfw/render_objects/tile_map.cpp -o sfw/render_objects/tile_map.o
|
||||
|
||||
ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/core -Isfw/render_core -Isfw/render_objects -c game_scene.cpp -o game_scene.o
|
||||
ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/core -Isfw/render_core -Isfw/render_objects -c main.cpp -o main.o
|
||||
ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/core -Isfw/object -Isfw/render_core -Isfw/render_objects -c game_scene.cpp -o game_scene.o
|
||||
ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/core -Isfw/object -Isfw/render_core -Isfw/render_objects -c main.cpp -o main.o
|
||||
|
||||
|
||||
ccache g++ -Wall -lm -ldl -lpthread -lX11 -D_REENTRANT -g sfw/core/aabb.o sfw/core/basis.o sfw/core/color.o \
|
||||
|
@ -136,8 +136,12 @@ GameScene::GameScene() {
|
||||
//float ar = static_cast<float>(w) / static_cast<float>(h);
|
||||
//camera->width = camera->height * ar;
|
||||
|
||||
image.instance();
|
||||
image->load_from_file("icon.png");
|
||||
|
||||
texture = new Texture();
|
||||
texture->load_image("icon.png");
|
||||
//texture->load_image("icon.png");
|
||||
texture->set_image(image);
|
||||
//ha a textúrának van alpha csatornája:
|
||||
//texture->load_image("download.bmp", GL_RGBA, GL_RGBA);
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "texture.h"
|
||||
#include "texture_material.h"
|
||||
#include "texture_material_2d.h"
|
||||
#include "image.h"
|
||||
|
||||
class GameScene : public Scene {
|
||||
public:
|
||||
@ -30,6 +31,7 @@ public:
|
||||
bool down;
|
||||
*/
|
||||
|
||||
Ref<Image> image;
|
||||
Texture *texture;
|
||||
TextureMaterial2D *material;
|
||||
|
||||
|
@ -31,12 +31,27 @@
|
||||
#include "image.h"
|
||||
|
||||
#include "error_macros.h"
|
||||
#include "hash_map.h"
|
||||
#include "math.h"
|
||||
#include "vector3.h"
|
||||
#include "memory.h"
|
||||
#include "vector3.h"
|
||||
#include <memory.h>
|
||||
#include <stdio.h>
|
||||
#include "hash_map.h"
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION // stbi
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION // stbi_write
|
||||
#define STB_SPRINTF_IMPLEMENTATION // stb_sprintf
|
||||
#define STB_SPRINTF_NOUNALIGNED // stb_sprintf
|
||||
|
||||
#include "3rd_stb_image.h"
|
||||
|
||||
//{{FILE:3rd_stb_image_write.h}}
|
||||
//---
|
||||
#undef freelist
|
||||
#define STBTT_malloc(x, u) ((void)(u), MALLOC(x))
|
||||
#define STBTT_free(x, u) ((void)(u), FREE(x))
|
||||
#define NK_ASSERT ASSERT
|
||||
#define NK_DTOA(s, n) strcpy(s, va("%f", n)) // override cos built-in nk_dtoa() will freeze while parsing UINT_MAX otherwise
|
||||
|
||||
const char *Image::format_names[Image::FORMAT_MAX] = {
|
||||
"Lum8", // luminance
|
||||
@ -1689,6 +1704,55 @@ int Image::get_data_size() const {
|
||||
return data.size();
|
||||
}
|
||||
|
||||
void Image::load_from_file(const String &file_name, Format p_format) {
|
||||
//stbi_set_flip_vertically_on_load(flags & IMAGE_FLIP ? 1 : 0);
|
||||
|
||||
int img_n = 4;
|
||||
|
||||
FILE *fp = fopen(file_name.utf8().get_data(), "r");
|
||||
|
||||
//case FORMAT_RF:
|
||||
//case FORMAT_RGF:
|
||||
//case FORMAT_RGBF:
|
||||
//case FORMAT_RGBAF:
|
||||
//img.pixels = stbi_loadf_from_file((const stbi_uc *)data, size, (int *)&img.x, (int *)&img.y, (int *)&img.n, n);
|
||||
|
||||
int x;
|
||||
int y;
|
||||
int n;
|
||||
|
||||
stbi_uc *pixels = stbi_load_from_file(fp, &x, &y, &n, img_n);
|
||||
fclose(fp);
|
||||
|
||||
ERR_FAIL_COND_MSG(!pixels, "Couldn't load image! " + file_name);
|
||||
|
||||
if (n != img_n) {
|
||||
memdelete(pixels);
|
||||
ERR_PRINT("Couldn't load image! n != img_n");
|
||||
return;
|
||||
}
|
||||
|
||||
int size = x * y * get_format_pixel_size(FORMAT_RGBA8);
|
||||
|
||||
{
|
||||
write_lock = true;
|
||||
data.resize(size);
|
||||
memcpy(data.ptrw(), pixels, size);
|
||||
write_lock = false;
|
||||
}
|
||||
|
||||
width = x;
|
||||
height = y;
|
||||
mipmaps = false;
|
||||
format = FORMAT_RGBA8;
|
||||
|
||||
memdelete(pixels);
|
||||
|
||||
if (p_format != FORMAT_RGBA8) {
|
||||
convert(p_format);
|
||||
}
|
||||
}
|
||||
|
||||
void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_format) {
|
||||
ERR_FAIL_COND_MSG(p_width <= 0, "Image width must be greater than 0.");
|
||||
ERR_FAIL_COND_MSG(p_height <= 0, "Image height must be greater than 0.");
|
||||
|
@ -200,10 +200,13 @@ public:
|
||||
/**
|
||||
* Create a new image of a given size and format. Current image will be lost
|
||||
*/
|
||||
void load_from_file(const String &file_name, Format p_format = FORMAT_RGBA8);
|
||||
|
||||
void create(int p_width, int p_height, bool p_use_mipmaps, Format p_format);
|
||||
void create(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data);
|
||||
|
||||
void create(const char **p_xpm);
|
||||
|
||||
/**
|
||||
* returns true when the image is empty (0,0) in size
|
||||
*/
|
||||
|
@ -3,80 +3,515 @@
|
||||
#include "memory.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION // stbi
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION // stbi_write
|
||||
#define STB_SPRINTF_IMPLEMENTATION // stb_sprintf
|
||||
#define STB_SPRINTF_NOUNALIGNED // stb_sprintf
|
||||
/*
|
||||
Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool p_force_decompress) const {
|
||||
r_gl_format = 0;
|
||||
Ref<Image> image = p_image;
|
||||
r_compressed = false;
|
||||
r_real_format = p_format;
|
||||
|
||||
#include "3rd_stb_image.h"
|
||||
bool need_decompress = false;
|
||||
|
||||
//{{FILE:3rd_stb_image_write.h}}
|
||||
//---
|
||||
#undef freelist
|
||||
#define STBTT_malloc(x, u) ((void)(u), MALLOC(x))
|
||||
#define STBTT_free(x, u) ((void)(u), FREE(x))
|
||||
#define NK_ASSERT ASSERT
|
||||
#define NK_DTOA(s, n) strcpy(s, va("%f", n)) // override cos built-in nk_dtoa() will freeze while parsing UINT_MAX otherwise
|
||||
switch (p_format) {
|
||||
case Image::FORMAT_L8: {
|
||||
r_gl_internal_format = GL_LUMINANCE;
|
||||
r_gl_format = GL_LUMINANCE;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
} break;
|
||||
case Image::FORMAT_LA8: {
|
||||
r_gl_internal_format = GL_LUMINANCE_ALPHA;
|
||||
r_gl_format = GL_LUMINANCE_ALPHA;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
} break;
|
||||
case Image::FORMAT_R8: {
|
||||
r_gl_internal_format = GL_ALPHA;
|
||||
r_gl_format = GL_ALPHA;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
|
||||
void Texture::image_data_load(const char *file_name, int flags) {
|
||||
//stbi_set_flip_vertically_on_load(flags & IMAGE_FLIP ? 1 : 0);
|
||||
|
||||
int img_n = 0;
|
||||
//if (flags & IMAGE_R)
|
||||
// n = 1;
|
||||
//if (flags & IMAGE_RG)
|
||||
// n = 2;
|
||||
//if (flags & IMAGE_RGB)
|
||||
// n = 3;
|
||||
//if (flags & IMAGE_RGBA)
|
||||
img_n = 4;
|
||||
//if (flags & IMAGE_FLOAT)
|
||||
// img.pixels = stbi_loadf_from_file((const stbi_uc *)data, size, (int *)&img.x, (int *)&img.y, (int *)&img.n, n);
|
||||
//else
|
||||
|
||||
FILE *fp = fopen(file_name, "r");
|
||||
|
||||
pixels = stbi_load_from_file(fp, &x, &y, &n, img_n);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
//if (img.pixels) {
|
||||
// PRINTF("Loaded image (%dx%d %.*s->%.*s)\n", img.w, img.h, img.n, "RGBA", n ? n : img.n, "RGBA");
|
||||
//} else {
|
||||
// PANIC("Error loading image (%s)\n", pathfile);
|
||||
//}
|
||||
|
||||
n = img_n ? img_n : n;
|
||||
}
|
||||
|
||||
void Texture::load_image(const char *file_name, const int format, const int internal_components) {
|
||||
if (pixels) {
|
||||
//TODO
|
||||
//memdelete(pixels);
|
||||
pixels = NULL;
|
||||
glDeleteTextures(1, &texture);
|
||||
} break;
|
||||
case Image::FORMAT_RG8: {
|
||||
ERR_PRINT("RG texture not supported, converting to RGB8.");
|
||||
if (image.is_valid()) {
|
||||
image->convert(Image::FORMAT_RGB8);
|
||||
}
|
||||
r_real_format = Image::FORMAT_RGB8;
|
||||
r_gl_internal_format = GL_RGB;
|
||||
r_gl_format = GL_RGB;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
|
||||
image_data_load(file_name, 0);
|
||||
} break;
|
||||
case Image::FORMAT_RGB8: {
|
||||
r_gl_internal_format = GL_RGB;
|
||||
r_gl_format = GL_RGB;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
|
||||
if (!pixels) {
|
||||
printf("Couldn't load %s.\n", file_name);
|
||||
} break;
|
||||
case Image::FORMAT_RGBA8: {
|
||||
r_gl_format = GL_RGBA;
|
||||
r_gl_internal_format = GL_RGBA;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
|
||||
} break;
|
||||
case Image::FORMAT_RGBA4444: {
|
||||
r_gl_internal_format = GL_RGBA;
|
||||
r_gl_format = GL_RGBA;
|
||||
r_gl_type = GL_UNSIGNED_SHORT_4_4_4_4;
|
||||
|
||||
} break;
|
||||
case Image::FORMAT_RGBA5551: {
|
||||
r_gl_internal_format = GL_RGB5_A1;
|
||||
r_gl_format = GL_RGBA;
|
||||
r_gl_type = GL_UNSIGNED_SHORT_5_5_5_1;
|
||||
|
||||
} break;
|
||||
case Image::FORMAT_RF: {
|
||||
if (!config.float_texture_supported) {
|
||||
ERR_PRINT("R float texture not supported, converting to RGB8.");
|
||||
if (image.is_valid()) {
|
||||
image->convert(Image::FORMAT_RGB8);
|
||||
}
|
||||
r_real_format = Image::FORMAT_RGB8;
|
||||
r_gl_internal_format = GL_RGB;
|
||||
r_gl_format = GL_RGB;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
} else {
|
||||
//image = SDL_ConvertSurfaceFormat(img, SDL_PIXELFORMAT_RGBA32, 0);
|
||||
//SDL_FreeSurface(img);
|
||||
|
||||
glGenTextures(1, &texture);
|
||||
|
||||
texture_update(0);
|
||||
|
||||
//glBindTexture(GL_TEXTURE_2D, texture);
|
||||
//glTexImage2D(GL_TEXTURE_2D, 0, format, image->w, image->h, 0, internal_components, GL_UNSIGNED_BYTE, image->pixels);
|
||||
//apply_filter();
|
||||
r_gl_internal_format = GL_ALPHA;
|
||||
r_gl_format = GL_ALPHA;
|
||||
r_gl_type = GL_FLOAT;
|
||||
}
|
||||
} break;
|
||||
case Image::FORMAT_RGF: {
|
||||
ERR_PRINT("RG float texture not supported, converting to RGB8.");
|
||||
if (image.is_valid()) {
|
||||
image->convert(Image::FORMAT_RGB8);
|
||||
}
|
||||
r_real_format = Image::FORMAT_RGB8;
|
||||
r_gl_internal_format = GL_RGB;
|
||||
r_gl_format = GL_RGB;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
} break;
|
||||
case Image::FORMAT_RGBF: {
|
||||
if (!config.float_texture_supported) {
|
||||
ERR_PRINT("RGB float texture not supported, converting to RGB8.");
|
||||
if (image.is_valid()) {
|
||||
image->convert(Image::FORMAT_RGB8);
|
||||
}
|
||||
r_real_format = Image::FORMAT_RGB8;
|
||||
r_gl_internal_format = GL_RGB;
|
||||
r_gl_format = GL_RGB;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
} else {
|
||||
r_gl_internal_format = GL_RGB;
|
||||
r_gl_format = GL_RGB;
|
||||
r_gl_type = GL_FLOAT;
|
||||
}
|
||||
} break;
|
||||
case Image::FORMAT_RGBAF: {
|
||||
if (!config.float_texture_supported) {
|
||||
ERR_PRINT("RGBA float texture not supported, converting to RGBA8.");
|
||||
if (image.is_valid()) {
|
||||
image->convert(Image::FORMAT_RGBA8);
|
||||
}
|
||||
r_real_format = Image::FORMAT_RGBA8;
|
||||
r_gl_internal_format = GL_RGBA;
|
||||
r_gl_format = GL_RGBA;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
} else {
|
||||
r_gl_internal_format = GL_RGBA;
|
||||
r_gl_format = GL_RGBA;
|
||||
r_gl_type = GL_FLOAT;
|
||||
}
|
||||
} break;
|
||||
case Image::FORMAT_RH: {
|
||||
need_decompress = true;
|
||||
} break;
|
||||
case Image::FORMAT_RGH: {
|
||||
need_decompress = true;
|
||||
} break;
|
||||
case Image::FORMAT_RGBH: {
|
||||
need_decompress = true;
|
||||
} break;
|
||||
case Image::FORMAT_RGBAH: {
|
||||
need_decompress = true;
|
||||
} break;
|
||||
case Image::FORMAT_RGBE9995: {
|
||||
r_gl_internal_format = GL_RGB;
|
||||
r_gl_format = GL_RGB;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
|
||||
if (image.is_valid()) {
|
||||
image = image->rgbe_to_srgb();
|
||||
}
|
||||
|
||||
return image;
|
||||
|
||||
} break;
|
||||
case Image::FORMAT_DXT1: {
|
||||
if (config.s3tc_supported) {
|
||||
r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT;
|
||||
r_gl_format = GL_RGBA;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
r_compressed = true;
|
||||
} else {
|
||||
need_decompress = true;
|
||||
}
|
||||
|
||||
} break;
|
||||
case Image::FORMAT_DXT3: {
|
||||
if (config.s3tc_supported) {
|
||||
r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT3_EXT;
|
||||
r_gl_format = GL_RGBA;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
r_compressed = true;
|
||||
} else {
|
||||
need_decompress = true;
|
||||
}
|
||||
|
||||
} break;
|
||||
case Image::FORMAT_DXT5: {
|
||||
if (config.s3tc_supported) {
|
||||
r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||
r_gl_format = GL_RGBA;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
r_compressed = true;
|
||||
} else {
|
||||
need_decompress = true;
|
||||
}
|
||||
|
||||
} break;
|
||||
case Image::FORMAT_RGTC_R: {
|
||||
if (config.rgtc_supported) {
|
||||
r_gl_internal_format = _EXT_COMPRESSED_RED_RGTC1_EXT;
|
||||
r_gl_format = GL_RGBA;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
r_compressed = true;
|
||||
|
||||
} else {
|
||||
need_decompress = true;
|
||||
}
|
||||
|
||||
} break;
|
||||
case Image::FORMAT_RGTC_RG: {
|
||||
if (config.rgtc_supported) {
|
||||
r_gl_internal_format = _EXT_COMPRESSED_RED_GREEN_RGTC2_EXT;
|
||||
r_gl_format = GL_RGBA;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
r_compressed = true;
|
||||
} else {
|
||||
need_decompress = true;
|
||||
}
|
||||
|
||||
} break;
|
||||
case Image::FORMAT_BPTC_RGBA: {
|
||||
if (config.bptc_supported) {
|
||||
r_gl_internal_format = _EXT_COMPRESSED_RGBA_BPTC_UNORM;
|
||||
r_gl_format = GL_RGBA;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
r_compressed = true;
|
||||
|
||||
} else {
|
||||
need_decompress = true;
|
||||
}
|
||||
} break;
|
||||
case Image::FORMAT_BPTC_RGBF: {
|
||||
if (config.bptc_supported) {
|
||||
r_gl_internal_format = _EXT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT;
|
||||
r_gl_format = GL_RGB;
|
||||
r_gl_type = GL_FLOAT;
|
||||
r_compressed = true;
|
||||
} else {
|
||||
need_decompress = true;
|
||||
}
|
||||
} break;
|
||||
case Image::FORMAT_BPTC_RGBFU: {
|
||||
if (config.bptc_supported) {
|
||||
r_gl_internal_format = _EXT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT;
|
||||
r_gl_format = GL_RGB;
|
||||
r_gl_type = GL_FLOAT;
|
||||
r_compressed = true;
|
||||
} else {
|
||||
need_decompress = true;
|
||||
}
|
||||
} break;
|
||||
case Image::FORMAT_PVRTC2: {
|
||||
if (config.pvrtc_supported) {
|
||||
r_gl_internal_format = _EXT_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
|
||||
r_gl_format = GL_RGBA;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
r_compressed = true;
|
||||
|
||||
} else {
|
||||
need_decompress = true;
|
||||
}
|
||||
} break;
|
||||
case Image::FORMAT_PVRTC2A: {
|
||||
if (config.pvrtc_supported) {
|
||||
r_gl_internal_format = _EXT_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
|
||||
r_gl_format = GL_RGBA;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
r_compressed = true;
|
||||
|
||||
} else {
|
||||
need_decompress = true;
|
||||
}
|
||||
|
||||
} break;
|
||||
case Image::FORMAT_PVRTC4: {
|
||||
if (config.pvrtc_supported) {
|
||||
r_gl_internal_format = _EXT_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
|
||||
r_gl_format = GL_RGBA;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
r_compressed = true;
|
||||
|
||||
} else {
|
||||
need_decompress = true;
|
||||
}
|
||||
|
||||
} break;
|
||||
case Image::FORMAT_PVRTC4A: {
|
||||
if (config.pvrtc_supported) {
|
||||
r_gl_internal_format = _EXT_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
|
||||
r_gl_format = GL_RGBA;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
r_compressed = true;
|
||||
|
||||
} else {
|
||||
need_decompress = true;
|
||||
}
|
||||
|
||||
} break;
|
||||
case Image::FORMAT_ETC: {
|
||||
if (config.etc1_supported) {
|
||||
r_gl_internal_format = _EXT_ETC1_RGB8_OES;
|
||||
r_gl_format = GL_RGBA;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
r_compressed = true;
|
||||
} else {
|
||||
need_decompress = true;
|
||||
}
|
||||
} break;
|
||||
case Image::FORMAT_ETC2_R11: {
|
||||
need_decompress = true;
|
||||
} break;
|
||||
case Image::FORMAT_ETC2_R11S: {
|
||||
need_decompress = true;
|
||||
} break;
|
||||
case Image::FORMAT_ETC2_RG11: {
|
||||
need_decompress = true;
|
||||
} break;
|
||||
case Image::FORMAT_ETC2_RG11S: {
|
||||
need_decompress = true;
|
||||
} break;
|
||||
case Image::FORMAT_ETC2_RGB8: {
|
||||
need_decompress = true;
|
||||
} break;
|
||||
case Image::FORMAT_ETC2_RGBA8: {
|
||||
need_decompress = true;
|
||||
} break;
|
||||
case Image::FORMAT_ETC2_RGB8A1: {
|
||||
need_decompress = true;
|
||||
} break;
|
||||
default: {
|
||||
ERR_FAIL_V(Ref<Image>());
|
||||
}
|
||||
}
|
||||
|
||||
if (need_decompress || p_force_decompress) {
|
||||
if (!image.is_null()) {
|
||||
image = image->duplicate();
|
||||
image->decompress();
|
||||
ERR_FAIL_COND_V(image->is_compressed(), image);
|
||||
switch (image->get_format()) {
|
||||
case Image::FORMAT_RGB8: {
|
||||
r_gl_format = GL_RGB;
|
||||
r_gl_internal_format = GL_RGB;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
r_real_format = Image::FORMAT_RGB8;
|
||||
r_compressed = false;
|
||||
} break;
|
||||
case Image::FORMAT_RGBA8: {
|
||||
r_gl_format = GL_RGBA;
|
||||
r_gl_internal_format = GL_RGBA;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
r_real_format = Image::FORMAT_RGBA8;
|
||||
r_compressed = false;
|
||||
} break;
|
||||
default: {
|
||||
image->convert(Image::FORMAT_RGBA8);
|
||||
r_gl_format = GL_RGBA;
|
||||
r_gl_internal_format = GL_RGBA;
|
||||
r_gl_type = GL_UNSIGNED_BYTE;
|
||||
r_real_format = Image::FORMAT_RGBA8;
|
||||
r_compressed = false;
|
||||
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
return p_image;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
void RasterizerStorageGLES2::texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_layer) {
|
||||
Texture *texture = texture_owner.getornull(p_texture);
|
||||
|
||||
ERR_FAIL_COND(!texture);
|
||||
if (texture->target == GL_TEXTURE_3D) {
|
||||
// Target is set to a 3D texture or array texture, exit early to avoid spamming errors
|
||||
return;
|
||||
}
|
||||
ERR_FAIL_COND(!texture->active);
|
||||
ERR_FAIL_COND(texture->render_target);
|
||||
ERR_FAIL_COND(texture->format != p_image->get_format());
|
||||
ERR_FAIL_COND(p_image.is_null());
|
||||
ERR_FAIL_COND(texture->type == RS::TEXTURE_TYPE_EXTERNAL);
|
||||
|
||||
GLenum type;
|
||||
GLenum format;
|
||||
GLenum internal_format;
|
||||
bool compressed = false;
|
||||
|
||||
if (config.keep_original_textures && !(texture->flags & RS::TEXTURE_FLAG_USED_FOR_STREAMING)) {
|
||||
texture->images.write[p_layer] = p_image;
|
||||
}
|
||||
|
||||
Image::Format real_format;
|
||||
Ref<Image> img = _get_gl_image_and_format(p_image, p_image->get_format(), texture->flags, real_format, format, internal_format, type, compressed, texture->resize_to_po2);
|
||||
|
||||
if (texture->resize_to_po2) {
|
||||
if (p_image->is_compressed()) {
|
||||
ERR_PRINT("Texture '" + texture->path + "' is required to be a power of 2 because it uses either mipmaps or repeat, so it was decompressed. This will hurt performance and memory usage.");
|
||||
}
|
||||
|
||||
if (img == p_image) {
|
||||
img = img->duplicate();
|
||||
}
|
||||
img->resize_to_po2(false, texture->flags & RS::TEXTURE_FLAG_FILTER ? Image::INTERPOLATE_BILINEAR : Image::INTERPOLATE_NEAREST);
|
||||
}
|
||||
|
||||
if (config.shrink_textures_x2 && (p_image->has_mipmaps() || !p_image->is_compressed()) && !(texture->flags & RS::TEXTURE_FLAG_USED_FOR_STREAMING)) {
|
||||
texture->alloc_height = MAX(1, texture->alloc_height / 2);
|
||||
texture->alloc_width = MAX(1, texture->alloc_width / 2);
|
||||
|
||||
if (texture->alloc_width == img->get_width() / 2 && texture->alloc_height == img->get_height() / 2) {
|
||||
img->shrink_x2();
|
||||
} else if (img->get_format() <= Image::FORMAT_RGBA8) {
|
||||
img->resize(texture->alloc_width, texture->alloc_height, Image::INTERPOLATE_BILINEAR);
|
||||
}
|
||||
}
|
||||
|
||||
GLenum blit_target = (texture->target == GL_TEXTURE_CUBE_MAP) ? _cube_side_enum[p_layer] : GL_TEXTURE_2D;
|
||||
|
||||
texture->data_size = img->get_data().size();
|
||||
PoolVector<uint8_t>::Read read = img->get_data().read();
|
||||
ERR_FAIL_COND(!read.ptr());
|
||||
|
||||
gl_wrapper.gl_active_texture(GL_TEXTURE0);
|
||||
glBindTexture(texture->target, texture->tex_id);
|
||||
|
||||
texture->ignore_mipmaps = compressed && !img->has_mipmaps();
|
||||
|
||||
if ((texture->flags & RS::TEXTURE_FLAG_MIPMAPS) && !texture->ignore_mipmaps) {
|
||||
if (texture->flags & RS::TEXTURE_FLAG_FILTER) {
|
||||
glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, config.use_fast_texture_filter ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR_MIPMAP_LINEAR);
|
||||
} else {
|
||||
glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, config.use_fast_texture_filter ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST_MIPMAP_LINEAR);
|
||||
}
|
||||
} else {
|
||||
if (texture->flags & RS::TEXTURE_FLAG_FILTER) {
|
||||
glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
} else {
|
||||
glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
}
|
||||
}
|
||||
|
||||
if (texture->flags & RS::TEXTURE_FLAG_FILTER) {
|
||||
glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering
|
||||
|
||||
} else {
|
||||
glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // raw Filtering
|
||||
}
|
||||
|
||||
if (((texture->flags & RS::TEXTURE_FLAG_REPEAT) || (texture->flags & RS::TEXTURE_FLAG_MIRRORED_REPEAT)) && texture->target != GL_TEXTURE_CUBE_MAP) {
|
||||
if (texture->flags & RS::TEXTURE_FLAG_MIRRORED_REPEAT) {
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
|
||||
} else {
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
}
|
||||
} else {
|
||||
//glTexParameterf( texture->target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );
|
||||
glTexParameterf(texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterf(texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
if (config.use_anisotropic_filter) {
|
||||
if (texture->flags & RS::TEXTURE_FLAG_ANISOTROPIC_FILTER) {
|
||||
glTexParameterf(texture->target, _GL_TEXTURE_MAX_ANISOTROPY_EXT, config.anisotropic_level);
|
||||
} else {
|
||||
glTexParameterf(texture->target, _GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
|
||||
}
|
||||
}
|
||||
|
||||
int mipmaps = ((texture->flags & RS::TEXTURE_FLAG_MIPMAPS) && img->has_mipmaps()) ? img->get_mipmap_count() + 1 : 1;
|
||||
|
||||
int w = img->get_width();
|
||||
int h = img->get_height();
|
||||
|
||||
int tsize = 0;
|
||||
|
||||
for (int i = 0; i < mipmaps; i++) {
|
||||
int size, ofs;
|
||||
img->get_mipmap_offset_and_size(i, ofs, size);
|
||||
|
||||
if (compressed) {
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
|
||||
int bw = w;
|
||||
int bh = h;
|
||||
|
||||
glCompressedTexImage2D(blit_target, i, internal_format, bw, bh, 0, size, &read[ofs]);
|
||||
} else {
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
if (texture->flags & RS::TEXTURE_FLAG_USED_FOR_STREAMING) {
|
||||
glTexSubImage2D(blit_target, i, 0, 0, w, h, format, type, &read[ofs]);
|
||||
} else {
|
||||
glTexImage2D(blit_target, i, internal_format, w, h, 0, format, type, &read[ofs]);
|
||||
}
|
||||
}
|
||||
|
||||
tsize += size;
|
||||
|
||||
w = MAX(1, w >> 1);
|
||||
h = MAX(1, h >> 1);
|
||||
}
|
||||
|
||||
info.texture_mem -= texture->total_data_size;
|
||||
texture->total_data_size = tsize;
|
||||
info.texture_mem += texture->total_data_size;
|
||||
|
||||
// printf("texture: %i x %i - size: %i - total: %i\n", texture->width, texture->height, tsize, info.texture_mem);
|
||||
|
||||
texture->stored_cube_sides |= (1 << p_layer);
|
||||
|
||||
if ((texture->flags & RS::TEXTURE_FLAG_MIPMAPS) && mipmaps == 1 && !texture->ignore_mipmaps && (texture->type != RS::TEXTURE_TYPE_CUBEMAP || texture->stored_cube_sides == (1 << 6) - 1)) {
|
||||
//generate mipmaps if they were requested and the image does not contain them
|
||||
glGenerateMipmap(texture->target);
|
||||
}
|
||||
|
||||
texture->mipmaps = mipmaps;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
void Texture::texture_update(int flags) {
|
||||
if (!pixels) {
|
||||
if (!_image.is_valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -95,6 +530,7 @@ void Texture::texture_update(int flags) {
|
||||
GLuint pixel_type = GL_RGBA;
|
||||
//GLuint texel_type = t->texel_type = pixel_types[n + 5 * !!(flags & TEXTURE_FLOAT)];
|
||||
GLuint texel_type = GL_RGBA;
|
||||
|
||||
GLenum wrap = GL_CLAMP_TO_EDGE;
|
||||
GLenum min_filter = GL_NEAREST, mag_filter = GL_NEAREST;
|
||||
// GLfloat color = (flags&7)/7.f, border_color[4] = { color, color, color, 1.f };
|
||||
@ -135,35 +571,22 @@ void Texture::texture_update(int flags) {
|
||||
mag_filter = flags & TEXTURE_LINEAR ? GL_LINEAR : GL_NEAREST;
|
||||
*/
|
||||
|
||||
#if 0
|
||||
if( 0 ) { // flags & TEXTURE_PREMULTIPLY_ALPHA )
|
||||
uint8_t *p = pixels;
|
||||
if(n == 2) for( unsigned i = 0; i < 2*w*h; i += 2 ) {
|
||||
p[i] = (p[i] * p[i+1] + 128) >> 8;
|
||||
}
|
||||
if(n == 4) for( unsigned i = 0; i < 4*w*h; i += 4 ) {
|
||||
p[i+0] = (p[i+0] * p[i+3] + 128) >> 8;
|
||||
p[i+1] = (p[i+1] * p[i+3] + 128) >> 8;
|
||||
p[i+2] = (p[i+2] * p[i+3] + 128) >> 8;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//GLenum texture_type = t->flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D; // @fixme: test GL_TEXTURE_2D_ARRAY
|
||||
GLenum texture_type = GL_TEXTURE_2D; // @fixme: test GL_TEXTURE_2D_ARRAY
|
||||
|
||||
//glPixelStorei( GL_UNPACK_ALIGNMENT, n < 4 ? 1 : 4 ); // for framebuffer reading
|
||||
//glActiveTexture(GL_TEXTURE0 + (flags&7));
|
||||
glBindTexture(texture_type, texture);
|
||||
glTexImage2D(texture_type, 0, texel_type, w, h, 0, pixel_type, pixel_storage, pixels);
|
||||
//glTexImage2D(texture_type, 0, texel_type, w, h, 0, pixel_type, pixel_storage, pixels);
|
||||
|
||||
glTexParameteri(texture_type, GL_TEXTURE_WRAP_S, wrap);
|
||||
glTexParameteri(texture_type, GL_TEXTURE_WRAP_T, wrap);
|
||||
glTexParameteri(texture_type, GL_TEXTURE_MIN_FILTER, min_filter);
|
||||
glTexParameteri(texture_type, GL_TEXTURE_MAG_FILTER, mag_filter);
|
||||
#if 0 // only for sampler2DShadow
|
||||
if( flags & TEXTURE_DEPTH ) glTexParameteri(texture_type, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||
if( flags & TEXTURE_DEPTH ) glTexParameteri(texture_type, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
|
||||
#endif
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glTexImage2D(texture_type, 0, texel_type, _image_width, _image_height, 0, pixel_type, pixel_storage, _image_data.ptr());
|
||||
|
||||
// if( flags & TEXTURE_BORDER ) glTexParameterfv(texture_type, GL_TEXTURE_BORDER_COLOR, border_color);
|
||||
/*
|
||||
if (flags & TEXTURE_MIPMAPS)
|
||||
@ -189,6 +612,10 @@ void Texture::texture_update(int flags) {
|
||||
}
|
||||
|
||||
void Texture::apply_filter() {
|
||||
if (!texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
GLint params = GL_NEAREST;
|
||||
|
||||
if (filter == TEXTURE_FILTER_LINEAR) {
|
||||
@ -200,17 +627,43 @@ void Texture::apply_filter() {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, params);
|
||||
}
|
||||
|
||||
void Texture::set_image(const Ref<Image> &img) {
|
||||
_image = img;
|
||||
|
||||
if (texture) {
|
||||
glDeleteTextures(1, &texture);
|
||||
}
|
||||
|
||||
if (!_image.is_valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_image_data = _image->get_data();
|
||||
_image_format = _image->get_format();
|
||||
_image_width = _image->get_width();
|
||||
_image_height = _image->get_height();
|
||||
_image_mip_maps = _image->has_mipmaps();
|
||||
|
||||
if (_image_data.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
glGenTextures(1, &texture);
|
||||
|
||||
texture_update(0);
|
||||
}
|
||||
|
||||
Texture::Texture() {
|
||||
filter = TEXTURE_FILTER_NEAREST;
|
||||
texture = 0;
|
||||
pixels = NULL;
|
||||
_image_width = 0;
|
||||
_image_height = 0;
|
||||
_image_format = Image::FORMAT_RGBA8;
|
||||
_image_mip_maps = false;
|
||||
}
|
||||
|
||||
Texture::~Texture() {
|
||||
if (pixels) {
|
||||
//todo
|
||||
//delete (pixels);
|
||||
|
||||
if (texture) {
|
||||
glDeleteTextures(1, &texture);
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define TEXTURE_H
|
||||
|
||||
#include "3rd_glad.h"
|
||||
#include "image.h"
|
||||
|
||||
class Texture {
|
||||
public:
|
||||
@ -10,36 +11,24 @@ public:
|
||||
TEXTURE_FILTER_LINEAR,
|
||||
};
|
||||
|
||||
void load_image(const char *file_name, const int format = GL_RGBA, const int internal_components = GL_RGBA);
|
||||
void apply_filter();
|
||||
|
||||
TextureFilter filter;
|
||||
GLuint texture;
|
||||
|
||||
// from fwk, temporary
|
||||
union {
|
||||
int x, w;
|
||||
};
|
||||
union {
|
||||
int y, h;
|
||||
};
|
||||
union {
|
||||
int n, comps;
|
||||
};
|
||||
union {
|
||||
void *pixels;
|
||||
uint8_t *pixels8;
|
||||
uint16_t *pixels16;
|
||||
uint32_t *pixels32;
|
||||
float *pixelsf;
|
||||
};
|
||||
|
||||
// From FWK
|
||||
void image_data_load(const char *file_name, int flags);
|
||||
void apply_filter();
|
||||
void texture_update(int flags);
|
||||
|
||||
void set_image(const Ref<Image> &img);
|
||||
|
||||
Texture();
|
||||
virtual ~Texture();
|
||||
|
||||
protected:
|
||||
int _image_width;
|
||||
int _image_height;
|
||||
Ref<Image> _image;
|
||||
Vector<uint8_t> _image_data;
|
||||
Image::Format _image_format;
|
||||
bool _image_mip_maps;
|
||||
};
|
||||
|
||||
#endif // TEXTURE_H
|
||||
|
Loading…
Reference in New Issue
Block a user