private void Dispose(bool disposing) { DestroyModelNameplate(); mModel = null; mRenderer = null; }
// TODO: Get rid of this public void OnFrame_Old(M2Renderer renderer) { UpdateVisibleInstances(renderer); if (mInstanceCount == 0) { return; } gMesh.UpdateIndexBuffer(renderer.IndexBuffer); gMesh.UpdateVertexBuffer(renderer.VertexBuffer); gMesh.UpdateInstanceBuffer(mInstanceBuffer); gMesh.Program.SetVertexConstantBuffer(1, renderer.AnimBuffer); foreach (var pass in Model.Passes) { // This renderer is only for opaque pass if (pass.BlendMode != 0 && pass.BlendMode != 1) { continue; } var program = pass.BlendMode == 0 ? gNoBlendProgram : gMaskBlendProgram; if (program != gMesh.Program) { gMesh.Program = program; program.Bind(); } var cullingDisabled = (pass.RenderFlag & 0x04) != 0; gMesh.UpdateRasterizerState(cullingDisabled ? gNoCullState : gCullState); gMesh.UpdateBlendState(BlendStates[pass.BlendMode]); var unlit = ((pass.RenderFlag & 0x01) != 0) ? 0.0f : 1.0f; var unfogged = ((pass.RenderFlag & 0x02) != 0) ? 0.0f : 1.0f; Matrix uvAnimMat; renderer.Animator.GetUvAnimMatrix(pass.TexAnimIndex, out uvAnimMat); var color = renderer.Animator.GetColorValue(pass.ColorAnimIndex); color.W *= renderer.Animator.GetAlphaValue(pass.AlphaAnimIndex); gPerPassBuffer.UpdateData(new PerModelPassBuffer { uvAnimMatrix1 = uvAnimMat, modelPassParams = new Vector4(unlit, unfogged, 0.0f, 0.0f), animatedColor = color }); gMesh.StartVertex = 0; gMesh.StartIndex = pass.StartIndex; gMesh.IndexCount = pass.IndexCount; gMesh.Program.SetPixelTexture(0, pass.Textures.First()); gMesh.Draw(mInstanceCount); } }
public M2RenderInstance(int uuid, Vector3 position, Vector3 rotation, Vector3 scale, M2Renderer renderer) { mScale = scale; mPosition = position; mRotation = rotation; NumReferences = 1; Uuid = uuid; mRenderer = renderer; mModel = mRenderer.Model; mBoundingBox = mModel.BoundingBox; var rotationMatrix = Matrix.RotationYawPitchRoll(MathUtil.DegreesToRadians(rotation.Y), MathUtil.DegreesToRadians(rotation.X), MathUtil.DegreesToRadians(rotation.Z)); Matrix.Invert(ref rotationMatrix, out mInverseRotation); mInstanceMatrix = rotationMatrix * Matrix.Scaling(scale) * Matrix.Translation(position); mBoundingBox = BoundingBox.Transform(ref mInstanceMatrix); Matrix.Invert(ref mInstanceMatrix, out mInverseMatrix); InstanceCorners = mModel.BoundingBox.GetCorners(); Vector3.TransformCoordinate(InstanceCorners, ref mInstanceMatrix, InstanceCorners); }
private void UpdateVisibleInstances(M2Renderer renderer) { lock (renderer.VisibleInstances) { if (mActiveInstances.Length < renderer.VisibleInstances.Count) { mActiveInstances = new PerInstanceBuffer[renderer.VisibleInstances.Count]; } for (var i = 0; i < renderer.VisibleInstances.Count; ++i) { mActiveInstances[i].matInstance = renderer.VisibleInstances[i].InstanceMatrix; mActiveInstances[i].colorMod = renderer.VisibleInstances[i].HighlightColor; } mInstanceCount = renderer.VisibleInstances.Count; if (mInstanceCount == 0) { return; } } mInstanceBuffer.UpdateData(mActiveInstances); }
public void OnFrame(M2Renderer renderer) { UpdateVisibleInstances(renderer); if (mInstanceCount == 0) { return; } gMesh.UpdateIndexBuffer(renderer.IndexBuffer); gMesh.UpdateVertexBuffer(renderer.VertexBuffer); gMesh.UpdateInstanceBuffer(mInstanceBuffer); gMesh.Program.SetVertexConstantBuffer(1, renderer.AnimBuffer); foreach (var pass in Model.Passes) { // This renderer is only for opaque pass if (pass.BlendMode != 0 && pass.BlendMode != 1) { continue; } // TODO: Since this isn't choosing among static programs anymore, cache a different way e.g. (comparison func) var ctx = WorldFrame.Instance.GraphicsContext; gCustomProgram.SetVertexShader(ctx.M2Shaders.GetVertexShader_Instanced(pass.VertexShaderType)); gCustomProgram.SetPixelShader(ctx.M2Shaders.GetPixelShader(pass.PixelShaderType)); gMesh.Program = gCustomProgram; gCustomProgram.Bind(); var cullingDisabled = (pass.RenderFlag & 0x04) != 0; gMesh.UpdateRasterizerState(cullingDisabled ? gNoCullState : gCullState); gMesh.UpdateBlendState(BlendStates[pass.BlendMode]); var unlit = ((pass.RenderFlag & 0x01) != 0) ? 0.0f : 1.0f; var unfogged = ((pass.RenderFlag & 0x02) != 0) ? 0.0f : 1.0f; var alphakey = (pass.BlendMode == 1) ? 1.0f : 0.0f; // These are per texture var alphaValues = new float[] { 1, 1, 1, 1 }; for (var i = 0; i < pass.OpCount; ++i) { alphaValues[i] = renderer.Animator.GetAlphaValue(pass.AlphaAnimIndex + i); } var uvAnimMatrix1 = Matrix.Identity; var uvAnimMatrix2 = Matrix.Identity; var uvAnimMatrix3 = Matrix.Identity; var uvAnimMatrix4 = Matrix.Identity; renderer.Animator.GetUvAnimMatrix(pass.TexAnimIndex + 0, out uvAnimMatrix1); if (pass.OpCount >= 2) { renderer.Animator.GetUvAnimMatrix(pass.TexAnimIndex + 1, out uvAnimMatrix2); } if (pass.OpCount >= 3) { renderer.Animator.GetUvAnimMatrix(pass.TexAnimIndex + 2, out uvAnimMatrix3); } if (pass.OpCount >= 4) { renderer.Animator.GetUvAnimMatrix(pass.TexAnimIndex + 3, out uvAnimMatrix4); } gPerPassBuffer.UpdateData(new PerModelPassBuffer { uvAnimMatrix1 = uvAnimMatrix1, uvAnimMatrix2 = uvAnimMatrix2, uvAnimMatrix3 = uvAnimMatrix3, uvAnimMatrix4 = uvAnimMatrix4, transparency = new Vector4(alphaValues[0], alphaValues[1], alphaValues[2], alphaValues[3]), modelPassParams = new Vector4(unlit, unfogged, alphakey, 0.0f), animatedColor = renderer.Animator.GetColorValue(pass.ColorAnimIndex) }); for (var i = 0; i < pass.OpCount && i < 4; ++i) { switch (Model.TextureInfos[pass.TextureIndices[i]].SamplerFlags) { case Graphics.Texture.SamplerFlagType.WrapBoth: gMesh.Program.SetPixelSampler(i, gSamplerWrapBoth); break; case Graphics.Texture.SamplerFlagType.WrapU: gMesh.Program.SetPixelSampler(i, gSamplerWrapU); break; case Graphics.Texture.SamplerFlagType.WrapV: gMesh.Program.SetPixelSampler(i, gSamplerWrapV); break; case Graphics.Texture.SamplerFlagType.ClampBoth: gMesh.Program.SetPixelSampler(i, gSamplerClampBoth); break; } gMesh.Program.SetPixelTexture(i, pass.Textures[i]); } gMesh.StartVertex = 0; gMesh.StartIndex = pass.StartIndex; gMesh.IndexCount = pass.IndexCount; gMesh.Draw(mInstanceCount); } }
// TODO: Get rid of this public void OnFrame_Old(M2Renderer renderer, M2RenderInstance instance) { var animator = mAnimator ?? renderer.Animator; if (mAnimator != null) { UpdateAnimations(instance); } gMesh.UpdateIndexBuffer(renderer.IndexBuffer); gMesh.UpdateVertexBuffer(renderer.VertexBuffer); gPerDrawCallBuffer.UpdateData(new PerDrawCallBuffer { instanceMat = instance.InstanceMatrix, colorMod = instance.HighlightColor }); gMesh.Program.SetVertexConstantBuffer(1, mAnimBuffer ?? renderer.AnimBuffer); foreach (var pass in mModel.Passes) { if (!mModel.NeedsPerInstanceAnimation) { // Prevent double rendering since this model pass // was already processed by the batch renderer if (pass.BlendMode == 0 || pass.BlendMode == 1) { continue; } } var oldProgram = gMesh.Program; ShaderProgram newProgram; switch (pass.BlendMode) { case 0: newProgram = gNoBlendProgram; break; case 1: newProgram = gBlendTestProgram; break; default: switch (pass.Textures.Count) { case 2: newProgram = g2PassProgram; break; case 3: newProgram = g3PassProgram; break; default: newProgram = gBlendProgram; break; } break; } if (newProgram != oldProgram) { gMesh.Program = newProgram; gMesh.Program.Bind(); } var depthState = gDepthNoWriteState; if (pass.BlendMode == 0 || pass.BlendMode == 1) { depthState = gDepthWriteState; } gMesh.UpdateDepthState(depthState); var cullingDisabled = (pass.RenderFlag & 0x04) != 0; gMesh.UpdateRasterizerState(cullingDisabled ? gNoCullState : gCullState); gMesh.UpdateBlendState(BlendStates[pass.BlendMode]); var unlit = ((pass.RenderFlag & 0x01) != 0) ? 0.0f : 1.0f; var unfogged = ((pass.RenderFlag & 0x02) != 0) ? 0.0f : 1.0f; Matrix uvAnimMat; animator.GetUvAnimMatrix(pass.TexAnimIndex, out uvAnimMat); var color = animator.GetColorValue(pass.ColorAnimIndex); var alpha = animator.GetAlphaValue(pass.AlphaAnimIndex); color.W *= alpha; gPerPassBuffer.UpdateData(new PerModelPassBuffer() { uvAnimMatrix1 = uvAnimMat, modelPassParams = new Vector4(unlit, unfogged, 0.0f, 0.0f), animatedColor = color }); for (var i = 0; i < pass.Textures.Count && i < 3; ++i) { gMesh.Program.SetPixelTexture(i, pass.Textures[i]); } gMesh.StartVertex = 0; gMesh.StartIndex = pass.StartIndex; gMesh.IndexCount = pass.IndexCount; gMesh.Draw(); } }
public void OnFrame(M2Renderer renderer, M2RenderInstance instance) { var animator = mAnimator ?? renderer.Animator; if (mAnimator != null) { UpdateAnimations(instance); } gMesh.UpdateIndexBuffer(renderer.IndexBuffer); gMesh.UpdateVertexBuffer(renderer.VertexBuffer); gPerDrawCallBuffer.UpdateData(new PerDrawCallBuffer { instanceMat = instance.InstanceMatrix, colorMod = instance.HighlightColor }); gMesh.Program.SetVertexConstantBuffer(1, mAnimBuffer ?? renderer.AnimBuffer); foreach (var pass in mModel.Passes) { if (!mModel.NeedsPerInstanceAnimation) { // Prevent double rendering since this model pass // was already processed by the batch renderer if (pass.BlendMode == 0 || pass.BlendMode == 1) { continue; } } // TODO: Since this isn't choosing among static programs anymore, cache a different way (comparison func?) var ctx = WorldFrame.Instance.GraphicsContext; gCustomProgram.SetVertexShader(ctx.M2Shaders.GetVertexShader_Single(pass.VertexShaderType)); gCustomProgram.SetPixelShader(ctx.M2Shaders.GetPixelShader(pass.PixelShaderType)); gMesh.Program = gCustomProgram; gCustomProgram.Bind(); var depthState = gDepthNoWriteState; if (pass.BlendMode == 0 || pass.BlendMode == 1) { depthState = gDepthWriteState; } gMesh.UpdateDepthState(depthState); var cullingDisabled = (pass.RenderFlag & 0x04) != 0; gMesh.UpdateRasterizerState(cullingDisabled ? gNoCullState : gCullState); gMesh.UpdateBlendState(BlendStates[pass.BlendMode]); var unlit = ((pass.RenderFlag & 0x01) != 0) ? 0.0f : 1.0f; var unfogged = ((pass.RenderFlag & 0x02) != 0) ? 0.0f : 1.0f; var alphakey = (pass.BlendMode == 1) ? 1.0f : 0.0f; // These are per texture var alphaValues = new float[] { 1, 1, 1, 1 }; for (var i = 0; i < pass.OpCount; ++i) { alphaValues[i] = animator.GetAlphaValue(pass.AlphaAnimIndex + i); } var uvAnimMatrix1 = Matrix.Identity; var uvAnimMatrix2 = Matrix.Identity; var uvAnimMatrix3 = Matrix.Identity; var uvAnimMatrix4 = Matrix.Identity; animator.GetUvAnimMatrix(pass.TexAnimIndex + 0, out uvAnimMatrix1); if (pass.OpCount >= 2) { animator.GetUvAnimMatrix(pass.TexAnimIndex + 1, out uvAnimMatrix2); } if (pass.OpCount >= 3) { animator.GetUvAnimMatrix(pass.TexAnimIndex + 2, out uvAnimMatrix3); } if (pass.OpCount >= 4) { animator.GetUvAnimMatrix(pass.TexAnimIndex + 3, out uvAnimMatrix4); } gPerPassBuffer.UpdateData(new PerModelPassBuffer() { uvAnimMatrix1 = uvAnimMatrix1, uvAnimMatrix2 = uvAnimMatrix2, uvAnimMatrix3 = uvAnimMatrix3, uvAnimMatrix4 = uvAnimMatrix4, transparency = new Vector4(alphaValues[0], alphaValues[1], alphaValues[2], alphaValues[3]), modelPassParams = new Vector4(unlit, unfogged, alphakey, 0.0f), animatedColor = animator.GetColorValue(pass.ColorAnimIndex) }); for (var i = 0; i < pass.OpCount && i < 4; ++i) { switch (mModel.TextureInfos[pass.TextureIndices[i]].SamplerFlags) { case Graphics.Texture.SamplerFlagType.WrapBoth: gMesh.Program.SetPixelSampler(i, gSamplerWrapBoth); break; case Graphics.Texture.SamplerFlagType.WrapU: gMesh.Program.SetPixelSampler(i, gSamplerWrapU); break; case Graphics.Texture.SamplerFlagType.WrapV: gMesh.Program.SetPixelSampler(i, gSamplerWrapV); break; case Graphics.Texture.SamplerFlagType.ClampBoth: gMesh.Program.SetPixelSampler(i, gSamplerClampBoth); break; } gMesh.Program.SetPixelTexture(i, pass.Textures[i]); } gMesh.StartVertex = 0; gMesh.StartIndex = pass.StartIndex; gMesh.IndexCount = pass.IndexCount; gMesh.Draw(); } }
public void OnFrame(M2Renderer renderer) { Animator.Update(null); Mesh.InitLayout(Mesh.Program); Mesh.BlendState = null; Mesh.BeginDraw(); Mesh.Program.SetPixelSampler(0, Sampler); Mesh.UpdateIndexBuffer(renderer.IndexBuffer); Mesh.UpdateVertexBuffer(renderer.VertexBuffer); if (Animator.GetBones(mAnimationMatrices)) { mAnimBuffer.UpdateData(mAnimationMatrices); } Mesh.Program.SetVertexConstantBuffer(1, mAnimBuffer); Mesh.Program.SetVertexConstantBuffer(2, mPerPassBuffer); Mesh.Program.SetPixelConstantBuffer(0, mPerPassBuffer); foreach (var pass in Model.Passes) { var cullingDisabled = (pass.RenderFlag & 0x04) != 0; Mesh.UpdateRasterizerState(cullingDisabled ? gNoCullState : gCullState); Mesh.UpdateBlendState(BlendStates[pass.BlendMode]); var oldProgram = Mesh.Program; ShaderProgram newProgram; switch (pass.BlendMode) { case 0: newProgram = gNoBlendProgram; break; case 1: newProgram = gBlendMaskProgram; break; default: switch (pass.TextureIndices.Count) { case 2: newProgram = g2PassProgram; break; case 3: newProgram = g3PassProgram; break; default: newProgram = gBlendProgram; break; } break; } if (newProgram != oldProgram) { Mesh.Program = newProgram; Mesh.Program.Bind(); } var unlit = ((pass.RenderFlag & 0x01) != 0) ? 0.0f : 1.0f; var unfogged = ((pass.RenderFlag & 0x02) != 0) ? 0.0f : 1.0f; Matrix uvAnimMat; Animator.GetUvAnimMatrix(pass.TexAnimIndex, out uvAnimMat); var color = Animator.GetColorValue(pass.ColorAnimIndex); var alpha = Animator.GetAlphaValue(pass.AlphaAnimIndex); color.W *= alpha; mPerPassBuffer.UpdateData(new PerModelPassBuffer { uvAnimMatrix1 = uvAnimMat, modelPassParams = new Vector4(unlit, unfogged, 0.0f, 0.0f), animatedColor = color }); Mesh.StartVertex = 0; Mesh.StartIndex = pass.StartIndex; Mesh.IndexCount = pass.IndexCount; for (var i = 0; i < pass.TextureIndices.Count; ++i) { Mesh.Program.SetPixelTexture(i, Textures[pass.TextureIndices[i]].Texture); } Mesh.Draw(); } }