renderer work

This commit is contained in:
Matt Thorson 2020-09-06 23:11:45 -07:00
parent 82f1f412eb
commit 52d1d5f383
7 changed files with 100 additions and 29 deletions

View File

@ -102,7 +102,8 @@ namespace Strawberry.Sample
{ {
base.Draw(); base.Draw();
DrawHitbox(.Red); DrawHitbox(.Green);
//Game.Batcher.Tex(Assets.Textures["test"], X - 4, Y - 8);
} }
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 B

View File

@ -0,0 +1,30 @@
namespace Strawberry
{
public enum BatchModes
{
TextureTint,
TextureWash,
Shape,
}
public struct Batch
{
public int IndicesStart;
public int IndicesCount;
public Texture Texture;
public BatchModes Mode;
public this(BatchModes mode, Texture texture, int start)
{
Mode = mode;
Texture = texture;
IndicesStart = start;
IndicesCount = 0;
}
public bool Matches(BatchModes mode, Texture texture)
{
return Mode == mode && Texture == texture;
}
}
}

View File

@ -4,6 +4,7 @@ namespace Strawberry
{ {
public class Batcher public class Batcher
{ {
private List<Batch> batches = new .() ~ delete _;
private List<Vertex> vertices = new .() ~ delete _; private List<Vertex> vertices = new .() ~ delete _;
private List<uint32> indices = new .() ~ delete _; private List<uint32> indices = new .() ~ delete _;
@ -47,15 +48,33 @@ namespace Strawberry
GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, indexBufferID); 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.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); for (let b in batches)
{
if (b.Mode == .Shape)
GL.glBindTexture(GL.GL_TEXTURE_2D, 0);
else
GL.glBindTexture(GL.GL_TEXTURE_2D, b.Texture.Handle);
GL.glDrawElements(GL.GL_TRIANGLES, b.IndicesCount, GL.GL_UNSIGNED_INT, (void*)(b.IndicesStart * sizeof(uint32)));
}
GL.glBindVertexArray(0); GL.glBindVertexArray(0);
vertices.Clear(); vertices.Clear();
indices.Clear(); indices.Clear();
batches.Clear();
} }
protected void PushQuad(Vertex a, Vertex b, Vertex c, Vertex d) private ref Batch GetBatch(BatchModes mode, Texture texture)
{ {
if (batches.Count == 0 || !batches.Back.Matches(mode, texture))
batches.Add(Batch(mode, texture, indices.Count));
return ref batches.Back;
}
protected void PushQuad(BatchModes mode, Texture texture, Vertex a, Vertex b, Vertex c, Vertex d)
{
GetBatch(mode, texture).IndicesCount += 6;
uint32 count = (uint32)vertices.Count; uint32 count = (uint32)vertices.Count;
vertices.Add(a); vertices.Add(a);
@ -71,8 +90,10 @@ namespace Strawberry
indices.Add(count + 3); indices.Add(count + 3);
} }
protected void PushTri(Vertex a, Vertex b, Vertex c) protected void PushTri(BatchModes mode, Texture texture, Vertex a, Vertex b, Vertex c)
{ {
GetBatch(mode, texture).IndicesCount += 3;
uint32 count = (uint32)vertices.Count; uint32 count = (uint32)vertices.Count;
vertices.Add(a); vertices.Add(a);
@ -86,12 +107,25 @@ namespace Strawberry
public void Rect(float x, float y, float w, float h, Color color) public void Rect(float x, float y, float w, float h, Color color)
{ {
PushQuad(.Shape(.(x, y), color), .Shape(.(x + w, y), color), .Shape(.(x + w, y + h), color), .Shape(.(x, y + h), color)); PushQuad(.Shape, null,
.Shape(.(x, y), color),
.Shape(.(x + w, y), color),
.Shape(.(x + w, y + h), color),
.Shape(.(x, y + h), color));
} }
public void Rect(Rect rect, Color color) public void Rect(Rect rect, Color color)
{ {
Rect(rect.X, rect.Y, rect.Width, rect.Height, color); Rect(rect.X, rect.Y, rect.Width, rect.Height, color);
} }
public void Tex(Texture texture, float x, float y)
{
PushQuad(.TextureTint, texture,
.Tex(.(x, y), .(0, 1), Color.White),
.Tex(.(x + texture.Width, y), .(1, 1), Color.White),
.Tex(.(x + texture.Width, y + texture.Height), .(1, 0), Color.White),
.Tex(.(x, y + texture.Height), .(0, 0), Color.White));
}
} }
} }

