/// <summary> /// Creates a cached shader for the specifed shader, using the specified shader enumeration /// as a lookup key. /// </summary> private ShaderProgram CreateCachedShader(EverlookShader shader) { if (!Enum.IsDefined(typeof(EverlookShader), shader)) { throw new ArgumentException("An unknown shader was passed to the rendering cache.", nameof(shader)); } Log.Info($"Creating cached shader for \"{shader}\""); ShaderProgram shaderProgram; switch (shader) { case EverlookShader.Plain2D: { shaderProgram = new Plain2DShader(); break; } case EverlookShader.WorldModel: { shaderProgram = new WorldModelShader(); break; } case EverlookShader.BoundingBox: { shaderProgram = new BoundingBoxShader(); break; } case EverlookShader.GameModel: { shaderProgram = new GameModelShader(); break; } case EverlookShader.BaseGrid: { shaderProgram = new BaseGridShader(); break; } default: { throw new ArgumentOutOfRangeException ( nameof(shader), "No implemented shader class for this shader." ); } } _shaderCache.Add(shader, shaderProgram); return(shaderProgram); }
/// <summary> /// Initializes the required data for rendering. /// </summary> public void Initialize() { this.Shader = this.Cache.GetShader(EverlookShader.GameModel) as GameModelShader; this.VertexBufferID = GL.GenBuffer(); byte[] vertexBufferData = this.Model.Vertices .Select(v => v.PackForOpenGL()) .SelectMany(b => b) .ToArray(); GL.BindBuffer(BufferTarget.ArrayBuffer, this.VertexBufferID); GL.BufferData ( BufferTarget.ArrayBuffer, (IntPtr)vertexBufferData.Length, vertexBufferData, BufferUsageHint.StaticDraw ); // TODO: Textures // TODO: Per-skin array index buffers foreach (MDXSkin skin in this.Model.Skins) { int skinIndexBuffer = GL.GenBuffer(); ushort[] absoluteTriangleVertexIndices = skin.Triangles.Select(relativeIndex => skin.VertexIndices[relativeIndex]).ToArray(); GL.BindBuffer(BufferTarget.ElementArrayBuffer, skinIndexBuffer); GL.BufferData ( BufferTarget.ElementArrayBuffer, absoluteTriangleVertexIndices.Length * sizeof(ushort), absoluteTriangleVertexIndices, BufferUsageHint.StaticDraw ); this.SkinIndexArrayLookup.Add(skin, skinIndexBuffer); } this.IsInitialized = true; }
/// <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; }