BizwareGL-rendertarget support

This commit is contained in:
zeromus 2014-01-27 09:36:18 +00:00
parent 25cab541b1
commit bc4a7e70a7
7 changed files with 159 additions and 20 deletions

View File

@ -55,6 +55,7 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK
//misc initialization
CreateRenderStates();
GL.Enable(EnableCap.Texture2D);
}
void IDisposable.Dispose()
@ -155,6 +156,7 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK
{
int sid = GL.CreateShader(ShaderType.VertexShader);
CompileShaderSimple(sid, source);
return new Shader(this, new IntPtr(sid));
}
@ -237,17 +239,22 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK
if (validateStatus == 0)
throw new InvalidOperationException("Error creating pipeline (validateStatus status false returned from glValidateProgram): " + errcode + "\r\n\r\n" + resultLog);
//set the program to active, in case we need to set sampler uniforms on it
GL.UseProgram(pid);
//get all the uniforms
List<UniformInfo> uniforms = new List<UniformInfo>();
int nUniforms;
int nSamplers = 0;
GL.GetProgram(pid,GetProgramParameterName.ActiveUniforms,out nUniforms);
for (int i = 0; i < nUniforms; i++)
{
int size, length;
ActiveUniformType type;
var sbName = new System.Text.StringBuilder();
GL.GetActiveUniform(pid, i, 1024, out length, out size, out type, sbName);
errcode = GL.GetError();
string name = sbName.ToString();
int loc = GL.GetUniformLocation(pid, name);
var ui = new UniformInfo();
@ -266,6 +273,8 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK
uniforms.Add(ui);
}
//deactivate the program, so we dont accidentally use it
GL.UseProgram(0);
return new Pipeline(this, new IntPtr(pid), uniforms);
}
@ -316,7 +325,7 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK
void IGL.SetPipelineUniformSampler(PipelineUniform uniform, IntPtr texHandle)
{
//set the sampler index into the uniform first
GL.Uniform1(uniform.Id.ToInt32(), uniform.SamplerIndex);
//GL.Uniform1(uniform.Id.ToInt32(), uniform.SamplerIndex);
//now bind the texture
GL.ActiveTexture((TextureUnit)((int)TextureUnit.Texture0 + uniform.SamplerIndex));
GL.BindTexture(TextureTarget.Texture2D, texHandle.ToInt32());
@ -359,6 +368,45 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK
}
}
unsafe RenderTarget IGL.CreateRenderTarget(int w, int h)
{
//create a texture for it
IntPtr texid = (this as IGL).GenTexture();
Texture2d tex = new Texture2d(this, texid, w, h);
GL.BindTexture(TextureTarget.Texture2D,texid.ToInt32());
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, w,h, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
tex.SetMagFilter(TextureMagFilter.Nearest);
tex.SetMinFilter(TextureMinFilter.Nearest);
//create the FBO
int fbid = GL.GenFramebuffer();
GL.BindFramebuffer(FramebufferTarget.Framebuffer, fbid);
//bind the tex to the FBO
GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, texid.ToInt32(), 0);
//do something, I guess say which colorbuffers are used by the framebuffer
DrawBuffersEnum* buffers = stackalloc DrawBuffersEnum[1];
buffers[0] = DrawBuffersEnum.ColorAttachment0;
GL.DrawBuffers(1, buffers);
if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferErrorCode.FramebufferComplete)
throw new InvalidOperationException("Error creating framebuffer (at CheckFramebufferStatus)");
//since we're done configuring unbind this framebuffer, to return to the default
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
return new RenderTarget(this, new IntPtr(fbid), tex);
}
void IGL.BindRenderTarget(RenderTarget rt)
{
if(rt == null)
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
else
GL.BindFramebuffer(FramebufferTarget.Framebuffer, rt.Id.ToInt32());
}
Texture2d IGL.LoadTexture(BitmapBuffer bmp)
{
Texture2d ret = null;
@ -408,9 +456,12 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK
void IGL.SetViewport(int x, int y, int width, int height)
{
ErrorCode errcode;
GL.Viewport(x, y, width, height);
errcode = GL.GetError();
}
void IGL.SetViewport(int width, int height)
{
GL.Viewport(0, 0, width, height);
}
void IGL.SetViewport(swf.Control control)
@ -450,11 +501,6 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK
string result = GL.GetShaderInfoLog(sid);
if (result != "")
throw new InvalidOperationException("Error compiling shader:\r\n\r\n" + result);
//HAX???
GL.Enable(EnableCap.Texture2D);
//GL.PolygonMode(MaterialFace.Back, PolygonMode.Line); //??
//GL.PolygonMode(MaterialFace.Front, PolygonMode.Line); //??
}
Dictionary<IGraphicsContext, VertexLayout> StateCurrentVertexLayouts = new Dictionary<IGraphicsContext, VertexLayout>();

View File

