public override void ReloadRenderState(BfresMeshAsset mesh) { var mat = mesh.Shape.Material; //Set custom priority value if (mat.Material.RenderInfos.ContainsKey("sort_priority")) { int priority = (int)mat.GetRenderInfo("sort_priority"); mesh.Priority = -priority; } if (mat.Material.RenderInfos.ContainsKey("draw_buffer_type")) { int type = (int)mat.GetRenderInfo("draw_buffer_type"); switch (type) { case 4: mat.BlendState.BlendColor = true; mat.IsTransparent = true; mat.BlendState.State = GLMaterialBlendState.BlendState.Mask; mesh.Pass = Pass.TRANSPARENT; break; } } }
public override void ReloadProgram(BfresMeshAsset mesh) { ProgramPasses.Clear(); var mat = mesh.Shape.Material; //Find index via option choices Dictionary <string, string> options = new Dictionary <string, string>(); foreach (var op in mat.Material.ShaderAssign.ShaderOptions) { options.Add(op.Key, op.Value); } //Update option from render state this.LoadRenderStateOptions(options, mat); //Dynamic options. options["cSkinWeightNum"] = mesh.Shape.VertexSkinCount.ToString(); options.Add("system_id", "0"); int programIndex = ShaderModel.GetProgramIndex(options); if (programIndex == -1) { return; } this.ProgramPasses.Add(ShaderModel.GetShaderProgram(programIndex)); }
public override void ReloadRenderState(BfresMeshAsset mesh) { var mat = mesh.Shape.Material; if (mat.GetRenderInfo("gsys_static_depth_shadow_only") == "1") { mesh.IsDepthShadow = true; } if (mat.GetRenderInfo("gsys_pass") == "seal") { mesh.IsSealPass = true; } if (mat.GetRenderInfo("gsys_cube_map_only") == "1") { mesh.IsCubeMap = true; } if (mat.GetRenderInfo("gsys_cube_map") == "1") { mesh.RenderInCubeMap = true; } if (mat.Material.ShaderAssign.ShaderOptions["gsys_enable_color_buffer"] == "1") { mesh.UseColorBufferPass = true; } mesh.Priority = mat.GetRenderInfo("gsys_priority"); }
private void DrawSolidColorMesh(GLFrameworkEngine.ShaderProgram shader, BfresMeshAsset mesh) { if (!mesh.IsVisible) { return; } if (mesh.SkinCount > 0) { SetModelMatrix(shader.program, ModelData.Skeleton, mesh.SkinCount > 1); } var worldTransform = ParentRender.Transform.TransformMatrix; var transform = this.ModelData.Skeleton.Bones[mesh.BoneIndex].Transform; shader.SetMatrix4x4("RigidBindTransform", ref transform); shader.SetMatrix4x4("mtxMdl", ref worldTransform); shader.SetInt("SkinCount", mesh.SkinCount); shader.SetInt("UseSkinning", 1); //Draw the mesh mesh.defaultVao.Enable(shader); mesh.defaultVao.Use(); mesh.Draw(); }
public override void ReloadRenderState(BfresMeshAsset mesh) { if (mesh.Shape.Material.ShaderArchive == "RenderMaterialAlphaMask") { mesh.Shape.Material.BlendState.State = GLMaterialBlendState.BlendState.Mask; } }
public override void ReloadRenderState(BfresMeshAsset mesh) { var mat = mesh.Material as FMAT; if (mat.GetRenderInfo("blendEnabled") == 1) { mat.BlendState.BlendColor = true; mat.IsTransparent = true; mat.BlendState.State = GLMaterialBlendState.BlendState.Translucent; mesh.Pass = Pass.TRANSPARENT; } mesh.Pass = Pass.OPAQUE; bool cullBoth = mat.GetRenderInfo("cullMode") == "both"; mat.CullBack = mat.GetRenderInfo("cullMode") == "back" || cullBoth; mat.CullFront = mat.GetRenderInfo("cullMode") == "front" || cullBoth; mat.BlendState.DepthTest = mat.GetRenderInfo("depthTestEnabled") == 1; mat.BlendState.DepthWrite = mat.GetRenderInfo("depthWriteEnabled") == 1; if (mat.GetRenderInfo("depthComparisonFunction") == "always") { mat.BlendState.DepthFunction = DepthFunction.Always; } //Todo, stencil testing if (mat.GetRenderInfo("stencilTestEnabled") == 1) { } }
public override void ReloadRenderState(BfresMeshAsset mesh) { var mat = mesh.Shape.Material; //Set custom priority value NSMBU uses if (mat.Material.RenderInfos.ContainsKey("priority")) { int sharc_priority = (int)mat.GetRenderInfo("priority"); mesh.Priority = (int)(sharc_priority * 0x10000 + (uint)mesh.Shape.Shape.MaterialIndex); } string polygonOffset = mat.GetRenderInfo("polygon_offset"); //Offset polygons if (polygonOffset != null && polygonOffset.Contains("yes")) { mesh.IsSealPass = true; } if (mat.GetRenderInfo("shadow_cast") == "shadow-only") { mesh.IsDepthShadow = true; } if (mat.GetRenderInfo("reflection") == "reflection-only") { mesh.Shape.IsVisible = false; } }
public override void ReloadRenderState(BfresMeshAsset mesh) { var mat = mesh.Shape.Material; if (mat.Material.ShaderAssign.ShaderOptions["cRenderType"] == "3") { mesh.UseColorBufferPass = true; } if (mat.Material.ShaderAssign.ShaderOptions["cRenderType"] != "0") { mat.BlendState.State = GLMaterialBlendState.BlendState.Translucent; mat.BlendState.BlendColor = true; mat.IsTransparent = true; mesh.Pass = Pass.TRANSPARENT; } mesh.IsSealPass = mat.GetRenderInfo("enable_polygon_offset") == "true"; mat.BlendState.DepthTest = mat.GetRenderInfo("enable_depth_test") == "true"; mat.BlendState.DepthWrite = mat.GetRenderInfo("enable_depth_write") == "true"; string displayFace = mat.GetRenderInfo("display_face"); switch (displayFace) { case "front": mat.CullState = FMAT.CullMode.Back; break; case "back": mat.CullState = FMAT.CullMode.Front; break; case "both": mat.CullState = FMAT.CullMode.None; break; case "none": mat.CullState = FMAT.CullMode.Both; break; } }
private void DrawCustomShaderRender(GLContext control, BfresMeshAsset mesh, int stage = 0) { var materialAsset = ((ShaderRenderBase)mesh.MaterialAsset); if (!materialAsset.HasValidProgram) { //Draw the mesh as solid color var solidRender = GLFrameworkEngine.GlobalShaders.GetShader("PICKING"); control.CurrentShader = solidRender; solidRender.SetVector4("color", new Vector4(1, 0, 0, 1)); DrawSolidColorMesh(control.CurrentShader, mesh); return; } materialAsset.ShaderIndex = stage; materialAsset.CheckProgram(control, mesh, stage); if (control.CurrentShader != materialAsset.Shader) { control.CurrentShader = materialAsset.Shader; } mesh.MaterialAsset.Render(control, materialAsset.Shader, mesh); //Draw the mesh mesh.vao.Enable(materialAsset.Shader); mesh.Render(control, materialAsset.Shader); }
/// <summary> /// A helper method to set a common shape block layout. /// Note not all games use the same shape block data! /// </summary> public virtual void SetShapeBlock(BfresMeshAsset mesh, Matrix4 transform, UniformBlock block) { int numSkinning = (int)mesh.SkinCount; block.Buffer.Clear(); block.Add(transform.Column0); block.Add(transform.Column1); block.Add(transform.Column2); block.AddInt(numSkinning); }
public void DrawDebug(GLContext control, BfresMeshAsset mesh) { if (Runtime.DebugRendering != Runtime.DebugRender.Diffuse) { control.UseSRBFrameBuffer = false; } DebugShaderRender.RenderMaterial(control); DrawSolidColorMesh(control.CurrentShader, mesh); }
public override void ReloadProgram(BfresMeshAsset mesh) { ProgramPasses.Clear(); //Keep things simple and add all the programs (game does not rely on variations) for (int i = 0; i < ShaderModel.ProgramCount; i++) { this.ProgramPasses.Add(ShaderModel.GetShaderProgram(i)); } }
public override void LoadMesh(BfresMeshAsset mesh) { base.LoadMesh(mesh); if (ShaderFileState == ShaderState.Global) { mesh.Shape.UpdateVertexBuffer(true); mesh.UpdateVertexBuffer(); } }
public override void ReloadProgram(BfresMeshAsset mesh) { ProgramPasses.Clear(); var mat = mesh.Shape.Material; //Find index via option choices Dictionary <string, string> options = new Dictionary <string, string>(); foreach (var op in mat.ShaderOptions) { options.Add(op.Key, op.Value); } if (!options.ContainsKey("gsys_alpha_test_enable")) { options.Add("gsys_alpha_test_enable", "0"); } if (!options.ContainsKey("gsys_alpha_test_func")) { options.Add("gsys_alpha_test_func", "6"); } //Update option from render state this.LoadRenderStateOptions(options, mat); //Dynamic options. options.Add("gsys_weight", mesh.Shape.VertexSkinCount.ToString()); options.Add("gsys_assign_type", "gsys_assign_material"); options.Add("system_id", "0"); options.Add("gsys_index_stream_format", "0"); Console.WriteLine($"Reloading Shader Program {mesh.Name}"); //The assign type has it's own set of programs for different passes foreach (var option in ShaderModel.DynamiOptions[2].ChoiceDict.GetKeys()) { if (string.IsNullOrEmpty(option)) { continue; } options["gsys_assign_type"] = option; int programIndex = ShaderModel.GetProgramIndex(options); if (programIndex == -1) { Console.WriteLine($"Failed to find program! {mesh.Name}"); continue; } this.ProgramPasses.Add(ShaderModel.GetShaderProgram(programIndex)); } }
/// <summary> /// Checks if the program needs to be reloaded from a change in shader pass. /// </summary> public override void CheckProgram(GLContext control, BfresMeshAsset mesh, int pass = 0) { if (ShaderModel == null) { return; } if (Shader == null || UpdateShader) { ReloadGLSLShaderFile(); } }
/// <summary> /// Loads the material renderer for the first time. /// </summary> /// <returns></returns> public override void TryLoadShader(BFRES bfres, FMDL fmdl, FSHP mesh, BfresMeshAsset meshAsset) { var sharcfb = TryLoadShaderArchive(bfres, mesh.Material.ShaderArchive, mesh.Material.ShaderModel); if (sharcfb == null) { return; } OnLoad(sharcfb, fmdl, mesh, meshAsset); }
/// <summary> /// Checks if the program needs to be reloaded from a change in shader pass. /// </summary> public override void CheckProgram(GLContext control, BfresMeshAsset mesh, int pass = 0) { if (ProgramPasses.Count == 0) { return; } ShaderIndex = pass; if (GLShaders[pass] == null || UpdateShader) { ReloadGLSLShaderFile(ProgramPasses[pass]); } shaderProgram = GLShaders[pass].Program; }
public override void SetShapeBlock(BfresMeshAsset mesh, Matrix4 transform, UniformBlock block) { int numSkinning = (int)mesh.SkinCount; block.Buffer.Clear(); block.Add(transform.Column0); block.Add(transform.Column1); block.Add(transform.Column2); block.Add(new Vector4(numSkinning, 0, 0, 0)); block.Add(new Vector4(0)); block.Add(AreaIndex); block.Add(AreaIndex); block.Add(AreaIndex); block.Add(AreaIndex); }
/// <summary> /// Reloads the program passes to render onto. /// If the program pass list is empty, the material will not load. /// </summary> public override void ReloadProgram(BfresMeshAsset mesh) { var mat = mesh.Shape.Material; Dictionary <string, string> options = new Dictionary <string, string>(); foreach (var macro in ShaderModel.VariationMacroData.symbols) { if (mat.ShaderOptions.ContainsKey(macro.SymbolName)) { options.Add(macro.Name, mat.ShaderOptions[macro.SymbolName]); } } VariationBaseIndex = ShaderModel.GetVariationIndex(options); }
public override void ReloadProgram(BfresMeshAsset mesh) { ProgramPasses.Clear(); //Find the variation index by material options var mat = mesh.Shape.Material; //Find index via option choices Dictionary <string, string> options = new Dictionary <string, string>(); foreach (var op in mat.Material.ShaderAssign.ShaderOptions) { options.Add(op.Key, op.Value); } //Update option from render state this.LoadRenderStateOptions(options, mat); //Dynamic options. options.Add("gsys_weight", mesh.Shape.VertexSkinCount.ToString()); options.Add("gsys_assign_type", "gsys_assign_material"); options.Add("system_id", "0"); //The assign type has it's own set of programs for different passes foreach (var option in ShaderModel.DynamiOptions[1].ChoiceDict.GetKeys()) { if (string.IsNullOrEmpty(option)) { continue; } options["gsys_assign_type"] = option; if (options["gsys_assign_type"] != "gsys_assign_gbuffer") { continue; } int programIndex = ShaderModel.GetProgramIndex(options); if (programIndex == -1) { continue; } this.ProgramPasses.Add(ShaderModel.GetShaderProgram(programIndex)); } }
public override void ReloadRenderState(BfresMeshAsset mesh) { var mat = mesh.Shape.Material; if (mat.GetRenderInfo("gsys_static_depth_shadow_only") == "1") { mesh.IsDepthShadow = true; } if (mat.GetRenderInfo("gsys_pass") == "seal") { mesh.IsSealPass = true; } if (mat.GetRenderInfo("gsys_cube_map_only") == "1") { mesh.IsCubeMap = true; } }
public override void LoadMesh(BfresMeshAsset mesh) { int offset = mesh.Attributes.Sum(x => x.Stride); for (int i = 0; i < 3; i++) { if (mesh.Attributes.Any(x => x.name == $"inst{i}")) { continue; } VaoAttribute vaoAtt = new VaoAttribute(); vaoAtt.vertexAttributeName = $"inst{i}"; vaoAtt.name = $"inst{i}"; vaoAtt.ElementCount = 4; vaoAtt.Offset = offset; vaoAtt.Type = VertexAttribPointerType.Float; mesh.Attributes.Add(vaoAtt); offset += vaoAtt.Stride; } var tangentAttribute = mesh.Attributes.FirstOrDefault(x => x.name == "_t0"); if (tangentAttribute != null) { tangentAttribute.name = "tangent"; } //Tangents need to be assigned manually for some reason. if (!mesh.Attributes.Any(x => x.name == "tangent")) { VaoAttribute vaoAtt = new VaoAttribute(); vaoAtt.vertexAttributeName = $"_t0"; vaoAtt.name = $"tangent"; vaoAtt.ElementCount = 4; vaoAtt.Offset = offset; vaoAtt.Type = VertexAttribPointerType.Float; mesh.Attributes.Add(vaoAtt); offset += vaoAtt.Stride; } mesh.UpdateVertexBuffer(); }
/// <summary> /// Loads the material renderer for the first time. /// </summary> /// <returns></returns> public override void TryLoadShader(BFRES bfres, FMDL fmdl, FSHP mesh, BfresMeshAsset meshAsset) { var bfsha = TryLoadShaderArchive(bfres, mesh.Material.ShaderArchive, mesh.Material.ShaderModel); if (bfsha == null) { return; } var shaderModel = bfsha.ShaderModels.Values.FirstOrDefault(x => x.Name == mesh.Material.ShaderModel); if (shaderModel != null) { OnLoad(shaderModel, fmdl, mesh, meshAsset); } }
public override void ReloadRenderState(BfresMeshAsset mesh) { var mat = mesh.Shape.Material; if (mat.GetRenderInfo("gsys_static_depth_shadow_only") == "1") { mesh.IsDepthShadow = true; } if (mat.GetRenderInfo("gsys_pass") == "seal") { mesh.IsSealPass = true; } if (mat.GetRenderInfo("gsys_cube_map_only") == "1") { mesh.IsCubeMap = true; } if (mat.GetRenderInfo("gsys_cube_map") == "1") { mesh.RenderInCubeMap = true; } if (mat.Material.ShaderAssign.ShaderOptions["enable_color_buffer"] == "1") { mesh.UseColorBufferPass = true; } if (mat.GetRenderInfo("gsys_light_diffuse") != null) { this.LightMap = mat.GetRenderInfo("gsys_light_diffuse"); } if (mat.Name.StartsWith("CausticsArea")) { mesh.Shape.IsVisible = false; } /*if (mat.Material.ShaderAssign.ShaderOptions["enable_static_depth_shadow"] == "1") * mesh.CastStaticDepthShadow = true; * * if (mat.Material.ShaderAssign.ShaderOptions["enable_dynamic_depth_shadow"] == "1") * mesh.CastDynamicDepthShadow = true;*/ }
public void RenderMesh(GLContext control, BfresMeshAsset mesh, int stage = 0) { if (!mesh.InFrustum) { return; } if (mesh.UpdateVertexData) { mesh.UpdateVertexBuffer(); } if (Runtime.DebugRendering != Runtime.DebugRender.Default) { DrawDebug(control, mesh); return; } else if (mesh.MaterialAsset is ShaderRenderBase) { DrawCustomShaderRender(control, mesh, stage); return; } else //Draw default if not using game shader rendering. { if (!control.IsShaderActive(BfresRender.DefaultShader)) { control.CurrentShader = BfresRender.DefaultShader; } var mtxMdl = this.ParentRender.Transform.TransformMatrix; var mtxCam = control.Camera.ViewProjectionMatrix; control.CurrentShader.SetMatrix4x4("mtxMdl", ref mtxMdl); control.CurrentShader.SetMatrix4x4("mtxCam", ref mtxCam); mesh.MaterialAsset.Render(control, control.CurrentShader, mesh); DrawSolidColorMesh(control.CurrentShader, mesh); } }
public override void ReloadProgram(BfresMeshAsset mesh) { ProgramPasses.Clear(); var mat = mesh.Shape.Material; //Find index via option choices Dictionary <string, string> options = new Dictionary <string, string>(); foreach (var op in mat.ShaderOptions) { options.Add(op.Key, op.Value); } //Update option from render state this.LoadRenderStateOptions(options, mat); //Dynamic options. options["cSkinWeightNum"] = mesh.Shape.VertexSkinCount.ToString(); options.Add("enable_compose_footprint", "0"); options.Add("enable_compose_capture", "0"); options.Add("enable_add_stain_proc_texture_3d", "0"); options.Add("compose_prog_texture0", "0"); options.Add("enable_parallax_cubemap", "0"); options.Add("is_output_motion_vec", "0"); options.Add("material_lod_level", "0"); options.Add("system_id", "0"); int programIndex = ShaderModel.GetProgramIndex(options); if (programIndex == -1) { return; } this.ProgramPasses.Add(ShaderModel.GetShaderProgram(programIndex)); }
public override void ReloadProgram(BfresMeshAsset mesh) { var mat = mesh.Shape.Material; Console.WriteLine($"{mesh.Shape.ParentModel.Name} mesh {mesh.Name} VertexSkinCount {mesh.Shape.VertexSkinCount}"); Dictionary <string, string> options = new Dictionary <string, string>(); options.Add("Shader_Path", "2"); //0 = Depth, 1 = gbuffer, 2 = material, 3 = ice //Most macros are usually shader options. Convert using the symbol names that match foreach (var macro in ShaderModel.VariationMacroData.symbols) { if (macro.Name == "vtx_skin_count") { options.Add(macro.Name, macro.Values[0]); } if (mat.ShaderOptions.ContainsKey(macro.SymbolName)) { options.Add(macro.Name, mat.ShaderOptions[macro.SymbolName]); } } VariationBaseIndex = ShaderModel.GetVariationIndex(options); }
private void SetShapeUniforms(BfresMeshAsset mesh, Matrix4 mat, UniformBlock block) { block.Add(mat.Column0); block.Add(mat.Column1); block.Add(mat.Column2); }
private void ParseKeyTrack(BfresMeshAsset mesh, STAnimationTrack baseTarget, List <STAnimationTrack> tracks) { float[] weights = new float[tracks.Count]; for (int i = 0; i < tracks.Count; i++) { weights[i] = tracks[i].GetFrameValue(this.Frame); } float totalWeight = 0; foreach (float f in weights) { totalWeight += f; } float baseWeight = 1.0f - totalWeight; float total = totalWeight + baseWeight; Vector3[] morphPositions = new Vector3[mesh.Shape.Vertices.Count]; //Trasform the existing track key data for (int i = 0; i < mesh.Shape.Vertices.Count; i++) { var vertex = mesh.Shape.Vertices[i]; //Determine what vertex to morph from. if (baseTarget != null && mesh.KeyGroups.ContainsKey(baseTarget.Name)) { var keyShape = mesh.KeyGroups[baseTarget.Name]; //Add the keyed position target morphPositions[i] = keyShape.Vertices[i].Position; } else { morphPositions[i] = vertex.Position; } Vector3 position = morphPositions[i]; position *= baseWeight; foreach (var track in tracks) { if (!mesh.KeyGroups.ContainsKey(track.Name)) { continue; } //The total weight used for a single vertex point var weight = track.GetFrameValue(this.Frame); //Get the track's key shape var keyShape = mesh.KeyGroups[track.Name]; //Add the keyed position and weigh it position += keyShape.Vertices[i].Position * weight; } //Set the output vertex position /= total; morphPositions[i] = position; } mesh.MorphPositions = morphPositions; mesh.UpdateVertexData = true; }
/// <summary> /// Reloads render info and state settings into the materials blend state for rendering. /// </summary> public override void ReloadRenderState(BfresMeshAsset mesh) { }