collada_scene: basic scene rendering

This commit is contained in:
Zack Buhman 2026-01-26 13:21:12 -06:00
parent 67820fce2b
commit b8cea38d9f
16 changed files with 1811 additions and 492 deletions

View File

@ -47,7 +47,8 @@ SHADERS = \
$(BUILD_TYPE)/effect/volume.fxo \ $(BUILD_TYPE)/effect/volume.fxo \
$(BUILD_TYPE)/effect/bloom.fxo \ $(BUILD_TYPE)/effect/bloom.fxo \
$(BUILD_TYPE)/effect/static.fxo \ $(BUILD_TYPE)/effect/static.fxo \
$(BUILD_TYPE)/effect/collada.fxo $(BUILD_TYPE)/effect/collada.fxo \
$(BUILD_TYPE)/effect/collada_scene.fxo
$(BUILD_TYPE)/%.res: %.rc $(SHADERS) $(BUILD_TYPE)/%.res: %.rc $(SHADERS)
@mkdir -p $(@D) @mkdir -p $(@D)
@ -65,7 +66,8 @@ OBJS = \
$(BUILD_TYPE)/print.obj \ $(BUILD_TYPE)/print.obj \
$(BUILD_TYPE)/render_state.obj \ $(BUILD_TYPE)/render_state.obj \
$(BUILD_TYPE)/input.obj \ $(BUILD_TYPE)/input.obj \
$(BUILD_TYPE)/collada.obj $(BUILD_TYPE)/collada.obj \
$(BUILD_TYPE)/collada_scene.obj
$(BUILD_TYPE)/d3d10.exe: $(OBJS) $(BUILD_TYPE)/d3d10.exe: $(OBJS)
@mkdir -p $(@D) @mkdir -p $(@D)

View File

@ -42,13 +42,7 @@ def mesh_vertex_index_buffer_triangles(collada, mesh, triangles):
p_stride = max_offset + 1 p_stride = max_offset + 1
offset_table, used_offsets = build_offset_table(collada, triangles, p_stride) offset_table, used_offsets = build_offset_table(collada, triangles, p_stride)
from prettyprinter import pprint, install_extras
install_extras(include=["dataclasses"])
@dataclass
class MeshVertexIndexBufferState: class MeshVertexIndexBufferState:
index_buffer: List[int]
def __init__(self): def __init__(self):
self.index_buffer = [] # a list of integers self.index_buffer = [] # a list of integers
self.vertex_buffer = [] # a list of floats self.vertex_buffer = [] # a list of floats

View File

@ -18,7 +18,8 @@ install_extras(include=["dataclasses"])
class State: class State:
# arbitrary binary data, including vertex buffers and index # arbitrary binary data, including vertex buffers and index
# buffers # buffers
buf: BytesIO vertex_buffer: BytesIO
index_buffer: BytesIO
# geometry__indices: # geometry__indices:
# keys: collada <geometry> id # keys: collada <geometry> id
@ -40,7 +41,8 @@ class State:
emitted_input_elements_arrays: Dict[str, tuple] emitted_input_elements_arrays: Dict[str, tuple]
def __init__(self): def __init__(self):
self.buf = BytesIO() self.vertex_buffer = BytesIO()
self.index_buffer = BytesIO()
self.geometry__indices = {} self.geometry__indices = {}
self.geometry__vertex_index_tables = {} self.geometry__vertex_index_tables = {}
self.node_names = {} self.node_names = {}
@ -109,9 +111,9 @@ def render_input_elements(state, collada, geometry_name, offset_tables):
key = tuple(offset_table_key(offset_table)) key = tuple(offset_table_key(offset_table))
key_name = input_elements_key_name(key) key_name = input_elements_key_name(key)
if key_name in state.emitted_input_elements_arrays: if key_name in state.emitted_input_elements_arrays:
assert state.emitted_input_elements_arrays[key_name] == key assert state.emitted_input_elements_arrays[key_name][1] == key
continue continue
state.emitted_input_elements_arrays[key_name] = key state.emitted_input_elements_arrays[key_name] = (i, key)
yield f"input_element const input_elements_{key_name}[] = {{" yield f"input_element const input_elements_{key_name}[] = {{"
for semantic, semantic_index, stride in key: for semantic, semantic_index, stride in key:
@ -131,14 +133,12 @@ def render_triangles(state, collada, geometry_name, primitive_elements, mesh_buf
key = tuple(offset_table_key(mesh_buffer_state.offset_tables[i])) key = tuple(offset_table_key(mesh_buffer_state.offset_tables[i]))
key_name = input_elements_key_name(key) key_name = input_elements_key_name(key)
index, _ = state.emitted_input_elements_arrays[key_name]
yield "{" yield "{"
yield f".count = {triangles.count}, // triangles" yield f".count = {triangles.count}, // triangles"
yield f".index_offset = {mesh_buffer_state.index_buffer_offsets[i]}, // indices" yield f".index_offset = {mesh_buffer_state.index_buffer_offsets[i]}, // indices"
yield ".inputs = {" yield f".inputs_index = {index}, // index into inputs_list"
yield f".elements = input_elements_{key_name},"
yield f".elements_count = {len(key)},"
yield "}"
yield "}," yield "},"
yield "};" yield "};"
@ -149,13 +149,13 @@ def render_geometry(state, collada, geometry):
assert type(mesh) is types.Mesh assert type(mesh) is types.Mesh
mesh_buffer_state = buffer.mesh_vertex_index_buffer(collada, mesh) mesh_buffer_state = buffer.mesh_vertex_index_buffer(collada, mesh)
vertex_buffer_offset = state.buf.tell() vertex_buffer_offset = state.vertex_buffer.tell()
renderbin(state.buf, mesh_buffer_state.vertex_buffer, float) renderbin(state.vertex_buffer, mesh_buffer_state.vertex_buffer, float)
vertex_buffer_size = state.buf.tell() - vertex_buffer_offset vertex_buffer_size = state.vertex_buffer.tell() - vertex_buffer_offset
index_buffer_offset = state.buf.tell() index_buffer_offset = state.index_buffer.tell()
renderbin(state.buf, mesh_buffer_state.index_buffer, int) renderbin(state.index_buffer, mesh_buffer_state.index_buffer, int)
index_buffer_size = state.buf.tell() - index_buffer_offset index_buffer_size = state.index_buffer.tell() - index_buffer_offset
yield from render_triangles(state, collada, geometry_name, mesh.primitive_elements, mesh_buffer_state) yield from render_triangles(state, collada, geometry_name, mesh.primitive_elements, mesh_buffer_state)
@ -328,12 +328,13 @@ def render_library_visual_scenes(state, collada):
yield f"&node_{node_name}," yield f"&node_{node_name},"
yield "};" yield "};"
def render_header(): def render_header(namespace):
yield '#include "collada_types.hpp"' yield '#include "collada_types.hpp"'
yield '' yield ''
yield f'namespace {namespace} {{'
yield ''
yield 'using namespace collada;' yield 'using namespace collada;'
def render_opt_color(field_name, color): def render_opt_color(field_name, color):
yield f".color = {render_float_tuple(color.value)}," yield f".color = {render_float_tuple(color.value)},"
@ -424,14 +425,38 @@ def render_library_materials(state, collada):
yield f".effect = &effect_{effect_name}," yield f".effect = &effect_{effect_name},"
yield "};" yield "};"
def render_all(collada): def render_input_elements_list(state):
yield "inputs const inputs_list[] = {"
for key_name, (index, key) in state.emitted_input_elements_arrays.items():
yield "{"
yield f".elements = input_elements_{key_name},"
yield f".elements_count = {len(key)},"
yield "},"
yield "};"
def render_descriptor():
yield "descriptor const descriptor = {"
yield ".nodes = nodes,"
yield ".nodes_count = (sizeof (nodes)) / (sizeof (nodes[0])),"
yield ""
yield ".inputs_list = inputs_list,"
yield ".inputs_list_count = (sizeof (inputs_list)) / (sizeof (inputs_list[0])),"
yield "};"
def render_end_of_namespace():
yield "}"
def render_all(collada, namespace):
state = State() state = State()
render, out = renderer() render, out = renderer()
render(render_header()) render(render_header(namespace))
render(render_library_effects(state, collada)) render(render_library_effects(state, collada))
render(render_library_materials(state, collada)) render(render_library_materials(state, collada))
render(render_library_geometries(state, collada)) render(render_library_geometries(state, collada))
render(render_library_visual_scenes(state, collada)) render(render_library_visual_scenes(state, collada))
render(render_input_elements_list(state))
render(render_descriptor())
render(render_end_of_namespace())
return state, out return state, out
if __name__ == "__main__": if __name__ == "__main__":
@ -442,5 +467,5 @@ if __name__ == "__main__":
#assert type(skin) is types.Skin #assert type(skin) is types.Skin
#foo = render_inverse_bind_matrix(collada, skin) #foo = render_inverse_bind_matrix(collada, skin)
state, out = render_all(collada) state, out = render_all(collada, "test")
print(out.getvalue()) print(out.getvalue())

View File

@ -1,4 +1,5 @@
import sys import sys
from os import path
from collada import parse from collada import parse
from collada import header from collada import header
@ -6,30 +7,36 @@ from collada import header
def usage(): def usage():
name = sys.argv[0] name = sys.argv[0]
print("usage:") print("usage:")
print(f" {name} [input_collada.dae] [output_header.hpp] [output_binary.bin]") print(f" {name} [input_collada.dae] [output_header.hpp] [output_vertex.vtx] [output_vertex.idx]")
sys.exit(1) sys.exit(1)
def main(): def main():
try: try:
input_collada = sys.argv[1] input_collada = sys.argv[1]
output_header = sys.argv[2] output_header = sys.argv[2]
output_binary = sys.argv[3] output_vertex = sys.argv[3]
output_index = sys.argv[4]
assert input_collada.lower().endswith(".dae") assert input_collada.lower().endswith(".dae")
assert output_header.lower().endswith(".hpp") assert output_header.lower().endswith(".hpp")
assert output_binary.lower().endswith(".bin") assert output_vertex.lower().endswith(".vtx")
except: assert output_index.lower().endswith(".idx")
except Exception as e:
usage() usage()
collada = parse.parse_collada_file(input_collada) collada = parse.parse_collada_file(input_collada)
state, out = header.render_all(collada) namespace = path.splitext(path.split(input_collada)[1])[0]
state, out = header.render_all(collada, namespace)
with open(output_header, 'wb') as f: with open(output_header, 'wb') as f:
header_buf = out.getvalue() header_buf = out.getvalue()
assert "\r\n" in header_buf assert "\r\n" in header_buf
f.write(header_buf.encode('utf-8')) f.write(header_buf.encode('utf-8'))
with open(output_binary, 'wb') as f: with open(output_vertex, 'wb') as f:
f.write(state.buf.getvalue()) f.write(state.vertex_buffer.getvalue())
with open(output_index, 'wb') as f:
f.write(state.index_buffer.getvalue())
if __name__ == "__main__": if __name__ == "__main__":
main() main()

25
include/collada_scene.hpp Normal file
View File

@ -0,0 +1,25 @@
#pragma once
#include "collada_types.hpp"
namespace collada_scene {
struct scene_state {
const UINT numBuffers = 1; // FIXME
const UINT strides[1] = {3 * 3 * 4}; // FIXME
const UINT offsets[1] = {0}; // FIXME
ID3D10Buffer * pVertexBuffers[1] = {}; // FIXME
ID3D10Buffer * pIndexBuffer = NULL;
ID3D10InputLayout ** pVertexLayouts = NULL;
HRESULT load_vertex_buffer(LPCWSTR name);
HRESULT load_index_buffer(LPCWSTR name);
HRESULT load_layout(int inputs_index, collada::inputs const& inputs);
HRESULT load_layouts(collada::descriptor const& descriptor);
};
HRESULT LoadScene(collada::descriptor const& descriptor, scene_state& state);
void Render(collada::descriptor const& descriptor, scene_state const& state);
}

View File

@ -56,8 +56,13 @@ namespace collada {
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
enum class input_format { enum class input_format {
FLOAT1,
FLOAT2,
FLOAT3, FLOAT3,
FLOAT4, FLOAT4,
INT1,
INT2,
INT3,
INT4, INT4,
}; };
@ -76,7 +81,7 @@ namespace collada {
struct triangles { struct triangles {
int const count; int const count;
int const index_offset; int const index_offset;
inputs const inputs; int const inputs_index;
}; };
struct mesh { struct mesh {
@ -138,7 +143,6 @@ namespace collada {
NODE, NODE,
}; };
struct color_or_texture { struct color_or_texture {
union { union {
float4 color; float4 color;
@ -236,4 +240,12 @@ namespace collada {
node const * const nodes; node const * const nodes;
int const nodes_count; int const nodes_count;
}; };
struct descriptor {
node const * const * const nodes;
int const nodes_count;
inputs const * inputs_list;
int const inputs_list_count;
};
} }

View File

@ -0,0 +1,529 @@
#include "collada_types.hpp"
namespace curve_interpolation {
using namespace collada;
effect const effect_material__15 = {
.type = effect_type::BLINN,
.blinn = {
.emission = {
.color = {0.0f, 0.0f, 0.0f, 1.0f},
},
.ambient = {
.color = {0.6705883f, 0.5843138f, 1.0f, 1.0f},
},
.diffuse = {
.color = {0.6705883f, 0.5843138f, 1.0f, 1.0f},
},
.specular = {
.color = {0.0f, 0.0f, 0.0f, 1.0f},
},
.shininess = 10.0f,
.reflective = {
.color = {0.0f, 0.0f, 0.0f, 1.0f},
},
.reflectivity = 0.0f,
.transparent = {
.color = {1.0f, 1.0f, 1.0f, 1.0f},
},
.transparency = 1.0f,
.index_of_refraction = 0.0f,
}
};
effect const effect_material__16 = {
.type = effect_type::BLINN,
.blinn = {
.emission = {
.color = {0.0f, 0.0f, 0.0f, 1.0f},
},
.ambient = {
.color = {0.5803922f, 1.0f, 0.9647059f, 1.0f},
},
.diffuse = {
.color = {0.5803922f, 1.0f, 0.9647059f, 1.0f},
},
.specular = {
.color = {0.0f, 0.0f, 0.0f, 1.0f},
},
.shininess = 10.0f,
.reflective = {
.color = {0.0f, 0.0f, 0.0f, 1.0f},
},
.reflectivity = 0.0f,
.transparent = {
.color = {1.0f, 1.0f, 1.0f, 1.0f},
},
.transparency = 1.0f,
.index_of_refraction = 0.0f,
}
};
effect const effect_material__17 = {
.type = effect_type::BLINN,
.blinn = {
.emission = {
.color = {0.0f, 0.0f, 0.0f, 1.0f},
},
.ambient = {
.color = {0.6509804f, 1.0f, 0.5803922f, 1.0f},
},
.diffuse = {
.color = {0.6509804f, 1.0f, 0.5803922f, 1.0f},
},
.specular = {
.color = {0.0f, 0.0f, 0.0f, 1.0f},
},
.shininess = 10.0f,
.reflective = {
.color = {0.0f, 0.0f, 0.0f, 1.0f},
},
.reflectivity = 0.0f,
.transparent = {
.color = {1.0f, 1.0f, 1.0f, 1.0f},
},
.transparency = 1.0f,
.index_of_refraction = 0.0f,
}
};
effect const effect_material__18 = {
.type = effect_type::BLINN,
.blinn = {
.emission = {
.color = {0.0f, 0.0f, 0.0f, 1.0f},
},
.ambient = {
.color = {0.9333334f, 1.0f, 0.5647059f, 1.0f},
},
.diffuse = {
.color = {0.9333334f, 1.0f, 0.5647059f, 1.0f},
},
.specular = {
.color = {0.0f, 0.0f, 0.0f, 1.0f},
},
.shininess = 10.0f,
.reflective = {
.color = {0.0f, 0.0f, 0.0f, 1.0f},
},
.reflectivity = 0.0f,
.transparent = {
.color = {1.0f, 1.0f, 1.0f, 1.0f},
},
.transparency = 1.0f,
.index_of_refraction = 0.0f,
}
};
effect const effect_material__19 = {
.type = effect_type::BLINN,
.blinn = {
.emission = {
.color = {0.0f, 0.0f, 0.0f, 1.0f},
},
.ambient = {
.color = {1.0f, 0.7686275f, 0.5803922f, 1.0f},
},
.diffuse = {
.color = {1.0f, 0.7686275f, 0.5803922f, 1.0f},
},
.specular = {
.color = {0.0f, 0.0f, 0.0f, 1.0f},
},
.shininess = 10.0f,
.reflective = {
.color = {0.0f, 0.0f, 0.0f, 1.0f},
},
.reflectivity = 0.0f,
.transparent = {
.color = {1.0f, 1.0f, 1.0f, 1.0f},
},
.transparency = 1.0f,
.index_of_refraction = 0.0f,
}
};
effect const effect_material__20 = {
.type = effect_type::BLINN,
.blinn = {
.emission = {
.color = {0.0f, 0.0f, 0.0f, 1.0f},
},
.ambient = {
.color = {1.0f, 0.5803922f, 0.5803922f, 1.0f},
},
.diffuse = {
.color = {1.0f, 0.5803922f, 0.5803922f, 1.0f},
},
.specular = {
.color = {0.0f, 0.0f, 0.0f, 1.0f},
},
.shininess = 10.0f,
.reflective = {
.color = {0.0f, 0.0f, 0.0f, 1.0f},
},
.reflectivity = 0.0f,
.transparent = {
.color = {1.0f, 1.0f, 1.0f, 1.0f},
},
.transparency = 1.0f,
.index_of_refraction = 0.0f,
}
};
effect const effect_coloreffectr229g154b215 = {
.type = effect_type::PHONG,
.phong = {
.emission = {
.color = {0.0f, 0.0f, 0.0f, 0.0f},
},
.ambient = {
.color = {0.8980392f, 0.6039216f, 0.8431373f, 1.0f},
},
.diffuse = {
.color = {0.8980392f, 0.6039216f, 0.8431373f, 1.0f},
},
.specular = {
.color = {1.0f, 1.0f, 1.0f, 1.0f},
},
.shininess = 10.0f,
.reflective = {
.color = {0.0f, 0.0f, 0.0f, 1.0f},
},
.reflectivity = 0.0f,
.transparent = {
.color = {1.0f, 1.0f, 1.0f, 1.0f},
},
.transparency = 1.0f,
.index_of_refraction = 0.0f,
}
};
effect const effect_coloreffectr28g149b177 = {
.type = effect_type::PHONG,
.phong = {
.emission = {
.color = {0.0f, 0.0f, 0.0f, 0.0f},
},
.ambient = {
.color = {0.1098039f, 0.5843137f, 0.6941176f, 1.0f},
},
.diffuse = {
.color = {0.1098039f, 0.5843137f, 0.6941176f, 1.0f},
},
.specular = {
.color = {1.0f, 1.0f, 1.0f, 1.0f},
},
.shininess = 10.0f,
.reflective = {
.color = {0.0f, 0.0f, 0.0f, 1.0f},
},
.reflectivity = 0.0f,
.transparent = {
.color = {1.0f, 1.0f, 1.0f, 1.0f},
},
.transparency = 1.0f,
.index_of_refraction = 0.0f,
}
};
material const material_coloreffectr229g154b215_material = {
.effect = &effect_coloreffectr229g154b215,
};
material const material_coloreffectr28g149b177_material = {
.effect = &effect_coloreffectr28g149b177,
};
material const material_material__15_material = {
.effect = &effect_material__15,
};
material const material_material__16_material = {
.effect = &effect_material__16,
};
material const material_material__17_material = {
.effect = &effect_material__17,
};
material const material_material__18_material = {
.effect = &effect_material__18,
};
material const material_material__19_material = {
.effect = &effect_material__19,
};
material const material_material__20_material = {
.effect = &effect_material__20,
};
input_element const input_elements_position_0_3_normal_0_3_texcoord_0_3[] = {
{
.semantic = "POSITION",
.semantic_index = 0,
.format = input_format::FLOAT3,
},
{
.semantic = "NORMAL",
.semantic_index = 0,
.format = input_format::FLOAT3,
},
{
.semantic = "TEXCOORD",
.semantic_index = 0,
.format = input_format::FLOAT3,
},
};
triangles const triangles_geom_cube[] = {
{
.count = 2, // triangles
.index_offset = 0, // indices
.inputs_index = 0, // index into inputs_list
},
{
.count = 2, // triangles
.index_offset = 6, // indices
.inputs_index = 0, // index into inputs_list
},
{
.count = 2, // triangles
.index_offset = 12, // indices
.inputs_index = 0, // index into inputs_list
},
{
.count = 2, // triangles
.index_offset = 18, // indices
.inputs_index = 0, // index into inputs_list
},
{
.count = 2, // triangles
.index_offset = 24, // indices
.inputs_index = 0, // index into inputs_list
},
{
.count = 2, // triangles
.index_offset = 30, // indices
.inputs_index = 0, // index into inputs_list
},
};
geometry const geometry_geom_cube = {
.mesh = {
.triangles = triangles_geom_cube,
.triangles_count = 6,
.vertex_buffer_offset = 0,
.vertex_buffer_size = 864,
.index_buffer_offset = 0,
.index_buffer_size = 144,
}
};
triangles const triangles_geom_cylinder001[] = {
{
.count = 30, // triangles
.index_offset = 0, // indices
.inputs_index = 0, // index into inputs_list
},
};
geometry const geometry_geom_cylinder001 = {
.mesh = {
.triangles = triangles_geom_cylinder001,
.triangles_count = 1,
.vertex_buffer_offset = 864,
.vertex_buffer_size = 1152,
.index_buffer_offset = 144,
.index_buffer_size = 360,
}
};
triangles const triangles_geom_plane001[] = {
{
.count = 2, // triangles
.index_offset = 0, // indices
.inputs_index = 0, // index into inputs_list
},
};
geometry const geometry_geom_plane001 = {
.mesh = {
.triangles = triangles_geom_plane001,
.triangles_count = 1,
.vertex_buffer_offset = 2016,
.vertex_buffer_size = 144,
.index_buffer_offset = 504,
.index_buffer_size = 24,
}
};
geometry const * const geometries[] = {
&geometry_geom_cube,
&geometry_geom_cylinder001,
&geometry_geom_plane001,
};
transform const transforms_node_environmentambientlight[] = {
};
instance_geometry const instance_geometries_node_environmentambientlight[] = {
};
node const node_node_environmentambientlight = {
.type = node_type::NODE,
.transforms = transforms_node_environmentambientlight,
.transforms_count = 0,
.instance_geometries = instance_geometries_node_environmentambientlight,
.instance_geometries_count = 0,
};
transform const transforms_node_cube[] = {
{
.type = transform_type::TRANSLATE,
.translate = {10.0f, 0.0f, 0.0f},
},
};
instance_material const instance_materials_node_cube_0[] = {
{
.element_index = 1, // an index into mesh.triangles
.material = &material_material__15_material,
},
{
.element_index = 5, // an index into mesh.triangles
.material = &material_material__17_material,
},
{
.element_index = 3, // an index into mesh.triangles
.material = &material_material__18_material,
},
{
.element_index = 2, // an index into mesh.triangles
.material = &material_material__19_material,
},
{
.element_index = 0, // an index into mesh.triangles
.material = &material_material__16_material,
},
{
.element_index = 4, // an index into mesh.triangles
.material = &material_material__20_material,
},
};
instance_geometry const instance_geometries_node_cube[] = {
{
.geometry = &geometry_geom_cube,
.instance_materials = instance_materials_node_cube_0,
.instance_materials_count = 6,
},
};
node const node_node_cube = {
.type = node_type::NODE,
.transforms = transforms_node_cube,
.transforms_count = 1,
.instance_geometries = instance_geometries_node_cube,
.instance_geometries_count = 1,
};
transform const transforms_node_cylinder001[] = {
};
instance_material const instance_materials_node_cylinder001_0[] = {
{
.element_index = 0, // an index into mesh.triangles
.material = &material_coloreffectr229g154b215_material,
},
};
instance_geometry const instance_geometries_node_cylinder001[] = {
{
.geometry = &geometry_geom_cylinder001,
.instance_materials = instance_materials_node_cylinder001_0,
.instance_materials_count = 1,
},
};
node const node_node_cylinder001 = {
.type = node_type::NODE,
.transforms = transforms_node_cylinder001,
.transforms_count = 0,
.instance_geometries = instance_geometries_node_cylinder001,
.instance_geometries_count = 1,
};
transform const transforms_node_plane001[] = {
{
.type = transform_type::TRANSLATE,
.translate = {0.0f, 0.0f, 0.01f},
},
{
.type = transform_type::ROTATE,
.rotate = {0.0f, 0.0f, -1.0f, -44.99999f},
},
};
instance_material const instance_materials_node_plane001_0[] = {
{
.element_index = 0, // an index into mesh.triangles
.material = &material_coloreffectr28g149b177_material,
},
};
instance_geometry const instance_geometries_node_plane001[] = {
{
.geometry = &geometry_geom_plane001,
.instance_materials = instance_materials_node_plane001_0,
.instance_materials_count = 1,
},
};
node const node_node_plane001 = {
.type = node_type::NODE,
.transforms = transforms_node_plane001,
.transforms_count = 2,
.instance_geometries = instance_geometries_node_plane001,
.instance_geometries_count = 1,
};
node const * const nodes[] = {
&node_node_environmentambientlight,
&node_node_cube,
&node_node_cylinder001,
&node_node_plane001,
};
inputs const inputs_list[] = {
{
.elements = input_elements_position_0_3_normal_0_3_texcoord_0_3,
.elements_count = 3,
},
};
descriptor const descriptor = {
.nodes = nodes,
.nodes_count = (sizeof (nodes)) / (sizeof (nodes[0])),
.inputs_list = inputs_list,
.inputs_list_count = (sizeof (inputs_list)) / (sizeof (inputs_list[0])),
};
}

View File

@ -7,4 +7,8 @@ RES_PERLIN RCDATA "texture/perlin.data"
RES_ROBOT_PLAYER RCDATA "models/robot_player/robot_player.data" RES_ROBOT_PLAYER RCDATA "models/robot_player/robot_player.data"
RES_FONT_TERMINUS_6X12 RCDATA "font/terminus_128x64_6x12.data" RES_FONT_TERMINUS_6X12 RCDATA "font/terminus_128x64_6x12.data"
RES_COLLADA_FXO RCDATA "collada.fxo" RES_COLLADA_FXO RCDATA "collada.fxo"
RES_COLLADA_SCENE_FXO RCDATA "collada_scene.fxo"
RES_MODELS_CURVE_INTERPOLATION_VTX RCDATA "models/curve_interpolation/curve_interpolation.vtx"
RES_MODELS_CURVE_INTERPOLATION_IDX RCDATA "models/curve_interpolation/curve_interpolation.idx"

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@ -313,14 +313,25 @@ namespace collada {
//XMConvertToRadians //XMConvertToRadians
XMVECTOR axis = XMVectorSet(0, 1, 0, 0); XMVECTOR axis = XMVectorSet(0, 1, 0, 0);
XMVECTOR axisZ = XMVectorSet(0, 0, 1, 0); XMVECTOR axisZ = XMVectorSet(0, 0, 1, 0);
XMMATRIX joint0 XMMATRIX joint0 = XMMatrixScaling(1, 1, 1);
= XMMatrixRotationNormal(axis, XMConvertToRadians(-90)) joint0 = XMMatrixTranslation(10, 0, 0) * joint0;
; joint0 = XMMatrixRotationNormal(axis, XMConvertToRadians(-90)) * joint0;
XMMATRIX joint1
= XMMatrixRotationNormal(axisZ, sin(t)) XMMATRIX joint1 = XMMatrixScaling(1, 1, 1);
* XMMatrixTranslation(10, 0, 0)
* joint0 /*
joint1 = joint1 * XMMatrixRotationNormal(axisZ, sin(t));
joint1 = joint1 * XMMatrixTranslation(10, 0, 0);
joint1 = joint1 * joint0;
*/
joint1 = joint0 * joint1;
joint1 = XMMatrixTranslation(10, 0, 0) * joint1;
joint1 = XMMatrixRotationNormal(axisZ, sin(t)) * joint1;
/*
= XMMatrixRotationNormal(axisZ, sin(t)) * XMMatrixTranslation(10, 0, 0) * joint0
; ;
*/
XMMATRIX joint0ibm = XMLoadFloat4x4((XMFLOAT4X4*)&inverse_bind_matrices[0 * 16]); XMMATRIX joint0ibm = XMLoadFloat4x4((XMFLOAT4X4*)&inverse_bind_matrices[0 * 16]);
XMMATRIX joint1ibm = XMLoadFloat4x4((XMFLOAT4X4*)&inverse_bind_matrices[1 * 16]); XMMATRIX joint1ibm = XMLoadFloat4x4((XMFLOAT4X4*)&inverse_bind_matrices[1 * 16]);

285
src/collada_scene.cpp Normal file
View File

@ -0,0 +1,285 @@
#include <windows.h>
#include <d3d10.h>
#include <assert.h>
#include "directxmath/directxmath.h"
#include "print.hpp"
#include "collada_scene.hpp"
extern ID3D10Device * g_pd3dDevice;
extern XMMATRIX g_View;
extern XMMATRIX g_Projection;
namespace collada_scene {
using namespace collada;
ID3D10Effect * g_pEffect = NULL;
ID3D10EffectTechnique * g_pTechniqueBlinn = NULL;
ID3D10EffectMatrixVariable * g_pWorldVariable = NULL;
ID3D10EffectMatrixVariable * g_pViewVariable = NULL;
ID3D10EffectMatrixVariable * g_pProjectionVariable = NULL;
static inline DXGI_FORMAT dxgi_format(input_format format)
{
switch (format) {
case input_format::FLOAT1: return DXGI_FORMAT_R32_FLOAT;
case input_format::FLOAT2: return DXGI_FORMAT_R32G32_FLOAT;
case input_format::FLOAT3: return DXGI_FORMAT_R32G32B32_FLOAT;
case input_format::FLOAT4: return DXGI_FORMAT_R32G32B32A32_FLOAT;
default:
assert(false);
}
}
static inline int format_size(input_format format)
{
switch (format) {
case input_format::FLOAT1: return 1 * 4;
case input_format::FLOAT2: return 2 * 4;
case input_format::FLOAT3: return 3 * 4;
case input_format::FLOAT4: return 4 * 4;
default:
assert(false);
}
}
HRESULT scene_state::load_vertex_buffer(LPCWSTR name)
{
HRESULT hr;
HRSRC hRes = FindResource(NULL, name, RT_RCDATA);
if (hRes == NULL) {
printW(L"FindResource %s\n", name);
return E_FAIL;
}
DWORD dwResSize = SizeofResource(NULL, hRes);
void * pData = LockResource(LoadResource(NULL, hRes));
D3D10_BUFFER_DESC bd;
D3D10_SUBRESOURCE_DATA initData;
bd.Usage = D3D10_USAGE_IMMUTABLE;
bd.ByteWidth = dwResSize;
bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
initData.pSysMem = pData;
hr = g_pd3dDevice->CreateBuffer(&bd, &initData, &pVertexBuffers[0]);
if (FAILED(hr)) {
print("CreateBuffer: D3D10_BIND_VERTEX_BUFFER\n");
return hr;
}
return S_OK;
}
HRESULT scene_state::load_index_buffer(LPCWSTR name)
{
HRESULT hr;
HRSRC hRes = FindResource(NULL, name, RT_RCDATA);
if (hRes == NULL) {
printW(L"FindResource %s\n", name);
return E_FAIL;
}
DWORD dwResSize = SizeofResource(NULL, hRes);
void * pData = LockResource(LoadResource(NULL, hRes));
D3D10_BUFFER_DESC bd;
D3D10_SUBRESOURCE_DATA initData;
bd.Usage = D3D10_USAGE_IMMUTABLE;
bd.ByteWidth = dwResSize;
bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
initData.pSysMem = pData;
hr = g_pd3dDevice->CreateBuffer(&bd, &initData, &pIndexBuffer);
if (FAILED(hr)) {
print("CreateBuffer: D3D10_BIND_VERTEX_BUFFER\n");
return hr;
}
return S_OK;
}
HRESULT scene_state::load_layout(int inputs_index, inputs const& inputs)
{
HRESULT hr;
D3D10_INPUT_ELEMENT_DESC layout[inputs.elements_count];
int byte_offset = 0;
for (int i = 0; i < inputs.elements_count; i++) {
layout[i].SemanticName = inputs.elements[i].semantic;
layout[i].SemanticIndex = inputs.elements[i].semantic_index;
layout[i].Format = dxgi_format(inputs.elements[i].format);
layout[i].InputSlot = 0;
layout[i].AlignedByteOffset = byte_offset;
layout[i].InputSlotClass = D3D10_INPUT_PER_VERTEX_DATA;
layout[i].InstanceDataStepRate = 0;
byte_offset += format_size(inputs.elements[i].format);
}
D3D10_PASS_DESC passDesc;
g_pTechniqueBlinn->GetPassByIndex(0)->GetDesc(&passDesc);
hr = g_pd3dDevice->CreateInputLayout(layout, inputs.elements_count,
passDesc.pIAInputSignature,
passDesc.IAInputSignatureSize,
&pVertexLayouts[inputs_index]);
if (FAILED(hr)) {
print("CreateInputLayout\n");
return hr;
}
return S_OK;
}
template <typename T>
T New(int elements)
{
return (T)malloc((sizeof (T)) * elements);
}
HRESULT scene_state::load_layouts(descriptor const& descriptor)
{
HRESULT hr;
//this->pVertexLayouts = new ID3D10InputLayout *[descriptor.inputs_list_count];
this->pVertexLayouts = New<ID3D10InputLayout **>(descriptor.inputs_list_count);
for (int i = 0; i < descriptor.inputs_list_count; i++) {
hr = load_layout(i, descriptor.inputs_list[i]);
if (FAILED(hr))
return hr;
}
return S_OK;
}
HRESULT LoadEffect()
{
HRESULT hr;
HRSRC hRes = FindResource(NULL, L"RES_COLLADA_SCENE_FXO", RT_RCDATA);
if (hRes == NULL) {
print("FindResource RES_COLLADA_SCENE_FXO\n");
return E_FAIL;
}
DWORD dwResSize = SizeofResource(NULL, hRes);
HGLOBAL hData = LoadResource(NULL, hRes);
void * pData = LockResource(hData);
hr = D3D10CreateEffectFromMemory(pData,
dwResSize,
0,
g_pd3dDevice,
NULL,
&g_pEffect
);
if (FAILED(hr)) {
print("D3D10CreateEffectFromMemory\n");
return hr;
}
g_pTechniqueBlinn = g_pEffect->GetTechniqueByName("Blinn");
g_pWorldVariable = g_pEffect->GetVariableByName("World")->AsMatrix();
g_pViewVariable = g_pEffect->GetVariableByName("View")->AsMatrix();
g_pProjectionVariable = g_pEffect->GetVariableByName("Projection")->AsMatrix();
return S_OK;
}
HRESULT LoadScene(descriptor const& descriptor, scene_state& state)
{
HRESULT hr;
// effects/techniques
hr = LoadEffect();
if (FAILED(hr))
return E_FAIL;
// layouts
hr = state.load_layouts(descriptor);
if (FAILED(hr))
return E_FAIL;
hr = state.load_vertex_buffer(L"RES_MODELS_CURVE_INTERPOLATION_VTX");
if (FAILED(hr))
return E_FAIL;
hr = state.load_index_buffer(L"RES_MODELS_CURVE_INTERPOLATION_IDX");
if (FAILED(hr))
return E_FAIL;
return S_OK;
}
static inline XMMATRIX transform_matrix(transform const& transform)
{
switch (transform.type) {
case transform_type::TRANSLATE:
return XMMatrixTranslationFromVector(XMLoadFloat3((XMFLOAT3 *)&transform.translate.x));
case transform_type::ROTATE:
return XMMatrixRotationNormal(XMLoadFloat3((XMFLOAT3 *)&transform.rotate.x),
XMConvertToRadians(transform.rotate.w));
case transform_type::SCALE:
return XMMatrixScalingFromVector(XMLoadFloat3((XMFLOAT3 *)&transform.scale.x));
default:
assert(false);
break;
}
}
void RenderGeometries(scene_state const& state,
instance_geometry const * const instance_geometries,
int const instance_geometries_count)
{
for (int i = 0; i < instance_geometries_count; i++) {
instance_geometry const &instance_geometry = instance_geometries[i];
mesh const& mesh = instance_geometry.geometry->mesh;
UINT strides[1] = { 3 * 3 * 4 };
UINT offsets[1] = { (UINT)mesh.vertex_buffer_offset };
g_pd3dDevice->IASetVertexBuffers(0, state.numBuffers, state.pVertexBuffers, strides, offsets);
g_pd3dDevice->IASetIndexBuffer(state.pIndexBuffer, DXGI_FORMAT_R32_UINT, mesh.index_buffer_offset);
D3D10_TECHNIQUE_DESC techDesc;
g_pTechniqueBlinn->GetDesc(&techDesc);
for (int j = 0; j < mesh.triangles_count; j++) {
triangles const& triangles = mesh.triangles[j];
g_pTechniqueBlinn->GetPassByIndex(0)->Apply(0);
g_pd3dDevice->IASetInputLayout(state.pVertexLayouts[triangles.inputs_index]);
g_pd3dDevice->DrawIndexed(triangles.count * 3, triangles.index_offset, 0);
}
}
}
void Render(descriptor const& descriptor, scene_state const& state)
{
g_pViewVariable->SetMatrix((float *)&g_View);
g_pProjectionVariable->SetMatrix((float *)&g_Projection);
g_pd3dDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
for (int i = 0; i < descriptor.nodes_count; i++) {
node const& node = *descriptor.nodes[i];
if (node.type != node_type::NODE)
continue;
XMMATRIX World = XMMatrixIdentity();
// build the world transform
for (int j = 0; j < node.transforms_count; j++) {
transform const& transform = node.transforms[j];
World = transform_matrix(transform) * World;
}
g_pWorldVariable->SetMatrix((float *)&World);
RenderGeometries(state, node.instance_geometries, node.instance_geometries_count);
}
}
}

View File

@ -0,0 +1,67 @@
cbuffer cbEveryFrame
{
matrix View;
matrix Projection;
};
cbuffer cbMultiplePerFrame
{
matrix World;
};
struct VS_INPUT
{
float3 Pos : POSITION;
float3 Norm : NORMAL;
float2 Tex : TEXCOORD0;
};
struct PS_INPUT
{
float4 Pos : SV_POSITION;
float3 Norm : NORMAL;
float2 Tex : TEXCOORD0;
};
PS_INPUT VS(VS_INPUT input)
{
PS_INPUT output;
output.Pos = mul(float4(input.Pos, 1), World);
output.Pos = mul(output.Pos, View);
output.Pos = mul(output.Pos, Projection);
output.Norm = mul(input.Norm, (float3x3)World);
output.Tex = input.Tex;
return output;
}
float4 PS(PS_INPUT input) : SV_Target
{
//return float4(input.Normal * 0.5 + 0.5, 1);
return float4(input.Tex.xy, 0, 1);
}
BlendState DisableBlending
{
BlendEnable[0] = FALSE;
};
DepthStencilState EnableDepth
{
DepthEnable = TRUE;
DepthWriteMask = ALL;
};
technique10 Blinn
{
pass P0
{
SetVertexShader(CompileShader(vs_4_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_4_0, PS()));
SetBlendState(DisableBlending, float4(0.0, 0.0, 0.0, 0.0), 0xffffffff);
SetDepthStencilState(EnableDepth, 0);
}
}

View File

@ -18,6 +18,9 @@
#include "cube.hpp" #include "cube.hpp"
#include "collada.hpp" #include "collada.hpp"
#include "collada_scene.hpp"
#include "scenes/curve_interpolation.hpp"
HINSTANCE g_hInstance = NULL; HINSTANCE g_hInstance = NULL;
HWND g_hWnd = NULL; HWND g_hWnd = NULL;
@ -129,6 +132,10 @@ XMFLOAT4 g_vLightColors[2] = {
XMVECTOR g_Eye = XMVectorSet(0.0f, -30.0f, 15.0f, 1.0f); XMVECTOR g_Eye = XMVectorSet(0.0f, -30.0f, 15.0f, 1.0f);
XMVECTOR g_At = XMVectorSet(0.0f, 0.0f, 15.0f, 1.0f); XMVECTOR g_At = XMVectorSet(0.0f, 0.0f, 15.0f, 1.0f);
// collada scene state
collada_scene::scene_state g_SceneState;
// forward declarations // forward declarations
HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow); HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow);
@ -197,6 +204,11 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLi
return 0; return 0;
} }
if (FAILED(collada_scene::LoadScene(curve_interpolation::descriptor, g_SceneState))) {
print("collada::LoadScene\n");
return 0;
}
InitializeNodeInstances(); InitializeNodeInstances();
if (FAILED(InitInput(hInstance))) { if (FAILED(InitInput(hInstance))) {
@ -1827,7 +1839,9 @@ void Render(float t, float dt)
RenderFont(dt); RenderFont(dt);
collada::Render(t); //collada::Render(t);
collada_scene::Render(curve_interpolation::descriptor, g_SceneState);
// present // present
g_pSwapChain->Present(0, 0); g_pSwapChain->Present(0, 0);