Add IGL extensions to replace a ton of overloaded calls, remove BeginScene/EndScene (mostly just D3D9 specific, not relevant nowadays; GDI+ usage seemed to not be needed in reality), misc cleanup

This commit is contained in:
CasualPokePlayer 2024-05-14 19:07:48 -07:00
parent a2bcbbdfb8
commit 92633e7743
9 changed files with 125 additions and 310 deletions

View File

@ -0,0 +1,71 @@
using System.IO;
using System.Drawing;
using System.Numerics;
namespace BizHawk.Bizware.BizwareGL
{
public static class IGLExtensions
{
/// <summary>
/// Loads a texture from disk
/// </summary>
public static Texture2d LoadTexture(this IGL igl, string path)
{
using var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
return igl.LoadTexture(fs);
}
/// <summary>
/// Loads a texture from the stream
/// </summary>
public static Texture2d LoadTexture(this IGL igl, Stream stream)
{
using var bmp = new BitmapBuffer(stream, new());
return igl.LoadTexture(bmp);
}
/// <summary>
/// Loads a texture from the System.Drawing.Bitmap
/// </summary>
public static Texture2d LoadTexture(this IGL igl, Bitmap bitmap)
{
using var bmp = new BitmapBuffer(bitmap, new());
return igl.LoadTexture(bmp);
}
/// <summary>
/// Loads a texture from the BitmapBuffer
/// </summary>
public static Texture2d LoadTexture(this IGL igl, BitmapBuffer buffer)
{
var ret = igl.CreateTexture(buffer.Width, buffer.Height);
igl.LoadTextureData(ret, buffer);
return ret;
}
/// <summary>
/// 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
/// </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
/// </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
/// 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)
=> igl.CreateGuiViewMatrix(dims.Width, dims.Height, autoflip);
}
}

View File

