2019-08-02 23:27:44 +02:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Toolbox.Library.Rendering;
|
|
|
|
|
using GL_EditorFramework.GL_Core;
|
|
|
|
|
using GL_EditorFramework.Interfaces;
|
|
|
|
|
using OpenTK;
|
|
|
|
|
using OpenTK.Graphics.OpenGL;
|
|
|
|
|
using Toolbox.Library;
|
|
|
|
|
|
|
|
|
|
namespace FirstPlugin
|
|
|
|
|
{
|
2019-08-03 04:06:45 +02:00
|
|
|
|
//Rendering methods based on noclip
|
|
|
|
|
//https://github.com/magcius/noclip.website/blob/master/src/oot3d/render.ts
|
2019-08-02 23:27:44 +02:00
|
|
|
|
public class CMB_Renderer : GenericModelRenderer
|
|
|
|
|
{
|
|
|
|
|
public override float PreviewScale { get; set; } = 0.01f;
|
|
|
|
|
|
|
|
|
|
public List<CTXB.TextureWrapper> TextureList = new List<CTXB.TextureWrapper>();
|
|
|
|
|
|
2019-08-03 04:06:45 +02:00
|
|
|
|
private string FragmentShader()
|
|
|
|
|
{
|
|
|
|
|
string frag = "";
|
|
|
|
|
return frag;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private string GenerateAlphaTestCompare(AlphaFunction compare, int reference)
|
|
|
|
|
{
|
|
|
|
|
float refSingle = (float)reference;
|
|
|
|
|
switch (compare)
|
|
|
|
|
{
|
|
|
|
|
case AlphaFunction.Never: return "false";
|
|
|
|
|
case AlphaFunction.Less: return $"t_CmbOut.a < {refSingle}";
|
|
|
|
|
case AlphaFunction.Lequal: return $"t_CmbOut.a <= {refSingle}";
|
|
|
|
|
case AlphaFunction.Equal: return $"t_CmbOut.a == {refSingle}";
|
|
|
|
|
case AlphaFunction.Notequal: return $"t_CmbOut.a != {refSingle}";
|
|
|
|
|
case AlphaFunction.Greater: return $"t_CmbOut.a > ${refSingle}";
|
|
|
|
|
case AlphaFunction.Gequal: return $"t_CmbOut.a >= ${refSingle}";
|
|
|
|
|
case AlphaFunction.Always: return "true";
|
|
|
|
|
default: throw new Exception("Unsupported alpha function");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private string GenerateTextureEnvironment()
|
|
|
|
|
{
|
|
|
|
|
string vale = $"";
|
|
|
|
|
return vale;
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-02 23:27:44 +02:00
|
|
|
|
public override void OnRender(GLControl control)
|
|
|
|
|
{
|
2019-08-03 19:33:02 +02:00
|
|
|
|
GL.Enable(EnableCap.AlphaTest);
|
|
|
|
|
GL.AlphaFunc(AlphaFunction.Gequal, 0.1f);
|
|
|
|
|
GL.Enable(EnableCap.Blend);
|
|
|
|
|
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void DrawModels(ShaderProgram shader, GL_ControlModern control)
|
|
|
|
|
{
|
|
|
|
|
shader.EnableVertexAttributes();
|
|
|
|
|
|
|
|
|
|
List<STGenericObject> opaque = new List<STGenericObject>();
|
|
|
|
|
List<STGenericObject> transparent = new List<STGenericObject>();
|
|
|
|
|
|
|
|
|
|
for (int m = 0; m < Meshes.Count; m++)
|
|
|
|
|
{
|
2020-04-14 22:40:24 +02:00
|
|
|
|
if (((CMB.CMBMaterialWrapper)Meshes[m].GetMaterial()).CMBMaterial.AlphaTest.Enabled)
|
2019-08-03 19:33:02 +02:00
|
|
|
|
transparent.Add(Meshes[m]);
|
|
|
|
|
else
|
|
|
|
|
opaque.Add(Meshes[m]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int m = 0; m < transparent.Count; m++)
|
|
|
|
|
{
|
|
|
|
|
DrawModel(control, Skeleton, transparent[m].GetMaterial(), transparent[m], shader);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int m = 0; m < opaque.Count; m++)
|
|
|
|
|
{
|
|
|
|
|
DrawModel(control, Skeleton, opaque[m].GetMaterial(), opaque[m], shader);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
shader.DisableVertexAttributes();
|
2019-08-02 23:27:44 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-08-03 03:24:13 +02:00
|
|
|
|
public override void SetRenderData(STGenericMaterial mat, ShaderProgram shader, STGenericObject m)
|
|
|
|
|
{
|
2020-01-15 01:19:02 +01:00
|
|
|
|
var cmbMaterial = ((CMB.CMBMaterialWrapper)mat).CMBMaterial;
|
2019-08-04 00:00:51 +02:00
|
|
|
|
var cmbMesh = ((CMB.CmbMeshWrapper)m);
|
2019-08-03 03:24:13 +02:00
|
|
|
|
|
2020-04-14 22:40:24 +02:00
|
|
|
|
bool HasNoNormals = cmbMesh.Mesh.HasNormal == false;
|
2019-08-04 00:00:51 +02:00
|
|
|
|
|
|
|
|
|
shader.SetBoolToInt("HasNoNormals", HasNoNormals);
|
2020-04-14 22:40:24 +02:00
|
|
|
|
shader.SetBoolToInt("isTransparent", cmbMaterial.BlendEnabled);
|
2019-08-03 04:06:45 +02:00
|
|
|
|
|
2019-08-03 22:07:52 +02:00
|
|
|
|
SetGLCullMode(cmbMaterial.CullMode);
|
|
|
|
|
|
2020-04-14 22:40:24 +02:00
|
|
|
|
if (cmbMaterial.BlendEnabled)
|
|
|
|
|
{
|
|
|
|
|
GL.Enable(EnableCap.Blend);
|
|
|
|
|
GL.BlendColor(cmbMaterial.BlendColor.R / 255, cmbMaterial.BlendColor.G / 255, cmbMaterial.BlendColor.B / 255, cmbMaterial.BlendColor.A / 255);
|
|
|
|
|
GL.BlendFunc(ConvertBlendFunc(cmbMaterial.BlendFunction.AlphaSrcFunc), ConvertBlendFunc(cmbMaterial.BlendFunction.AlphaDstFunc));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
GL.Disable(EnableCap.Blend);
|
|
|
|
|
|
|
|
|
|
if (cmbMaterial.AlphaTest.Enabled)
|
|
|
|
|
{
|
2019-08-03 04:06:45 +02:00
|
|
|
|
GL.Enable(EnableCap.AlphaTest);
|
2020-04-14 22:40:24 +02:00
|
|
|
|
GL.AlphaFunc(ConvertTestFunction(cmbMaterial.AlphaTest.Function), cmbMaterial.AlphaTest.Reference / 255f);
|
|
|
|
|
}
|
2019-08-03 04:06:45 +02:00
|
|
|
|
else
|
|
|
|
|
GL.Disable(EnableCap.AlphaTest);
|
2020-04-14 22:40:24 +02:00
|
|
|
|
}
|
2019-08-03 03:24:13 +02:00
|
|
|
|
|
2020-04-14 22:40:24 +02:00
|
|
|
|
private AlphaFunction ConvertTestFunction(ZeldaLib.CtrModelBinary.Types.TestFunc func)
|
|
|
|
|
{
|
|
|
|
|
switch (func)
|
|
|
|
|
{
|
|
|
|
|
case ZeldaLib.CtrModelBinary.Types.TestFunc.Always: return AlphaFunction.Always;
|
|
|
|
|
case ZeldaLib.CtrModelBinary.Types.TestFunc.Equal: return AlphaFunction.Equal;
|
|
|
|
|
case ZeldaLib.CtrModelBinary.Types.TestFunc.Gequal: return AlphaFunction.Gequal;
|
|
|
|
|
case ZeldaLib.CtrModelBinary.Types.TestFunc.Greater: return AlphaFunction.Greater;
|
|
|
|
|
case ZeldaLib.CtrModelBinary.Types.TestFunc.Lequal: return AlphaFunction.Lequal;
|
|
|
|
|
case ZeldaLib.CtrModelBinary.Types.TestFunc.Less: return AlphaFunction.Less;
|
|
|
|
|
case ZeldaLib.CtrModelBinary.Types.TestFunc.Never: return AlphaFunction.Never;
|
|
|
|
|
case ZeldaLib.CtrModelBinary.Types.TestFunc.Notequal: return AlphaFunction.Notequal;
|
|
|
|
|
default: return AlphaFunction.Always;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private BlendingFactor ConvertBlendFunc(ZeldaLib.CtrModelBinary.Types.BlendFunc factor)
|
|
|
|
|
{
|
|
|
|
|
switch (factor)
|
|
|
|
|
{
|
|
|
|
|
case ZeldaLib.CtrModelBinary.Types.BlendFunc.ConstantAlpha: return BlendingFactor.ConstantAlpha;
|
|
|
|
|
case ZeldaLib.CtrModelBinary.Types.BlendFunc.ConstantColor: return BlendingFactor.ConstantColor;
|
|
|
|
|
case ZeldaLib.CtrModelBinary.Types.BlendFunc.DestinationAlpha: return BlendingFactor.DstAlpha;
|
|
|
|
|
case ZeldaLib.CtrModelBinary.Types.BlendFunc.DestinationColor: return BlendingFactor.DstColor;
|
|
|
|
|
case ZeldaLib.CtrModelBinary.Types.BlendFunc.One: return BlendingFactor.One;
|
|
|
|
|
case ZeldaLib.CtrModelBinary.Types.BlendFunc.OneMinusConstantAlpha: return BlendingFactor.OneMinusConstantAlpha;
|
|
|
|
|
case ZeldaLib.CtrModelBinary.Types.BlendFunc.OneMinusConstantColor: return BlendingFactor.OneMinusConstantColor;
|
|
|
|
|
case ZeldaLib.CtrModelBinary.Types.BlendFunc.OneMinusDestinationAlpha: return BlendingFactor.OneMinusDstAlpha;
|
|
|
|
|
case ZeldaLib.CtrModelBinary.Types.BlendFunc.OneMinusDestinationColor: return BlendingFactor.OneMinusDstColor;
|
|
|
|
|
case ZeldaLib.CtrModelBinary.Types.BlendFunc.OneMinusSourceAlpha: return BlendingFactor.OneMinusSrcAlpha;
|
|
|
|
|
case ZeldaLib.CtrModelBinary.Types.BlendFunc.OneMinusSourceColor: return BlendingFactor.OneMinusSrcColor;
|
|
|
|
|
case ZeldaLib.CtrModelBinary.Types.BlendFunc.SourceAlpha: return BlendingFactor.SrcAlpha;
|
|
|
|
|
case ZeldaLib.CtrModelBinary.Types.BlendFunc.SourceColor: return BlendingFactor.SrcColor;
|
|
|
|
|
case ZeldaLib.CtrModelBinary.Types.BlendFunc.SourceAlphaSaturate: return BlendingFactor.SrcAlphaSaturate;
|
|
|
|
|
case ZeldaLib.CtrModelBinary.Types.BlendFunc.Zero: return BlendingFactor.Zero;
|
|
|
|
|
default: return BlendingFactor.Zero;
|
|
|
|
|
}
|
2019-08-03 03:24:13 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-04-14 22:40:24 +02:00
|
|
|
|
private void SetGLCullMode(ZeldaLib.CtrModelBinary.Types.CullMode CullMode)
|
2019-08-03 22:07:52 +02:00
|
|
|
|
{
|
|
|
|
|
GL.Enable(EnableCap.CullFace);
|
|
|
|
|
|
2020-04-14 22:40:24 +02:00
|
|
|
|
if (CullMode == ZeldaLib.CtrModelBinary.Types.CullMode.Back)
|
2019-08-03 22:07:52 +02:00
|
|
|
|
GL.CullFace(CullFaceMode.Back);
|
2020-04-14 22:40:24 +02:00
|
|
|
|
if (CullMode == ZeldaLib.CtrModelBinary.Types.CullMode.Front)
|
2019-08-03 22:07:52 +02:00
|
|
|
|
GL.CullFace(CullFaceMode.Front);
|
2020-04-14 22:40:24 +02:00
|
|
|
|
if (CullMode == ZeldaLib.CtrModelBinary.Types.CullMode.Both)
|
2019-08-03 22:07:52 +02:00
|
|
|
|
GL.CullFace(CullFaceMode.FrontAndBack);
|
2020-04-14 22:40:24 +02:00
|
|
|
|
if (CullMode == ZeldaLib.CtrModelBinary.Types.CullMode.None)
|
2019-08-03 22:07:52 +02:00
|
|
|
|
GL.Disable(EnableCap.CullFace);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-02 23:27:44 +02:00
|
|
|
|
public override int BindTexture(STGenericMatTexture tex, ShaderProgram shader)
|
|
|
|
|
{
|
|
|
|
|
GL.ActiveTexture(TextureUnit.Texture0 + tex.textureUnit + 1);
|
|
|
|
|
GL.BindTexture(TextureTarget.Texture2D, RenderTools.defaultTex.RenderableTex.TexID);
|
|
|
|
|
|
|
|
|
|
string activeTex = tex.Name;
|
|
|
|
|
|
|
|
|
|
foreach (var texture in TextureList)
|
|
|
|
|
{
|
|
|
|
|
if (TextureList.IndexOf(texture) == ((CMB.CMBTextureMapWrapper)tex).TextureIndex)
|
|
|
|
|
{
|
|
|
|
|
BindGLTexture(tex, shader, TextureList[((CMB.CMBTextureMapWrapper)tex).TextureIndex]);
|
|
|
|
|
return tex.textureUnit + 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return tex.textureUnit + 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|