fixed render
This commit is contained in:
517
core.cm
517
core.cm
@@ -1,7 +1,7 @@
|
||||
// retro3d fantasy game console
|
||||
var io = use('fd')
|
||||
var time_mod = use('time')
|
||||
var blob = use('blob')
|
||||
var blob_mod = use('blob')
|
||||
var video = use('sdl3/video')
|
||||
var gpu_mod = use('sdl3/gpu')
|
||||
var events = use('sdl3/events')
|
||||
@@ -9,6 +9,7 @@ var keyboard = use('sdl3/keyboard')
|
||||
var gltf = use('mload/gltf')
|
||||
var obj_loader = use('mload/obj')
|
||||
var model_c = use('model')
|
||||
var png = use('cell-image/png')
|
||||
|
||||
// Internal state
|
||||
var _state = {
|
||||
@@ -166,47 +167,274 @@ function log_msg() {
|
||||
function load_model(path) {
|
||||
var data = io.slurp(path)
|
||||
if (!data) return null
|
||||
|
||||
|
||||
var ext = path.slice(path.lastIndexOf('.') + 1).toLowerCase()
|
||||
var parsed = null
|
||||
|
||||
if (ext == "gltf" || ext == "glb") {
|
||||
parsed = gltf.decode(data)
|
||||
} else if (ext == "obj") {
|
||||
parsed = obj_loader.decode(data)
|
||||
} else {
|
||||
|
||||
if (ext == "obj") {
|
||||
var parsed = obj_loader.decode(data)
|
||||
if (!parsed) return null
|
||||
return _load_obj_model(parsed)
|
||||
}
|
||||
|
||||
if (ext != "gltf" && ext != "glb") {
|
||||
log.console("retro3d: unsupported model format: " + ext)
|
||||
return null
|
||||
}
|
||||
|
||||
if (!parsed || parsed.mesh_count == 0) return null
|
||||
|
||||
// Process meshes into GPU-ready format
|
||||
|
||||
// Parse gltf
|
||||
var g = gltf.decode(data)
|
||||
if (!g) return null
|
||||
|
||||
// Get the main buffer blob
|
||||
var buffer_blob = g.buffers[0] ? g.buffers[0].blob : null
|
||||
if (!buffer_blob) {
|
||||
log.console("retro3d: gltf has no buffer data")
|
||||
return null
|
||||
}
|
||||
|
||||
// Build model structure
|
||||
var model = {
|
||||
meshes: [],
|
||||
animations: parsed.animations || [],
|
||||
animation_count: parsed.animation_count || 0
|
||||
nodes: [],
|
||||
root_nodes: [],
|
||||
textures: [],
|
||||
materials: g.materials || [],
|
||||
animations: g.animations || [],
|
||||
animation_count: g.animations ? g.animations.length : 0,
|
||||
_gltf: g
|
||||
}
|
||||
|
||||
|
||||
// Load textures from embedded images
|
||||
for (var ti = 0; ti < g.images.length; ti++) {
|
||||
var img = g.images[ti]
|
||||
var tex = null
|
||||
if (img.kind == "buffer_view" && img.view != null) {
|
||||
var view = g.views[img.view]
|
||||
var img_data = _extract_buffer_view(buffer_blob, view)
|
||||
if (img.mime == "image/png") {
|
||||
var decoded = png.decode(img_data)
|
||||
if (decoded) {
|
||||
tex = _create_texture(decoded.width, decoded.height, decoded.pixels)
|
||||
}
|
||||
}
|
||||
}
|
||||
model.textures.push(tex)
|
||||
}
|
||||
|
||||
// Build node transforms (preserving hierarchy)
|
||||
for (var ni = 0; ni < g.nodes.length; ni++) {
|
||||
var node = g.nodes[ni]
|
||||
var t = null
|
||||
|
||||
if (node.matrix) {
|
||||
t = make_transform({
|
||||
local_mat: model_c.mat4_from_array(node.matrix),
|
||||
has_local_mat: true
|
||||
})
|
||||
} else {
|
||||
var trans = node.translation || [0, 0, 0]
|
||||
var rot = node.rotation || [0, 0, 0, 1]
|
||||
var scale = node.scale || [1, 1, 1]
|
||||
t = make_transform({
|
||||
x: trans[0], y: trans[1], z: trans[2],
|
||||
qx: rot[0], qy: rot[1], qz: rot[2], qw: rot[3],
|
||||
sx: scale[0], sy: scale[1], sz: scale[2]
|
||||
})
|
||||
}
|
||||
t.mesh_index = node.mesh
|
||||
t.name = node.name
|
||||
t.gltf_children = node.children || []
|
||||
model.nodes.push(t)
|
||||
}
|
||||
|
||||
// Set up parent-child relationships
|
||||
for (var ni = 0; ni < model.nodes.length; ni++) {
|
||||
var t = model.nodes[ni]
|
||||
for (var ci = 0; ci < t.gltf_children.length; ci++) {
|
||||
var child_idx = t.gltf_children[ci]
|
||||
if (child_idx < model.nodes.length) {
|
||||
transform_set_parent(model.nodes[child_idx], t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find root nodes (those without parents)
|
||||
for (var ni = 0; ni < model.nodes.length; ni++) {
|
||||
if (!model.nodes[ni].parent) {
|
||||
model.root_nodes.push(model.nodes[ni])
|
||||
}
|
||||
}
|
||||
|
||||
// Process meshes
|
||||
for (var mi = 0; mi < g.meshes.length; mi++) {
|
||||
var mesh = g.meshes[mi]
|
||||
for (var pi = 0; pi < mesh.primitives.length; pi++) {
|
||||
var prim = mesh.primitives[pi]
|
||||
var gpu_mesh = _process_gltf_primitive(g, buffer_blob, prim, model.textures)
|
||||
if (gpu_mesh) {
|
||||
gpu_mesh.name = mesh.name
|
||||
gpu_mesh.mesh_index = mi
|
||||
gpu_mesh.primitive_index = pi
|
||||
model.meshes.push(gpu_mesh)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return model
|
||||
}
|
||||
|
||||
function _extract_buffer_view(buffer_blob, view) {
|
||||
// Extract a portion of the buffer as a new blob
|
||||
var offset = view.byte_offset || 0
|
||||
var length = view.byte_length
|
||||
var newblob = buffer_blob.read_blob(offset*8, (offset + length)*8)
|
||||
return stone(newblob)
|
||||
}
|
||||
|
||||
function _process_gltf_primitive(g, buffer_blob, prim, textures) {
|
||||
var attrs = prim.attributes
|
||||
if (!attrs.POSITION) return null
|
||||
|
||||
// Get accessors
|
||||
var pos_acc = g.accessors[attrs.POSITION]
|
||||
var norm_acc = attrs.NORMAL != null ? g.accessors[attrs.NORMAL] : null
|
||||
var uv_acc = attrs.TEXCOORD_0 != null ? g.accessors[attrs.TEXCOORD_0] : null
|
||||
var idx_acc = prim.indices != null ? g.accessors[prim.indices] : null
|
||||
|
||||
var vertex_count = pos_acc.count
|
||||
|
||||
// Extract position data
|
||||
var pos_view = g.views[pos_acc.view]
|
||||
var positions = model_c.extract_accessor(
|
||||
buffer_blob,
|
||||
pos_view.byte_offset || 0,
|
||||
pos_view.byte_stride || 0,
|
||||
pos_acc.byte_offset || 0,
|
||||
pos_acc.count,
|
||||
pos_acc.component_type,
|
||||
pos_acc.type
|
||||
)
|
||||
|
||||
// Extract normals
|
||||
var normals = null
|
||||
if (norm_acc) {
|
||||
var norm_view = g.views[norm_acc.view]
|
||||
normals = model_c.extract_accessor(
|
||||
buffer_blob,
|
||||
norm_view.byte_offset || 0,
|
||||
norm_view.byte_stride || 0,
|
||||
norm_acc.byte_offset || 0,
|
||||
norm_acc.count,
|
||||
norm_acc.component_type,
|
||||
norm_acc.type
|
||||
)
|
||||
}
|
||||
|
||||
// Extract UVs
|
||||
var uvs = null
|
||||
if (uv_acc) {
|
||||
var uv_view = g.views[uv_acc.view]
|
||||
uvs = model_c.extract_accessor(
|
||||
buffer_blob,
|
||||
uv_view.byte_offset || 0,
|
||||
uv_view.byte_stride || 0,
|
||||
uv_acc.byte_offset || 0,
|
||||
uv_acc.count,
|
||||
uv_acc.component_type,
|
||||
uv_acc.type
|
||||
)
|
||||
}
|
||||
|
||||
// Extract indices
|
||||
var indices = null
|
||||
var index_count = 0
|
||||
var index_type = "uint16"
|
||||
if (idx_acc) {
|
||||
var idx_view = g.views[idx_acc.view]
|
||||
indices = model_c.extract_indices(
|
||||
buffer_blob,
|
||||
idx_view.byte_offset || 0,
|
||||
idx_acc.byte_offset || 0,
|
||||
idx_acc.count,
|
||||
idx_acc.component_type
|
||||
)
|
||||
index_count = idx_acc.count
|
||||
index_type = idx_acc.component_type == "u32" ? "uint32" : "uint16"
|
||||
}
|
||||
|
||||
// Pack vertices
|
||||
var mesh_data = {
|
||||
vertex_count: vertex_count,
|
||||
positions: positions,
|
||||
normals: normals,
|
||||
uvs: uvs,
|
||||
colors: null
|
||||
}
|
||||
var packed = model_c.pack_vertices(mesh_data)
|
||||
|
||||
// Create GPU buffers
|
||||
var vertex_buffer = _create_vertex_buffer(packed.data)
|
||||
var index_buffer = indices ? _create_index_buffer(indices) : null
|
||||
|
||||
// Get material texture
|
||||
var texture = null
|
||||
if (prim.material != null && g.materials[prim.material]) {
|
||||
var mat = g.materials[prim.material]
|
||||
if (mat.pbr && mat.pbr.base_color_texture) {
|
||||
var tex_info = mat.pbr.base_color_texture
|
||||
var tex_obj = g.textures[tex_info.texture]
|
||||
if (tex_obj && tex_obj.image != null && textures[tex_obj.image]) {
|
||||
texture = textures[tex_obj.image]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
vertex_buffer: vertex_buffer,
|
||||
index_buffer: index_buffer,
|
||||
index_count: index_count,
|
||||
index_type: index_type,
|
||||
vertex_count: vertex_count,
|
||||
material_index: prim.material,
|
||||
texture: texture
|
||||
}
|
||||
}
|
||||
|
||||
function _load_obj_model(parsed) {
|
||||
if (!parsed || !parsed.meshes || parsed.meshes.length == 0) return null
|
||||
|
||||
var model = {
|
||||
meshes: [],
|
||||
nodes: [],
|
||||
root_nodes: [],
|
||||
textures: [],
|
||||
materials: [],
|
||||
animations: [],
|
||||
animation_count: 0
|
||||
}
|
||||
|
||||
for (var i = 0; i < parsed.meshes.length; i++) {
|
||||
var mesh = parsed.meshes[i]
|
||||
var packed = model_c.pack_vertices(mesh)
|
||||
|
||||
// Create GPU buffers
|
||||
var vertex_buffer = _create_vertex_buffer(packed.data)
|
||||
var index_buffer = _create_index_buffer(mesh.indices)
|
||||
|
||||
|
||||
model.meshes.push({
|
||||
vertex_buffer: vertex_buffer,
|
||||
index_buffer: index_buffer,
|
||||
index_count: mesh.index_count,
|
||||
index_type: mesh.index_type,
|
||||
index_type: mesh.index_type || "uint16",
|
||||
vertex_count: mesh.vertex_count,
|
||||
material: mesh.material,
|
||||
name: mesh.name
|
||||
name: mesh.name,
|
||||
texture: null
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// Create a single root transform
|
||||
var root = make_transform()
|
||||
model.nodes.push(root)
|
||||
model.root_nodes.push(root)
|
||||
|
||||
return model
|
||||
}
|
||||
|
||||
@@ -379,18 +607,123 @@ function set_music_volume(v) {}
|
||||
function set_sfx_volume(v) {}
|
||||
|
||||
// ============================================================================
|
||||
// 3) Transforms
|
||||
// 3) Transforms - Hierarchical with dirty flags
|
||||
// ============================================================================
|
||||
|
||||
function make_transform() {
|
||||
function make_transform(opts) {
|
||||
opts = opts || {}
|
||||
return {
|
||||
x: 0, y: 0, z: 0,
|
||||
rot_x: 0, rot_y: 0, rot_z: 0,
|
||||
scale_x: 1, scale_y: 1, scale_z: 1,
|
||||
parent: null
|
||||
parent: opts.parent || null,
|
||||
children: [],
|
||||
|
||||
// TRS (authoring) - translation
|
||||
x: opts.x || 0,
|
||||
y: opts.y || 0,
|
||||
z: opts.z || 0,
|
||||
// Quaternion rotation
|
||||
qx: opts.qx || 0,
|
||||
qy: opts.qy || 0,
|
||||
qz: opts.qz || 0,
|
||||
qw: opts.qw != null ? opts.qw : 1,
|
||||
// Scale
|
||||
sx: opts.sx != null ? opts.sx : 1,
|
||||
sy: opts.sy != null ? opts.sy : 1,
|
||||
sz: opts.sz != null ? opts.sz : 1,
|
||||
|
||||
// Matrices (opaque blobs)
|
||||
local_mat: opts.local_mat || null,
|
||||
world_mat: null,
|
||||
|
||||
// Authority: if true, local_mat is used directly, TRS ignored
|
||||
has_local_mat: opts.has_local_mat || false,
|
||||
|
||||
// Cache invalidation
|
||||
dirty_local: true,
|
||||
dirty_world: true
|
||||
}
|
||||
}
|
||||
|
||||
function transform_set_parent(child, parent) {
|
||||
if (child.parent) {
|
||||
var idx = child.parent.children.indexOf(child)
|
||||
if (idx >= 0) child.parent.children.splice(idx, 1)
|
||||
}
|
||||
child.parent = parent
|
||||
if (parent) parent.children.push(child)
|
||||
transform_mark_dirty(child)
|
||||
}
|
||||
|
||||
function transform_mark_dirty(t) {
|
||||
t.dirty_local = true
|
||||
t.dirty_world = true
|
||||
for (var i = 0; i < t.children.length; i++) {
|
||||
transform_mark_world_dirty(t.children[i])
|
||||
}
|
||||
}
|
||||
|
||||
function transform_mark_world_dirty(t) {
|
||||
t.dirty_world = true
|
||||
for (var i = 0; i < t.children.length; i++) {
|
||||
transform_mark_world_dirty(t.children[i])
|
||||
}
|
||||
}
|
||||
|
||||
function transform_get_local_matrix(t) {
|
||||
if (!t.dirty_local && t.local_mat) return t.local_mat
|
||||
|
||||
if (t.has_local_mat && t.local_mat) {
|
||||
t.dirty_local = false
|
||||
return t.local_mat
|
||||
}
|
||||
|
||||
// Build from TRS
|
||||
t.local_mat = model_c.mat4_from_trs(
|
||||
t.x, t.y, t.z,
|
||||
t.qx, t.qy, t.qz, t.qw,
|
||||
t.sx, t.sy, t.sz
|
||||
)
|
||||
t.dirty_local = false
|
||||
return t.local_mat
|
||||
}
|
||||
|
||||
function transform_get_world_matrix(t) {
|
||||
if (!t.dirty_world && t.world_mat) return t.world_mat
|
||||
|
||||
var local = transform_get_local_matrix(t)
|
||||
if (t.parent) {
|
||||
var parent_world = transform_get_world_matrix(t.parent)
|
||||
t.world_mat = model_c.mat4_mul(parent_world, local)
|
||||
} else {
|
||||
t.world_mat = local
|
||||
}
|
||||
t.dirty_world = false
|
||||
return t.world_mat
|
||||
}
|
||||
|
||||
function transform_set_position(t, x, y, z) {
|
||||
t.x = x; t.y = y; t.z = z
|
||||
t.has_local_mat = false
|
||||
transform_mark_dirty(t)
|
||||
}
|
||||
|
||||
function transform_set_rotation_quat(t, qx, qy, qz, qw) {
|
||||
t.qx = qx; t.qy = qy; t.qz = qz; t.qw = qw
|
||||
t.has_local_mat = false
|
||||
transform_mark_dirty(t)
|
||||
}
|
||||
|
||||
function transform_set_scale(t, sx, sy, sz) {
|
||||
t.sx = sx; t.sy = sy; t.sz = sz
|
||||
t.has_local_mat = false
|
||||
transform_mark_dirty(t)
|
||||
}
|
||||
|
||||
function transform_set_matrix(t, mat) {
|
||||
t.local_mat = mat
|
||||
t.has_local_mat = true
|
||||
transform_mark_dirty(t)
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 4) Camera & Projection
|
||||
// ============================================================================
|
||||
@@ -513,19 +846,69 @@ function clear_depth() {
|
||||
|
||||
function draw_model(model, transform, anim_instance) {
|
||||
if (!model || !model.meshes) return
|
||||
|
||||
var world_matrix = model_c.compute_world_matrix(transform)
|
||||
|
||||
// Get view and projection matrices
|
||||
var view_matrix = _compute_view_matrix()
|
||||
var proj_matrix = _compute_projection_matrix()
|
||||
|
||||
var mat = _state.current_material
|
||||
var tint = mat ? mat.color : [1, 1, 1, 1]
|
||||
var tex = mat && mat.texture ? mat.texture : _state.white_texture
|
||||
|
||||
var uniforms = model_c.build_uniforms({
|
||||
model: world_matrix,
|
||||
view: view_matrix,
|
||||
projection: proj_matrix,
|
||||
|
||||
// If transform is provided, use it as an additional parent for the model's root nodes
|
||||
var extra_transform = transform ? transform_get_world_matrix(transform) : null
|
||||
|
||||
// Draw each node that has a mesh
|
||||
for (var ni = 0; ni < model.nodes.length; ni++) {
|
||||
var node = model.nodes[ni]
|
||||
if (node.mesh_index == null) continue
|
||||
|
||||
// Find meshes for this node
|
||||
for (var mi = 0; mi < model.meshes.length; mi++) {
|
||||
var mesh = model.meshes[mi]
|
||||
if (mesh.mesh_index != node.mesh_index) continue
|
||||
|
||||
// Get world matrix for this node
|
||||
var node_world = transform_get_world_matrix(node)
|
||||
|
||||
// Apply extra transform if provided
|
||||
var world_matrix = extra_transform
|
||||
? model_c.mat4_mul(extra_transform, node_world)
|
||||
: node_world
|
||||
|
||||
// Get material/texture
|
||||
var mat = _state.current_material
|
||||
var tint = mat ? mat.color : [1, 1, 1, 1]
|
||||
var tex = mesh.texture || (mat && mat.texture ? mat.texture : _state.white_texture)
|
||||
|
||||
// Build uniforms in cell script
|
||||
var uniforms = _build_uniforms(world_matrix, view_matrix, proj_matrix, tint)
|
||||
|
||||
_draw_mesh(mesh, uniforms, tex, mat ? mat.kind : "lit")
|
||||
_state.draw_calls++
|
||||
_state.triangles += mesh.index_count / 3
|
||||
}
|
||||
}
|
||||
|
||||
// If model has no nodes with meshes, draw meshes directly (fallback)
|
||||
if (model.nodes.length == 0) {
|
||||
var world_matrix = transform ? transform_get_world_matrix(transform) : model_c.mat4_identity()
|
||||
var mat = _state.current_material
|
||||
var tint = mat ? mat.color : [1, 1, 1, 1]
|
||||
|
||||
for (var i = 0; i < model.meshes.length; i++) {
|
||||
var mesh = model.meshes[i]
|
||||
var tex = mesh.texture || (mat && mat.texture ? mat.texture : _state.white_texture)
|
||||
var uniforms = _build_uniforms(world_matrix, view_matrix, proj_matrix, tint)
|
||||
_draw_mesh(mesh, uniforms, tex, mat ? mat.kind : "lit")
|
||||
_state.draw_calls++
|
||||
_state.triangles += mesh.index_count / 3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build uniform buffer using C helper (blob API doesn't have write_f32)
|
||||
function _build_uniforms(model_mat, view_mat, proj_mat, tint) {
|
||||
return model_c.build_uniforms({
|
||||
model: model_mat,
|
||||
view: view_mat,
|
||||
projection: proj_mat,
|
||||
ambient: _state.ambient,
|
||||
light_dir: _state.light_dir,
|
||||
light_color: _state.light_color,
|
||||
@@ -538,13 +921,6 @@ function draw_model(model, transform, anim_instance) {
|
||||
resolution_w: _state.resolution_w,
|
||||
resolution_h: _state.resolution_h
|
||||
})
|
||||
|
||||
for (var i = 0; i < model.meshes.length; i++) {
|
||||
var mesh = model.meshes[i]
|
||||
_draw_mesh(mesh, uniforms, tex, mat ? mat.kind : "lit")
|
||||
_state.draw_calls++
|
||||
_state.triangles += mesh.index_count / 3
|
||||
}
|
||||
}
|
||||
|
||||
// Immediate mode
|
||||
@@ -764,7 +1140,7 @@ function _init_gpu() {
|
||||
})
|
||||
|
||||
// Create GPU device
|
||||
_state.gpu = new gpu_mod.gpu({ debug: false, shaders_msl: true })
|
||||
_state.gpu = new gpu_mod.gpu({ debug: true, shaders_msl: true })
|
||||
_state.gpu.claim_window(_state.window)
|
||||
|
||||
// Load shaders
|
||||
@@ -781,7 +1157,7 @@ function _init_gpu() {
|
||||
stage: "vertex",
|
||||
format: "msl",
|
||||
entrypoint: "vertex_main",
|
||||
num_uniform_buffers: 1
|
||||
num_uniform_buffers: 2
|
||||
})
|
||||
|
||||
var frag_shader = new gpu_mod.shader(_state.gpu, {
|
||||
@@ -789,7 +1165,7 @@ function _init_gpu() {
|
||||
stage: "fragment",
|
||||
format: "msl",
|
||||
entrypoint: "fragment_main",
|
||||
num_uniform_buffers: 1,
|
||||
num_uniform_buffers: 2,
|
||||
num_samplers: 1
|
||||
})
|
||||
|
||||
@@ -853,7 +1229,7 @@ function _init_gpu() {
|
||||
})
|
||||
|
||||
// Create white texture (1x1)
|
||||
var white_pixels = new blob(32, true)
|
||||
var white_pixels = new blob_mod(32, true)
|
||||
|
||||
_state.white_texture = _create_texture(1, 1, stone(white_pixels))
|
||||
}
|
||||
@@ -948,7 +1324,7 @@ function _create_texture(w, h, pixels) {
|
||||
|
||||
function _make_model_from_arrays(positions, normals, uvs, indices, colors) {
|
||||
var vertex_count = positions.length / 3
|
||||
|
||||
|
||||
// Build mesh object
|
||||
var mesh = {
|
||||
vertex_count: vertex_count,
|
||||
@@ -962,18 +1338,24 @@ function _make_model_from_arrays(positions, normals, uvs, indices, colors) {
|
||||
|
||||
mesh.indices = model_c.u16_blob(indices)
|
||||
mesh.index_type = "uint16"
|
||||
|
||||
|
||||
// Pack and create GPU buffers
|
||||
var packed = model_c.pack_vertices(mesh)
|
||||
|
||||
|
||||
return {
|
||||
meshes: [{
|
||||
vertex_buffer: _create_vertex_buffer(packed.data),
|
||||
index_buffer: _create_index_buffer(mesh.indices),
|
||||
index_count: mesh.index_count,
|
||||
index_type: "uint16",
|
||||
vertex_count: vertex_count
|
||||
vertex_count: vertex_count,
|
||||
texture: null,
|
||||
mesh_index: 0
|
||||
}],
|
||||
nodes: [],
|
||||
root_nodes: [],
|
||||
textures: [],
|
||||
materials: [],
|
||||
animations: [],
|
||||
animation_count: 0
|
||||
}
|
||||
@@ -1079,7 +1461,7 @@ function _end_frame() {
|
||||
var cmd = _state.gpu.acquire_cmd_buffer()
|
||||
|
||||
// Get swapchain pass instead
|
||||
var swap_pass = cmd.swapchain_pass(_state.window, {
|
||||
var pass_desc = {
|
||||
color_targets: [{
|
||||
texture: null, // Will use swapchain
|
||||
load: "clear",
|
||||
@@ -1090,8 +1472,11 @@ function _end_frame() {
|
||||
b: _state._clear_color[2],
|
||||
a: _state._clear_color[3]
|
||||
}
|
||||
}],
|
||||
depth_stencil: {
|
||||
}]
|
||||
}
|
||||
|
||||
if (_state.depth_texture) {
|
||||
pass_desc.depth_stencil = {
|
||||
texture: _state.depth_texture,
|
||||
load: _state._clear_depth ? "clear" : "load",
|
||||
store: "dont_care",
|
||||
@@ -1100,7 +1485,9 @@ function _end_frame() {
|
||||
clear: 1.0,
|
||||
clear_stencil: 0
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
var swap_pass = cmd.swapchain_pass(_state.window, pass_desc)
|
||||
|
||||
// Draw all pending meshes
|
||||
var draws = _state._pending_draws || []
|
||||
@@ -1111,8 +1498,9 @@ function _end_frame() {
|
||||
swap_pass.bind_vertex_buffers(0, [{ buffer: d.mesh.vertex_buffer, offset: 0 }])
|
||||
swap_pass.bind_index_buffer({ buffer: d.mesh.index_buffer, offset: 0 }, d.mesh.index_type == "uint32" ? 32 : 16)
|
||||
|
||||
cmd.push_vertex_uniform_data(0, d.uniforms)
|
||||
cmd.push_fragment_uniform_data(0, d.uniforms)
|
||||
// Shaders use [[buffer(1)]] for uniforms (buffer(0) is vertex data)
|
||||
cmd.push_vertex_uniform_data(1, d.uniforms)
|
||||
cmd.push_fragment_uniform_data(1, d.uniforms)
|
||||
|
||||
var sampler = _state.style_id == 1 ? _state.sampler_linear : _state.sampler_nearest
|
||||
swap_pass.bind_fragment_samplers(0, [{ texture: d.texture, sampler: sampler }])
|
||||
@@ -1154,6 +1542,13 @@ return {
|
||||
set_sfx_volume: set_sfx_volume,
|
||||
|
||||
make_transform: make_transform,
|
||||
transform_set_parent: transform_set_parent,
|
||||
transform_set_position: transform_set_position,
|
||||
transform_set_rotation_quat: transform_set_rotation_quat,
|
||||
transform_set_scale: transform_set_scale,
|
||||
transform_set_matrix: transform_set_matrix,
|
||||
transform_get_local_matrix: transform_get_local_matrix,
|
||||
transform_get_world_matrix: transform_get_world_matrix,
|
||||
|
||||
camera_look_at: camera_look_at,
|
||||
camera_perspective: camera_perspective,
|
||||
|
||||
Reference in New Issue
Block a user