mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/PCK-Studio.git
synced 2026-05-23 19:24:48 +00:00
Separated ShaderObjects to its own class
This commit is contained in:
@@ -159,8 +159,9 @@
|
||||
<Compile Include="Rendering\RenderBuffer.cs" />
|
||||
<Compile Include="Rendering\Renderer.cs" />
|
||||
<Compile Include="Rendering\RenderGroup.cs" />
|
||||
<Compile Include="Rendering\Shader.cs" />
|
||||
<Compile Include="Rendering\ShaderSource.cs" />
|
||||
<Compile Include="Rendering\Shader\ShaderProgram.cs" />
|
||||
<Compile Include="Rendering\Shader\ShaderObject.cs" />
|
||||
<Compile Include="Rendering\Shader\ShaderSource.cs" />
|
||||
<Compile Include="Rendering\SkinRenderer.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
|
||||
@@ -16,12 +16,13 @@
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
**/
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
using PckStudio.Rendering.Shader;
|
||||
|
||||
namespace PckStudio.Rendering
|
||||
{
|
||||
internal static class Renderer
|
||||
{
|
||||
public static void Draw(Shader shader, RenderBuffer renderBuffer)
|
||||
public static void Draw(ShaderProgram shader, RenderBuffer renderBuffer)
|
||||
{
|
||||
shader.Bind();
|
||||
renderBuffer.VertexArray.Bind();
|
||||
|
||||
62
PCK-Studio/Rendering/Shader/ShaderObject.cs
Normal file
62
PCK-Studio/Rendering/Shader/ShaderObject.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
|
||||
namespace PckStudio.Rendering.Shader
|
||||
{
|
||||
internal class ShaderObject
|
||||
{
|
||||
private int _shaderId;
|
||||
private ShaderSource _source;
|
||||
private int _compileStatus;
|
||||
|
||||
internal bool CompileStatusOK => _compileStatus != 0;
|
||||
|
||||
private ShaderObject(ShaderSource source)
|
||||
{
|
||||
_shaderId = GL.CreateShader(source.Type);
|
||||
_source = source;
|
||||
_compileStatus = 0;
|
||||
}
|
||||
|
||||
internal static ShaderObject CreateNew(ShaderSource shaderSource)
|
||||
{
|
||||
var shaderObject = new ShaderObject(shaderSource);
|
||||
shaderObject.Compile();
|
||||
if (!shaderObject.CompileStatusOK)
|
||||
{
|
||||
shaderObject.Delete();
|
||||
return null;
|
||||
}
|
||||
return shaderObject;
|
||||
}
|
||||
|
||||
internal void Delete()
|
||||
{
|
||||
GL.DeleteShader(_shaderId);
|
||||
}
|
||||
|
||||
private void Compile()
|
||||
{
|
||||
GL.ShaderSource(_shaderId, _source.Source);
|
||||
GL.CompileShader(_shaderId);
|
||||
|
||||
GL.GetShader(_shaderId, ShaderParameter.CompileStatus, out _compileStatus);
|
||||
|
||||
if (!CompileStatusOK)
|
||||
{
|
||||
string infoLog = GL.GetShaderInfoLog(_shaderId);
|
||||
Debug.Fail(infoLog);
|
||||
}
|
||||
}
|
||||
|
||||
internal void AttachToProgram(int programId)
|
||||
{
|
||||
GL.AttachShader(programId, _shaderId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,14 +8,14 @@ using System.Threading.Tasks;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
|
||||
namespace PckStudio.Rendering
|
||||
namespace PckStudio.Rendering.Shader
|
||||
{
|
||||
internal class Shader : IDisposable
|
||||
internal class ShaderProgram : IDisposable
|
||||
{
|
||||
private int _programId;
|
||||
private Dictionary<string, int> locationCache = new Dictionary<string, int>();
|
||||
|
||||
private Shader(int programId)
|
||||
private ShaderProgram(int programId)
|
||||
{
|
||||
_programId = programId;
|
||||
}
|
||||
@@ -25,7 +25,6 @@ namespace PckStudio.Rendering
|
||||
GL.UseProgram(_programId);
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
public void Unbind()
|
||||
{
|
||||
GL.UseProgram(0);
|
||||
@@ -43,6 +42,12 @@ namespace PckStudio.Rendering
|
||||
GL.Uniform1(location, value);
|
||||
}
|
||||
|
||||
public void SetUniform1(string name, float value)
|
||||
{
|
||||
int location = GetUniformLocation(name);
|
||||
GL.Uniform1(location, value);
|
||||
}
|
||||
|
||||
public void SetUniform2(string name, Vector2 value)
|
||||
{
|
||||
int location = GetUniformLocation(name);
|
||||
@@ -94,21 +99,13 @@ namespace PckStudio.Rendering
|
||||
return shaderId;
|
||||
}
|
||||
|
||||
public static Shader Create(string vertexSource, string fragmentSource)
|
||||
{
|
||||
return Create(
|
||||
new ShaderSource(ShaderType.VertexShader, vertexSource),
|
||||
new ShaderSource(ShaderType.FragmentShader, fragmentSource)
|
||||
);
|
||||
}
|
||||
|
||||
private bool Link()
|
||||
{
|
||||
GL.LinkProgram(_programId);
|
||||
GL.GetProgram(_programId, GetProgramParameterName.LinkStatus, out int status);
|
||||
bool success = status != 0;
|
||||
if (!success)
|
||||
Debug.WriteLine(GL.GetProgramInfoLog(_programId), category: nameof(Shader));
|
||||
Debug.WriteLine(GL.GetProgramInfoLog(_programId), category: nameof(ShaderProgram));
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -119,33 +116,41 @@ namespace PckStudio.Rendering
|
||||
GL.GetProgram(_programId, GetProgramParameterName.ValidateStatus, out int status);
|
||||
bool success = status != 0;
|
||||
if (!success)
|
||||
Debug.WriteLine(GL.GetProgramInfoLog(_programId), category: nameof(Shader));
|
||||
Debug.WriteLine(GL.GetProgramInfoLog(_programId), category: nameof(ShaderProgram));
|
||||
return success;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static Shader Create(params ShaderSource[] shaderSources)
|
||||
public static ShaderProgram Create(string vertexSource, string fragmentSource)
|
||||
{
|
||||
return Create(
|
||||
new ShaderSource(ShaderType.VertexShader, vertexSource),
|
||||
new ShaderSource(ShaderType.FragmentShader, fragmentSource)
|
||||
);
|
||||
}
|
||||
|
||||
public static ShaderProgram Create(params ShaderSource[] shaderSources)
|
||||
{
|
||||
int programId = GL.CreateProgram();
|
||||
|
||||
var shaderIds = new List<int>(shaderSources.Length);
|
||||
var shaderObjects = new List<ShaderObject>(shaderSources.Length);
|
||||
|
||||
foreach (var shaderSource in shaderSources)
|
||||
{
|
||||
int shaderId = CompileShader(shaderSource.Type, shaderSource.Source);
|
||||
GL.AttachShader(programId, shaderId);
|
||||
shaderIds.Add(shaderId);
|
||||
ShaderObject shaderObject = ShaderObject.CreateNew(shaderSource);
|
||||
shaderObject.AttachToProgram(programId);
|
||||
shaderObjects.Add(shaderObject);
|
||||
}
|
||||
|
||||
var shader = new Shader(programId);
|
||||
var shader = new ShaderProgram(programId);
|
||||
bool success = shader.Link();
|
||||
Debug.Assert(success, "Shader Program linking failed.");
|
||||
|
||||
foreach (var shaderId in shaderIds)
|
||||
foreach (var shaderObject in shaderObjects)
|
||||
{
|
||||
GL.DeleteShader(shaderId);
|
||||
shaderObject.Delete();
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
@@ -5,9 +5,9 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
|
||||
namespace PckStudio.Rendering
|
||||
namespace PckStudio.Rendering.Shader
|
||||
{
|
||||
internal readonly struct ShaderSource
|
||||
public readonly struct ShaderSource
|
||||
{
|
||||
public readonly ShaderType Type;
|
||||
public readonly string Source;
|
||||
@@ -33,6 +33,7 @@ using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using PckStudio.Rendering.Camera;
|
||||
using PckStudio.Rendering.Texture;
|
||||
using PckStudio.Rendering.Shader;
|
||||
|
||||
namespace PckStudio.Rendering
|
||||
{
|
||||
@@ -158,11 +159,12 @@ namespace PckStudio.Rendering
|
||||
private Point PreviousMouseLocation;
|
||||
private Point CurrentMouseLocation;
|
||||
|
||||
private Shader _skinShader;
|
||||
private ShaderProgram _skinShader;
|
||||
private SkinANIM _anim;
|
||||
private Image _texture;
|
||||
|
||||
private Shader _skyboxShader;
|
||||
private ShaderProgram _skyboxShader;
|
||||
private RenderBuffer _skyboxRenderBuffer;
|
||||
private CubeTexture _skyboxTexture;
|
||||
private float skyboxRotation = 0f;
|
||||
@@ -198,12 +200,27 @@ namespace PckStudio.Rendering
|
||||
private Matrix4 RightLegMatrix { get; set; } = Matrix4.Identity;
|
||||
private Matrix4 LeftLegMatrix { get; set; } = Matrix4.Identity;
|
||||
|
||||
private static Vector3[] cubeVertices = new Vector3[]
|
||||
{
|
||||
// front
|
||||
new Vector3(-1.0f, -1.0f, 1.0f),
|
||||
new Vector3( 1.0f, -1.0f, 1.0f),
|
||||
new Vector3( 1.0f, 1.0f, 1.0f),
|
||||
new Vector3(-1.0f, 1.0f, 1.0f),
|
||||
// back
|
||||
new Vector3(-1.0f, -1.0f, -1.0f),
|
||||
new Vector3( 1.0f, -1.0f, -1.0f),
|
||||
new Vector3( 1.0f, 1.0f, -1.0f),
|
||||
new Vector3(-1.0f, 1.0f, -1.0f)
|
||||
};
|
||||
public SkinRenderer() : base()
|
||||
{
|
||||
InitializeComponent();
|
||||
InitializeCamera();
|
||||
InitializeSkinData();
|
||||
ANIM ??= SkinANIM.Empty;
|
||||
InitializeShaders();
|
||||
InitializeComponent();
|
||||
|
||||
ANIM ??= new SkinANIM(SkinAnimMask.RESOLUTION_64x64);
|
||||
OnTimerTick = AnimationTick;
|
||||
ModelData = new ObservableCollection<SkinBOX>();
|
||||
ModelData.CollectionChanged += ModelData_CollectionChanged;
|
||||
@@ -321,9 +338,8 @@ namespace PckStudio.Rendering
|
||||
leftLegOverlay.Submit();
|
||||
}
|
||||
|
||||
protected override void OnLoad(EventArgs e)
|
||||
private void InitializeShaders()
|
||||
{
|
||||
base.OnLoad(e);
|
||||
if (DesignMode)
|
||||
return;
|
||||
|
||||
@@ -331,22 +347,34 @@ namespace PckStudio.Rendering
|
||||
|
||||
Trace.TraceInformation(GL.GetString(StringName.Version));
|
||||
|
||||
// Initialize skybox shader
|
||||
// Skin shader
|
||||
{
|
||||
Vector3[] cubeVertices = new Vector3[]
|
||||
{
|
||||
// front
|
||||
new Vector3(-1.0f, -1.0f, 1.0f),
|
||||
new Vector3( 1.0f, -1.0f, 1.0f),
|
||||
new Vector3( 1.0f, 1.0f, 1.0f),
|
||||
new Vector3(-1.0f, 1.0f, 1.0f),
|
||||
// back
|
||||
new Vector3(-1.0f, -1.0f, -1.0f),
|
||||
new Vector3( 1.0f, -1.0f, -1.0f),
|
||||
new Vector3( 1.0f, 1.0f, -1.0f),
|
||||
new Vector3(-1.0f, 1.0f, -1.0f)
|
||||
};
|
||||
_skinShader = ShaderProgram.Create(
|
||||
new ShaderSource(ShaderType.VertexShader, Resources.skinVertexShader),
|
||||
new ShaderSource(ShaderType.FragmentShader, Resources.skinFragmentShader),
|
||||
new ShaderSource(ShaderType.GeometryShader, Resources.skinGeometryShader)
|
||||
);
|
||||
_skinShader.Bind();
|
||||
_skinShader.SetUniform1("u_Texture", 0);
|
||||
_skinShader.Validate();
|
||||
GLErrorCheck();
|
||||
|
||||
skinTexture = new Texture2D(0);
|
||||
skinTexture.PixelFormat = OpenTK.Graphics.OpenGL.PixelFormat.Bgra;
|
||||
skinTexture.InternalPixelFormat = PixelInternalFormat.Rgba8;
|
||||
skinTexture.MinFilter = TextureMinFilter.Nearest;
|
||||
skinTexture.MagFilter = TextureMagFilter.Nearest;
|
||||
skinTexture.WrapS = TextureWrapMode.Repeat;
|
||||
skinTexture.WrapT = TextureWrapMode.Repeat;
|
||||
|
||||
Texture ??= Resources.classic_template;
|
||||
|
||||
_skinShader.Unbind();
|
||||
GLErrorCheck();
|
||||
}
|
||||
|
||||
// Skybox shader
|
||||
{
|
||||
var skyboxVAO = new VertexArray();
|
||||
var skyboxVBO = new VertexBuffer<Vector3>(cubeVertices, cubeVertices.Length * Vector3.SizeInBytes);
|
||||
var vboLayout = new VertexBufferLayout();
|
||||
@@ -377,6 +405,12 @@ namespace PckStudio.Rendering
|
||||
skyboxVAO.Unbind();
|
||||
skybocIBO.Unbind();
|
||||
|
||||
_skyboxShader = ShaderProgram.Create(Resources.skyboxVertexShader, Resources.skyboxFragmentShader);
|
||||
_skyboxShader.Bind();
|
||||
_skyboxShader.SetUniform1("skybox", 1);
|
||||
_skyboxShader.SetUniform1("brightness", 1f);
|
||||
_skyboxShader.Validate();
|
||||
|
||||
string customSkyboxFilepath = Path.Combine(Program.AppData, "cubemap.png");
|
||||
Image skyboxImage = File.Exists(customSkyboxFilepath)
|
||||
? Image.FromFile(customSkyboxFilepath)
|
||||
@@ -553,21 +587,23 @@ namespace PckStudio.Rendering
|
||||
|
||||
MakeCurrent();
|
||||
|
||||
Camera.Update(AspectRatio);
|
||||
GL.Viewport(Size);
|
||||
|
||||
GL.ClearColor(BackColor);
|
||||
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
||||
GL.Enable(EnableCap.DepthTest); // Enable correct Z Drawings
|
||||
|
||||
// Render (custom) skin
|
||||
{
|
||||
var viewProjection = Camera.GetViewProjection();
|
||||
_skinShader.Bind();
|
||||
_skinShader.SetUniformMat4("u_ViewProjection", ref viewProjection);
|
||||
_skinShader.SetUniform2("u_TexSize", new Vector2(TextureSize.Width, TextureSize.Height));
|
||||
|
||||
GL.Viewport(Size);
|
||||
|
||||
GL.ClearColor(BackColor);
|
||||
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
||||
skinTexture.Bind();
|
||||
|
||||
GL.Enable(EnableCap.Texture2D); // Enable textures
|
||||
|
||||
GL.Enable(EnableCap.DepthTest); // Enable correct Z Drawings
|
||||
GL.DepthFunc(DepthFunction.Lequal); // Enable correct Z Drawings
|
||||
GL.DepthMask(true);
|
||||
|
||||
@@ -620,7 +656,8 @@ namespace PckStudio.Rendering
|
||||
RenderBodyPart(new Vector3( 4f, 2f, 0f), new Vector3(slimModel ? -4f : -5f, -2f, 0f), RightArmMatrix * armRightMatrix, modelMatrix, "ARM0", "SLEEVE0");
|
||||
RenderBodyPart(new Vector3(-4f, 2f, 0f), new Vector3( 5f, -2f, 0f), LeftArmMatrix * armLeftMatrix , modelMatrix, "ARM1", "SLEEVE1");
|
||||
RenderBodyPart(new Vector3(0f, 12f, 0f), new Vector3(-2f, -12f, 0f), RightLegMatrix * legRightMatrix, modelMatrix, "LEG0", "PANTS0");
|
||||
RenderBodyPart(new Vector3(0f, 12f, 0f), new Vector3( 2f, -12f, 0f), LeftLegMatrix * legLeftMatrix , modelMatrix, "LEG1", "PANTS1");
|
||||
RenderBodyPart(new Vector3(0f, 12f, 0f), new Vector3(2f, -12f, 0f), LeftLegMatrix * legLeftMatrix, modelMatrix, "LEG1", "PANTS1");
|
||||
}
|
||||
|
||||
// Render Skybox
|
||||
{
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
layout(location = 0) out vec4 color;
|
||||
|
||||
uniform samplerCube skybox;
|
||||
uniform float brightness;
|
||||
|
||||
in vec3 texCoords;
|
||||
|
||||
void main()
|
||||
{
|
||||
color = texture(skybox, texCoords);
|
||||
color = texture(skybox, texCoords) * vec4(vec3(clamp(brightness, 0.0, 1.0)), 1.0);
|
||||
}
|
||||
Reference in New Issue
Block a user