Skip to content

Commit

Permalink
VRAM tab tiled UV lines and combo box typing
Browse files Browse the repository at this point in the history
* Fixed RenderInfo mistakenly losing the MSB of MixtureRate when doing comparisons.
* Added shorthand IsTextured property to ModelEntity, so that we don't need to spam `model.RenderFlags.hasFlag(RenderFlags.Textured)` everywhere.
* Added IsPageUsed function to VRAMPages, which states if any textures have been drawn to a specific page.
* Added ContainsPage function to VRAMPages as a simple bounds test.
* Pluralized VRAMPages private fields.
* TiledUV now stores its area values in 4 floats, rather than 2 Vector2s.
* UV lines now draw in the VRAM tab even if a Sub-model is selected.
* UV lines no longer draw for all VRAM pages, only for the current page.
* UV lines in the VRAM tab now draw tiled rectangles (cyan colored), rather than useless tile-converted UV lines.
* VRAM combo box now shows " (drawn to)" text after page numbers for pages that have had textures drawn to them.
* VRAM combo box now accepts typing to instantly change the VRAM page. The page will update as you type, and ignores characters appearing after the digits (to support the " (drawn to)" text of real combo box item names). Pressing Enter, or unfocusing the combo box will fully update the selected index.
* VRAM selected page is now stored as a separate field, and updated as needed. This is because when typing to update the current VRAM page, the combo box's SelectedIndex will be -1.
  • Loading branch information
trigger-segfault committed Jul 21, 2023
1 parent 34ed02e commit e174354
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 59 deletions.
2 changes: 1 addition & 1 deletion Classes/MeshBatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ private void BindMesh(ModelEntity modelEntity, Matrix4? matrix = null, TextureBi
}
mesh.SetData(numElements, positionList, normalList, colorList, uvList, tiledAreaList);
}
if (textureBinder != null && modelEntity.Texture != null && modelEntity.RenderFlags.HasFlag(RenderFlags.Textured))
if (textureBinder != null && modelEntity.Texture != null && modelEntity.IsTextured)
{
mesh.Texture = textureBinder.GetTexture((int)modelEntity.TexturePage);
}
Expand Down
3 changes: 3 additions & 0 deletions Classes/ModelEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ public bool HasTiled
}
}

[Browsable(false)]
public bool IsTextured => RenderFlags.HasFlag(RenderFlags.Textured);

//[ReadOnly(true)]
//public uint PrimitiveIndex { get; set; }

