Added documentation to all GLObject types
This commit is contained in:
@@ -8,6 +8,10 @@ using OpenTK.Graphics.OpenGL4;
|
||||
|
||||
namespace Diamond.Buffers
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages an OpenGL Buffer object
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of data used for this buffer</typeparam>
|
||||
public class Buffer<T> : GLObject where T : struct
|
||||
{
|
||||
private readonly BufferWrap _buffer;
|
||||
@@ -16,8 +20,15 @@ namespace Diamond.Buffers
|
||||
|
||||
private readonly int _size;
|
||||
|
||||
/// <summary>
|
||||
/// The target for this buffer; its type
|
||||
/// </summary>
|
||||
public BufferTarget Target => _buffer.Target;
|
||||
|
||||
/// <summary>
|
||||
/// The usage hint for this buffer. Use StaticDraw for one-time uploads to
|
||||
/// vertex buffers, and DynamicDraw for repeated uploads to vertex buffers.
|
||||
/// </summary>
|
||||
public BufferUsageHint Usage
|
||||
{
|
||||
get => _buffer.Usage;
|
||||
@@ -32,12 +43,31 @@ namespace Diamond.Buffers
|
||||
_vdi = VertexDataInfo.GetInfo<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Upload data to this buffer
|
||||
/// </summary>
|
||||
/// <param name="data">The data to upload</param>
|
||||
public void Data(T[] data) => _buffer.Data(_size, data);
|
||||
|
||||
/// <summary>
|
||||
/// Upload a range of data to this buffer
|
||||
/// </summary>
|
||||
/// <param name="offset">The range offset</param>
|
||||
/// <param name="count">The range length</param>
|
||||
/// <param name="data">The data to upload, offset and length apply to both this and the target</param>
|
||||
public void Data(int offset, int count, T[] data) => _buffer.SubData(_size, offset, count, data);
|
||||
|
||||
/// <summary>
|
||||
/// Upload a range of data to this buffer
|
||||
/// </summary>
|
||||
/// <param name="data">The data to upload</param>
|
||||
public void Data(SubArray<T> data) => Data(data.Offset, data.Length, data.Array);
|
||||
|
||||
/// <summary>
|
||||
/// Point this buffer to a program's vertex attributes. T must have [VertexDataAttribute], and all fields
|
||||
/// of T must have [VertexPointerAttribute] to infer vertex pointer locations.
|
||||
/// </summary>
|
||||
/// <param name="program">The program to point this buffer to</param>
|
||||
public void PointTo(Program program)
|
||||
{
|
||||
if (_vdi == null)
|
||||
@@ -60,6 +90,13 @@ namespace Diamond.Buffers
|
||||
? $"Buffer<{typeof(T).Name}> {Target} ({Id})"
|
||||
: $"Buffer<{typeof(T).Name}> {Target} {Name} ({Id})";
|
||||
|
||||
/// <summary>
|
||||
/// Create an empty buffer of this type
|
||||
/// </summary>
|
||||
/// <param name="target">The buffer target</param>
|
||||
/// <param name="usage">The initial usage hint</param>
|
||||
/// <param name="name">The name of this GLObject</param>
|
||||
/// <returns>The buffer, or null if initialization failed</returns>
|
||||
internal static Buffer<T> Empty(BufferTarget target, BufferUsageHint usage, string name)
|
||||
{
|
||||
var wrapper = new BufferWrap(target, usage);
|
||||
@@ -70,6 +107,14 @@ namespace Diamond.Buffers
|
||||
return service;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a buffer of this type and upload data
|
||||
/// </summary>
|
||||
/// <param name="data">The data to upload</param>
|
||||
/// <param name="target">The buffer target</param>
|
||||
/// <param name="usage">The initial usage hint</param>
|
||||
/// <param name="name">The name of this GLObject</param>
|
||||
/// <returns>The buffer, or null if initialization failed</returns>
|
||||
internal static Buffer<T> FromData(T[] data, BufferTarget target, BufferUsageHint usage, string name = null)
|
||||
{
|
||||
var service = Empty(target, usage, name);
|
||||
@@ -80,11 +125,29 @@ namespace Diamond.Buffers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class for static Buffer operations and public factory methods
|
||||
/// </summary>
|
||||
public static class Buffer
|
||||
{
|
||||
/// <summary>
|
||||
/// Create an empty buffer of this type
|
||||
/// </summary>
|
||||
/// <param name="target">The buffer target</param>
|
||||
/// <param name="usage">The initial usage hint</param>
|
||||
/// <param name="name">The name of this GLObject</param>
|
||||
/// <returns>The buffer, or null if initialization failed</returns>
|
||||
public static Buffer<T> Empty<T>(BufferTarget target, BufferUsageHint usage = BufferUsageHint.StaticDraw,
|
||||
string name = null) where T : struct => Buffer<T>.Empty(target, usage, name);
|
||||
|
||||
/// <summary>
|
||||
/// Create a buffer of this type and upload data
|
||||
/// </summary>
|
||||
/// <param name="data">The data to upload</param>
|
||||
/// <param name="target">The buffer target</param>
|
||||
/// <param name="usage">The initial usage hint</param>
|
||||
/// <param name="name">The name of this GLObject</param>
|
||||
/// <returns>The buffer, or null if initialization failed</returns>
|
||||
public static Buffer<T> FromData<T>(T[] data, BufferTarget target,
|
||||
BufferUsageHint usage = BufferUsageHint.StaticDraw,
|
||||
string name = null) where T : struct => Buffer<T>.FromData(data, target, usage, name);
|
||||
|
||||
@@ -60,13 +60,12 @@
|
||||
<Compile Include="Util\SubArray.cs" />
|
||||
<Compile Include="Buffers\VertexDataAttribute.cs" />
|
||||
<Compile Include="Wrappers\Wrapper.cs" />
|
||||
<Compile Include="Level\TileData.cs" />
|
||||
<Compile Include="Util\TileData.cs" />
|
||||
<Compile Include="Util\Mesh.cs" />
|
||||
<Compile Include="Util\ObjVertex.cs" />
|
||||
<Compile Include="Shaders\Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Shaders\Shader.cs" />
|
||||
<Compile Include="Shaders\ShaderException.cs" />
|
||||
<Compile Include="Textures\Texture.cs" />
|
||||
<Compile Include="Buffers\VertexPointerAttribute.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -4,17 +4,33 @@ using NLog;
|
||||
|
||||
namespace Diamond
|
||||
{
|
||||
/// <summary>
|
||||
/// Provide managed access to OpenGL objects
|
||||
/// </summary>
|
||||
public abstract class GLObject : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Logger for all GLObjects
|
||||
/// </summary>
|
||||
protected static readonly Logger Logger = LogManager.GetLogger("GLObject");
|
||||
|
||||
private bool _disposed;
|
||||
|
||||
/// <summary>
|
||||
/// Name of this GLObject used for identification
|
||||
/// </summary>
|
||||
public string Name { get; protected set; } = "GLObject";
|
||||
|
||||
/// <summary>
|
||||
/// Underlying managed wrapper to this OpenGL object
|
||||
/// </summary>
|
||||
internal abstract Wrapper Wrapper { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The OpenGL name of this object
|
||||
/// </summary>
|
||||
public int Id => Wrapper.Id;
|
||||
|
||||
#region IDisposable
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (_disposed)
|
||||
@@ -29,6 +45,10 @@ namespace Diamond
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
#region Implemented
|
||||
|
||||
private bool _disposed;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
@@ -39,5 +59,9 @@ namespace Diamond
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -6,14 +6,22 @@ using OpenTK.Graphics.OpenGL4;
|
||||
|
||||
namespace Diamond.Shaders
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages an OpenGL Program object
|
||||
/// </summary>
|
||||
public class Program : GLObject
|
||||
{
|
||||
private readonly ProgramWrap _program;
|
||||
internal override Wrapper Wrapper => _program;
|
||||
|
||||
/// <summary>
|
||||
/// The currently active program. Manually invoking glUseProgram will break this.
|
||||
/// </summary>
|
||||
public static Program Current { get; private set; }
|
||||
|
||||
// keep a cache of uniform and attributes to prevent repeated queries
|
||||
private readonly Dictionary<string, int> _uniforms = new Dictionary<string, int>();
|
||||
|
||||
private readonly Dictionary<string, int> _attributes = new Dictionary<string, int>();
|
||||
|
||||
internal Program(ProgramWrap program, string name)
|
||||
@@ -22,24 +30,42 @@ namespace Diamond.Shaders
|
||||
Name = name;
|
||||
}
|
||||
|
||||
// todo change these to not use int? - possibly use TryGet, or return negative value if not present
|
||||
|
||||
/// <summary>
|
||||
/// Get the location of a uniform
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the uniform</param>
|
||||
/// <returns>The location, or no value if uniform not present</returns>
|
||||
public int? UniformLocation(string name)
|
||||
{
|
||||
if (_uniforms.ContainsKey(name)) return _uniforms[name];
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the location of an attribute
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the attribute</param>
|
||||
/// <returns>The location, or no value if attribute not present</returns>
|
||||
public int? AttributeLocation(string name)
|
||||
{
|
||||
if (_attributes.ContainsKey(name)) return _attributes[name];
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this Program to render. Also updates Program.Current
|
||||
/// </summary>
|
||||
public void Use()
|
||||
{
|
||||
GL.UseProgram(Id);
|
||||
Current = this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use the default shader to render
|
||||
/// </summary>
|
||||
//? Could create static Program instance which wraps the default shader
|
||||
// ie Shader.Default.Use()
|
||||
// would also allow sending arrays to the default attribs like gl_Vertex etc.
|
||||
@@ -49,6 +75,10 @@ namespace Diamond.Shaders
|
||||
Current = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to try to link this program
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private bool Link()
|
||||
{
|
||||
_uniforms.Clear();
|
||||
@@ -68,6 +98,10 @@ namespace Diamond.Shaders
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to attach a shader to this program
|
||||
/// </summary>
|
||||
/// <param name="shader">The shader to attach</param>
|
||||
private void Attach(Shader shader)
|
||||
{
|
||||
_program.Attach((ShaderWrap) shader.Wrapper);
|
||||
@@ -75,16 +109,23 @@ namespace Diamond.Shaders
|
||||
|
||||
public override string ToString() => $"Program \'{Name}\' ({Id})";
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Factory Methods
|
||||
|
||||
/// <summary>
|
||||
/// Create a program from compiled shaders
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this GLObject</param>
|
||||
/// <param name="shaders">The shaders to use in this program</param>
|
||||
/// <returns>The linked program, or null if initialization failed</returns>
|
||||
public static Program FromShaders(string name, params Shader[] shaders) => FromShaders(name,
|
||||
(IEnumerable<Shader>) shaders);
|
||||
|
||||
/// <summary>
|
||||
/// Create a program from compiled shaders
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this GLObject</param>
|
||||
/// <param name="shaders">The shaders to use in this program</param>
|
||||
/// <returns>The linked program, or null if initialization failed</returns>
|
||||
public static Program FromShaders(string name, IEnumerable<Shader>shaders)
|
||||
{
|
||||
if (shaders == null)
|
||||
@@ -110,9 +151,9 @@ namespace Diamond.Shaders
|
||||
service.Attach(shader);
|
||||
}
|
||||
|
||||
service.Link();
|
||||
var linked = service.Link();
|
||||
|
||||
if (!wrapper.Linked)
|
||||
if (!linked)
|
||||
{
|
||||
Logger.Warn("Failed to link {0}", service);
|
||||
Logger.Debug("InfoLog for {0}", service);
|
||||
@@ -125,9 +166,18 @@ namespace Diamond.Shaders
|
||||
return service;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Create a program from compiled shaders
|
||||
/// </summary>
|
||||
/// <param name="shaders">The shaders to use in this program</param>
|
||||
/// <returns>The linked program, or null if initialization failed</returns>
|
||||
public static Program FromShaders(params Shader[] shaders) => FromShaders((IEnumerable<Shader>) shaders);
|
||||
|
||||
/// <summary>
|
||||
/// Create a program from compiled shaders
|
||||
/// </summary>
|
||||
/// <param name="shaders">The shaders to use in this program</param>
|
||||
/// <returns>The linked program, or null if initialization failed</returns>
|
||||
public static Program FromShaders(IEnumerable<Shader> shaders)
|
||||
{
|
||||
var shaderList = shaders.ToList(); // prevent multiple enumeration
|
||||
@@ -136,14 +186,26 @@ namespace Diamond.Shaders
|
||||
return FromShaders(name, shaderList);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create shaders from glsl source files, and create a program using them.
|
||||
/// Shader types must be inferrable from file extensions.
|
||||
/// </summary>
|
||||
/// <param name="paths">The glsl source files</param>
|
||||
/// <returns>The linked program, or null if initialization faileds</returns>
|
||||
public static Program FromFiles(params string[] paths)
|
||||
{
|
||||
var shaders = paths.Select(Shader.FromFile).ToList();
|
||||
if (paths == null)
|
||||
{
|
||||
Logger.Warn("Cannot create a program from no shaders.");
|
||||
return null;
|
||||
}
|
||||
|
||||
var shaders = paths.Select(path => Shader.FromFile(path)).ToList();
|
||||
|
||||
var program = FromShaders(shaders);
|
||||
|
||||
foreach (var shader in shaders)
|
||||
shader.Dispose();
|
||||
shader?.Dispose();
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
@@ -6,12 +6,22 @@ using OpenTK.Graphics.OpenGL4;
|
||||
|
||||
namespace Diamond.Shaders
|
||||
{
|
||||
/// <summary>
|
||||
/// Manges a OpenGL Shader object
|
||||
/// </summary>
|
||||
public class Shader : GLObject
|
||||
{
|
||||
private readonly ShaderWrap _shader;
|
||||
internal override Wrapper Wrapper => _shader;
|
||||
|
||||
/// <summary>
|
||||
/// The source used to create this shader
|
||||
/// </summary>
|
||||
public string Source { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The type of this shader
|
||||
/// </summary>
|
||||
public ShaderType Type { get; }
|
||||
|
||||
internal Shader(ShaderWrap shader, string source, ShaderType type, string name)
|
||||
@@ -26,14 +36,24 @@ namespace Diamond.Shaders
|
||||
|
||||
#region Factory Methods
|
||||
|
||||
// Used to infer shader type based on file extension
|
||||
private static readonly Dictionary<string, ShaderType> Extensions = new Dictionary<string, ShaderType>
|
||||
{
|
||||
[".vs"] = ShaderType.VertexShader,
|
||||
[".vert"] = ShaderType.VertexShader,
|
||||
[".fs"] = ShaderType.FragmentShader,
|
||||
[".frag"] = ShaderType.FragmentShader,
|
||||
[".gs"] = ShaderType.GeometryShader,
|
||||
[".geom"] = ShaderType.GeometryShader,
|
||||
};
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Create and compile a shader from glsl source code
|
||||
/// </summary>
|
||||
/// <param name="source">The glsl source</param>
|
||||
/// <param name="type">The type of shader to create</param>
|
||||
/// <param name="name">The name of this GLObject</param>
|
||||
/// <returns>The compiled Shader, or null if initialization failed</returns>
|
||||
public static Shader FromSource(string source, ShaderType type, string name = "Shader")
|
||||
{
|
||||
var wrapper = new ShaderWrap(type);
|
||||
@@ -57,7 +77,14 @@ namespace Diamond.Shaders
|
||||
return service;
|
||||
}
|
||||
|
||||
public static Shader FromFile(string path, ShaderType type)
|
||||
/// <summary>
|
||||
/// Create and compile a shader from a glsl source file
|
||||
/// </summary>
|
||||
/// <param name="path">The path to the glsl source file</param>
|
||||
/// <param name="type">The type of the shader to create</param>
|
||||
/// <param name="name">The name of this GLObject</param>
|
||||
/// <returns></returns>
|
||||
public static Shader FromFile(string path, ShaderType type, string name = null)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
@@ -65,11 +92,21 @@ namespace Diamond.Shaders
|
||||
return null;
|
||||
}
|
||||
|
||||
var name = Path.GetFileNameWithoutExtension(path);
|
||||
if (name == null)
|
||||
name = Path.GetFileNameWithoutExtension(path);
|
||||
|
||||
return FromSource(File.ReadAllText(path), type, name);
|
||||
}
|
||||
|
||||
public static Shader FromFile(string path)
|
||||
/// <summary>
|
||||
/// Create and compile a shader from a glsl source file. Shader type is inferred from file extension.
|
||||
/// Extension must be .vs, .vert, .fs, .frag, .gs, or .geom. This can optionally be followed by .glsl or .txt,
|
||||
/// but the shader type extension must be present.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to the glsl source file</param>
|
||||
/// <param name="name">The name of this GLObject</param>
|
||||
/// <returns>The compiled shader, or null if initialization failed or shader type cannot be inferred</returns>
|
||||
public static Shader FromFile(string path, string name = null)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
@@ -78,12 +115,14 @@ namespace Diamond.Shaders
|
||||
}
|
||||
|
||||
var ext = Path.GetExtension(path);
|
||||
var name = Path.GetFileNameWithoutExtension(path);
|
||||
var fileName = Path.GetFileNameWithoutExtension(path);
|
||||
|
||||
// get sub-extension if real extension is not valid
|
||||
if (ext != null)
|
||||
if (!Extensions.ContainsKey(ext))
|
||||
ext = Path.GetExtension(name);
|
||||
ext = Path.GetExtension(fileName);
|
||||
|
||||
// if no extension, no sub-extension, or invalid sub-extension
|
||||
if (ext == null || !Extensions.ContainsKey(ext))
|
||||
{
|
||||
Logger.Warn("Could not infer shader type from glsl file name {0}", path);
|
||||
@@ -91,8 +130,10 @@ namespace Diamond.Shaders
|
||||
}
|
||||
|
||||
var type = Extensions[ext];
|
||||
if (name == null)
|
||||
name = fileName;
|
||||
|
||||
return FromFile(path, type);
|
||||
return FromFile(path, type, name);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Diamond.Shaders
|
||||
{
|
||||
/// <summary>
|
||||
/// Exception relating to <code>Shader</code> and <code>Program</code> operations.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ShaderException : Exception
|
||||
{
|
||||
public ShaderException()
|
||||
{
|
||||
}
|
||||
|
||||
public ShaderException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public ShaderException(string message, Exception inner)
|
||||
: base(message, inner)
|
||||
{
|
||||
}
|
||||
|
||||
protected ShaderException(
|
||||
SerializationInfo info,
|
||||
StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using Diamond.Wrappers;
|
||||
using NLog;
|
||||
using OpenTK.Graphics.OpenGL4;
|
||||
@@ -7,6 +8,9 @@ using PixelFormat = OpenTK.Graphics.OpenGL4.PixelFormat;
|
||||
|
||||
namespace Diamond.Textures
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages a OpenGL Texture object
|
||||
/// </summary>
|
||||
public class Texture : GLObject
|
||||
{
|
||||
private readonly TextureWrap _texture;
|
||||
@@ -18,15 +22,26 @@ namespace Diamond.Textures
|
||||
Name = name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This textures target; how it is used
|
||||
/// </summary>
|
||||
public TextureTarget Target => _texture.Target;
|
||||
|
||||
public void Bind() => _texture.Bind();
|
||||
/// <summary>
|
||||
/// Bind this texture to a particular unit
|
||||
/// </summary>
|
||||
public void Bind(int unit) => _texture.Bind(unit);
|
||||
|
||||
public override string ToString() => Name == null ? $"{Target} ({Id})" : $"{Target} \'{Name}\' ({Id})";
|
||||
|
||||
#region Factory Methods
|
||||
|
||||
/// <summary>
|
||||
/// Create a texture object and upload bitmap data to it
|
||||
/// </summary>
|
||||
/// <param name="bmp">The image to upload</param>
|
||||
/// <param name="name">The name of this GLObject</param>
|
||||
/// <returns>The initialized Texture, or null if initialsation failed</returns>
|
||||
public static Texture FromBitmap(Bitmap bmp, string name = null)
|
||||
{
|
||||
var wrapper = new TextureWrap(TextureTarget.Texture2D);
|
||||
@@ -35,6 +50,8 @@ namespace Diamond.Textures
|
||||
Logger.Debug("Created Texture {0}", service);
|
||||
|
||||
wrapper.Bind();
|
||||
|
||||
// todo: expose texture parameters to enable setting different filters
|
||||
wrapper.TexParameter(TextureParameterName.TextureMinFilter, (int) TextureMinFilter.Nearest);
|
||||
wrapper.TexParameter(TextureParameterName.TextureMagFilter, (int) TextureMagFilter.Nearest);
|
||||
|
||||
@@ -47,9 +64,18 @@ namespace Diamond.Textures
|
||||
return service;
|
||||
}
|
||||
|
||||
public static Texture FromFile(string path)
|
||||
/// <summary>
|
||||
/// Create a texture and upload the contents of an image file to it
|
||||
/// </summary>
|
||||
/// <param name="path">The path to the file</param>
|
||||
/// <param name="name">The name of this GLObject</param>
|
||||
/// <returns>The initialized Texture, or null if instantiation failed</returns>
|
||||
public static Texture FromFile(string path, string name = null)
|
||||
{
|
||||
return FromBitmap(new Bitmap(path));
|
||||
if (name == null)
|
||||
name = Path.GetFileNameWithoutExtension(path);
|
||||
|
||||
return FromBitmap(new Bitmap(path), name);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Diamond.Buffers;
|
||||
using OpenTK;
|
||||
|
||||
namespace Diamond.Level
|
||||
namespace Diamond.Util
|
||||
{
|
||||
[VertexData(Divisor = 1)]
|
||||
public struct TileData
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Diamond.Buffers;
|
||||
using Diamond.Level;
|
||||
using Diamond.Shaders;
|
||||
using Diamond.Textures;
|
||||
using Diamond.Util;
|
||||
|
||||
Reference in New Issue
Block a user