refactor(render3d): textures behind gpu.ludic, their sampler state recorded

Texture creation, 2D and array uploads, pixel packing, filters, wraps, comparison, border,
anisotropy, mipmaps, texture units, read-backs and freeing now go through gpu_tex_* and
gpu_bind_sampler, and no other file names them. Each call is the one GL call it replaces,
in the same order, so OpenGL renders bit-identically at the fixed viewpoints and the game's
self-tests report what they did before.

What those calls say about a texture - size, format, layers, min and mag filter, wraps,
comparison, mipmaps, anisotropy - is recorded per handle as it is set: a backend with
immutable images and separate sampler objects creates both from exactly that.
r3d_bind_tex takes a texture kind (GPU_TEX2D / GPU_TEX2D_ARRAY) instead of a GL target.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-15 10:29:28 +03:00
parent 43c379aa0f
commit 4d3479d431
10 changed files with 201 additions and 113 deletions

View file

@ -177,10 +177,10 @@ function actor_draw_one(a: Actor, ap: AcProg, shadow: bool) -> void {
if a.ptint != null and a.ptint[i * 4] != 0 { u_f3(ap.l_tint, a.ptint[i * 4 + 1], a.ptint[i * 4 + 2], a.ptint[i * 4 + 3]) }
else { u_v3(ap.l_tint, a.tint) }
}
gl_active_texture(GL_TEXTURE0); gl_bind_texture(GL_TEXTURE_2D, pr.diff)
gpu_tex_unit(0); gpu_tex_bind(GPU_TEX2D, pr.diff)
if not shadow {
gl_active_texture(GL_TEXTURE0 + 1); gl_bind_texture(GL_TEXTURE_2D, pr.nrm)
gl_active_texture(GL_TEXTURE0 + 2); gl_bind_texture(GL_TEXTURE_2D, pr.arm)
gpu_tex_unit(1); gpu_tex_bind(GPU_TEX2D, pr.nrm)
gpu_tex_unit(2); gpu_tex_bind(GPU_TEX2D, pr.arm)
}
mesh_draw(pr.mesh)
}
@ -296,7 +296,7 @@ function actor_draw_outline_one(a: Actor, ap: AcProg) -> void {
for i in 0 .. len(model.prims) {
let pr = model.prims[i]
if a.hide != null and a.hide[i] != 0 { continue }
if a.cutout { gl_active_texture(GL_TEXTURE0); gl_bind_texture(GL_TEXTURE_2D, pr.diff) }
if a.cutout { gpu_tex_unit(0); gpu_tex_bind(GPU_TEX2D, pr.diff) }
mesh_draw(pr.mesh)
}
}