feat: add shader pipeline and chunk GLSL shaders
This commit is contained in:
13
Assets/shaders/chunk.frag
Normal file
13
Assets/shaders/chunk.frag
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#version 330 core
|
||||||
|
in vec2 vUv;
|
||||||
|
in float vShade;
|
||||||
|
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
uniform sampler2D atlas;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 texel = texture(atlas, vUv);
|
||||||
|
FragColor = vec4(texel.rgb * vShade, 1.0);
|
||||||
|
}
|
||||||
19
Assets/shaders/chunk.vert
Normal file
19
Assets/shaders/chunk.vert
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#version 330 core
|
||||||
|
layout(location = 0) in vec3 aPos;
|
||||||
|
layout(location = 1) in vec2 aUv;
|
||||||
|
layout(location = 2) in float aShade;
|
||||||
|
|
||||||
|
out vec2 vUv;
|
||||||
|
out float vShade;
|
||||||
|
|
||||||
|
uniform mat4 model;
|
||||||
|
uniform mat4 view;
|
||||||
|
uniform mat4 projection;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vUv = aUv;
|
||||||
|
vShade = aShade;
|
||||||
|
// Vector-on-left convention; matrices are uploaded with transpose=true.
|
||||||
|
gl_Position = vec4(aPos, 1.0) * model * view * projection;
|
||||||
|
}
|
||||||
64
Rendering/Shader.cs
Normal file
64
Rendering/Shader.cs
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
using OpenTK.Graphics.OpenGL4;
|
||||||
|
using OpenTK.Mathematics;
|
||||||
|
|
||||||
|
namespace VoxelEngine.Rendering;
|
||||||
|
|
||||||
|
public sealed class Shader : IDisposable
|
||||||
|
{
|
||||||
|
private readonly int _handle;
|
||||||
|
private readonly Dictionary<string, int> _uniforms = new();
|
||||||
|
|
||||||
|
public Shader(string vertexPath, string fragmentPath)
|
||||||
|
{
|
||||||
|
int vertex = CompileFromFile(ShaderType.VertexShader, vertexPath);
|
||||||
|
int fragment = CompileFromFile(ShaderType.FragmentShader, fragmentPath);
|
||||||
|
|
||||||
|
_handle = GL.CreateProgram();
|
||||||
|
GL.AttachShader(_handle, vertex);
|
||||||
|
GL.AttachShader(_handle, fragment);
|
||||||
|
GL.LinkProgram(_handle);
|
||||||
|
|
||||||
|
GL.GetProgram(_handle, GetProgramParameterName.LinkStatus, out int linked);
|
||||||
|
if (linked == 0)
|
||||||
|
throw new InvalidOperationException($"Program link failed: {GL.GetProgramInfoLog(_handle)}");
|
||||||
|
|
||||||
|
GL.DetachShader(_handle, vertex);
|
||||||
|
GL.DetachShader(_handle, fragment);
|
||||||
|
GL.DeleteShader(vertex);
|
||||||
|
GL.DeleteShader(fragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Use() => GL.UseProgram(_handle);
|
||||||
|
|
||||||
|
public void SetMatrix4(string name, Matrix4 value) =>
|
||||||
|
GL.UniformMatrix4(Location(name), true, ref value);
|
||||||
|
|
||||||
|
public void SetInt(string name, int value) =>
|
||||||
|
GL.Uniform1(Location(name), value);
|
||||||
|
|
||||||
|
private int Location(string name)
|
||||||
|
{
|
||||||
|
if (!_uniforms.TryGetValue(name, out int location))
|
||||||
|
{
|
||||||
|
location = GL.GetUniformLocation(_handle, name);
|
||||||
|
_uniforms[name] = location;
|
||||||
|
}
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int CompileFromFile(ShaderType type, string path)
|
||||||
|
{
|
||||||
|
string source = File.ReadAllText(path);
|
||||||
|
int shader = GL.CreateShader(type);
|
||||||
|
GL.ShaderSource(shader, source);
|
||||||
|
GL.CompileShader(shader);
|
||||||
|
|
||||||
|
GL.GetShader(shader, ShaderParameter.CompileStatus, out int compiled);
|
||||||
|
if (compiled == 0)
|
||||||
|
throw new InvalidOperationException($"{type} compile failed ({path}): {GL.GetShaderInfoLog(shader)}");
|
||||||
|
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose() => GL.DeleteProgram(_handle);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user