Start to impliment a base for custom bfres renderers
This commit is contained in:
parent
1f8390e03a
commit
bdf2b625e9
@ -758,7 +758,8 @@ namespace FirstPlugin
|
||||
return editor;
|
||||
}
|
||||
|
||||
public BFRESRender BFRESRender;
|
||||
|
||||
public BFRESRenderBase BFRESRender;
|
||||
public void Load(System.IO.Stream stream)
|
||||
{
|
||||
CanSave = true;
|
||||
@ -781,7 +782,6 @@ namespace FirstPlugin
|
||||
|
||||
|
||||
BFRESRender = new BFRESRender();
|
||||
DrawableContainer.Drawables.Add(BFRESRender);
|
||||
DrawableContainer.Name = FileName;
|
||||
|
||||
BFRESRender.ModelTransform = MarioCostumeEditor.SetTransform(FileName);
|
||||
@ -796,6 +796,20 @@ namespace FirstPlugin
|
||||
LoadFile(new Syroot.NintenTools.NSW.Bfres.ResFile(stream));
|
||||
}
|
||||
|
||||
if (resFileU != null) {
|
||||
if (resFileU.VersioFull == "3,0,0,1")
|
||||
{
|
||||
//Todo check for valid sharc files to parse as programs via materials to map
|
||||
|
||||
// Console.WriteLine("RedPro_Renderer!");
|
||||
/* BFRESRender = new RedPro_Renderer();
|
||||
BFRESRender.ModelTransform = Matrix4.Identity;
|
||||
BFRESRender.ResFileNode = this;*/
|
||||
}
|
||||
}
|
||||
|
||||
DrawableContainer.Drawables.Add(BFRESRender);
|
||||
|
||||
var Models = GetModels();
|
||||
if (Models != null)
|
||||
{
|
||||
|
@ -203,7 +203,7 @@ namespace Bfres.Structs
|
||||
((BFRES)Parent.Parent.Parent.Parent).BFRESRender.UpdateSingleMaterialTextureMaps(this);
|
||||
}
|
||||
|
||||
public BFRESRender GetRenderer()
|
||||
public BFRESRenderBase GetRenderer()
|
||||
{
|
||||
return ((BFRES)Parent.Parent.Parent.Parent).BFRESRender;
|
||||
}
|
||||
|
@ -186,10 +186,11 @@ namespace Bfres.Structs
|
||||
public override string ImportFilter => FileFilters.GetFilter(typeof(BfresBone));
|
||||
public override string ReplaceFilter => FileFilters.GetFilter(typeof(FSKL));
|
||||
|
||||
public BFRESRender GetRenderer()
|
||||
public BFRESRenderBase GetRenderer()
|
||||
{
|
||||
return ((FMDL)Parent.Parent).GetRenderer();
|
||||
}
|
||||
|
||||
public fsklNode()
|
||||
{
|
||||
Text = "Skeleton";
|
||||
|
@ -396,7 +396,7 @@
|
||||
<Compile Include="FileFormats\Texture\BTI.cs" />
|
||||
<Compile Include="FileFormats\Texture\WTB.cs" />
|
||||
<Compile Include="GL\BCH_Render.cs" />
|
||||
<Compile Include="GL\BFRES_Render.cs" />
|
||||
<Compile Include="GL\BFRES\BFRESRenderBase.cs" />
|
||||
<Compile Include="GL\BMD_Renderer.cs" />
|
||||
<Compile Include="GL\CMB_Renderer.cs" />
|
||||
<Compile Include="GL\GXToOpenGL.cs" />
|
||||
@ -406,6 +406,8 @@
|
||||
<Compile Include="GL\Custom2D\KCLRendering2D.cs" />
|
||||
<Compile Include="GL\LM3_Renderer.cs" />
|
||||
<Compile Include="GL\PunchOutWii_Renderer.cs" />
|
||||
<Compile Include="GL\BFRES\RedPro\RedPro_Renderer.cs" />
|
||||
<Compile Include="GL\BFRES\RedPro\ShaderProgram.cs" />
|
||||
<Compile Include="GL\Strikers_Renderer.cs" />
|
||||
<Compile Include="GUI\BCH\BCHMeshEditor.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
@ -1392,6 +1394,7 @@
|
||||
<Compile Include="FileFormats\Texture\XTX.cs" />
|
||||
<Compile Include="FileFormats\Rom\XCI.cs" />
|
||||
<Compile Include="GetSwitchKeys.cs" />
|
||||
<Compile Include="GL\BFRES\BFRES_Render.cs" />
|
||||
<Compile Include="GUI\Advanced Editor\TextureViewer.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
|
255
File_Format_Library/GL/BFRES/BFRESRenderBase.cs
Normal file
255
File_Format_Library/GL/BFRES/BFRESRenderBase.cs
Normal file
@ -0,0 +1,255 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Toolbox.Library;
|
||||
using Toolbox.Library.Rendering;
|
||||
using GL_EditorFramework.GL_Core;
|
||||
using GL_EditorFramework.Interfaces;
|
||||
using Bfres.Structs;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
using OpenTK;
|
||||
|
||||
namespace FirstPlugin
|
||||
{
|
||||
public class BFRESRenderBase : AbstractGlDrawable, IMeshContainer
|
||||
{
|
||||
public Matrix4 ModelTransform = Matrix4.Identity;
|
||||
|
||||
// gl buffer objects
|
||||
internal int vbo_position;
|
||||
internal int ibo_elements;
|
||||
|
||||
public BFRES ResFileNode;
|
||||
|
||||
public List<STGenericObject> Meshes
|
||||
{
|
||||
get
|
||||
{
|
||||
List<STGenericObject> meshes = new List<STGenericObject>();
|
||||
for (int m = 0; m < models.Count; m++)
|
||||
{
|
||||
for (int s = 0; s < models[m].shapes.Count; s++)
|
||||
meshes.Add(models[m].shapes[s]);
|
||||
}
|
||||
return meshes;
|
||||
}
|
||||
}
|
||||
|
||||
private List<FMDL> _models = new List<FMDL>();
|
||||
public List<FMDL> models
|
||||
{
|
||||
get
|
||||
{
|
||||
return _models;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool Disposing = false;
|
||||
|
||||
public void UpdateModelList()
|
||||
{
|
||||
_models.Clear();
|
||||
foreach (var node in ResFileNode.Nodes)
|
||||
{
|
||||
if (node is BFRESGroupNode &&
|
||||
((BFRESGroupNode)node).Type == BRESGroupType.Models)
|
||||
{
|
||||
foreach (FMDL mdl in ((BFRESGroupNode)node).Nodes)
|
||||
_models.Add(mdl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void TransformBones()
|
||||
{
|
||||
for (int mdl = 0; mdl < models.Count; mdl++)
|
||||
{
|
||||
for (int b = 0; b < models[mdl].Skeleton.bones.Count; b++)
|
||||
{
|
||||
models[mdl].Skeleton.bones[b].ModelMatrix = ModelTransform;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void GenerateBuffers()
|
||||
{
|
||||
GL.GenBuffers(1, out vbo_position);
|
||||
GL.GenBuffers(1, out ibo_elements);
|
||||
|
||||
TransformBones();
|
||||
|
||||
UpdateVertexData();
|
||||
UpdateTextureMaps();
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
bool buffersWereInitialized = ibo_elements != 0 && vbo_position != 0;
|
||||
|
||||
if (!buffersWereInitialized)
|
||||
return;
|
||||
|
||||
GL.DeleteBuffer(vbo_position);
|
||||
GL.DeleteBuffer(ibo_elements);
|
||||
|
||||
Disposing = true;
|
||||
}
|
||||
|
||||
public virtual void UpdateVertexData()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void UpdateTextureMaps()
|
||||
{
|
||||
if (!Runtime.OpenTKInitialized)
|
||||
return;
|
||||
|
||||
foreach (BNTX bntx in PluginRuntime.bntxContainers)
|
||||
{
|
||||
if (!bntx.AllGLInitialized)
|
||||
{
|
||||
foreach (var tex in bntx.Textures)
|
||||
{
|
||||
if (tex.Value.RenderableTex != null && !tex.Value.RenderableTex.GLInitialized)
|
||||
tex.Value.LoadOpenGLTexture();
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (BFRESGroupNode ftexCont in PluginRuntime.ftexContainers)
|
||||
{
|
||||
foreach (var tex in ftexCont.ResourceNodes)
|
||||
{
|
||||
if (!((FTEX)tex.Value).RenderableTex.GLInitialized)
|
||||
((FTEX)tex.Value).LoadOpenGLTexture();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void UpdateSingleMaterialTextureMaps(FMAT mat)
|
||||
{
|
||||
if (!Runtime.OpenTKInitialized)
|
||||
return;
|
||||
|
||||
foreach (BNTX bntx in PluginRuntime.bntxContainers)
|
||||
{
|
||||
foreach (var t in mat.TextureMaps)
|
||||
{
|
||||
if (bntx.Textures.ContainsKey(t.Name))
|
||||
{
|
||||
if (!bntx.Textures[t.Name].RenderableTex.GLInitialized)
|
||||
bntx.Textures[t.Name].LoadOpenGLTexture();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LibraryGUI.UpdateViewport();
|
||||
}
|
||||
|
||||
public override void Prepare(GL_ControlModern control)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Prepare(GL_ControlLegacy control)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Draw(GL_ControlLegacy control, Pass pass)
|
||||
{
|
||||
if (Disposing || pass == Pass.TRANSPARENT) return;
|
||||
|
||||
bool buffersWereInitialized = ibo_elements != 0 && vbo_position != 0;
|
||||
if (!buffersWereInitialized)
|
||||
GenerateBuffers();
|
||||
|
||||
if (!Runtime.OpenTKInitialized)
|
||||
return;
|
||||
|
||||
Matrix4 mvpMat = control.ModelMatrix * control.CameraMatrix * control.ProjectionMatrix;
|
||||
|
||||
Matrix4 invertedCamera = Matrix4.Identity;
|
||||
if (invertedCamera.Determinant != 0)
|
||||
invertedCamera = mvpMat.Inverted();
|
||||
|
||||
Vector3 lightDirection = new Vector3(0f, 0f, -1f);
|
||||
Vector3 difLightDirection = Vector3.TransformNormal(lightDirection, invertedCamera).Normalized();
|
||||
|
||||
GL.Enable(EnableCap.Texture2D);
|
||||
GL.Enable(EnableCap.DepthTest);
|
||||
|
||||
foreach (var model in models)
|
||||
{
|
||||
foreach (var shape in model.shapes)
|
||||
{
|
||||
if (Runtime.RenderModels && model.Checked && shape.Checked)
|
||||
{
|
||||
var mat = shape.GetMaterial();
|
||||
|
||||
List<int> faces = shape.lodMeshes[shape.DisplayLODIndex].getDisplayFace();
|
||||
|
||||
GL.Begin(PrimitiveType.Triangles);
|
||||
foreach (var index in faces)
|
||||
{
|
||||
Vertex vert = shape.vertices[index];
|
||||
float normal = Vector3.Dot(difLightDirection, vert.nrm) * 0.5f + 0.5f;
|
||||
GL.Color3(new Vector3(normal));
|
||||
GL.TexCoord2(vert.uv0);
|
||||
GL.Vertex3(vert.pos);
|
||||
}
|
||||
GL.End();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GL.Enable(EnableCap.Texture2D);
|
||||
}
|
||||
|
||||
public void CenterCamera(GL_ControlBase control)
|
||||
{
|
||||
if (!Runtime.FrameCamera)
|
||||
return;
|
||||
|
||||
var spheres = new List<Vector4>();
|
||||
for (int mdl = 0; mdl < models.Count; mdl++)
|
||||
{
|
||||
for (int shp = 0; shp < models[mdl].shapes.Count; shp++)
|
||||
{
|
||||
var vertexPositions = models[mdl].shapes[shp].vertices.Select(x => x.pos).Distinct();
|
||||
spheres.Add(control.GenerateBoundingSphere(vertexPositions));
|
||||
}
|
||||
}
|
||||
|
||||
control.FrameSelect(spheres);
|
||||
}
|
||||
|
||||
public static Vector4 GenerateBoundingSphere(IEnumerable<Vector4> boundingSpheres)
|
||||
{
|
||||
// The initial max/min should be the first point.
|
||||
Vector3 min = boundingSpheres.FirstOrDefault().Xyz - new Vector3(boundingSpheres.FirstOrDefault().W);
|
||||
Vector3 max = boundingSpheres.FirstOrDefault().Xyz + new Vector3(boundingSpheres.FirstOrDefault().W);
|
||||
|
||||
// Calculate the end points using the center and radius
|
||||
foreach (var sphere in boundingSpheres)
|
||||
{
|
||||
min = Vector3.ComponentMin(min, sphere.Xyz - new Vector3(sphere.W));
|
||||
max = Vector3.ComponentMax(max, sphere.Xyz + new Vector3(sphere.W));
|
||||
}
|
||||
|
||||
return GetBoundingSphereFromSpheres(min, max);
|
||||
}
|
||||
private static Vector4 GetBoundingSphereFromSpheres(Vector3 min, Vector3 max)
|
||||
{
|
||||
Vector3 lengths = max - min;
|
||||
float maxLength = Math.Max(lengths.X, Math.Max(lengths.Y, lengths.Z));
|
||||
Vector3 center = (max + min) / 2.0f;
|
||||
float radius = maxLength / 2.0f;
|
||||
return new Vector4(center, radius);
|
||||
}
|
||||
|
||||
public override void Draw(GL_ControlModern control, Pass pass) {
|
||||
}
|
||||
}
|
||||
}
|
@ -19,11 +19,8 @@ using SF = SFGraphics.GLObjects.Shaders;
|
||||
|
||||
namespace FirstPlugin
|
||||
{
|
||||
public class BFRESRender : AbstractGlDrawable, IMeshContainer
|
||||
public class BFRESRender : BFRESRenderBase
|
||||
{
|
||||
private bool Disposing = false;
|
||||
|
||||
public Matrix4 ModelTransform = Matrix4.Identity;
|
||||
Vector3 position = new Vector3(0);
|
||||
|
||||
public static Vector4 hoverColor = new Vector4(1);
|
||||
@ -34,179 +31,19 @@ namespace FirstPlugin
|
||||
|
||||
public bool IsSelected() => Selected;
|
||||
|
||||
// gl buffer objects
|
||||
int vbo_position;
|
||||
int ibo_elements;
|
||||
|
||||
public List<STGenericObject> Meshes
|
||||
{
|
||||
get
|
||||
{
|
||||
List<STGenericObject> meshes = new List<STGenericObject>();
|
||||
for (int m =0; m < models.Count; m++)
|
||||
{
|
||||
for (int s = 0; s < models[m].shapes.Count; s++)
|
||||
meshes.Add(models[m].shapes[s]);
|
||||
}
|
||||
return meshes;
|
||||
}
|
||||
}
|
||||
|
||||
private List<FMDL> _models = new List<FMDL>();
|
||||
public List<FMDL> models
|
||||
{
|
||||
get
|
||||
{
|
||||
return _models;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateModelList()
|
||||
{
|
||||
_models.Clear();
|
||||
foreach (var node in ResFileNode.Nodes)
|
||||
{
|
||||
if (node is BFRESGroupNode &&
|
||||
((BFRESGroupNode)node).Type == BRESGroupType.Models)
|
||||
{
|
||||
foreach (FMDL mdl in ((BFRESGroupNode)node).Nodes)
|
||||
_models.Add(mdl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public BFRES ResFileNode;
|
||||
|
||||
public BFRESRender()
|
||||
{
|
||||
|
||||
}
|
||||
private void GenerateBuffers()
|
||||
{
|
||||
GL.GenBuffers(1, out vbo_position);
|
||||
GL.GenBuffers(1, out ibo_elements);
|
||||
|
||||
TransformBones();
|
||||
|
||||
UpdateVertexData();
|
||||
UpdateTextureMaps();
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
bool buffersWereInitialized = ibo_elements != 0 && vbo_position != 0;
|
||||
|
||||
if (!buffersWereInitialized)
|
||||
return;
|
||||
|
||||
GL.DeleteBuffer(vbo_position);
|
||||
GL.DeleteBuffer(ibo_elements);
|
||||
|
||||
Disposing = true;
|
||||
}
|
||||
|
||||
private void TransformBones()
|
||||
{
|
||||
for (int mdl = 0; mdl < models.Count; mdl++)
|
||||
{
|
||||
for (int b = 0; b < models[mdl].Skeleton.bones.Count; b++)
|
||||
{
|
||||
models[mdl].Skeleton.bones[b].ModelMatrix = ModelTransform;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Rendering
|
||||
|
||||
|
||||
// public ShaderProgram BotwShaderProgram;
|
||||
// public ShaderProgram normalsShaderProgram;
|
||||
// public ShaderProgram debugShaderProgram;
|
||||
// public ShaderProgram pbrShaderProgram;
|
||||
// public ShaderProgram defaultShaderProgram;
|
||||
// public ShaderProgram solidColorShaderProgram;
|
||||
|
||||
public override void Prepare(GL_ControlModern control)
|
||||
{
|
||||
/* string pathFrag = System.IO.Path.Combine(Runtime.ExecutableDir, "Shader", "Bfres") + "\\BFRES.frag";
|
||||
string pathVert = System.IO.Path.Combine(Runtime.ExecutableDir, "Shader", "Bfres") + "\\BFRES.vert";
|
||||
|
||||
|
||||
string pathBotwFrag = System.IO.Path.Combine(Runtime.ExecutableDir, "Shader", "Bfres") + "\\BFRES_Botw.frag";
|
||||
|
||||
string pathPbrFrag = System.IO.Path.Combine(Runtime.ExecutableDir, "Shader", "Bfres") + "\\BFRES_PBR.frag";
|
||||
|
||||
string pathBfresUtiltyFrag = System.IO.Path.Combine(Runtime.ExecutableDir, "Shader", "Bfres") + "\\BFRES_utility.frag";
|
||||
string pathBfresTurboShadow = System.IO.Path.Combine(Runtime.ExecutableDir, "Shader", "Bfres") + "\\BFRESTurboShadow.frag";
|
||||
|
||||
string pathUtiltyFrag = System.IO.Path.Combine(Runtime.ExecutableDir, "Shader", "Utility") + "\\Utility.frag";
|
||||
|
||||
|
||||
|
||||
string pathDebugFrag = System.IO.Path.Combine(Runtime.ExecutableDir, "Shader", "Bfres") + "\\BFRES_Debug.frag";
|
||||
string pathNormalsFrag = System.IO.Path.Combine(Runtime.ExecutableDir, "Shader", "Bfres") + "\\Normals.frag";
|
||||
string pathNormalsVert = System.IO.Path.Combine(Runtime.ExecutableDir, "Shader", "Bfres") + "\\Normals.vert";
|
||||
string pathNormalGeom = System.IO.Path.Combine(Runtime.ExecutableDir, "Shader", "Bfres") + "\\Normals.geom";
|
||||
|
||||
var defaultFrag = new FragmentShader(System.IO.File.ReadAllText(pathFrag));
|
||||
var defaultVert = new VertexShader(System.IO.File.ReadAllText(pathVert));
|
||||
|
||||
var BotwtFrag = new FragmentShader(System.IO.File.ReadAllText(pathBotwFrag));
|
||||
|
||||
var shadowMapAGL = new FragmentShader(System.IO.File.ReadAllText(pathBfresTurboShadow));
|
||||
|
||||
var PbrFrag = new FragmentShader(System.IO.File.ReadAllText(pathPbrFrag));
|
||||
|
||||
var debugFrag = new FragmentShader(System.IO.File.ReadAllText(pathDebugFrag));
|
||||
var normalsVert = new VertexShader(System.IO.File.ReadAllText(pathNormalsVert));
|
||||
var normalsFrag = new FragmentShader(System.IO.File.ReadAllText(pathNormalsFrag));
|
||||
var normalsGeom = new GeomertyShader(System.IO.File.ReadAllText(pathNormalGeom));
|
||||
|
||||
var bfresUtiltyFrag = new FragmentShader(System.IO.File.ReadAllText(pathBfresUtiltyFrag));
|
||||
var utiltyFrag = new FragmentShader(System.IO.File.ReadAllText(pathUtiltyFrag));
|
||||
|
||||
var solidColorFrag = new FragmentShader(
|
||||
@"#version 330
|
||||
uniform vec4 color;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main(){
|
||||
fragColor = color;
|
||||
}");
|
||||
|
||||
var solidColorVert = new VertexShader(
|
||||
@"#version 330
|
||||
in vec3 vPosition;
|
||||
in vec3 vNormal;
|
||||
in vec3 vColor;
|
||||
|
||||
uniform mat4 mtxMdl;
|
||||
uniform mat4 mtxCam;
|
||||
|
||||
out vec3 normal;
|
||||
out vec3 color;
|
||||
out vec3 position;
|
||||
|
||||
void main(){
|
||||
normal = vNormal;
|
||||
color = vColor;
|
||||
position = vPosition;
|
||||
|
||||
gl_Position = mtxMdl * mtxCam * vec4(vPosition.xyz, 1.0);
|
||||
}");
|
||||
|
||||
defaultShaderProgram = new ShaderProgram(new Shader[] { bfresUtiltyFrag, utiltyFrag, defaultFrag, defaultVert, utiltyFrag, shadowMapAGL });
|
||||
BotwShaderProgram = new ShaderProgram(new Shader[] { bfresUtiltyFrag, utiltyFrag, BotwtFrag, defaultVert, utiltyFrag, shadowMapAGL });
|
||||
|
||||
normalsShaderProgram = new ShaderProgram(new Shader[] { normalsFrag, normalsVert, normalsGeom });
|
||||
debugShaderProgram = new ShaderProgram(new Shader[] { bfresUtiltyFrag, utiltyFrag, debugFrag, defaultVert, utiltyFrag, shadowMapAGL });
|
||||
pbrShaderProgram = new ShaderProgram(new Shader[] { bfresUtiltyFrag, utiltyFrag, PbrFrag, defaultVert, shadowMapAGL });
|
||||
solidColorShaderProgram = new ShaderProgram(solidColorFrag, solidColorVert);*/
|
||||
}
|
||||
|
||||
public override void Prepare(GL_ControlLegacy control)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Draw(GL_ControlLegacy control, Pass pass)
|
||||
@ -259,56 +96,10 @@ namespace FirstPlugin
|
||||
GL.Enable(EnableCap.Texture2D);
|
||||
}
|
||||
|
||||
public void CenterCamera(GL_ControlBase control)
|
||||
{
|
||||
if (!Runtime.FrameCamera)
|
||||
return;
|
||||
|
||||
var spheres = new List<Vector4>();
|
||||
for (int mdl = 0; mdl < models.Count; mdl++)
|
||||
{
|
||||
for (int shp = 0; shp < models[mdl].shapes.Count; shp++)
|
||||
{
|
||||
var vertexPositions = models[mdl].shapes[shp].vertices.Select(x => x.pos).Distinct();
|
||||
spheres.Add(control.GenerateBoundingSphere(vertexPositions));
|
||||
}
|
||||
}
|
||||
|
||||
control.FrameSelect(spheres);
|
||||
}
|
||||
|
||||
public static Vector4 GenerateBoundingSphere(IEnumerable<Vector4> boundingSpheres)
|
||||
{
|
||||
// The initial max/min should be the first point.
|
||||
Vector3 min = boundingSpheres.FirstOrDefault().Xyz - new Vector3(boundingSpheres.FirstOrDefault().W);
|
||||
Vector3 max = boundingSpheres.FirstOrDefault().Xyz + new Vector3(boundingSpheres.FirstOrDefault().W);
|
||||
|
||||
// Calculate the end points using the center and radius
|
||||
foreach (var sphere in boundingSpheres)
|
||||
{
|
||||
min = Vector3.ComponentMin(min, sphere.Xyz - new Vector3(sphere.W));
|
||||
max = Vector3.ComponentMax(max, sphere.Xyz + new Vector3(sphere.W));
|
||||
}
|
||||
|
||||
return GetBoundingSphereFromSpheres(min, max);
|
||||
}
|
||||
private static Vector4 GetBoundingSphereFromSpheres(Vector3 min, Vector3 max)
|
||||
{
|
||||
Vector3 lengths = max - min;
|
||||
float maxLength = Math.Max(lengths.X, Math.Max(lengths.Y, lengths.Z));
|
||||
Vector3 center = (max + min) / 2.0f;
|
||||
float radius = maxLength / 2.0f;
|
||||
return new Vector4(center, radius);
|
||||
}
|
||||
|
||||
public override void Draw(GL_ControlModern control, Pass pass) {
|
||||
DrawBfres(control, pass);
|
||||
}
|
||||
|
||||
/* public override void Draw(GL_ControlModern control, Pass pass, EditorSceneBase editorScene) {
|
||||
DrawBfres(control, pass);
|
||||
}*/
|
||||
|
||||
private void DrawBfres(GL_ControlModern control, Pass pass)
|
||||
{
|
||||
if (!Runtime.OpenTKInitialized || pass == Pass.TRANSPARENT || Disposing)
|
||||
@ -445,26 +236,6 @@ namespace FirstPlugin
|
||||
shader.DisableVertexAttributes();
|
||||
}
|
||||
|
||||
public void DepthSortMeshes(Vector3 cameraPosition)
|
||||
{
|
||||
foreach (FMDL fmdl in models)
|
||||
{
|
||||
List<FSHP> unsortedMeshes = new List<FSHP>();
|
||||
|
||||
foreach (FSHP m in fmdl.shapes)
|
||||
{
|
||||
m.sortingDistance = m.CalculateSortingDistance(cameraPosition);
|
||||
unsortedMeshes.Add(m);
|
||||
}
|
||||
|
||||
fmdl.depthSortedMeshes = unsortedMeshes.OrderBy(o => (o.sortingDistance)).ToList();
|
||||
}
|
||||
|
||||
|
||||
// Order by the distance from the camera to the closest point on the bounding sphere.
|
||||
// Positive values are usually closer to camera. Negative values are usually farther away.
|
||||
}
|
||||
|
||||
private void SetRenderSettings(SF.Shader shader)
|
||||
{
|
||||
shader.SetBoolToInt("renderVertColor", Runtime.renderVertColor);
|
||||
@ -813,7 +584,7 @@ namespace FirstPlugin
|
||||
}
|
||||
|
||||
static bool Loaded = false;
|
||||
public void UpdateVertexData()
|
||||
public override void UpdateVertexData()
|
||||
{
|
||||
if (!Runtime.OpenTKInitialized)
|
||||
return;
|
||||
@ -872,50 +643,6 @@ namespace FirstPlugin
|
||||
|
||||
Loaded = true;
|
||||
}
|
||||
public void UpdateSingleMaterialTextureMaps(FMAT mat)
|
||||
{
|
||||
if (!Runtime.OpenTKInitialized)
|
||||
return;
|
||||
|
||||
foreach (BNTX bntx in PluginRuntime.bntxContainers)
|
||||
{
|
||||
foreach (var t in mat.TextureMaps)
|
||||
{
|
||||
if (bntx.Textures.ContainsKey(t.Name))
|
||||
{
|
||||
if (!bntx.Textures[t.Name].RenderableTex.GLInitialized)
|
||||
bntx.Textures[t.Name].LoadOpenGLTexture();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LibraryGUI.UpdateViewport();
|
||||
}
|
||||
public void UpdateTextureMaps()
|
||||
{
|
||||
if (!Runtime.OpenTKInitialized)
|
||||
return;
|
||||
|
||||
foreach (BNTX bntx in PluginRuntime.bntxContainers)
|
||||
{
|
||||
if (!bntx.AllGLInitialized)
|
||||
{
|
||||
foreach (var tex in bntx.Textures)
|
||||
{
|
||||
if (tex.Value.RenderableTex != null && !tex.Value.RenderableTex.GLInitialized)
|
||||
tex.Value.LoadOpenGLTexture();
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (BFRESGroupNode ftexCont in PluginRuntime.ftexContainers)
|
||||
{
|
||||
foreach (var tex in ftexCont.ResourceNodes)
|
||||
{
|
||||
if (!((FTEX)tex.Value).RenderableTex.GLInitialized)
|
||||
((FTEX)tex.Value).LoadOpenGLTexture();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetRenderPass(FMAT mat)
|
||||
{
|
||||
@ -1300,107 +1027,6 @@ namespace FirstPlugin
|
||||
GL.DrawElements(PrimitiveType.Triangles, p.lodMeshes[p.DisplayLODIndex].displayFaceSize, DrawElementsType.UnsignedInt, p.Offset);
|
||||
}
|
||||
|
||||
/* public override BoundingBox GetSelectionBox()
|
||||
{
|
||||
Vector3 Min = new Vector3(0);
|
||||
Vector3 Max = new Vector3(0);
|
||||
|
||||
foreach (var model in models)
|
||||
{
|
||||
foreach (var shape in model.shapes)
|
||||
{
|
||||
foreach (var vertex in shape.vertices)
|
||||
{
|
||||
Min.X = Math.Min(Min.X, vertex.pos.X);
|
||||
Min.Y = Math.Min(Min.Y, vertex.pos.Y);
|
||||
Min.Z = Math.Min(Min.Z, vertex.pos.Z);
|
||||
Max.X = Math.Max(Max.X, vertex.pos.X);
|
||||
Max.Y = Math.Max(Max.Y, vertex.pos.Y);
|
||||
Max.Z = Math.Max(Max.Z, vertex.pos.Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new BoundingBox()
|
||||
{
|
||||
minX = Min.X,
|
||||
minY = Min.Y,
|
||||
minZ = Min.Z,
|
||||
maxX = Max.X,
|
||||
maxY = Max.Y,
|
||||
maxZ = Max.Z,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public override uint SelectAll(GL_ControlBase control)
|
||||
{
|
||||
Selected = true;
|
||||
return REDRAW;
|
||||
}
|
||||
|
||||
public override uint SelectDefault(GL_ControlBase control)
|
||||
{
|
||||
Selected = true;
|
||||
return REDRAW;
|
||||
}
|
||||
|
||||
public override uint Select(int partIndex, GL_ControlBase control)
|
||||
{
|
||||
Selected = true;
|
||||
return REDRAW;
|
||||
}
|
||||
|
||||
public override uint Deselect(int partIndex, GL_ControlBase control)
|
||||
{
|
||||
Selected = false;
|
||||
return REDRAW;
|
||||
}
|
||||
|
||||
public override LocalOrientation GetLocalOrientation(int partIndex)
|
||||
{
|
||||
return new LocalOrientation(position);
|
||||
}
|
||||
|
||||
public override bool TryStartDragging(DragActionType actionType, int hoveredPart, out LocalOrientation localOrientation, out bool dragExclusively)
|
||||
{
|
||||
localOrientation = new LocalOrientation(position);
|
||||
dragExclusively = false;
|
||||
return Selected;
|
||||
}
|
||||
|
||||
public override bool IsInRange(float range, float rangeSquared, Vector3 pos)
|
||||
{
|
||||
range = 20000; //Make the range large for now. Todo go back to this
|
||||
|
||||
BoundingBox box = GetSelectionBox();
|
||||
|
||||
if (pos.X < box.maxX + range && pos.X > box.minX - range &&
|
||||
pos.Y < box.maxY + range && pos.Y > box.minY - range &&
|
||||
pos.Z < box.maxZ + range && pos.Z > box.minZ - range)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override uint DeselectAll(GL_ControlBase control)
|
||||
{
|
||||
Selected = false;
|
||||
return REDRAW;
|
||||
}
|
||||
|
||||
public override Vector3 Position
|
||||
{
|
||||
get
|
||||
{
|
||||
return position;
|
||||
}
|
||||
set
|
||||
{
|
||||
position = value;
|
||||
}
|
||||
}*/
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
795
File_Format_Library/GL/BFRES/RedPro/RedPro_Renderer.cs
Normal file
795
File_Format_Library/GL/BFRES/RedPro/RedPro_Renderer.cs
Normal file
@ -0,0 +1,795 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Drawing;
|
||||
using Syroot.NintenTools.NSW.Bfres;
|
||||
using Syroot.NintenTools.NSW.Bfres.Helpers;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
using System.Windows.Forms;
|
||||
using GL_EditorFramework.GL_Core;
|
||||
using GL_EditorFramework.Interfaces;
|
||||
using Toolbox.Library;
|
||||
using Toolbox.Library.Rendering;
|
||||
using Toolbox.Library.IO;
|
||||
using Toolbox.Library.Forms;
|
||||
using ResU = Syroot.NintenTools.Bfres;
|
||||
using Bfres.Structs;
|
||||
using FirstPlugin.RedPro;
|
||||
|
||||
namespace FirstPlugin
|
||||
{
|
||||
public class RedPro_Renderer : BFRESRenderBase
|
||||
{
|
||||
public List<SHShaderProgram> ShaderPrograms = new List<SHShaderProgram>();
|
||||
|
||||
Vector3 position = new Vector3(0);
|
||||
|
||||
public static Vector4 hoverColor = new Vector4(1);
|
||||
public static Vector4 selectColor = new Vector4(1);
|
||||
|
||||
protected bool Selected = false;
|
||||
public bool Hovered = false;
|
||||
|
||||
public bool IsSelected() => Selected;
|
||||
|
||||
public struct DisplayVertex
|
||||
{
|
||||
// Used for rendering.
|
||||
public Vector3 Position;
|
||||
public Vector3 Normal;
|
||||
public Vector4 BlendWeight;
|
||||
public Vector4 BlendIndex;
|
||||
public Vector2 TexCoord0;
|
||||
public Vector2 TexCoord1;
|
||||
public Vector2 TexCoord2;
|
||||
public Vector2 TexCoord3;
|
||||
public Vector2 TexCoord4;
|
||||
public Vector2 TexCoord5;
|
||||
public Vector2 TexCoord6;
|
||||
public Vector2 TexCoord7;
|
||||
public Vector4 Color0;
|
||||
public Vector4 Color1;
|
||||
|
||||
public static int Size = 4 * (3 + 3 + 4 + 4 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 4 + 4);
|
||||
}
|
||||
|
||||
public RedPro_Renderer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#region Rendering
|
||||
|
||||
public override void Prepare(GL_ControlModern control)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Prepare(GL_ControlLegacy control)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Draw(GL_ControlLegacy control, Pass pass)
|
||||
{
|
||||
if (Disposing || pass == Pass.TRANSPARENT) return;
|
||||
|
||||
bool buffersWereInitialized = ibo_elements != 0 && vbo_position != 0;
|
||||
if (!buffersWereInitialized)
|
||||
GenerateBuffers();
|
||||
|
||||
if (!Runtime.OpenTKInitialized)
|
||||
return;
|
||||
|
||||
Matrix4 mvpMat = control.ModelMatrix * control.CameraMatrix * control.ProjectionMatrix;
|
||||
|
||||
Matrix4 invertedCamera = Matrix4.Identity;
|
||||
if (invertedCamera.Determinant != 0)
|
||||
invertedCamera = mvpMat.Inverted();
|
||||
|
||||
Vector3 lightDirection = new Vector3(0f, 0f, -1f);
|
||||
Vector3 difLightDirection = Vector3.TransformNormal(lightDirection, invertedCamera).Normalized();
|
||||
|
||||
GL.Enable(EnableCap.Texture2D);
|
||||
GL.Enable(EnableCap.DepthTest);
|
||||
|
||||
foreach (var model in models)
|
||||
{
|
||||
foreach (var shape in model.shapes)
|
||||
{
|
||||
if (Runtime.RenderModels && model.Checked && shape.Checked)
|
||||
{
|
||||
var mat = shape.GetMaterial();
|
||||
|
||||
List<int> faces = shape.lodMeshes[shape.DisplayLODIndex].getDisplayFace();
|
||||
|
||||
GL.Begin(PrimitiveType.Triangles);
|
||||
foreach (var index in faces)
|
||||
{
|
||||
Vertex vert = shape.vertices[index];
|
||||
float normal = Vector3.Dot(difLightDirection, vert.nrm) * 0.5f + 0.5f;
|
||||
GL.Color3(new Vector3(normal));
|
||||
GL.TexCoord2(vert.uv0);
|
||||
GL.Vertex3(vert.pos);
|
||||
}
|
||||
GL.End();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GL.Enable(EnableCap.Texture2D);
|
||||
}
|
||||
|
||||
public override void Draw(GL_ControlModern control, Pass pass)
|
||||
{
|
||||
DrawBfres(control, pass);
|
||||
}
|
||||
|
||||
private void DrawBfres(GL_ControlModern control, Pass pass)
|
||||
{
|
||||
if (!Runtime.OpenTKInitialized || pass == Pass.TRANSPARENT || Disposing)
|
||||
return;
|
||||
|
||||
bool buffersWereInitialized = ibo_elements != 0 && vbo_position != 0;
|
||||
if (!buffersWereInitialized)
|
||||
GenerateBuffers();
|
||||
|
||||
if (Hovered == true)
|
||||
throw new Exception("model selected");
|
||||
|
||||
control.UpdateModelMatrix(ModelTransform * Matrix4.CreateScale(Runtime.previewScale));
|
||||
|
||||
for (int m = 0; m < models.Count; m++)
|
||||
{
|
||||
if (models[m].Checked)
|
||||
{
|
||||
List<FSHP> opaque = new List<FSHP>();
|
||||
List<FSHP> transparent = new List<FSHP>();
|
||||
|
||||
for (int shp = 0; shp < models[m].shapes.Count; shp++)
|
||||
{
|
||||
if (models[m].shapes[shp].GetFMAT().isTransparent)
|
||||
transparent.Add(models[m].shapes[shp]);
|
||||
else
|
||||
opaque.Add(models[m].shapes[shp]);
|
||||
}
|
||||
|
||||
for (int shp = 0; shp < transparent.Count; shp++)
|
||||
{
|
||||
DrawModel(control, transparent[shp], models[m], models[m].IsSelected);
|
||||
}
|
||||
|
||||
for (int shp = 0; shp < opaque.Count; shp++)
|
||||
{
|
||||
DrawModel(control, opaque[shp], models[m], models[m].IsSelected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GL.Disable(EnableCap.DepthTest);
|
||||
GL.Enable(EnableCap.DepthTest);
|
||||
GL.Enable(EnableCap.CullFace);
|
||||
}
|
||||
|
||||
public void DepthSortMeshes(Vector3 cameraPosition)
|
||||
{
|
||||
foreach (FMDL fmdl in models)
|
||||
{
|
||||
List<FSHP> unsortedMeshes = new List<FSHP>();
|
||||
|
||||
foreach (FSHP m in fmdl.shapes)
|
||||
{
|
||||
m.sortingDistance = m.CalculateSortingDistance(cameraPosition);
|
||||
unsortedMeshes.Add(m);
|
||||
}
|
||||
|
||||
fmdl.depthSortedMeshes = unsortedMeshes.OrderBy(o => (o.sortingDistance)).ToList();
|
||||
}
|
||||
|
||||
|
||||
// Order by the distance from the camera to the closest point on the bounding sphere.
|
||||
// Positive values are usually closer to camera. Negative values are usually farther away.
|
||||
}
|
||||
|
||||
private static void SetTextureUniforms(FMAT mat, FSHP m, SHShaderProgram shader)
|
||||
{
|
||||
for (int t = 0; t < mat.TextureMaps.Count; t++) {
|
||||
MatTexture matex = (MatTexture)mat.TextureMaps[t];
|
||||
mat.HasDiffuseMap = TextureUniform(shader, mat, $"tex_map{t}", matex);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TextureUniform(SHShaderProgram shader, FMAT mat, string name, MatTexture mattex)
|
||||
{
|
||||
if (mattex.textureState == STGenericMatTexture.TextureState.Binded)
|
||||
return true;
|
||||
|
||||
// Bind the texture and create the uniform if the material has the right textures.
|
||||
BindTexture(mattex, mat, shader, mat.GetResFileU() != null);
|
||||
|
||||
return true;
|
||||
}
|
||||
public static bool BindTexture(MatTexture tex, FMAT material, SHShaderProgram shader, bool IsWiiU)
|
||||
{
|
||||
BFRES bfres = (BFRES)material.Parent.Parent.Parent.Parent;
|
||||
|
||||
GL.ActiveTexture(TextureUnit.Texture0 + tex.textureUnit + 1);
|
||||
GL.BindTexture(TextureTarget.Texture2D, RenderTools.defaultTex.RenderableTex.TexID);
|
||||
|
||||
string activeTex = tex.Name;
|
||||
if (tex.animatedTexName != "")
|
||||
activeTex = tex.animatedTexName;
|
||||
|
||||
if (IsWiiU)
|
||||
{
|
||||
if (bfres.HasTextures)
|
||||
{
|
||||
var ftexCont = bfres.GetFTEXContainer;
|
||||
if (ftexCont != null)
|
||||
{
|
||||
if (ftexCont.ResourceNodes.ContainsKey(activeTex))
|
||||
{
|
||||
return BindFTEX(ftexCont, tex, shader, activeTex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var ftexContainer in PluginRuntime.ftexContainers)
|
||||
{
|
||||
if (ftexContainer.ResourceNodes.ContainsKey(activeTex))
|
||||
{
|
||||
return BindFTEX(ftexContainer, tex, shader, activeTex);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bfres.HasTextures)
|
||||
{
|
||||
var bntx = bfres.GetBNTX;
|
||||
if (bntx != null)
|
||||
{
|
||||
if (bntx.Textures.ContainsKey(activeTex))
|
||||
{
|
||||
return BindBNTX(bntx, tex, shader, activeTex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var bntx in PluginRuntime.bntxContainers)
|
||||
{
|
||||
if (bntx.Textures.ContainsKey(activeTex))
|
||||
{
|
||||
return BindBNTX(bntx, tex, shader, activeTex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool BindFTEX(BFRESGroupNode ftexContainer, MatTexture tex, SHShaderProgram shader, string activeTex)
|
||||
{
|
||||
FTEX ftex = (FTEX)ftexContainer.ResourceNodes[activeTex];
|
||||
|
||||
if (ftex.RenderableTex == null || !ftex.RenderableTex.GLInitialized)
|
||||
ftex.LoadOpenGLTexture();
|
||||
|
||||
BindGLTexture(tex, shader, ftex);
|
||||
|
||||
return ftex.RenderableTex.GLInitialized;
|
||||
}
|
||||
|
||||
private static bool BindBNTX(BNTX bntx, MatTexture tex, SHShaderProgram shader, string activeTex)
|
||||
{
|
||||
if (bntx.Textures[activeTex].RenderableTex == null ||
|
||||
!bntx.Textures[activeTex].RenderableTex.GLInitialized)
|
||||
{
|
||||
bntx.Textures[activeTex].LoadOpenGLTexture();
|
||||
}
|
||||
|
||||
BindGLTexture(tex, shader, bntx.Textures[activeTex]);
|
||||
|
||||
return bntx.Textures[activeTex].RenderableTex.GLInitialized;
|
||||
}
|
||||
|
||||
private static void BindGLTexture(MatTexture tex, SHShaderProgram shader, STGenericTexture texture)
|
||||
{
|
||||
//If the texture is still not initialized then return
|
||||
if (!texture.RenderableTex.GLInitialized)
|
||||
return;
|
||||
|
||||
// GL.ActiveTexture(TextureUnit.Texture0 + texid);
|
||||
GL.BindTexture(TextureTarget.Texture2D, texture.RenderableTex.TexID);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)MatTexture.wrapmode[tex.WrapModeS]);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)MatTexture.wrapmode[tex.WrapModeT]);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)MatTexture.minfilter[tex.MinFilter]);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)MatTexture.magfilter[tex.MagFilter]);
|
||||
GL.TexParameter(TextureTarget.Texture2D, (TextureParameterName)ExtTextureFilterAnisotropic.TextureMaxAnisotropyExt, 0.0f);
|
||||
}
|
||||
|
||||
private SHShaderProgram SearchProgram(string shaderArchive, string shaderProgram)
|
||||
{
|
||||
for (int i = 0; i < ShaderPrograms.Count; i++)
|
||||
if (ShaderPrograms[i].IsLinked(shaderArchive, shaderProgram))
|
||||
return ShaderPrograms[i];
|
||||
return null;
|
||||
}
|
||||
|
||||
private void DrawModel(GL_ControlBase control, FSHP m, FMDL mdl, bool ModelSelected)
|
||||
{
|
||||
if (m.lodMeshes[m.DisplayLODIndex].faces.Count <= 3)
|
||||
return;
|
||||
|
||||
var mat = m.GetFMAT();
|
||||
|
||||
SHShaderProgram shader = SearchProgram(
|
||||
mat.shaderassign.ShaderArchive,
|
||||
mat.shaderassign.ShaderModel);
|
||||
|
||||
if (shader == null) return;
|
||||
|
||||
shader.Enable();
|
||||
shader.EnableVertexAttributes();
|
||||
|
||||
GL.Enable(EnableCap.AlphaTest);
|
||||
GL.AlphaFunc(AlphaFunction.Gequal, 0.1f);
|
||||
|
||||
// SetRenderPass(mat);
|
||||
// SetUniforms(mat, shader, m, m.DisplayId);
|
||||
// SetTextureUniforms(mat, m, shader);
|
||||
|
||||
shader.LoadUniforms(mdl, m, mdl.Skeleton, control);
|
||||
|
||||
SetVertexAttributes(m, shader);
|
||||
|
||||
if (m.Checked && mdl.Skeleton.bones.Count > 0 && mdl.Skeleton.bones[m.BoneIndex].Visible && mat.Enabled)
|
||||
{
|
||||
PrimitiveType primitiveType = PrimitiveType.Triangles;
|
||||
|
||||
switch (m.lodMeshes[m.DisplayLODIndex].PrimativeType)
|
||||
{
|
||||
case STPrimitiveType.Lines:
|
||||
primitiveType = PrimitiveType.Lines;
|
||||
break;
|
||||
case STPrimitiveType.LineStrips:
|
||||
primitiveType = PrimitiveType.LineStrip;
|
||||
break;
|
||||
case STPrimitiveType.Points:
|
||||
primitiveType = PrimitiveType.Points;
|
||||
break;
|
||||
case STPrimitiveType.Triangles:
|
||||
primitiveType = PrimitiveType.Triangles;
|
||||
break;
|
||||
}
|
||||
|
||||
GL.DrawElements(primitiveType, m.lodMeshes[m.DisplayLODIndex].displayFaceSize, DrawElementsType.UnsignedInt, m.Offset);
|
||||
}
|
||||
|
||||
shader.DisableVertexAttributes();
|
||||
shader.Disable();
|
||||
}
|
||||
|
||||
public void UpdateShaders()
|
||||
{
|
||||
if (ShaderPrograms.Count > 0) return;
|
||||
|
||||
foreach (var file in ResFileNode.IFileInfo.ArchiveParent.Files) {
|
||||
if (Utils.GetExtension(file.FileName) == ".sharc")
|
||||
{
|
||||
var fileFormat = file.OpenFile();
|
||||
if (fileFormat != null && fileFormat is SHARC) {
|
||||
ShaderPrograms.AddRange(LoadProgram((SHARC)fileFormat));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<SHShaderProgram> LoadProgram(SHARC sharc)
|
||||
{
|
||||
List<SHShaderProgram> programs = new List<SHShaderProgram>();
|
||||
foreach (var program in sharc.header.ShaderPrograms)
|
||||
programs.Add(new SHShaderProgram(sharc.header, program));
|
||||
|
||||
return programs;
|
||||
}
|
||||
|
||||
static bool Loaded = false;
|
||||
public override void UpdateVertexData()
|
||||
{
|
||||
if (!Runtime.OpenTKInitialized)
|
||||
return;
|
||||
|
||||
UpdateShaders();
|
||||
UpdateModelList();
|
||||
Loaded = false;
|
||||
|
||||
DisplayVertex[] Vertices;
|
||||
int[] Faces;
|
||||
|
||||
int poffset = 0;
|
||||
int voffset = 0;
|
||||
List<DisplayVertex> Vs = new List<DisplayVertex>();
|
||||
List<int> Ds = new List<int>();
|
||||
|
||||
int TotalShapeCount = models.Sum(b => b.shapes.Count);
|
||||
|
||||
int value = 0;
|
||||
|
||||
for (int m = 0; m < models.Count; m++)
|
||||
{
|
||||
//Reset min/max
|
||||
models[m].MaxPosition = new Vector3(0);
|
||||
models[m].MinPosition = new Vector3(0);
|
||||
|
||||
for (int shp = 0; shp < models[m].shapes.Count; shp++)
|
||||
{
|
||||
//Update render pass aswell
|
||||
//CheckRenderPass(models[m].shapes[shp].GetFMAT());
|
||||
|
||||
models[m].shapes[shp].Offset = poffset * 4;
|
||||
List<DisplayVertex> pv = CreateDisplayVertices(models[m], models[m].shapes[shp]);
|
||||
Vs.AddRange(pv);
|
||||
|
||||
for (int i = 0; i < models[m].shapes[shp].lodMeshes[models[m].shapes[shp].DisplayLODIndex].displayFaceSize; i++)
|
||||
{
|
||||
Ds.Add(models[m].shapes[shp].display[i] + voffset);
|
||||
}
|
||||
poffset += models[m].shapes[shp].lodMeshes[models[m].shapes[shp].DisplayLODIndex].displayFaceSize;
|
||||
voffset += pv.Count;
|
||||
}
|
||||
}
|
||||
|
||||
// Binds
|
||||
Vertices = Vs.ToArray();
|
||||
Faces = Ds.ToArray();
|
||||
|
||||
// Bind only once!
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_position);
|
||||
GL.BufferData<DisplayVertex>(BufferTarget.ArrayBuffer, (IntPtr)(Vertices.Length * DisplayVertex.Size), Vertices, BufferUsageHint.StaticDraw);
|
||||
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo_elements);
|
||||
GL.BufferData<int>(BufferTarget.ElementArrayBuffer, (IntPtr)(Faces.Length * sizeof(int)), Faces, BufferUsageHint.StaticDraw);
|
||||
|
||||
LibraryGUI.UpdateViewport();
|
||||
|
||||
Loaded = true;
|
||||
}
|
||||
|
||||
static List<DisplayVertex> CreateDisplayVertices(FMDL model, FSHP mesh)
|
||||
{
|
||||
// rearrange faces
|
||||
mesh.display = mesh.lodMeshes[mesh.DisplayLODIndex].getDisplayFace().ToArray();
|
||||
|
||||
List<DisplayVertex> displayVertList = new List<DisplayVertex>();
|
||||
|
||||
if (mesh.lodMeshes[mesh.DisplayLODIndex].faces.Count <= 3)
|
||||
return displayVertList;
|
||||
|
||||
foreach (Vertex v in mesh.vertices)
|
||||
{
|
||||
model.MaxPosition = OpenGLUtils.GetMax(model.MaxPosition, v.pos);
|
||||
model.MinPosition = OpenGLUtils.GetMin(model.MinPosition, v.pos);
|
||||
|
||||
DisplayVertex displayVert = new DisplayVertex()
|
||||
{
|
||||
Position = v.pos,
|
||||
Normal = v.nrm,
|
||||
Color0 = v.col,
|
||||
Color1 = v.col2,
|
||||
TexCoord0 = v.uv0,
|
||||
TexCoord1 = v.uv1,
|
||||
TexCoord2 = v.uv2,
|
||||
BlendIndex = new Vector4(
|
||||
v.boneIds.Count > 0 ? v.boneIds[0] : -1,
|
||||
v.boneIds.Count > 1 ? v.boneIds[1] : -1,
|
||||
v.boneIds.Count > 2 ? v.boneIds[2] : -1,
|
||||
v.boneIds.Count > 3 ? v.boneIds[3] : -1),
|
||||
BlendWeight = new Vector4(
|
||||
v.boneWeights.Count > 0 ? v.boneWeights[0] : 0,
|
||||
v.boneWeights.Count > 1 ? v.boneWeights[1] : 0,
|
||||
v.boneWeights.Count > 2 ? v.boneWeights[2] : 0,
|
||||
v.boneWeights.Count > 3 ? v.boneWeights[3] : 0),
|
||||
};
|
||||
|
||||
displayVertList.Add(displayVert);
|
||||
}
|
||||
|
||||
return displayVertList;
|
||||
}
|
||||
|
||||
public void UpdateSingleMaterialTextureMaps(FMAT mat)
|
||||
{
|
||||
if (!Runtime.OpenTKInitialized)
|
||||
return;
|
||||
|
||||
foreach (BNTX bntx in PluginRuntime.bntxContainers)
|
||||
{
|
||||
foreach (var t in mat.TextureMaps)
|
||||
{
|
||||
if (bntx.Textures.ContainsKey(t.Name))
|
||||
{
|
||||
if (!bntx.Textures[t.Name].RenderableTex.GLInitialized)
|
||||
bntx.Textures[t.Name].LoadOpenGLTexture();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LibraryGUI.UpdateViewport();
|
||||
}
|
||||
public void UpdateTextureMaps()
|
||||
{
|
||||
if (!Runtime.OpenTKInitialized)
|
||||
return;
|
||||
|
||||
foreach (BNTX bntx in PluginRuntime.bntxContainers)
|
||||
{
|
||||
if (!bntx.AllGLInitialized)
|
||||
{
|
||||
foreach (var tex in bntx.Textures)
|
||||
{
|
||||
if (tex.Value.RenderableTex != null && !tex.Value.RenderableTex.GLInitialized)
|
||||
tex.Value.LoadOpenGLTexture();
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (BFRESGroupNode ftexCont in PluginRuntime.ftexContainers)
|
||||
{
|
||||
foreach (var tex in ftexCont.ResourceNodes)
|
||||
{
|
||||
if (!((FTEX)tex.Value).RenderableTex.GLInitialized)
|
||||
((FTEX)tex.Value).LoadOpenGLTexture();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetRenderPass(FMAT mat)
|
||||
{
|
||||
bool NoCull = false;
|
||||
bool CullBack = false;
|
||||
bool CullFront = false;
|
||||
|
||||
for (int i = 0; i < mat.renderinfo.Count; i++)
|
||||
{
|
||||
if (mat.renderinfo[i].Name == "display_face")
|
||||
{
|
||||
NoCull = mat.renderinfo[i].ValueString.Contains("both");
|
||||
CullFront = mat.renderinfo[i].ValueString.Contains("back");
|
||||
CullBack = mat.renderinfo[i].ValueString.Contains("front");
|
||||
}
|
||||
|
||||
if (mat.shaderassign.ShaderArchive == "Turbo_UBER")
|
||||
{
|
||||
AglShaderTurbo aglShader = new AglShaderTurbo();
|
||||
aglShader.LoadRenderInfo(mat.renderinfo[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (NoCull)
|
||||
{
|
||||
GL.Disable(EnableCap.CullFace);
|
||||
}
|
||||
else if (CullFront)
|
||||
{
|
||||
GL.Enable(EnableCap.CullFace);
|
||||
GL.CullFace(CullFaceMode.Front);
|
||||
}
|
||||
else if (CullBack)
|
||||
{
|
||||
GL.Enable(EnableCap.CullFace);
|
||||
GL.CullFace(CullFaceMode.Back);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CheckRenderPass(FMAT mat)
|
||||
{
|
||||
if (mat.ImageKey != "material")
|
||||
{
|
||||
mat.ImageKey = "material";
|
||||
mat.SelectedImageKey = "material";
|
||||
}
|
||||
|
||||
bool IsTranslucent = false;
|
||||
bool IsTransparentMask = false;
|
||||
|
||||
|
||||
for (int i = 0; i < mat.renderinfo.Count; i++)
|
||||
{
|
||||
if (mat.renderinfo[i].Name == "gsys_render_state_mode")
|
||||
{
|
||||
IsTranslucent = mat.renderinfo[i].ValueString.Contains("translucent");
|
||||
IsTransparentMask = mat.renderinfo[i].ValueString.Contains("mask");
|
||||
}
|
||||
if (mat.renderinfo[i].Name == "renderPass")
|
||||
{
|
||||
IsTransparentMask = mat.renderinfo[i].ValueString.Contains("xlu");
|
||||
}
|
||||
}
|
||||
|
||||
if (mat.shaderassign.options.ContainsKey("enable_translucent"))
|
||||
IsTranslucent = mat.shaderassign.options["enable_translucent"] == "1";
|
||||
if (mat.shaderassign.options.ContainsKey("enable_translucent"))
|
||||
IsTransparentMask = mat.shaderassign.options["enable_transparent"] == "1";
|
||||
|
||||
if (mat.MaterialU != null)
|
||||
{
|
||||
IsTranslucent = mat.MaterialU.RenderState.FlagsMode == ResU.RenderStateFlagsMode.Translucent;
|
||||
IsTransparentMask = mat.MaterialU.RenderState.FlagsMode == ResU.RenderStateFlagsMode.AlphaMask;
|
||||
}
|
||||
|
||||
mat.isTransparent = IsTransparentMask || IsTranslucent;
|
||||
|
||||
SetMaterialIcon(mat, IsTranslucent, "MaterialTranslucent");
|
||||
SetMaterialIcon(mat, IsTransparentMask, "MaterialTransparent");
|
||||
}
|
||||
|
||||
private static void SetMaterialIcon(FMAT mat, bool IsEffect, string Key)
|
||||
{
|
||||
if (IsEffect)
|
||||
{
|
||||
mat.ImageKey = Key;
|
||||
mat.SelectedImageKey = Key;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetUniforms(FMAT mat, SHShaderProgram shader, FSHP m, int id)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private static void SetUniformData(FMAT mat, SHShaderProgram shader, string propertyName)
|
||||
{
|
||||
if (mat.shaderassign.options.ContainsKey(propertyName))
|
||||
{
|
||||
float value = float.Parse(mat.shaderassign.options[propertyName]);
|
||||
shader.SetFloat(propertyName, value);
|
||||
}
|
||||
if (mat.matparam.ContainsKey(propertyName))
|
||||
{
|
||||
if (mat.matparam[propertyName].Type == ShaderParamType.Float)
|
||||
{
|
||||
if (mat.anims.ContainsKey(propertyName))
|
||||
mat.matparam[propertyName].ValueFloat[0] = mat.anims[propertyName][0];
|
||||
shader.SetFloat(propertyName, mat.matparam[propertyName].ValueFloat[0]);
|
||||
}
|
||||
|
||||
if (mat.matparam[propertyName].Type == ShaderParamType.Float2)
|
||||
{
|
||||
if (mat.anims.ContainsKey(propertyName))
|
||||
{
|
||||
mat.matparam[propertyName].ValueFloat = new float[2] {
|
||||
mat.anims[propertyName][0], mat.anims[propertyName][1]};
|
||||
}
|
||||
|
||||
shader.SetVec2(propertyName, Utils.ToVec2(mat.matparam[propertyName].ValueFloat));
|
||||
}
|
||||
|
||||
if (mat.matparam[propertyName].Type == ShaderParamType.Float3)
|
||||
{
|
||||
if (mat.anims.ContainsKey(propertyName))
|
||||
{
|
||||
mat.matparam[propertyName].ValueFloat = new float[3] {
|
||||
mat.anims[propertyName][0],
|
||||
mat.anims[propertyName][1],
|
||||
mat.anims[propertyName][2]};
|
||||
}
|
||||
|
||||
shader.SetVec3(propertyName, Utils.ToVec3(mat.matparam[propertyName].ValueFloat));
|
||||
}
|
||||
if (mat.matparam[propertyName].Type == ShaderParamType.Float4)
|
||||
{
|
||||
if (mat.anims.ContainsKey(propertyName))
|
||||
{
|
||||
mat.matparam[propertyName].ValueFloat = new float[4] {
|
||||
mat.anims[propertyName][0], mat.anims[propertyName][1],
|
||||
mat.anims[propertyName][2], mat.anims[propertyName][3]};
|
||||
}
|
||||
|
||||
shader.SetVec4(propertyName, Utils.ToVec4(mat.matparam[propertyName].ValueFloat));
|
||||
}
|
||||
if (mat.matparam[propertyName].Type == ShaderParamType.TexSrt)
|
||||
{
|
||||
// Vector 2 Scale
|
||||
// 1 roation float
|
||||
// Vector2 translate
|
||||
TexSrt texSRT = mat.matparam[propertyName].ValueTexSrt;
|
||||
|
||||
shader.SetVec2("SRT_Scale", Utils.ToVec2(texSRT.Scaling));
|
||||
shader.SetFloat("SRT_Rotate", texSRT.Rotation);
|
||||
shader.SetVec2("SRT_Translate", Utils.ToVec2(texSRT.Translation));
|
||||
}
|
||||
|
||||
//MTA SRT
|
||||
if (propertyName == "texsrt0" && mat.shaderassign.ShaderArchive == "ssg")
|
||||
{
|
||||
TexSrt texSRT = mat.matparam[propertyName].ValueTexSrt;
|
||||
|
||||
shader.SetVec2("SRT_Scale", Utils.ToVec2(texSRT.Scaling));
|
||||
shader.SetFloat("SRT_Rotate", texSRT.Rotation);
|
||||
shader.SetVec2("SRT_Translate", Utils.ToVec2(texSRT.Translation));
|
||||
}
|
||||
}
|
||||
|
||||
if (mat.animatedMatParams.ContainsKey(propertyName))
|
||||
{
|
||||
if (mat.animatedMatParams[propertyName].Type == ShaderParamType.Float)
|
||||
{
|
||||
if (mat.anims.ContainsKey(propertyName))
|
||||
mat.animatedMatParams[propertyName].ValueFloat[0] = mat.anims[propertyName][0];
|
||||
shader.SetFloat(propertyName, mat.animatedMatParams[propertyName].ValueFloat[0]);
|
||||
}
|
||||
|
||||
if (mat.animatedMatParams[propertyName].Type == ShaderParamType.Float2)
|
||||
{
|
||||
if (mat.anims.ContainsKey(propertyName))
|
||||
{
|
||||
mat.animatedMatParams[propertyName].ValueFloat = new float[2] {
|
||||
mat.anims[propertyName][0], mat.anims[propertyName][1]};
|
||||
}
|
||||
|
||||
shader.SetVec2(propertyName, Utils.ToVec2(mat.animatedMatParams[propertyName].ValueFloat));
|
||||
}
|
||||
|
||||
if (mat.animatedMatParams[propertyName].Type == ShaderParamType.Float3)
|
||||
{
|
||||
Console.WriteLine(propertyName + " " + mat.animatedMatParams[propertyName].ValueFloat);
|
||||
|
||||
if (mat.anims.ContainsKey(propertyName))
|
||||
{
|
||||
mat.animatedMatParams[propertyName].ValueFloat = new float[3] {
|
||||
mat.anims[propertyName][0],
|
||||
mat.anims[propertyName][1],
|
||||
mat.anims[propertyName][2]};
|
||||
}
|
||||
|
||||
shader.SetVec3(propertyName, Utils.ToVec3(mat.animatedMatParams[propertyName].ValueFloat));
|
||||
}
|
||||
if (mat.animatedMatParams[propertyName].Type == ShaderParamType.Float4)
|
||||
{
|
||||
if (mat.anims.ContainsKey(propertyName))
|
||||
{
|
||||
mat.animatedMatParams[propertyName].ValueFloat = new float[4] {
|
||||
mat.anims[propertyName][0], mat.anims[propertyName][1],
|
||||
mat.anims[propertyName][2], mat.anims[propertyName][3]};
|
||||
}
|
||||
|
||||
shader.SetVec4(propertyName, Utils.ToVec4(mat.animatedMatParams[propertyName].ValueFloat));
|
||||
}
|
||||
|
||||
if (mat.animatedMatParams[propertyName].Type == ShaderParamType.TexSrt)
|
||||
{
|
||||
// Vector 2 Scale
|
||||
// 1 roation float
|
||||
// Vector2 translate
|
||||
TexSrt texSRT = mat.animatedMatParams[propertyName].ValueTexSrt;
|
||||
|
||||
shader.SetVec2("SRT_Scale", Utils.ToVec2(texSRT.Scaling));
|
||||
shader.SetFloat("SRT_Rotate", texSRT.Rotation);
|
||||
shader.SetVec2("SRT_Translate", Utils.ToVec2(texSRT.Translation));
|
||||
}
|
||||
}
|
||||
}
|
||||
private void SetVertexAttributes(FSHP m, SHShaderProgram shader)
|
||||
{
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_position);
|
||||
GL.VertexAttribPointer(shader.GetAttribute("aPosition"), 3, VertexAttribPointerType.Float, false, DisplayVertex.Size, 0);
|
||||
GL.VertexAttribPointer(shader.GetAttribute("aNormal"), 3, VertexAttribPointerType.Float, false, DisplayVertex.Size, 12);
|
||||
GL.VertexAttribPointer(shader.GetAttribute("aBlendWeight"), 4, VertexAttribPointerType.Float, false, DisplayVertex.Size, 24);
|
||||
GL.VertexAttribIPointer(shader.GetAttribute("aBlendIndex"), 4, VertexAttribIntegerType.Int, DisplayVertex.Size, new IntPtr(40));
|
||||
GL.VertexAttribPointer(shader.GetAttribute("aTexCoord0"), 2, VertexAttribPointerType.Float, false, DisplayVertex.Size, 56);
|
||||
GL.VertexAttribPointer(shader.GetAttribute("aTexCoord1"), 2, VertexAttribPointerType.Float, false, DisplayVertex.Size, 64);
|
||||
GL.VertexAttribPointer(shader.GetAttribute("aTexCoord2"), 2, VertexAttribPointerType.Float, false, DisplayVertex.Size, 72);
|
||||
GL.VertexAttribPointer(shader.GetAttribute("aTexCoord3"), 2, VertexAttribPointerType.Float, false, DisplayVertex.Size, 80);
|
||||
GL.VertexAttribPointer(shader.GetAttribute("aTexCoord4"), 2, VertexAttribPointerType.Float, false, DisplayVertex.Size, 88);
|
||||
GL.VertexAttribPointer(shader.GetAttribute("aTexCoord5"), 2, VertexAttribPointerType.Float, false, DisplayVertex.Size, 96);
|
||||
GL.VertexAttribPointer(shader.GetAttribute("aTexCoord6"), 2, VertexAttribPointerType.Float, false, DisplayVertex.Size, 104);
|
||||
GL.VertexAttribPointer(shader.GetAttribute("aTexCoord7"), 2, VertexAttribPointerType.Float, false, DisplayVertex.Size, 112);
|
||||
GL.VertexAttribPointer(shader.GetAttribute("aColor0"), 4, VertexAttribPointerType.Float, false, DisplayVertex.Size, 120);
|
||||
GL.VertexAttribPointer(shader.GetAttribute("aColor1"), 4, VertexAttribPointerType.Float, false, DisplayVertex.Size, 136);
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo_elements);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
37
File_Format_Library/GL/BFRES/RedPro/ShaderProgram.cs
Normal file
37
File_Format_Library/GL/BFRES/RedPro/ShaderProgram.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Toolbox.Library;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
using OpenTK;
|
||||
using Bfres.Structs;
|
||||
using Toolbox.Library.IO;
|
||||
|
||||
namespace FirstPlugin.RedPro
|
||||
{
|
||||
public class SHShaderProgram : GLShaderGeneric
|
||||
{
|
||||
public SHARC.Header ShaderArchive { get; set; }
|
||||
public SHARC.ShaderProgram Program { get; set; }
|
||||
|
||||
public SHShaderProgram(SHARC.Header shader, SHARC.ShaderProgram program)
|
||||
{
|
||||
ShaderArchive = shader;
|
||||
Program = program;
|
||||
|
||||
this.Compile();
|
||||
}
|
||||
|
||||
public bool IsLinked(string shaderArchive, string shaderProgram)
|
||||
{
|
||||
return (ShaderArchive.Name == shaderArchive.Replace(" ", string.Empty) && Program.Text.Replace(" ", string.Empty) == shaderProgram);
|
||||
}
|
||||
|
||||
public void LoadUniforms(FMDL fmdl, FSHP shp, STSkeleton skeleton, GL_EditorFramework.GL_Core.GL_ControlBase control)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -136,7 +136,7 @@ namespace FirstPlugin.Forms
|
||||
return null;
|
||||
}
|
||||
|
||||
public void FrameCamera(BFRESRender Renderer)
|
||||
public void FrameCamera(BFRESRenderBase Renderer)
|
||||
{
|
||||
if (!Runtime.UseOpenGL || !DisplayViewport)
|
||||
return;
|
||||
|
@ -345,7 +345,6 @@ namespace FirstPlugin
|
||||
Formats.Add(typeof(BTI));
|
||||
Formats.Add(typeof(TXE));
|
||||
Formats.Add(typeof(SARC));
|
||||
Formats.Add(typeof(BCRES));
|
||||
Formats.Add(typeof(BNTX));
|
||||
Formats.Add(typeof(BEA));
|
||||
Formats.Add(typeof(BYAML));
|
||||
@ -445,6 +444,7 @@ namespace FirstPlugin
|
||||
Formats.Add(typeof(NLG_NLOC));
|
||||
Formats.Add(typeof(PCK));
|
||||
Formats.Add(typeof(NLG.StrikersSAnim));
|
||||
Formats.Add(typeof(CtrLibrary.BCH));
|
||||
|
||||
|
||||
|
||||
|
@ -16,6 +16,7 @@ namespace Toolbox.Library
|
||||
private int vertexShaderID;
|
||||
private int fragmentShaderID;
|
||||
|
||||
private Dictionary<string, int> uniformBlocks = new Dictionary<string, int>();
|
||||
private Dictionary<string, int> attributes = new Dictionary<string, int>();
|
||||
private Dictionary<string, int> uniforms = new Dictionary<string, int>();
|
||||
private int activeAttributeCount;
|
||||
@ -66,18 +67,32 @@ namespace Toolbox.Library
|
||||
{
|
||||
if (uniforms.ContainsKey(name))
|
||||
GL.Uniform4(uniforms[name], value);
|
||||
else
|
||||
Console.WriteLine("Could not find vec4 " + name);
|
||||
}
|
||||
|
||||
public void SetVec3(string name, Vector3 value)
|
||||
{
|
||||
if (uniforms.ContainsKey(name))
|
||||
GL.Uniform3(uniforms[name], value);
|
||||
else
|
||||
Console.WriteLine("Could not find vec3 " + name);
|
||||
}
|
||||
|
||||
public void SetVec2(string name, Vector2 value)
|
||||
{
|
||||
if (uniforms.ContainsKey(name))
|
||||
GL.Uniform2(uniforms[name], value);
|
||||
else
|
||||
Console.WriteLine("Could not find vec2 " + name);
|
||||
}
|
||||
|
||||
public void SetFloat(string name, float value)
|
||||
{
|
||||
if (uniforms.ContainsKey(name))
|
||||
GL.Uniform1(uniforms[name], value);
|
||||
else
|
||||
Console.WriteLine("Could not find float " + name);
|
||||
}
|
||||
|
||||
public void SetInt(string name, int value)
|
||||
@ -106,6 +121,50 @@ namespace Toolbox.Library
|
||||
GL.UniformMatrix4(uniforms[name], false, ref value);
|
||||
}
|
||||
|
||||
public void LoadLayout(string name)
|
||||
{
|
||||
if (!uniformBlocks.ContainsKey(name)) {
|
||||
//Get block indices
|
||||
var uniformID = GL.GetUniformBlockIndex(program, name);
|
||||
|
||||
//Link them
|
||||
GL.UniformBlockBinding(program, uniformID, 0);
|
||||
|
||||
int buffer;
|
||||
GL.GenBuffers(1, out buffer);
|
||||
uniformBlocks.Add(name, buffer);
|
||||
|
||||
var dataValues = new Vector4[3]
|
||||
{
|
||||
new Vector4(1, 0, 0, 0),
|
||||
new Vector4(0, 1, 0, 0),
|
||||
new Vector4(0, 0, 1, 0)
|
||||
};
|
||||
|
||||
var totalSize = (Vector3.SizeInBytes + 4) * dataValues.Length; //Add 4 for alignment
|
||||
|
||||
GL.BindBuffer(BufferTarget.UniformBuffer, buffer);
|
||||
GL.BufferData(BufferTarget.UniformBuffer,
|
||||
totalSize,
|
||||
IntPtr.Zero,
|
||||
BufferUsageHint.StaticDraw);
|
||||
GL.BindBuffer(BufferTarget.UniformBuffer, 0);
|
||||
|
||||
// define the range of the buffer that links to a uniform binding point
|
||||
GL.BindBufferRange(BufferRangeTarget.UniformBuffer, 0, buffer,
|
||||
IntPtr.Zero, totalSize);
|
||||
|
||||
GL.BindBuffer(BufferTarget.UniformBuffer, buffer);
|
||||
GL.BufferSubData<Vector4>(BufferTarget.UniformBuffer, IntPtr.Zero, (Vector3.SizeInBytes + 4) * dataValues.Length, dataValues); //Add 4 for alignment
|
||||
GL.BindBuffer(BufferTarget.UniformBuffer, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void GetAttribLocation()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public int this[string name]
|
||||
{
|
||||
get { return uniforms[name]; }
|
||||
|
@ -28,8 +28,9 @@ vec3 SpecularPass(vec3 I, vec3 normal, int HasSpecularMap, sampler2D SpecularMap
|
||||
float specBrdf = max(dot(I, normal), 0);
|
||||
float exponent = 8;
|
||||
|
||||
if (SpecColor == vec3(0)) //Color shouldn't be black unless it's not set
|
||||
SpecColor = vec3(1);
|
||||
vec3 specularColor = SpecColor;
|
||||
if (specularColor == vec3(0)) //Color shouldn't be black unless it's not set
|
||||
specularColor = vec3(1);
|
||||
|
||||
if (HasSpecularMap == 0)
|
||||
{
|
||||
@ -51,7 +52,7 @@ vec3 SpecularPass(vec3 I, vec3 normal, int HasSpecularMap, sampler2D SpecularMap
|
||||
result *= SpecColor.rgb;
|
||||
|
||||
float intensity = 0.3;
|
||||
return result * intensity;
|
||||
return result * vec3(intensity);
|
||||
}
|
||||
|
||||
vec3 EmissionPass(sampler2D EmissionMap, float emission_intensity, VertexAttributes vert, float texCoordIndex, vec3 emission_color)
|
||||
|
Loading…
Reference in New Issue
Block a user