Expand Down
2 changes: 1 addition & 1 deletion Classes/ObjExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public void Export(RootEntity[] entities, string selectedPath, bool experimental

private void WriteModel(ModelEntity model)
{
if (model.Texture != null && model.RenderFlags.HasFlag(RenderFlags.Textured))
if (model.Texture != null && model.IsTextured)
{
if (_mtlExporter.AddMaterial((int) model.TexturePage))
{
Expand Down
2 changes: 1 addition & 1 deletion Classes/PlyExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public void Export(RootEntity[] entities, string selectedPath)
{
var model = (ModelEntity)entityBase;
faceCount += model.Triangles.Count();
if (model.RenderFlags.HasFlag(RenderFlags.Textured))
if (model.IsTextured)
{
var texturePage = model.TexturePage;
if (!materialsDic.ContainsKey((int)texturePage))
Expand Down
14 changes: 7 additions & 7 deletions Classes/RenderInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ public enum RenderFlags
Subdivision = (1 << 6),
AutomaticDivision = (1 << 7),

// Bits 30 and 31 are reserved for MixtureRate.
// Bits 29-31 are reserved for MixtureRate.
}

// Blending when RenderFlags.SemiTransparent is set.
public enum MixtureRate
{
None,
Back50_Poly50, // 50% back + 50% poly
Back100_Poly100, // 100% back + 100% poly
Back100_PolyM100, // 100% back - 100% poly
Back100_Poly25, // 100% back + 25% poly
None = 0,
Back50_Poly50 = 1, // 50% back + 50% poly
Back100_Poly100 = 2, // 100% back + 100% poly
Back100_PolyM100 = 3, // 100% back - 100% poly
Back100_Poly25 = 4, // 100% back + 25% poly
}

// A named Tuple<uint, RenderFlags, MixtureRate> for render information used to separate models/meshes.
Expand All @@ -47,7 +47,7 @@ private ulong RawValue
{
return (((ulong)TexturePage << 0) |
((ulong)RenderFlags << 32) |
((ulong)MixtureRate << 62));
((ulong)MixtureRate << 61));
}
}

Expand Down
34 changes: 24 additions & 10 deletions Classes/TiledUV.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,37 @@ namespace PSXPrev.Classes
public class TiledUV
{
public Vector2[] BaseUv { get; set; }
public Vector2 Offset { get; set; } // Position added to BaseUv after wrapping.
public Vector2 Size { get; set; } // Denominator of modulus with BaseUv for wrapping.
public float X { get; set; } // Position added to BaseUv after wrapping.
public float Y { get; set; }
public float Width { get; set; } // Denominator of modulus with BaseUv for wrapping.
public float Height { get; set; }

public Vector4 Area => new Vector4(Offset.X, Offset.Y, Size.X, Size.Y);
public Vector2 Offset => new Vector2(X, Y);
public Vector2 Size => new Vector2(Width, Height);
public Vector4 Area => new Vector4(X, Y, Width, Height);

public TiledUV(Vector2[] baseUv, float x, float y, float width, float height)
{
BaseUv = baseUv;
Offset = new Vector2(x, y);
Size = new Vector2(width, height);
X = x;
Y = y;
Width = width;
Height = height;
}

public TiledUV(Vector2[] baseUv, Vector2 offset, Vector2 size)
: this(baseUv, offset.X, offset.Y, size.X, size.Y)
{
}

public TiledUV(Vector2[] baseUv, Vector4 area)
: this(baseUv, area.X, area.Y, area.Z, area.W)
{
}

public TiledUV(TiledUV fromTiledUv)
: this(fromTiledUv.BaseUv, fromTiledUv.X, fromTiledUv.Y, fromTiledUv.Width, fromTiledUv.Height)
{
BaseUv = fromTiledUv.BaseUv;
Offset = fromTiledUv.Offset;
Size = fromTiledUv.Size;
}

// This function isn't used, since the tiled (display) UV can be calculated with integer math.
Expand All @@ -30,12 +44,12 @@ public Vector2[] ConvertBaseUv()
var uv = new Vector2[BaseUv.Length];
for (var i = 0; i < uv.Length; i++)
{
uv[i] = Convert(BaseUv[i], Offset.X, Offset.Y, Size.X, Size.Y);
uv[i] = Convert(BaseUv[i], X, Y, Width, Height);
}
return uv;
}

public Vector2 Convert(Vector2 uv) => Convert(uv, Offset.X, Offset.Y, Size.X, Size.Y);
public Vector2 Convert(Vector2 uv) => Convert(uv, X, Y, Width, Height);


public static Vector2 Convert(Vector2 uv, float x, float y, float width, float height)
Expand Down
60 changes: 41 additions & 19 deletions Classes/VRAMPages.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,28 @@ public class VRAMPages : IReadOnlyList<Texture>, IDisposable


private readonly Scene _scene;
private readonly Texture[] _vramPage;
private readonly bool[] _modifiedPage;
private readonly Texture[] _vramPages;
private readonly bool[] _modifiedPages; // Pages that that require a scene update.
private readonly bool[] _usedPages; // Pages that have textures drawn to them (not reset unless cleared).

public System.Drawing.Color BackgroundColor { get; set; } = System.Drawing.Color.White;

public VRAMPages(Scene scene)
{
_scene = scene;
_vramPage = new Texture[PageCount];
_modifiedPage = new bool[PageCount];
_vramPages = new Texture[PageCount];
_modifiedPages = new bool[PageCount];
_usedPages = new bool[PageCount];
}

public Texture this[uint index] => _vramPage[index];
public Texture this[int index] => _vramPage[index];
public Texture this[uint index] => _vramPages[index];
public Texture this[int index] => _vramPages[index];

public int Count => PageCount;

public IEnumerator<Texture> GetEnumerator()
{
return ((IReadOnlyList<Texture>)_vramPage).GetEnumerator();
return ((IReadOnlyList<Texture>)_vramPages).GetEnumerator();
}

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
Expand All @@ -41,34 +43,52 @@ public void Dispose()
{
for (var i = 0; i < PageCount; i++)
{
_vramPage[i]?.Dispose();
//_vramPage[i] = null;
_vramPages[i]?.Dispose();
//_vramPages[i] = null;
_modifiedPages[i] = false;
_usedPages[i] = false;
}
}

public void Setup(bool suppressUpdate = false)
{
for (var i = 0; i < PageCount; i++)
{
if (_vramPage[i] == null)
if (_vramPages[i] == null)
{
// X coordinates [0,256) store texture data.
// X coordinates [256,512) store semi-transparency information for textures.
_vramPage[i] = new Texture(PageSize * 2, PageSize, 0, 0, 32, i, true); // Is VRAM page
_vramPages[i] = new Texture(PageSize * 2, PageSize, 0, 0, 32, i, true); // Is VRAM page
ClearPage(i, suppressUpdate);
}
}
}


// Gets if a page has had at least one texture drawn to it.
public bool IsPageUsed(uint index) => IsPageUsed((int)index);

public bool IsPageUsed(int index)
{
return _usedPages[index];
}

// Returns true if the index is a valid VRAM texture page number.
public bool ContainsPage(uint index) => ContainsPage((int)index);

public bool ContainsPage(int index)
{
return index >= 0 && index < PageCount;
}

// Update page textures in the scene.
public void UpdatePage(uint index, bool force = false) => UpdatePage((int)index, force);

public void UpdatePage(int index, bool force = false)
{
if (force || _modifiedPage[index])
if (force || _modifiedPages[index])
{
_scene.UpdateTexture(_vramPage[index].Bitmap, index);
_modifiedPage[index] = false;
_scene.UpdateTexture(_vramPages[index].Bitmap, index);
_modifiedPages[index] = false;
}
}

Expand All @@ -85,7 +105,7 @@ public void UpdateAllPages()

public void ClearPage(int index, bool suppressUpdate = false)
{
using (var graphics = Graphics.FromImage(_vramPage[index].Bitmap))
using (var graphics = Graphics.FromImage(_vramPages[index].Bitmap))
{
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;

Expand All @@ -99,9 +119,10 @@ public void ClearPage(int index, bool suppressUpdate = false)
}
}

_usedPages[index] = false;
if (suppressUpdate)
{
_modifiedPage[index] = true;
_modifiedPages[index] = true;
}
else
{
Expand All @@ -127,7 +148,7 @@ public void DrawTexture(Texture texture, bool suppressUpdate = false)
var textureHeight = texture.Height;
var textureBitmap = texture.Bitmap;
var textureSemiTransparentMap = texture.SemiTransparentMap;
using (var graphics = Graphics.FromImage(_vramPage[index].Bitmap))
using (var graphics = Graphics.FromImage(_vramPages[index].Bitmap))
{
// Use SourceCopy to overwrite image alpha with alpha stored in textures.
graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
Expand All @@ -154,9 +175,10 @@ public void DrawTexture(Texture texture, bool suppressUpdate = false)
graphics.ResetClip();
}

_usedPages[index] = true;
if (suppressUpdate)
{
_modifiedPage[index] = true;
_modifiedPages[index] = true;
}
else
{
Expand Down
5 changes: 4 additions & 1 deletion Forms/PreviewForm.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit e174354

Please sign in to comment.