View File

@ -166,7 +166,10 @@ namespace Strawberry.SDL2
public override Texture LoadTexture(String path) public override Texture LoadTexture(String path)
{ {
var surface = SDLImage.Load(path); let surface = SDLImage.Load(path);
Debug.Assert(surface != null, "Could not load from path.");
Debug.Assert(surface.format.bytesPerPixel == 4, "Surface format incorrect.");
var tex = new Texture(surface.w, surface.h, (uint8*)surface.pixels); var tex = new Texture(surface.w, surface.h, (uint8*)surface.pixels);
SDL.FreeSurface(surface); SDL.FreeSurface(surface);

View File

@ -18,5 +18,15 @@ namespace Strawberry
v.Mode = (0, 0, 255); v.Mode = (0, 0, 255);
return v; return v;
} }
static public Vertex Tex(Vector pos, Vector texCoord, Color color)
{
Vertex v = Vertex();
v.Position = pos;
v.TexCoord = texCoord;
v.Color = color;
v.Mode = (255, 0, 0);
return v;
}
} }
} }

View File

@ -6,60 +6,53 @@ namespace Strawberry
{ {
static public class Assets static public class Assets
{ {
static public Dictionary<String, Sprite> Sprites { get; private set; } static public Dictionary<String, Texture> Textures { get; private set; }
static public Dictionary<String, Font> Fonts { get; private set; }
static public String ContentRoot { get; private set; } #if DEBUG
static public readonly String Root = "../../../src/assets/";
#else
static public readonly String Root = "assets/";
#endif
static public void LoadAll() static public void LoadAll()
{ {
#if DEBUG Textures = new Dictionary<String, Texture>();
ContentRoot = "../../../src/Content/"; Load<Texture>("textures", "*.png", Textures, (path) => Game.PlatformLayer.LoadTexture(path));
#else
ContentRoot = "Content";
#endif
Sprites = new Dictionary<String, Sprite>();
Load<Sprite>("Sprites", "*.ase*", Sprites);
Fonts = new Dictionary<String, Font>();
Load<Font>("Fonts", "*.ttf", Fonts);
} }
static public void DisposeAll() static public void DisposeAll()
{ {
DeleteDictionaryAndKeysAndItems!(Sprites); DeleteDictionaryAndKeysAndItems!(Textures);
DeleteDictionaryAndKeysAndItems!(Fonts);
Sprite.[Friend]Dispose(); Sprite.[Friend]Dispose();
} }
static private void Load<T>(String directory, String wildcard, Dictionary<String, T> putInto) where T : Asset static private void Load<T>(String directory, String wildcard, Dictionary<String, T> putInto, function T(String) loader)
{ {
let root = scope String(ContentRoot); let root = scope String(Root);
root.Append(Path.DirectorySeparatorChar); root.Append(Path.DirectorySeparatorChar);
root.Append(directory); root.Append(directory);
if (Directory.Exists(root)) if (Directory.Exists(root))
LoadDir<T>(root, root, wildcard, putInto); LoadDir<T>(root, root, wildcard, putInto, loader);
else else
Calc.Log("Create a Content/{0} folder to load {0}", directory); Calc.Log("Create a Content/{0} folder to load {0}", directory);
} }
static private void LoadDir<T>(String rootDir, String directory, String wildcard, Dictionary<String, T> putInto) where T : Asset static private void LoadDir<T>(String rootDir, String directory, String wildcard, Dictionary<String, T> putInto, function T(String) loader)
{ {
//Recursive folder search //Recursive folder search
for (let dir in Directory.EnumerateDirectories(directory)) for (let dir in Directory.EnumerateDirectories(directory))
{ {
let path = scope String(); let path = scope String();
dir.GetFilePath(path); dir.GetFilePath(path);
LoadDir<T>(rootDir, path, wildcard, putInto); LoadDir<T>(rootDir, path, wildcard, putInto, loader);
} }
//Load files //Load files
for (let file in Directory.EnumerateFiles(directory, wildcard)) for (let file in Directory.EnumerateFiles(directory, wildcard))
{ {
let path = new String(); let path = scope String();
file.GetFilePath(path); file.GetFilePath(path);
let asset = new [Friend]T(path); let asset = loader(path);
let key = new String(path); let key = new String(path);
key.Remove(0, rootDir.Length + 1); key.Remove(0, rootDir.Length + 1);