fix av dumping with osd enabled (screenshots as well);
default av dumping extension to the dumper plugin's desired default
This commit is contained in:
parent
239eb5b268
commit
bb1b1ff5b5
|
@ -0,0 +1,56 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Bizware.BizwareGL;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
public class BitmapBufferVideoProvider : IVideoProvider, IDisposable
|
||||
{
|
||||
BitmapBuffer bb;
|
||||
public BitmapBufferVideoProvider(BitmapBuffer bb)
|
||||
{
|
||||
this.bb = bb;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (bb != null) bb.Dispose();
|
||||
bb = null;
|
||||
}
|
||||
|
||||
public int[] GetVideoBuffer()
|
||||
{
|
||||
return bb.Pixels;
|
||||
}
|
||||
|
||||
public int VirtualWidth
|
||||
{
|
||||
get { return bb.Width; }
|
||||
}
|
||||
|
||||
public int VirtualHeight
|
||||
{
|
||||
get { return bb.Height; }
|
||||
}
|
||||
|
||||
public int BufferWidth
|
||||
{
|
||||
get { return bb.Width; }
|
||||
}
|
||||
|
||||
public int BufferHeight
|
||||
{
|
||||
get { return bb.Height; }
|
||||
}
|
||||
|
||||
public int BackgroundColor
|
||||
{
|
||||
get { return 0; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,12 +9,12 @@ using BizHawk.Emulation.Common;
|
|||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
/// <summary>
|
||||
/// an IVideoProivder wrapping a Bitmap
|
||||
/// an IVideoProvder wrapping a Bitmap
|
||||
/// </summary>
|
||||
public class BmpVideoProvder : IVideoProvider, IDisposable
|
||||
public class BmpVideoProvider : IVideoProvider, IDisposable
|
||||
{
|
||||
Bitmap bmp;
|
||||
public BmpVideoProvder(Bitmap bmp)
|
||||
public BmpVideoProvider(Bitmap bmp)
|
||||
{
|
||||
this.bmp = bmp;
|
||||
}
|
||||
|
|
|
@ -123,6 +123,7 @@
|
|||
<DependentUpon>ArchiveChooser.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="AVOut\AviWriter.cs" />
|
||||
<Compile Include="AVOut\BitmapBufferVideoProvder.cs" />
|
||||
<Compile Include="AVOut\BmpVideoProvder.cs" />
|
||||
<Compile Include="AVOut\FFmpegWriter.cs" />
|
||||
<Compile Include="AVOut\FFmpegWriterForm.cs">
|
||||
|
|
|
@ -261,9 +261,28 @@ namespace BizHawk.Client.EmuHawk
|
|||
/// </summary>
|
||||
public void UpdateSource(IVideoProvider videoProvider)
|
||||
{
|
||||
UpdateSourceInternal(videoProvider,false, GraphicsControl.Size);
|
||||
var job = new JobInfo
|
||||
{
|
||||
videoProvider = videoProvider,
|
||||
simulate = false,
|
||||
chain_outsize = GraphicsControl.Size
|
||||
};
|
||||
UpdateSourceInternal(job);
|
||||
}
|
||||
|
||||
public BitmapBuffer RenderOffscreen(IVideoProvider videoProvider)
|
||||
{
|
||||
var job = new JobInfo
|
||||
{
|
||||
videoProvider = videoProvider,
|
||||
simulate = false,
|
||||
chain_outsize = GraphicsControl.Size,
|
||||
offscreen = true
|
||||
};
|
||||
UpdateSourceInternal(job);
|
||||
return job.offscreenBB;
|
||||
}
|
||||
|
||||
class FakeVideoProvider : IVideoProvider
|
||||
{
|
||||
public int[] GetVideoBuffer() { return new int[] {}; }
|
||||
|
@ -293,7 +312,13 @@ namespace BizHawk.Client.EmuHawk
|
|||
if (Global.Config.DispObeyAR && Global.Config.DispFixAspectRatio)
|
||||
chain_outsize = new Size(fvp.VirtualWidth * zoom, fvp.VirtualHeight * zoom);
|
||||
|
||||
var filterProgram = UpdateSourceInternal(fvp, true, chain_outsize);
|
||||
var job = new JobInfo
|
||||
{
|
||||
videoProvider = fvp,
|
||||
simulate = true,
|
||||
chain_outsize = chain_outsize
|
||||
};
|
||||
var filterProgram = UpdateSourceInternal(job);
|
||||
|
||||
var size = filterProgram.Filters[filterProgram.Filters.Count - 1].FindOutput().SurfaceFormat.Size;
|
||||
|
||||
|
@ -313,8 +338,21 @@ namespace BizHawk.Client.EmuHawk
|
|||
return size;
|
||||
}
|
||||
|
||||
FilterManager.FilterProgram UpdateSourceInternal(IVideoProvider videoProvider, bool simulate, Size chain_outsize)
|
||||
class JobInfo
|
||||
{
|
||||
public IVideoProvider videoProvider;
|
||||
public bool simulate;
|
||||
public Size chain_outsize;
|
||||
public bool offscreen;
|
||||
public BitmapBuffer offscreenBB;
|
||||
}
|
||||
|
||||
FilterManager.FilterProgram UpdateSourceInternal(JobInfo job)
|
||||
{
|
||||
IVideoProvider videoProvider = job.videoProvider;
|
||||
bool simulate = job.simulate;
|
||||
Size chain_outsize = job.chain_outsize;
|
||||
|
||||
int vw = videoProvider.BufferWidth;
|
||||
int vh = videoProvider.BufferHeight;
|
||||
|
||||
|
@ -381,7 +419,7 @@ TESTEROO:
|
|||
fPresent.GuiRenderer = Renderer;
|
||||
fPresent.GL = GL;
|
||||
|
||||
filterProgram.Compile("default", chain_insize, chain_outsize);
|
||||
filterProgram.Compile("default", chain_insize, chain_outsize, !job.offscreen);
|
||||
|
||||
if (simulate)
|
||||
{
|
||||
|
@ -389,7 +427,7 @@ TESTEROO:
|
|||
else
|
||||
{
|
||||
CurrentFilterProgram = filterProgram;
|
||||
UpdateSourceDrawingWork();
|
||||
UpdateSourceDrawingWork(job);
|
||||
}
|
||||
|
||||
//cleanup:
|
||||
|
@ -398,7 +436,7 @@ TESTEROO:
|
|||
return filterProgram;
|
||||
}
|
||||
|
||||
void UpdateSourceDrawingWork()
|
||||
void UpdateSourceDrawingWork(JobInfo job)
|
||||
{
|
||||
//begin rendering on this context
|
||||
//should this have been done earlier?
|
||||
|
@ -440,31 +478,41 @@ TESTEROO:
|
|||
break;
|
||||
}
|
||||
case FilterManager.FilterProgram.ProgramStepType.FinalTarget:
|
||||
inFinalTarget = true;
|
||||
rtCurr = null;
|
||||
CurrentFilterProgram.CurrRenderTarget = null;
|
||||
GL.BindRenderTarget(null);
|
||||
break;
|
||||
{
|
||||
var size = (Size)step.Args;
|
||||
inFinalTarget = true;
|
||||
rtCurr = null;
|
||||
CurrentFilterProgram.CurrRenderTarget = null;
|
||||
GL.BindRenderTarget(null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Debug.Assert(inFinalTarget);
|
||||
|
||||
//apply the vsync setting (should probably try to avoid repeating this)
|
||||
bool vsync = Global.Config.VSyncThrottle || Global.Config.VSync;
|
||||
if (LastVsyncSetting != vsync || LastVsyncSettingGraphicsControl != presentationPanel.GraphicsControl)
|
||||
if (job.offscreen)
|
||||
{
|
||||
presentationPanel.GraphicsControl.SetVsync(vsync);
|
||||
LastVsyncSettingGraphicsControl = presentationPanel.GraphicsControl;
|
||||
LastVsyncSetting = vsync;
|
||||
job.offscreenBB = rtCurr.Texture2d.Resolve();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Assert(inFinalTarget);
|
||||
//apply the vsync setting (should probably try to avoid repeating this)
|
||||
bool vsync = Global.Config.VSyncThrottle || Global.Config.VSync;
|
||||
if (LastVsyncSetting != vsync || LastVsyncSettingGraphicsControl != presentationPanel.GraphicsControl)
|
||||
{
|
||||
presentationPanel.GraphicsControl.SetVsync(vsync);
|
||||
LastVsyncSettingGraphicsControl = presentationPanel.GraphicsControl;
|
||||
LastVsyncSetting = vsync;
|
||||
}
|
||||
|
||||
//present and conclude drawing
|
||||
presentationPanel.GraphicsControl.SwapBuffers();
|
||||
//present and conclude drawing
|
||||
presentationPanel.GraphicsControl.SwapBuffers();
|
||||
|
||||
//nope. dont do this. workaround for slow context switching on intel GPUs. just switch to another context when necessary before doing anything
|
||||
//presentationPanel.GraphicsControl.End();
|
||||
//nope. dont do this. workaround for slow context switching on intel GPUs. just switch to another context when necessary before doing anything
|
||||
//presentationPanel.GraphicsControl.End();
|
||||
|
||||
NeedsToPaint = false; //??
|
||||
NeedsToPaint = false; //??
|
||||
}
|
||||
}
|
||||
|
||||
bool? LastVsyncSetting;
|
||||
|
|
|
@ -117,7 +117,7 @@ namespace BizHawk.Client.EmuHawk.FilterManager
|
|||
}
|
||||
}
|
||||
|
||||
public void Compile(string channel, Size insize, Size outsize)
|
||||
public void Compile(string channel, Size insize, Size outsize, bool finalTarget)
|
||||
{
|
||||
RETRY:
|
||||
|
||||
|
@ -231,16 +231,19 @@ namespace BizHawk.Client.EmuHawk.FilterManager
|
|||
}
|
||||
|
||||
//patch the program so that the final rendertarget set operation is the framebuffer instead
|
||||
for (int i = Program.Count - 1; i >= 0; i--)
|
||||
if (finalTarget)
|
||||
{
|
||||
var ps = Program[i];
|
||||
if (ps.Type == ProgramStepType.NewTarget)
|
||||
for (int i = Program.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var size = (Size)ps.Args;
|
||||
Debug.Assert(size == outsize);
|
||||
ps.Type = ProgramStepType.FinalTarget;
|
||||
ps.Args = null;
|
||||
break;
|
||||
var ps = Program[i];
|
||||
if (ps.Type == ProgramStepType.NewTarget)
|
||||
{
|
||||
var size = (Size)ps.Args;
|
||||
Debug.Assert(size == outsize);
|
||||
ps.Type = ProgramStepType.FinalTarget;
|
||||
ps.Args = size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ using System.Windows.Forms;
|
|||
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Bizware.BizwareGL;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
using BizHawk.Emulation.Cores.Atari.Atari2600;
|
||||
|
@ -758,9 +759,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
public void TakeScreenshotToClipboard()
|
||||
{
|
||||
using (var img = Global.Config.Screenshot_CaptureOSD ? CaptureOSD() : MakeScreenshotImage())
|
||||
using (var bb = Global.Config.Screenshot_CaptureOSD ? CaptureOSD() : MakeScreenshotImage())
|
||||
{
|
||||
Clipboard.SetImage(img);
|
||||
using(var img = bb.ToSysdrawingBitmap())
|
||||
Clipboard.SetImage(img);
|
||||
}
|
||||
|
||||
GlobalWin.OSD.AddMessage("Screenshot saved to clipboard.");
|
||||
|
@ -781,9 +783,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
fi.Directory.Create();
|
||||
}
|
||||
|
||||
using (var img = Global.Config.Screenshot_CaptureOSD ? CaptureOSD() : MakeScreenshotImage())
|
||||
using (var bb = Global.Config.Screenshot_CaptureOSD ? CaptureOSD() : MakeScreenshotImage())
|
||||
{
|
||||
img.Save(fi.FullName, ImageFormat.Png);
|
||||
using(var img = bb.ToSysdrawingBitmap())
|
||||
img.Save(fi.FullName, ImageFormat.Png);
|
||||
}
|
||||
|
||||
GlobalWin.OSD.AddMessage(fi.Name + " saved.");
|
||||
|
@ -1510,43 +1513,46 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
|
||||
private static unsafe Image MakeScreenshotImage()
|
||||
private static unsafe BitmapBuffer MakeScreenshotImage()
|
||||
{
|
||||
var video = Global.Emulator.VideoProvider;
|
||||
var image = new Bitmap(video.BufferWidth, video.BufferHeight, PixelFormat.Format32bppArgb);
|
||||
//var video = Global.Emulator.VideoProvider;
|
||||
//var image = new Bitmap(video.BufferWidth, video.BufferHeight, PixelFormat.Format32bppArgb);
|
||||
return new BitmapBuffer(Global.Emulator.VideoProvider.BufferWidth, Global.Emulator.VideoProvider.BufferHeight, Global.Emulator.VideoProvider.GetVideoBuffer());
|
||||
|
||||
//this is all rotten.
|
||||
//among other things, cores are required to set 0xFF000000 themselves
|
||||
// TODO - replace with BitmapBuffer
|
||||
var framebuf = video.GetVideoBuffer();
|
||||
var bmpdata = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||
int* ptr = (int*)bmpdata.Scan0.ToPointer();
|
||||
int stride = bmpdata.Stride / 4;
|
||||
for (int y = 0; y < video.BufferHeight; y++)
|
||||
{
|
||||
for (int x = 0; x < video.BufferWidth; x++)
|
||||
{
|
||||
int col = framebuf[(y * video.BufferWidth) + x];
|
||||
//var framebuf = video.GetVideoBuffer();
|
||||
//var bmpdata = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||
//int* ptr = (int*)bmpdata.Scan0.ToPointer();
|
||||
//int stride = bmpdata.Stride / 4;
|
||||
//for (int y = 0; y < video.BufferHeight; y++)
|
||||
//{
|
||||
// for (int x = 0; x < video.BufferWidth; x++)
|
||||
// {
|
||||
// int col = framebuf[(y * video.BufferWidth) + x];
|
||||
|
||||
if (Global.Emulator is TI83)
|
||||
{
|
||||
if (col == 0)
|
||||
{
|
||||
col = Color.Black.ToArgb();
|
||||
}
|
||||
else
|
||||
{
|
||||
col = Color.White.ToArgb();
|
||||
}
|
||||
}
|
||||
// if (Global.Emulator is TI83)
|
||||
// {
|
||||
// if (col == 0)
|
||||
// {
|
||||
// col = Color.Black.ToArgb();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// col = Color.White.ToArgb();
|
||||
// }
|
||||
// }
|
||||
|
||||
// make opaque
|
||||
col |= unchecked((int)0xff000000);
|
||||
// // make opaque
|
||||
// col |= unchecked((int)0xff000000);
|
||||
|
||||
ptr[(y * stride) + x] = col;
|
||||
}
|
||||
}
|
||||
// ptr[(y * stride) + x] = col;
|
||||
// }
|
||||
//}
|
||||
|
||||
image.UnlockBits(bmpdata);
|
||||
return image;
|
||||
//image.UnlockBits(bmpdata);
|
||||
//return image;
|
||||
}
|
||||
|
||||
private void SaveStateAs()
|
||||
|
@ -1944,26 +1950,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
Slot9StatusButton.BackColor = Global.Config.SaveSlot == 9 ? SystemColors.Highlight : SystemColors.Control;
|
||||
}
|
||||
|
||||
//TODO GL - this whole feature will have to be re-added
|
||||
private Bitmap CaptureOSD() // sort of like MakeScreenShot(), but with OSD and LUA captured as well. slow and bad.
|
||||
private BitmapBuffer CaptureOSD()
|
||||
{
|
||||
// // this code captures the emu display with OSD and lua composited onto it.
|
||||
// // it's slow and a bit hackish; a better solution is to create a new
|
||||
// // "dummy render" class that implements IRenderer, IBlitter, and possibly
|
||||
// // IVideoProvider, and pass that to DisplayManager.UpdateSourceEx()
|
||||
// if (_captureOsdRvp == null)
|
||||
// {
|
||||
// _captureOsdRvp = new RetainedViewportPanel();
|
||||
// _captureOsdSrp = new SysdrawingRenderPanel(_captureOsdRvp);
|
||||
// }
|
||||
|
||||
// // this size can be different for showing off stretching or filters
|
||||
// _captureOsdRvp.Width = Global.Emulator.VideoProvider.BufferWidth;
|
||||
// _captureOsdRvp.Height = Global.Emulator.VideoProvider.BufferHeight;
|
||||
|
||||
// GlobalWin.DisplayManager.UpdateSourceEx(Global.Emulator.VideoProvider, _captureOsdSrp);
|
||||
// return (Bitmap)_captureOsdRvp.GetBitmap().Clone();
|
||||
return null;
|
||||
var bb = GlobalWin.DisplayManager.RenderOffscreen(Global.Emulator.VideoProvider);
|
||||
bb.Normalize(true);
|
||||
return bb;
|
||||
}
|
||||
|
||||
private void IncreaseWindowSize()
|
||||
|
@ -2713,7 +2704,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
var sfd = new SaveFileDialog();
|
||||
if (!(Global.Emulator is NullEmulator))
|
||||
{
|
||||
sfd.FileName = PathManager.FilesystemSafeName(Global.Game);
|
||||
sfd.FileName = PathManager.FilesystemSafeName(Global.Game) + "." + aw.DesiredExtension(); //dont use Path.ChangeExtension, it might wreck game names with dots in them
|
||||
sfd.InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries.AvPathFragment, null);
|
||||
}
|
||||
else
|
||||
|
@ -2816,57 +2807,68 @@ namespace BizHawk.Client.EmuHawk
|
|||
_aviSoundInput.GetSamples(temp);
|
||||
_dumpProxy.buffer.enqueue_samples(temp, (int)nsamp);
|
||||
|
||||
//TODO ZERO - this code is pretty jacked. we'll want to frugalize buffers better for speedier dumping, and we might want to rely on the GL layer for padding
|
||||
try
|
||||
{
|
||||
IVideoProvider output;
|
||||
IDisposable disposableOutput = null;
|
||||
if (_avwriterResizew > 0 && _avwriterResizeh > 0)
|
||||
{
|
||||
Bitmap bmpin;
|
||||
if (Global.Config.AVI_CaptureOSD)
|
||||
BizHawk.Bizware.BizwareGL.BitmapBuffer bbin = null;
|
||||
Bitmap bmpin = null;
|
||||
Bitmap bmpout = null;
|
||||
try
|
||||
{
|
||||
bmpin = CaptureOSD();
|
||||
}
|
||||
else
|
||||
{
|
||||
bmpin = new Bitmap(
|
||||
Global.Emulator.VideoProvider.BufferWidth,
|
||||
Global.Emulator.VideoProvider.BufferHeight,
|
||||
PixelFormat.Format32bppArgb);
|
||||
var lockdata = bmpin.LockBits(
|
||||
new Rectangle(0, 0, bmpin.Width, bmpin.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||
System.Runtime.InteropServices.Marshal.Copy(
|
||||
Global.Emulator.VideoProvider.GetVideoBuffer(), 0, lockdata.Scan0, bmpin.Width * bmpin.Height);
|
||||
bmpin.UnlockBits(lockdata);
|
||||
}
|
||||
|
||||
var bmpout = new Bitmap(_avwriterResizew, _avwriterResizeh, PixelFormat.Format32bppArgb);
|
||||
using (var g = Graphics.FromImage(bmpout))
|
||||
{
|
||||
if (_avwriterpad)
|
||||
if (Global.Config.AVI_CaptureOSD)
|
||||
{
|
||||
g.Clear(Color.FromArgb(Global.Emulator.VideoProvider.BackgroundColor));
|
||||
g.DrawImageUnscaled(bmpin, (bmpout.Width - bmpin.Width) / 2, (bmpout.Height - bmpin.Height) / 2);
|
||||
bbin = CaptureOSD();
|
||||
}
|
||||
else
|
||||
{
|
||||
g.DrawImage(bmpin, new Rectangle(0, 0, bmpout.Width, bmpout.Height));
|
||||
bbin = new Bizware.BizwareGL.BitmapBuffer(Global.Emulator.VideoProvider.BufferWidth, Global.Emulator.VideoProvider.BufferHeight, Global.Emulator.VideoProvider.GetVideoBuffer());
|
||||
}
|
||||
}
|
||||
|
||||
bmpin.Dispose();
|
||||
output = new BmpVideoProvder(bmpout);
|
||||
|
||||
bmpout = new Bitmap(_avwriterResizew, _avwriterResizeh, PixelFormat.Format32bppArgb);
|
||||
bmpin = bbin.ToSysdrawingBitmap();
|
||||
using (var g = Graphics.FromImage(bmpout))
|
||||
{
|
||||
if (_avwriterpad)
|
||||
{
|
||||
g.Clear(Color.FromArgb(Global.Emulator.VideoProvider.BackgroundColor));
|
||||
g.DrawImageUnscaled(bmpin, (bmpout.Width - bmpin.Width) / 2, (bmpout.Height - bmpin.Height) / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
g.DrawImage(bmpin, new Rectangle(0, 0, bmpout.Width, bmpout.Height));
|
||||
}
|
||||
}
|
||||
|
||||
output = new BmpVideoProvider(bmpout);
|
||||
disposableOutput = (IDisposable)output;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (bbin != null) bbin.Dispose();
|
||||
if (bmpin != null) bmpin.Dispose();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
output = Global.Config.AVI_CaptureOSD
|
||||
? new BmpVideoProvder(CaptureOSD())
|
||||
: Global.Emulator.VideoProvider;
|
||||
if (Global.Config.AVI_CaptureOSD)
|
||||
{
|
||||
output = new BitmapBufferVideoProvider(CaptureOSD());
|
||||
disposableOutput = (IDisposable)output;
|
||||
}
|
||||
else
|
||||
output = Global.Emulator.VideoProvider;
|
||||
}
|
||||
|
||||
_currAviWriter.AddFrame(output);
|
||||
if (output is BmpVideoProvder)
|
||||
|
||||
if (disposableOutput != null)
|
||||
{
|
||||
(output as BmpVideoProvder).Dispose();
|
||||
disposableOutput.Dispose();
|
||||
}
|
||||
|
||||
_currAviWriter.AddSamples(temp);
|
||||
|
|
|
@ -465,7 +465,7 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK
|
|||
BindTexture2d(tex);
|
||||
var bb = new BitmapBuffer(tex.IntWidth, tex.IntHeight);
|
||||
var bmpdata = bb.LockBits();
|
||||
GL.GetTexImage(TextureTarget.Texture2D, 0, PixelFormat.Bgra, PixelType.Byte, bmpdata.Scan0);
|
||||
GL.GetTexImage(TextureTarget.Texture2D, 0, PixelFormat.Bgra, PixelType.UnsignedByte, bmpdata.Scan0);
|
||||
bb.UnlockBits(bmpdata);
|
||||
return bb;
|
||||
}
|
||||
|
|
|
@ -76,6 +76,34 @@ namespace BizHawk.Bizware.BizwareGL
|
|||
UnlockBits(CurrLock);
|
||||
}
|
||||
|
||||
public unsafe void Normalize(bool yflip)
|
||||
{
|
||||
var bmpdata = LockBits();
|
||||
int[] newPixels = new int[Width * Height];
|
||||
int todo = Width*Height;
|
||||
int* s = (int*)bmpdata.Scan0.ToPointer();
|
||||
fixed (int* d = newPixels)
|
||||
{
|
||||
if (yflip)
|
||||
for (int y = 0, si = 0, di = (Height - 1) * Width; y < Height; y++)
|
||||
{
|
||||
for (int x = 0; x < Width; x++, si++, di++)
|
||||
{
|
||||
d[di] = s[si] | unchecked((int)0xFF000000);
|
||||
}
|
||||
di -= Width * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
}
|
||||
|
||||
UnlockBits(bmpdata);
|
||||
|
||||
Pixels = newPixels;
|
||||
}
|
||||
|
||||
public int GetPixel(int x, int y) { return Pixels[Width * y + x]; }
|
||||
public void SetPixel(int x, int y, int value) { Pixels[Width * y + x] = value; }
|
||||
public Color GetPixelAsColor(int x, int y)
|
||||
|
|
Loading…
Reference in New Issue