diff --git a/Makefile b/Makefile index 3a36b5e..3c972c9 100644 --- a/Makefile +++ b/Makefile @@ -84,7 +84,7 @@ all: main $(CXX) $(ARCH) $(CXXSTD) $(CFLAGS) $(OPT) $(DEBUG) -c $< -o $@ PACK_FILENAMES = $(shell cat filenames.txt) -test.pack: tool/pack_file $(PACK_FILENAMES) +test.pack: tool/pack_file $(PACK_FILENAMES) filenames.txt ./tool/pack_file $@ $(PACK_FILENAMES) test.pack.o: test.pack diff --git a/filenames.txt b/filenames.txt index bf9e33e..e162c76 100644 --- a/filenames.txt +++ b/filenames.txt @@ -1,56 +1,53 @@ -shader/minecraft.vert -shader/minecraft.frag -minecraft/per_vertex.vtx -minecraft/configuration.idx -minecraft/terrain2.data -minecraft/grandlecturn/region.0.0.instance.vtx -minecraft/grandlecturn/region.0.0.instance.cfg -minecraft/grandlecturn/region.-1.0.instance.vtx -minecraft/grandlecturn/region.-1.0.instance.cfg -minecraft/grandlecturn/region.0.-1.instance.vtx -minecraft/grandlecturn/region.0.-1.instance.cfg -minecraft/grandlecturn/region.-1.-1.instance.vtx -minecraft/grandlecturn/region.-1.-1.instance.cfg -minecraft/grandlecturn/global.lights.vtx -minecraft/grandlecturn/global.dump -minecraft/midnightmeadow/region.0.0.instance.vtx -minecraft/midnightmeadow/region.0.0.instance.cfg -minecraft/midnightmeadow/region.-1.0.instance.vtx -minecraft/midnightmeadow/region.-1.0.instance.cfg -minecraft/midnightmeadow/region.0.-1.instance.vtx -minecraft/midnightmeadow/region.0.-1.instance.cfg -minecraft/midnightmeadow/region.-1.-1.instance.vtx -minecraft/midnightmeadow/region.-1.-1.instance.cfg -minecraft/midnightmeadow/global.lights.vtx -minecraft/midnightmeadow/global.dump -shader/font.vert -shader/font.frag -font/bitmap/terminus_128x64_6x12.data +data/scenes/eidelwind/images/0_map_face_only.dds +data/scenes/eidelwind/scene.idx +data/scenes/eidelwind/scene.vjw +data/scenes/eidelwind/scene.vtx font/bitmap/terminus_128x128_8x16.data +font/bitmap/terminus_128x64_6x12.data font/bitmap/terminus_256x128_10x18.data font/bitmap/terminus_256x128_12x24.data font/bitmap/terminus_256x256_16x32.data -shader/font.vert -shader/font_outline.frag font/outline/uncial_antiqua_36.data -shader/quad.vert -shader/quad.frag -shader/quad.vert -shader/lighting.frag -shader/non_block.vert -shader/non_block.frag +minecraft/configuration.idx +minecraft/flame.data +minecraft/grandlecturn/global.dump +minecraft/grandlecturn/global.lights.vtx +minecraft/grandlecturn/region.0.0.instance.cfg +minecraft/grandlecturn/region.0.0.instance.vtx +minecraft/grandlecturn/region.0.-1.instance.cfg +minecraft/grandlecturn/region.0.-1.instance.vtx +minecraft/grandlecturn/region.-1.0.instance.cfg +minecraft/grandlecturn/region.-1.0.instance.vtx +minecraft/grandlecturn/region.-1.-1.instance.cfg +minecraft/grandlecturn/region.-1.-1.instance.vtx +minecraft/midnightmeadow/global.dump +minecraft/midnightmeadow/global.lights.vtx +minecraft/midnightmeadow/region.0.0.instance.cfg +minecraft/midnightmeadow/region.0.0.instance.vtx +minecraft/midnightmeadow/region.0.-1.instance.cfg +minecraft/midnightmeadow/region.0.-1.instance.vtx +minecraft/midnightmeadow/region.-1.0.instance.cfg +minecraft/midnightmeadow/region.-1.0.instance.vtx +minecraft/midnightmeadow/region.-1.-1.instance.cfg +minecraft/midnightmeadow/region.-1.-1.instance.vtx minecraft/non_block.idx minecraft/non_block.vtx -shader/line_art.vert -shader/line_art.frag -shader/collada/static.vert -shader/collada/generic.frag +minecraft/per_vertex.vtx +minecraft/terrain2.data +shader/collada/generic_geometry.frag shader/collada/skinned.vert -shader/collada/generic.frag -data/scenes/eidelwind/scene.vtx -data/scenes/eidelwind/scene.vjw -data/scenes/eidelwind/scene.idx -data/scenes/eidelwind/images/0_map_face_only.dds -shader/flame.vert +shader/collada/static.vert shader/flame.frag -minecraft/flame.data +shader/flame.vert +shader/font.frag +shader/font_outline.frag +shader/font.vert +shader/lighting.frag +shader/line_art.frag +shader/line_art.vert +shader/minecraft.frag +shader/minecraft.vert +shader/non_block.frag +shader/non_block.vert +shader/quad.frag +shader/quad.vert diff --git a/include/collada/scene.h b/include/collada/scene.h index dd3fda3..6055248 100644 --- a/include/collada/scene.h +++ b/include/collada/scene.h @@ -48,8 +48,8 @@ namespace collada::scene { void draw_instance_controllers(types::instance_controller const * const instance_controllers, int const instance_controllers_count); - void draw_node(types::node const & node, instance_types::node const & node_instance); - void draw(); + void draw_node(XMMATRIX const & ext_transform, types::node const & node, instance_types::node const & node_instance); + void draw(XMMATRIX const & ext_transform); // state updates void update(float t); diff --git a/shader/collada/generic_geometry.frag b/shader/collada/generic_geometry.frag new file mode 100644 index 0000000..21c8bd6 --- /dev/null +++ b/shader/collada/generic_geometry.frag @@ -0,0 +1,64 @@ +#version 430 core + +in VS_OUT { + vec3 Position; // world coordinates + vec3 Normal; + vec2 Texture; +} fs_in; + +layout (location = 10) uniform vec4 EmissionColor; +layout (location = 11) uniform vec4 AmbientColor; +layout (location = 12) uniform vec4 DiffuseColor; +layout (location = 13) uniform vec4 SpecularColor; + +layout (location = 14) uniform float shininess; + +layout (location = 15) uniform sampler2D EmissionSampler; +layout (location = 16) uniform sampler2D AmbientSampler; +layout (location = 17) uniform sampler2D DiffuseSampler; +layout (location = 18) uniform sampler2D SpecularSampler; + +layout (location = 19) uniform ivec4 TextureChannel; + +layout (location = 0) out vec4 Position; +layout (location = 1) out vec4 Normal; +layout (location = 2) out vec4 Color; +layout (location = 3) out vec4 Block; + +void main() +{ + vec4 emission; + vec4 ambient; + vec4 diffuse; + vec4 specular; + if (TextureChannel.x >= 0) { // emission + emission = texture(EmissionSampler, fs_in.Texture.xy); + } else { + emission = EmissionColor; + } + if (TextureChannel.y >= 0) { // ambient + ambient = texture(AmbientSampler, fs_in.Texture.xy); + } else { + ambient = AmbientColor; + } + if (TextureChannel.z >= 0) { // diffuse + diffuse = texture(DiffuseSampler, fs_in.Texture.xy); + } else { + diffuse = DiffuseColor; + } + if (TextureChannel.w >= 0) { // specular + specular = texture(SpecularSampler, fs_in.Texture.xy); + } else { + specular = SpecularColor; + } + + vec3 color = emission.xyz * 0; + color += ambient.xyz * 0.05; + color += diffuse.xyz * 1; + color += specular.xyz * 0 * 0.3; + + Position = vec4(fs_in.Position, 1.0); + Normal = vec4(fs_in.Normal, 0.0); + Color = vec4(color, 1.0); + Block = vec4(0, 0, 0, 0); +} diff --git a/shader/collada/skinned.vert b/shader/collada/skinned.vert index 2a45cdd..bd95217 100644 --- a/shader/collada/skinned.vert +++ b/shader/collada/skinned.vert @@ -7,20 +7,21 @@ layout (location = 3) in ivec4 BlendIndices; layout (location = 4) in vec4 BlendWeight; layout (location = 0) uniform mat4 Transform; +layout (location = 1) uniform mat4 WorldTransform; layout (std140, binding = 0) uniform JointsLayout { mat4 Joints[64]; }; -out vec3 PixelNormal; -out vec2 PixelTexture; +out VS_OUT { + vec3 Position; + vec3 Normal; + vec2 Texture; +} vs_out; void main() { - PixelNormal = Normal; - PixelTexture = vec2(Texture.x, 1.0 - Texture.y); - mat4 skin = BlendWeight.x * Joints[BlendIndices.x] + BlendWeight.y * Joints[BlendIndices.y] @@ -30,5 +31,9 @@ void main() vec4 position = skin * vec4(Position, 1); + vs_out.Position = (WorldTransform * position).xyz; + vs_out.Normal = Normal; + vs_out.Texture = vec2(Texture.x, 1.0 - Texture.y); + gl_Position = Transform * position; } diff --git a/shader/collada/static.vert b/shader/collada/static.vert index 971eba0..0645ad8 100644 --- a/shader/collada/static.vert +++ b/shader/collada/static.vert @@ -5,14 +5,19 @@ layout (location = 1) in vec3 Normal; layout (location = 2) in vec2 Texture; layout (location = 0) uniform mat4 Transform; +layout (location = 1) uniform mat4 WorldTransform; -out vec3 PixelNormal; -out vec2 PixelTexture; +out VS_OUT { + vec3 Position; + vec3 Normal; + vec2 Texture; +} vs_out; void main() { - PixelNormal = Normal; - PixelTexture = vec2(Texture.x, 1.0 - Texture.y); + vs_out.Position = Position; + vs_out.Normal = Normal; + vs_out.Texture = vec2(Texture.x, 1.0 - Texture.y); gl_Position = Transform * vec4(Position, 1); } diff --git a/shader/lighting.frag b/shader/lighting.frag index ab6e19f..35809a0 100644 --- a/shader/lighting.frag +++ b/shader/lighting.frag @@ -29,7 +29,7 @@ void main() if (LightCount != 0) { for (int i = 0; i < LightCount; i++) { vec3 light_position = light[i].xzy + vec3(0, 0, 0.5); - float light_distance = length(light_position - position.xyz); + float light_distance = length(light_position - position.xyz) * 0.5; vec3 light_direction = normalize(light_position - position.xyz); float diffuse = max(dot(normal.xyz, light_direction), 0.0); if (normal.w == 1.0) // two-sided diff --git a/src/collada/effect.cpp b/src/collada/effect.cpp index 190160f..0f2e929 100644 --- a/src/collada/effect.cpp +++ b/src/collada/effect.cpp @@ -11,10 +11,10 @@ namespace collada::effect { { program_static = compile_from_files("shader/collada/static.vert", nullptr, - "shader/collada/generic.frag"); + "shader/collada/generic_geometry.frag"); program_skinned = compile_from_files("shader/collada/skinned.vert", nullptr, - "shader/collada/generic.frag"); + "shader/collada/generic_geometry.frag"); } } diff --git a/src/collada/scene.cpp b/src/collada/scene.cpp index 692bff3..adb44be 100644 --- a/src/collada/scene.cpp +++ b/src/collada/scene.cpp @@ -29,6 +29,7 @@ namespace collada::scene { struct { // vertex unsigned int transform; + unsigned int world_transform; // fragment unsigned int emission_color; unsigned int ambient_color; @@ -66,6 +67,7 @@ namespace collada::scene { .uniform = { // vertex .transform = 0, + .world_transform = 1, // fragment .emission_color = 10, .ambient_color = 11, @@ -481,30 +483,38 @@ namespace collada::scene { } } - void state::draw_node(types::node const & node, instance_types::node const & node_instance) + void state::draw_node(XMMATRIX const& ext_transform, types::node const & node, instance_types::node const & node_instance) { - XMMATRIX transform = node_instance.world * view::state.transform; - XMFLOAT4X4 float_transform; - XMStoreFloat4x4(&float_transform, transform); - if (node.instance_geometries_count) { + XMMATRIX world_transform = node_instance.world * ext_transform; + XMMATRIX transform = world_transform * view::state.transform; + XMFLOAT4X4 float_transform; + XMStoreFloat4x4(&float_transform, transform); + XMFLOAT4X4 float_world_transform; + XMStoreFloat4x4(&float_world_transform, world_transform); + glUseProgram(collada::effect::program_static); glUniformMatrix4fv(layout.uniform.transform, 1, false, (float *)&float_transform); + glUniformMatrix4fv(layout.uniform.world_transform, 1, false, (float *)&float_world_transform); draw_instance_geometries(node.instance_geometries, node.instance_geometries_count); } if (node.instance_controllers_count) { - XMMATRIX transform = view::state.transform; + XMMATRIX world_transform = ext_transform; + XMMATRIX transform = world_transform * view::state.transform; XMFLOAT4X4 float_transform; XMStoreFloat4x4(&float_transform, transform); + XMFLOAT4X4 float_world_transform; + XMStoreFloat4x4(&float_world_transform, world_transform); glUseProgram(collada::effect::program_skinned); glUniformMatrix4fv(layout.uniform.transform, 1, false, (float *)&float_transform); + glUniformMatrix4fv(layout.uniform.world_transform, 1, false, (float *)&float_world_transform); draw_instance_controllers(node.instance_controllers, node.instance_controllers_count); } } - void state::draw() + void state::draw(XMMATRIX const& ext_transform) { unsigned int effects[] = {collada::effect::program_static, collada::effect::program_skinned}; for (int i = 0; i < 2; i++) { @@ -528,7 +538,7 @@ namespace collada::scene { if (((node_draw_type & 0b10) == 0) && (node.type == types::node_type::JOINT)) continue; - draw_node(node, node_state.node_instances[i]); + draw_node(ext_transform, node, node_state.node_instances[i]); } } diff --git a/src/test.cpp b/src/test.cpp index e350d4d..d6e95b5 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -25,6 +25,7 @@ #include "boids_scene.h" #include "collada/effect.h" #include "collada/scene.h" +#include "collada/animate.h" #include "collada/types.h" #include "collada/instance_types.h" #include "flame.h" @@ -188,16 +189,18 @@ void load() scene_state.load_scene(&eidelwind::descriptor); node_eye = scene_state.find_node_by_name("Camera001"); assert(node_eye != nullptr); - view::state.eye = XMVector3Transform(XMVectorZero(), node_eye->world); + view::state.eye = XMVectorSet(26.85, 10.71, 53.34, 0); + //view::state.eye = XMVector3Transform(XMVectorZero(), node_eye->world); node_at = scene_state.find_node_by_name("Camera001.Target"); assert(node_at != nullptr); - view::state.at = XMVector3Transform(XMVectorZero(), node_at->world); + view::state.at = XMVectorSet(17.07, 10.61, 51.38, 0); + //view::state.at = XMVector3Transform(XMVectorZero(), node_at->world); view::state.direction = XMVector3Normalize(view::state.at - view::state.eye); view::state.normal = XMVector3Cross(view::state.direction, view::state.up); view::state.forward = -XMVector3Cross(view::state.normal, view::state.up); - view::state.pitch = 0; + view::state.pitch = -0.19; ////////////////////////////////////////////////////////////////////// // flame @@ -350,7 +353,7 @@ void update_joystick(float lx, float ly, int leftshoulder, int rightshoulder, int start) { - float translate_rate = 2.0; + float translate_rate = 0.5; float forward = -ly * translate_rate; float strafe = lx * translate_rate; @@ -399,11 +402,15 @@ void update_joystick(float lx, float ly, */ } +static float ext_position = 0; + void update(float time) { current_time = time; scene_state.update(time); + + ext_position = collada::animate::loop(time, 10); /* view::state.eye = XMVector3Transform(XMVectorZero(), node_eye->world); if (node_at == nullptr) @@ -477,7 +484,7 @@ void draw() glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(-1.0f); - if (false) { + if (true) { // possibly re-initialize geometry buffer if window width/height changes init_geometry_buffer(geometry_buffer_pnc, geometry_buffer_pnc_types); @@ -486,11 +493,21 @@ void draw() minecraft::draw(); - non_block::draw(); + //non_block::draw(); flame::draw(minecraft::current_world->light_uniform_buffer, minecraft::current_world->light_count); + float scale = 0.03f; + float pos = ext_position * 51.228f * scale * 2.0f; + + XMMATRIX ext_transform + = XMMatrixScaling(scale, scale, scale) + * XMMatrixRotationZ(XM_PI * 0.5f) + * XMMatrixTranslation(8 + pos, 11, 50.5); + + scene_state.draw(ext_transform); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -506,7 +523,7 @@ void draw() } else { glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - scene_state.draw(); + //scene_state.draw(); hud::draw(); }