Added buffer and buffer<>, tweaked more documentation
This commit is contained in:
257
Diamond/Buffer.cs
Normal file
257
Diamond/Buffer.cs
Normal file
@@ -0,0 +1,257 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using NLog;
|
||||||
|
using OpenTK.Graphics.OpenGL4;
|
||||||
|
|
||||||
|
namespace Diamond
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Wrap an OpenGL buffer object
|
||||||
|
/// </summary>
|
||||||
|
public class Buffer : GLObject
|
||||||
|
{
|
||||||
|
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
#region Static
|
||||||
|
|
||||||
|
private static readonly Dictionary<BufferTarget, Buffer> BoundBuffers;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
static Buffer()
|
||||||
|
{
|
||||||
|
BoundBuffers = new Dictionary<BufferTarget, Buffer>();
|
||||||
|
foreach (var value in Enum.GetValues(typeof(BufferTarget)).Cast<BufferTarget>())
|
||||||
|
BoundBuffers[value] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region ArrayBuffer
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The buffer will be used as a source for vertex data, but the connection is only made when
|
||||||
|
/// glVertexAttribPointer is called. The pointer field of this function is taken as a byte
|
||||||
|
/// offset from the beginning of whatever buffer is currently bound to this target.
|
||||||
|
/// </summary>
|
||||||
|
public static Buffer ArrayBuffer
|
||||||
|
{
|
||||||
|
get => BoundBuffers[BufferTarget.ArrayBuffer];
|
||||||
|
set => Bind(BufferTarget.ArrayBuffer, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ElementArrayBuffer
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// All rendering functions of the form gl*Draw*Elements* will use the pointer field as a byte
|
||||||
|
/// offset from the beginning of the buffer object bound to this target. The indices used for
|
||||||
|
/// indexed rendering will be taken from the buffer object. Note that this binding target is
|
||||||
|
/// part of a Vertex Array Objects state, so a VAO must be bound before binding a buffer here.
|
||||||
|
/// </summary>
|
||||||
|
public static Buffer ElementArrayBuffer
|
||||||
|
{
|
||||||
|
get => BoundBuffers[BufferTarget.ArrayBuffer];
|
||||||
|
set => Bind(BufferTarget.ElementArrayBuffer, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region DrawIndirectBuffer
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The buffer bound to this target will be used as the source for the indirect data when performing
|
||||||
|
/// indirect rendering. This is only available in core OpenGL 4.0 or with ARB_draw_indirect.
|
||||||
|
/// </summary>
|
||||||
|
public static Buffer DrawIndirectBuffer
|
||||||
|
{
|
||||||
|
get => BoundBuffers[BufferTarget.DrawIndirectBuffer];
|
||||||
|
set => Bind(BufferTarget.DrawIndirectBuffer, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Bind a buffer to a target. If buffer is null, unbinds the target.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="target">The binding target</param>
|
||||||
|
/// <param name="buffer">The buffer to bind, or 0 if null</param>
|
||||||
|
public static void Bind(BufferTarget target, Buffer buffer)
|
||||||
|
{
|
||||||
|
GL.BindBuffer(target, buffer?.Id ?? 0);
|
||||||
|
Logger.Debug("Bound {0} to {1}", (object) buffer ?? "default buffer", target);
|
||||||
|
|
||||||
|
BoundBuffers[target] = buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ctor, Delete()
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a buffer object wrapper
|
||||||
|
/// </summary>
|
||||||
|
internal Buffer()
|
||||||
|
: base(GL.GenBuffer())
|
||||||
|
{
|
||||||
|
Logger.Debug("Created {0}", this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Delete()
|
||||||
|
{
|
||||||
|
Logger.Debug("Disposing {0}", this);
|
||||||
|
GL.DeleteBuffer(Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
#region Queries
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The usage hint for the current data store
|
||||||
|
/// </summary>
|
||||||
|
public BufferUsageHint Usage => (BufferUsageHint) Get(BufferParameterName.BufferUsage);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The size of the current data store in bytes
|
||||||
|
/// </summary>
|
||||||
|
public int Size => Get(BufferParameterName.BufferSize);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Stored
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a property of this buffer
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="param">The property to get</param>
|
||||||
|
/// <returns>The int value of the property</returns>
|
||||||
|
public int Get(BufferParameterName param)
|
||||||
|
{
|
||||||
|
ArrayBuffer = this;
|
||||||
|
GL.GetBufferParameter(BufferTarget.ArrayBuffer, param, out int res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Bind this buffer to a target
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="target">The binding target</param>
|
||||||
|
public void Bind(BufferTarget target) => Bind(target, this);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override string ToString() =>
|
||||||
|
$"'Buffer {Id}'";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Upload data to this buffer. Deletes the existing data store and creates a new one
|
||||||
|
/// from the marshalled size of T.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Data element type, used with Marshal.SizeOf to calculate size of data store</typeparam>
|
||||||
|
/// <param name="data">Values to upload</param>
|
||||||
|
/// <param name="usage">Usage hint for for this data.</param>
|
||||||
|
// todo: add usage hint documentation
|
||||||
|
public void Upload<T>(T[] data, BufferUsageHint usage = BufferUsageHint.StaticDraw) where T : struct
|
||||||
|
{
|
||||||
|
Logger.Debug("Updating {0} data (replacing store)", this);
|
||||||
|
ArrayBuffer = this;
|
||||||
|
GL.BufferData(BufferTarget.ArrayBuffer, data.SizeInBytes(), data, usage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Upload the data to this buffer within a range. Does not delete the existing data store.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">The data to upload. The range is also applied to this array.</param>
|
||||||
|
/// <param name="offset">The offset index of data to begin uploading</param>
|
||||||
|
/// <param name="count">The number of T elements to upload</param>
|
||||||
|
/// <typeparam name="T">Data element type. Offsets are applied according to the size of this in bytes.</typeparam>
|
||||||
|
public void Upload<T>(T[] data, int offset, int count) where T : struct
|
||||||
|
{
|
||||||
|
Logger.Debug("Updating {0} data range ({1} for {2}] from type {3}",
|
||||||
|
this, offset, count, typeof(T).Name);
|
||||||
|
ArrayBuffer = this;
|
||||||
|
GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr) offset, count, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Factory Methods
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a buffer, initialized with an array
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Data element type.</typeparam>
|
||||||
|
/// <param name="data">Data used to initialize the buffer</param>
|
||||||
|
/// <param name="usage">The usage hint for this buffer</param>
|
||||||
|
/// <returns>The initialized buffer, or null if initialization failed</returns>
|
||||||
|
// todo: add usage hint documentation
|
||||||
|
public static Buffer<T> FromData<T>(T[] data, BufferUsageHint usage = BufferUsageHint.StaticDraw)
|
||||||
|
where T : struct
|
||||||
|
{
|
||||||
|
var buffer = new Buffer<T>();
|
||||||
|
|
||||||
|
buffer.Upload(data, usage);
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generic overload for Buffer. Caches properties like data, usage, and size.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Data type used for all operations</typeparam>
|
||||||
|
// todo this needs to be made as complete as the non-generic version
|
||||||
|
public sealed class Buffer<T> : Buffer where T : struct
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Cached usage hint for the buffer's storage
|
||||||
|
/// </summary>
|
||||||
|
public new BufferUsageHint Usage { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Size of the buffer data storage in T units.
|
||||||
|
/// </summary>
|
||||||
|
public new int Size { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The data in this buffer. Not copied to the buffer until Upload() is called.
|
||||||
|
/// </summary>
|
||||||
|
public T[] Data { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Upload data to this buffer. Deletes the existing data store and creates a new one.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">Values to upload</param>
|
||||||
|
/// <param name="usage">Usage hint for for this data.</param>
|
||||||
|
// todo: add usage hint documentation
|
||||||
|
public void Upload(T[] data, BufferUsageHint usage = BufferUsageHint.StaticDraw)
|
||||||
|
{
|
||||||
|
base.Upload<T>(data, usage);
|
||||||
|
Data = data;
|
||||||
|
Usage = usage;
|
||||||
|
Size = data.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Upload the data to this buffer within a range. Does not delete the existing data store.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="offset">The offset index of data to begin uploading</param>
|
||||||
|
/// <param name="count">The number of T elements to upload</param>
|
||||||
|
public void Upload(int offset, int count)
|
||||||
|
{
|
||||||
|
base.Upload<T>(Data, offset, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<DocumentationFile>bin\Debug\Diamond.xml</DocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
@@ -51,6 +52,8 @@
|
|||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Buffer.cs" />
|
||||||
|
<Compile Include="Extensions.cs" />
|
||||||
<Compile Include="GLObject.cs" />
|
<Compile Include="GLObject.cs" />
|
||||||
<Compile Include="Util\SubArray.cs" />
|
<Compile Include="Util\SubArray.cs" />
|
||||||
<Compile Include="Shaders\Program.cs" />
|
<Compile Include="Shaders\Program.cs" />
|
||||||
|
|||||||
26
Diamond/Extensions.cs
Normal file
26
Diamond/Extensions.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Diamond
|
||||||
|
{
|
||||||
|
internal static class Extensions
|
||||||
|
{
|
||||||
|
private static readonly Dictionary<Type, int> ByteSizes = new Dictionary<Type, int>();
|
||||||
|
|
||||||
|
public static int SizeInBytes(this Type type)
|
||||||
|
{
|
||||||
|
if (!ByteSizes.ContainsKey(type))
|
||||||
|
ByteSizes[type] = Marshal.SizeOf(type);
|
||||||
|
return ByteSizes[type];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int SizeInBytes<T>(this T[] arr) where T : struct
|
||||||
|
{
|
||||||
|
return typeof(T).SizeInBytes() * arr.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,9 @@ using OpenTK.Graphics;
|
|||||||
|
|
||||||
namespace Diamond
|
namespace Diamond
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A wrapper class for any OpenGL object
|
||||||
|
/// </summary>
|
||||||
public abstract class GLObject : IDisposable
|
public abstract class GLObject : IDisposable
|
||||||
{
|
{
|
||||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace Diamond.Shaders
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Wrap and OpenGL program object
|
/// Wrap and OpenGL program object
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Program : GLObject
|
public sealed class Program : GLObject
|
||||||
{
|
{
|
||||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
@@ -19,31 +19,36 @@ namespace Diamond.Shaders
|
|||||||
private static Program _current;
|
private static Program _current;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The currently active program
|
/// The currently active program, or null if the default program is active.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static Program Current
|
public static Program Current
|
||||||
{
|
{
|
||||||
get => _current;
|
get => _current;
|
||||||
set
|
set => Use(value);
|
||||||
{
|
}
|
||||||
if (value != null && !value.Linked)
|
|
||||||
{
|
|
||||||
Logger.Error("Cannot use {0} because it is not linked", value);
|
|
||||||
value = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.Debug("Using {0}", (object) value ?? "default program");
|
/// <summary>
|
||||||
GL.UseProgram((_current = value)?.Id ?? 0);
|
/// Use this program. If program is null, use the default program.
|
||||||
|
/// </summary>
|
||||||
|
public static void Use(Program program)
|
||||||
|
{
|
||||||
|
if (program != null && !program.Linked)
|
||||||
|
{
|
||||||
|
Logger.Error("Cannot use {0} because it is not linked", program);
|
||||||
|
program = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GL.UseProgram(program?.Id ?? 0);
|
||||||
|
Logger.Debug("Using {0}", (object) program ?? "default program");
|
||||||
|
|
||||||
|
_current = program;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constructor, Delete()
|
#region ctor, Delete()
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// Create a program object wrapper
|
|
||||||
/// </summary>
|
|
||||||
private Program()
|
private Program()
|
||||||
: base(GL.CreateProgram())
|
: base(GL.CreateProgram())
|
||||||
{
|
{
|
||||||
@@ -64,12 +69,12 @@ namespace Diamond.Shaders
|
|||||||
#region Queries
|
#region Queries
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The number of active uniforms
|
/// Gets the number of active uniforms
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int ActiveUniforms => Get(GetProgramParameterName.ActiveUniforms);
|
public int ActiveUniforms => Get(GetProgramParameterName.ActiveUniforms);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The number of active attributes
|
/// Gets the number of active attributes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int ActiveAttributes => Get(GetProgramParameterName.ActiveAttributes);
|
public int ActiveAttributes => Get(GetProgramParameterName.ActiveAttributes);
|
||||||
|
|
||||||
@@ -78,7 +83,7 @@ namespace Diamond.Shaders
|
|||||||
#region Stored
|
#region Stored
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The InfoLog for this program
|
/// The InfoLog for this program since it was last linked
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string InfoLog { get; private set; }
|
public string InfoLog { get; private set; }
|
||||||
|
|
||||||
@@ -94,7 +99,7 @@ namespace Diamond.Shaders
|
|||||||
#region Methods
|
#region Methods
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a property of this program
|
/// Get a property of this program. invokes glGetProgram and returns an int result.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="param">The program property to get</param>
|
/// <param name="param">The program property to get</param>
|
||||||
/// <returns>The int value of the program property</returns>
|
/// <returns>The int value of the program property</returns>
|
||||||
@@ -105,7 +110,8 @@ namespace Diamond.Shaders
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Try to link this program
|
/// Try to link this program. If linking fails, the InfoLog is updated, and attribute and uniform caches are reset.
|
||||||
|
/// If linking is successful, attribute and uniform caches are generated
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Link()
|
public void Link()
|
||||||
{
|
{
|
||||||
@@ -148,11 +154,9 @@ namespace Diamond.Shaders
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Use this program
|
/// Use this program. Equivalent to Program.Use(this);
|
||||||
/// <para></para>
|
|
||||||
/// Equivalent to <code>Program.Current = value</code>
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Use() => Current = this;
|
public void Use() => Use(this);
|
||||||
|
|
||||||
#region Attribute Locations
|
#region Attribute Locations
|
||||||
|
|
||||||
@@ -163,18 +167,19 @@ namespace Diamond.Shaders
|
|||||||
/// Check if this program has an active attribute
|
/// Check if this program has an active attribute
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The attribute name</param>
|
/// <param name="name">The attribute name</param>
|
||||||
/// <returns>Whether the progrma has an active attribute</returns>
|
/// <returns>Whether the program has an active attribute</returns>
|
||||||
public bool HasAttribute(string name) => _attributes.ContainsKey(name);
|
public bool HasAttribute(string name) => _attributes.ContainsKey(name);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check if this program has an active uniform
|
/// Check if this program has an active uniform
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The uniform name</param>
|
/// <param name="name">The uniform name</param>
|
||||||
/// <returns>Whether the progrma has an active uniform</returns>
|
/// <returns>Whether the program has an active uniform</returns>
|
||||||
public bool HasUniform(string name) => _uniforms.ContainsKey(name);
|
public bool HasUniform(string name) => _uniforms.ContainsKey(name);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the location of an attribute by name
|
/// Get the location of an attribute by name. Throws InvalidOperationException if the attribute
|
||||||
|
/// is not found. This can be checked with HasAttribute
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The attribute name</param>
|
/// <param name="name">The attribute name</param>
|
||||||
/// <returns>The location of the attribute</returns>
|
/// <returns>The location of the attribute</returns>
|
||||||
@@ -186,7 +191,8 @@ namespace Diamond.Shaders
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the location of an uniform by name
|
/// Get the location of an uniform by name. Throws InvalidOperationException if the uniform
|
||||||
|
/// is not found. This can be checked with HasUniform
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The uniform name</param>
|
/// <param name="name">The uniform name</param>
|
||||||
/// <returns>The location of the uniform</returns>
|
/// <returns>The location of the uniform</returns>
|
||||||
@@ -199,11 +205,21 @@ namespace Diamond.Shaders
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Attach a shader to this program
|
/// Attach a shader to this program. If shader is null, does nothing. If shader is not compiled
|
||||||
|
/// it is still attached but program link will likely fail.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="shader">The shader to attach</param>
|
/// <param name="shader">The shader to attach</param>
|
||||||
public void Attach(Shader shader)
|
public void Attach(Shader shader)
|
||||||
{
|
{
|
||||||
|
if (shader == null)
|
||||||
|
{
|
||||||
|
Logger.Error("Cannot attach null shader to {0}", this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!shader.Compiled)
|
||||||
|
Logger.Warn("{0} is not compiled. Program link will likely fail.", shader);
|
||||||
|
|
||||||
Logger.Debug("Attaching {0} to {1}", shader, this);
|
Logger.Debug("Attaching {0} to {1}", shader, this);
|
||||||
GL.AttachShader(Id, shader.Id);
|
GL.AttachShader(Id, shader.Id);
|
||||||
}
|
}
|
||||||
@@ -217,14 +233,16 @@ namespace Diamond.Shaders
|
|||||||
#region Factory Methods
|
#region Factory Methods
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create and link a program from precompiled shaders
|
/// Create and link a program from precompiled shaders. If any shader is null or uncompiled it is still
|
||||||
|
/// attached, although program link will likely fail.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="shaders">The shaders used in this program</param>
|
/// <param name="shaders">The shaders used in this program</param>
|
||||||
/// <returns>A linked program, or null if initialization failed</returns>
|
/// <returns>A linked program, or null if initialization failed</returns>
|
||||||
public static Program FromShaders(params Shader[] shaders) => FromShaders((IEnumerable<Shader>) shaders);
|
public static Program FromShaders(params Shader[] shaders) => FromShaders((IEnumerable<Shader>) shaders);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create and link a program from precompiled shaders
|
/// Create and link a program from precompiled shaders. If any shader is null or uncompiled it is still
|
||||||
|
/// attached, although program link will likely fail.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="shaders">The shaders used in this program</param>
|
/// <param name="shaders">The shaders used in this program</param>
|
||||||
/// <returns>A linked program, or null if initialization failed</returns>
|
/// <returns>A linked program, or null if initialization failed</returns>
|
||||||
@@ -239,15 +257,7 @@ namespace Diamond.Shaders
|
|||||||
var program = new Program();
|
var program = new Program();
|
||||||
|
|
||||||
foreach (var shader in shaders)
|
foreach (var shader in shaders)
|
||||||
{
|
|
||||||
if (shader == null)
|
|
||||||
{
|
|
||||||
Logger.Error("One or more shaders is null - cannot create program");
|
|
||||||
program.Dispose();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
program.Attach(shader);
|
program.Attach(shader);
|
||||||
}
|
|
||||||
|
|
||||||
program.Link();
|
program.Link();
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace Diamond.Shaders
|
|||||||
{
|
{
|
||||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
#region Constructor, Delete()
|
#region ctor, Delete()
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a shader object wrapper
|
/// Create a shader object wrapper
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ namespace Diamond.Util
|
|||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
if (Length == 0)
|
if (Length == 0)
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using Diamond.Shaders;
|
using Diamond.Shaders;
|
||||||
using Diamond.Util;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using OpenTK.Graphics.OpenGL4;
|
using OpenTK.Graphics.OpenGL4;
|
||||||
|
using Diamond;
|
||||||
|
using Buffer = Diamond.Buffer;
|
||||||
|
|
||||||
namespace hexworld
|
namespace hexworld
|
||||||
{
|
{
|
||||||
@@ -24,6 +21,7 @@ namespace hexworld
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Program _pgm;
|
private Program _pgm;
|
||||||
|
private Buffer<float> _buf;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void OnUnload(EventArgs e)
|
protected override void OnUnload(EventArgs e)
|
||||||
@@ -41,7 +39,25 @@ namespace hexworld
|
|||||||
_pgm = Program.FromFiles("res/obj.fs.glsl", "res/obj.vs.glsl");
|
_pgm = Program.FromFiles("res/obj.fs.glsl", "res/obj.vs.glsl");
|
||||||
|
|
||||||
Program.Current = _pgm;
|
Program.Current = _pgm;
|
||||||
Program.Current = null;
|
|
||||||
|
_buf = Buffer.FromData(new float[]
|
||||||
|
{
|
||||||
|
-.8f, -.8f,
|
||||||
|
+.8f, -.8f,
|
||||||
|
+.0f, +.8f
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnRenderFrame(FrameEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnRenderFrame(e);
|
||||||
|
|
||||||
|
GL.Viewport(ClientRectangle);
|
||||||
|
|
||||||
|
GL.Clear(ClearBufferMask.ColorBufferBit);
|
||||||
|
|
||||||
|
SwapBuffers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,10 +19,12 @@
|
|||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<Optimize>false</Optimize>
|
<Optimize>false</Optimize>
|
||||||
<OutputPath>bin\Debug\</OutputPath>
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>TRACE;DEBUG</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||||
|
<DocumentationFile>
|
||||||
|
</DocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
|||||||
Reference in New Issue
Block a user