render_model: use numeric conversion from float

This commit is contained in:
Zack Buhman 2025-04-26 02:50:06 -05:00
parent 99856aa1b9
commit 37e0b80b68
3 changed files with 48 additions and 7 deletions

View File

@ -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())

View File

@ -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

View File

@ -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},"