refactor(render3d): vertex data and draws behind gpu.ludic
Every vertex array, vertex and index buffer, attribute pointer, instance divisor, stream upload and draw call now goes through gpu_mesh_* / gpu_buffer_* / gpu_draw_*, and no other file in the package names them. A Mesh records its layout as it is built - which buffer feeds which attribute at what stride and offset, per vertex or per instance - so a backend that bakes vertex input into a pipeline can read it back. On OpenGL each call is the GL it replaces, in the same order: the five fixed viewpoints render bit-identically and the game's self-tests report exactly what they did before. scatter_attach takes the mesh rather than its vertex array; a mesh now frees every vertex buffer it owns (glTF meshes used to keep all but the first); the two helpers nothing called, mesh_grid_patches and mesh_instance_buffer, are gone. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
3fb1b7cd87
commit
43c379aa0f
8 changed files with 271 additions and 267 deletions
|
|
@ -68,14 +68,20 @@ property Layer {
|
|||
lvl: words # scratch: the level chosen per gathered instance
|
||||
}
|
||||
|
||||
# the procedural models' one layout: position, normal, uv, interleaved at 32 bytes
|
||||
function sc_model_layout(m: Mesh) -> void {
|
||||
gpu_mesh_attr(m, 0, 3, GPU_F32, 32, 0, false)
|
||||
gpu_mesh_attr(m, 1, 3, GPU_F32, 32, 12, false)
|
||||
gpu_mesh_attr(m, 2, 2, GPU_F32, 32, 24, false)
|
||||
}
|
||||
|
||||
# Two crossed unit quads (x in [-0.5, 0.5], y in [0, 1]), attribute 0 = pos,
|
||||
# 1 = the quad's facing normal, 2 = uv. Scaled per layer to the atlas card size.
|
||||
function model_cross_card() -> Model {
|
||||
let model = new Model
|
||||
model.prims = new []Prim
|
||||
let pr = new Prim
|
||||
let m = new Mesh
|
||||
m.vao = gl_vao()
|
||||
let m = gpu_mesh_new()
|
||||
let v = gl_floats(8 * 8)
|
||||
var k = 0
|
||||
for q in 0 .. 2 {
|
||||
|
|
@ -89,22 +95,16 @@ function model_cross_card() -> Model {
|
|||
k += 8
|
||||
}
|
||||
}
|
||||
m.vbo = gl_buffer()
|
||||
gl_bind_buffer(GL_ARRAY_BUFFER, m.vbo)
|
||||
gl_buffer_data(GL_ARRAY_BUFFER, gl_bytes_of(64), v, GL_STATIC_DRAW)
|
||||
gl_enable_vertex_attrib_array(0); gl_vertex_attrib_pointer(0, 3, GL_FLOAT, 0, 32, null)
|
||||
gl_enable_vertex_attrib_array(1); gl_vertex_attrib_pointer(1, 3, GL_FLOAT, 0, 32, gl_ptr(null, 12))
|
||||
gl_enable_vertex_attrib_array(2); gl_vertex_attrib_pointer(2, 2, GL_FLOAT, 0, 32, gl_ptr(null, 24))
|
||||
gpu_mesh_vertices(m, v, gl_bytes_of(64), GPU_STATIC)
|
||||
sc_model_layout(m)
|
||||
free(v)
|
||||
let idx = words(12)
|
||||
idx[0] = 0; idx[1] = 1; idx[2] = 2; idx[3] = 0; idx[4] = 2; idx[5] = 3
|
||||
idx[6] = 4; idx[7] = 5; idx[8] = 6; idx[9] = 4; idx[10] = 6; idx[11] = 7
|
||||
m.ebo = gl_buffer()
|
||||
gl_bind_buffer(GL_ELEMENT_ARRAY_BUFFER, m.ebo)
|
||||
gl_buffer_data(GL_ELEMENT_ARRAY_BUFFER, 48, idx, GL_STATIC_DRAW)
|
||||
gpu_mesh_indices(m, idx, 48, 4)
|
||||
free(idx)
|
||||
m.count = 12
|
||||
gl_bind_vertex_array(0)
|
||||
gpu_mesh_done(m)
|
||||
pr.mesh = m
|
||||
if gltf_white == 0 { gltf_white = tex_solid(200, 200, 200, 255); gltf_flat = tex_solid(128, 128, 255, 255) }
|
||||
pr.diff = gltf_white; pr.nrm = gltf_flat; pr.arm = gltf_white
|
||||
|
|
@ -127,8 +127,7 @@ function model_lupine() -> Model {
|
|||
let model = new Model
|
||||
model.prims = new []Prim
|
||||
let pr = new Prim
|
||||
let m = new Mesh
|
||||
m.vao = gl_vao()
|
||||
let m = gpu_mesh_new()
|
||||
# quads: stem x2 + tiers 12 x 2 + 3 leaves = 29 quads
|
||||
let nq = 29
|
||||
let v = gl_floats(nq * 4 * 8)
|
||||
|
|
@ -172,19 +171,13 @@ function model_lupine() -> Model {
|
|||
idx[qi] = b; idx[qi + 1] = b + 1; idx[qi + 2] = b + 2; idx[qi + 3] = b; idx[qi + 4] = b + 2; idx[qi + 5] = b + 3
|
||||
qi += 6
|
||||
}
|
||||
m.vbo = gl_buffer()
|
||||
gl_bind_buffer(GL_ARRAY_BUFFER, m.vbo)
|
||||
gl_buffer_data(GL_ARRAY_BUFFER, gl_bytes_of(nq * 4 * 8), v, GL_STATIC_DRAW)
|
||||
gl_enable_vertex_attrib_array(0); gl_vertex_attrib_pointer(0, 3, GL_FLOAT, 0, 32, null)
|
||||
gl_enable_vertex_attrib_array(1); gl_vertex_attrib_pointer(1, 3, GL_FLOAT, 0, 32, gl_ptr(null, 12))
|
||||
gl_enable_vertex_attrib_array(2); gl_vertex_attrib_pointer(2, 2, GL_FLOAT, 0, 32, gl_ptr(null, 24))
|
||||
gpu_mesh_vertices(m, v, gl_bytes_of(nq * 4 * 8), GPU_STATIC)
|
||||
sc_model_layout(m)
|
||||
free(v)
|
||||
m.ebo = gl_buffer()
|
||||
gl_bind_buffer(GL_ELEMENT_ARRAY_BUFFER, m.ebo)
|
||||
gl_buffer_data(GL_ELEMENT_ARRAY_BUFFER, nq * 6 * 4, idx, GL_STATIC_DRAW)
|
||||
gpu_mesh_indices(m, idx, nq * 6 * 4, 4)
|
||||
free(idx)
|
||||
m.count = nq * 6
|
||||
gl_bind_vertex_array(0)
|
||||
gpu_mesh_done(m)
|
||||
pr.mesh = m
|
||||
if gltf_white == 0 { gltf_white = tex_solid(200, 200, 200, 255); gltf_flat = tex_solid(128, 128, 255, 255) }
|
||||
pr.diff = gltf_white; pr.nrm = gltf_flat; pr.arm = gltf_white
|
||||
|
|
@ -199,8 +192,7 @@ function model_lupine_dense() -> Model {
|
|||
let model = new Model
|
||||
model.prims = new []Prim
|
||||
let pr = new Prim
|
||||
let m = new Mesh
|
||||
m.vao = gl_vao()
|
||||
let m = gpu_mesh_new()
|
||||
let nfl = 220
|
||||
let nq = 2 + nfl + 5
|
||||
let v = gl_floats(nq * 4 * 8)
|
||||
|
|
@ -252,19 +244,13 @@ function model_lupine_dense() -> Model {
|
|||
idx[qi] = b; idx[qi + 1] = b + 1; idx[qi + 2] = b + 2; idx[qi + 3] = b; idx[qi + 4] = b + 2; idx[qi + 5] = b + 3
|
||||
qi += 6
|
||||
}
|
||||
m.vbo = gl_buffer()
|
||||
gl_bind_buffer(GL_ARRAY_BUFFER, m.vbo)
|
||||
gl_buffer_data(GL_ARRAY_BUFFER, gl_bytes_of(nq * 4 * 8), v, GL_STATIC_DRAW)
|
||||
gl_enable_vertex_attrib_array(0); gl_vertex_attrib_pointer(0, 3, GL_FLOAT, 0, 32, null)
|
||||
gl_enable_vertex_attrib_array(1); gl_vertex_attrib_pointer(1, 3, GL_FLOAT, 0, 32, gl_ptr(null, 12))
|
||||
gl_enable_vertex_attrib_array(2); gl_vertex_attrib_pointer(2, 2, GL_FLOAT, 0, 32, gl_ptr(null, 24))
|
||||
gpu_mesh_vertices(m, v, gl_bytes_of(nq * 4 * 8), GPU_STATIC)
|
||||
sc_model_layout(m)
|
||||
free(v)
|
||||
m.ebo = gl_buffer()
|
||||
gl_bind_buffer(GL_ELEMENT_ARRAY_BUFFER, m.ebo)
|
||||
gl_buffer_data(GL_ELEMENT_ARRAY_BUFFER, nq * 6 * 4, idx, GL_STATIC_DRAW)
|
||||
gpu_mesh_indices(m, idx, nq * 6 * 4, 4)
|
||||
free(idx)
|
||||
m.count = nq * 6
|
||||
gl_bind_vertex_array(0)
|
||||
gpu_mesh_done(m)
|
||||
pr.mesh = m
|
||||
if gltf_white == 0 { gltf_white = tex_solid(200, 200, 200, 255); gltf_flat = tex_solid(128, 128, 255, 255) }
|
||||
pr.diff = gltf_white; pr.nrm = gltf_flat; pr.arm = gltf_white
|
||||
|
|
@ -278,8 +264,7 @@ function model_blade() -> Model {
|
|||
let model = new Model
|
||||
model.prims = new []Prim
|
||||
let pr = new Prim
|
||||
let m = new Mesh
|
||||
m.vao = gl_vao()
|
||||
let m = gpu_mesh_new()
|
||||
let rows = 5
|
||||
let v = gl_floats(rows * 2 * 8)
|
||||
var k = 0
|
||||
|
|
@ -298,12 +283,8 @@ function model_blade() -> Model {
|
|||
k += 8
|
||||
}
|
||||
}
|
||||
m.vbo = gl_buffer()
|
||||
gl_bind_buffer(GL_ARRAY_BUFFER, m.vbo)
|
||||
gl_buffer_data(GL_ARRAY_BUFFER, gl_bytes_of(rows * 2 * 8), v, GL_STATIC_DRAW)
|
||||
gl_enable_vertex_attrib_array(0); gl_vertex_attrib_pointer(0, 3, GL_FLOAT, 0, 32, null)
|
||||
gl_enable_vertex_attrib_array(1); gl_vertex_attrib_pointer(1, 3, GL_FLOAT, 0, 32, gl_ptr(null, 12))
|
||||
gl_enable_vertex_attrib_array(2); gl_vertex_attrib_pointer(2, 2, GL_FLOAT, 0, 32, gl_ptr(null, 24))
|
||||
gpu_mesh_vertices(m, v, gl_bytes_of(rows * 2 * 8), GPU_STATIC)
|
||||
sc_model_layout(m)
|
||||
free(v)
|
||||
let ni = (rows - 1) * 6
|
||||
let idx = words(ni)
|
||||
|
|
@ -314,12 +295,10 @@ function model_blade() -> Model {
|
|||
idx[k + 3] = a + 1; idx[k + 4] = a + 3; idx[k + 5] = a + 2
|
||||
k += 6
|
||||
}
|
||||
m.ebo = gl_buffer()
|
||||
gl_bind_buffer(GL_ELEMENT_ARRAY_BUFFER, m.ebo)
|
||||
gl_buffer_data(GL_ELEMENT_ARRAY_BUFFER, ni * 4, idx, GL_STATIC_DRAW)
|
||||
gpu_mesh_indices(m, idx, ni * 4, 4)
|
||||
free(idx)
|
||||
m.count = ni
|
||||
gl_bind_vertex_array(0)
|
||||
gpu_mesh_done(m)
|
||||
pr.mesh = m
|
||||
if gltf_white == 0 { gltf_white = tex_solid(200, 200, 200, 255); gltf_flat = tex_solid(128, 128, 255, 255) }
|
||||
pr.diff = gltf_white; pr.nrm = gltf_flat; pr.arm = gltf_white
|
||||
|
|
@ -389,24 +368,18 @@ function scatter_init() -> void {
|
|||
let one = gl_floats(INST_FLOATS)
|
||||
for i in 0 .. INST_FLOATS { gl_put_bits(one, i, F_ZERO) }
|
||||
gl_put_bits(one, 3, F_ONE); gl_put_bits(one, 5, F_ONE)
|
||||
sc_ident_buf = gl_buffer()
|
||||
gl_bind_buffer(GL_ARRAY_BUFFER, sc_ident_buf)
|
||||
gl_buffer_data(GL_ARRAY_BUFFER, INST_FLOATS * 4, one, GL_STATIC_DRAW)
|
||||
sc_ident_buf = gpu_buffer_new()
|
||||
gpu_buffer_upload(sc_ident_buf, INST_FLOATS * 4, one, GPU_STATIC)
|
||||
free(one)
|
||||
sc_layers = new []Layer
|
||||
}
|
||||
|
||||
# attach a GL instance buffer to a VAO at attributes 3, 4
|
||||
function scatter_attach(vao: int, buf: int) -> void {
|
||||
gl_bind_vertex_array(vao)
|
||||
gl_bind_buffer(GL_ARRAY_BUFFER, buf)
|
||||
gl_enable_vertex_attrib_array(3)
|
||||
gl_vertex_attrib_pointer(3, 4, GL_FLOAT, 0, INST_FLOATS * 4, null)
|
||||
gl_vertex_attrib_divisor(3, 1)
|
||||
gl_enable_vertex_attrib_array(4)
|
||||
gl_vertex_attrib_pointer(4, 4, GL_FLOAT, 0, INST_FLOATS * 4, gl_ptr(null, 16))
|
||||
gl_vertex_attrib_divisor(4, 1)
|
||||
gl_bind_vertex_array(0)
|
||||
# feed a mesh its instances from `buf`: attribute 3 = position + scale, 4 = sin, cos, seed, wind
|
||||
function scatter_attach(m: Mesh, buf: int) -> void {
|
||||
gpu_mesh_bind_instances(m, buf)
|
||||
gpu_mesh_attr_inst(m, 3, 4, GPU_F32, INST_FLOATS * 4, 0)
|
||||
gpu_mesh_attr_inst(m, 4, 4, GPU_F32, INST_FLOATS * 4, 16)
|
||||
gpu_mesh_done(m)
|
||||
}
|
||||
|
||||
function layer_new(model: Model, cap: int, foliage: bool, wind: int, near: int, cull: int) -> Layer {
|
||||
|
|
@ -421,11 +394,11 @@ function layer_new(model: Model, cap: int, foliage: bool, wind: int, near: int,
|
|||
l.inst = words(cap * INST_FLOATS)
|
||||
l.scratch = words(cap * INST_FLOATS)
|
||||
l.last_cam = v3_new(fi(100000), F_ZERO, F_ZERO)
|
||||
l.buf = gl_buffer()
|
||||
l.imp_buf = gl_buffer()
|
||||
l.sh_buf = gl_buffer()
|
||||
l.buf = gpu_buffer_new()
|
||||
l.imp_buf = gpu_buffer_new()
|
||||
l.sh_buf = gpu_buffer_new()
|
||||
l.rough = F_ONE
|
||||
for i in 0 .. len(model.prims) { scatter_attach(model.prims[i].mesh.vao, l.buf) }
|
||||
for i in 0 .. len(model.prims) { scatter_attach(model.prims[i].mesh, l.buf) }
|
||||
push(sc_layers, l)
|
||||
return l
|
||||
}
|
||||
|
|
@ -469,7 +442,7 @@ function impostor_bake(model: Model, tiles: int, tw: int, th: int) -> Impostor {
|
|||
gpu_cull(false)
|
||||
gpu_blend(false)
|
||||
# the model's prims temporarily take the identity instance
|
||||
for i in 0 .. len(model.prims) { scatter_attach(model.prims[i].mesh.vao, sc_ident_buf) }
|
||||
for i in 0 .. len(model.prims) { scatter_attach(model.prims[i].mesh, sc_ident_buf) }
|
||||
let view = m4_new(); let proj = m4_new()
|
||||
let eye = words(3); let at = words(3); let up = v3_new(F_ZERO, F_ONE, F_ZERO)
|
||||
let cy = f_add(model.ymin, f_mul(model.height, F_HALF))
|
||||
|
|
@ -521,9 +494,9 @@ function layer_set_lods(l: Layer, models: []Model, dists: words) -> void {
|
|||
l.lod_dist = words(l.n_lods); l.lod_card = words(l.n_lods); l.lod_buf = words(l.n_lods); l.n_lod = words(l.n_lods)
|
||||
for k in 0 .. l.n_lods {
|
||||
l.lod_dist[k] = dists[k]; l.lod_card[k] = 0; l.n_lod[k] = 0
|
||||
l.lod_buf[k] = gl_buffer()
|
||||
l.lod_buf[k] = gpu_buffer_new()
|
||||
let m = models[k]
|
||||
for i in 0 .. len(m.prims) { scatter_attach(m.prims[i].mesh.vao, l.lod_buf[k]) }
|
||||
for i in 0 .. len(m.prims) { scatter_attach(m.prims[i].mesh, l.lod_buf[k]) }
|
||||
}
|
||||
l.model = models[0]
|
||||
l.near = dists[l.n_lods - 1]
|
||||
|
|
@ -534,7 +507,7 @@ function layer_lod_card(l: Layer, k: int) -> void { l.lod_card[k] = 1 }
|
|||
|
||||
function layer_set_impostor(l: Layer, im: Impostor) -> void {
|
||||
l.imp = im
|
||||
scatter_attach(sc_card.vao, l.imp_buf)
|
||||
scatter_attach(sc_card, l.imp_buf)
|
||||
}
|
||||
|
||||
# ---- per frame -----------------------------------------------------------------------
|
||||
|
|
@ -596,8 +569,7 @@ function layer_grid_build(l: Layer, cell: int) -> void {
|
|||
free(cellof); free(fill)
|
||||
if l.vis == null { l.vis = words(l.cap * INST_FLOATS) }
|
||||
l.n_sh = l.count
|
||||
gl_bind_buffer(GL_ARRAY_BUFFER, l.sh_buf)
|
||||
gl_buffer_data(GL_ARRAY_BUFFER, l.count * INST_FLOATS * 4, l.inst, GL_STATIC_DRAW)
|
||||
gpu_buffer_upload(l.sh_buf, l.count * INST_FLOATS * 4, l.inst, GPU_STATIC)
|
||||
}
|
||||
|
||||
# gather the instances of the cells the camera can see (and that are within cull)
|
||||
|
|
@ -671,21 +643,19 @@ function layer_partition_lods(l: Layer, src: words, total: int) -> void {
|
|||
for k in 0 .. n {
|
||||
l.n_lod[k] = counts[k]
|
||||
if counts[k] > 0 {
|
||||
gl_bind_buffer(GL_ARRAY_BUFFER, l.lod_buf[k])
|
||||
gl_buffer_data(GL_ARRAY_BUFFER, counts[k] * INST_FLOATS * 4, mem_off(tmp, start[k] * INST_FLOATS * 4), GL_DYNAMIC_DRAW)
|
||||
gpu_buffer_upload(l.lod_buf[k], counts[k] * INST_FLOATS * 4, mem_off(tmp, start[k] * INST_FLOATS * 4), GPU_DYNAMIC)
|
||||
}
|
||||
}
|
||||
l.n_near = counts[0]
|
||||
l.n_far = counts[n]
|
||||
if sc_dbg_lod and total > 1000 { print(`lod partition: total {total} dropped {counts[n + 1]} far {counts[n]} l0 {counts[0]} l1 {counts[1]} l2 {counts[2]} l3 {counts[3]} dist0 {f_fx(l.lod_dist[0])} dist3 {f_fx(l.lod_dist[n - 1])} cull {f_fx(l.cull)} cam {f_fx(cam_pos[0])} {f_fx(cam_pos[2])} first {f_fx(src[0])} {f_fx(src[2])}`) }
|
||||
if l.n_far > 0 {
|
||||
gl_bind_buffer(GL_ARRAY_BUFFER, l.imp_buf)
|
||||
gl_buffer_data(GL_ARRAY_BUFFER, l.n_far * INST_FLOATS * 4, mem_off(tmp, start[n] * INST_FLOATS * 4), GL_DYNAMIC_DRAW)
|
||||
gpu_buffer_upload(l.imp_buf, l.n_far * INST_FLOATS * 4, mem_off(tmp, start[n] * INST_FLOATS * 4), GPU_DYNAMIC)
|
||||
}
|
||||
# casters: the whole (gathered) set from the shadow buffer, unless the impostor casts
|
||||
if l.gcell == 0 {
|
||||
l.n_sh = total
|
||||
if total > 0 { gl_bind_buffer(GL_ARRAY_BUFFER, l.sh_buf); gl_buffer_data(GL_ARRAY_BUFFER, total * INST_FLOATS * 4, src, GL_DYNAMIC_DRAW) }
|
||||
if total > 0 { gpu_buffer_upload(l.sh_buf, total * INST_FLOATS * 4, src, GPU_DYNAMIC) }
|
||||
}
|
||||
free(counts); free(start); free(fill)
|
||||
}
|
||||
|
|
@ -702,8 +672,7 @@ function layer_update(l: Layer) -> void {
|
|||
# per-instance loop — one upload, and the same buffer casts its shadows.
|
||||
if l.streamed and l.imp == null and l.near == 0 and l.n_lods <= 1 {
|
||||
l.n_near = l.count; l.n_far = 0; l.n_sh = l.count
|
||||
gl_bind_buffer(GL_ARRAY_BUFFER, l.buf)
|
||||
gl_buffer_data(GL_ARRAY_BUFFER, l.count * INST_FLOATS * 4, l.inst, GL_DYNAMIC_DRAW)
|
||||
gpu_buffer_upload(l.buf, l.count * INST_FLOATS * 4, l.inst, GPU_DYNAMIC)
|
||||
prof_layer_add(gl_now_us() - t_lu, l.count * INST_FLOATS * 4)
|
||||
return
|
||||
}
|
||||
|
|
@ -753,15 +722,12 @@ function layer_update(l: Layer) -> void {
|
|||
if l.gcell == 0 {
|
||||
l.n_sh = l.count
|
||||
if l.count > 0 {
|
||||
gl_bind_buffer(GL_ARRAY_BUFFER, l.sh_buf)
|
||||
gl_buffer_data(GL_ARRAY_BUFFER, l.count * INST_FLOATS * 4, l.inst, GL_DYNAMIC_DRAW)
|
||||
gpu_buffer_upload(l.sh_buf, l.count * INST_FLOATS * 4, l.inst, GPU_DYNAMIC)
|
||||
}
|
||||
}
|
||||
gl_bind_buffer(GL_ARRAY_BUFFER, l.buf)
|
||||
gl_buffer_data(GL_ARRAY_BUFFER, nn * INST_FLOATS * 4, tmp, GL_DYNAMIC_DRAW)
|
||||
gpu_buffer_upload(l.buf, nn * INST_FLOATS * 4, tmp, GPU_DYNAMIC)
|
||||
if nf > 0 {
|
||||
gl_bind_buffer(GL_ARRAY_BUFFER, l.imp_buf)
|
||||
gl_buffer_data(GL_ARRAY_BUFFER, nf * INST_FLOATS * 4, mem_off(tmp, (far_off - nf * INST_FLOATS) * 4), GL_DYNAMIC_DRAW)
|
||||
gpu_buffer_upload(l.imp_buf, nf * INST_FLOATS * 4, mem_off(tmp, (far_off - nf * INST_FLOATS) * 4), GPU_DYNAMIC)
|
||||
}
|
||||
prof_layer_add(gl_now_us() - t_lu, (nn + nf + l.n_sh) * INST_FLOATS * 4)
|
||||
}
|
||||
|
|
@ -857,7 +823,7 @@ function layer_draw_model(l: Layer, model: Model, vb: int, cnt: int, card: bool,
|
|||
gpu_cull(false)
|
||||
for i in 0 .. len(model.prims) {
|
||||
let pr = model.prims[i]
|
||||
scatter_attach(pr.mesh.vao, vb)
|
||||
scatter_attach(pr.mesh, vb)
|
||||
if not card {
|
||||
r3d_bind_2d(p, "u_diff", 0, pr.diff)
|
||||
if not shadow { r3d_bind_2d(p, "u_nrm", 1, pr.nrm); r3d_bind_2d(p, "u_arm", 2, pr.arm) }
|
||||
|
|
@ -896,7 +862,7 @@ function layer_draw_far(l: Layer, shadow: bool, light_vp: words) -> void {
|
|||
}
|
||||
gpu_cull(false)
|
||||
if not shadow and sc_a2c { gpu_alpha_to_coverage(true) }
|
||||
scatter_attach(sc_card.vao, l.imp_buf)
|
||||
scatter_attach(sc_card, l.imp_buf)
|
||||
mesh_draw_instanced(sc_card, l.n_far)
|
||||
gpu_alpha_to_coverage(false)
|
||||
}
|
||||
|
|
@ -918,7 +884,7 @@ function layer_draw_shadow(l: Layer, light_vp: words) -> void {
|
|||
u_v3(gpu_uniform(p, "u_face_dir"), sun_dir)
|
||||
u_v3(gpu_uniform(p, "u_cam_pos"), cam_pos)
|
||||
gpu_cull(false)
|
||||
scatter_attach(sc_card.vao, l.sh_buf)
|
||||
scatter_attach(sc_card, l.sh_buf)
|
||||
mesh_draw_instanced(sc_card, l.n_sh)
|
||||
}
|
||||
|
||||
|
|
@ -946,7 +912,7 @@ function layer_draw_depth(l: Layer, model: Model, vb: int, cnt: int) -> void {
|
|||
gpu_cull(false)
|
||||
for i in 0 .. len(model.prims) {
|
||||
let pr = model.prims[i]
|
||||
scatter_attach(pr.mesh.vao, vb)
|
||||
scatter_attach(pr.mesh, vb)
|
||||
r3d_bind_2d(p, "u_diff", 0, pr.diff)
|
||||
mesh_draw_instanced(pr.mesh, cnt)
|
||||
}
|
||||
|
|
@ -1065,9 +1031,8 @@ function carpet_bake(layers: []Layer, count: int, tile: int, res: int) -> int {
|
|||
}
|
||||
}
|
||||
}
|
||||
let buf = gl_buffer()
|
||||
gl_bind_buffer(GL_ARRAY_BUFFER, buf)
|
||||
gl_buffer_data(GL_ARRAY_BUFFER, gl_bytes_of(n9 * INST_FLOATS), inst, GL_STATIC_DRAW)
|
||||
let buf = gpu_buffer_new()
|
||||
gpu_buffer_upload(buf, gl_bytes_of(n9 * INST_FLOATS), inst, GPU_STATIC)
|
||||
free(inst)
|
||||
# straight down: the window is exactly one tile
|
||||
let view = m4_new(); let proj = m4_new()
|
||||
|
|
@ -1088,7 +1053,7 @@ function carpet_bake(layers: []Layer, count: int, tile: int, res: int) -> int {
|
|||
r3d_bind_2d(bake, "u_arm", 2, l.atlas.normal)
|
||||
for i in 0 .. len(l.model.prims) {
|
||||
let pr = l.model.prims[i]
|
||||
scatter_attach(pr.mesh.vao, buf)
|
||||
scatter_attach(pr.mesh, buf)
|
||||
mesh_draw_instanced(pr.mesh, n9)
|
||||
}
|
||||
}
|
||||
|
|
@ -1098,8 +1063,7 @@ function carpet_bake(layers: []Layer, count: int, tile: int, res: int) -> int {
|
|||
gl_delete_framebuffers(1, ids)
|
||||
ids[0] = rb
|
||||
gl_delete_renderbuffers(1, ids)
|
||||
ids[0] = buf
|
||||
gl_delete_buffers(1, ids)
|
||||
gpu_buffer_free(buf)
|
||||
gl_bind_texture(GL_TEXTURE_2D, tex)
|
||||
gl_tex_parameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
|
||||
gl_tex_parameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
|
||||
|
|
@ -1121,10 +1085,10 @@ function scatter_clear_all() -> void {
|
|||
let ids = gl_scratch()
|
||||
for i in 0 .. len(sc_layers) {
|
||||
let l = sc_layers[i]
|
||||
if l.buf != 0 { ids[0] = l.buf; gl_delete_buffers(1, ids) }
|
||||
if l.imp_buf != 0 { ids[0] = l.imp_buf; gl_delete_buffers(1, ids) }
|
||||
if l.sh_buf != 0 { ids[0] = l.sh_buf; gl_delete_buffers(1, ids) }
|
||||
if l.lod_buf != null { for k in 0 .. l.n_lods { ids[0] = l.lod_buf[k]; gl_delete_buffers(1, ids) } }
|
||||
if l.buf != 0 { gpu_buffer_free(l.buf) }
|
||||
if l.imp_buf != 0 { gpu_buffer_free(l.imp_buf) }
|
||||
if l.sh_buf != 0 { gpu_buffer_free(l.sh_buf) }
|
||||
if l.lod_buf != null { for k in 0 .. l.n_lods { gpu_buffer_free(l.lod_buf[k]) } }
|
||||
if l.inst != null { free(l.inst) }
|
||||
if l.scratch != null { free(l.scratch) }
|
||||
if l.tint != null { free(l.tint) }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue