From 37e0b80b6829e46092ed83b6c3122acab3ef8693 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Sat, 26 Apr 2025 02:50:06 -0500 Subject: [PATCH] render_model: use numeric conversion from float --- color_convert.py | 29 +++++++++++++++++++++++++++++ fixed_point.py | 16 ++++++++++++++-- render_model.py | 10 +++++----- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/color_convert.py b/color_convert.py index 4a8a369..12b218f 100644 --- a/color_convert.py +++ b/color_convert.py @@ -45,6 +45,23 @@ class color_format: ("axxx4444", color_format.axxx4444), ])[s] +class unconvert_color_format: + def argb1555(value): + a = (value >> 15) & 0b1 + r = (value >> 10) & 0b11111 + g = (value >> 5 ) & 0b11111 + b = (value >> 0 ) & 0b11111 + return (r * 8, g * 8, b * 8, a * 255) + + def from_string(s): + return dict([ + #("gbgr1555", unconvert_color_format.gbgr1555), + #("argb4444", unconvert_color_format.argb4444), + ("argb1555", unconvert_color_format.argb1555), + #("rgb565", unconvert_color_format.rgb565), + #("axxx4444", unconvert_color_format.axxx4444), + ])[s] + def convert_colors(convert, colors): for color in colors: value = convert(*color) @@ -122,6 +139,12 @@ def write_mips(f, im: Image, is_twiddled: bool, convert): for mip in generate_mips(im): write_mip(f, mip, is_twiddled, convert) +def write_png_reference(size, filename, unconvert, colors): + im = Image.new("RGBA", size) + data = [unconvert(value) for value in colors] + im.putdata(data) + im.save(filename) + def main(): in_file = sys.argv[1] format = sys.argv[2] @@ -130,6 +153,7 @@ def main(): assert sys.argv[4] in {"mipmapped", "non_mipmapped"} is_mipmapped = sys.argv[4] == "mipmapped" out_file = sys.argv[5] + ref_file = sys.argv[6] if len(sys.argv) > 6 else None convert = color_format.from_string(format) @@ -145,6 +169,11 @@ def main(): write_mips(f, im, is_twiddled, convert) else: write_mip(f, im, is_twiddled, convert) + """ + if ref_file is not None: + unconvert = unconvert_color_format.from_string(format) + write_png_reference(im.size, ref_file, unconvert, colors) + """ else: assert False pixels = list(im.convert("P").getdata()) diff --git a/fixed_point.py b/fixed_point.py index b105407..ea36c00 100644 --- a/fixed_point.py +++ b/fixed_point.py @@ -47,8 +47,8 @@ def parse(s): sign = -1 if s.startswith('-') else 1 s = s.removeprefix('-') integer, fraction = s.split('.') - assert all(c in string.digits for c in integer), integer - assert all(c in string.digits for c in fraction), fraction + assert all(c in string.digits for c in integer), (integer, s) + assert all(c in string.digits for c in fraction), (fraction, s) assert len(integer) > 0 and len(fraction) > 0, s point = 10 ** len(fraction) value = int(integer) * point + int(fraction) @@ -58,6 +58,18 @@ def parse(s): point ) +def from_float(f): + sign = -1 if f < 0 else 1 + f = f * sign + + point = 10 ** 6 + value = int(f * point) + return FixedPoint( + sign, + value, + point + ) + def equal(a, b): epsilon = 0.00001 return (a - b) < epsilon diff --git a/render_model.py b/render_model.py index 30460d7..94f8a45 100644 --- a/render_model.py +++ b/render_model.py @@ -25,7 +25,7 @@ def render_face(face): yield "}}," def render_faces(prefix, name, faces): - yield f"union {name} {prefix}_{name}[] = {{" + yield f"const union {name} {prefix}_{name}[] = {{" for face in faces: yield from render_face(face) yield "};" @@ -42,9 +42,9 @@ def unit_vector(vec): z = vec.z.to_float() norm = math.sqrt(x ** 2 + y ** 2 + z ** 2) return type(vec)( - fixed_point.parse(f"{x / norm:f}"), - fixed_point.parse(f"{y / norm:f}"), - fixed_point.parse(f"{z / norm:f}") + fixed_point.from_float(x / norm), + fixed_point.from_float(y / norm), + fixed_point.from_float(z / norm) ) def xyz(vec): @@ -113,7 +113,7 @@ def render_object(prefix, object_name, d, material): yield f".quadrilateral_count = {quadrilateral_count}," if material is None: - yield f".material = -1,", + yield f".material = -1," else: yield f".material = {prefix}_{material.name},"