@ -200,6 +200,18 @@ namespace BizHawk.Bizware.BizwareGL
else LoadInternal(null, bitmap, options);
}
/// <summary>
/// Initializes a BitmapBuffer --WRAPPED-- from the supplied parameters, which should definitely have a stride==width and be in the standard color format
/// </summary>
public BitmapBuffer(int width, int height, int[] pixels)
{
this.Pixels = pixels;
this.Width = width;
this.Height = height;
}
void LoadInternal(Stream stream, sd.Bitmap bitmap, BitmapLoadOptions options)
{
bool cleanup = options.CleanupAlpha0;
@ -344,8 +356,19 @@ namespace BizHawk.Bizware.BizwareGL
InitSize(width, height);
}
/// <summary>
/// Makes a new bitmap buffer, in ??? state
/// </summary>
public BitmapBuffer() { }
/// <summary>
/// initializes an empty BitmapBuffer, cleared to all 0
/// </summary>
public BitmapBuffer(Size size)
{
InitSize(size.Width, size.Height);
}
/// <summary>
/// clears this instance to (0,0,0,0) -- without allocating a new array (to avoid GC churn)
/// </summary>
@ -386,14 +409,6 @@ namespace BizHawk.Bizware.BizwareGL
Pixels = arr;
}
/// <summary>
/// initializes an empty BitmapBuffer, cleared to all 0
/// </summary>
public BitmapBuffer(Size size)
{
InitSize(size.Width, size.Height);
}
void InitSize(int width, int height)
{
Pixels = new int[width * height];

View File

@ -66,6 +66,7 @@
<Compile Include="Pipeline.cs" />
<Compile Include="PipelineUniform.cs" />
<Compile Include="RenderStates.cs" />
<Compile Include="RenderTarget.cs" />
<Compile Include="Shader.cs" />
<Compile Include="StringRenderer.cs" />
<Compile Include="TexAtlas.cs" />

View File

@ -98,16 +98,25 @@ namespace BizHawk.Bizware.BizwareGL
}
}
/// <summary>
/// begin rendering, initializing viewport and projections to the given dimensions
/// </summary>
public void Begin(int width, int height)
/// <param name="yflipped">Whether the matrices should be Y-flipped, for use with render targets</param>
public void Begin(int width, int height, bool yflipped = false)
{
Begin();
Projection = Owner.CreateGuiProjectionMatrix(width, height);
Modelview = Owner.CreateGuiViewMatrix(width, height);
Owner.SetViewport(0, 0, width, height);
if (yflipped)
{
//not sure this is the best way to do it. could be done in the view matrix creation
Modelview.Scale(1, -1);
Modelview.Translate(0, -height);
}
Owner.SetViewport(width, height);
}
/// <summary>
@ -183,6 +192,11 @@ namespace BizHawk.Bizware.BizwareGL
/// </summary>
public void Draw(Texture2d tex) { DrawInternal(tex, 0, 0, tex.Width, tex.Height); }
/// <summary>
/// draws the specified texture2d resource.
/// </summary>
public void Draw(Texture2d tex, float x, float y) { DrawInternal(tex, x, y, tex.Width, tex.Height); }
/// <summary>
/// draws the specified Art resource with the given flip flags
/// </summary>

View File

@ -187,6 +187,11 @@ namespace BizHawk.Bizware.BizwareGL
/// </summary>
void SetViewport(int x, int y, int width, int height);
/// <summary>
/// sets the viewport according to the provided specifications
/// </summary>
void SetViewport(int width, int height);
/// <summary>
/// sets the viewport according to the client area of the provided control
/// </summary>
@ -202,5 +207,15 @@ namespace BizHawk.Bizware.BizwareGL
/// re-establishing of a normal 2d graphics top-left origin. suitable for use in a GUI
/// </summary>
Matrix4 CreateGuiViewMatrix(int w, int h);
/// <summary>
/// Creates a render target. Includes a color buffer. Pixel format control TBD
/// </summary>
RenderTarget CreateRenderTarget(int w, int h);
/// <summary>
/// Binds a RenderTarget for current rendering
/// </summary>
void BindRenderTarget(RenderTarget rt);
}
}

View File

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
namespace BizHawk.Bizware.BizwareGL
{
public class RenderTarget
{
public RenderTarget(IGL owner, IntPtr handle, Texture2d tex)
{
Owner = owner;
Id = handle;
Texture2d = tex;
}
public IntPtr Id { get; private set; }
public IGL Owner { get; private set; }
public Texture2d Texture2d { get; private set; }
public void Unbind()
{
Owner.BindRenderTarget(null);
}
public void Bind()
{
Owner.BindRenderTarget(this);
}
}
}

View File

@ -30,6 +30,7 @@ namespace BizHawk.Bizware.Test
GuiRenderer gr = new GuiRenderer(igl);
TestForm tf = new TestForm();
GraphicsControl c = igl.CreateGraphicsControl();
tf.Controls.Add(c);
@ -44,6 +45,18 @@ namespace BizHawk.Bizware.Test
c.SetVsync(false);
//create a render target, in the control context
c.Begin();
RenderTarget rt = igl.CreateRenderTarget(60, 60);
rt.Bind();
igl.ClearColor(Color.Blue);
igl.Clear(ClearBufferMask.ColorBufferBit);
gr.Begin(60, 60, true);
gr.Draw(smile);
gr.End();
rt.Unbind();
c.End();
DateTime start = DateTime.Now;
int wobble = 0;
for (; ; )
@ -51,14 +64,20 @@ namespace BizHawk.Bizware.Test
if (c == null) break;
c.Begin();
igl.ClearColor(Color.Red);
igl.Clear(BizwareGL.ClearBufferMask.ColorBufferBit);
int frame = (int)((DateTime.Now - start).TotalSeconds) % testArts.Count;
gr.Begin(c.Control.ClientSize.Width, c.Control.ClientSize.Height);
sr.RenderString(gr, 0, 0, "60 fps");
gr.SetBlendState(igl.BlendNone);
gr.Draw(rt.Texture2d, 0, 20);
gr.SetBlendState(igl.BlendNormal);
sr.RenderString(gr, 0, 0, "?? fps");
gr.Modelview.Translate((float)Math.Sin(wobble / 360.0f) * 50, 0);
gr.Modelview.Translate(100, 100);
gr.Modelview.Push();