From 5f389391c2acf21ec4fbd16d11d667717ba42f19 Mon Sep 17 00:00:00 2001 From: Lila Date: Tue, 10 Sep 2024 09:57:35 +0100 Subject: [PATCH] [SM64/F3D] Fix and update Ui Image Exporter Fixes #451 Missing: Load and set commands and pallets (currently relying on multitex manager, will have to be changed somehow) Updated: Tex prop is now drawn using ui_image, ui_image has been updated to optionally hide low and high props (are handled by size cmd, does not exist for texrect) materialless_setup func for TexInfo, equivelant to moreSetupFromModel for bpy material-less contexts, obviously cannot handle flipbooks ignore_tex_set bool for fromProp Use only fromProp and updated writeAll Some basic ui reordering to match other panels --- fast64_internal/f3d/f3d_material.py | 4 +- fast64_internal/f3d/f3d_texture_writer.py | 36 ++++++++++++++-- fast64_internal/sm64/sm64_f3d_writer.py | 52 ++++------------------- 3 files changed, 45 insertions(+), 47 deletions(-) diff --git a/fast64_internal/f3d/f3d_material.py b/fast64_internal/f3d/f3d_material.py index f4be233ed..71a6147f7 100644 --- a/fast64_internal/f3d/f3d_material.py +++ b/fast64_internal/f3d/f3d_material.py @@ -2919,6 +2919,7 @@ def ui_image( textureProp: TextureProperty, name: str, showCheckBox: bool, + hide_lowhigh=False, ): inputGroup = layout.box().column() @@ -3025,7 +3026,8 @@ def ui_image( shift = prop_input.row() shift.prop(textureProp.S, "shift", text="Shift S") shift.prop(textureProp.T, "shift", text="Shift T") - + if hide_lowhigh: + return low = prop_input.row() low.prop(textureProp.S, "low", text="S Low") low.prop(textureProp.T, "low", text="T Low") diff --git a/fast64_internal/f3d/f3d_texture_writer.py b/fast64_internal/f3d/f3d_texture_writer.py index d08d80ced..9d4dcb0b4 100644 --- a/fast64_internal/f3d/f3d_texture_writer.py +++ b/fast64_internal/f3d/f3d_texture_writer.py @@ -420,10 +420,10 @@ def fromMat(self, index: int, f3dMat: F3DMaterialProperty) -> bool: texProp = getattr(f3dMat, "tex" + str(index)) return self.fromProp(texProp, index) - def fromProp(self, texProp: TextureProperty, index: int) -> bool: + def fromProp(self, texProp: TextureProperty, index: int, ignore_tex_set=False) -> bool: self.indexInMat = index self.texProp = texProp - if not texProp.tex_set: + if not texProp.tex_set and not ignore_tex_set: return True self.useTex = True @@ -463,6 +463,33 @@ def fromProp(self, texProp: TextureProperty, index: int) -> bool: return True + def materialless_setup(self) -> None: + """moreSetupFromModel equivelent that does not handle material properties like OOT flipbooks""" + if not self.useTex: + return + + if self.isTexCI: + self.imDependencies, self.flipbook, self.pal = ( + [] if self.texProp.tex is None else [self.texProp.tex], + None, + None, + ) + if self.isTexRef: + self.palLen = self.texProp.pal_reference_size + else: + assert self.flipbook is None + self.pal = getColorsUsedInImage(self.texProp.tex, self.palFormat) + self.palLen = len(self.pal) + if self.palLen > (16 if self.texFormat == "CI4" else 256): + raise PluginError( + f"Error in Texture {self.indexInMat} uses too many unique colors to fit in format {self.texFormat}." + ) + else: + self.imDependencies, self.flipbook = [] if self.texProp.tex is None else [self.texProp.tex], None + + self.isPalRef = self.isTexRef and self.flipbook is None + self.palDependencies = self.imDependencies + def moreSetupFromModel( self, material: bpy.types.Material, @@ -514,7 +541,7 @@ def writeAll( return assert ( self.imDependencies is not None - ) # Must be set manually if didn't use moreSetupFromModel, e.g. ti.imDependencies = [tex] + ), "self.imDependencies is None, either moreSetupFromModel or materialless_setup must be called beforehand" # Get definitions imageKey, fImage = saveOrGetTextureDefinition( @@ -551,6 +578,9 @@ def writeAll( fModel.writeTexRefNonCITextures(self.flipbook, self.texFormat) else: if self.isTexCI: + assert ( + self.pal is not None + ), "self.pal is None, either moreSetupFromModel or materialless_setup must be called beforehand" writeCITextureData(self.texProp.tex, fImage, self.pal, self.palFormat, self.texFormat) else: writeNonCITextureData(self.texProp.tex, fImage, self.texFormat) diff --git a/fast64_internal/sm64/sm64_f3d_writer.py b/fast64_internal/sm64/sm64_f3d_writer.py index ab69b095f..555e0d918 100644 --- a/fast64_internal/sm64/sm64_f3d_writer.py +++ b/fast64_internal/sm64/sm64_f3d_writer.py @@ -8,8 +8,8 @@ from ..f3d.f3d_texture_writer import TexInfo from ..f3d.f3d_material import ( TextureProperty, - tmemUsageUI, all_combiner_uses, + ui_image, ui_procAnim, update_world_default_rendermode, ) @@ -283,18 +283,8 @@ def exportTexRectCommon(texProp, name, convertTextureData): if tex is None: raise PluginError("No texture is selected.") - texProp.S.low = 0 - texProp.S.high = texProp.tex.size[0] - 1 - texProp.S.mask = ceil(log(texProp.tex.size[0], 2) - 0.001) - texProp.S.shift = 0 - - texProp.T.low = 0 - texProp.T.high = texProp.tex.size[1] - 1 - texProp.T.mask = ceil(log(texProp.tex.size[1], 2) - 0.001) - texProp.T.shift = 0 - fTexRect = FTexRect(toAlnum(name), GfxMatWriteMethod.WriteDifferingAndRevert) - fMaterial = FMaterial(toAlnum(name) + "_mat", DLFormat.Dynamic) + fMaterial = fTexRect.addMaterial(toAlnum(name) + "_mat") # dl_hud_img_begin fTexRect.draw.commands.extend( @@ -311,21 +301,12 @@ def exportTexRectCommon(texProp, name, convertTextureData): drawEndCommands = GfxList("temp", GfxListTag.Draw, DLFormat.Dynamic) ti = TexInfo() - if not ti.fromProp(texProp, 0): - raise PluginError(f"In {name}: {texProp.errorMsg}.") - if not ti.useTex: - raise PluginError(f"In {name}: texture disabled.") - if ti.isTexCI: - raise PluginError(f"In {name}: CI textures not compatible with exportTexRectCommon (because copy mode).") - if ti.tmemSize > 512: - raise PluginError(f"In {name}: texture is too big (> 4 KiB).") - if ti.texFormat != "RGBA16": - raise PluginError(f"In {name}: texture format must be RGBA16 (because copy mode).") - ti.imDependencies = [tex] - ti.writeAll(fTexRect.draw, fMaterial, fTexRect, convertTextureData) + ti.fromProp(texProp, index=0, ignore_tex_set=True) + ti.materialless_setup() + ti.writeAll(fMaterial, fTexRect, convertTextureData) fTexRect.draw.commands.append( - SPScisTextureRectangle(0, 0, (texDimensions[0] - 1) << 2, (texDimensions[1] - 1) << 2, 0, 0, 0) + SPScisTextureRectangle(0, 0, (ti.imageDims[0] - 1) << 2, (ti.imageDims[1] - 1) << 2, 0, 0, 0) ) fTexRect.draw.commands.extend(drawEndCommands.commands) @@ -822,25 +803,7 @@ class ExportTexRectDrawPanel(SM64_Panel): # called every frame def draw(self, context): col = self.layout.column() - propsTexRectE = col.operator(ExportTexRectDraw.bl_idname) - - textureProp = context.scene.texrect - tex = textureProp.tex - col.label(text="This is for decomp only.") - col.template_ID(textureProp, "tex", new="image.new", open="image.open", unlink="image.texrect_unlink") - # col.prop(textureProp, 'tex') - - tmemUsageUI(col, textureProp) - if tex is not None and tex.size[0] > 0 and tex.size[1] > 0: - col.prop(textureProp, "tex_format", text="Format") - if textureProp.tex_format[:2] == "CI": - col.prop(textureProp, "ci_format", text="CI Format") - col.prop(textureProp.S, "clamp", text="Clamp S") - col.prop(textureProp.T, "clamp", text="Clamp T") - col.prop(textureProp.S, "mirror", text="Mirror S") - col.prop(textureProp.T, "mirror", text="Mirror T") - prop_split(col, context.scene, "TexRectName", "Name") col.prop(context.scene, "TexRectCustomExport") if context.scene.TexRectCustomExport: col.prop(context.scene, "TexRectExportPath") @@ -857,6 +820,9 @@ def draw(self, context): infoBox.label(text="After export, call your hud's draw function in ") infoBox.label(text=enumHUDPaths[context.scene.TexRectExportType][0] + ": ") infoBox.label(text=enumHUDPaths[context.scene.TexRectExportType][1] + ".") + prop_split(col, context.scene, "TexRectName", "Name") + ui_image(False, col, None, context.scene.texrect, context.scene.TexRectName, False, hide_lowhigh=True) + col.operator(ExportTexRectDraw.bl_idname) class SM64_DrawLayersPanel(bpy.types.Panel):