taisei/src/resource/texture.c

191 lines
4.1 KiB
C
Raw Permalink Normal View History

/*
* This software is licensed under the terms of the MIT License.
* See COPYING for further information.
* ---
2024-05-16 23:30:41 +02:00
* Copyright (c) 2011-2024, Lukas Weber <laochailan@web.de>.
* Copyright (c) 2012-2024, Andrei Alexeyev <akari@taisei-project.org>.
*/
Texturing overhaul: GPU compression, sRGB sampling, swizzles, etc. (#240) * WIP compressed textures, swizzles, sRGB sampling, ... * refactor texture type info & fix random bugs * fix preprocessing of sRGB textures * handle y-flipped basis textures * glcommon: better WebGL compat for compressed format detection * missed WEBGL_compressed_texture_pvrtc * implement compressed texture xcoding and uploading * Add basis_universal submodule * Reorganize texture loader code Clean up some code Isolate Basis Universal loader into a separate module * Add wrapper script for encoding .basis textures * basisu: honor custom metadata written by the mkbasis.py script * mkbasis.py: add --incredibly-slow and --dry-run * Move pixmap code from util/ to pixmap/ * Add an on-disk transcode cache for basis textures to speed up loads * Compress texture cache with zlib * Use readable format names for basisu cache filenames * basisu: mip bias test code * basisu: small caching cleanup * add TAISEI_BASISU_MIP_BIAS env variable * Improve OpenGL format matching heuristics * Document considerations for compressed format priority * Remove dead code * Enable two forgotten formats, BC3_RGBA and ATC_RGBA Also prefer BC7 over BC1/BC3 * Recognize GL_ANGLE_compressed_texture_etc for ETC2 textures * Default depth buffers to 24-bit; remove ANGLE hack * Fix glcommon_check_extension for GLES2/legacy gl * Add renderer feature bit for texture swizzle masks * glcommon: Fixup internal formats for GLES2 Sized internal formats are not allowed in GLES2 * Fix emscripten compile errors * Update basis_universal * remove more dead code * revert irrelevant stage4 change * shut up UBSan * basisu: shut up some debug spam * Add normalmap sampling helper to util.glslh * basisu: add a gray-alpha mode * mkbasis.py: Abort if image dimansions aren't multiples of 4 * Add basic Basis Universal encoding documentation (WIP) * doc/basisu: Add paragraph about modes; minor tweaks * basisu: workarounds for GL texture size requirements * gles20: fix uncompressed sRGB formats * Partial workaround for missing swizzles in gles2 and webgl * remove invalid assertion * New renderer API to expose glDrawBuffers-like functionality * stagedraw: disable all color outputs for copy_depth pass required for WebGL compatibility * support GL_ANGLE_request_extension * emscripten: include *.basis in gfx package Also fix a potential problem when more than one .pkgdir is used to construct emscripten packages * Don't rely on emscripten runtime to enable webgl extensions
2020-08-15 13:51:12 +02:00
#include "texture_loader/texture_loader.h"
#include "global.h"
#include "renderer/api.h"
#include "video.h"
static bool texture_transfer(void *dst, void *src) {
return r_texture_transfer(dst, src);
}
ResourceHandler texture_res_handler = {
.type = RES_TEXTURE,
.typename = "texture",
.subdir = TEX_PATH_PREFIX,
.procs = {
Texturing overhaul: GPU compression, sRGB sampling, swizzles, etc. (#240) * WIP compressed textures, swizzles, sRGB sampling, ... * refactor texture type info & fix random bugs * fix preprocessing of sRGB textures * handle y-flipped basis textures * glcommon: better WebGL compat for compressed format detection * missed WEBGL_compressed_texture_pvrtc * implement compressed texture xcoding and uploading * Add basis_universal submodule * Reorganize texture loader code Clean up some code Isolate Basis Universal loader into a separate module * Add wrapper script for encoding .basis textures * basisu: honor custom metadata written by the mkbasis.py script * mkbasis.py: add --incredibly-slow and --dry-run * Move pixmap code from util/ to pixmap/ * Add an on-disk transcode cache for basis textures to speed up loads * Compress texture cache with zlib * Use readable format names for basisu cache filenames * basisu: mip bias test code * basisu: small caching cleanup * add TAISEI_BASISU_MIP_BIAS env variable * Improve OpenGL format matching heuristics * Document considerations for compressed format priority * Remove dead code * Enable two forgotten formats, BC3_RGBA and ATC_RGBA Also prefer BC7 over BC1/BC3 * Recognize GL_ANGLE_compressed_texture_etc for ETC2 textures * Default depth buffers to 24-bit; remove ANGLE hack * Fix glcommon_check_extension for GLES2/legacy gl * Add renderer feature bit for texture swizzle masks * glcommon: Fixup internal formats for GLES2 Sized internal formats are not allowed in GLES2 * Fix emscripten compile errors * Update basis_universal * remove more dead code * revert irrelevant stage4 change * shut up UBSan * basisu: shut up some debug spam * Add normalmap sampling helper to util.glslh * basisu: add a gray-alpha mode * mkbasis.py: Abort if image dimansions aren't multiples of 4 * Add basic Basis Universal encoding documentation (WIP) * doc/basisu: Add paragraph about modes; minor tweaks * basisu: workarounds for GL texture size requirements * gles20: fix uncompressed sRGB formats * Partial workaround for missing swizzles in gles2 and webgl * remove invalid assertion * New renderer API to expose glDrawBuffers-like functionality * stagedraw: disable all color outputs for copy_depth pass required for WebGL compatibility * support GL_ANGLE_request_extension * emscripten: include *.basis in gfx package Also fix a potential problem when more than one .pkgdir is used to construct emscripten packages * Don't rely on emscripten runtime to enable webgl extensions
2020-08-15 13:51:12 +02:00
.find = texture_loader_path,
.check = texture_loader_check_path,
.load = texture_loader_stage1,
.unload = texture_loader_unload,
.transfer = texture_transfer,
},
};
static struct draw_texture_state {
bool drawing;
bool texture_matrix_tainted;
} draw_texture_state;
void begin_draw_texture(FloatRect dest, FloatRect frag, Texture *tex) {
Texturing overhaul: GPU compression, sRGB sampling, swizzles, etc. (#240) * WIP compressed textures, swizzles, sRGB sampling, ... * refactor texture type info & fix random bugs * fix preprocessing of sRGB textures * handle y-flipped basis textures * glcommon: better WebGL compat for compressed format detection * missed WEBGL_compressed_texture_pvrtc * implement compressed texture xcoding and uploading * Add basis_universal submodule * Reorganize texture loader code Clean up some code Isolate Basis Universal loader into a separate module * Add wrapper script for encoding .basis textures * basisu: honor custom metadata written by the mkbasis.py script * mkbasis.py: add --incredibly-slow and --dry-run * Move pixmap code from util/ to pixmap/ * Add an on-disk transcode cache for basis textures to speed up loads * Compress texture cache with zlib * Use readable format names for basisu cache filenames * basisu: mip bias test code * basisu: small caching cleanup * add TAISEI_BASISU_MIP_BIAS env variable * Improve OpenGL format matching heuristics * Document considerations for compressed format priority * Remove dead code * Enable two forgotten formats, BC3_RGBA and ATC_RGBA Also prefer BC7 over BC1/BC3 * Recognize GL_ANGLE_compressed_texture_etc for ETC2 textures * Default depth buffers to 24-bit; remove ANGLE hack * Fix glcommon_check_extension for GLES2/legacy gl * Add renderer feature bit for texture swizzle masks * glcommon: Fixup internal formats for GLES2 Sized internal formats are not allowed in GLES2 * Fix emscripten compile errors * Update basis_universal * remove more dead code * revert irrelevant stage4 change * shut up UBSan * basisu: shut up some debug spam * Add normalmap sampling helper to util.glslh * basisu: add a gray-alpha mode * mkbasis.py: Abort if image dimansions aren't multiples of 4 * Add basic Basis Universal encoding documentation (WIP) * doc/basisu: Add paragraph about modes; minor tweaks * basisu: workarounds for GL texture size requirements * gles20: fix uncompressed sRGB formats * Partial workaround for missing swizzles in gles2 and webgl * remove invalid assertion * New renderer API to expose glDrawBuffers-like functionality * stagedraw: disable all color outputs for copy_depth pass required for WebGL compatibility * support GL_ANGLE_request_extension * emscripten: include *.basis in gfx package Also fix a potential problem when more than one .pkgdir is used to construct emscripten packages * Don't rely on emscripten runtime to enable webgl extensions
2020-08-15 13:51:12 +02:00
assume(!draw_texture_state.drawing);
draw_texture_state.drawing = true;
r_uniform_sampler("tex", tex);
r_mat_mv_push();
uint tw, th;
r_texture_get_size(tex, 0, &tw, &th);
float x = dest.x;
float y = dest.y;
float w = dest.w;
float h = dest.h;
float s = frag.w/tw;
float t = frag.h/th;
if(r_supports(RFEAT_TEXTURE_BOTTOMLEFT_ORIGIN)) {
// FIXME: please somehow abstract this shit away!
frag.y = th - frag.y - frag.h;
}
if(s != 1 || t != 1 || frag.x || frag.y) {
draw_texture_state.texture_matrix_tainted = true;
r_mat_tex_push();
r_mat_tex_scale(1.0/tw, 1.0/th, 1);
if(frag.x || frag.y) {
r_mat_tex_translate(frag.x, frag.y, 0);
}
if(s != 1 || t != 1) {
r_mat_tex_scale(frag.w, frag.h, 1);
}
}
if(x || y) {
r_mat_mv_translate(x, y, 0);
}
if(w != 1 || h != 1) {
r_mat_mv_scale(w, h, 1);
}
}
void end_draw_texture(void) {
assume(draw_texture_state.drawing);
2011-12-25 08:18:03 +01:00
if(draw_texture_state.texture_matrix_tainted) {
draw_texture_state.texture_matrix_tainted = false;
r_mat_tex_pop();
}
r_mat_mv_pop();
draw_texture_state.drawing = false;
}
void fill_viewport(float xoff, float yoff, float ratio, const char *name) {
fill_viewport_p(xoff, yoff, ratio, 1, 0, res_texture(name));
}
void fill_viewport_p(float xoff, float yoff, float ratio, float aspect, float angle, Texture *tex) {
r_uniform_sampler("tex", tex);
float rw, rh;
if(ratio == 0) {
rw = aspect;
rh = 1;
} else {
rw = ratio * aspect;
rh = ratio;
}
if(r_supports(RFEAT_TEXTURE_BOTTOMLEFT_ORIGIN)) {
// FIXME: we should somehow account for this globally if possible...
yoff *= -1;
yoff += (1 - ratio);
}
bool texture_matrix_tainted = false;
if(xoff || yoff || rw != 1 || rh != 1 || angle) {
texture_matrix_tainted = true;
r_mat_tex_push();
if(xoff || yoff) {
r_mat_tex_translate(xoff, yoff, 0);
}
if(rw != 1 || rh != 1) {
r_mat_tex_scale(rw, rh, 1);
}
if(angle) {
r_mat_tex_translate(0.5, 0.5, 0);
r_mat_tex_rotate(angle * DEG2RAD, 0, 0, 1);
r_mat_tex_translate(-0.5, -0.5, 0);
}
}
r_mat_mv_push();
r_mat_mv_translate(VIEWPORT_W*0.5, VIEWPORT_H*0.5, 0);
r_mat_mv_scale(VIEWPORT_W, VIEWPORT_H, 1);
r_draw_quad();
r_mat_mv_pop();
if(texture_matrix_tainted) {
r_mat_tex_pop();
}
}
void fill_screen(const char *name) {
fill_screen_p(res_texture(name));
}
void fill_screen_p(Texture *tex) {
uint tw, th;
r_texture_get_size(tex, 0, &tw, &th);
begin_draw_texture((FloatRect){ SCREEN_W*0.5, SCREEN_H*0.5, SCREEN_W, SCREEN_H }, (FloatRect){ 0, 0, tw, th }, tex);
r_draw_quad();
end_draw_texture();
}
2017-03-25 09:22:45 +01:00
// draws a thin, w-width rectangle from point A to point B with a texture that
// moves along the line.
2017-03-25 09:22:45 +01:00
//
void loop_tex_line_p(cmplx a, cmplx b, float w, float t, Texture *texture) {
cmplx d = b-a;
cmplx c = (b+a)/2;
2017-03-25 09:22:45 +01:00
r_mat_mv_push();
2023-09-20 04:14:15 +02:00
r_mat_mv_translate(re(c), im(c), 0);
r_mat_mv_rotate(carg(d), 0, 0, 1);
r_mat_mv_scale(cabs(d), w, 1);
2017-03-25 09:22:45 +01:00
r_mat_tex_push();
r_mat_tex_translate(t, 0, 0);
2017-03-25 09:22:45 +01:00
r_uniform_sampler("tex", texture);
r_draw_quad();
2017-03-25 09:22:45 +01:00
r_mat_tex_pop();
r_mat_mv_pop();
2017-03-25 09:22:45 +01:00
}
2017-03-25 15:23:37 +01:00
void loop_tex_line(cmplx a, cmplx b, float w, float t, const char *texture) {
loop_tex_line_p(a, b, w, t, res_texture(texture));
2017-03-25 15:23:37 +01:00
}