Skip to content

Allow custom CJ clothing textures of any size and format (DXT, up to 1024×1024)#4958

Open
TheCrazy17 wants to merge 1 commit into
multitheftauto:masterfrom
TheCrazy17:feature/clothes-textures
Open

Allow custom CJ clothing textures of any size and format (DXT, up to 1024×1024)#4958
TheCrazy17 wants to merge 1 commit into
multitheftauto:masterfrom
TheCrazy17:feature/clothes-textures

Conversation

@TheCrazy17

@TheCrazy17 TheCrazy17 commented Jun 16, 2026

Copy link
Copy Markdown

Summary

You can now import custom CJ clothing textures of any size (up to 1024×1024) and any format (DXT1/DXT3/DXT5, raster, etc.) with engineImportTXD, just like any other texture. Before, clothing textures had to be exactly the vanilla 256×256 — anything else showed up garbled or silently crashed the game.

mta-screen_2026-06-15_21-17-35 image

Motivation

Resolves the silent crash when importing custom CJ clothing textures (Fixes #4417).

Normal textures (vehicles, objects, etc.) are handed straight to the GPU, so they accept any size or format. CJ clothing is special: the game mixes several textures together into one before putting it on the model, and that mixing only worked when every texture was the exact same size and uncompressed. So a bigger or compressed clothing texture broke it — or crashed the game outright.

This makes the clothing textures get resized and decompressed automatically when needed, so importing them now works like any other texture.

Why the 1024×1024 limit? It's just a safe default and can be raised easily. Bigger clothing textures use noticeably more memory, so a cap avoids problems on lower-end setups. It's not unlimited for the same reason — a huge texture could eat too much memory. Normal clothing isn't affected: it only uses more memory when you actually import something bigger.

Test plan

  • Import any custom clothing texture with engineImportTXD — any size (up to 1024×1024) and any format (normal/raster or DXT1/DXT3/DXT5) — and equip it on a CJ. The texture should show correctly and the game should no longer crash.
  • Try it across several sizes (256/512/1024) and formats, and cycle through different outfits, to confirm none of them crash or render garbled.
  • As a stress test, load a full custom player.img and import everything at once — it should not crash.
  • Check that stock (unmodified) clothing still looks identical and uses no extra memory.
  • Test on both Debug and Release builds.

Checklist

  • Your code should follow the coding guidelines.
  • Smaller pull requests are easier to review. If your pull request is beefy, your pull request should be reviewable commit-by-commit.

GTA SA builds CJ clothing by compositing several textures together on the
CPU (body skin + fat/muscle variants + clothing design) into one texture
per body part, via CClothesBuilder. That CPU compositing assumes every
texture taking part has identical dimensions and is uncompressed 32bpp.
So, unlike normal model/vehicle textures (which the GPU samples directly
in any format), a custom clothing texture imported with engineImportTXD had
to be exactly 256x256 32bpp - anything else corrupted the composite or wrote
past the destination buffer and silently crashed the game.

This reimplements the five clothes texture compositing primitives
(CopyTexture, PlaceTextureOnTopOfTexture and the three BlendTextures
variants) in a resolution- and format-agnostic way:

- Sizes are equalized per composite: the owned accumulator raster is grown
  in place and shared source textures are resampled into temporaries, so the
  composite runs at a common resolution of min(max(all sizes), 1024). An
  all-vanilla ped stays 256x256 with no extra cost; it only grows when a
  larger texture is actually used.
- Non-32bpp sources (e.g. DXT1/3/5) are decompressed to A8R8G8B8 on the fly,
  in memory, only at composite time. The replacement TXD is therefore stored
  and streamed as-is, exactly like any other engineImportTXD - no up-front
  re-encoding and no temporary files on disk.

Details:
- New CRenderWareSA.ClothesTextures.cpp with the reimplemented primitives,
  installed from StaticSetClothesReplacingHooks.
- CGraphics::ResizeTextureData gains an optional target format and uses
  D3DXLoadSurfaceFromMemory to decode/decompress the source in one step.
- CreateResizedTexture extracted from RightSizeTexture; the conversion case
  builds the texture directly via RwRasterCreate.
- Add RwRasterDestroy to the RenderWare function table.
- Remove the now-redundant CopyTexture null-check hook from
  CMultiplayerSA_ClothesSpeedUp.cpp (folded into the new CopyTexture).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Custom CJ Clothes textures are extremely finicky

1 participant