diff --git a/Makefile b/Makefile index 25f67c2..2254f7a 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,7 @@ all: include common.mk geometry/%.hpp: geometry/%.obj - PYTHONPATH=regs/gen python tools/obj_to_cpp.py $< > $@ + PYTHONPATH=regs/gen python tools/obj_to_cpp.py $< > $@.tmp + mv $@.tmp $@ include example/example.mk diff --git a/example/example.mk b/example/example.mk index d0583af..a9d50d6 100644 --- a/example/example.mk +++ b/example/example.mk @@ -129,6 +129,17 @@ WIFFLE_ATTENUATION_OBJ = \ example/wiffle_attenuation.elf: LDSCRIPT = $(LIB)/alt.lds example/wiffle_attenuation.elf: $(START_OBJ) $(WIFFLE_ATTENUATION_OBJ) +MODIFIER_VOLUME_OBJ = \ + example/modifier_volume.o \ + vga.o \ + holly/core.o \ + holly/region_array.o \ + holly/background.o \ + holly/ta_fifo_polygon_converter.o + +example/modifier_volume.elf: LDSCRIPT = $(LIB)/alt.lds +example/modifier_volume.elf: $(START_OBJ) $(MODIFIER_VOLUME_OBJ) + MACAW_CUBE_OBJ = \ example/macaw_cube.o \ vga.o \ diff --git a/example/icosphere.cpp b/example/icosphere.cpp index d997765..7482bd4 100644 --- a/example/icosphere.cpp +++ b/example/icosphere.cpp @@ -23,7 +23,8 @@ constexpr float half_degree = 0.01745329f / 2; #define MODEL suzanne -vec3 rotate(const vec3& vertex, float theta) +vec3 rotate(const vec3& vertex, + const float theta) { float x = vertex.x; float y = vertex.y; diff --git a/example/modifier_volume.cpp b/example/modifier_volume.cpp index f541b2d..3ed4db4 100644 --- a/example/modifier_volume.cpp +++ b/example/modifier_volume.cpp @@ -14,70 +14,155 @@ #include "holly/background.hpp" #include "memorymap.hpp" -struct vertex { - float x; - float y; - float z; - float u; - float v; - uint32_t color; -}; +#include "geometry/plane.hpp" +#include "geometry/cube.hpp" +#include "math/vec3.hpp" +#include "math/vec4.hpp" -const struct vertex strip_vertices[4] = { - // [ position ] [ uv coordinates ] [color ] - { -0.5f, 0.5f, 0.f, 0.f , 127.f/128.f, 0x00000000}, // the first two base colors in a - { -0.5f, -0.5f, 0.f, 0.f , 0.f , 0x00000000}, // non-Gouraud triangle strip are ignored - { 0.5f, 0.5f, 0.f, 127.f/128.f, 127.f/128.f, 0x00000000}, - { 0.5f, -0.5f, 0.f, 127.f/128.f, 0.f , 0x00000000}, -}; -constexpr uint32_t strip_length = (sizeof (strip_vertices)) / (sizeof (struct vertex)); - -static float theta = 0; -constexpr float half_degree = 0.01745329f / 2.f; - -uint32_t transform(uint32_t * ta_parameter_buf, - const vertex * strip_vertices, - const uint32_t strip_length) +vec3 _transform(const vec3& point, + const uint32_t scale, + const float theta) { - auto parameter = ta_parameter_writer(ta_parameter_buf); - uint32_t texture_address = (offsetof (struct texture_memory_alloc, texture)); - parameter.append() = global_polygon_type_0(texture_address); + float x = point.x; + float y = point.y; + float z = point.z; + float t; + // object transform + t = z * cos(theta) - x * sin(theta); + x = z * sin(theta) + x * cos(theta); + z = t; + + x *= scale; + y *= scale; + z *= scale; + + // world transform + y += 2.0f; + x *= 0.8; + y *= 0.8; + z *= 0.8; + + // camera transform + z += 4; + + // perspective + x = x / z; + y = y / z; + + // screen space transform + x *= 240.f; + y *= 240.f; + x += 320.f; + y += 240.f; + z = 1 / z; + + return {x, y, z}; +} + +void transform_polygon(ta_parameter_writer& parameter, + const vec3 * vertices, + const face& face, + const float scale, + const vec4& color, + const float theta) +{ + const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume + | para_control::list_type::opaque + | obj_control::col_type::floating_color + | obj_control::shadow; + + const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::greater + | isp_tsp_instruction_word::culling_mode::no_culling; + + const uint32_t tsp_instruction_word = tsp_instruction_word::src_alpha_instr::one + | tsp_instruction_word::dst_alpha_instr::zero + | tsp_instruction_word::fog_control::no_fog; + + parameter.append() = global_polygon_type_0(parameter_control_word, + isp_tsp_instruction_word, + tsp_instruction_word, + 0); + + constexpr uint32_t strip_length = 3; for (uint32_t i = 0; i < strip_length; i++) { + // world transform + uint32_t vertex_ix = face[i].vertex; + auto& vertex = vertices[vertex_ix]; + auto point = _transform(vertex, scale, theta); + bool end_of_strip = i == strip_length - 1; - - float x = strip_vertices[i].x; - float y = strip_vertices[i].y; - float z = strip_vertices[i].z; - float x1; - - x1 = x * __builtin_cosf(theta) - z * __builtin_sinf(theta); - z = x * __builtin_sinf(theta) + z * __builtin_cosf(theta); - x = x1; - x *= 240.f; - y *= 240.f; - x += 320.f; - y += 240.f; - z = 1.f / (z + 10.f); - - parameter.append() = - vertex_polygon_type_3(x, y, z, - strip_vertices[i].u, - strip_vertices[i].v, - strip_vertices[i].color, - end_of_strip); + parameter.append() = + vertex_polygon_type_1(polygon_vertex_parameter_control_word(end_of_strip), + point.x, + point.y, + point.z, + color.a, // alpha + color.r, // red + color.g, // green + color.b // blue + ); } +} - parameter.append() = global_end_of_list(); +void transform_modifier_volume(ta_parameter_writer& parameter, + const vec3 * vertices, + const face * faces, + const uint32_t num_faces, + const float scale) +{ + const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume + | para_control::list_type::opaque_modifier_volume + // | group_control::group_en + // | group_control::user_clip::inside_enable + ; - return parameter.offset; + const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::volume_instruction::normal_polygon + | isp_tsp_instruction_word::culling_mode::no_culling; + + parameter.append() = + global_modifier_volume(parameter_control_word, + isp_tsp_instruction_word); + + for (uint32_t i = 0; i < num_faces; i++) { + // world transform + uint32_t ix_a = faces[i][0].vertex; + uint32_t ix_b = faces[i][1].vertex; + uint32_t ix_c = faces[i][2].vertex; + auto& _a = vertices[ix_a]; + auto& _b = vertices[ix_b]; + auto& _c = vertices[ix_c]; + auto a = _transform(_a, scale, 0.f); + auto b = _transform(_b, scale, 0.f); + auto c = _transform(_c, scale, 0.f); + + if (i == (num_faces - 1)) { + const uint32_t last_parameter_control_word = para_control::para_type::polygon_or_modifier_volume + | para_control::list_type::opaque_modifier_volume + | obj_control::volume::modifier_volume::last_in_volume; + + const uint32_t last_isp_tsp_instruction_word = isp_tsp_instruction_word::volume_instruction::inside_last_polygon + | isp_tsp_instruction_word::culling_mode::no_culling; + + parameter.append() = + global_modifier_volume(last_parameter_control_word, + last_isp_tsp_instruction_word); + + } + + parameter.append() = + vertex_modifier_volume(modifier_volume_vertex_parameter_control_word(), + a.x, a.y, a.z, + b.x, b.y, b.z, + c.x, c.y, c.z); + } } void init_texture_memory(const struct opb_size& opb_size) { auto mem = reinterpret_cast(texture_memory32); - background_parameter(mem->background); + background_parameter(mem->background, 0xff220000); region_array2(mem->region_array, (offsetof (struct texture_memory_alloc, object_list)), @@ -87,27 +172,11 @@ void init_texture_memory(const struct opb_size& opb_size) ); } -void copy_macaw_texture() -{ - auto src = reinterpret_cast(&_binary_macaw_data_start); - auto size = reinterpret_cast(&_binary_macaw_data_size); - auto mem = reinterpret_cast(texture_memory64); - for (uint32_t px = 0; px < size / 3; px++) { - uint8_t r = src[px * 3 + 0]; - uint8_t g = src[px * 3 + 1]; - uint8_t b = src[px * 3 + 2]; - - uint16_t rgb565 = ((r / 8) << 11) | ((g / 4) << 5) | ((b / 8) << 0); - mem->texture[px] = rgb565; - } -} - -uint32_t _ta_parameter_buf[((32 * (strip_length + 2)) + 32) / 4]; +uint32_t _ta_parameter_buf[((32 * 8192) + 32) / 4]; void main() { vga(); - copy_macaw_texture(); // The address of `ta_parameter_buf` must be a multiple of 32 bytes. // This is mandatory for ch2-dma to the ta fifo polygon converter. @@ -116,18 +185,16 @@ void main() constexpr uint32_t ta_alloc = ta_alloc_ctrl::pt_opb::no_list | ta_alloc_ctrl::tm_opb::no_list | ta_alloc_ctrl::t_opb::no_list - | ta_alloc_ctrl::om_opb::no_list + | ta_alloc_ctrl::om_opb::_16x4byte | ta_alloc_ctrl::o_opb::_16x4byte; constexpr struct opb_size opb_size = { .opaque = 16 * 4 - , .opaque_modifier = 0 + , .opaque_modifier = 16 * 4 , .translucent = 0 , .translucent_modifier = 0 , .punch_through = 0 }; - constexpr uint32_t tiles = (640 / 32) * (320 / 32); - holly.SOFTRESET = softreset::pipeline_soft_reset | softreset::ta_soft_reset; holly.SOFTRESET = 0; @@ -138,17 +205,59 @@ void main() uint32_t frame_ix = 0; constexpr uint32_t num_frames = 1; + float theta = 0; + while (true) { - ta_polygon_converter_init(opb_size.total() * tiles, ta_alloc); - uint32_t ta_parameter_size = transform(ta_parameter_buf, strip_vertices, strip_length); - ta_polygon_converter_transfer(ta_parameter_buf, ta_parameter_size); - ta_wait_opaque_list(); + ta_polygon_converter_init(opb_size.total(), + ta_alloc, + 640 / 32, + 480 / 32); + auto parameter = ta_parameter_writer(ta_parameter_buf); + { // plane + vec4 color = {1.0, 0.9, 0.4, 0.2}; + float scale = 2.f; + for (uint32_t i = 0; i < plane::num_faces; i++) { + transform_polygon(parameter, + plane::vertices, + plane::faces[i], + scale, + color, + theta); + } + + /* + for (uint32_t i = 0; i < cube::num_faces; i++) { + transform_polygon(parameter, + cube::vertices, + cube::faces[i], + 1.f, + {1.0f, 0.0f, 1.0f, 0.0f}); + } + */ + } + // end of opaque list + parameter.append() = global_end_of_list(); + + { // cube + float scale = 1.f; + transform_modifier_volume(parameter, + cube::vertices, + cube::faces, + cube::num_faces, + scale); + } + // end of opaque modifier list + parameter.append() = global_end_of_list(); + + ta_polygon_converter_transfer(ta_parameter_buf, parameter.offset); + ta_wait_opaque_modifier_volume_list(); core_start_render(frame_ix, num_frames); v_sync_in(); core_wait_end_of_render_video(frame_ix, num_frames); + constexpr float half_degree = 0.01745329f / 2; theta += half_degree; frame_ix += 1; } diff --git a/example/wiffle_attenuation.cpp b/example/wiffle_attenuation.cpp index 23c97e8..d87b24e 100644 --- a/example/wiffle_attenuation.cpp +++ b/example/wiffle_attenuation.cpp @@ -15,8 +15,6 @@ #include "memorymap.hpp" #include "serial.hpp" -#include "geometry/icosphere.hpp" -#include "geometry/suzanne.hpp" #include "geometry/wiffle.hpp" #include "math/vec4.hpp" diff --git a/geometry/cube.hpp b/geometry/cube.hpp index e69de29..3a3b11d 100644 --- a/geometry/cube.hpp +++ b/geometry/cube.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include "geometry.hpp" + +namespace cube { + constexpr vec3 vertices[] = { + { -1.000000f, -1.000000f, 1.000000f }, + { -1.000000f, 1.000000f, 1.000000f }, + { -1.000000f, -1.000000f, -1.000000f }, + { -1.000000f, 1.000000f, -1.000000f }, + { 1.000000f, -1.000000f, 1.000000f }, + { 1.000000f, 1.000000f, 1.000000f }, + { 1.000000f, -1.000000f, -1.000000f }, + { 1.000000f, 1.000000f, -1.000000f }, + }; + + constexpr vec2 texture[] = { + { 1.000000f, 1.000000f }, + { 1.000000f, 0.000000f }, + { 0.000000f, 1.000000f }, + { 0.000000f, 0.000000f }, + }; + + constexpr vec3 normals[] = { + { -1.000000f, -0.000000f, -0.000000f }, + { -0.000000f, -0.000000f, -1.000000f }, + { 1.000000f, -0.000000f, -0.000000f }, + { -0.000000f, -0.000000f, 1.000000f }, + { -0.000000f, -1.000000f, -0.000000f }, + { -0.000000f, 1.000000f, -0.000000f }, + }; + + constexpr face faces[] = { + {{1, 0, 0}, {2, 0, 0}, {0, 1, 0}}, + {{3, 1, 1}, {6, 2, 1}, {2, 3, 1}}, + {{7, 0, 2}, {4, 3, 2}, {6, 1, 2}}, + {{5, 2, 3}, {0, 1, 3}, {4, 3, 3}}, + {{6, 2, 4}, {0, 1, 4}, {2, 0, 4}}, + {{3, 1, 5}, {5, 2, 5}, {7, 3, 5}}, + {{1, 0, 0}, {3, 1, 0}, {2, 0, 0}}, + {{3, 1, 1}, {7, 0, 1}, {6, 2, 1}}, + {{7, 0, 2}, {5, 2, 2}, {4, 3, 2}}, + {{5, 2, 3}, {1, 0, 3}, {0, 1, 3}}, + {{6, 2, 4}, {4, 3, 4}, {0, 1, 4}}, + {{3, 1, 5}, {1, 0, 5}, {5, 2, 5}}, + }; + + constexpr uint32_t num_faces = (sizeof (faces)) / (sizeof (face)); + +} diff --git a/geometry/geometry.hpp b/geometry/geometry.hpp index cf47830..cd865a5 100644 --- a/geometry/geometry.hpp +++ b/geometry/geometry.hpp @@ -10,10 +10,10 @@ using vec2 = vec<2, float>; using vec3 = vec<3, float>; using vec4 = vec<4, float>; -struct vertex__normal { +struct vertex__texture__normal { uint16_t vertex; uint16_t texture; uint16_t normal; }; -using face = vertex__normal[3]; +using face = vertex__texture__normal[3]; diff --git a/geometry/plane.hpp b/geometry/plane.hpp new file mode 100644 index 0000000..79af336 --- /dev/null +++ b/geometry/plane.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include "geometry.hpp" + +namespace plane { + constexpr vec3 vertices[] = { + { -1.000000f, 0.000000f, 1.000000f }, + { 1.000000f, 0.000000f, 1.000000f }, + { -1.000000f, 0.000000f, -1.000000f }, + { 1.000000f, 0.000000f, -1.000000f }, + }; + + constexpr vec2 texture[] = { + { 1.000000f, 0.000000f }, + { 0.000000f, 1.000000f }, + { 0.000000f, 0.000000f }, + { 1.000000f, 1.000000f }, + }; + + constexpr vec3 normals[] = { + { -0.000000f, 1.000000f, -0.000000f }, + }; + + constexpr face faces[] = { + {{1, 0, 0}, {2, 1, 0}, {0, 2, 0}}, + {{1, 0, 0}, {3, 3, 0}, {2, 1, 0}}, + }; + + constexpr uint32_t num_faces = (sizeof (faces)) / (sizeof (face)); + +} diff --git a/holly/core.cpp b/holly/core.cpp index d712f8d..061f914 100644 --- a/holly/core.cpp +++ b/holly/core.cpp @@ -16,7 +16,8 @@ void core_init() holly.ISP_FEED_CFG = isp_feed_cfg::cache_size_for_translucency(0x200) | isp_feed_cfg::punch_through_chunk_size(0x040); - holly.FPU_SHAD_SCALE = fpu_shad_scale::scale_factor_for_shadows(1); + holly.FPU_SHAD_SCALE = fpu_shad_scale::simple_shadow_enable::intensity_volume_mode + | fpu_shad_scale::scale_factor_for_shadows(127); holly.FPU_CULL_VAL = _i(1.f); holly.FPU_PERP_VAL = _i(0.f); holly.SPAN_SORT_CFG = span_sort_cfg::span_sort_enable @@ -81,6 +82,8 @@ void core_start_render(uint32_t frame_ix, uint32_t num_frames) frame_ix, num_frames); } +static bool flycast_bug = 0; + void core_wait_end_of_render_video() { /* diff --git a/holly/isp_tsp.hpp b/holly/isp_tsp.hpp index e1d524a..9886b30 100644 --- a/holly/isp_tsp.hpp +++ b/holly/isp_tsp.hpp @@ -12,6 +12,12 @@ namespace isp_tsp_instruction_word { constexpr uint32_t always = 7 << 29; } + namespace volume_instruction { + constexpr uint32_t normal_polygon = 0 << 29; + constexpr uint32_t inside_last_polygon = 1 << 29; + constexpr uint32_t outside_last_polygon = 1 << 29; + } + namespace culling_mode { constexpr uint32_t no_culling = 0 << 27; constexpr uint32_t cull_if_small = 1 << 27; // compared to FPU_CULL_VAL diff --git a/holly/ta_fifo_polygon_converter.cpp b/holly/ta_fifo_polygon_converter.cpp index 904a6d2..feab290 100644 --- a/holly/ta_fifo_polygon_converter.cpp +++ b/holly/ta_fifo_polygon_converter.cpp @@ -111,6 +111,13 @@ void ta_wait_opaque_list() system.ISTNRM = ISTNRM__END_OF_TRANSFERRING_OPAQUE_LIST; } +void ta_wait_opaque_modifier_volume_list() +{ + while ((system.ISTNRM & ISTNRM__END_OF_TRANSFERRING_OPAQUE_MODIFIER_VOLUME_LIST) == 0); + + system.ISTNRM = ISTNRM__END_OF_TRANSFERRING_OPAQUE_MODIFIER_VOLUME_LIST; +} + void ta_wait_translucent_list() { while ((system.ISTNRM & ISTNRM__END_OF_TRANSFERRING_TRANSLUCENT_LIST) == 0); diff --git a/holly/ta_fifo_polygon_converter.hpp b/holly/ta_fifo_polygon_converter.hpp index 29f36d2..dab1fd8 100644 --- a/holly/ta_fifo_polygon_converter.hpp +++ b/holly/ta_fifo_polygon_converter.hpp @@ -10,5 +10,6 @@ void ta_polygon_converter_cont(uint32_t ol_base_offset, uint32_t ta_alloc); void ta_polygon_converter_transfer(volatile uint32_t * buf, uint32_t size); void ta_wait_opaque_list(); +void ta_wait_opaque_modifier_volume_list(); void ta_wait_translucent_list(); void ta_wait_punch_through_list(); diff --git a/holly/ta_parameter.hpp b/holly/ta_parameter.hpp index 6548e20..dff45e8 100644 --- a/holly/ta_parameter.hpp +++ b/holly/ta_parameter.hpp @@ -44,7 +44,14 @@ namespace group_control { namespace obj_control { constexpr uint32_t shadow = 1 << 7; - constexpr uint32_t volume = 1 << 6; + namespace volume { + namespace polygon { + constexpr uint32_t with_two_volumes = 1 << 6; + } + namespace modifier_volume { + constexpr uint32_t last_in_volume = 1 << 6; + } + } namespace col_type { constexpr uint32_t packed_color = 0 << 4; @@ -61,6 +68,20 @@ namespace obj_control { static_assert((sizeof (float)) == (sizeof (uint32_t))); +constexpr uint32_t polygon_vertex_parameter_control_word(const bool end_of_strip) +{ + return para_control::para_type::vertex_parameter + | (end_of_strip ? para_control::end_of_strip : 0); +} + +constexpr uint32_t modifier_volume_vertex_parameter_control_word() +{ + // DCDBSysArc990907E page 212 indirectly suggests the end_of_strip bit should + // always be set. + return para_control::para_type::vertex_parameter + | para_control::end_of_strip; +} + struct vertex_polygon_type_0 { uint32_t parameter_control_word; float x; @@ -71,15 +92,13 @@ struct vertex_polygon_type_0 { uint32_t base_color; uint32_t _res2; - vertex_polygon_type_0(const float x, + vertex_polygon_type_0(const uint32_t parameter_control_word, + const float x, const float y, const float z, - const uint32_t base_color, - const bool end_of_strip + const uint32_t base_color ) - : parameter_control_word( para_control::para_type::vertex_parameter - | (end_of_strip ? para_control::end_of_strip : 0) - ) + : parameter_control_word(parameter_control_word) , x(x) , y(y) , z(z) @@ -100,18 +119,16 @@ struct vertex_polygon_type_1 { float base_color_g; float base_color_b; - vertex_polygon_type_1(const float x, + vertex_polygon_type_1(const uint32_t parameter_control_word, + const float x, const float y, const float z, const float base_color_alpha, const float base_color_r, const float base_color_g, - const float base_color_b, - const bool end_of_strip + const float base_color_b ) - : parameter_control_word( para_control::para_type::vertex_parameter - | (end_of_strip ? para_control::end_of_strip : 0) - ) + : parameter_control_word(parameter_control_word) , x(x) , y(y) , z(z) @@ -132,15 +149,13 @@ struct vertex_polygon_type_2 { float base_intensity; uint32_t _res2; - vertex_polygon_type_2(const float x, + vertex_polygon_type_2(const uint32_t parameter_control_word, + const float x, const float y, const float z, - const float base_intensity, - const bool end_of_strip + const float base_intensity ) - : parameter_control_word( para_control::para_type::vertex_parameter - | (end_of_strip ? para_control::end_of_strip : 0) - ) + : parameter_control_word(parameter_control_word) , x(x) , y(y) , z(z) @@ -161,17 +176,15 @@ struct vertex_polygon_type_3 { uint32_t base_color; uint32_t offset_color; - vertex_polygon_type_3(const float x, + vertex_polygon_type_3(const uint32_t parameter_control_word, + const float x, const float y, const float z, const float u, const float v, - const uint32_t base_color, - const bool end_of_strip + const uint32_t base_color ) - : parameter_control_word( para_control::para_type::vertex_parameter - | (end_of_strip ? para_control::end_of_strip : 0) - ) + : parameter_control_word(parameter_control_word) , x(x) , y(y) , z(z) @@ -202,16 +215,14 @@ struct vertex_polygon_type_4 { uint32_t base_color; uint32_t offset_color; - vertex_polygon_type_4(const float x, + vertex_polygon_type_4(const uint32_t parameter_control_word, + const float x, const float y, const float z, const uint32_t uv, - const uint32_t base_color, - const bool end_of_strip + const uint32_t base_color ) - : parameter_control_word( para_control::para_type::vertex_parameter - | (end_of_strip ? para_control::end_of_strip : 0) - ) + : parameter_control_word(parameter_control_word) , x(x) , y(y) , z(z) @@ -367,6 +378,31 @@ struct global_sprite { static_assert((sizeof (global_sprite)) == 32); +struct global_modifier_volume { + uint32_t parameter_control_word; + uint32_t isp_tsp_instruction_word; + uint32_t _res0; + uint32_t _res1; + uint32_t _res2; + uint32_t _res3; + uint32_t _res4; + uint32_t _res5; + + global_modifier_volume(const uint32_t parameter_control_word, + const uint32_t isp_tsp_instruction_word) + : parameter_control_word(parameter_control_word) + , isp_tsp_instruction_word(isp_tsp_instruction_word) + , _res0(0) + , _res1(0) + , _res2(0) + , _res3(0) + , _res4(0) + , _res5(0) + { } +}; + +static_assert((sizeof (global_modifier_volume)) == 32); + struct vertex_sprite_type_0 { uint32_t parameter_control_word; float ax; @@ -470,6 +506,56 @@ struct vertex_sprite_type_1 { static_assert((sizeof (vertex_sprite_type_1)) == 64); +struct vertex_modifier_volume { + uint32_t parameter_control_word; + float ax; + float ay; + float az; + float bx; + float by; + float bz; + float cx; + float cy; + float cz; + float _res0; + float _res1; + float _res2; + float _res3; + float _res4; + float _res5; + + vertex_modifier_volume(const uint32_t parameter_control_word, + const float ax, + const float ay, + const float az, + const float bx, + const float by, + const float bz, + const float cx, + const float cy, + const float cz + ) + : parameter_control_word(parameter_control_word) + , ax(ax) + , ay(ay) + , az(az) + , bx(bx) + , by(by) + , bz(bz) + , cx(cx) + , cy(cy) + , cz(cz) + , _res0(0) + , _res1(0) + , _res2(0) + , _res3(0) + , _res4(0) + , _res5(0) + { } +}; + +static_assert((sizeof (vertex_modifier_volume)) == 64); + struct global_end_of_list { uint32_t parameter_control_word; uint32_t _res0; diff --git a/math/vec2.hpp b/math/vec2.hpp index 1197ce2..dc76b80 100644 --- a/math/vec2.hpp +++ b/math/vec2.hpp @@ -28,12 +28,12 @@ struct vec<2, T> template inline constexpr vec<2, T>::vec() - : x(0), y(0), z(0) + : x(0), y(0) {} template inline constexpr vec<2, T>::vec(T scalar) - : x(scalar), y(scalar), z(scalar) + : x(scalar), y(scalar) {} template @@ -55,7 +55,6 @@ inline constexpr T const& vec<2, T>::operator[](int i) const default: [[fallthrough]]; case 0: return x; case 1: return y; - case 2: return z; } } diff --git a/math/vec4.hpp b/math/vec4.hpp index 4db56d7..bbf7813 100644 --- a/math/vec4.hpp +++ b/math/vec4.hpp @@ -12,8 +12,8 @@ struct vec<4, T> { union { struct { T x, y, z, w; }; - struct { T r, g, b, a; }; - } + struct { T a, r, g, b; }; + }; inline constexpr vec(); inline constexpr vec(T scalar); diff --git a/tools/obj_to_cpp.py b/tools/obj_to_cpp.py index 2cb67ab..17a7919 100644 --- a/tools/obj_to_cpp.py +++ b/tools/obj_to_cpp.py @@ -1,3 +1,4 @@ +import math from dataclasses import dataclass import sys @@ -87,9 +88,18 @@ def generate_texture_coordinates(texture_coordinates): yield "" def generate_faces(faces): + max_ix = max( + i + for f in faces + for vtn in f + for i in [vtn.vertex, vtn.texture, vtn.normal] + ) + align = 1 + math.floor(math.log(max_ix) / math.log(10)) yield "constexpr face faces[] = {" + def align_vtn(vtn): + return ", ".join(str(ix).rjust(align) for ix in [vtn.vertex, vtn.texture, vtn.normal]) for f in faces: - inner = ", ".join(f"{{{vtn.vertex:3}, {vtn.texture:3}, {vtn.normal:3}}}" for vtn in f) + inner = ", ".join(f"{{{align_vtn(vtn)}}}" for vtn in f) yield f"{{{inner}}}," yield "};" yield ""