예제 #1
0
        public M2RenderInstance AddInstance(int uuid, Vector3 position, Vector3 rotation, Vector3 scaling)
        {
            M2RenderInstance inst;

            // ReSharper disable once InconsistentlySynchronizedField
            if (mFullInstances.TryGetValue(uuid, out inst))
            {
                ++inst.NumReferences;
                return(inst);
            }

            var instance = new M2RenderInstance(uuid, position, rotation, scaling, this);

            lock (mFullInstances)
            {
                mFullInstances.Add(uuid, instance);
                if (!WorldFrame.Instance.ActiveCamera.Contains(ref instance.BoundingBox))
                {
                    return(instance);
                }

                lock (mInstanceBufferLock)
                    mVisibleInstances.Add(instance);
                return(instance);
            }
        }
예제 #2
0
파일: M2Renderer.cs 프로젝트: veserine/Neo
        public void RenderSingleInstance(M2RenderInstance instance)
        {
            if (mIsSyncLoaded == false)
            {
                if (!BeginSyncLoad())
                {
                    return;
                }
            }

            if (mSkipRendering)
            {
                return;
            }

            // TODO: We *really* need to get rid of this!
            if (IO.FileManager.Instance.Version == IO.FileDataVersion.Lichking)
            {
                mSingleRenderer.OnFrame_Old(this, instance);
            }
            else
            {
                mSingleRenderer.OnFrame(this, instance);
            }
        }
예제 #3
0
        private void UpdateAnimations(M2RenderInstance instance)
        {
            var camera = WorldFrame.Instance.ActiveCamera;

            mAnimator.Update(new BillboardParameters
            {
                Forward         = camera.Forward,
                Right           = camera.Right,
                Up              = camera.Up,
                InverseRotation = instance.InverseRotation
            });

            if (mAnimator.GetBones(mAnimationMatrices))
            {
                mAnimBuffer.UpdateData(mAnimationMatrices);
            }
        }
예제 #4
0
        // 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();
            }
        }
예제 #5
0
        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();
            }
        }
예제 #6
0
        public M2RenderInstance AddInstance(int uuid, Vector3 position, Vector3 rotation, Vector3 scaling)
        {
            M2RenderInstance inst;
            // ReSharper disable once InconsistentlySynchronizedField
            if (mFullInstances.TryGetValue(uuid, out inst))
            {
                ++inst.NumReferences;
                return inst;
            }

            var instance = new M2RenderInstance(uuid, position, rotation, scaling, this);
            lock (mFullInstances)
            {
                mFullInstances.Add(uuid, instance);
                if (!WorldFrame.Instance.ActiveCamera.Contains(ref instance.BoundingBox))
                    return instance;

                lock (mInstanceBufferLock)
                    mVisibleInstances.Add(instance);
                return instance;
            }
        }