コード例 #1
0
        /// <inheritdoc />
        public void Initialize()
        {
            ThrowIfDisposed();

            if (this.IsInitialized)
            {
                return;
            }

            this.Shader = this.Cache.GetShader(EverlookShader.GameModel) as GameModelShader;

            if (this.Shader == null)
            {
                throw new ShaderNullException(typeof(GameModelShader));
            }

            this.VertexBuffer = new Buffer <byte>(BufferTarget.ArrayBuffer, BufferUsageHint.StaticDraw)
            {
                Data = this.Model.Vertices.Select(v => v.PackForOpenGL()).SelectMany(b => b).ToArray()
            };

            var attributePointers = new[]
            {
                // Position
                new VertexAttributePointer(0, 3, VertexAttribPointerType.Float, MDXVertex.GetSize(), 0),
                // Bone weights
                new VertexAttributePointer(1, 4, VertexAttribPointerType.UnsignedByte, MDXVertex.GetSize(), 12),
                // Bone indexes
                new VertexAttributePointer(2, 4, VertexAttribPointerType.UnsignedByte, MDXVertex.GetSize(), 16),
                // Normal
                new VertexAttributePointer(3, 3, VertexAttribPointerType.Float, MDXVertex.GetSize(), 20),
                // UV1
                new VertexAttributePointer(4, 2, VertexAttribPointerType.Float, MDXVertex.GetSize(), 32),
                // UV2
                new VertexAttributePointer(5, 2, VertexAttribPointerType.Float, MDXVertex.GetSize(), 40)
            };

            this.VertexBuffer.AttachAttributePointers(attributePointers);

            this.BoundingBox = new RenderableBoundingBox(this.Model.BoundingBox, this.ActorTransform);
            this.BoundingBox.Initialize();

            foreach (MDXTexture texture in this.Model.Textures)
            {
                if (!this.TextureLookup.ContainsKey(texture.Filename))
                {
                    this.TextureLookup.Add
                    (
                        texture.Filename,
                        this.Cache.GetTexture(texture, this.GameContext)
                    );
                }
            }

            foreach (MDXSkin skin in this.Model.Skins)
            {
                ushort[] absoluteTriangleVertexIndexes = skin.Triangles.Select(relativeIndex => skin.VertexIndices[relativeIndex]).ToArray();
                var      skinIndexBuffer = new Buffer <ushort>(BufferTarget.ElementArrayBuffer, BufferUsageHint.StaticDraw)
                {
                    Data = absoluteTriangleVertexIndexes
                };

                this.SkinIndexArrayBuffers.Add(skin, skinIndexBuffer);

                if (this.Model.Version <= WarcraftVersion.Wrath)
                {
                    // In models earlier than Cata, we need to calculate the shader selector value at runtime.
                    foreach (var renderBatch in skin.RenderBatches)
                    {
                        ushort shaderSelector = MDXShaderHelper.GetRuntimeShaderID(renderBatch.ShaderID, renderBatch, this.Model);
                        renderBatch.ShaderID = shaderSelector;
                    }
                }
            }

            // Cache the default display info
            if (this.CurrentDisplayInfo != null)
            {
                CacheDisplayInfo(this.CurrentDisplayInfo);
            }

            this.IsInitialized = true;
        }
