Giant reorg, move most of Bizware.BizwareGL to Bizware.Graphics, remove some unused code, de-duplicate more code

TODO: Change a lot of these IGL resources into interfaces (instead of doing IGL specific things for that instance in the opaque member)
This commit is contained in:
CasualPokePlayer 2024-05-15 18:06:32 -07:00
parent d787c0fefc
commit f78fcc82e3
60 changed files with 258 additions and 1018 deletions

View File

@ -29,8 +29,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BizHawk.Bizware.Graphics",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BizHawk.Bizware.Graphics.Controls", "src\BizHawk.Bizware.Graphics.Controls\BizHawk.Bizware.Graphics.Controls.csproj", "{3D050D35-B57D-4D14-BE0F-FD63552DADB0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BizHawk.Bizware.BizwareGL", "src\BizHawk.Bizware.BizwareGL\BizHawk.Bizware.BizwareGL.csproj", "{658BB7AA-74A1-496F-A6AA-B7D3DD9C7CBE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BizHawk.BizInvoke", "src\BizHawk.BizInvoke\BizHawk.BizInvoke.csproj", "{E5D76DC1-84A8-47AF-BE25-E76F06D2FBBC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BizHawk.WinForms.Controls", "src\BizHawk.WinForms.Controls\BizHawk.WinForms.Controls.csproj", "{B5A2214B-3CB0-48C4-8DB1-98B38D48AC4A}"
@ -89,10 +87,6 @@ Global
{3D050D35-B57D-4D14-BE0F-FD63552DADB0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3D050D35-B57D-4D14-BE0F-FD63552DADB0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3D050D35-B57D-4D14-BE0F-FD63552DADB0}.Release|Any CPU.Build.0 = Release|Any CPU
{658BB7AA-74A1-496F-A6AA-B7D3DD9C7CBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{658BB7AA-74A1-496F-A6AA-B7D3DD9C7CBE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{658BB7AA-74A1-496F-A6AA-B7D3DD9C7CBE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{658BB7AA-74A1-496F-A6AA-B7D3DD9C7CBE}.Release|Any CPU.Build.0 = Release|Any CPU
{E5D76DC1-84A8-47AF-BE25-E76F06D2FBBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E5D76DC1-84A8-47AF-BE25-E76F06D2FBBC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E5D76DC1-84A8-47AF-BE25-E76F06D2FBBC}.Release|Any CPU.ActiveCfg = Release|Any CPU

View File

@ -1,34 +0,0 @@
namespace BizHawk.Bizware.BizwareGL
{
/// <summary>
/// Represents a piece of 2d art. Not as versatile as a texture.. could have come from an atlas. So it comes with a boatload of constraints
/// </summary>
public class Art
{
// bleh, didnt mean to have this here, but I need it now
public Art(Texture2d tex)
{
BaseTexture = tex;
u1 = 1;
v1 = 1;
Width = tex.Width;
Height = tex.Height;
}
public Art(ArtManager owner)
{
Owner = owner;
}
public ArtManager Owner { get; }
public Texture2d BaseTexture { get; set; }
public float Width, Height;
public float u0, v0, u1, v1;
internal void Initialize()
{
//TBD
}
}
}

View File

@ -1,175 +0,0 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
namespace BizHawk.Bizware.BizwareGL
{
/// <summary>
/// Load resources through here, and they can be grouped together, for purposes of batching and whatnot.
/// You can't use any of the returned Art resources until calling Close on the ArtManager
/// </summary>
public class ArtManager : IDisposable
{
public ArtManager(IGL owner)
{
Owner = owner;
Open();
}
public void Dispose()
{
// todo
}
/// <summary>
/// Reopens this instance for further resource loading. Fails if it has been closed forever.
/// </summary>
public void Open()
{
AssertIsOpen(false);
if (IsClosedForever)
{
throw new InvalidOperationException($"{nameof(ArtManager)} instance has been closed forever!");
}
IsOpened = true;
}
/// <summary>
/// Loads the given stream as an Art instance
/// </summary>
public Art LoadArt(Stream stream)
{
return LoadArtInternal(new BitmapBuffer(stream, new BitmapLoadOptions()));
}
/// <summary>
/// Loads the given path as an Art instance.
/// </summary>
public Art LoadArt(string path)
{
using var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
return LoadArtInternal(new BitmapBuffer(path, new BitmapLoadOptions()));
}
private Art LoadArtInternal(BitmapBuffer tex)
{
AssertIsOpen(true);
var a = new Art(this);
ArtLooseTextureAssociation.Add((a, tex));
ManagedArts.Add(a);
return a;
}
/// <summary>
/// Closes this instance for for further resource loading. Will result in a texture atlasing operation.
/// If the close operation is forever, then internal backup copies of resources will be freed, but it can never be reopened.
/// This function may take some time to run, as it is
/// </summary>
public void Close(bool forever = true)
{
AssertIsOpen(true);
IsOpened = false;
IsClosedForever = forever;
// first, cleanup old stuff
foreach (var tex in ManagedTextures)
{
tex.Dispose();
}
ManagedTextures.Clear();
// prepare input for atlas process and perform atlas
// add 2 extra pixels for padding on all sides
var atlasItems = ArtLooseTextureAssociation
.Select(kvp => new TexAtlas.RectItem(kvp.Bitmap.Width + 2, kvp.Bitmap.Height + 2, kvp))
.ToList();
var results = TexAtlas.PackAtlas(atlasItems);
// this isn't supported yet:
if (results.Count > 1)
throw new InvalidOperationException("Art files too big for atlas");
// prepare the output buffer
var bmpResult = new BitmapBuffer(results[0].Size);
//for each item, copy it into the output buffer and set the tex parameters on them
for (var i = 0; i < atlasItems.Count; i++)
{
var item = results[0].Items[i];
var (art, bitmap) = ((Art, BitmapBuffer)) item.Item;
var w = bitmap.Width;
var h = bitmap.Height;
var dx = item.X + 1;
var dy = item.Y + 1;
for (var y = 0; y < h; y++)
{
for (var x = 0; x < w; x++)
{
var pixel = bitmap.GetPixel(x, y);
bmpResult.SetPixel(x+dx,y+dy,pixel);
}
}
var myDestWidth = (float)bmpResult.Width;
var myDestHeight = (float)bmpResult.Height;
art.u0 = dx / myDestWidth;
art.v0 = dy / myDestHeight;
art.u1 = (dx + w) / myDestWidth;
art.v1 = (dy + h) / myDestHeight;
art.Width = w;
art.Height = h;
}
//if we're closed forever, then forget all the original bitmaps
if (forever)
{
foreach (var tuple in ArtLooseTextureAssociation) tuple.Bitmap.Dispose();
ArtLooseTextureAssociation.Clear();
}
//create a physical texture
var texture = Owner.LoadTexture(bmpResult);
ManagedTextures.Add(texture);
//oops, we couldn't do this earlier.
foreach (var art in ManagedArts)
art.BaseTexture = texture;
}
/// <summary>
/// Throws an exception if the instance is not open
/// </summary>
private void AssertIsOpen(bool state)
{
if (IsOpened != state)
{
throw new InvalidOperationException($"{nameof(ArtManager)} instance is not open!");
}
}
public IGL Owner { get; }
public bool IsOpened { get; private set; }
public bool IsClosedForever { get; private set; }
/// <summary>
/// This is used to remember the original bitmap sources for art files. Once the ArtManager is closed forever, this will be purged
/// </summary>
private readonly List<(Art Art, BitmapBuffer Bitmap)> ArtLooseTextureAssociation = new();
/// <summary>
/// Physical texture resources, which exist after this ArtManager has been closed
/// </summary>
private readonly List<Texture2d> ManagedTextures = new();
/// <summary>
/// All the Arts managed by this instance
/// </summary>
private readonly List<Art> ManagedArts = new();
}
}

View File

@ -1,10 +0,0 @@
using System;
namespace BizHawk.Bizware.BizwareGL
{
public class AttributeInfo
{
public IntPtr Handle;
public string Name;
}
}

View File

@ -1,18 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<Import Project="../MainSlnCommon.props" />
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Nullable>disable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Cyotek.Drawing.BitmapFont" />
<PackageReference Include="System.Drawing.Common" />
<ProjectReference Include="$(ProjectDir)../BizHawk.Common/BizHawk.Common.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="IGuiRenderer.cs" SubType="Code" />
</ItemGroup>
</Project>

View File

@ -1,118 +0,0 @@
using System;
using System.Drawing;
using System.Numerics;
namespace BizHawk.Bizware.BizwareGL
{
public interface IGuiRenderer : IDisposable
{
/// <summary>
/// Begins rendering
/// </summary>
void Begin();
void Begin(Size size);
/// <summary>
/// begin rendering, initializing viewport and projections to the given dimensions
/// </summary>
void Begin(int width, int height);
/// <summary>
/// draws the specified Art resource
/// </summary>
void Draw(Art art);
/// <summary>
/// draws the specified Art resource with the specified offset. This could be tricky if youve applied other rotate or scale transforms first.
/// </summary>
void Draw(Art art, Vector2 pos);
/// <summary>
/// draws the specified Art resource with the specified offset. This could be tricky if youve applied other rotate or scale transforms first.
/// </summary>
void Draw(Art art, float x, float y);
/// <summary>
/// draws the specified Art resource with the specified offset, with the specified size. This could be tricky if youve applied other rotate or scale transforms first.
/// </summary>
void Draw(Art art, float x, float y, float width, float height);
/// <summary>
/// draws the specified Texture with the specified offset, with the specified size. This could be tricky if youve applied other rotate or scale transforms first.
/// </summary>
void Draw(Texture2d art, float x, float y, float width, float height);
/// <summary>
/// draws the specified texture2d resource.
/// </summary>
void Draw(Texture2d tex);
/// <summary>
/// draws the specified texture2d resource.
/// </summary>
void Draw(Texture2d tex, float x, float y);
/// <summary>
/// draws the specified Art resource with the given flip flags
/// </summary>
void DrawFlipped(Art art, bool xflip, bool yflip);
/// <summary>
/// Draws a subrectangle from the provided texture. For advanced users only
/// </summary>
void DrawSubrect(Texture2d tex, float x, float y, float w, float h, float u0, float v0, float u1, float v1);
/// <summary>
/// Ends rendering
/// </summary>
void End();
/// <summary>
/// Use this, if you must do something sneaky to openGL without this GuiRenderer knowing.
/// It might be faster than End and Beginning again, and certainly prettier
/// </summary>
void Flush();
bool IsActive { get; }
MatrixStack Modelview { get; set; }
IGL Owner { get; }
MatrixStack Projection { get; set; }
void RectFill(float x, float y, float w, float h);
void EnableBlending();
void DisableBlending();
/// <summary>
/// Sets the specified corner color (for the gradient effect)
/// </summary>
/// <remarks>(x, y, z, w) is (r, g, b, a)</remarks>
void SetCornerColor(int which, Vector4 color);
/// <summary>
/// Sets all four corner colors at once
/// </summary>
/// <remarks>(x, y, z, w) is (r, g, b, a)</remarks>
void SetCornerColors(Vector4[] colors);
/// <summary>
/// Restores the pipeline to the default
/// </summary>
void SetDefaultPipeline();
void SetModulateColor(Color color);
void SetModulateColorWhite();
/// <summary>
/// Sets the pipeline for this GuiRenderer to use. We won't keep possession of it.
/// This pipeline must work in certain ways, which can be discerned by inspecting the built-in one
/// </summary>
void SetPipeline(Pipeline pipeline);
}
}

View File

@ -1,298 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Drawing;
namespace BizHawk.Bizware.BizwareGL
{
public static class TexAtlas
{
public class RectItem
{
public RectItem(int width, int height, object item)
{
Width = width;
Height = height;
Item = item;
}
public int X, Y;
public int Width, Height;
public int TexIndex;
public object Item;
}
private class TryFitParam
{
public TryFitParam(int _w, int _h) { this.w = _w; this.h = _h; }
public readonly int w;
public readonly int h;
public bool ok = true;
public readonly RectangleBinPack rbp = new RectangleBinPack();
public readonly List<RectangleBinPack.Node> nodes = new List<RectangleBinPack.Node>();
}
public const int MaxSizeBits = 16;
/// <summary>
/// packs the supplied RectItems into an atlas. Modifies the RectItems with x/y values of location in new atlas.
/// </summary>
public static IReadOnlyList<(Size Size, List<RectItem> Items)> PackAtlas(IEnumerable<RectItem> items)
{
static void AddAtlas(ICollection<(Size, List<RectItem>)> atlases, IEnumerable<RectItem> initItems)
{
List<RectItem> currentItems = new(initItems);
List<RectItem> remainItems = new();
TryFitParam tfpFinal;
while (true)
{
// this is where the texture size range is determined.
// we run this every time we make an atlas, in case we want to variably control the maximum texture output size.
// ALSO - we accumulate data in there, so we need to refresh it each time. ... lame.
var todoSizes = new List<TryFitParam>();
for (var i = 3; i <= MaxSizeBits; i++)
{
for (var j = 3; j <= MaxSizeBits; j++)
{
var w = 1 << i;
var h = 1 << j;
var tfp = new TryFitParam(w, h);
todoSizes.Add(tfp);
}
}
//run the packing algorithm on each potential size
Parallel.ForEach(todoSizes, (param) =>
{
var rbp = new RectangleBinPack();
rbp.Init(16384, 16384);
param.rbp.Init(param.w, param.h);
// ReSharper disable once AccessToModifiedClosure
foreach (var ri in currentItems)
{
var node = param.rbp.Insert(ri.Width, ri.Height);
if (node == null)
{
param.ok = false;
}
else
{
node.ri = ri;
param.nodes.Add(node);
}
}
});
// find the best fit among the potential sizes that worked
var best = long.MaxValue;
tfpFinal = todoSizes[0];
foreach (var tfp in todoSizes)
{
if (!tfp.ok)
{
continue;
}
var area = tfp.w * (long) tfp.h;
if (area > best)
{
continue; // larger than best, not interested
}
if (area == best) // same area, compare perimeter as tie-breaker (to create squares, which are nicer to look at)
{
if (tfp.w + tfp.h >= tfpFinal.w + tfpFinal.h)
{
continue;
}
}
best = area;
tfpFinal = tfp;
}
//did we find any fit?
if (best < long.MaxValue)
{
break;
}
//nope - move an item to the remaining list and try again
remainItems.Add(currentItems[currentItems.Count - 1]);
currentItems.RemoveAt(currentItems.Count - 1);
}
//we found a fit. setup this atlas in the result and drop the items into it
atlases.Add((new(tfpFinal.w, tfpFinal.h), new(currentItems)));
foreach (var item in currentItems)
{
var node = tfpFinal.nodes.Find(x => x.ri == item);
item.X = node.x;
item.Y = node.y;
item.TexIndex = atlases.Count - 1;
}
//if we have any items left, we've got to run this again
if (remainItems.Count > 0) AddAtlas(atlases, remainItems);
}
List<(Size, List<RectItem>)> atlases = new();
AddAtlas(atlases, items);
if (atlases.Count > 1) Console.WriteLine($"Created animset with >1 texture ({atlases.Count} textures)");
return atlases;
}
// original file: RectangleBinPack.cpp
// author: Jukka Jylänki
private class RectangleBinPack
{
/** A node of a binary tree. Each node represents a rectangular area of the texture
we surface. Internal nodes store rectangles of used data, whereas leaf nodes track
rectangles of free space. All the rectangles stored in the tree are disjoint. */
public class Node
{
// Left and right child. We don't really distinguish which is which, so these could
// as well be child1 and child2.
public Node left;
public Node right;
// The top-left coordinate of the rectangle.
public int x;
public int y;
// The dimension of the rectangle.
public int width;
public int height;
public RectItem ri;
}
/// <summary>Starts a new packing process to a bin of the given dimension.</summary>
public void Init(int width, int height)
{
binWidth = width;
binHeight = height;
root = new();
root.left = root.right = null;
root.x = root.y = 0;
root.width = width;
root.height = height;
}
/// <summary>Inserts a new rectangle of the given size into the bin.</summary>
/// <returns>A pointer to the node that stores the newly added rectangle, or 0 if it didn't fit.</returns>
/// <remarks>Running time is linear to the number of rectangles that have been already packed.</remarks>
public Node Insert(int width, int height)
{
return Insert(root, width, height);
}
/// <summary>Computes the ratio of used surface area.</summary>
private float Occupancy()
{
var totalSurfaceArea = binWidth * binHeight;
var usedSurfaceArea = UsedSurfaceArea(root);
return (float)usedSurfaceArea / totalSurfaceArea;
}
private Node root;
// The total size of the bin we started with.
private int binWidth;
private int binHeight;
/// <returns>The surface area used by the subtree rooted at node.</returns>
private static int UsedSurfaceArea(Node node)
{
if (node.left != null || node.right != null)
{
var usedSurfaceArea = node.width * node.height;
if (node.left != null)
usedSurfaceArea += UsedSurfaceArea(node.left);
if (node.right != null)
usedSurfaceArea += UsedSurfaceArea(node.right);
return usedSurfaceArea;
}
// This is a leaf node, it doesn't constitute to the total surface area.
return 0;
}
/// <summary>Inserts a new rectangle in the subtree rooted at the given node.</summary>
private static Node Insert(Node node, int width, int height)
{
// If this node is an internal node, try both leaves for possible space.
// (The rectangle in an internal node stores used space, the leaves store free space)
if (node.left != null || node.right != null)
{
if (node.left != null)
{
var newNode = Insert(node.left, width, height);
if (newNode != null)
return newNode;
}
if (node.right != null)
{
var newNode = Insert(node.right, width, height);
if (newNode != null)
return newNode;
}
return null; // Didn't fit into either subtree!
}
// This node is a leaf, but can we fit the new rectangle here?
if (width > node.width || height > node.height)
return null; // Too bad, no space.
// The new cell will fit, split the remaining space along the shorter axis,
// that is probably more optimal.
var w = node.width - width;
var h = node.height - height;
node.left = new();
node.right = new();
if (w <= h) // Split the remaining space in horizontal direction.
{
node.left.x = node.x + width;
node.left.y = node.y;
node.left.width = w;
node.left.height = height;
node.right.x = node.x;
node.right.y = node.y + height;
node.right.width = node.width;
node.right.height = h;
}
else // Split the remaining space in vertical direction.
{
node.left.x = node.x;
node.left.y = node.y + height;
node.left.width = width;
node.left.height = h;
node.right.x = node.x + width;
node.right.y = node.y;
node.right.width = w;
node.right.height = node.height;
}
// Note that as a result of the above, it can happen that node.left or node.right
// is now a degenerate (zero area) rectangle. No need to do anything about it,
// like remove the nodes as "unnecessary" since they need to exist as children of
// this node (this node can't be a leaf anymore).
// This node is now a non-leaf, so shrink its area - it now denotes
// *occupied* space instead of free space. Its children spawn the resulting
// area of free space.
node.width = width;
node.height = height;
return node;
}
}
}
}

View File

@ -1,7 +1,5 @@
using System;
using BizHawk.Bizware.BizwareGL;
namespace BizHawk.Bizware.Graphics.Controls
{
/// <summary>

View File

@ -1,4 +1,4 @@
namespace BizHawk.Bizware.BizwareGL
namespace BizHawk.Bizware.Graphics
{
public enum AttribUsage
{

View File

@ -6,10 +6,12 @@ using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.IO;
using System.Runtime.InteropServices;
namespace BizHawk.Bizware.BizwareGL
using SDGraphics = System.Drawing.Graphics;
namespace BizHawk.Bizware.Graphics
{
/// <summary>
/// a software-based bitmap, way easier (and faster) to use than .net's built-in bitmap.
@ -559,7 +561,7 @@ namespace BizHawk.Bizware.BizwareGL
{
if (WrappedBitmap != null)
{
using var g = Graphics.FromImage(bmp);
using var g = SDGraphics.FromImage(bmp);
g.CompositingMode = CompositingMode.SourceCopy;
g.CompositingQuality = CompositingQuality.HighSpeed;
g.DrawImageUnscaled(WrappedBitmap, 0, 0);

View File

@ -1,7 +1,7 @@
using System;
using System.Drawing;
namespace BizHawk.Bizware.BizwareGL
namespace BizHawk.Bizware.Graphics
{
public class BitmapLoadOptions
{

View File

@ -8,10 +8,12 @@
<Nullable>disable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Cyotek.Drawing.BitmapFont" />
<PackageReference Include="System.Drawing.Common" />
<PackageReference Include="Silk.NET.OpenGL.Legacy" />
<PackageReference Include="ppy.SDL2-CS" ExcludeAssets="native;contentFiles" />
<PackageReference Include="Vortice.Direct3D11" />
<PackageReference Include="Vortice.D3DCompiler" />
<ProjectReference Include="$(ProjectDir)../BizHawk.Bizware.BizwareGL/BizHawk.Bizware.BizwareGL.csproj" />
<ProjectReference Include="$(ProjectDir)../BizHawk.Common/BizHawk.Common.csproj" />
</ItemGroup>
</Project>

View File

@ -5,7 +5,6 @@ using System.Linq;
using System.Runtime.InteropServices;
using System.Numerics;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Common;
using BizHawk.Common.StringExtensions;

View File

@ -1,4 +1,4 @@
namespace BizHawk.Bizware.BizwareGL
namespace BizHawk.Bizware.Graphics
{
public enum EDispMethod
{

View File

@ -1,6 +1,6 @@
using System.Drawing;
namespace BizHawk.Bizware.BizwareGL.DrawingExtensions
namespace BizHawk.Bizware.Graphics
{
public static class DrawingExtensions
{

View File

@ -2,10 +2,15 @@ using System.IO;
using System.Drawing;
using System.Numerics;
namespace BizHawk.Bizware.BizwareGL
namespace BizHawk.Bizware.Graphics
{
public static class IGLExtensions
{
public static IGuiRenderer CreateRenderer(this IGL gl)
=> gl is IGL_GDIPlus gdipImpl
? new GDIPlusGuiRenderer(gdipImpl)
: new GuiRenderer(gl);
/// <summary>
/// Loads a texture from disk
/// </summary>
@ -44,25 +49,25 @@ namespace BizHawk.Bizware.BizwareGL
}
/// <summary>
/// sets the viewport (and scissor) according to the provided specifications
/// Sets the viewport (and scissor) according to the provided specifications
/// </summary>
public static void SetViewport(this IGL igl, int width, int height)
=> igl.SetViewport(0, 0, width, height);
/// <summary>
/// sets the viewport (and scissor) according to the provided specifications
/// Sets the viewport (and scissor) according to the provided specifications
/// </summary>
public static void SetViewport(this IGL igl, Size size)
=> igl.SetViewport(0, 0, size.Width, size.Height);
/// <summary>
/// generates a proper 2d othographic projection for the given destination size, suitable for use in a GUI
/// Generates a proper 2d othographic projection for the given destination size, suitable for use in a GUI
/// </summary>
public static Matrix4x4 CreateGuiProjectionMatrix(this IGL igl, Size dims)
=> igl.CreateGuiProjectionMatrix(dims.Width, dims.Height);
/// <summary>
/// generates a proper view transform for a standard 2d ortho projection, including half-pixel jitter if necessary and
/// Generates a proper view transform for a standard 2d ortho projection, including half-pixel jitter if necessary and
/// re-establishing of a normal 2d graphics top-left origin. suitable for use in a GUI
/// </summary>
public static Matrix4x4 CreateGuiViewMatrix(this IGL igl, Size dims, bool autoflip = true)

View File

@ -0,0 +1,47 @@
using System.Drawing;
namespace BizHawk.Bizware.Graphics
{
public static class IGuiRendererExtensions
{
/// <summary>
/// Begin rendering, initializing viewport and projections to the given dimensions
/// </summary>
public static void Begin(this IGuiRenderer guiRenderer, Size size)
=> guiRenderer.Begin(size.Width, size.Height);
/// <summary>
/// Draws the specified texture2d resource.
/// </summary>
public static void Draw(this IGuiRenderer guiRenderer, Texture2d tex)
=> guiRenderer.Draw(tex, 0, 0, tex.Width, tex.Height);
/// <summary>
/// Draws the specified texture2d resource with the specified offset.
/// </summary>
public static void Draw(this IGuiRenderer guiRenderer, Texture2d tex, float x, float y)
=> guiRenderer.Draw(tex, x, y, tex.Width, tex.Height);
/// <summary>
/// Draws the specified Texture with the specified offset and the specified size. This could be tricky if youve applied other rotate or scale transforms first.
/// </summary>
public static void Draw(this IGuiRenderer guiRenderer, Texture2d tex, float x, float y, float width, float height)
{
const float u0 = 0, u1 = 1;
float v0, v1;
if (tex.IsUpsideDown)
{
v0 = 1;
v1 = 0;
}
else
{
v0 = 0;
v1 = 1;
}
guiRenderer.DrawSubrect(tex, x, y, width, height, u0, v0, u1, v1);
}
}
}

View File

@ -1,8 +1,6 @@
using System;
using System.Drawing;
using BizHawk.Bizware.BizwareGL;
using SDGraphics = System.Drawing.Graphics;
namespace BizHawk.Bizware.Graphics

View File

@ -4,8 +4,6 @@ using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Numerics;
using BizHawk.Bizware.BizwareGL;
using SDGraphics = System.Drawing.Graphics;
//TODO - maybe a layer to cache Graphics parameters (notably, filtering) ?

View File

@ -2,7 +2,7 @@ using System;
using System.Drawing;
using System.Numerics;
namespace BizHawk.Bizware.BizwareGL
namespace BizHawk.Bizware.Graphics
{
/// <summary>
/// This is a wrapper over OpenGL and direct3d to give a uniform interface

View File

@ -2,7 +2,7 @@ using System.Drawing;
using System.Collections.Generic;
using System.Numerics;
namespace BizHawk.Bizware.BizwareGL
namespace BizHawk.Bizware.Graphics
{
// note: the sense of these matrices, as well as pre- and post- multiplying may be all mixed up.
// conceptually here is how we should be working, in the example of spinning a sprite in place

View File

@ -13,12 +13,11 @@ using System.Drawing;
using System.Linq;
using System.Numerics;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Common;
using Silk.NET.OpenGL.Legacy;
using BizShader = BizHawk.Bizware.BizwareGL.Shader;
using BizShader = BizHawk.Bizware.Graphics.Shader;
using GLVertexAttribPointerType = Silk.NET.OpenGL.Legacy.VertexAttribPointerType;
@ -180,17 +179,6 @@ namespace BizHawk.Bizware.Graphics
// set the program to active, in case we need to set sampler uniforms on it
GL.UseProgram(pid);
#if false
//get all the attributes (not needed)
var attributes = new List<AttributeInfo>();
GL.GetProgram(pid, GLEnum.ActiveAttributes, out var nAttributes);
for (uint i = 0; i < nAttributes; i++)
{
GL.GetActiveAttrib(pid, i, 1024, out _, out _, out AttributeType _, out string name);
attributes.Add(new() { Handle = new(i), Name = name });
}
#endif
// get all the uniforms
var uniforms = new List<UniformInfo>();
GL.GetProgram(pid, GLEnum.ActiveUniforms, out var nUniforms);

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
using BizHawk.Common.CollectionExtensions;
namespace BizHawk.Bizware.BizwareGL
namespace BizHawk.Bizware.Graphics
{
/// <summary>
/// WARNING! PLEASE SET THIS PIPELINE CURRENT BEFORE SETTING UNIFORMS IN IT! NOT TOO GREAT, I KNOW.

View File

@ -2,10 +2,10 @@ using System;
using System.Collections.Generic;
using System.Numerics;
namespace BizHawk.Bizware.BizwareGL
namespace BizHawk.Bizware.Graphics
{
/// <summary>
/// represents a pipeline uniform...
/// Represents a pipeline uniform...
/// and one of those can represent multiple shader uniforms!!
/// </summary>
public class PipelineUniform
@ -24,7 +24,7 @@ namespace BizHawk.Bizware.BizwareGL
private readonly List<UniformInfo> _uniformInfos = new();
/// <returns>the first and only <see cref="UniformInfo"/></returns>
/// <returns>The first and only <see cref="UniformInfo"/>, Only relevant for OpenGL</returns>
/// <exception cref="InvalidOperationException">more than one <see cref="UniformInfo"/> exists</exception>
public UniformInfo Sole
{

View File

@ -1,6 +1,6 @@
using System;
namespace BizHawk.Bizware.BizwareGL
namespace BizHawk.Bizware.Graphics
{
public class RenderTarget : IDisposable
{

View File

@ -6,8 +6,6 @@ using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Numerics;
using BizHawk.Bizware.BizwareGL;
using SDGraphics = System.Drawing.Graphics;
namespace BizHawk.Bizware.Graphics
@ -105,42 +103,29 @@ namespace BizHawk.Bizware.Graphics
Owner.DisableBlending();
}
private MatrixStack _Projection, _Modelview;
private MatrixStack _projection, _modelView;
public MatrixStack Projection
{
get => _Projection;
get => _projection;
set
{
_Projection = value;
_Projection.IsDirty = true;
_projection = value;
_projection.IsDirty = true;
}
}
public MatrixStack Modelview
public MatrixStack ModelView
{
get => _Modelview;
get => _modelView;
set
{
_Modelview = value;
_Modelview.IsDirty = true;
_modelView = value;
_modelView.IsDirty = true;
}
}
public void Begin(Size size)
{
Begin(size.Width, size.Height);
}
public void Begin(int width, int height)
{
Begin();
Projection = Owner.CreateGuiProjectionMatrix(width, height);
Modelview = Owner.CreateGuiViewMatrix(width, height);
}
public void Begin()
{
// uhhmmm I want to throw an exception if its already active, but its annoying.
IsActive = true;
@ -148,8 +133,11 @@ namespace BizHawk.Bizware.Graphics
CurrentImageAttributes?.Dispose();
CurrentImageAttributes = new();
Modelview?.Clear();
ModelView?.Clear();
Projection?.Clear();
Projection = Owner.CreateGuiProjectionMatrix(width, height);
ModelView = Owner.CreateGuiViewMatrix(width, height);
}
public void Flush()
@ -170,22 +158,15 @@ namespace BizHawk.Bizware.Graphics
CurrentImageAttributes = null;
}
public void RectFill(float x, float y, float w, float h)
{
}
public void DrawSubrect(Texture2d tex, float x, float y, float w, float h, float u0, float v0, float u1, float v1)
{
var gtex = (GDIPlusTexture)tex.Opaque;
var g = _gdi.GetCurrentGraphics();
PrepDraw(g, tex);
SetupMatrix(g);
var tw = (GDIPlusTexture)tex.Opaque;
// TODO - we can support bicubic for the final presentation...
g.InterpolationMode = tw.LinearFiltering ? InterpolationMode.Bilinear : InterpolationMode.NearestNeighbor;
var x0 = u0 * tex.Width;
var y0 = v0 * tex.Height;
var x1 = u1 * tex.Width;
var y1 = v1 * tex.Height;
SetupMatrix(g);
PointF[] destPoints =
{
@ -194,79 +175,25 @@ namespace BizHawk.Bizware.Graphics
new(x, y + h),
};
var x0 = u0 * tex.Width;
var y0 = v0 * tex.Height;
var x1 = u1 * tex.Width;
var y1 = v1 * tex.Height;
var gtex = (GDIPlusTexture)tex.Opaque;
g.PixelOffsetMode = PixelOffsetMode.Half;
g.DrawImage(gtex.SDBitmap, destPoints, new(x0, y0, x1 - x0, y1 - y0), GraphicsUnit.Pixel, CurrentImageAttributes);
g.Transform = new(); // .Reset() doesnt work?
}
public void Draw(Art art) { DrawInternal(art, 0, 0, art.Width, art.Height, false, false); }
public void Draw(Art art, float x, float y) { DrawInternal(art, x, y, art.Width, art.Height, false, false); }
public void Draw(Art art, float x, float y, float width, float height) { DrawInternal(art, x, y, width, height, false, false); }
public void Draw(Art art, Vector2 pos) { DrawInternal(art, pos.X, pos.Y, art.Width, art.Height, false, false); }
public void Draw(Texture2d tex) { DrawInternal(tex, 0, 0, tex.Width, tex.Height); }
public void Draw(Texture2d tex, float x, float y) { DrawInternal(tex, x, y, tex.Width, tex.Height); }
public void DrawFlipped(Art art, bool xflip, bool yflip) { DrawInternal(art, 0, 0, art.Width, art.Height, xflip, yflip); }
public void Draw(Texture2d art, float x, float y, float width, float height)
{
DrawInternal(art, x, y, width, height);
}
private static void PrepDraw(SDGraphics g, Texture2d tex)
{
var tw = (GDIPlusTexture)tex.Opaque;
// TODO - we can support bicubic for the final presentation...
g.InterpolationMode = tw.LinearFiltering ? InterpolationMode.Bilinear : InterpolationMode.NearestNeighbor;
}
private void SetupMatrix(SDGraphics g)
{
// projection is always identity, so who cares i guess
// var mat = Projection.Top * Modelview.Top;
var mat = Modelview.Top;
var mat = ModelView.Top;
g.Transform = new(mat.M11, mat.M12, mat.M21, mat.M22, mat.M41, mat.M42);
}
private void DrawInternal(Art art, float x, float y, float w, float h)
{
DrawInternal(art.BaseTexture, x, y, w, h, art.u0, art.v0, art.u1, art.v1);
}
private void DrawInternal(Texture2d tex, float x, float y, float w, float h)
{
DrawInternal(tex, x, y, w, h, 0, 0, 1, 1);
}
private void DrawInternal(Texture2d tex, float x, float y, float w, float h, float u0, float v0, float u1, float v1)
{
var g = _gdi.GetCurrentGraphics();
PrepDraw(g, tex);
SetupMatrix(g);
PointF[] destPoints =
{
new(x, y),
new(x+w, y),
new(x, y+h),
};
var sx = tex.Width * u0;
var sy = tex.Height * v0;
var sx2 = tex.Width * u1;
var sy2 = tex.Height * v1;
var sw = sx2 - sx;
var sh = sy2 - sy;
var gtex = (GDIPlusTexture)tex.Opaque;
g.PixelOffsetMode = PixelOffsetMode.Half;
g.DrawImage(gtex.SDBitmap, destPoints, new(sx, sy, sw, sh), GraphicsUnit.Pixel, CurrentImageAttributes);
g.Transform = new(); // .Reset() doesn't work ? ?
}
private static void DrawInternal(Art art, float x, float y, float w, float h, bool fx, bool fy)
{
}
public bool IsActive { get; private set; }
public IGL Owner => _gdi;

View File

@ -4,17 +4,15 @@ using System;
using System.Drawing;
using System.Numerics;
using BizHawk.Bizware.BizwareGL;
namespace BizHawk.Bizware.Graphics
{
/// <summary>
/// A simple renderer useful for rendering GUI stuff.
/// When doing GUI rendering, run everything through here (if you need a GL feature not done through here, run it through here first)
/// Call Begin, then draw, then End, and don't use other Renderers or GL calls in the meantime, unless you know what you're doing.
/// Call Begin, then Draw, then End, and don't use other Renderers or GL calls in the meantime, unless you know what you're doing.
/// This can perform batching (well.. maybe not yet), which is occasionally necessary for drawing large quantities of things.
/// </summary>
public class GuiRenderer : IDisposable, IGuiRenderer
public class GuiRenderer : IGuiRenderer
{
public GuiRenderer(IGL owner)
{
@ -26,8 +24,8 @@ namespace BizHawk.Bizware.Graphics
VertexLayout.DefineVertexAttribute("aColor", 2, 4, VertexAttribPointerType.Float, AttribUsage.Texcoord1, false, 32, 16);
VertexLayout.Close();
_Projection = new();
_Modelview = new();
_projection = new();
_modelView = new();
string psProgram, vsProgram;
@ -61,15 +59,20 @@ namespace BizHawk.Bizware.Graphics
public void SetCornerColor(int which, Vector4 color)
{
Flush(); //don't really need to flush with current implementation. we might as well roll modulate color into it too.
Flush(); // don't really need to flush with current implementation. we might as well roll modulate color into it too.
CornerColors[which] = color;
}
/// <exception cref="ArgumentException"><paramref name="colors"/> does not have exactly <c>4</c> elements</exception>
public void SetCornerColors(Vector4[] colors)
{
Flush(); //don't really need to flush with current implementation. we might as well roll modulate color into it too.
if (colors.Length != 4) throw new ArgumentException("array must be size 4", nameof(colors));
Flush(); // don't really need to flush with current implementation. we might as well roll modulate color into it too.
if (colors.Length != 4)
{
throw new ArgumentException("array must be size 4", nameof(colors));
}
for (var i = 0; i < 4; i++)
{
CornerColors[i] = colors[i];
@ -79,20 +82,23 @@ namespace BizHawk.Bizware.Graphics
public void Dispose()
{
DefaultPipeline.Dispose();
VertexLayout.Release();
VertexLayout.Dispose();
}
/// <exception cref="InvalidOperationException"><see cref="IsActive"/> is <see langword="true"/></exception>
public void SetPipeline(Pipeline pipeline)
{
if (IsActive)
{
throw new InvalidOperationException("Can't change pipeline while renderer is running!");
}
Flush();
CurrPipeline = pipeline;
// clobber state cache
sTexture = null;
// save the modulate color? user beware, I guess, for now.
}
@ -124,43 +130,30 @@ namespace BizHawk.Bizware.Graphics
Owner.DisableBlending();
}
private MatrixStack _Projection, _Modelview;
private MatrixStack _projection, _modelView;
public MatrixStack Projection
{
get => _Projection;
get => _projection;
set
{
_Projection = value;
_Projection.IsDirty = true;
}
}
public MatrixStack Modelview
{
get => _Modelview;
set
{
_Modelview = value;
_Modelview.IsDirty = true;
_projection = value;
_projection.IsDirty = true;
}
}
public void Begin(Size size)
public MatrixStack ModelView
{
Begin(size.Width, size.Height);
}
public void Begin(int width, int height)
{
Begin();
Projection = Owner.CreateGuiViewMatrix(width, height) * Owner.CreateGuiProjectionMatrix(width, height);
Modelview.Clear();
Owner.SetViewport(width, height);
get => _modelView;
set
{
_modelView = value;
_modelView.IsDirty = true;
}
}
/// <exception cref="InvalidOperationException">no pipeline set (need to call <see cref="SetPipeline"/>)</exception>
public void Begin()
public void Begin(int width, int height)
{
// uhhmmm I want to throw an exception if its already active, but its annoying.
@ -176,9 +169,14 @@ namespace BizHawk.Bizware.Graphics
//clear state cache
sTexture = null;
CurrPipeline["uSamplerEnable"].Set(false);
Modelview.Clear();
ModelView.Clear();
Projection.Clear();
SetModulateColorWhite();
Projection = Owner.CreateGuiViewMatrix(width, height) * Owner.CreateGuiProjectionMatrix(width, height);
ModelView.Clear();
Owner.SetViewport(width, height);
}
public void Flush()
@ -197,113 +195,10 @@ namespace BizHawk.Bizware.Graphics
IsActive = false;
}
public void RectFill(float x, float y, float w, float h)
{
PrepDrawSubrectInternal(null);
EmitRectangleInternal(x, y, w, h, 0, 0, 0, 0);
}
public void DrawSubrect(Texture2d tex, float x, float y, float w, float h, float u0, float v0, float u1, float v1)
{
DrawSubrectInternal(tex, x, y, w, h, u0, v0, u1, v1);
}
public void Draw(Art art)
{
DrawInternal(art, 0, 0, art.Width, art.Height, false, false);
}
public void Draw(Art art, float x, float y)
{
DrawInternal(art, x, y, art.Width, art.Height, false, false);
}
public void Draw(Art art, float x, float y, float width, float height)
{
DrawInternal(art, x, y, width, height, false, false);
}
public void Draw(Art art, Vector2 pos)
{
DrawInternal(art, pos.X, pos.Y, art.Width, art.Height, false, false);
}
public void Draw(Texture2d tex)
{
DrawInternal(tex, 0, 0, tex.Width, tex.Height);
}
public void Draw(Texture2d tex, float x, float y)
{
DrawInternal(tex, x, y, tex.Width, tex.Height);
}
public void DrawFlipped(Art art, bool xflip, bool yflip)
{
DrawInternal(art, 0, 0, art.Width, art.Height, xflip, yflip);
}
public void Draw(Texture2d art, float x, float y, float width, float height)
{
DrawInternal(art, x, y, width, height);
}
private void DrawInternal(Texture2d tex, float x, float y, float w, float h)
{
var art = new Art((ArtManager)null)
{
Width = w,
Height = h
};
art.u0 = art.v0 = 0;
art.u1 = art.v1 = 1;
art.BaseTexture = tex;
DrawInternal(art, x, y, w, h, false, tex.IsUpsideDown);
}
private unsafe void DrawInternal(Art art, float x, float y, float w, float h, bool fx, bool fy)
{
float u0, v0, u1, v1;
if (fx)
{
u0 = art.u1;
u1 = art.u0;
}
else
{
u0 = art.u0;
u1 = art.u1;
}
if (fy)
{
v0 = art.v1;
v1 = art.v0;
}
else
{
v0 = art.v0;
v1 = art.v1;
}
var data = stackalloc float[32]
{
x, y, u0, v0,
CornerColors[0].X, CornerColors[0].Y, CornerColors[0].Z, CornerColors[0].W,
x + w, y, u1, v0,
CornerColors[1].X, CornerColors[1].Y, CornerColors[1].Z, CornerColors[1].W,
x, y + h, u0, v1,
CornerColors[2].X, CornerColors[2].Y, CornerColors[2].Z, CornerColors[2].W,
x + w, y + h, u1, v1,
CornerColors[3].X, CornerColors[3].Y, CornerColors[3].Z, CornerColors[3].W,
};
PrepDrawSubrectInternal(art.BaseTexture);
Owner.Draw(new(data), 4);
PrepDrawSubrectInternal(tex);
EmitRectangleInternal(x, y, w, h, u0, v0, u1, v1);
}
private void PrepDrawSubrectInternal(Texture2d tex)
@ -315,15 +210,16 @@ namespace BizHawk.Bizware.Graphics
CurrPipeline["uSamplerEnable"].Set(tex != null);
}
if (_Projection.IsDirty)
if (_projection.IsDirty)
{
CurrPipeline["um44Projection"].Set(ref _Projection.Top);
_Projection.IsDirty = false;
CurrPipeline["um44Projection"].Set(ref _projection.Top);
_projection.IsDirty = false;
}
if (_Modelview.IsDirty)
if (_modelView.IsDirty)
{
CurrPipeline["um44Modelview"].Set(ref _Modelview.Top);
_Modelview.IsDirty = false;
CurrPipeline["um44Modelview"].Set(ref _modelView.Top);
_modelView.IsDirty = false;
}
}
@ -366,15 +262,10 @@ namespace BizHawk.Bizware.Graphics
Owner.Draw(new(pData), 4);
}
private void DrawSubrectInternal(Texture2d tex, float x, float y, float w, float h, float u0, float v0, float u1, float v1)
{
PrepDrawSubrectInternal(tex);
EmitRectangleInternal(x, y, w, h, u0, v0, u1, v1);
}
public bool IsActive { get; private set; }
public IGL Owner { get; }
private readonly VertexLayout VertexLayout;
private Pipeline CurrPipeline;
private readonly Pipeline DefaultPipeline;

View File

@ -0,0 +1,69 @@
using System;
using System.Drawing;
using System.Numerics;
namespace BizHawk.Bizware.Graphics
{
public interface IGuiRenderer : IDisposable
{
/// <summary>
/// Begin rendering, initializing viewport and projections to the given dimensions
/// </summary>
void Begin(int width, int height);
/// <summary>
/// Draws a subrectangle from the provided texture. For advanced users only
/// </summary>
void DrawSubrect(Texture2d tex, float x, float y, float w, float h, float u0, float v0, float u1, float v1);
/// <summary>
/// Ends rendering
/// </summary>
void End();
/// <summary>
/// Use this, if you must do something sneaky to OpenGL without this GuiRenderer knowing.
/// It might be faster than End and Beginning again, and certainly prettier
/// </summary>
void Flush();
bool IsActive { get; }
MatrixStack ModelView { get; set; }
IGL Owner { get; }
MatrixStack Projection { get; set; }
void EnableBlending();
void DisableBlending();
/// <summary>
/// Sets the specified corner color (for the gradient effect)
/// </summary>
/// <remarks>(x, y, z, w) is (r, g, b, a)</remarks>
void SetCornerColor(int which, Vector4 color);
/// <summary>
/// Sets all four corner colors at once
/// </summary>
/// <remarks>(x, y, z, w) is (r, g, b, a)</remarks>
void SetCornerColors(Vector4[] colors);
/// <summary>
/// Restores the pipeline to the default
/// </summary>
void SetDefaultPipeline();
void SetModulateColor(Color color);
void SetModulateColorWhite();
/// <summary>
/// Sets the pipeline for this GuiRenderer to use. We won't keep possession of it.
/// This pipeline must work in certain ways, which can be discerned by inspecting the built-in one
/// </summary>
void SetPipeline(Pipeline pipeline);
}
}

View File

@ -8,7 +8,7 @@ using System.IO;
using Cyotek.Drawing.BitmapFont;
namespace BizHawk.Bizware.BizwareGL
namespace BizHawk.Bizware.Graphics
{
public class StringRenderer : IDisposable
{

View File

@ -2,7 +2,7 @@ using System;
using System.Drawing;
using System.Numerics;
namespace BizHawk.Bizware.BizwareGL
namespace BizHawk.Bizware.Graphics
{
/// <summary>
/// Handles RetroArch's GLSL shader pass format
@ -68,7 +68,7 @@ namespace BizHawk.Bizware.BizwareGL
public void Dispose()
{
Pipeline.Dispose();
VertexLayout.Release();
VertexLayout.Dispose();
}
public void Bind()

View File

@ -1,4 +1,4 @@
namespace BizHawk.Bizware.BizwareGL
namespace BizHawk.Bizware.Graphics
{
/// <summary>
/// Represents an individual (fragment,vertex) shader.

View File

@ -1,7 +1,7 @@
using System;
using System.Drawing;
namespace BizHawk.Bizware.BizwareGL
namespace BizHawk.Bizware.Graphics
{
/// <summary>
/// A full-scale 2D texture, with mip levels and everything.

View File

@ -1,4 +1,4 @@
namespace BizHawk.Bizware.BizwareGL
namespace BizHawk.Bizware.Graphics
{
public class UniformInfo
{

View File

@ -1,4 +1,4 @@
namespace BizHawk.Bizware.BizwareGL
namespace BizHawk.Bizware.Graphics
{
public enum VertexAttribPointerType
{

View File

@ -1,14 +1,14 @@
using System;
using BizHawk.Common;
namespace BizHawk.Bizware.BizwareGL
namespace BizHawk.Bizware.Graphics
{
/// <summary>
/// Represents a vertex layout, really a kind of a peer of the vertex and fragment shaders.
/// It isn't IDisposable because it'll be lifecycle-managed by the IGL (disposed when all dependent pipelines are disposed)
/// But if you want to be sure to save it for later, use AddRef
/// Only can be held by 1 pipeline at a time
/// </summary>
public class VertexLayout
public class VertexLayout : IDisposable
{
public VertexLayout(IGL owner, object opaque)
{
@ -20,20 +20,9 @@ namespace BizHawk.Bizware.BizwareGL
public object Opaque { get; }
public IGL Owner { get; }
private int RefCount;
public void Release()
public void Dispose()
{
RefCount--;
if (RefCount <= 0)
{
Owner.Internal_FreeVertexLayout(this);
}
}
public void AddRef()
{
RefCount++;
Owner.Internal_FreeVertexLayout(this);
}
/// <exception cref="InvalidOperationException">already closed (by call to <see cref="Close"/>)</exception>
@ -77,6 +66,5 @@ namespace BizHawk.Bizware.BizwareGL
public LayoutItemWorkingDictionary Items { get; }
private bool Closed;
}
}

View File

@ -1,7 +1,7 @@
using System;
using BizHawk.Bizware.Graphics;
using BizHawk.Emulation.Common;
using BizHawk.Bizware.BizwareGL;
namespace BizHawk.Client.Common
{

View File

@ -13,7 +13,7 @@
<PackageReference Include="SharpCompress" />
<PackageReference Include="SQLitePCLRaw.provider.e_sqlite3" />
<ProjectReference Include="$(ProjectDir)../BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj" />
<ProjectReference Include="$(ProjectDir)../BizHawk.Bizware.BizwareGL/BizHawk.Bizware.BizwareGL.csproj" />
<ProjectReference Include="$(ProjectDir)../BizHawk.Bizware.Graphics/BizHawk.Bizware.Graphics.csproj" />
<EmbeddedResource Include="Resources/**/*" />
</ItemGroup>
<ItemGroup>

View File

@ -9,8 +9,7 @@ using System.IO;
using System.Numerics;
using System.Runtime.InteropServices;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Bizware.BizwareGL.DrawingExtensions;
using BizHawk.Bizware.Graphics;
using BizHawk.Client.Common.FilterManager;
using BizHawk.Client.Common.Filters;
using BizHawk.Common.CollectionExtensions;

View File

@ -7,7 +7,7 @@ using System.Numerics;
using BizHawk.Client.Common.Filters;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Bizware.Graphics;
namespace BizHawk.Client.Common.FilterManager
{

View File

@ -2,7 +2,7 @@ using System.Collections.Generic;
using System.Drawing;
using System.Numerics;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Bizware.Graphics;
using BizHawk.Client.Common.FilterManager;
// Here's how to make a filter:

View File

@ -2,7 +2,7 @@ using System;
using System.Drawing;
using System.Numerics;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Bizware.Graphics;
using BizHawk.Client.Common.FilterManager;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Consoles.Nintendo.N3DS;
@ -464,7 +464,7 @@ namespace BizHawk.Client.Common.Filters
var outSize = FindOutput().SurfaceFormat.Size;
FilterProgram.GuiRenderer.Begin(outSize);
FilterProgram.GuiRenderer.DisableBlending();
FilterProgram.GuiRenderer.Modelview.Scale(Scale);
FilterProgram.GuiRenderer.ModelView.Scale(Scale);
FilterProgram.GuiRenderer.Draw(InputTexture);
FilterProgram.GuiRenderer.End();
}
@ -519,7 +519,7 @@ namespace BizHawk.Client.Common.Filters
{
FilterProgram.GuiRenderer.Begin(OutputSize); // hope this didn't change
FilterProgram.GuiRenderer.DisableBlending();
FilterProgram.GuiRenderer.Modelview.Scale(XIS,YIS);
FilterProgram.GuiRenderer.ModelView.Scale(XIS,YIS);
FilterProgram.GuiRenderer.Draw(InputTexture);
FilterProgram.GuiRenderer.End();
}

View File

@ -10,12 +10,12 @@ using System.IO;
using System.Numerics;
using System.Text.RegularExpressions;
using BizHawk.Client.Common.FilterManager;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Bizware.Graphics;
using BizHawk.Common;
using BizHawk.Common.StringExtensions;
using BizHawk.Client.Common.FilterManager;
namespace BizHawk.Client.Common.Filters
{
public class RetroShaderChain : IDisposable

View File

@ -1,6 +1,6 @@
using System.Drawing;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Bizware.Graphics;
using BizHawk.Client.Common.FilterManager;
namespace BizHawk.Client.Common.Filters

View File

@ -2,7 +2,7 @@ using System;
using System.Drawing;
using System.Collections.Generic;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Bizware.Graphics;
namespace BizHawk.Client.Common
{

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Bizware.Graphics;
namespace BizHawk.Client.Common
{

View File

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.IO;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Bizware.Graphics;
using BizHawk.Common;
using BizHawk.Common.PathExtensions;
using BizHawk.Emulation.Common;

View File

@ -2,8 +2,10 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Bizware.Graphics;
using BizHawk.Common.IOExtensions;
namespace BizHawk.Client.Common

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Bizware.Graphics;
using BizHawk.Common;
using BizHawk.Emulation.Common;

View File

@ -2,7 +2,7 @@
using System.IO;
using System.Drawing.Imaging;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Bizware.Graphics;
using BizHawk.Client.Common;
using BizHawk.Common.PathExtensions;
using BizHawk.Emulation.Common;

View File

@ -5,7 +5,7 @@ using System.Drawing.Imaging;
using System.Text;
using BizHawk.Emulation.Common;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Bizware.Graphics;
using BizHawk.Client.Common;
using BizHawk.Common.PathExtensions;

View File

@ -4,7 +4,7 @@ using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Bizware.Graphics;
using BizHawk.Client.Common;
using BizHawk.Emulation.Common;

View File

@ -2,7 +2,7 @@
using System.Drawing;
using System.Windows.Forms;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Bizware.Graphics;
namespace BizHawk.Client.EmuHawk
{

View File

@ -2,7 +2,7 @@ using System;
using System.Diagnostics;
using System.Drawing;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Bizware.Graphics;
using BizHawk.Bizware.Graphics.Controls;
using BizHawk.Client.Common;
using BizHawk.Emulation.Common;

View File

@ -1,13 +0,0 @@
using BizHawk.Bizware.BizwareGL;
using BizHawk.Bizware.Graphics;
namespace BizHawk.Client.EmuHawk
{
public static class IGLExtensions
{
public static IGuiRenderer CreateRenderer(this IGL gl)
=> gl is IGL_GDIPlus gdipImpl
? new GDIPlusGuiRenderer(gdipImpl)
: new GuiRenderer(gl); // This implementation doesn't seem to require any OpenGL-specific (or D3D-specific) behaviour; can it be used with IGL_GdiPlus too? If so, is GDIPlusGuiRenderer only kept around because it's faster? --yoshi
}
}

View File

@ -1,6 +1,5 @@
using System.Windows.Forms;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Bizware.Graphics;
using BizHawk.Bizware.Graphics.Controls;

View File

@ -1,6 +1,6 @@
using System;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Bizware.Graphics;
using BizHawk.Client.Common;
using BizHawk.Emulation.Common;

View File

@ -14,13 +14,14 @@ using System.Security.AccessControl;
using System.Security.Principal;
using System.IO.Pipes;
using BizHawk.Bizware.Graphics;
using BizHawk.Common;
using BizHawk.Common.BufferExtensions;
using BizHawk.Common.PathExtensions;
using BizHawk.Common.StringExtensions;
using BizHawk.Client.Common;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Common.Base_Implementations;

View File

@ -3,7 +3,7 @@ using System.Drawing;
using System.Windows.Forms;
using BizHawk.Client.Common;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Bizware.Graphics;
using BizHawk.Bizware.Graphics.Controls;
namespace BizHawk.Client.EmuHawk

View File

@ -7,7 +7,6 @@ using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Bizware.Graphics;
using BizHawk.Common;
using BizHawk.Common.PathExtensions;
@ -108,7 +107,6 @@ namespace BizHawk.Client.EmuHawk
{
BizInvoke.ReflectionCache.AsmVersion,
Bizware.Audio.ReflectionCache.AsmVersion,
Bizware.BizwareGL.ReflectionCache.AsmVersion,
Bizware.Graphics.ReflectionCache.AsmVersion,
Bizware.Graphics.Controls.ReflectionCache.AsmVersion,
Bizware.Input.ReflectionCache.AsmVersion,

View File

@ -3,7 +3,7 @@ using System.Globalization;
using System.IO;
using System.Windows.Forms;
using BizHawk.Bizware.BizwareGL;
using BizHawk.Bizware.Graphics;
using BizHawk.Client.Common;
using BizHawk.Client.Common.Filters;
using BizHawk.Common;