/// <summary> /// Initialize the OpenGL state of the given model group. /// </summary> /// <param name="modelGroup">The model group to initialize.</param> private void InitializeModelGroup(ModelGroup modelGroup) { /* * Buffers */ var vertexBuffer = new Buffer <Vector3>(BufferTarget.ArrayBuffer, BufferUsageHint.StaticDraw); var normalBuffer = new Buffer <Vector3>(BufferTarget.ArrayBuffer, BufferUsageHint.StaticDraw); var coordinateBuffer = new Buffer <Vector2>(BufferTarget.ArrayBuffer, BufferUsageHint.StaticDraw); var vertexIndexes = new Buffer <ushort>(BufferTarget.ElementArrayBuffer, BufferUsageHint.StaticDraw); // Upload all of the vertices in this group vertexBuffer.Data = modelGroup.GetVertices().Select(v => v.ToOpenGLVector()).ToArray(); _vertexBufferLookup.Add(modelGroup, vertexBuffer); vertexBuffer.AttachAttributePointer(new VertexAttributePointer(0, 3, VertexAttribPointerType.Float, 0, 0)); // Upload all of the normals in this group normalBuffer.Data = modelGroup.GetNormals().Select(v => v.ToOpenGLVector()).ToArray(); _normalBufferLookup.Add(modelGroup, normalBuffer); normalBuffer.AttachAttributePointer(new VertexAttributePointer(1, 3, VertexAttribPointerType.Float, 0, 0)); // Upload all of the UVs in this group coordinateBuffer.Data = modelGroup.GetTextureCoordinates().Select(v => v.ToOpenGLVector()).ToArray(); _textureCoordinateBufferLookup.Add(modelGroup, coordinateBuffer); coordinateBuffer.AttachAttributePointer ( new VertexAttributePointer(2, 2, VertexAttribPointerType.Float, 0, 0) ); // Upload vertex indices for this group vertexIndexes.Data = modelGroup.GetVertexIndices().ToArray(); _vertexIndexBufferLookup.Add(modelGroup, vertexIndexes); var boundingBox = new RenderableBoundingBox ( modelGroup.GetBoundingBox(), this.ActorTransform ); boundingBox.Initialize(); _boundingBoxLookup.Add(modelGroup, boundingBox); }
/// <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; }