@ -1,5 +1,4 @@
using System; using System;
using System.IO;
using System.Drawing; using System.Drawing;
using System.Numerics; using System.Numerics;
@ -14,7 +13,9 @@ namespace BizHawk.Bizware.BizwareGL
/// </summary> /// </summary>
public interface IGL : IDisposable public interface IGL : IDisposable
{ {
/// <remarks>HACK</remarks> /// <summary>
/// Returns the display method represented by this IGL
/// </summary>
EDispMethod DispMethodEnum { get; } EDispMethod DispMethodEnum { get; }
/// <summary> /// <summary>
@ -82,16 +83,6 @@ namespace BizHawk.Bizware.BizwareGL
/// </summary> /// </summary>
void SetPipelineUniform(PipelineUniform uniform, bool value); void SetPipelineUniform(PipelineUniform uniform, bool value);
/// <summary>
/// Begins a rendering scene; use before doing any draw calls, as per normal
/// </summary>
void BeginScene();
/// <summary>
/// Indicates end of scene rendering; use after all draw calls as per normal
/// </summary>
void EndScene();
/// <summary> /// <summary>
/// Draws based on the currently set pipeline /// Draws based on the currently set pipeline
/// data contains vertexes based on the pipeline's VertexLayout /// data contains vertexes based on the pipeline's VertexLayout
@ -122,7 +113,7 @@ namespace BizHawk.Bizware.BizwareGL
/// <summary> /// <summary>
/// Creates a texture with the specified dimensions /// Creates a texture with the specified dimensions
/// TODO - pass in specifications somehow /// The texture will use a clamping address mode
/// </summary> /// </summary>
Texture2d CreateTexture(int width, int height); Texture2d CreateTexture(int width, int height);
@ -136,8 +127,6 @@ namespace BizHawk.Bizware.BizwareGL
/// Sets the texture's filtering mode /// Sets the texture's filtering mode
/// The default is linear = false (i.e. nearest neighbor) /// The default is linear = false (i.e. nearest neighbor)
/// </summary> /// </summary>
/// <param name="texture"></param>
/// <param name="linear"></param>
public void SetTextureFilter(Texture2d texture, bool linear); public void SetTextureFilter(Texture2d texture, bool linear);
/// <summary> /// <summary>
@ -145,85 +134,32 @@ namespace BizHawk.Bizware.BizwareGL
/// </summary> /// </summary>
void LoadTextureData(Texture2d tex, BitmapBuffer bmp); void LoadTextureData(Texture2d tex, BitmapBuffer bmp);
/// <summary>
/// Loads a texture from disk
/// </summary>
Texture2d LoadTexture(string path);
/// <summary>
/// Loads a texture from the stream
/// </summary>
Texture2d LoadTexture(Stream stream);
/// <summary>
/// Loads a texture from the BitmapBuffer
/// </summary>
Texture2d LoadTexture(BitmapBuffer buffer);
/// <summary>
/// Loads a texture from the System.Drawing.Bitmap
/// </summary>
Texture2d LoadTexture(Bitmap bitmap);
/// <summary> /// <summary>
/// sets the viewport (and scissor) according to the provided specifications /// sets the viewport (and scissor) according to the provided specifications
/// </summary> /// </summary>
void SetViewport(int x, int y, int width, int height); void SetViewport(int x, int y, int width, int height);
/// <summary>
/// sets the viewport (and scissor) according to the provided specifications
/// </summary>
void SetViewport(int width, int height);
#if false // Unused and WinForms unavailable on .NET Standard
/// <summary>
/// sets the viewport (and scissor) according to the client area of the provided control
/// </summary>
void SetViewport(System.Windows.Forms.Control control);
#endif
/// <summary>
/// sets the viewport (and scissor) according to the provided specifications
/// </summary>
void SetViewport(Size size);
/// <summary> /// <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> /// </summary>
Matrix4x4 CreateGuiProjectionMatrix(int w, int h); Matrix4x4 CreateGuiProjectionMatrix(int width, int height);
/// <summary>
/// generates a proper 2d othographic projection for the given destination size, suitable for use in a GUI
/// </summary>
Matrix4x4 CreateGuiProjectionMatrix(Size dims);
/// <summary> /// <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 /// re-establishing of a normal 2d graphics top-left origin. suitable for use in a GUI
/// </summary> /// </summary>
Matrix4x4 CreateGuiViewMatrix(int w, int h, bool autoflip = true); Matrix4x4 CreateGuiViewMatrix(int width, int height, bool autoflip = true);
/// <summary>
/// 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>
Matrix4x4 CreateGuiViewMatrix(Size dims, bool autoflip = true);
/// <summary> /// <summary>
/// Creates a render target. Only includes a color buffer. Pixel format control TBD /// Creates a render target. Only includes a color buffer. Pixel format control TBD
/// </summary> /// </summary>
RenderTarget CreateRenderTarget(int w, int h); RenderTarget CreateRenderTarget(int width, int height);
/// <summary> /// <summary>
/// Binds a RenderTarget for current rendering /// Binds a RenderTarget for current rendering
/// </summary> /// </summary>
void BindRenderTarget(RenderTarget rt); void BindRenderTarget(RenderTarget rt);
/// <summary>
/// Returns a string representing the API employed by this context
/// </summary>
string API { get; }
/// <summary> /// <summary>
/// Frees the provided render target. Same as disposing the resource. /// Frees the provided render target. Same as disposing the resource.
/// </summary> /// </summary>

View File

@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.IO;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Numerics; using System.Numerics;
@ -16,7 +15,6 @@ using Vortice.Direct3D11;
using Vortice.Direct3D11.Shader; using Vortice.Direct3D11.Shader;
using Vortice.DXGI; using Vortice.DXGI;
// todo - do a better job selecting shader model? base on caps somehow? try several and catch compilation exceptions (yuck, exceptions)
namespace BizHawk.Bizware.Graphics namespace BizHawk.Bizware.Graphics
{ {
/// <summary> /// <summary>
@ -159,8 +157,6 @@ namespace BizHawk.Bizware.Graphics
private readonly HashSet<Shader> _pixelShaders = new(); private readonly HashSet<Shader> _pixelShaders = new();
private readonly HashSet<Pipeline> _pipelines = new(); private readonly HashSet<Pipeline> _pipelines = new();
public string API => "D3D11";
public IGL_D3D11() public IGL_D3D11()
{ {
if (OSTailoredCode.IsUnixHost) if (OSTailoredCode.IsUnixHost)
@ -974,18 +970,6 @@ namespace BizHawk.Bizware.Graphics
tw.LinearFiltering = linear; tw.LinearFiltering = linear;
} }
public Texture2d LoadTexture(Bitmap bitmap)
{
using var bmp = new BitmapBuffer(bitmap, new());
return LoadTexture(bmp);
}
public Texture2d LoadTexture(Stream stream)
{
using var bmp = new BitmapBuffer(stream, new());
return LoadTexture(bmp);
}
private ID3D11Texture2D CreateTextureForShader(int width, int height) private ID3D11Texture2D CreateTextureForShader(int width, int height)
{ {
return Device.CreateTexture2D( return Device.CreateTexture2D(
@ -1015,7 +999,6 @@ namespace BizHawk.Bizware.Graphics
return null; return null;
} }
/// <exception cref="InvalidOperationException">GDI+ call returned unexpected data</exception>
public unsafe void LoadTextureData(Texture2d tex, BitmapBuffer bmp) public unsafe void LoadTextureData(Texture2d tex, BitmapBuffer bmp)
{ {
if (bmp.Width != tex.IntWidth || bmp.Height != tex.IntHeight) if (bmp.Width != tex.IntWidth || bmp.Height != tex.IntHeight)
@ -1057,13 +1040,6 @@ namespace BizHawk.Bizware.Graphics
} }
} }
public Texture2d LoadTexture(BitmapBuffer bmp)
{
var ret = CreateTexture(bmp.Width, bmp.Height);
LoadTextureData(ret, bmp);
return ret;
}
/// <exception cref="InvalidOperationException">Vortice call returned unexpected data</exception> /// <exception cref="InvalidOperationException">Vortice call returned unexpected data</exception>
public BitmapBuffer ResolveTexture2d(Texture2d tex) public BitmapBuffer ResolveTexture2d(Texture2d tex)
{ {
@ -1111,32 +1087,20 @@ namespace BizHawk.Bizware.Graphics
} }
} }
public Texture2d LoadTexture(string path) public Matrix4x4 CreateGuiProjectionMatrix(int width, int height)
{
using var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
return LoadTexture(fs);
}
public Matrix4x4 CreateGuiProjectionMatrix(int w, int h)
=> CreateGuiProjectionMatrix(new(w, h));
public Matrix4x4 CreateGuiViewMatrix(int w, int h, bool autoFlip)
=> CreateGuiViewMatrix(new(w, h), autoFlip);
public Matrix4x4 CreateGuiProjectionMatrix(Size dims)
{ {
var ret = Matrix4x4.Identity; var ret = Matrix4x4.Identity;
ret.M11 = 2.0f / dims.Width; ret.M11 = 2.0f / width;
ret.M22 = 2.0f / dims.Height; ret.M22 = 2.0f / height;
return ret; return ret;
} }
public Matrix4x4 CreateGuiViewMatrix(Size dims, bool autoFlip) public Matrix4x4 CreateGuiViewMatrix(int width, int height, bool autoFlip)
{ {
var ret = Matrix4x4.Identity; var ret = Matrix4x4.Identity;
ret.M22 = -1.0f; ret.M22 = -1.0f;
ret.M41 = -dims.Width * 0.5f; ret.M41 = width * -0.5f;
ret.M42 = dims.Height * 0.5f; ret.M42 = height * 0.5f;
// auto-flipping isn't needed on D3D // auto-flipping isn't needed on D3D
return ret; return ret;
@ -1148,12 +1112,6 @@ namespace BizHawk.Bizware.Graphics
Context.RSSetScissorRect(x, y, width, height); Context.RSSetScissorRect(x, y, width, height);
} }
public void SetViewport(int width, int height)
=> SetViewport(0, 0, width, height);
public void SetViewport(Size size)
=> SetViewport(size.Width, size.Height);
public void FreeRenderTarget(RenderTarget rt) public void FreeRenderTarget(RenderTarget rt)
{ {
var rw = (RenderTargetWrapper)rt.Opaque; var rw = (RenderTargetWrapper)rt.Opaque;
@ -1176,13 +1134,13 @@ namespace BizHawk.Bizware.Graphics
cpuAccessFlags: CpuAccessFlags.None); cpuAccessFlags: CpuAccessFlags.None);
} }
public RenderTarget CreateRenderTarget(int w, int h) public RenderTarget CreateRenderTarget(int width, int height)
{ {
var tex = CreateTextureForRenderTarget(w, h); var tex = CreateTextureForRenderTarget(width, height);
var srvd = new ShaderResourceViewDescription(ShaderResourceViewDimension.Texture2D, Format.B8G8R8A8_UNorm, mostDetailedMip: 0, mipLevels: 1); var srvd = new ShaderResourceViewDescription(ShaderResourceViewDimension.Texture2D, Format.B8G8R8A8_UNorm, mostDetailedMip: 0, mipLevels: 1);
var srv = Device.CreateShaderResourceView(tex, srvd); var srv = Device.CreateShaderResourceView(tex, srvd);
var tw = new TextureWrapper { Texture = tex, SRV = srv }; var tw = new TextureWrapper { Texture = tex, SRV = srv };
var tex2d = new Texture2d(this, tw, w, h); var tex2d = new Texture2d(this, tw, width, height);
var rtvd = new RenderTargetViewDescription(RenderTargetViewDimension.Texture2D, Format.B8G8R8A8_UNorm); var rtvd = new RenderTargetViewDescription(RenderTargetViewDimension.Texture2D, Format.B8G8R8A8_UNorm);
var rw = new RenderTargetWrapper { RTV = Device.CreateRenderTargetView(tw.Texture, rtvd) }; var rw = new RenderTargetWrapper { RTV = Device.CreateRenderTargetView(tw.Texture, rtvd) };
@ -1264,13 +1222,5 @@ namespace BizHawk.Bizware.Graphics
Context.Draw(count, 0); Context.Draw(count, 0);
} }
public void BeginScene()
{
}
public void EndScene()
{
}
} }
} }

