コード例 #1
0
        public override void LoadMesh(BfresMeshAsset mesh)
        {
            base.LoadMesh(mesh);

            if (ShaderFileState == ShaderState.Global)
            {
                mesh.Shape.UpdateVertexBuffer(true);
                mesh.UpdateVertexBuffer();
            }
        }
コード例 #2
0
        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();
        }
コード例 #3
0
        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);
            }
        }
コード例 #4
0
        /// <summary>
        /// Called once when the renderer can be loaded from a given shader model and mesh.
        /// </summary>
        public void OnLoad(BfshaLibrary.ShaderModel shaderModel, FMDL model, FSHP mesh, BfresMeshAsset meshAsset)
        {
            var shapeBlock = shaderModel.UniformBlocks.Values.FirstOrDefault(x =>
                                                                             x.Type == BfshaLibrary.UniformBlock.BlockType.Shape);

            //Models may update the shape block outside the shader if the shape block is unused so update mesh matrix manually
            if (shapeBlock.Size == 0 && mesh.VertexSkinCount == 0)
            {
                mesh.UpdateVertexBuffer(true);
                meshAsset.UpdateVertexBuffer();
            }

            //Assign some necessary data
            meshAsset.MaterialAsset = this;

            //Force reload from material editing
            mesh.ShaderReload += delegate
            {
                Console.WriteLine($"Reloading shader program {meshAsset.Name}");
                this.ReloadRenderState(meshAsset);
                this.ReloadProgram(meshAsset);
                mesh.HasValidShader = this.HasValidProgram;

                Console.WriteLine($"Program Validation: {this.HasValidProgram}");
                this.UpdateShader = true;
            };

            ShaderModel  = shaderModel;
            MaterialData = mesh.Material;
            ParentModel  = model;
            //Load mesh function for loading the custom shader for the first time
            LoadMesh(meshAsset);
            ReloadRenderState(meshAsset);
            ReloadProgram(meshAsset);

            var bfresMaterial = (FMAT)this.MaterialData;

            //Remap the vertex layouts from shader model attributes
            if (!IsSwitch)
            {
                //GX2 shaders can be directly mapped via string and location searches
                Dictionary <string, string> attributeLocations = new Dictionary <string, string>();
                for (int i = 0; i < shaderModel.Attributes.Count; i++)
                {
                    string key = shaderModel.Attributes.GetKey(i);
                    attributeLocations.Add(key, $"{key}_0_0");
                }
                meshAsset.UpdateVaoAttributes(attributeLocations);
            }
            else
            {
                Dictionary <string, int> attributeLocations = new Dictionary <string, int>();
                for (int i = 0; i < shaderModel.Attributes.Count; i++)
                {
                    string key      = shaderModel.Attributes.GetKey(i);
                    int    location = shaderModel.Attributes[i].Location;
                    attributeLocations.Add(key, location);
                }
                meshAsset.UpdateVaoAttributes(attributeLocations);
            }
        }