コード例 #2
0
        /// <summary>
        /// Prepares the OpenGL state for rendering the specified batch.
        /// </summary>
        /// <param name="renderBatch">The batch to prepare for rendering.</param>
        /// <exception cref="ArgumentOutOfRangeException">Thrown if the batch has more than four textures.</exception>
        private void PrepareBatchForRender(MDXRenderBatch renderBatch)
        {
            var fragmentShader = MDXShaderHelper.GetFragmentShaderType(renderBatch.TextureCount, renderBatch.ShaderID);
            var vertexShader   = MDXShaderHelper.GetVertexShaderType(renderBatch.TextureCount, renderBatch.ShaderID);
            var batchMaterial  = this.Model.Materials[renderBatch.MaterialIndex];

            this.Shader.SetVertexShaderType(vertexShader);
            this.Shader.SetFragmentShaderType(fragmentShader);
            this.Shader.SetMaterial(batchMaterial);

            var baseColour = Color4.White;

            if (renderBatch.ColorIndex >= 0)
            {
                var colorAnimation = this.Model.ColourAnimations[renderBatch.ColorIndex];

                // TODO: Sample based on animated values
                RGB   rgb;
                float alpha;

                if (colorAnimation.ColourTrack.IsComposite)
                {
                    rgb   = colorAnimation.ColourTrack.CompositeTimelineValues.First();
                    alpha = colorAnimation.OpacityTrack.CompositeTimelineValues.First() / 0x7fff;
                }
                else
                {
                    rgb   = colorAnimation.ColourTrack.Values.First().First();
                    alpha = colorAnimation.OpacityTrack.Values.First().First() / 0x7fff;
                }

                baseColour = new Color4
                             (
                    MathHelper.Clamp(rgb.R, 0.0f, 1.0f),
                    MathHelper.Clamp(rgb.G, 0.0f, 1.0f),
                    MathHelper.Clamp(rgb.B, 0.0f, 1.0f),
                    MathHelper.Clamp(alpha, 0.0f, 1.0f)
                             );
            }

            if ((short)renderBatch.TransparencyLookupTableIndex >= 0)
            {
                var transparencyAnimationIndex = this.Model.TransparencyLookupTable[renderBatch.TransparencyLookupTableIndex];
                var transparencyAnimation      = this.Model.TransparencyAnimations[transparencyAnimationIndex];

                float alphaWeight;
                if (transparencyAnimation.Weight.IsComposite)
                {
                    alphaWeight = transparencyAnimation.Weight.CompositeTimelineValues.First() / 0x7fff;
                }
                else
                {
                    alphaWeight = transparencyAnimation.Weight.Values.First().First() / 0x7fff;
                }

                baseColour.A *= alphaWeight;
            }

            this.Shader.SetBaseInputColour(baseColour);

            var textureIndexes = this.Model.TextureLookupTable.Skip(renderBatch.TextureLookupTableIndex)
                                 .Take(renderBatch.TextureCount);
            var textures = this.Model.Textures.Where((t, i) => textureIndexes.Contains((short)i)).ToList();

            for (int i = 0; i < textures.Count; ++i)
            {
                var    texture = textures[i];
                string textureName;
                switch (texture.TextureType)
                {
                case MDXTextureType.Regular:
                {
                    textureName = texture.Filename;
                    break;
                }

                case MDXTextureType.MonsterSkin1:
                {
                    textureName = GetDisplayInfoTexturePath(this.CurrentDisplayInfo?.TextureVariation1.Value);
                    break;
                }

                case MDXTextureType.MonsterSkin2:
                {
                    textureName = GetDisplayInfoTexturePath(this.CurrentDisplayInfo?.TextureVariation2.Value);
                    break;
                }

                case MDXTextureType.MonsterSkin3:
                {
                    textureName = GetDisplayInfoTexturePath(this.CurrentDisplayInfo?.TextureVariation3.Value);
                    break;
                }

                default:
                {
                    // Use the fallback texture if we don't know how to load the texture type
                    textureName = string.Empty;
                    break;
                }
                }

                var textureObject = this.TextureLookup[textureName];
                switch (i)
                {
                case 0:
                {
                    this.Shader.BindTexture0(textureObject);
                    break;
                }

                case 1:
                {
                    this.Shader.BindTexture1(textureObject);
                    break;
                }

                case 2:
                {
                    this.Shader.BindTexture2(textureObject);
                    break;
                }

                case 3:
                {
                    this.Shader.BindTexture3(textureObject);
                    break;
                }

                default:
                {
                    throw new ArgumentOutOfRangeException();
                }
                }
            }
        }
コード例 #3
0
        /// <summary>
        /// Prepares the OpenGL state for rendering the specified batch.
        /// </summary>
        /// <param name="renderBatch">The batch to prepare for rendering.</param>
        /// <exception cref="ArgumentOutOfRangeException">Thrown if the batch has more than four textures.</exception>
        private void PrepareBatchForRender(MDXRenderBatch renderBatch)
        {
            var fragmentShader = MDXShaderHelper.GetFragmentShaderType(renderBatch.TextureCount, renderBatch.ShaderID);
            var vertexShader   = MDXShaderHelper.GetVertexShaderType(renderBatch.TextureCount, renderBatch.ShaderID);
            var batchMaterial  = this.Model.Materials[renderBatch.MaterialIndex];

            this.Shader.SetVertexShaderType(vertexShader);
            this.Shader.SetFragmentShaderType(fragmentShader);
            this.Shader.SetMaterial(batchMaterial);

            var textureIndexes = this.Model.TextureLookupTable.Skip(renderBatch.TextureLookupTableIndex)
                                 .Take(renderBatch.TextureCount);
            var textures = this.Model.Textures.Where((t, i) => textureIndexes.Contains((short)i)).ToList();

            for (int i = 0; i < textures.Count; ++i)
            {
                var    texture = textures[i];
                string textureName;
                switch (texture.TextureType)
                {
                case EMDXTextureType.Regular:
                {
                    textureName = texture.Filename;
                    break;
                }

                case EMDXTextureType.MonsterSkin1:
                {
                    textureName = GetDisplayInfoTexturePath(this.CurrentDisplayInfo?.TextureVariation1.Value);
                    break;
                }

                case EMDXTextureType.MonsterSkin2:
                {
                    textureName = GetDisplayInfoTexturePath(this.CurrentDisplayInfo?.TextureVariation2.Value);
                    break;
                }

                case EMDXTextureType.MonsterSkin3:
                {
                    textureName = GetDisplayInfoTexturePath(this.CurrentDisplayInfo?.TextureVariation3.Value);
                    break;
                }

                default:
                {
                    // Use the fallback texture if we don't know how to load the texture type
                    textureName = string.Empty;
                    break;
                }
                }

                var textureObject = this.TextureLookup[textureName];
                switch (i)
                {
                case 0:
                {
                    this.Shader.BindTexture0(textureObject);
                    break;
                }

                case 1:
                {
                    this.Shader.BindTexture1(textureObject);
                    break;
                }

                case 2:
                {
                    this.Shader.BindTexture2(textureObject);
                    break;
                }

                case 3:
                {
                    this.Shader.BindTexture3(textureObject);
                    break;
                }

                default:
                {
                    throw new ArgumentOutOfRangeException();
                }
                }
            }
        }