Rendering stuff

This commit is contained in:
Matt Thorson 2020-08-09 01:29:46 -07:00
parent 5cef6c2b26
commit 637dcb21a3
5 changed files with 197 additions and 24 deletions

View File

@ -0,0 +1,16 @@
using System.Collections.Generic;
namespace Strawberry
{
public class Batcher
{
List<Batch> batchStack = new System.Collections.List<Batch>() ~ DeleteContainerAndItems!(_);
Batch top => batchStack.Count > 0 ? batchStack[batchStack.Count - 1] : null;
private class Batch
{
}
}
}

View File

@ -2,26 +2,6 @@ using System;
namespace Strawberry
{
class GLTexture : Texture
{
private uint32 handle;
public this(int width, int height, void* pixels)
{
Width = width;
Height = height;
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);
}
}
class GL
{
public function void* GetProcAddressFunc(StringView procname);

View File

@ -4,12 +4,12 @@ namespace Strawberry
public abstract class PlatformLayer
{
public abstract void Init();
public abstract bool Closed(); // If the game window has been closed
public abstract bool Closed(); // Returns whether the game window has been closed
//Rendering
public abstract void RenderBegin();
public abstract void RenderEnd();
//Update
public abstract uint32 Ticks { get; } // Milliseconds since game launched
@ -20,11 +20,53 @@ namespace Strawberry
public abstract bool PollKey(Keys key);
public abstract bool PollGamepadButton(int gamepadID, Buttons button);
public abstract float PollGamepadAxis(int gamepadID, Axes axis);
//Graphics
public abstract Texture LoadTexture(String path);
}
public abstract class Texture
{
public int Width { get; protected set; }
public int Height { get; protected set; }
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);
}
}
}

View File

@ -10,8 +10,10 @@ namespace Strawberry
private SDL.Surface* screen;
private SDL.Rect screenRect;
private SDL.Renderer* renderer;
private SDL2Shader shader;
private SDL.SDL_GLContext glContext;
private uint glProgram;
private uint glVertexShader;
private SDL.SDL_GameController*[] gamepads;
private bool* keyboard;
@ -51,7 +53,55 @@ namespace Strawberry
SDL.GL_SetSwapInterval(1);
GL.Init(=> SdlGetProcAddress);
shader = new SDL2Shader(String[2] (
// vertex shader
"""
#version 330
uniform mat4 u_matrix;
layout(location=0) in vec2 a_position;
layout(location=1) in vec2 a_tex;
layout(location=2) in vec4 a_color;
layout(location=3) in vec3 a_type;
out vec2 v_tex;
out vec4 v_col;
out vec3 v_type;
void main(void)
{
gl_Position = u_matrix * vec4(a_position.xy, 0, 1);
v_tex = a_tex;
v_col = a_color;
v_type = a_type;
}
""",
// fragment shader
"""
#version 330
uniform sampler2D u_texture;
in vec2 v_tex;
in vec4 v_col;
in vec3 v_type;
out vec4 o_color;
void main(void)
{
vec4 color = texture(u_texture, v_tex);
o_color =
v_type.x * color * v_col +
v_type.y * color.a * v_col +
v_type.z * v_col;
}
"""));
glProgram = GL.glCreateProgram();
GL.glAttachShader(glProgram, shader.vertexHandle);
GL.glAttachShader(glProgram, shader.fragmentHandle);
GL.glLinkProgram(glProgram);
int32 logLen = 0;
char8[1024] log;
GL.glGetProgramInfoLog(glProgram, 1024, &logLen, &log);
if (logLen > 0)
Calc.Log(&log, logLen);
}
//Audio
@ -76,6 +126,7 @@ namespace Strawberry
public ~this()
{
delete gamepads;
delete shader;
GL.glDeleteProgram(glProgram);
SDL.GL_DeleteContext(glContext);
@ -103,6 +154,15 @@ namespace Strawberry
SDL.GL_SwapWindow(window);
}
public override Texture LoadTexture(String path)
{
var surface = SDLImage.Load(path);
var tex = new SDL2Texture(surface.w, surface.h, (uint8*)surface.pixels);
SDL.FreeSurface(surface);
return tex;
}
public override void UpdateInput()
{
SDL.PumpEvents();
@ -141,4 +201,72 @@ namespace Strawberry
return val / 32768f;
}
}
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);
}
}
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);
}
}
}

View File

@ -129,5 +129,12 @@ namespace Strawberry
let string = StringArgs(scope String(str), params args);
Debug.WriteLine(string);
}
[Inline]
static public void Log(char8* str, int len)
{
String s = scope String(str, len);
Debug.WriteLine(s);
}
}
}