feat(render3d): gpu.ludic - the seam for a second graphics API, and what the GPU can do
Render state (depth, blending, culling, colour writes, alpha-to-coverage, depth bias, scissor) and uniforms go through gpu_* / u_* and nowhere else; OpenGL state is cached and only changes reach the driver. Frames are bit-identical to before at the fixed viewpoints. R3D_GFX=gl|vk or gpu_request chooses a backend, falling back to OpenGL with a reason. gpu_caps_probe() asks Vulkan, on Windows, for the 1.3 floor, ray tracing, mesh shaders, the NVIDIA RTX generation, Reflex and HDR colour spaces, for a game's settings to grey out what a machine cannot use; R3D_CAPS pretends to be a given card for tests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
208cad7ca1
commit
54eeef5f8d
17 changed files with 652 additions and 312 deletions
|
|
@ -66,14 +66,14 @@ function ac_prog_new(vs: string, fs: string, defs: string) -> AcProg {
|
|||
let a = new AcProg
|
||||
a.prog = r3d_program(vs, fs, defs)
|
||||
let p = a.prog
|
||||
a.l_model = gl_uniform(p, "u_model"); a.l_skin = gl_uniform(p, "u_skinned"); a.l_lvp = gl_uniform(p, "u_light_vp")
|
||||
a.l_bones = gl_uniform(p, "u_bones[0]"); if a.l_bones < 0 { a.l_bones = gl_uniform(p, "u_bones") }
|
||||
a.l_tint = gl_uniform(p, "u_tint"); a.l_rough = gl_uniform(p, "u_rough_scale"); a.l_emis = gl_uniform(p, "u_emissive")
|
||||
a.l_view = gl_uniform(p, "u_view"); a.l_proj = gl_uniform(p, "u_proj"); a.l_mh = gl_uniform(p, "u_model_h")
|
||||
a.l_out = gl_uniform(p, "u_outline"); a.l_ocol = gl_uniform(p, "u_outline_col")
|
||||
a.l_model = gpu_uniform(p, "u_model"); a.l_skin = gpu_uniform(p, "u_skinned"); a.l_lvp = gpu_uniform(p, "u_light_vp")
|
||||
a.l_bones = gpu_uniform(p, "u_bones[0]"); if a.l_bones < 0 { a.l_bones = gpu_uniform(p, "u_bones") }
|
||||
a.l_tint = gpu_uniform(p, "u_tint"); a.l_rough = gpu_uniform(p, "u_rough_scale"); a.l_emis = gpu_uniform(p, "u_emissive")
|
||||
a.l_view = gpu_uniform(p, "u_view"); a.l_proj = gpu_uniform(p, "u_proj"); a.l_mh = gpu_uniform(p, "u_model_h")
|
||||
a.l_out = gpu_uniform(p, "u_outline"); a.l_ocol = gpu_uniform(p, "u_outline_col")
|
||||
# the samplers never move: units 0, 1, 2
|
||||
gl_use_program(p)
|
||||
gl_uniform1i(gl_uniform(p, "u_diff"), 0); gl_uniform1i(gl_uniform(p, "u_nrm"), 1); gl_uniform1i(gl_uniform(p, "u_arm"), 2)
|
||||
u_i(gpu_uniform(p, "u_diff"), 0); u_i(gpu_uniform(p, "u_nrm"), 1); u_i(gpu_uniform(p, "u_arm"), 2)
|
||||
return a
|
||||
}
|
||||
function actor_init() -> void {
|
||||
|
|
@ -161,14 +161,14 @@ function actor_draw_one(a: Actor, ap: AcProg, shadow: bool) -> void {
|
|||
gl_use_program(p)
|
||||
u_mat4(ap.l_model, a.mat)
|
||||
var skinned = F_ZERO
|
||||
if a.skin != null { skinned = F_ONE; gl_uniform_matrix4fv(ap.l_bones, a.skin.n_joints, 0, a.skin.bones) }
|
||||
else if a.model.skin != null { skinned = F_ONE; gl_uniform_matrix4fv(ap.l_bones, a.model.skin.n_joints, 0, a.model.skin.bones) }
|
||||
if a.skin != null { skinned = F_ONE; u_mat4n(ap.l_bones, a.skin.n_joints, a.skin.bones) }
|
||||
else if a.model.skin != null { skinned = F_ONE; u_mat4n(ap.l_bones, a.model.skin.n_joints, a.model.skin.bones) }
|
||||
u_f(ap.l_skin, skinned)
|
||||
if not shadow {
|
||||
u_f(ap.l_emis, a.emissive)
|
||||
u_f(ap.l_rough, a.rough)
|
||||
}
|
||||
gl_disable(GL_CULL_FACE)
|
||||
gpu_cull(false)
|
||||
let model = a.model
|
||||
for i in 0 .. len(model.prims) {
|
||||
let pr = model.prims[i]
|
||||
|
|
@ -248,7 +248,7 @@ function actor_draw() -> void {
|
|||
actor_draw_one(a, ap, false)
|
||||
}
|
||||
actor_draw_outlines()
|
||||
gl_enable(GL_CULL_FACE)
|
||||
gpu_cull(true)
|
||||
}
|
||||
# The rim around a highlighted actor: the model again, its vertices pushed out along their
|
||||
# normals (skin.vert, OUTLINE) and its front faces culled, so only the far side of the
|
||||
|
|
@ -258,8 +258,8 @@ function actor_draw_outlines() -> void {
|
|||
var any = ac_oq_n > 0
|
||||
for i in 0 .. len(ac_actors) { if ac_actors[i].outline != 0 and ac_visible(ac_actors[i], false) { any = true; break } }
|
||||
if not any { return }
|
||||
gl_enable(GL_CULL_FACE)
|
||||
gl_cull_face(GL_FRONT)
|
||||
gpu_cull(true)
|
||||
gpu_cull_face(GL_FRONT)
|
||||
for i in 0 .. len(ac_actors) {
|
||||
let a = ac_actors[i]
|
||||
if a.outline == 0 or not ac_visible(a, false) { continue }
|
||||
|
|
@ -284,13 +284,13 @@ function actor_draw_outlines() -> void {
|
|||
for k in 0 .. len(q.model.prims) { mesh_draw(q.model.prims[k].mesh) }
|
||||
}
|
||||
ac_oq_closed = true
|
||||
gl_cull_face(GL_BACK)
|
||||
gpu_cull_face(GL_BACK)
|
||||
}
|
||||
function actor_draw_outline_one(a: Actor, ap: AcProg) -> void {
|
||||
u_mat4(ap.l_model, a.mat)
|
||||
var skinned = F_ZERO
|
||||
if a.skin != null { skinned = F_ONE; gl_uniform_matrix4fv(ap.l_bones, a.skin.n_joints, 0, a.skin.bones) }
|
||||
else if a.model.skin != null { skinned = F_ONE; gl_uniform_matrix4fv(ap.l_bones, a.model.skin.n_joints, 0, a.model.skin.bones) }
|
||||
if a.skin != null { skinned = F_ONE; u_mat4n(ap.l_bones, a.skin.n_joints, a.skin.bones) }
|
||||
else if a.model.skin != null { skinned = F_ONE; u_mat4n(ap.l_bones, a.model.skin.n_joints, a.model.skin.bones) }
|
||||
u_f(ap.l_skin, skinned)
|
||||
let model = a.model
|
||||
for i in 0 .. len(model.prims) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue