collada: draw ship20 (untextured)
This commit is contained in:
parent
7f01fd0483
commit
829cea09ba
8
Makefile
8
Makefile
@ -2,7 +2,7 @@
|
|||||||
CC=$(PREFIX)gcc
|
CC=$(PREFIX)gcc
|
||||||
CXX=$(PREFIX)g++
|
CXX=$(PREFIX)g++
|
||||||
|
|
||||||
OPT = -O2 -march=x86-64-v3
|
OPT = -O0 -march=x86-64-v3
|
||||||
|
|
||||||
CSTD = -std=gnu23
|
CSTD = -std=gnu23
|
||||||
CXXSTD = -std=gnu++23
|
CXXSTD = -std=gnu++23
|
||||||
@ -35,7 +35,11 @@ OBJS = \
|
|||||||
src/collision_scene.o \
|
src/collision_scene.o \
|
||||||
src/line_art.o \
|
src/line_art.o \
|
||||||
src/boids.o \
|
src/boids.o \
|
||||||
src/boids_scene.o
|
src/boids_scene.o \
|
||||||
|
src/collada/scene.o \
|
||||||
|
src/collada/effect.o \
|
||||||
|
src/collada/node_state.o \
|
||||||
|
data/scenes/ship20/ship20.o
|
||||||
|
|
||||||
all: test.so
|
all: test.so
|
||||||
|
|
||||||
|
|||||||
427
data/scenes/ship20.cpp
Normal file
427
data/scenes/ship20.cpp
Normal file
@ -0,0 +1,427 @@
|
|||||||
|
#include "collada/types.h"
|
||||||
|
|
||||||
|
namespace ship20 {
|
||||||
|
|
||||||
|
using namespace collada::types;
|
||||||
|
|
||||||
|
light const light_environmentambientlight = {
|
||||||
|
.type = light_type::AMBIENT,
|
||||||
|
.color = { 0.0f, 0.0f, 0.0f },
|
||||||
|
};
|
||||||
|
|
||||||
|
light const light_omni002_light = {
|
||||||
|
.type = light_type::POINT,
|
||||||
|
.color = { 1.0f, 1.0f, 1.0f },
|
||||||
|
};
|
||||||
|
|
||||||
|
light const light_omni003_light = {
|
||||||
|
.type = light_type::POINT,
|
||||||
|
.color = { 1.0f, 1.0f, 1.0f },
|
||||||
|
};
|
||||||
|
|
||||||
|
// shipple2_png
|
||||||
|
image const image_shipple2_png = {
|
||||||
|
.resource_name = "_0_SHIPPLE2_PNG",
|
||||||
|
};
|
||||||
|
|
||||||
|
image const * const images[] = {
|
||||||
|
&image_shipple2_png,
|
||||||
|
};
|
||||||
|
|
||||||
|
effect const effect_diffusetexture = {
|
||||||
|
.type = effect_type::BLINN,
|
||||||
|
.blinn = {
|
||||||
|
.emission = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.0f, 0.0f, 0.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.ambient = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.588f, 0.588f, 0.588f, 1.0f},
|
||||||
|
},
|
||||||
|
.diffuse = {
|
||||||
|
.type = color_or_texture_type::TEXTURE,
|
||||||
|
.texture = { .image_index = 0 }, // shipple2_png
|
||||||
|
},
|
||||||
|
.specular = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.5f, 0.5f, 0.5f, 1.0f},
|
||||||
|
},
|
||||||
|
.shininess = 10.0f,
|
||||||
|
.reflective = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.0f, 0.0f, 0.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.reflectivity = 0.0f,
|
||||||
|
.transparent = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {1.0f, 1.0f, 1.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.transparency = 1.0f,
|
||||||
|
.index_of_refraction = 0.0f,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
effect const effect_cyanengine = {
|
||||||
|
.type = effect_type::BLINN,
|
||||||
|
.blinn = {
|
||||||
|
.emission = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.0f, 0.9647059f, 1.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.ambient = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.0f, 0.0f, 0.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.diffuse = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.0f, 0.0f, 0.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.specular = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.0f, 0.0f, 0.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.shininess = 10.0f,
|
||||||
|
.reflective = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.0f, 0.0f, 0.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.reflectivity = 0.0f,
|
||||||
|
.transparent = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {1.0f, 1.0f, 1.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.transparency = 1.0f,
|
||||||
|
.index_of_refraction = 0.0f,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
effect const effect_emissivetexture = {
|
||||||
|
.type = effect_type::BLINN,
|
||||||
|
.blinn = {
|
||||||
|
.emission = {
|
||||||
|
.type = color_or_texture_type::TEXTURE,
|
||||||
|
.texture = { .image_index = 0 }, // shipple2_png
|
||||||
|
},
|
||||||
|
.ambient = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.588f, 0.588f, 0.588f, 1.0f},
|
||||||
|
},
|
||||||
|
.diffuse = {
|
||||||
|
.type = color_or_texture_type::TEXTURE,
|
||||||
|
.texture = { .image_index = 0 }, // shipple2_png
|
||||||
|
},
|
||||||
|
.specular = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.0f, 0.0f, 0.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.shininess = 10.0f,
|
||||||
|
.reflective = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.0f, 0.0f, 0.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.reflectivity = 0.0f,
|
||||||
|
.transparent = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {1.0f, 1.0f, 1.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.transparency = 1.0f,
|
||||||
|
.index_of_refraction = 0.0f,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
material const material_diffusetexture_material = {
|
||||||
|
.effect = &effect_diffusetexture,
|
||||||
|
};
|
||||||
|
|
||||||
|
material const material_cyanengine_material = {
|
||||||
|
.effect = &effect_cyanengine,
|
||||||
|
};
|
||||||
|
|
||||||
|
material const material_emissivetexture_material = {
|
||||||
|
.effect = &effect_emissivetexture,
|
||||||
|
};
|
||||||
|
|
||||||
|
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_ship[] = {
|
||||||
|
{
|
||||||
|
.count = 2949, // triangles
|
||||||
|
.index_offset = 0, // indices
|
||||||
|
.inputs_index = 0, // index into inputs_list
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.count = 60, // triangles
|
||||||
|
.index_offset = 8847, // indices
|
||||||
|
.inputs_index = 0, // index into inputs_list
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.count = 239, // triangles
|
||||||
|
.index_offset = 9027, // indices
|
||||||
|
.inputs_index = 0, // index into inputs_list
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
geometry const geometry_geom_ship = {
|
||||||
|
.mesh = {
|
||||||
|
.triangles = triangles_geom_ship,
|
||||||
|
.triangles_count = 3,
|
||||||
|
|
||||||
|
.vertex_buffer_offset = 0,
|
||||||
|
.vertex_buffer_size = 133272,
|
||||||
|
|
||||||
|
.index_buffer_offset = 0,
|
||||||
|
.index_buffer_size = 38976,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
geometry const * const geometries[] = {
|
||||||
|
&geometry_geom_ship,
|
||||||
|
};
|
||||||
|
|
||||||
|
transform const transforms_node_environmentambientlight[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_geometry const instance_geometries_node_environmentambientlight[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_controller const instance_controllers_node_environmentambientlight[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_light const instance_lights_node_environmentambientlight[] = {
|
||||||
|
{
|
||||||
|
.light = &light_environmentambientlight,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
channel const * const node_channels_node_environmentambientlight[] = {};
|
||||||
|
|
||||||
|
node const node_node_environmentambientlight = {
|
||||||
|
.parent_index = -1,
|
||||||
|
|
||||||
|
.type = node_type::NODE,
|
||||||
|
|
||||||
|
.transforms = transforms_node_environmentambientlight,
|
||||||
|
.transforms_count = 0,
|
||||||
|
|
||||||
|
.instance_geometries = instance_geometries_node_environmentambientlight,
|
||||||
|
.instance_geometries_count = 0,
|
||||||
|
|
||||||
|
.instance_controllers = instance_controllers_node_environmentambientlight,
|
||||||
|
.instance_controllers_count = 0,
|
||||||
|
|
||||||
|
.instance_lights = instance_lights_node_environmentambientlight,
|
||||||
|
.instance_lights_count = 1,
|
||||||
|
|
||||||
|
.channels = node_channels_node_environmentambientlight,
|
||||||
|
.channels_count = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
transform const transforms_node_ship[] = {
|
||||||
|
{
|
||||||
|
.type = transform_type::ROTATE,
|
||||||
|
.rotate = {0.0f, 0.0f, 1.0f, -180.0f},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_material const instance_geometry_instance_materials_node_ship_0[] = {
|
||||||
|
{
|
||||||
|
.element_index = 1, // an index into mesh.triangles
|
||||||
|
.material = &material_cyanengine_material,
|
||||||
|
|
||||||
|
.emission = { .input_set = -1 },
|
||||||
|
.ambient = { .input_set = -1 },
|
||||||
|
.diffuse = { .input_set = -1 },
|
||||||
|
.specular = { .input_set = -1 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.element_index = 0, // an index into mesh.triangles
|
||||||
|
.material = &material_diffusetexture_material,
|
||||||
|
|
||||||
|
.emission = { .input_set = -1 },
|
||||||
|
.ambient = { .input_set = -1 },
|
||||||
|
.diffuse = { .input_set = 0 },
|
||||||
|
.specular = { .input_set = -1 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.element_index = 2, // an index into mesh.triangles
|
||||||
|
.material = &material_emissivetexture_material,
|
||||||
|
|
||||||
|
.emission = { .input_set = 0 },
|
||||||
|
.ambient = { .input_set = -1 },
|
||||||
|
.diffuse = { .input_set = 0 },
|
||||||
|
.specular = { .input_set = -1 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_geometry const instance_geometries_node_ship[] = {
|
||||||
|
{
|
||||||
|
.geometry = &geometry_geom_ship,
|
||||||
|
|
||||||
|
.instance_materials = instance_geometry_instance_materials_node_ship_0,
|
||||||
|
.instance_materials_count = 3,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_controller const instance_controllers_node_ship[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_light const instance_lights_node_ship[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
channel const * const node_channels_node_ship[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
node const node_node_ship = {
|
||||||
|
.parent_index = -1,
|
||||||
|
|
||||||
|
.type = node_type::NODE,
|
||||||
|
|
||||||
|
.transforms = transforms_node_ship,
|
||||||
|
.transforms_count = 1,
|
||||||
|
|
||||||
|
.instance_geometries = instance_geometries_node_ship,
|
||||||
|
.instance_geometries_count = 1,
|
||||||
|
|
||||||
|
.instance_controllers = instance_controllers_node_ship,
|
||||||
|
.instance_controllers_count = 0,
|
||||||
|
|
||||||
|
.instance_lights = instance_lights_node_ship,
|
||||||
|
.instance_lights_count = 0,
|
||||||
|
|
||||||
|
.channels = node_channels_node_ship,
|
||||||
|
.channels_count = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
transform const transforms_node_omni002[] = {
|
||||||
|
{
|
||||||
|
.type = transform_type::TRANSLATE,
|
||||||
|
.translate = {-286.5521f, 395.7583f, 161.5579f},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_geometry const instance_geometries_node_omni002[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_controller const instance_controllers_node_omni002[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_light const instance_lights_node_omni002[] = {
|
||||||
|
{
|
||||||
|
.light = &light_omni002_light,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
channel const * const node_channels_node_omni002[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
node const node_node_omni002 = {
|
||||||
|
.parent_index = -1,
|
||||||
|
|
||||||
|
.type = node_type::NODE,
|
||||||
|
|
||||||
|
.transforms = transforms_node_omni002,
|
||||||
|
.transforms_count = 1,
|
||||||
|
|
||||||
|
.instance_geometries = instance_geometries_node_omni002,
|
||||||
|
.instance_geometries_count = 0,
|
||||||
|
|
||||||
|
.instance_controllers = instance_controllers_node_omni002,
|
||||||
|
.instance_controllers_count = 0,
|
||||||
|
|
||||||
|
.instance_lights = instance_lights_node_omni002,
|
||||||
|
.instance_lights_count = 1,
|
||||||
|
|
||||||
|
.channels = node_channels_node_omni002,
|
||||||
|
.channels_count = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
transform const transforms_node_omni003[] = {
|
||||||
|
{
|
||||||
|
.type = transform_type::TRANSLATE,
|
||||||
|
.translate = {333.2103f, -314.4593f, 161.5578f},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_geometry const instance_geometries_node_omni003[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_controller const instance_controllers_node_omni003[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_light const instance_lights_node_omni003[] = {
|
||||||
|
{
|
||||||
|
.light = &light_omni003_light,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
channel const * const node_channels_node_omni003[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
node const node_node_omni003 = {
|
||||||
|
.parent_index = -1,
|
||||||
|
|
||||||
|
.type = node_type::NODE,
|
||||||
|
|
||||||
|
.transforms = transforms_node_omni003,
|
||||||
|
.transforms_count = 1,
|
||||||
|
|
||||||
|
.instance_geometries = instance_geometries_node_omni003,
|
||||||
|
.instance_geometries_count = 0,
|
||||||
|
|
||||||
|
.instance_controllers = instance_controllers_node_omni003,
|
||||||
|
.instance_controllers_count = 0,
|
||||||
|
|
||||||
|
.instance_lights = instance_lights_node_omni003,
|
||||||
|
.instance_lights_count = 1,
|
||||||
|
|
||||||
|
.channels = node_channels_node_omni003,
|
||||||
|
.channels_count = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
node const * const nodes[] = {
|
||||||
|
&node_node_environmentambientlight, // 0
|
||||||
|
&node_node_ship, // 1
|
||||||
|
&node_node_omni002, // 2
|
||||||
|
&node_node_omni003, // 3
|
||||||
|
};
|
||||||
|
|
||||||
|
inputs const inputs_list[] = {
|
||||||
|
{
|
||||||
|
.elements = input_elements_position_0_3_normal_0_3_texcoord_0_3,
|
||||||
|
.elements_count = 3,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
types::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])),
|
||||||
|
|
||||||
|
.images = images,
|
||||||
|
.images_count = (sizeof (images)) / (sizeof (images[0])),
|
||||||
|
|
||||||
|
.position_normal_texture_buffer = "RES_SCENES_SHIP20_VTX",
|
||||||
|
.joint_weight_buffer = "RES_SCENES_SHIP20_VJW",
|
||||||
|
.index_buffer = "RES_SCENES_SHIP20_IDX",
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
429
data/scenes/ship20/ship20.cpp
Normal file
429
data/scenes/ship20/ship20.cpp
Normal file
@ -0,0 +1,429 @@
|
|||||||
|
#include "collada/types.h"
|
||||||
|
|
||||||
|
#include "data/scenes/ship20.h"
|
||||||
|
|
||||||
|
namespace ship20 {
|
||||||
|
|
||||||
|
using namespace collada::types;
|
||||||
|
|
||||||
|
light const light_environmentambientlight = {
|
||||||
|
.type = light_type::AMBIENT,
|
||||||
|
.color = { 0.0f, 0.0f, 0.0f },
|
||||||
|
};
|
||||||
|
|
||||||
|
light const light_omni002_light = {
|
||||||
|
.type = light_type::POINT,
|
||||||
|
.color = { 1.0f, 1.0f, 1.0f },
|
||||||
|
};
|
||||||
|
|
||||||
|
light const light_omni003_light = {
|
||||||
|
.type = light_type::POINT,
|
||||||
|
.color = { 1.0f, 1.0f, 1.0f },
|
||||||
|
};
|
||||||
|
|
||||||
|
// shipple2_png
|
||||||
|
image const image_shipple2_png = {
|
||||||
|
.resource_name = "_0_SHIPPLE2_PNG",
|
||||||
|
};
|
||||||
|
|
||||||
|
image const * const images[] = {
|
||||||
|
&image_shipple2_png,
|
||||||
|
};
|
||||||
|
|
||||||
|
effect const effect_diffusetexture = {
|
||||||
|
.type = effect_type::BLINN,
|
||||||
|
.blinn = {
|
||||||
|
.emission = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.0f, 0.0f, 0.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.ambient = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.588f, 0.588f, 0.588f, 1.0f},
|
||||||
|
},
|
||||||
|
.diffuse = {
|
||||||
|
.type = color_or_texture_type::TEXTURE,
|
||||||
|
.texture = { .image_index = 0 }, // shipple2_png
|
||||||
|
},
|
||||||
|
.specular = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.5f, 0.5f, 0.5f, 1.0f},
|
||||||
|
},
|
||||||
|
.shininess = 10.0f,
|
||||||
|
.reflective = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.0f, 0.0f, 0.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.reflectivity = 0.0f,
|
||||||
|
.transparent = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {1.0f, 1.0f, 1.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.transparency = 1.0f,
|
||||||
|
.index_of_refraction = 0.0f,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
effect const effect_cyanengine = {
|
||||||
|
.type = effect_type::BLINN,
|
||||||
|
.blinn = {
|
||||||
|
.emission = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.0f, 0.9647059f, 1.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.ambient = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.0f, 0.0f, 0.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.diffuse = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.0f, 0.0f, 0.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.specular = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.0f, 0.0f, 0.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.shininess = 10.0f,
|
||||||
|
.reflective = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.0f, 0.0f, 0.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.reflectivity = 0.0f,
|
||||||
|
.transparent = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {1.0f, 1.0f, 1.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.transparency = 1.0f,
|
||||||
|
.index_of_refraction = 0.0f,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
effect const effect_emissivetexture = {
|
||||||
|
.type = effect_type::BLINN,
|
||||||
|
.blinn = {
|
||||||
|
.emission = {
|
||||||
|
.type = color_or_texture_type::TEXTURE,
|
||||||
|
.texture = { .image_index = 0 }, // shipple2_png
|
||||||
|
},
|
||||||
|
.ambient = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.588f, 0.588f, 0.588f, 1.0f},
|
||||||
|
},
|
||||||
|
.diffuse = {
|
||||||
|
.type = color_or_texture_type::TEXTURE,
|
||||||
|
.texture = { .image_index = 0 }, // shipple2_png
|
||||||
|
},
|
||||||
|
.specular = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.0f, 0.0f, 0.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.shininess = 10.0f,
|
||||||
|
.reflective = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {0.0f, 0.0f, 0.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.reflectivity = 0.0f,
|
||||||
|
.transparent = {
|
||||||
|
.type = color_or_texture_type::COLOR,
|
||||||
|
.color = {1.0f, 1.0f, 1.0f, 1.0f},
|
||||||
|
},
|
||||||
|
.transparency = 1.0f,
|
||||||
|
.index_of_refraction = 0.0f,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
material const material_diffusetexture_material = {
|
||||||
|
.effect = &effect_diffusetexture,
|
||||||
|
};
|
||||||
|
|
||||||
|
material const material_cyanengine_material = {
|
||||||
|
.effect = &effect_cyanengine,
|
||||||
|
};
|
||||||
|
|
||||||
|
material const material_emissivetexture_material = {
|
||||||
|
.effect = &effect_emissivetexture,
|
||||||
|
};
|
||||||
|
|
||||||
|
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_ship[] = {
|
||||||
|
{
|
||||||
|
.count = 2949, // triangles
|
||||||
|
.index_offset = 0, // indices
|
||||||
|
.inputs_index = 0, // index into inputs_list
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.count = 60, // triangles
|
||||||
|
.index_offset = 8847, // indices
|
||||||
|
.inputs_index = 0, // index into inputs_list
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.count = 239, // triangles
|
||||||
|
.index_offset = 9027, // indices
|
||||||
|
.inputs_index = 0, // index into inputs_list
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
geometry const geometry_geom_ship = {
|
||||||
|
.mesh = {
|
||||||
|
.triangles = triangles_geom_ship,
|
||||||
|
.triangles_count = 3,
|
||||||
|
|
||||||
|
.vertex_buffer_offset = 0,
|
||||||
|
.vertex_buffer_size = 133272,
|
||||||
|
|
||||||
|
.index_buffer_offset = 0,
|
||||||
|
.index_buffer_size = 38976,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
geometry const * const geometries[] = {
|
||||||
|
&geometry_geom_ship,
|
||||||
|
};
|
||||||
|
|
||||||
|
transform const transforms_node_environmentambientlight[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_geometry const instance_geometries_node_environmentambientlight[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_controller const instance_controllers_node_environmentambientlight[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_light const instance_lights_node_environmentambientlight[] = {
|
||||||
|
{
|
||||||
|
.light = &light_environmentambientlight,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
channel const * const node_channels_node_environmentambientlight[] = {};
|
||||||
|
|
||||||
|
node const node_node_environmentambientlight = {
|
||||||
|
.parent_index = -1,
|
||||||
|
|
||||||
|
.type = node_type::NODE,
|
||||||
|
|
||||||
|
.transforms = transforms_node_environmentambientlight,
|
||||||
|
.transforms_count = 0,
|
||||||
|
|
||||||
|
.instance_geometries = instance_geometries_node_environmentambientlight,
|
||||||
|
.instance_geometries_count = 0,
|
||||||
|
|
||||||
|
.instance_controllers = instance_controllers_node_environmentambientlight,
|
||||||
|
.instance_controllers_count = 0,
|
||||||
|
|
||||||
|
.instance_lights = instance_lights_node_environmentambientlight,
|
||||||
|
.instance_lights_count = 1,
|
||||||
|
|
||||||
|
.channels = node_channels_node_environmentambientlight,
|
||||||
|
.channels_count = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
transform const transforms_node_ship[] = {
|
||||||
|
{
|
||||||
|
.type = transform_type::ROTATE,
|
||||||
|
.rotate = {0.0f, 0.0f, 1.0f, -180.0f},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_material const instance_geometry_instance_materials_node_ship_0[] = {
|
||||||
|
{
|
||||||
|
.element_index = 1, // an index into mesh.triangles
|
||||||
|
.material = &material_cyanengine_material,
|
||||||
|
|
||||||
|
.emission = { .input_set = -1 },
|
||||||
|
.ambient = { .input_set = -1 },
|
||||||
|
.diffuse = { .input_set = -1 },
|
||||||
|
.specular = { .input_set = -1 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.element_index = 0, // an index into mesh.triangles
|
||||||
|
.material = &material_diffusetexture_material,
|
||||||
|
|
||||||
|
.emission = { .input_set = -1 },
|
||||||
|
.ambient = { .input_set = -1 },
|
||||||
|
.diffuse = { .input_set = 0 },
|
||||||
|
.specular = { .input_set = -1 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.element_index = 2, // an index into mesh.triangles
|
||||||
|
.material = &material_emissivetexture_material,
|
||||||
|
|
||||||
|
.emission = { .input_set = 0 },
|
||||||
|
.ambient = { .input_set = -1 },
|
||||||
|
.diffuse = { .input_set = 0 },
|
||||||
|
.specular = { .input_set = -1 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_geometry const instance_geometries_node_ship[] = {
|
||||||
|
{
|
||||||
|
.geometry = &geometry_geom_ship,
|
||||||
|
|
||||||
|
.instance_materials = instance_geometry_instance_materials_node_ship_0,
|
||||||
|
.instance_materials_count = 3,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_controller const instance_controllers_node_ship[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_light const instance_lights_node_ship[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
channel const * const node_channels_node_ship[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
node const node_node_ship = {
|
||||||
|
.parent_index = -1,
|
||||||
|
|
||||||
|
.type = node_type::NODE,
|
||||||
|
|
||||||
|
.transforms = transforms_node_ship,
|
||||||
|
.transforms_count = 1,
|
||||||
|
|
||||||
|
.instance_geometries = instance_geometries_node_ship,
|
||||||
|
.instance_geometries_count = 1,
|
||||||
|
|
||||||
|
.instance_controllers = instance_controllers_node_ship,
|
||||||
|
.instance_controllers_count = 0,
|
||||||
|
|
||||||
|
.instance_lights = instance_lights_node_ship,
|
||||||
|
.instance_lights_count = 0,
|
||||||
|
|
||||||
|
.channels = node_channels_node_ship,
|
||||||
|
.channels_count = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
transform const transforms_node_omni002[] = {
|
||||||
|
{
|
||||||
|
.type = transform_type::TRANSLATE,
|
||||||
|
.translate = {-286.5521f, 395.7583f, 161.5579f},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_geometry const instance_geometries_node_omni002[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_controller const instance_controllers_node_omni002[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_light const instance_lights_node_omni002[] = {
|
||||||
|
{
|
||||||
|
.light = &light_omni002_light,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
channel const * const node_channels_node_omni002[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
node const node_node_omni002 = {
|
||||||
|
.parent_index = -1,
|
||||||
|
|
||||||
|
.type = node_type::NODE,
|
||||||
|
|
||||||
|
.transforms = transforms_node_omni002,
|
||||||
|
.transforms_count = 1,
|
||||||
|
|
||||||
|
.instance_geometries = instance_geometries_node_omni002,
|
||||||
|
.instance_geometries_count = 0,
|
||||||
|
|
||||||
|
.instance_controllers = instance_controllers_node_omni002,
|
||||||
|
.instance_controllers_count = 0,
|
||||||
|
|
||||||
|
.instance_lights = instance_lights_node_omni002,
|
||||||
|
.instance_lights_count = 1,
|
||||||
|
|
||||||
|
.channels = node_channels_node_omni002,
|
||||||
|
.channels_count = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
transform const transforms_node_omni003[] = {
|
||||||
|
{
|
||||||
|
.type = transform_type::TRANSLATE,
|
||||||
|
.translate = {333.2103f, -314.4593f, 161.5578f},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_geometry const instance_geometries_node_omni003[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_controller const instance_controllers_node_omni003[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
instance_light const instance_lights_node_omni003[] = {
|
||||||
|
{
|
||||||
|
.light = &light_omni003_light,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
channel const * const node_channels_node_omni003[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
node const node_node_omni003 = {
|
||||||
|
.parent_index = -1,
|
||||||
|
|
||||||
|
.type = node_type::NODE,
|
||||||
|
|
||||||
|
.transforms = transforms_node_omni003,
|
||||||
|
.transforms_count = 1,
|
||||||
|
|
||||||
|
.instance_geometries = instance_geometries_node_omni003,
|
||||||
|
.instance_geometries_count = 0,
|
||||||
|
|
||||||
|
.instance_controllers = instance_controllers_node_omni003,
|
||||||
|
.instance_controllers_count = 0,
|
||||||
|
|
||||||
|
.instance_lights = instance_lights_node_omni003,
|
||||||
|
.instance_lights_count = 1,
|
||||||
|
|
||||||
|
.channels = node_channels_node_omni003,
|
||||||
|
.channels_count = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
node const * const nodes[] = {
|
||||||
|
&node_node_environmentambientlight, // 0
|
||||||
|
&node_node_ship, // 1
|
||||||
|
&node_node_omni002, // 2
|
||||||
|
&node_node_omni003, // 3
|
||||||
|
};
|
||||||
|
|
||||||
|
inputs const inputs_list[] = {
|
||||||
|
{
|
||||||
|
.elements = input_elements_position_0_3_normal_0_3_texcoord_0_3,
|
||||||
|
.elements_count = 3,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
collada::types::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])),
|
||||||
|
|
||||||
|
.images = images,
|
||||||
|
.images_count = (sizeof (images)) / (sizeof (images[0])),
|
||||||
|
|
||||||
|
.position_normal_texture_buffer = "data/scenes/ship20/ship20.vtx",
|
||||||
|
.joint_weight_buffer = "data/scenes/ship20/ship20.vjw",
|
||||||
|
.index_buffer = "data/scenes/ship20/ship20.idx",
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
BIN
data/scenes/ship20/ship20.idx
Normal file
BIN
data/scenes/ship20/ship20.idx
Normal file
Binary file not shown.
0
data/scenes/ship20/ship20.vjw
Normal file
0
data/scenes/ship20/ship20.vjw
Normal file
BIN
data/scenes/ship20/ship20.vtx
Normal file
BIN
data/scenes/ship20/ship20.vtx
Normal file
Binary file not shown.
8
include/collada/effect.h
Normal file
8
include/collada/effect.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace collada::effect {
|
||||||
|
extern unsigned int program_static;
|
||||||
|
extern unsigned int program_skinned;
|
||||||
|
|
||||||
|
void load_effects();
|
||||||
|
}
|
||||||
28
include/collada/instance_types.h
Normal file
28
include/collada/instance_types.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "directxmath/directxmath.h"
|
||||||
|
|
||||||
|
#include "collada/types.h"
|
||||||
|
|
||||||
|
namespace collada::instance_types {
|
||||||
|
|
||||||
|
struct __attribute__((aligned(16))) lookat {
|
||||||
|
XMVECTOR eye;
|
||||||
|
XMVECTOR at;
|
||||||
|
XMVECTOR up;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct __attribute__((aligned(16))) transform {
|
||||||
|
union {
|
||||||
|
instance_types::lookat lookat;
|
||||||
|
XMMATRIX matrix;
|
||||||
|
XMVECTOR vector;
|
||||||
|
};
|
||||||
|
types::transform_type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct node_instance {
|
||||||
|
transform * transforms = NULL;
|
||||||
|
XMMATRIX world;
|
||||||
|
};
|
||||||
|
}
|
||||||
32
include/collada/scene.h
Normal file
32
include/collada/scene.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "collada/types.h"
|
||||||
|
|
||||||
|
namespace collada::scene {
|
||||||
|
struct static_skinned {
|
||||||
|
unsigned int static_mesh;
|
||||||
|
unsigned int skinned_mesh;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct state {
|
||||||
|
types::descriptor const * descriptor;
|
||||||
|
|
||||||
|
unsigned int vertex_buffer_pnt;
|
||||||
|
unsigned int vertex_buffer_jw;
|
||||||
|
unsigned int index_buffer;
|
||||||
|
|
||||||
|
static_skinned * vertex_arrays;
|
||||||
|
int * vertex_buffer_strides;
|
||||||
|
|
||||||
|
void load_layouts();
|
||||||
|
void load_scene(types::descriptor const * const descriptor);
|
||||||
|
|
||||||
|
void draw_geometry(types::geometry const & geometry,
|
||||||
|
types::instance_material const * const instance_materials,
|
||||||
|
int const instance_materials_count);
|
||||||
|
void draw_instance_geometries(types::instance_geometry const * const instance_geometries,
|
||||||
|
int const instance_geometries_count);
|
||||||
|
void draw_node(types::node const & node);
|
||||||
|
void draw();
|
||||||
|
};
|
||||||
|
}
|
||||||
407
include/collada/types.h
Normal file
407
include/collada/types.h
Normal file
@ -0,0 +1,407 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace collada::types {
|
||||||
|
|
||||||
|
struct float2 {
|
||||||
|
float const x;
|
||||||
|
float const y;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct float3 {
|
||||||
|
float const x;
|
||||||
|
float const y;
|
||||||
|
float const z;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct float4 {
|
||||||
|
float const x;
|
||||||
|
float const y;
|
||||||
|
float const z;
|
||||||
|
float const w;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct float7 {
|
||||||
|
float const a;
|
||||||
|
float const b;
|
||||||
|
float const c;
|
||||||
|
float const d;
|
||||||
|
float const e;
|
||||||
|
float const f;
|
||||||
|
float const g;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct matrix {
|
||||||
|
float const _11, _12, _13, _14;
|
||||||
|
float const _21, _22, _23, _24;
|
||||||
|
float const _31, _32, _33, _34;
|
||||||
|
float const _41, _42, _43, _44;
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// geometry
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
enum class input_format {
|
||||||
|
FLOAT1,
|
||||||
|
FLOAT2,
|
||||||
|
FLOAT3,
|
||||||
|
FLOAT4,
|
||||||
|
INT1,
|
||||||
|
INT2,
|
||||||
|
INT3,
|
||||||
|
INT4,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct input_element {
|
||||||
|
char const * const semantic;
|
||||||
|
int const semantic_index;
|
||||||
|
enum input_format const format;
|
||||||
|
};
|
||||||
|
|
||||||
|
// inputs uniqueness is by evaluted pointer
|
||||||
|
struct inputs {
|
||||||
|
input_element const * const elements;
|
||||||
|
int const elements_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct triangles {
|
||||||
|
int const count;
|
||||||
|
int const index_offset;
|
||||||
|
int const inputs_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mesh {
|
||||||
|
// `triangles` must become a union if non-triangles are implemented.
|
||||||
|
// instance_geometry is an index into this array.
|
||||||
|
types::triangles const * triangles;
|
||||||
|
int const triangles_count;
|
||||||
|
|
||||||
|
int const vertex_buffer_offset;
|
||||||
|
int const vertex_buffer_size;
|
||||||
|
|
||||||
|
int const index_buffer_offset;
|
||||||
|
int const index_buffer_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct geometry {
|
||||||
|
types::mesh mesh;
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// light
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
enum class light_type {
|
||||||
|
AMBIENT,
|
||||||
|
DIRECTIONAL,
|
||||||
|
POINT,
|
||||||
|
SPOT,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct light {
|
||||||
|
light_type type;
|
||||||
|
float3 color;
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// image
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct image {
|
||||||
|
const char * resource_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// effect
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
enum class color_or_texture_type {
|
||||||
|
COLOR,
|
||||||
|
TEXTURE,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct texture {
|
||||||
|
int const image_index; // index in to images
|
||||||
|
};
|
||||||
|
|
||||||
|
struct color_or_texture {
|
||||||
|
color_or_texture_type type;
|
||||||
|
union {
|
||||||
|
float4 color;
|
||||||
|
types::texture texture;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct blinn {
|
||||||
|
color_or_texture const emission;
|
||||||
|
color_or_texture const ambient;
|
||||||
|
color_or_texture const diffuse;
|
||||||
|
color_or_texture const specular;
|
||||||
|
float const shininess;
|
||||||
|
color_or_texture const reflective;
|
||||||
|
float const reflectivity;
|
||||||
|
color_or_texture const transparent;
|
||||||
|
float const transparency;
|
||||||
|
float const index_of_refraction;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lambert {
|
||||||
|
color_or_texture const emission;
|
||||||
|
color_or_texture const ambient;
|
||||||
|
color_or_texture const diffuse;
|
||||||
|
color_or_texture const reflective;
|
||||||
|
float const reflectivity;
|
||||||
|
color_or_texture const transparent;
|
||||||
|
float const transparency;
|
||||||
|
float const index_of_refraction;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct phong {
|
||||||
|
color_or_texture const emission;
|
||||||
|
color_or_texture const ambient;
|
||||||
|
color_or_texture const diffuse;
|
||||||
|
color_or_texture const specular;
|
||||||
|
float const shininess;
|
||||||
|
color_or_texture const reflective;
|
||||||
|
float const reflectivity;
|
||||||
|
color_or_texture const transparent;
|
||||||
|
float const transparency;
|
||||||
|
float const index_of_refraction;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct constant {
|
||||||
|
float4 const color;
|
||||||
|
color_or_texture const reflective;
|
||||||
|
float const reflectivity;
|
||||||
|
color_or_texture const transparent;
|
||||||
|
float const transparency;
|
||||||
|
float const index_of_refraction;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class effect_type {
|
||||||
|
BLINN,
|
||||||
|
LAMBERT,
|
||||||
|
PHONG,
|
||||||
|
CONSTANT,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct effect {
|
||||||
|
effect_type const type;
|
||||||
|
union {
|
||||||
|
types::blinn const blinn;
|
||||||
|
types::lambert const lambert;
|
||||||
|
types::phong const phong;
|
||||||
|
types::constant const constant;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// node
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct lookat {
|
||||||
|
float3 const eye;
|
||||||
|
float3 const at;
|
||||||
|
float3 const up;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class transform_type {
|
||||||
|
LOOKAT,
|
||||||
|
MATRIX,
|
||||||
|
ROTATE,
|
||||||
|
SCALE,
|
||||||
|
SKEW,
|
||||||
|
TRANSLATE,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct transform {
|
||||||
|
transform_type const type;
|
||||||
|
union {
|
||||||
|
types::lookat const lookat;
|
||||||
|
types::matrix const matrix;
|
||||||
|
float4 const rotate;
|
||||||
|
float3 const scale;
|
||||||
|
float7 const skew;
|
||||||
|
float3 const translate;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class node_type {
|
||||||
|
JOINT,
|
||||||
|
NODE,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct material {
|
||||||
|
types::effect const * const effect;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bind_vertex_input {
|
||||||
|
int input_set; // TEXCOORD semantic input slot
|
||||||
|
};
|
||||||
|
|
||||||
|
struct instance_material {
|
||||||
|
int const element_index; // an index into mesh.triangles
|
||||||
|
types::material const * const material;
|
||||||
|
|
||||||
|
// heavily simplified from collada data model
|
||||||
|
bind_vertex_input const emission;
|
||||||
|
bind_vertex_input const ambient;
|
||||||
|
bind_vertex_input const diffuse;
|
||||||
|
bind_vertex_input const specular;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct instance_geometry {
|
||||||
|
types::geometry const * const geometry;
|
||||||
|
|
||||||
|
instance_material const * const instance_materials;
|
||||||
|
int const instance_materials_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct skin {
|
||||||
|
types::geometry const * const geometry; // source
|
||||||
|
|
||||||
|
matrix const * const inverse_bind_matrices; // one per joint
|
||||||
|
|
||||||
|
int const vertex_buffer_offset;
|
||||||
|
int const vertex_buffer_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct controller {
|
||||||
|
types::skin skin;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct instance_controller {
|
||||||
|
types::controller const * const controller;
|
||||||
|
|
||||||
|
//node const * const skeleton; // a reference to the root of the joint heirarchy
|
||||||
|
|
||||||
|
int const * const joint_node_indices; // one per joint
|
||||||
|
int const joint_count;
|
||||||
|
|
||||||
|
instance_material const * const instance_materials;
|
||||||
|
int const instance_materials_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct instance_light {
|
||||||
|
types::light const * const light;
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// animation
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
enum class interpolation {
|
||||||
|
LINEAR,
|
||||||
|
BEZIER,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct source {
|
||||||
|
union {
|
||||||
|
float const * const float_array;
|
||||||
|
enum interpolation const * const interpolation_array;
|
||||||
|
};
|
||||||
|
int const count;
|
||||||
|
int const stride;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sampler {
|
||||||
|
source const input;
|
||||||
|
source const output;
|
||||||
|
source const in_tangent;
|
||||||
|
source const out_tangent;
|
||||||
|
source const interpolation;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class target_attribute {
|
||||||
|
A, // alpha color component
|
||||||
|
ANGLE, // euler angle
|
||||||
|
B, // blue color component
|
||||||
|
G, // green color component
|
||||||
|
P, // third texture component
|
||||||
|
Q, // fourth texture component
|
||||||
|
R, // red color component
|
||||||
|
S, // first texture coordinate
|
||||||
|
T, // second texture coordinate
|
||||||
|
TIME, // time in seconds
|
||||||
|
U, // first generic parameter
|
||||||
|
V, // second generic parameter
|
||||||
|
W, // fourth cartesian coordinate
|
||||||
|
X, // first cartesian coordinate
|
||||||
|
Y, // second cartesian coordinate
|
||||||
|
Z, // third cartesian coordinate
|
||||||
|
ALL,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct channel {
|
||||||
|
sampler const * const source_sampler;
|
||||||
|
int const target_node_index; // an index into the nodes array
|
||||||
|
int const target_transform_index;
|
||||||
|
types::target_attribute const target_attribute;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct animation {
|
||||||
|
animation const * const animations; // nested animations
|
||||||
|
int const animations_count;
|
||||||
|
|
||||||
|
channels const * const channels;
|
||||||
|
int const channels_count;
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct camera {
|
||||||
|
float xfov;
|
||||||
|
float yfov;
|
||||||
|
float znear;
|
||||||
|
float zfar;
|
||||||
|
float aspect_ratio;
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// scene
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct node {
|
||||||
|
int const parent_index;
|
||||||
|
|
||||||
|
node_type const type;
|
||||||
|
|
||||||
|
transform const * const transforms;
|
||||||
|
int const transforms_count;
|
||||||
|
|
||||||
|
instance_geometry const * const instance_geometries;
|
||||||
|
int const instance_geometries_count;
|
||||||
|
|
||||||
|
instance_controller const * const instance_controllers;
|
||||||
|
int const instance_controllers_count;
|
||||||
|
|
||||||
|
instance_light const * const instance_lights;
|
||||||
|
int const instance_lights_count;
|
||||||
|
|
||||||
|
channel const * const * const channels;
|
||||||
|
int const channels_count;
|
||||||
|
|
||||||
|
//node const * const * const nodes;
|
||||||
|
//int const nodes_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct descriptor {
|
||||||
|
// these are only the top-level nodes; nodes may have children
|
||||||
|
node const * const * const nodes;
|
||||||
|
int const nodes_count;
|
||||||
|
|
||||||
|
inputs const * const inputs_list;
|
||||||
|
int const inputs_list_count;
|
||||||
|
|
||||||
|
image const * const * const images;
|
||||||
|
int const images_count;
|
||||||
|
|
||||||
|
//animation const * const animations;
|
||||||
|
//int const animations_count;
|
||||||
|
|
||||||
|
// hmm, this part is not really platform-agnostic:
|
||||||
|
char const * const position_normal_texture_buffer;
|
||||||
|
char const * const joint_weight_buffer;
|
||||||
|
char const * const index_buffer;
|
||||||
|
};
|
||||||
|
}
|
||||||
7
include/collada_scene/ship20.h
Normal file
7
include/collada_scene/ship20.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "collada/types.h"
|
||||||
|
|
||||||
|
namespace collada_scene::ship20 {
|
||||||
|
extern collada::types::descriptor const descriptor;
|
||||||
|
}
|
||||||
3
include/data/scenes/ship20.h
Normal file
3
include/data/scenes/ship20.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
namespace ship20 {
|
||||||
|
extern collada::types::descriptor const descriptor;
|
||||||
|
}
|
||||||
9
include/new.h
Normal file
9
include/new.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T * New(int elements)
|
||||||
|
{
|
||||||
|
return (T *)aligned_alloc(16, (sizeof (T)) * elements);
|
||||||
|
}
|
||||||
8
shader/collada/generic.frag
Normal file
8
shader/collada/generic.frag
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#version 430 core
|
||||||
|
|
||||||
|
out vec4 Color;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
Color = vec4(1, 0, 0, 1);
|
||||||
|
}
|
||||||
12
shader/collada/static.vert
Normal file
12
shader/collada/static.vert
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#version 430 core
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 Position;
|
||||||
|
layout (location = 1) in vec3 Normal;
|
||||||
|
layout (location = 2) in vec3 Texture;
|
||||||
|
|
||||||
|
layout (location = 0) uniform mat4 Transform;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = Transform * vec4(Position, 1);
|
||||||
|
}
|
||||||
205
src/collada/animate.cpp
Normal file
205
src/collada/animate.cpp
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
static inline float fract(float f)
|
||||||
|
{
|
||||||
|
return f - floorf(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline float loop(float f, float n)
|
||||||
|
{
|
||||||
|
return fract(f / n) * n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int find_frame_ix(source const& source, float t)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < source.count - 1; i++) {
|
||||||
|
if (source.float_array[i] <= t && source.float_array[i+1] > t) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline float linear_interpolate_iv(source const& source, int frame_ix, float t)
|
||||||
|
{
|
||||||
|
float prev = source.float_array[(frame_ix+0) * source.stride];
|
||||||
|
float next = source.float_array[(frame_ix+1) * source.stride];
|
||||||
|
return (t - prev) / (next - prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline float linear_interpolate_value(source const& source, int frame_ix, int parameter_ix, float iv)
|
||||||
|
{
|
||||||
|
float prev = source.float_array[(frame_ix+0) * source.stride + parameter_ix];
|
||||||
|
float next = source.float_array[(frame_ix+1) * source.stride + parameter_ix];
|
||||||
|
return prev + iv * (next - prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline float pow3(float f)
|
||||||
|
{
|
||||||
|
return f * f * f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline float pow2(float f)
|
||||||
|
{
|
||||||
|
return f * f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline XMVECTOR bezier(XMVECTOR p0, XMVECTOR c0, XMVECTOR c1, XMVECTOR p1, float s)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
p0 * pow3(1 - s)
|
||||||
|
+ 3 * c0 * s * pow2(1 - s)
|
||||||
|
+ 3 * c1 * pow2(s) * (1 - s)
|
||||||
|
+ p1 * pow3(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline float bezier_binary_search(XMVECTOR p0, XMVECTOR c0, XMVECTOR c1, XMVECTOR p1, float want)
|
||||||
|
{
|
||||||
|
float low = 0.0f;
|
||||||
|
float high = 1.0f;
|
||||||
|
|
||||||
|
int iterations = 0;
|
||||||
|
while (iterations < 20) {
|
||||||
|
iterations += 1;
|
||||||
|
|
||||||
|
float s = (high + low) * 0.5f;
|
||||||
|
XMVECTOR bs = bezier(p0, c0, c1, p1, s);
|
||||||
|
float t = XMVectorGetX(bs);
|
||||||
|
|
||||||
|
const float epsilon = 0.001f;
|
||||||
|
if (fabsf(t - want) < epsilon) {
|
||||||
|
return XMVectorGetY(bs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t > want) {
|
||||||
|
high = s;
|
||||||
|
} else {
|
||||||
|
low = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print("%f %f\n", XMVectorGetX(p0), XMVectorGetY(p0));
|
||||||
|
print("%f %f\n", XMVectorGetX(c0), XMVectorGetY(c0));
|
||||||
|
print("%f %f\n", XMVectorGetX(c1), XMVectorGetY(c1));
|
||||||
|
print("%f %f\n", XMVectorGetX(p1), XMVectorGetY(p1));
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline XMFLOAT2 const * tangent_index(source const& source, int frame_ix, int parameter_ix)
|
||||||
|
{
|
||||||
|
int ix = frame_ix * source.stride + parameter_ix * 2;
|
||||||
|
return (XMFLOAT2 const *)&source.float_array[ix];
|
||||||
|
}
|
||||||
|
|
||||||
|
static float bezier_sampler(sampler const * const sampler, int frame_ix, int parameter_ix, float t)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
P0 is (INPUT[i] , OUTPUT[i])
|
||||||
|
C0 (or T0) is (OUT_TANGENT[i][0] , OUT_TANGENT[i][1])
|
||||||
|
C1 (or T1) is (IN_TANGENT[i+1][0], IN_TANGENT[i+1][1])
|
||||||
|
P1 is (INPUT[i+1], OUTPUT[i+1])
|
||||||
|
*/
|
||||||
|
|
||||||
|
float frame0_input = sampler->input.float_array[frame_ix+0];
|
||||||
|
float frame1_input = sampler->input.float_array[frame_ix+1];
|
||||||
|
|
||||||
|
float frame0_output = sampler->output.float_array[(frame_ix+0) * sampler->output.stride + parameter_ix];
|
||||||
|
float frame1_output = sampler->output.float_array[(frame_ix+1) * sampler->output.stride + parameter_ix];
|
||||||
|
|
||||||
|
XMVECTOR p0 = XMVectorSet(frame0_input, frame0_output, 0, 0);
|
||||||
|
XMVECTOR c0 = XMLoadFloat2(tangent_index(sampler->out_tangent, frame_ix + 0, parameter_ix));
|
||||||
|
XMVECTOR c1 = XMLoadFloat2(tangent_index(sampler->in_tangent, frame_ix + 1, parameter_ix));
|
||||||
|
XMVECTOR p1 = XMVectorSet(frame1_input, frame1_output, 0, 0);
|
||||||
|
|
||||||
|
return bezier_binary_search(p0, c0, c1, p1, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void apply_transform_target(transform& transform,
|
||||||
|
enum target_attribute channel_target_attribute,
|
||||||
|
float value)
|
||||||
|
{
|
||||||
|
switch (transform.type) {
|
||||||
|
case transform_type::TRANSLATE: __attribute__((fallthrough));
|
||||||
|
case transform_type::SCALE:
|
||||||
|
switch (channel_target_attribute) {
|
||||||
|
case target_attribute::X: transform.vector = XMVectorSetX(transform.vector, value); return;
|
||||||
|
case target_attribute::Y: transform.vector = XMVectorSetY(transform.vector, value); return;
|
||||||
|
case target_attribute::Z: transform.vector = XMVectorSetZ(transform.vector, value); return;
|
||||||
|
default: assert(false);
|
||||||
|
}
|
||||||
|
case transform_type::ROTATE:
|
||||||
|
switch (channel_target_attribute) {
|
||||||
|
case target_attribute::X: transform.vector = XMVectorSetX(transform.vector, value); return;
|
||||||
|
case target_attribute::Y: transform.vector = XMVectorSetY(transform.vector, value); return;
|
||||||
|
case target_attribute::Z: transform.vector = XMVectorSetZ(transform.vector, value); return;
|
||||||
|
case target_attribute::ANGLE: transform.vector = XMVectorSetW(transform.vector, value); return;
|
||||||
|
default: assert(false);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum target_attribute const rotate_target_attributes[] = {
|
||||||
|
target_attribute::X,
|
||||||
|
target_attribute::Y,
|
||||||
|
target_attribute::Z,
|
||||||
|
target_attribute::ANGLE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static enum target_attribute const translate_scale_target_attributes[] = {
|
||||||
|
target_attribute::X,
|
||||||
|
target_attribute::Y,
|
||||||
|
target_attribute::Z,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void animate_channel_segment(channel const& channel,
|
||||||
|
transform& transform,
|
||||||
|
int frame_ix, float t)
|
||||||
|
{
|
||||||
|
enum target_attribute const * target_attributes = &channel.target_attribute;
|
||||||
|
int target_attributes_count = 1;
|
||||||
|
if (channel.target_attribute == target_attribute::ALL) {
|
||||||
|
switch (transform.type) {
|
||||||
|
case transform_type::TRANSLATE: __attribute__((fallthrough));
|
||||||
|
case transform_type::SCALE:
|
||||||
|
target_attributes = translate_scale_target_attributes;
|
||||||
|
target_attributes_count = 3;
|
||||||
|
break;
|
||||||
|
case transform_type::ROTATE:
|
||||||
|
target_attributes = rotate_target_attributes;
|
||||||
|
target_attributes_count = 4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int parameter_ix = 0; parameter_ix < target_attributes_count; parameter_ix++) {
|
||||||
|
|
||||||
|
enum collada::interpolation interpolation = channel.source_sampler->interpolation.interpolation_array[frame_ix];
|
||||||
|
|
||||||
|
float value;
|
||||||
|
if (interpolation == interpolation::BEZIER) {
|
||||||
|
value = bezier_sampler(channel.source_sampler, frame_ix, parameter_ix, t);
|
||||||
|
} else {
|
||||||
|
float iv = linear_interpolate_iv(channel.source_sampler->input, frame_ix, t);
|
||||||
|
value = linear_interpolate_value(channel.source_sampler->output, frame_ix, parameter_ix, iv);
|
||||||
|
}
|
||||||
|
|
||||||
|
apply_transform_target(transform, target_attributes[parameter_ix], value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void animate_node(node const& node, node_instance& node_instance, float t)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < node.channels_count; i++) {
|
||||||
|
channel const& channel = *node.channels[i];
|
||||||
|
transform& transform = node_instance.transforms[channel.target_transform_index];
|
||||||
|
|
||||||
|
int frame_ix = find_frame_ix(channel.source_sampler->input, t);
|
||||||
|
assert(frame_ix >= 0); // animation is missing a key frame
|
||||||
|
|
||||||
|
animate_channel_segment(channel, transform, frame_ix, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/collada/effect.cpp
Normal file
16
src/collada/effect.cpp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#include "opengl.h"
|
||||||
|
|
||||||
|
#include "collada/effect.h"
|
||||||
|
|
||||||
|
namespace collada::effect {
|
||||||
|
|
||||||
|
unsigned int program_static;
|
||||||
|
unsigned int program_skinned;
|
||||||
|
|
||||||
|
void load_effects()
|
||||||
|
{
|
||||||
|
program_static = compile_from_files("shader/collada/static.vert",
|
||||||
|
nullptr,
|
||||||
|
"shader/collada/generic.frag");
|
||||||
|
}
|
||||||
|
}
|
||||||
67
src/collada/node_state.cpp
Normal file
67
src/collada/node_state.cpp
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#include "directxmath/directxmath.h"
|
||||||
|
|
||||||
|
#include "collada/types.h"
|
||||||
|
#include "collada/instance_types.h"
|
||||||
|
|
||||||
|
namespace collada::node_state {
|
||||||
|
inline static void load_transform(instance_types::transform * instance_transform,
|
||||||
|
types::transform const & transform)
|
||||||
|
{
|
||||||
|
switch (transform.type) {
|
||||||
|
case types::transform_type::LOOKAT:
|
||||||
|
instance_transform->lookat.eye = XMLoadFloat3((XMFLOAT3 *)&transform.lookat.eye);
|
||||||
|
instance_transform->lookat.at = XMLoadFloat3((XMFLOAT3 *)&transform.lookat.at);
|
||||||
|
instance_transform->lookat.up = XMLoadFloat3((XMFLOAT3 *)&transform.lookat.up);
|
||||||
|
break;
|
||||||
|
case types::transform_type::MATRIX:
|
||||||
|
instance_transform->matrix = XMLoadFloat4x4((XMFLOAT4X4 *)&transform.matrix);
|
||||||
|
break;
|
||||||
|
case types::transform_type::ROTATE:
|
||||||
|
instance_transform->vector = XMLoadFloat4((XMFLOAT4 *)&transform.rotate);
|
||||||
|
break;
|
||||||
|
case types::transform_type::SCALE:
|
||||||
|
instance_transform->vector = XMLoadFloat3((XMFLOAT3*)&transform.scale);
|
||||||
|
break;
|
||||||
|
case types::transform_type::TRANSLATE:
|
||||||
|
instance_transform->vector = XMLoadFloat3((XMFLOAT3*)&transform.translate);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void initialize_node_transforms(types::node const * const node,
|
||||||
|
instance_types::node_instance * const node_instance)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < node->transforms_count; i++) {
|
||||||
|
load_transform(&node_instance->transforms[i],
|
||||||
|
node->transforms[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static bool vector_equal(XMVECTOR V1, XMVECTOR V2)
|
||||||
|
{
|
||||||
|
uint32_t CR;
|
||||||
|
XMVectorEqualR(&CR, V1, V2);
|
||||||
|
return XMComparisonAllTrue(CR);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static XMMATRIX transform_matrix(instance_types::transform const& transform)
|
||||||
|
{
|
||||||
|
switch (transform.type) {
|
||||||
|
case types::transform_type::TRANSLATE:
|
||||||
|
return XMMatrixTranslationFromVector(transform.vector);
|
||||||
|
case types::transform_type::ROTATE:
|
||||||
|
assert(!vector_equal(XMVectorSetW(transform.vector, 0), XMVectorZero()));
|
||||||
|
return XMMatrixRotationNormal(transform.vector,
|
||||||
|
XMConvertToRadians(XMVectorGetW(transform.vector)));
|
||||||
|
case types::transform_type::SCALE:
|
||||||
|
return XMMatrixScalingFromVector(transform.vector);
|
||||||
|
case types::transform_type::MATRIX:
|
||||||
|
return transform.matrix;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
280
src/collada/scene.cpp
Normal file
280
src/collada/scene.cpp
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "glad/gl.h"
|
||||||
|
#include "directxmath/directxmath.h"
|
||||||
|
|
||||||
|
#include "new.h"
|
||||||
|
#include "file.h"
|
||||||
|
#include "view.h"
|
||||||
|
|
||||||
|
#include "collada/types.h"
|
||||||
|
#include "collada/instance_types.h"
|
||||||
|
#include "collada/scene.h"
|
||||||
|
#include "collada/effect.h"
|
||||||
|
|
||||||
|
namespace collada::scene {
|
||||||
|
|
||||||
|
struct layout {
|
||||||
|
struct {
|
||||||
|
unsigned int position;
|
||||||
|
unsigned int normal;
|
||||||
|
unsigned int texture;
|
||||||
|
unsigned int blend_indices;
|
||||||
|
unsigned int blend_weight;
|
||||||
|
} attribute;
|
||||||
|
struct {
|
||||||
|
unsigned int transform;
|
||||||
|
} uniform;
|
||||||
|
};
|
||||||
|
|
||||||
|
const layout layout = {
|
||||||
|
.attribute = {
|
||||||
|
.position = 0,
|
||||||
|
.normal = 1,
|
||||||
|
.texture = 2,
|
||||||
|
.blend_indices = 3,
|
||||||
|
.blend_weight = 4,
|
||||||
|
},
|
||||||
|
.uniform = {
|
||||||
|
.transform = 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned int attribute_location(char const * const semantic,
|
||||||
|
int semantic_index)
|
||||||
|
{
|
||||||
|
if (strcmp(semantic, "POSITION") == 0 && semantic_index == 0) {
|
||||||
|
return layout.attribute.position;
|
||||||
|
}
|
||||||
|
if (strcmp(semantic, "NORMAL") == 0 && semantic_index == 0) {
|
||||||
|
return layout.attribute.normal;
|
||||||
|
}
|
||||||
|
if (strcmp(semantic, "TEXCOORD") == 0 && semantic_index == 0) {
|
||||||
|
return layout.attribute.texture;
|
||||||
|
}
|
||||||
|
if (strcmp(semantic, "BLENDINDICES") == 0 && semantic_index == 0) {
|
||||||
|
return layout.attribute.blend_indices;
|
||||||
|
}
|
||||||
|
if (strcmp(semantic, "BLENDWEIGHT") == 0 && semantic_index == 0) {
|
||||||
|
return layout.attribute.blend_weight;
|
||||||
|
}
|
||||||
|
printf("unknown semantic %s index %d\n",semantic, semantic_index);
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int input_format_gl_size(types::input_format format)
|
||||||
|
{
|
||||||
|
switch (format) {
|
||||||
|
case types::input_format::FLOAT1: return 1;
|
||||||
|
case types::input_format::FLOAT2: return 2;
|
||||||
|
case types::input_format::FLOAT3: return 3;
|
||||||
|
case types::input_format::FLOAT4: return 4;
|
||||||
|
case types::input_format::INT1: return 1;
|
||||||
|
case types::input_format::INT2: return 2;
|
||||||
|
case types::input_format::INT3: return 3;
|
||||||
|
case types::input_format::INT4: return 4;
|
||||||
|
default: assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int input_format_gl_type(types::input_format format)
|
||||||
|
{
|
||||||
|
switch (format) {
|
||||||
|
case types::input_format::FLOAT1: return GL_FLOAT;
|
||||||
|
case types::input_format::FLOAT2: return GL_FLOAT;
|
||||||
|
case types::input_format::FLOAT3: return GL_FLOAT;
|
||||||
|
case types::input_format::FLOAT4: return GL_FLOAT;
|
||||||
|
case types::input_format::INT1: return GL_INT;
|
||||||
|
case types::input_format::INT2: return GL_INT;
|
||||||
|
case types::input_format::INT3: return GL_INT;
|
||||||
|
case types::input_format::INT4: return GL_INT;
|
||||||
|
default: assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// return stride
|
||||||
|
static inline int load_layout(types::inputs const & inputs,
|
||||||
|
int binding,
|
||||||
|
int start_offset,
|
||||||
|
unsigned int vertex_array)
|
||||||
|
{
|
||||||
|
glBindVertexArray(vertex_array);
|
||||||
|
int offset = start_offset;
|
||||||
|
for (int i = 0; i < inputs.elements_count; i++) {
|
||||||
|
unsigned int location = attribute_location(inputs.elements[i].semantic, inputs.elements[i].semantic_index);
|
||||||
|
glEnableVertexAttribArray(location);
|
||||||
|
unsigned int gl_size = input_format_gl_size(inputs.elements[i].format);
|
||||||
|
unsigned int gl_type = input_format_gl_type(inputs.elements[i].format);
|
||||||
|
glVertexAttribFormat(location, gl_size, gl_type, GL_FALSE, offset);
|
||||||
|
glVertexAttribBinding(location, binding);
|
||||||
|
offset += gl_size * 4;
|
||||||
|
}
|
||||||
|
int stride = offset - start_offset;
|
||||||
|
glBindVertexArray(0);
|
||||||
|
return stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
types::input_element const input_elements_blendindices_0_4_blendweight_0_4[] = {
|
||||||
|
{
|
||||||
|
.semantic = "BLENDINDICES",
|
||||||
|
.semantic_index = 0,
|
||||||
|
.format = types::input_format::INT4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.semantic = "BLENDWEIGHT",
|
||||||
|
.semantic_index = 0,
|
||||||
|
.format = types::input_format::FLOAT4,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
types::inputs const skin_inputs = {
|
||||||
|
.elements = input_elements_blendindices_0_4_blendweight_0_4,
|
||||||
|
.elements_count = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
void state::load_layouts()
|
||||||
|
{
|
||||||
|
vertex_arrays = New<static_skinned>(descriptor->inputs_list_count);
|
||||||
|
vertex_buffer_strides = New<int>(descriptor->inputs_list_count);
|
||||||
|
|
||||||
|
glGenVertexArrays(2 * descriptor->inputs_list_count, (unsigned int *)vertex_arrays);
|
||||||
|
|
||||||
|
for (int i = 0; i < descriptor->inputs_list_count; i++) {
|
||||||
|
// static
|
||||||
|
int stride = load_layout(descriptor->inputs_list[i],
|
||||||
|
0, // binding
|
||||||
|
0, // start_offset
|
||||||
|
vertex_arrays[i].static_mesh);
|
||||||
|
vertex_buffer_strides[i] = stride;
|
||||||
|
|
||||||
|
// skinned
|
||||||
|
load_layout(descriptor->inputs_list[i],
|
||||||
|
0, // binding
|
||||||
|
0, // start_offset
|
||||||
|
vertex_arrays[i].skinned_mesh);
|
||||||
|
load_layout(skin_inputs,
|
||||||
|
1, // binding
|
||||||
|
0, // start_offset
|
||||||
|
vertex_arrays[i].skinned_mesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int load_vertex_buffer(const char * filename)
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
void * data = read_file(filename, &size);
|
||||||
|
assert(data != NULL);
|
||||||
|
unsigned int vertex_buffer;
|
||||||
|
glGenBuffers(1, &vertex_buffer);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
return vertex_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int load_index_buffer(const char * filename)
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
void * data = read_file(filename, &size);
|
||||||
|
assert(data != NULL);
|
||||||
|
printf("%s %d\n", filename, size);
|
||||||
|
|
||||||
|
unsigned int index_buffer;
|
||||||
|
glGenBuffers(1, &index_buffer);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
return index_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void state::load_scene(types::descriptor const * const descriptor)
|
||||||
|
{
|
||||||
|
this->descriptor = descriptor;
|
||||||
|
|
||||||
|
load_layouts();
|
||||||
|
|
||||||
|
vertex_buffer_pnt = load_vertex_buffer(descriptor->position_normal_texture_buffer);
|
||||||
|
vertex_buffer_jw = load_vertex_buffer(descriptor->joint_weight_buffer);
|
||||||
|
index_buffer = load_index_buffer(descriptor->index_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void state::draw_geometry(types::geometry const & geometry,
|
||||||
|
types::instance_material const * const instance_materials,
|
||||||
|
int const instance_materials_count)
|
||||||
|
{
|
||||||
|
glUseProgram(collada::effect::program_static);
|
||||||
|
|
||||||
|
types::mesh const& mesh = geometry.mesh;
|
||||||
|
|
||||||
|
for (int j = 0; j < instance_materials_count; j++) {
|
||||||
|
types::instance_material const& instance_material = instance_materials[j];
|
||||||
|
types::triangles const& triangles = mesh.triangles[instance_material.element_index];
|
||||||
|
|
||||||
|
//set_instance_material(instance_material);
|
||||||
|
|
||||||
|
unsigned int vertex_buffer_offset = mesh.vertex_buffer_offset;
|
||||||
|
unsigned int vertex_buffer_stride = vertex_buffer_strides[triangles.inputs_index];
|
||||||
|
unsigned int vertex_array = vertex_arrays[triangles.inputs_index].static_mesh;
|
||||||
|
|
||||||
|
glBindVertexArray(vertex_array);
|
||||||
|
glBindVertexBuffer(0, vertex_buffer_pnt, vertex_buffer_offset, vertex_buffer_stride);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
|
||||||
|
|
||||||
|
unsigned int index_count = triangles.count * 3;
|
||||||
|
unsigned int indices = triangles.index_offset * (sizeof (unsigned int)) + mesh.index_buffer_offset;
|
||||||
|
|
||||||
|
unsigned int instance_count = 1;
|
||||||
|
unsigned int base_vertex = 0;
|
||||||
|
unsigned int base_instance = 1;
|
||||||
|
glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLES,
|
||||||
|
index_count,
|
||||||
|
GL_UNSIGNED_INT,
|
||||||
|
(void *)((ptrdiff_t)indices),
|
||||||
|
instance_count,
|
||||||
|
base_vertex,
|
||||||
|
base_instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void state::draw_instance_geometries(types::instance_geometry const * const instance_geometries,
|
||||||
|
int const instance_geometries_count)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < instance_geometries_count; i++) {
|
||||||
|
types::instance_geometry const &instance_geometry = instance_geometries[i];
|
||||||
|
draw_geometry(*instance_geometry.geometry,
|
||||||
|
instance_geometry.instance_materials,
|
||||||
|
instance_geometry.instance_materials_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void state::draw_node(types::node const & node)
|
||||||
|
{
|
||||||
|
draw_instance_geometries(node.instance_geometries, node.instance_geometries_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void state::draw()
|
||||||
|
{
|
||||||
|
glUseProgram(collada::effect::program_static);
|
||||||
|
glUniformMatrix4fv(layout.uniform.transform, 1, false, (float *)&view::state.float_transform);
|
||||||
|
|
||||||
|
for (int i = 0; i < descriptor->nodes_count; i++) {
|
||||||
|
types::node const & node = *descriptor->nodes[i];
|
||||||
|
|
||||||
|
// joints are not drawn
|
||||||
|
if (node.type != types::node_type::NODE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
draw_node(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/test.cpp
16
src/test.cpp
@ -21,6 +21,10 @@
|
|||||||
#include "collision_scene.h"
|
#include "collision_scene.h"
|
||||||
#include "collision.h"
|
#include "collision.h"
|
||||||
#include "boids_scene.h"
|
#include "boids_scene.h"
|
||||||
|
#include "collada/effect.h"
|
||||||
|
#include "collada/scene.h"
|
||||||
|
#include "collada/types.h"
|
||||||
|
#include "data/scenes/ship20.h"
|
||||||
|
|
||||||
struct line_location {
|
struct line_location {
|
||||||
struct {
|
struct {
|
||||||
@ -50,6 +54,8 @@ static quad_location quad_location;
|
|||||||
// globals
|
// globals
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static collada::scene::state scene_state;
|
||||||
|
|
||||||
unsigned int empty_vertex_array_object = -1;
|
unsigned int empty_vertex_array_object = -1;
|
||||||
unsigned int quad_index_buffer = -1;
|
unsigned int quad_index_buffer = -1;
|
||||||
|
|
||||||
@ -290,6 +296,13 @@ void load(const char * source_path)
|
|||||||
line_art::load();
|
line_art::load();
|
||||||
collision_scene::load();
|
collision_scene::load();
|
||||||
boids_scene::load();
|
boids_scene::load();
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// collada
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
collada::effect::load_effects();
|
||||||
|
scene_state.load_scene(&ship20::descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_keyboard(int up, int down, int left, int right,
|
void update_keyboard(int up, int down, int left, int right,
|
||||||
@ -569,7 +582,8 @@ void draw()
|
|||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
//collision_scene::draw();
|
//collision_scene::draw();
|
||||||
boids_scene::draw();
|
//boids_scene::draw();
|
||||||
|
scene_state.draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
last_frame_time = current_time;
|
last_frame_time = current_time;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user