mirror of
https://github.com/MaddyThorson/StrawberryBF.git
synced 2025-07-18 19:41:54 +08:00
OpenGL rendering hooked up. Better platform layer abstraction
This commit is contained in:
@ -1,110 +1,20 @@
|
||||
using System.Collections;
|
||||
using System;
|
||||
|
||||
namespace Strawberry
|
||||
{
|
||||
public class Batcher
|
||||
public abstract class Batcher
|
||||
{
|
||||
static public int VertexSize => sizeof(Vertex);
|
||||
public abstract void Draw();
|
||||
|
||||
private List<Batch> batchStack = new List<Batch>() ~ DeleteContainerAndItems!(_);
|
||||
private Batch top => batchStack.Count > 0 ? batchStack[batchStack.Count - 1] : null;
|
||||
protected abstract void PushQuad(Vertex a, Vertex b, Vertex c, Vertex d);
|
||||
protected abstract void PushTri(Vertex a, Vertex b, Vertex c);
|
||||
|
||||
private List<Vertex> vertices = new .() ~ delete _;
|
||||
private List<uint32> indices = new .() ~ delete _;
|
||||
|
||||
private uint32 vaoID;
|
||||
private uint32 vertexBufferID;
|
||||
private uint32 indexBufferID;
|
||||
|
||||
public this()
|
||||
public void Rect(float x, float y, float w, float h, Color color)
|
||||
{
|
||||
GL.glGenVertexArrays(1, &vaoID);
|
||||
GL.glBindVertexArray(vaoID);
|
||||
GL.glGenBuffers(1, &vertexBufferID);
|
||||
GL.glGenBuffers(1, &indexBufferID);
|
||||
GL.glBindVertexArray(0);
|
||||
PushQuad(.Shape(.(x, y), color), .Shape(.(x + w, y), color), .Shape(.(x + w, y + h), color), .Shape(.(x, y + h), color));
|
||||
}
|
||||
|
||||
public ~this()
|
||||
public void Rect(Rect rect, Color color)
|
||||
{
|
||||
GL.glDeleteBuffers(1, &vertexBufferID);
|
||||
GL.glDeleteBuffers(1, &indexBufferID);
|
||||
GL.glDeleteVertexArrays(1, &vaoID);
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
GL.glDisable(GL.GL_CULL_FACE);
|
||||
|
||||
GL.glBindVertexArray(vaoID);
|
||||
|
||||
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vertexBufferID);
|
||||
GL.glEnableVertexAttribArray(0);
|
||||
GL.glVertexAttribPointer(0, 2, GL.GL_FLOAT, GL.GL_FALSE, Batcher.VertexSize, (void*)0);
|
||||
GL.glEnableVertexAttribArray(1);
|
||||
GL.glVertexAttribPointer(1, 2, GL.GL_FLOAT, GL.GL_FALSE, Batcher.VertexSize, (void*)8);
|
||||
GL.glEnableVertexAttribArray(2);
|
||||
GL.glVertexAttribPointer(2, 4, GL.GL_UNSIGNED_BYTE, GL.GL_TRUE, Batcher.VertexSize, (void*)16);
|
||||
GL.glEnableVertexAttribArray(3);
|
||||
GL.glVertexAttribPointer(3, 3, GL.GL_UNSIGNED_BYTE, GL.GL_TRUE, Batcher.VertexSize, (void*)20);
|
||||
GL.glBufferData(GL.GL_ARRAY_BUFFER, vertices.Count * sizeof(Vertex), vertices.Ptr, GL.GL_DYNAMIC_DRAW);
|
||||
|
||||
GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
|
||||
GL.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indices.Count * sizeof(uint32), indices.Ptr, GL.GL_DYNAMIC_DRAW);
|
||||
|
||||
GL.glDrawElements(GL.GL_TRIANGLES, indices.Count, GL.GL_UNSIGNED_INT, (void*)0);
|
||||
GL.glBindVertexArray(0);
|
||||
|
||||
vertices.Clear();
|
||||
indices.Clear();
|
||||
}
|
||||
|
||||
public void PushQuad(Vector a, Vector b, Vector c, Vector d, Color color)
|
||||
{
|
||||
uint32 count = (uint32)vertices.Count;
|
||||
|
||||
vertices.Add(Vertex.Shape(a, color));
|
||||
vertices.Add(Vertex.Shape(b, color));
|
||||
vertices.Add(Vertex.Shape(c, color));
|
||||
vertices.Add(Vertex.Shape(d, color));
|
||||
|
||||
indices.Add(count + 0);
|
||||
indices.Add(count + 1);
|
||||
indices.Add(count + 2);
|
||||
indices.Add(count + 0);
|
||||
indices.Add(count + 2);
|
||||
indices.Add(count + 3);
|
||||
}
|
||||
|
||||
private class Batch
|
||||
{
|
||||
uint32 bufferHandle;
|
||||
|
||||
public this()
|
||||
{
|
||||
//GL.glGenBuffers(1, &bufferHandle);
|
||||
//GL.glBindBuffer(GL.GL_ARRAY_BUFFER, bufferHandle);
|
||||
//GL.glDeleteBuffers(1, &bufferHandle);
|
||||
}
|
||||
}
|
||||
|
||||
[Ordered, Packed, CRepr]
|
||||
private struct Vertex
|
||||
{
|
||||
public Vector Position;
|
||||
public Vector TexCoord;
|
||||
public Color Color;
|
||||
public (uint8, uint8, uint8) Mode;
|
||||
|
||||
static public Vertex Shape(Vector pos, Color color)
|
||||
{
|
||||
Vertex v = Vertex();
|
||||
v.Position = pos;
|
||||
v.Color = color;
|
||||
v.Mode = (0, 0, 255);
|
||||
return v;
|
||||
}
|
||||
Rect(rect.X, rect.Y, rect.Width, rect.Height, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,50 +23,7 @@ namespace Strawberry
|
||||
|
||||
//Graphics
|
||||
public abstract Texture LoadTexture(String path);
|
||||
}
|
||||
|
||||
public abstract class Texture
|
||||
{
|
||||
public int Width { get; private set; }
|
||||
public int Height { get; private set; }
|
||||
|
||||
public virtual this(int width, int height, uint8* pixels)
|
||||
{
|
||||
Width = width;
|
||||
Height = height;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class Shader
|
||||
{
|
||||
public bool IsValid { get; protected set; }
|
||||
|
||||
public this(ShaderDef def)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public struct ShaderDef
|
||||
{
|
||||
public String Vertex;
|
||||
public String Fragment;
|
||||
|
||||
public this(String vertex, String fragment)
|
||||
{
|
||||
Vertex = vertex;
|
||||
Fragment = fragment;
|
||||
}
|
||||
|
||||
public this(String[2] str)
|
||||
{
|
||||
Vertex = str[0];
|
||||
Fragment = str[1];
|
||||
}
|
||||
|
||||
static implicit public operator ShaderDef(String[2] str)
|
||||
{
|
||||
return ShaderDef(str);
|
||||
}
|
||||
public abstract Batcher CreateBatcher();
|
||||
public abstract Shader CreateShader(ShaderDef def);
|
||||
}
|
||||
}
|
||||
|
88
src/PlatformLayer/SDL2/SDL2Batcher.bf
Normal file
88
src/PlatformLayer/SDL2/SDL2Batcher.bf
Normal file
@ -0,0 +1,88 @@
|
||||
using System.Collections;
|
||||
using System;
|
||||
|
||||
namespace Strawberry.SDL2
|
||||
{
|
||||
public class SDL2Batcher : Batcher
|
||||
{
|
||||
private List<Vertex> vertices = new .() ~ delete _;
|
||||
private List<uint32> indices = new .() ~ delete _;
|
||||
|
||||
private uint32 vaoID;
|
||||
private uint32 vertexBufferID;
|
||||
private uint32 indexBufferID;
|
||||
|
||||
public this()
|
||||
{
|
||||
GL.glGenVertexArrays(1, &vaoID);
|
||||
GL.glBindVertexArray(vaoID);
|
||||
GL.glGenBuffers(1, &vertexBufferID);
|
||||
GL.glGenBuffers(1, &indexBufferID);
|
||||
GL.glBindVertexArray(0);
|
||||
}
|
||||
|
||||
public ~this()
|
||||
{
|
||||
GL.glDeleteBuffers(1, &vertexBufferID);
|
||||
GL.glDeleteBuffers(1, &indexBufferID);
|
||||
GL.glDeleteVertexArrays(1, &vaoID);
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
GL.glDisable(GL.GL_CULL_FACE);
|
||||
|
||||
GL.glBindVertexArray(vaoID);
|
||||
|
||||
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vertexBufferID);
|
||||
GL.glEnableVertexAttribArray(0);
|
||||
GL.glVertexAttribPointer(0, 2, GL.GL_FLOAT, GL.GL_FALSE, sizeof(Vertex), (void*)0);
|
||||
GL.glEnableVertexAttribArray(1);
|
||||
GL.glVertexAttribPointer(1, 2, GL.GL_FLOAT, GL.GL_FALSE, sizeof(Vertex), (void*)8);
|
||||
GL.glEnableVertexAttribArray(2);
|
||||
GL.glVertexAttribPointer(2, 4, GL.GL_UNSIGNED_BYTE, GL.GL_TRUE, sizeof(Vertex), (void*)16);
|
||||
GL.glEnableVertexAttribArray(3);
|
||||
GL.glVertexAttribPointer(3, 3, GL.GL_UNSIGNED_BYTE, GL.GL_TRUE, sizeof(Vertex), (void*)20);
|
||||
GL.glBufferData(GL.GL_ARRAY_BUFFER, vertices.Count * sizeof(Vertex), vertices.Ptr, GL.GL_DYNAMIC_DRAW);
|
||||
|
||||
GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
|
||||
GL.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indices.Count * sizeof(uint32), indices.Ptr, GL.GL_DYNAMIC_DRAW);
|
||||
|
||||
GL.glDrawElements(GL.GL_TRIANGLES, indices.Count, GL.GL_UNSIGNED_INT, (void*)0);
|
||||
GL.glBindVertexArray(0);
|
||||
|
||||
vertices.Clear();
|
||||
indices.Clear();
|
||||
}
|
||||
|
||||
protected override void PushQuad(Vertex a, Vertex b, Vertex c, Vertex d)
|
||||
{
|
||||
uint32 count = (uint32)vertices.Count;
|
||||
|
||||
vertices.Add(a);
|
||||
vertices.Add(b);
|
||||
vertices.Add(c);
|
||||
vertices.Add(d);
|
||||
|
||||
indices.Add(count + 0);
|
||||
indices.Add(count + 1);
|
||||
indices.Add(count + 2);
|
||||
indices.Add(count + 0);
|
||||
indices.Add(count + 2);
|
||||
indices.Add(count + 3);
|
||||
}
|
||||
|
||||
protected override void PushTri(Vertex a, Vertex b, Vertex c)
|
||||
{
|
||||
uint32 count = (uint32)vertices.Count;
|
||||
|
||||
vertices.Add(a);
|
||||
vertices.Add(b);
|
||||
vertices.Add(c);
|
||||
|
||||
indices.Add(count + 0);
|
||||
indices.Add(count + 1);
|
||||
indices.Add(count + 2);
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ using SDL2;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Strawberry
|
||||
namespace Strawberry.SDL2
|
||||
{
|
||||
public class SDL2PlatformLayer : PlatformLayer
|
||||
{
|
||||
@ -118,11 +118,6 @@ namespace Strawberry
|
||||
}
|
||||
}
|
||||
|
||||
static void* SdlGetProcAddress(StringView string)
|
||||
{
|
||||
return SDL.SDL_GL_GetProcAddress(string.ToScopeCStr!());
|
||||
}
|
||||
|
||||
public ~this()
|
||||
{
|
||||
delete gamepads;
|
||||
@ -134,6 +129,11 @@ namespace Strawberry
|
||||
SDL.Quit();
|
||||
}
|
||||
|
||||
static void* SdlGetProcAddress(StringView string)
|
||||
{
|
||||
return SDL.SDL_GL_GetProcAddress(string.ToScopeCStr!());
|
||||
}
|
||||
|
||||
public override bool Closed()
|
||||
{
|
||||
SDL.Event event;
|
||||
@ -149,21 +149,12 @@ namespace Strawberry
|
||||
GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
|
||||
GL.glUseProgram(glProgram);
|
||||
|
||||
float zNearPlane = 0;
|
||||
float zFarPlane = 1000;
|
||||
|
||||
float[16] mat =
|
||||
.(2.0f / Game.Width, 0, 0, 0,
|
||||
0, 2.0f / Game.Height, 0, 0,
|
||||
0, 0, 1.0f / (zNearPlane - zFarPlane), zNearPlane / (zNearPlane - zFarPlane),
|
||||
0, 0, 0, 1);
|
||||
Mat4x4 mat = Mat4x4.CreateOrthographic(Game.Width, Game.Height * 0.5f, 0, 1);
|
||||
mat *= Mat4x4.CreateScale(.(1, -1, 1));
|
||||
mat *= Mat4x4.CreateTranslation(.(-1, 1, 0));
|
||||
|
||||
let loc = GL.glGetUniformLocation(glProgram, "u_matrix");
|
||||
GL.glUniformMatrix4fv(loc, 1, GL.GL_FALSE, &mat);
|
||||
|
||||
Batcher b = scope Batcher();
|
||||
b.PushQuad(.(-40, -40), .(40, -40), .(40, 40), .(-40, 40), .Yellow);
|
||||
b.Draw();
|
||||
GL.glUniformMatrix4fv(loc, 1, GL.GL_FALSE, &mat.Values);
|
||||
}
|
||||
|
||||
public override void RenderEnd()
|
||||
@ -219,73 +210,15 @@ namespace Strawberry
|
||||
else
|
||||
return val / 32768f;
|
||||
}
|
||||
}
|
||||
|
||||
class SDL2Texture : Texture
|
||||
{
|
||||
private uint32 handle;
|
||||
|
||||
public this(int width, int height, uint8* pixels)
|
||||
: base(width, height, pixels)
|
||||
public override Batcher CreateBatcher()
|
||||
{
|
||||
GL.glGenTextures(1, &handle);
|
||||
GL.glBindTexture(GL.GL_TEXTURE_2D, handle);
|
||||
GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, width, height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, pixels);
|
||||
return new SDL2Batcher();
|
||||
}
|
||||
|
||||
public ~this()
|
||||
public override Shader CreateShader(ShaderDef def)
|
||||
{
|
||||
GL.glDeleteTextures(1, &handle);
|
||||
}
|
||||
}
|
||||
|
||||
class SDL2Shader : Shader
|
||||
{
|
||||
public uint vertexHandle;
|
||||
public uint fragmentHandle;
|
||||
|
||||
public this(ShaderDef def)
|
||||
: base(def)
|
||||
{
|
||||
IsValid = true;
|
||||
int32 logLen = 0;
|
||||
char8[1024] log;
|
||||
|
||||
vertexHandle = GL.glCreateShader(GL.GL_VERTEX_SHADER);
|
||||
{
|
||||
int32 len = (int32)def.Vertex.Length;
|
||||
char8* data = def.Vertex.CStr();
|
||||
GL.glShaderSource(vertexHandle, 1, &data, &len);
|
||||
GL.glCompileShader(vertexHandle);
|
||||
GL.glGetShaderInfoLog(vertexHandle, 1024, &logLen, &log);
|
||||
|
||||
if (logLen > 0)
|
||||
{
|
||||
Calc.Log(&log, logLen);
|
||||
IsValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
fragmentHandle = GL.glCreateShader(GL.GL_FRAGMENT_SHADER);
|
||||
{
|
||||
int32 len = (int32)def.Fragment.Length;
|
||||
char8* data = def.Fragment.CStr();
|
||||
GL.glShaderSource(fragmentHandle, 1, &data, &len);
|
||||
GL.glCompileShader(fragmentHandle);
|
||||
GL.glGetShaderInfoLog(fragmentHandle, 1024, &logLen, &log);
|
||||
|
||||
if (logLen > 0)
|
||||
{
|
||||
Calc.Log(&log, logLen);
|
||||
IsValid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ~this()
|
||||
{
|
||||
GL.glDeleteShader(vertexHandle);
|
||||
GL.glDeleteShader(fragmentHandle);
|
||||
return new SDL2Shader(def);
|
||||
}
|
||||
}
|
||||
}
|
52
src/PlatformLayer/SDL2/SDL2Shader.bf
Normal file
52
src/PlatformLayer/SDL2/SDL2Shader.bf
Normal file
@ -0,0 +1,52 @@
|
||||
namespace Strawberry.SDL2
|
||||
{
|
||||
class SDL2Shader : Shader
|
||||
{
|
||||
public uint vertexHandle;
|
||||
public uint fragmentHandle;
|
||||
|
||||
public this(ShaderDef def)
|
||||
: base(def)
|
||||
{
|
||||
IsValid = true;
|
||||
int32 logLen = 0;
|
||||
char8[1024] log;
|
||||
|
||||
vertexHandle = GL.glCreateShader(GL.GL_VERTEX_SHADER);
|
||||
{
|
||||
int32 len = (int32)def.Vertex.Length;
|
||||
char8* data = def.Vertex.CStr();
|
||||
GL.glShaderSource(vertexHandle, 1, &data, &len);
|
||||
GL.glCompileShader(vertexHandle);
|
||||
GL.glGetShaderInfoLog(vertexHandle, 1024, &logLen, &log);
|
||||
|
||||
if (logLen > 0)
|
||||
{
|
||||
Calc.Log(&log, logLen);
|
||||
IsValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
fragmentHandle = GL.glCreateShader(GL.GL_FRAGMENT_SHADER);
|
||||
{
|
||||
int32 len = (int32)def.Fragment.Length;
|
||||
char8* data = def.Fragment.CStr();
|
||||
GL.glShaderSource(fragmentHandle, 1, &data, &len);
|
||||
GL.glCompileShader(fragmentHandle);
|
||||
GL.glGetShaderInfoLog(fragmentHandle, 1024, &logLen, &log);
|
||||
|
||||
if (logLen > 0)
|
||||
{
|
||||
Calc.Log(&log, logLen);
|
||||
IsValid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ~this()
|
||||
{
|
||||
GL.glDeleteShader(vertexHandle);
|
||||
GL.glDeleteShader(fragmentHandle);
|
||||
}
|
||||
}
|
||||
}
|
20
src/PlatformLayer/SDL2/SDL2Texture.bf
Normal file
20
src/PlatformLayer/SDL2/SDL2Texture.bf
Normal file
@ -0,0 +1,20 @@
|
||||
namespace Strawberry.SDL2
|
||||
{
|
||||
class SDL2Texture : Texture
|
||||
{
|
||||
private uint32 handle;
|
||||
|
||||
public this(int width, int height, uint8* pixels)
|
||||
: base(width, height, pixels)
|
||||
{
|
||||
GL.glGenTextures(1, &handle);
|
||||
GL.glBindTexture(GL.GL_TEXTURE_2D, handle);
|
||||
GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, width, height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, pixels);
|
||||
}
|
||||
|
||||
public ~this()
|
||||
{
|
||||
GL.glDeleteTextures(1, &handle);
|
||||
}
|
||||
}
|
||||
}
|
12
src/PlatformLayer/Shader.bf
Normal file
12
src/PlatformLayer/Shader.bf
Normal file
@ -0,0 +1,12 @@
|
||||
namespace Strawberry
|
||||
{
|
||||
public abstract class Shader
|
||||
{
|
||||
public bool IsValid { get; protected set; }
|
||||
|
||||
public this(ShaderDef def)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
27
src/PlatformLayer/ShaderDef.bf
Normal file
27
src/PlatformLayer/ShaderDef.bf
Normal file
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
|
||||
namespace Strawberry
|
||||
{
|
||||
public struct ShaderDef
|
||||
{
|
||||
public String Vertex;
|
||||
public String Fragment;
|
||||
|
||||
public this(String vertex, String fragment)
|
||||
{
|
||||
Vertex = vertex;
|
||||
Fragment = fragment;
|
||||
}
|
||||
|
||||
public this(String[2] str)
|
||||
{
|
||||
Vertex = str[0];
|
||||
Fragment = str[1];
|
||||
}
|
||||
|
||||
static implicit public operator ShaderDef(String[2] str)
|
||||
{
|
||||
return ShaderDef(str);
|
||||
}
|
||||
}
|
||||
}
|
14
src/PlatformLayer/Texture.bf
Normal file
14
src/PlatformLayer/Texture.bf
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Strawberry
|
||||
{
|
||||
public abstract class Texture
|
||||
{
|
||||
public int Width { get; private set; }
|
||||
public int Height { get; private set; }
|
||||
|
||||
public virtual this(int width, int height, uint8* pixels)
|
||||
{
|
||||
Width = width;
|
||||
Height = height;
|
||||
}
|
||||
}
|
||||
}
|
22
src/PlatformLayer/Vertex.bf
Normal file
22
src/PlatformLayer/Vertex.bf
Normal file
@ -0,0 +1,22 @@
|
||||
using System;
|
||||
|
||||
namespace Strawberry
|
||||
{
|
||||
[Ordered, Packed, CRepr]
|
||||
public struct Vertex
|
||||
{
|
||||
public Vector Position;
|
||||
public Vector TexCoord;
|
||||
public Color Color;
|
||||
public (uint8, uint8, uint8) Mode;
|
||||
|
||||
static public Vertex Shape(Vector pos, Color color)
|
||||
{
|
||||
Vertex v = Vertex();
|
||||
v.Position = pos;
|
||||
v.Color = color;
|
||||
v.Mode = (0, 0, 255);
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user