Refactored, and added separate constructor for custom shader.
This commit is contained in:
parent
614602e7cd
commit
512b5f4b13
@ -10,14 +10,19 @@ using SlatedGameToolkit.Framework.Utilities;
|
|||||||
|
|
||||||
namespace SlatedGameToolkit.Framework.Graphics.Render
|
namespace SlatedGameToolkit.Framework.Graphics.Render
|
||||||
{
|
{
|
||||||
public class MeshBatch : IDisposable {
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a grouping of similar meshes that can be rendered with similar properties.
|
||||||
|
/// Specifically, properties that need to be the same are:
|
||||||
|
/// Texture and it's respective properties, model matrix, and vertex buffer array and objects.
|
||||||
|
/// </summary>
|
||||||
|
public class MeshBatchRenderer : IDisposable {
|
||||||
public bool Debug { get; set; }
|
public bool Debug { get; set; }
|
||||||
private const int VERTEX_LENGTH = 9;
|
private const int VERTEX_LENGTH = 9;
|
||||||
private bool disposed;
|
private bool disposed;
|
||||||
private float batchDelta;
|
private float batchDelta;
|
||||||
public GLContext GLContext {get; private set; }
|
public GLContext GLContext {get; private set; }
|
||||||
private int projALoc, viewALoc, modelALoc, texturedALoc, singleChanneledALoc, flippedALoc;
|
private int projULoc, viewULoc, modelULoc, texturedULoc, singleChanneledULoc, flippedULoc;
|
||||||
private bool flipped, singleChanneled;
|
|
||||||
private Camera camera;
|
private Camera camera;
|
||||||
private RenderProgram renderProgram;
|
private RenderProgram renderProgram;
|
||||||
private ITexture texture;
|
private ITexture texture;
|
||||||
@ -32,15 +37,20 @@ namespace SlatedGameToolkit.Framework.Graphics.Render
|
|||||||
private int[] verticeOffsets;
|
private int[] verticeOffsets;
|
||||||
private int dataIndex, indicesIndex, offsetIndex;
|
private int dataIndex, indicesIndex, offsetIndex;
|
||||||
|
|
||||||
public MeshBatch(Camera camera, RenderProgram renderProgram = null, uint BatchVertexSize = 1024) {
|
/// <summary>
|
||||||
if (renderProgram == null) {
|
/// Instantiates a mesh batch with a default vertex and fragment shader.
|
||||||
VertexShader vert = new VertexShader(EmbeddedResUtils.ReadEmbeddedResourceText("default.vert"));
|
/// </summary>
|
||||||
FragmentShader frag = new FragmentShader(EmbeddedResUtils.ReadEmbeddedResourceText("default.frag"));
|
/// <param name="camera">The camera to use for providing the correct matrices.</param>
|
||||||
renderProgram = new RenderProgram(null, vert, frag);
|
/// <param name="BatchVertexSize">The vertex batch size. Defaults to 1024. This is multiplied by 9 for each individual value of the vertex.</param>
|
||||||
}
|
/// <param name="glContext">The glContext to associate the shaders with. Defaults to the currently active one.</param>
|
||||||
this.renderProgram = renderProgram;
|
public MeshBatchRenderer(Camera camera, uint BatchVertexSize = 1024, GLContext glContext = null) {
|
||||||
this.GLContext = renderProgram.GLContext;
|
VertexShader vert = new VertexShader(EmbeddedResUtils.ReadEmbeddedResourceText("default.vert"));
|
||||||
|
FragmentShader frag = new FragmentShader(EmbeddedResUtils.ReadEmbeddedResourceText("default.frag"));
|
||||||
|
this.GLContext = glContext ?? WindowContextsManager.CurrentGL;
|
||||||
|
renderProgram = new RenderProgram(this.GLContext, vert, frag);
|
||||||
|
|
||||||
this.camera = camera ?? throw new ArgumentNullException("camera");
|
this.camera = camera ?? throw new ArgumentNullException("camera");
|
||||||
|
if (BatchVertexSize < 1) throw new ArgumentException("Batch vertex size cannot be less than 1.");
|
||||||
indices = new uint[BatchVertexSize];
|
indices = new uint[BatchVertexSize];
|
||||||
lengths = new int[BatchVertexSize];
|
lengths = new int[BatchVertexSize];
|
||||||
indiceOffsets = new int[BatchVertexSize];
|
indiceOffsets = new int[BatchVertexSize];
|
||||||
@ -51,16 +61,61 @@ namespace SlatedGameToolkit.Framework.Graphics.Render
|
|||||||
definitions[0] = new VertexAttributeDefinition((uint)GLContext.GetAttribLocation(renderProgram.Handle, "aPosition"), 3);
|
definitions[0] = new VertexAttributeDefinition((uint)GLContext.GetAttribLocation(renderProgram.Handle, "aPosition"), 3);
|
||||||
definitions[1] = new VertexAttributeDefinition((uint)GLContext.GetAttribLocation(renderProgram.Handle, "aColor"), 4);
|
definitions[1] = new VertexAttributeDefinition((uint)GLContext.GetAttribLocation(renderProgram.Handle, "aColor"), 4);
|
||||||
definitions[2] = new VertexAttributeDefinition((uint)GLContext.GetAttribLocation(renderProgram.Handle, "aTexCoord"), 2);
|
definitions[2] = new VertexAttributeDefinition((uint)GLContext.GetAttribLocation(renderProgram.Handle, "aTexCoord"), 2);
|
||||||
renderProgram.Use();
|
|
||||||
modelALoc = GLContext.GetUniformLocation(renderProgram.Handle, "models");
|
|
||||||
viewALoc = GLContext.GetUniformLocation(renderProgram.Handle, "view");
|
|
||||||
projALoc = GLContext.GetUniformLocation(renderProgram.Handle, "projection");
|
|
||||||
texturedALoc = GLContext.GetUniformLocation(renderProgram.Handle, "textured");
|
|
||||||
singleChanneledALoc = GLContext.GetUniformLocation(renderProgram.Handle, "singleChanneled");
|
|
||||||
flippedALoc = GLContext.GetUniformLocation(renderProgram.Handle, "flipped");
|
|
||||||
vertexBuffers.defineVertexAttributes(definitions: definitions);
|
vertexBuffers.defineVertexAttributes(definitions: definitions);
|
||||||
|
renderProgram.Use();
|
||||||
|
modelULoc = GLContext.GetUniformLocation(renderProgram.Handle, "models");
|
||||||
|
viewULoc = GLContext.GetUniformLocation(renderProgram.Handle, "view");
|
||||||
|
projULoc = GLContext.GetUniformLocation(renderProgram.Handle, "projection");
|
||||||
|
texturedULoc = GLContext.GetUniformLocation(renderProgram.Handle, "textured");
|
||||||
|
singleChanneledULoc = GLContext.GetUniformLocation(renderProgram.Handle, "singleChanneled");
|
||||||
|
flippedULoc = GLContext.GetUniformLocation(renderProgram.Handle, "flipped");
|
||||||
|
|
||||||
GLContext.UniformMatrix4fv(projALoc, 1, false, camera.ProjectionMatrix.ToColumnMajorArray());
|
GLContext.UniformMatrix4fv(projULoc, 1, false, camera.ProjectionMatrix.ToColumnMajorArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiates the mesh batch with a custom shader program.
|
||||||
|
///
|
||||||
|
/// For this shader to work with this mesh batch, it must have at least defined the required attributes and uniforms.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="aPosition">The position vertex attribute's name. A vec3. To be used to detect the index of the attribute in the shader program.</param>
|
||||||
|
/// <param name="aColor">The color vertex attribute's name. A vec4. To be used to detect the index of the attribute in the shader program.</param>
|
||||||
|
/// <param name="aTexCoord">The texture coordinate vertex attribute's name. A vec2. To be used to detect the index of the attribute in the shader program.</param>
|
||||||
|
/// <param name="uModels">The models 4x4 matrix's uniform name. To be used to detect the index of the uniform in the shader program.</param>
|
||||||
|
/// <param name="uView">The view 4x4 matrix's uniform name. To be used to detect the index of the uniform in the shader program.</param>
|
||||||
|
/// <param name="uProjection">The projection 4x4 matrix's uniform name. To be used to detect the index of the uniform in the shader program.</param>
|
||||||
|
/// <param name="uTextured">The name of a boolean uniform dictating whether or not the batch of meshes have an associated texture.</param>
|
||||||
|
/// <param name="uSingleChanneled">The name of a boolean uniform dictating whether or not the current texture is single channelled and only uses red.</param>
|
||||||
|
/// <param name="uFlipped">The name of a boolean uniform dictating whether or not the current texture is to have it's coordinates flipped.</param>
|
||||||
|
/// <param name="camera">The camera to use to provide the matrices.</param>
|
||||||
|
/// <param name="renderProgram">The render program to use for the actual rendering.</param>
|
||||||
|
/// <param name="BatchVertexSize">The vertex buffer size. Defaults to 1024, and is multiplied by 9 for the individual values of each vertex.</param>
|
||||||
|
public MeshBatchRenderer(string aPosition, string aColor, string aTexCoord, string uModels, string uView, string uProjection, string uTextured, string uSingleChanneled, string uFlipped, Camera camera, RenderProgram renderProgram, uint BatchVertexSize = 1024) {
|
||||||
|
this.renderProgram = renderProgram ?? throw new ArgumentNullException("renderProgram");
|
||||||
|
this.camera = camera ?? throw new ArgumentNullException("camera");
|
||||||
|
if (BatchVertexSize < 1) throw new ArgumentException("Batch vertex size cannot be less than 1.");
|
||||||
|
this.GLContext = renderProgram.GLContext;
|
||||||
|
|
||||||
|
indices = new uint[BatchVertexSize];
|
||||||
|
lengths = new int[BatchVertexSize];
|
||||||
|
indiceOffsets = new int[BatchVertexSize];
|
||||||
|
data = new float[BatchVertexSize * VERTEX_LENGTH];
|
||||||
|
verticeOffsets = new int[BatchVertexSize];
|
||||||
|
vertexBuffers = new VertexArrayBuffers(GLContext);
|
||||||
|
VertexAttributeDefinition[] definitions = new VertexAttributeDefinition[3];
|
||||||
|
definitions[0] = new VertexAttributeDefinition((uint)GLContext.GetAttribLocation(renderProgram.Handle, aPosition), 3);
|
||||||
|
definitions[1] = new VertexAttributeDefinition((uint)GLContext.GetAttribLocation(renderProgram.Handle, aColor), 4);
|
||||||
|
definitions[2] = new VertexAttributeDefinition((uint)GLContext.GetAttribLocation(renderProgram.Handle, aTexCoord), 2);
|
||||||
|
|
||||||
|
renderProgram.Use();
|
||||||
|
modelULoc = GLContext.GetUniformLocation(renderProgram.Handle, uModels);
|
||||||
|
viewULoc = GLContext.GetUniformLocation(renderProgram.Handle, uView);
|
||||||
|
projULoc = GLContext.GetUniformLocation(renderProgram.Handle, uProjection);
|
||||||
|
texturedULoc = GLContext.GetUniformLocation(renderProgram.Handle, uTextured);
|
||||||
|
singleChanneledULoc = GLContext.GetUniformLocation(renderProgram.Handle, uSingleChanneled);
|
||||||
|
flippedULoc = GLContext.GetUniformLocation(renderProgram.Handle, uFlipped);
|
||||||
|
|
||||||
|
GLContext.UniformMatrix4fv(projULoc, 1, false, camera.ProjectionMatrix.ToColumnMajorArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -92,16 +147,10 @@ namespace SlatedGameToolkit.Framework.Graphics.Render
|
|||||||
if (mesh.Texture?.Handle != this.texture?.Handle) {
|
if (mesh.Texture?.Handle != this.texture?.Handle) {
|
||||||
Flush();
|
Flush();
|
||||||
this.texture = mesh.Texture;
|
this.texture = mesh.Texture;
|
||||||
GLContext.Uniform1i(texturedALoc, texture == null ? 0 : 1);
|
GLContext.Uniform1i(texturedULoc, texture == null ? 0 : 1);
|
||||||
}
|
if (texture != null) {
|
||||||
if (texture != null) {
|
GLContext.Uniform1i(flippedULoc, texture.Flipped ? 1 : 0);
|
||||||
if (flipped != texture.Flipped) {
|
GLContext.Uniform1i(singleChanneledULoc, texture.SingleChanneled ? 1 : 0);
|
||||||
GLContext.Uniform1i(flippedALoc, texture.Flipped ? 1 : 0);
|
|
||||||
this.flipped = texture.Flipped;
|
|
||||||
}
|
|
||||||
if (singleChanneled != texture.SingleChanneled) {
|
|
||||||
GLContext.Uniform1i(singleChanneledALoc, texture.SingleChanneled ? 1 : 0);
|
|
||||||
this.singleChanneled = texture.SingleChanneled;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ValueTuple<Vector3, Vector2>[] vertices = mesh.Vertices;
|
ValueTuple<Vector3, Vector2>[] vertices = mesh.Vertices;
|
||||||
@ -161,9 +210,9 @@ namespace SlatedGameToolkit.Framework.Graphics.Render
|
|||||||
|
|
||||||
vertexBuffers.BufferVertices(data, true);
|
vertexBuffers.BufferVertices(data, true);
|
||||||
vertexBuffers.BufferIndices(indices, true);
|
vertexBuffers.BufferIndices(indices, true);
|
||||||
GLContext.UniformMatrix4fv(modelALoc, 1, false, modelsMatrix.ToColumnMajorArray());
|
GLContext.UniformMatrix4fv(modelULoc, 1, false, modelsMatrix.ToColumnMajorArray());
|
||||||
if (camera.ViewChanged) GLContext.UniformMatrix4fv(viewALoc, 1, false, camera.ViewMatrix.ToColumnMajorArray());
|
if (camera.ViewChanged) GLContext.UniformMatrix4fv(viewULoc, 1, false, camera.ViewMatrix.ToColumnMajorArray());
|
||||||
if (camera.ProjectionChanged) GLContext.UniformMatrix4fv(projALoc, 1, false, camera.ProjectionMatrix.ToColumnMajorArray());
|
if (camera.ProjectionChanged) GLContext.UniformMatrix4fv(projULoc, 1, false, camera.ProjectionMatrix.ToColumnMajorArray());
|
||||||
|
|
||||||
if (Debug) {
|
if (Debug) {
|
||||||
GLContext.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
|
GLContext.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
|
||||||
@ -195,7 +244,7 @@ namespace SlatedGameToolkit.Framework.Graphics.Render
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~MeshBatch()
|
~MeshBatchRenderer()
|
||||||
{
|
{
|
||||||
Dispose(false);
|
Dispose(false);
|
||||||
}
|
}
|
@ -108,7 +108,7 @@ namespace SlatedGameToolkit.Framework.Graphics.Text
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void WriteLine(MeshBatch batch, float x, float y, string text, Color color) {
|
public unsafe void WriteLine(MeshBatchRenderer batch, float x, float y, string text, Color color) {
|
||||||
float currentPoint = x;
|
float currentPoint = x;
|
||||||
float baseLine = y;
|
float baseLine = y;
|
||||||
char[] chars = text.ToCharArray();
|
char[] chars = text.ToCharArray();
|
||||||
|
@ -17,7 +17,7 @@ namespace SlatedGameToolkit.Tools.Utilities.Playground
|
|||||||
{
|
{
|
||||||
private WindowContext window;
|
private WindowContext window;
|
||||||
private Camera2D camera;
|
private Camera2D camera;
|
||||||
private MeshBatch batch;
|
private MeshBatchRenderer renderer;
|
||||||
private BitmapFont font;
|
private BitmapFont font;
|
||||||
private Texture logoTexture, fillerTexture;
|
private Texture logoTexture, fillerTexture;
|
||||||
private RectangleMesh logo, textureTester, untextured;
|
private RectangleMesh logo, textureTester, untextured;
|
||||||
@ -40,7 +40,7 @@ namespace SlatedGameToolkit.Tools.Utilities.Playground
|
|||||||
logoTexture.Dispose();
|
logoTexture.Dispose();
|
||||||
fillerTexture.Dispose();
|
fillerTexture.Dispose();
|
||||||
font.Dispose();
|
font.Dispose();
|
||||||
batch.Dispose();
|
renderer.Dispose();
|
||||||
window.Dispose();
|
window.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ namespace SlatedGameToolkit.Tools.Utilities.Playground
|
|||||||
Vector2 drawableDimensions = window.GetDrawableDimensions();
|
Vector2 drawableDimensions = window.GetDrawableDimensions();
|
||||||
float ratio = drawableDimensions.Y / drawableDimensions.X;
|
float ratio = drawableDimensions.Y / drawableDimensions.X;
|
||||||
camera = new Camera2D(2f, ratio * 2f);
|
camera = new Camera2D(2f, ratio * 2f);
|
||||||
batch = new MeshBatch(camera, BatchVertexSize: 2048);
|
renderer = new MeshBatchRenderer(camera, BatchVertexSize: 2048);
|
||||||
|
|
||||||
logoTexture = TextureLoader.Load2DTexture("Resources/Playground/yhdnbgnc.png");
|
logoTexture = TextureLoader.Load2DTexture("Resources/Playground/yhdnbgnc.png");
|
||||||
logo = new RectangleMesh(logoTexture, Color.White);
|
logo = new RectangleMesh(logoTexture, Color.White);
|
||||||
@ -84,12 +84,12 @@ namespace SlatedGameToolkit.Tools.Utilities.Playground
|
|||||||
|
|
||||||
public void Render(double delta)
|
public void Render(double delta)
|
||||||
{
|
{
|
||||||
batch.Begin(Matrix4x4.Identity, delta);
|
renderer.Begin(Matrix4x4.Identity, delta);
|
||||||
batch.Draw(logo);
|
renderer.Draw(logo);
|
||||||
batch.Draw(textureTester);
|
renderer.Draw(textureTester);
|
||||||
batch.Draw(untextured);
|
renderer.Draw(untextured);
|
||||||
font.WriteLine(batch, 0.25f, -0.35f, "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n1234567890", Color.White);
|
font.WriteLine(renderer, 0.25f, -0.35f, "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n1234567890", Color.White);
|
||||||
batch.End();
|
renderer.End();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update(double timeStep)
|
public void Update(double timeStep)
|
||||||
|
Loading…
Reference in New Issue
Block a user