View File

@ -1,5 +1,4 @@
using System; using System;
using System.IO;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Drawing.Imaging; using System.Drawing.Imaging;
@ -24,8 +23,6 @@ namespace BizHawk.Bizware.Graphics
public void ClearColor(Color color) public void ClearColor(Color color)
=> GetCurrentGraphics().Clear(color); => GetCurrentGraphics().Clear(color);
public string API => "GDIPLUS";
public void FreeTexture(Texture2d tex) public void FreeTexture(Texture2d tex)
{ {
var gtex = (GDIPlusTexture)tex.Opaque; var gtex = (GDIPlusTexture)tex.Opaque;
@ -116,21 +113,12 @@ namespace BizHawk.Bizware.Graphics
public void SetTextureFilter(Texture2d texture, bool linear) public void SetTextureFilter(Texture2d texture, bool linear)
=> ((GDIPlusTexture) texture.Opaque).LinearFiltering = linear; => ((GDIPlusTexture) texture.Opaque).LinearFiltering = linear;
public Texture2d LoadTexture(Bitmap bitmap)
{
var sdBitmap = (Bitmap)bitmap.Clone();
var gtex = new GDIPlusTexture { SDBitmap = sdBitmap };
return new(this, gtex, bitmap.Width, bitmap.Height);
}
public Texture2d LoadTexture(Stream stream)
{
using var bmp = new BitmapBuffer(stream, new());
return LoadTexture(bmp);
}
public Texture2d CreateTexture(int width, int height) public Texture2d CreateTexture(int width, int height)
=> null; {
var sdBitmap = new Bitmap(width, height);
var gtex = new GDIPlusTexture { SDBitmap = sdBitmap };
return new(this, gtex, width, height);
}
public Texture2d WrapGLTexture2d(IntPtr glTexId, int width, int height) public Texture2d WrapGLTexture2d(IntPtr glTexId, int width, int height)
{ {
@ -144,14 +132,6 @@ namespace BizHawk.Bizware.Graphics
bmp.ToSysdrawingBitmap(gtex.SDBitmap); bmp.ToSysdrawingBitmap(gtex.SDBitmap);
} }
public Texture2d LoadTexture(BitmapBuffer bmp)
{
// definitely needed (by TextureFrugalizer at least)
var sdBitmap = bmp.ToSysdrawingBitmap();
var gtex = new GDIPlusTexture { SDBitmap = sdBitmap };
return new(this, gtex, bmp.Width, bmp.Height);
}
public BitmapBuffer ResolveTexture2d(Texture2d tex) public BitmapBuffer ResolveTexture2d(Texture2d tex)
{ {
var gtex = (GDIPlusTexture)tex.Opaque; var gtex = (GDIPlusTexture)tex.Opaque;
@ -164,29 +144,13 @@ namespace BizHawk.Bizware.Graphics
return bb; return bb;
} }
public Texture2d LoadTexture(string path) public Matrix4x4 CreateGuiProjectionMatrix(int width, int height)
{
using var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
return LoadTexture(fs);
}
public Matrix4x4 CreateGuiProjectionMatrix(int w, int h)
{
return CreateGuiProjectionMatrix(new(w, h));
}
public Matrix4x4 CreateGuiViewMatrix(int w, int h, bool autoFlip)
{
return CreateGuiViewMatrix(new(w, h), autoFlip);
}
public Matrix4x4 CreateGuiProjectionMatrix(Size dims)
{ {
// see CreateGuiViewMatrix for more // see CreateGuiViewMatrix for more
return Matrix4x4.Identity; return Matrix4x4.Identity;
} }
public Matrix4x4 CreateGuiViewMatrix(Size dims, bool autoFlip) public Matrix4x4 CreateGuiViewMatrix(int width, int height, bool autoFlip)
{ {
// on account of gdi+ working internally with a default view exactly like we want, we don't need to setup a new one here // on account of gdi+ working internally with a default view exactly like we want, we don't need to setup a new one here
// furthermore, we _cant_, without inverting the GuiView and GuiProjection before drawing, to completely undo it // furthermore, we _cant_, without inverting the GuiView and GuiProjection before drawing, to completely undo it
@ -198,39 +162,19 @@ namespace BizHawk.Bizware.Graphics
{ {
} }
public void SetViewport(int width, int height)
{
}
public void SetViewport(Size size)
{
SetViewport(size.Width, size.Height);
}
public void BeginScene()
{
}
public void EndScene()
{
// maybe an inconsistent semantic with other implementations..
// but accomplishes the needed goal of getting the current RT to render
BindRenderTarget(null);
}
public void FreeRenderTarget(RenderTarget rt) public void FreeRenderTarget(RenderTarget rt)
{ {
var grt = (GDIPlusRenderTarget)rt.Opaque; var grt = (GDIPlusRenderTarget)rt.Opaque;
grt.Dispose(); grt.Dispose();
} }
public RenderTarget CreateRenderTarget(int w, int h) public RenderTarget CreateRenderTarget(int width, int height)
{ {
var gtex = new GDIPlusTexture var gtex = new GDIPlusTexture
{ {
SDBitmap = new(w, h, PixelFormat.Format32bppArgb) SDBitmap = new(width, height, PixelFormat.Format32bppArgb)
}; };
var tex = new Texture2d(this, gtex, w, h); var tex = new Texture2d(this, gtex, width, height);
var grt = new GDIPlusRenderTarget(() => BufferedGraphicsContext); var grt = new GDIPlusRenderTarget(() => BufferedGraphicsContext);
var rt = new RenderTarget(this, grt, tex); var rt = new RenderTarget(this, grt, tex);

View File

@ -10,7 +10,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Drawing; using System.Drawing;
using System.IO;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
@ -38,8 +37,6 @@ namespace BizHawk.Bizware.Graphics
private Pipeline _currPipeline; private Pipeline _currPipeline;
private RenderTarget _currRenderTarget; private RenderTarget _currRenderTarget;
public string API => "OPENGL";
// this IGL either requires at least OpenGL 3.0 // this IGL either requires at least OpenGL 3.0
public static bool Available => OpenGLVersion.SupportsVersion(3, 0); public static bool Available => OpenGLVersion.SupportsVersion(3, 0);
@ -53,14 +50,6 @@ namespace BizHawk.Bizware.Graphics
GL = GL.GetApi(SDL2OpenGLContext.GetGLProcAddress); GL = GL.GetApi(SDL2OpenGLContext.GetGLProcAddress);
} }
public void BeginScene()
{
}
public void EndScene()
{
}
public void Dispose() public void Dispose()
{ {
GL.Dispose(); GL.Dispose();
@ -491,34 +480,22 @@ namespace BizHawk.Bizware.Graphics
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)(linear ? TextureMagFilter.Linear : TextureMagFilter.Nearest)); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)(linear ? TextureMagFilter.Linear : TextureMagFilter.Nearest));
} }
public Texture2d LoadTexture(Bitmap bitmap) public Texture2d CreateTexture(int width, int height)
{ {
using var bmp = new BitmapBuffer(bitmap, new()); var texId = GL.GenTexture();
return LoadTexture(bmp); GL.BindTexture(TextureTarget.Texture2D, texId);
} unsafe
{
GL.TexImage2D(TextureTarget.Texture2D, 0, InternalFormat.Rgba8, (uint)width, (uint)height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, null);
}
public Texture2d LoadTexture(Stream stream)
{
using var bmp = new BitmapBuffer(stream, new());
return LoadTexture(bmp);
}
private uint GenTexture()
{
var id = GL.GenTexture();
// sensible defaults // sensible defaults
GL.BindTexture(TextureTarget.Texture2D, id);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
return id;
}
public Texture2d CreateTexture(int width, int height) return new(this, texId, width, height);
{
var id = GenTexture();
return new(this, id, width, height);
} }
public Texture2d WrapGLTexture2d(IntPtr glTexId, int width, int height) public Texture2d WrapGLTexture2d(IntPtr glTexId, int width, int height)
@ -545,13 +522,11 @@ namespace BizHawk.Bizware.Graphics
} }
/// <exception cref="InvalidOperationException">framebuffer creation unsuccessful</exception> /// <exception cref="InvalidOperationException">framebuffer creation unsuccessful</exception>
public unsafe RenderTarget CreateRenderTarget(int w, int h) public RenderTarget CreateRenderTarget(int width, int height)
{ {
// create a texture for it // create a texture for it
var texId = GenTexture(); var tex = CreateTexture(width, height);
var tex = new Texture2d(this, texId, w, h); var texId = (uint)tex.Opaque;
GL.TexImage2D(TextureTarget.Texture2D, 0, InternalFormat.Rgba8, (uint)w, (uint)h, 0, PixelFormat.Bgra, PixelType.UnsignedByte, null);
// create the FBO // create the FBO
var fbId = GL.GenFramebuffer(); var fbId = GL.GenFramebuffer();
@ -587,27 +562,6 @@ namespace BizHawk.Bizware.Graphics
} }
} }
public unsafe Texture2d LoadTexture(BitmapBuffer bmp)
{
Texture2d ret;
var id = GenTexture();
try
{
ret = new(this, id, bmp.Width, bmp.Height);
GL.BindTexture(TextureTarget.Texture2D, id);
// picking a color order that matches doesnt seem to help, any. maybe my driver is accelerating it, or maybe it isnt a big deal. but its something to study on another day
GL.TexImage2D(TextureTarget.Texture2D, 0, InternalFormat.Rgba, (uint)bmp.Width, (uint)bmp.Height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero.ToPointer());
LoadTextureData(ret, bmp);
}
catch
{
GL.DeleteTexture(id);
throw;
}
return ret;
}
public unsafe BitmapBuffer ResolveTexture2d(Texture2d tex) public unsafe BitmapBuffer ResolveTexture2d(Texture2d tex)
{ {
// note - this is dangerous since it changes the bound texture. could we save it? // note - this is dangerous since it changes the bound texture. could we save it?
@ -619,36 +573,20 @@ namespace BizHawk.Bizware.Graphics
return bb; return bb;
} }
public Texture2d LoadTexture(string path) public Matrix4x4 CreateGuiProjectionMatrix(int width, int height)
{
using var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
return LoadTexture(fs);
}
public Matrix4x4 CreateGuiProjectionMatrix(int w, int h)
{
return CreateGuiProjectionMatrix(new(w, h));
}
public Matrix4x4 CreateGuiViewMatrix(int w, int h, bool autoflip)
{
return CreateGuiViewMatrix(new(w, h), autoflip);
}
public Matrix4x4 CreateGuiProjectionMatrix(Size dims)
{ {
var ret = Matrix4x4.Identity; var ret = Matrix4x4.Identity;
ret.M11 = 2.0f / dims.Width; ret.M11 = 2.0f / width;
ret.M22 = 2.0f / dims.Height; ret.M22 = 2.0f / height;
return ret; return ret;
} }
public Matrix4x4 CreateGuiViewMatrix(Size dims, bool autoflip) public Matrix4x4 CreateGuiViewMatrix(int width, int height, bool autoflip)
{ {
var ret = Matrix4x4.Identity; var ret = Matrix4x4.Identity;
ret.M22 = -1.0f; ret.M22 = -1.0f;
ret.M41 = dims.Width * -0.5f; ret.M41 = width * -0.5f;
ret.M42 = dims.Height * 0.5f; ret.M42 = height * 0.5f;
if (autoflip && _currRenderTarget is not null) // flip as long as we're not a final render target if (autoflip && _currRenderTarget is not null) // flip as long as we're not a final render target
{ {
ret.M22 = 1.0f; ret.M22 = 1.0f;
@ -665,16 +603,6 @@ namespace BizHawk.Bizware.Graphics
// BUT ALSO: new specifications.. viewport+scissor make sense together // BUT ALSO: new specifications.. viewport+scissor make sense together
} }
public void SetViewport(int width, int height)
{
SetViewport(0, 0, width, height);
}
public void SetViewport(Size size)
{
SetViewport(size.Width, size.Height);
}
private BizShader CreateShader(ShaderType type, string source, bool required) private BizShader CreateShader(ShaderType type, string source, bool required)
{ {
var sw = new ShaderWrapper(); var sw = new ShaderWrapper();

View File

@ -31,13 +31,14 @@ namespace BizHawk.Bizware.Graphics
string psProgram, vsProgram; string psProgram, vsProgram;
switch (owner.API) // ReSharper disable once SwitchStatementHandlesSomeKnownEnumValuesWithDefault
switch (owner.DispMethodEnum)
{ {
case "D3D11": case EDispMethod.D3D11:
vsProgram = DefaultShader_d3d9; vsProgram = DefaultShader_d3d9;
psProgram = DefaultShader_d3d9; psProgram = DefaultShader_d3d9;
break; break;
case "OPENGL": case EDispMethod.OpenGL:
vsProgram = DefaultVertexShader_gl; vsProgram = DefaultVertexShader_gl;
psProgram = DefaultPixelShader_gl; psProgram = DefaultPixelShader_gl;
break; break;

View File

@ -865,10 +865,8 @@ namespace BizHawk.Client.Common
public void Blank() public void Blank()
{ {
ActivateGraphicsControlContext(); ActivateGraphicsControlContext();
_gl.BeginScene();
_gl.BindRenderTarget(null); _gl.BindRenderTarget(null);
_gl.ClearColor(Color.Black); _gl.ClearColor(Color.Black);
_gl.EndScene();
SwapBuffersOfGraphicsControl(); SwapBuffersOfGraphicsControl();
} }
@ -876,19 +874,12 @@ namespace BizHawk.Client.Common
{ {
if (!job.Offscreen) throw new InvalidOperationException(); if (!job.Offscreen) throw new InvalidOperationException();
// begin rendering on this context
// should this have been done earlier?
// do i need to check this on an intel video card to see if running excessively is a problem? (it used to be in the FinalTarget command below, shouldn't be a problem)
//GraphicsControl.Begin(); // CRITICAL POINT for yabause+GL
//TODO - auto-create and age these (and dispose when old) //TODO - auto-create and age these (and dispose when old)
var rtCounter = 0; var rtCounter = 0;
// ReSharper disable once AccessToModifiedClosure // ReSharper disable once AccessToModifiedClosure
_currentFilterProgram.RenderTargetProvider = new DisplayManagerRenderTargetProvider(size => _shaderChainFrugalizers[rtCounter++].Get(size)); _currentFilterProgram.RenderTargetProvider = new DisplayManagerRenderTargetProvider(size => _shaderChainFrugalizers[rtCounter++].Get(size));
_gl.BeginScene();
RunFilterChainSteps(ref rtCounter, out var rtCurr, out _); RunFilterChainSteps(ref rtCounter, out var rtCurr, out _);
_gl.EndScene();
job.OffscreenBb = rtCurr.Texture2d.Resolve(); job.OffscreenBb = rtCurr.Texture2d.Resolve();
job.OffscreenBb.DiscardAlpha(); job.OffscreenBb.DiscardAlpha();

View File

@ -45,9 +45,9 @@ namespace BizHawk.Client.Common.Filters
Passes = preset.Passes.ToArray(); Passes = preset.Passes.ToArray();
Errors = string.Empty; Errors = string.Empty;
if (owner.API is not ("OPENGL" or "D3D11")) if (owner.DispMethodEnum is not (EDispMethod.OpenGL or EDispMethod.D3D11))
{ {
Errors = $"Unsupported API {owner.API}"; Errors = $"Unsupported Display Method {owner.DispMethodEnum}";
return; return;
} }
@ -67,11 +67,12 @@ namespace BizHawk.Client.Common.Filters
if (!File.Exists(path)) if (!File.Exists(path))
{ {
path = owner.API switch // ReSharper disable once SwitchExpressionHandlesSomeKnownEnumValuesWithExceptionInDefault
path = owner.DispMethodEnum switch
{ {
"OPENGL" => Path.ChangeExtension(path, ".glsl"), EDispMethod.OpenGL => Path.ChangeExtension(path, ".glsl"),
"D3D11" => Path.ChangeExtension(path, ".hlsl"), EDispMethod.D3D11 => Path.ChangeExtension(path, ".hlsl"),
_ => throw new InvalidOperationException(), _ => throw new InvalidOperationException()
}; };
} }
} }

View File

@ -91,18 +91,11 @@ namespace BizHawk.Client.EmuHawk
} }
} }
// begin rendering on this context
// should this have been done earlier?
// do i need to check this on an intel video card to see if running excessively is a problem? (it used to be in the FinalTarget command below, shouldn't be a problem)
//TODO - auto-create and age these (and dispose when old) //TODO - auto-create and age these (and dispose when old)
int rtCounter = 0; int rtCounter = 0;
_currentFilterProgram.RenderTargetProvider = new DisplayManagerRenderTargetProvider(size => _shaderChainFrugalizers[rtCounter++].Get(size)); _currentFilterProgram.RenderTargetProvider = new DisplayManagerRenderTargetProvider(size => _shaderChainFrugalizers[rtCounter++].Get(size));
_gl.BeginScene();
RunFilterChainSteps(ref rtCounter, out var rtCurr, out var inFinalTarget); RunFilterChainSteps(ref rtCounter, out var rtCurr, out var inFinalTarget);
_gl.EndScene();
if (job.Offscreen) if (job.Offscreen)
{ {