コード例 #1
0
        private StaticBuffer <ushort> CreateIndexBuffer(
            ResourceUploadBatch uploadBatch,
            TerrainPatchSize size,
            out ushort[] indices)
        {
            // TODO: Could use triangle strip

            var numIndices = CalculateNumIndices(size.Width, size.Height);

            indices = new ushort[numIndices];

            for (int y = 0, indexIndex = 0; y < size.Height - 1; y++)
            {
                var yThis = y * size.Width;
                var yNext = (y + 1) * size.Width;

                for (var x = 0; x < size.Width - 1; x++)
                {
                    // Triangle 1
                    indices[indexIndex++] = (ushort)(yThis + x);
                    indices[indexIndex++] = (ushort)(yThis + x + 1);
                    indices[indexIndex++] = (ushort)(yNext + x);

                    // Triangle 2
                    indices[indexIndex++] = (ushort)(yNext + x);
                    indices[indexIndex++] = (ushort)(yThis + x + 1);
                    indices[indexIndex++] = (ushort)(yNext + x + 1);
                }
            }

            return(StaticBuffer.Create(
                       _graphicsDevice,
                       uploadBatch,
                       indices));
        }
コード例 #2
0
        internal ModelMeshMaterialPass(
            GraphicsDevice graphicsDevice,
            ResourceUploadBatch uploadBatch,
            uint numTextureStages,
            MeshTexCoords[] texCoords,
            MeshTextureIndex[] textureIndices,
            uint[] materialIndices,
            IReadOnlyList <ModelMeshPart> meshParts)
        {
            NumTextureStages = numTextureStages;

            TexCoordVertexBuffer = AddDisposable(StaticBuffer.Create(
                                                     graphicsDevice,
                                                     uploadBatch,
                                                     texCoords));

            TextureIndicesBuffer = AddDisposable(StaticBuffer.Create(
                                                     graphicsDevice,
                                                     uploadBatch,
                                                     textureIndices));

            MaterialIndicesBuffer = AddDisposable(StaticBuffer.Create(
                                                      graphicsDevice,
                                                      uploadBatch,
                                                      materialIndices));

            MeshParts = meshParts;
        }
コード例 #3
0
ファイル: MapLoader.cs プロジェクト: ElonGame/OpenSAGE
        private TerrainPatchComponent CreatePatch(
            TerrainEffect terrainEffect,
            EffectPipelineStateHandle pipelineStateHandle,
            HeightMap heightMap,
            BlendTileData blendTileData,
            Int32Rect patchBounds,
            GraphicsDevice graphicsDevice,
            ResourceUploadBatch uploadBatch,
            TerrainPatchIndexBufferCache indexBufferCache)
        {
            var indexBuffer = indexBufferCache.GetIndexBuffer(
                patchBounds.Width,
                patchBounds.Height,
                uploadBatch,
                out var indices);

            var vertexBuffer = AddDisposable(CreateVertexBuffer(
                                                 graphicsDevice,
                                                 uploadBatch,
                                                 heightMap,
                                                 patchBounds,
                                                 indices,
                                                 out var boundingBox,
                                                 out var triangles));

            return(new TerrainPatchComponent(
                       terrainEffect,
                       pipelineStateHandle,
                       patchBounds,
                       vertexBuffer,
                       indexBuffer,
                       triangles,
                       boundingBox));
        }
コード例 #4
0
ファイル: MapLoader.cs プロジェクト: ElonGame/OpenSAGE
        private static StaticBuffer <CliffInfo> CreateCliffDetails(
            GraphicsDevice graphicsDevice,
            ResourceUploadBatch uploadBatch,
            MapFile mapFile)
        {
            var cliffDetails = new CliffInfo[mapFile.BlendTileData.CliffTextureMappings.Length];

            const int cliffScalingFactor = 64;

            for (var i = 0; i < cliffDetails.Length; i++)
            {
                var cliffMapping = mapFile.BlendTileData.CliffTextureMappings[i];
                cliffDetails[i] = new CliffInfo
                {
                    BottomLeftUV  = cliffMapping.BottomLeftCoords * cliffScalingFactor,
                    BottomRightUV = cliffMapping.BottomRightCoords * cliffScalingFactor,
                    TopLeftUV     = cliffMapping.TopLeftCoords * cliffScalingFactor,
                    TopRightUV    = cliffMapping.TopRightCoords * cliffScalingFactor
                };
            }

            return(cliffDetails.Length > 0
                ? StaticBuffer.Create(
                       graphicsDevice,
                       uploadBatch,
                       cliffDetails)
                : null);
        }
コード例 #5
0
        public StaticBuffer <ushort> GetIndexBuffer(
            int width,
            int height,
            ResourceUploadBatch uploadBatch,
            out ushort[] indices)
        {
            var size = new TerrainPatchSize
            {
                Width  = width,
                Height = height
            };

            if (!_cachedIndexBuffers.TryGetValue(size, out var result))
            {
                _cachedIndexBuffers[size] = result = new CacheEntry
                {
                    Buffer  = AddDisposable(CreateIndexBuffer(uploadBatch, size, out indices)),
                    Indices = indices
                };
            }
            else
            {
                indices = result.Indices;
            }
            return(result.Buffer);
        }
コード例 #6
0
ファイル: MapLoader.cs プロジェクト: ElonGame/OpenSAGE
        private static void CreateTextures(
            ContentManager contentManager,
            ResourceUploadBatch uploadBatch,
            BlendTileData blendTileData,
            out Texture[] textures,
            out TextureInfo[] textureDetails)
        {
            var numTextures = blendTileData.Textures.Length;

            textures       = new Texture[numTextures];
            textureDetails = new TextureInfo[numTextures];
            for (var i = 0; i < numTextures; i++)
            {
                var mapTexture = blendTileData.Textures[i];

                var terrainType = contentManager.IniDataContext.TerrainTextures.First(x => x.Name == mapTexture.Name);

                var texturePath = Path.Combine("Art", "Terrain", terrainType.Texture);
                textures[i] = contentManager.Load <Texture>(texturePath, uploadBatch);

                textureDetails[i] = new TextureInfo
                {
                    CellSize = mapTexture.CellSize * 2
                };
            }
        }
コード例 #7
0
ファイル: ParticleSystem.cs プロジェクト: ElonGame/OpenSAGE
        private static StaticBuffer <ushort> CreateIndexBuffer(GraphicsDevice graphicsDevice, int maxParticles)
        {
            var uploadBatch = new ResourceUploadBatch(graphicsDevice);

            uploadBatch.Begin();

            var indices      = new ushort[maxParticles * 2 * 3]; // Two triangles per particle.
            var indexCounter = 0;

            for (ushort i = 0; i < maxParticles * 4; i += 4)
            {
                indices[indexCounter++] = (ushort)(i + 0);
                indices[indexCounter++] = (ushort)(i + 2);
                indices[indexCounter++] = (ushort)(i + 1);

                indices[indexCounter++] = (ushort)(i + 1);
                indices[indexCounter++] = (ushort)(i + 2);
                indices[indexCounter++] = (ushort)(i + 3);
            }

            var result = StaticBuffer.Create(
                graphicsDevice,
                uploadBatch,
                indices);

            uploadBatch.End();

            return(result);
        }
コード例 #8
0
ファイル: ContentManager.cs プロジェクト: ElonGame/OpenSAGE
        public T Load <T>(
            string filePath,
            ResourceUploadBatch uploadBatch,
            LoadOptions options = null)
            where T : class
        {
            if (_cachedObjects.TryGetValue(filePath, out var asset))
            {
                return((T)asset);
            }

            var type = typeof(T);

            if (!_contentLoaders.TryGetValue(type, out var contentLoader))
            {
                throw new Exception($"Could not finder content loader for type '{type.FullName}'");
            }

            FileSystemEntry entry = null;

            foreach (var testFilePath in contentLoader.GetPossibleFilePaths(filePath))
            {
                entry = _fileSystem.GetFile(testFilePath);
                if (entry != null)
                {
                    break;
                }
            }

            if (entry != null)
            {
                var createdUploadBatch = false;
                if (uploadBatch == null)
                {
                    uploadBatch = new ResourceUploadBatch(GraphicsDevice);
                    uploadBatch.Begin();
                    createdUploadBatch = true;
                }

                asset = contentLoader.Load(entry, this, uploadBatch);
                if (asset is IDisposable d)
                {
                    AddDisposable(d);
                }

                if (createdUploadBatch)
                {
                    uploadBatch.End();
                }
            }
            else
            {
                asset = contentLoader.PlaceholderValue;
            }

            _cachedObjects.Add(filePath, asset);

            return((T)asset);
        }
コード例 #9
0
ファイル: MapLoader.cs プロジェクト: ElonGame/OpenSAGE
        private static Texture CreateTileDataTexture(
            GraphicsDevice graphicsDevice,
            ResourceUploadBatch uploadBatch,
            MapFile mapFile,
            HeightMap heightMap)
        {
            var tileData = new uint[heightMap.Width * heightMap.Height * 4];

            var tileDataIndex = 0;

            for (var y = 0; y < heightMap.Height; y++)
            {
                for (var x = 0; x < heightMap.Width; x++)
                {
                    var baseTextureIndex = (byte)mapFile.BlendTileData.TextureIndices[mapFile.BlendTileData.Tiles[x, y]].TextureIndex;

                    var blendData1 = GetBlendData(mapFile, x, y, mapFile.BlendTileData.Blends[x, y], baseTextureIndex);
                    var blendData2 = GetBlendData(mapFile, x, y, mapFile.BlendTileData.ThreeWayBlends[x, y], baseTextureIndex);

                    uint packedTextureIndices = 0;
                    packedTextureIndices |= baseTextureIndex;
                    packedTextureIndices |= (uint)(blendData1.TextureIndex << 8);
                    packedTextureIndices |= (uint)(blendData2.TextureIndex << 16);

                    tileData[tileDataIndex++] = packedTextureIndices;

                    var packedBlendInfo = 0u;
                    packedBlendInfo |= blendData1.BlendDirection;
                    packedBlendInfo |= (uint)(blendData1.Flags << 8);
                    packedBlendInfo |= (uint)(blendData2.BlendDirection << 16);
                    packedBlendInfo |= (uint)(blendData2.Flags << 24);

                    tileData[tileDataIndex++] = packedBlendInfo;

                    tileData[tileDataIndex++] = mapFile.BlendTileData.CliffTextures[x, y];

                    tileData[tileDataIndex++] = 0;
                }
            }

            byte[] textureIDsByteArray = new byte[tileData.Length * sizeof(uint)];
            System.Buffer.BlockCopy(tileData, 0, textureIDsByteArray, 0, tileData.Length * sizeof(uint));

            return(Texture.CreateTexture2D(
                       graphicsDevice,
                       uploadBatch,
                       PixelFormat.Rgba32UInt,
                       heightMap.Width,
                       heightMap.Height,
                       new[]
            {
                new TextureMipMapData
                {
                    BytesPerRow = heightMap.Width * sizeof(uint) * 4,
                    Data = textureIDsByteArray
                }
            }));
        }
コード例 #10
0
ファイル: TextureLoader.cs プロジェクト: ElonGame/OpenSAGE
        public TextureLoader(GraphicsDevice graphicsDevice)
        {
            var uploadBatch = new ResourceUploadBatch(graphicsDevice);

            uploadBatch.Begin();

            PlaceholderValue = AddDisposable(Texture.CreatePlaceholderTexture2D(
                                                 graphicsDevice,
                                                 uploadBatch));

            uploadBatch.End();
        }
コード例 #11
0
ファイル: MapLoader.cs プロジェクト: ElonGame/OpenSAGE
        private void CreatePatches(
            GraphicsDevice graphicsDevice,
            ResourceUploadBatch uploadBatch,
            Entity terrainEntity,
            HeightMap heightMap,
            BlendTileData blendTileData,
            TerrainEffect terrainEffect,
            EffectPipelineStateHandle pipelineStateHandle,
            TerrainPatchIndexBufferCache indexBufferCache)
        {
            const int numTilesPerPatch = TerrainComponent.PatchSize - 1;

            var numPatchesX = heightMap.Width / numTilesPerPatch;

            if (heightMap.Width % numTilesPerPatch != 0)
            {
                numPatchesX += 1;
            }

            var numPatchesY = heightMap.Height / numTilesPerPatch;

            if (heightMap.Height % numTilesPerPatch != 0)
            {
                numPatchesY += 1;
            }

            for (var y = 0; y < numPatchesY; y++)
            {
                for (var x = 0; x < numPatchesX; x++)
                {
                    var patchX = x * numTilesPerPatch;
                    var patchY = y * numTilesPerPatch;

                    var patchBounds = new Int32Rect
                    {
                        X      = patchX,
                        Y      = patchY,
                        Width  = Math.Min(TerrainComponent.PatchSize, heightMap.Width - patchX),
                        Height = Math.Min(TerrainComponent.PatchSize, heightMap.Height - patchY)
                    };

                    terrainEntity.Components.Add(CreatePatch(
                                                     terrainEffect,
                                                     pipelineStateHandle,
                                                     heightMap,
                                                     blendTileData,
                                                     patchBounds,
                                                     graphicsDevice,
                                                     uploadBatch,
                                                     indexBufferCache));
                }
            }
        }
コード例 #12
0
ファイル: Texture.cs プロジェクト: ElonGame/OpenSAGE
 public static Texture CreateTexture2D(
     GraphicsDevice graphicsDevice,
     ResourceUploadBatch uploadBatch,
     PixelFormat pixelFormat,
     int width,
     int height,
     TextureMipMapData[] mipMapData)
 {
     return(new Texture(
                graphicsDevice,
                uploadBatch,
                pixelFormat,
                width,
                height,
                mipMapData));
 }
コード例 #13
0
ファイル: ModelMesh.cs プロジェクト: ElonGame/OpenSAGE
        public ModelMesh(
            GraphicsDevice graphicsDevice,
            ResourceUploadBatch uploadBatch,
            string name,
            MeshVertex[] vertices,
            ushort[] indices,
            VertexMaterial[] vertexMaterials,
            Texture[] textures,
            ModelMeshMaterialPass[] materialPasses,
            bool isSkinned,
            ModelBone parentBone,
            uint numBones,
            BoundingBox boundingBox)
        {
            Name = name;

            ParentBone = parentBone;
            NumBones   = numBones;

            BoundingBox = boundingBox;

            Skinned = isSkinned;

            _vertexBuffer = AddDisposable(StaticBuffer.Create(
                                              graphicsDevice,
                                              uploadBatch,
                                              vertices));

            _indexBuffer = AddDisposable(StaticBuffer.Create(
                                             graphicsDevice,
                                             uploadBatch,
                                             indices));

            _materialsBuffer = AddDisposable(StaticBuffer.Create(
                                                 graphicsDevice,
                                                 uploadBatch,
                                                 vertexMaterials));

            _textures = AddDisposable(new TextureSet(graphicsDevice, textures));

            foreach (var materialPass in materialPasses)
            {
                AddDisposable(materialPass);
            }
            MaterialPasses = materialPasses;
        }
コード例 #14
0
ファイル: Texture.cs プロジェクト: ElonGame/OpenSAGE
 public static Texture CreatePlaceholderTexture2D(
     GraphicsDevice graphicsDevice,
     ResourceUploadBatch uploadBatch)
 {
     return(CreateTexture2D(
                graphicsDevice,
                uploadBatch,
                PixelFormat.Rgba8UNorm,
                1,
                1,
                new[]
     {
         new TextureMipMapData
         {
             BytesPerRow = 4,
             Data = new byte[] { 255, 105, 180, 255 }
         }
     }));
 }
コード例 #15
0
ファイル: TextureLoader.cs プロジェクト: ElonGame/OpenSAGE
        private static Texture CreateTextureFromTga(
            GraphicsDevice graphicsDevice,
            ResourceUploadBatch uploadBatch,
            TgaFile tgaFile,
            bool generateMipMaps)
        {
            if (tgaFile.Header.ImageType != TgaImageType.UncompressedRgb)
            {
                throw new InvalidOperationException();
            }

            var data = ConvertTgaPixels(
                tgaFile.Header.ImagePixelSize,
                tgaFile.Data);

            TextureMipMapData[] mipMapData;
            if (generateMipMaps)
            {
                mipMapData = MipMapUtility.GenerateMipMaps(
                    tgaFile.Header.Width,
                    tgaFile.Header.Height,
                    data);
            }
            else
            {
                mipMapData = new[]
                {
                    new TextureMipMapData
                    {
                        Data        = data,
                        BytesPerRow = tgaFile.Header.Width * 4
                    }
                };
            }

            return(Texture.CreateTexture2D(
                       graphicsDevice,
                       uploadBatch,
                       PixelFormat.Rgba8UNorm,
                       tgaFile.Header.Width,
                       tgaFile.Header.Height,
                       mipMapData));
        }
コード例 #16
0
ファイル: Texture.cs プロジェクト: ElonGame/OpenSAGE
        private Texture(
            GraphicsDevice graphicsDevice,
            ResourceUploadBatch uploadBatch,
            PixelFormat pixelFormat,
            int width,
            int height,
            TextureMipMapData[] mipMapData)
            : base(graphicsDevice)
        {
            Width       = width;
            Height      = height;
            MipMapCount = mipMapData.Length;

            PlatformConstruct(
                graphicsDevice,
                uploadBatch,
                pixelFormat,
                width,
                height,
                mipMapData);
        }
コード例 #17
0
ファイル: ModelLoader.cs プロジェクト: ElonGame/OpenSAGE
        private static ModelMesh CreateModelMesh(
            ContentManager contentManager,
            ResourceUploadBatch uploadBatch,
            W3dMesh w3dMesh,
            ModelBone parentBone,
            int numBones)
        {
            var materialPasses = new ModelMeshMaterialPass[w3dMesh.MaterialPasses.Length];

            for (var i = 0; i < materialPasses.Length; i++)
            {
                materialPasses[i] = CreateModelMeshMaterialPass(
                    contentManager.GraphicsDevice,
                    uploadBatch,
                    w3dMesh,
                    w3dMesh.MaterialPasses[i]);
            }

            var boundingBox = new BoundingBox(
                w3dMesh.Header.Min,
                w3dMesh.Header.Max);

            var isSkinned = w3dMesh.Header.Attributes.HasFlag(W3dMeshFlags.GeometryTypeSkin);

            return(new ModelMesh(
                       contentManager.GraphicsDevice,
                       uploadBatch,
                       w3dMesh.Header.MeshName,
                       CreateVertices(w3dMesh, isSkinned),
                       CreateIndices(w3dMesh),
                       CreateMaterials(w3dMesh),
                       CreateTextures(contentManager, uploadBatch, w3dMesh),
                       materialPasses,
                       isSkinned,
                       parentBone,
                       (uint)numBones,
                       boundingBox));
        }
コード例 #18
0
ファイル: ModelLoader.cs プロジェクト: ElonGame/OpenSAGE
        private static Texture[] CreateTextures(
            ContentManager contentManager,
            ResourceUploadBatch uploadBatch,
            W3dMesh w3dMesh)
        {
            var numTextures = w3dMesh.Textures.Count;
            var textures    = new Texture[numTextures];

            for (var i = 0; i < numTextures; i++)
            {
                var w3dTexture = w3dMesh.Textures[i];

                if (w3dTexture.TextureInfo != null && w3dTexture.TextureInfo.FrameCount != 1)
                {
                    throw new NotImplementedException();
                }

                var w3dTextureFilePath = Path.Combine("Art", "Textures", w3dTexture.Name);
                textures[i] = contentManager.Load <Texture>(w3dTextureFilePath, uploadBatch);
            }

            return(textures);
        }
コード例 #19
0
ファイル: TextureLoader.cs プロジェクト: ElonGame/OpenSAGE
        private static Texture CreateTextureFromDds(
            GraphicsDevice graphicsDevice,
            ResourceUploadBatch uploadBatch,
            DdsFile ddsFile)
        {
            var mipMapData = new TextureMipMapData[ddsFile.Header.MipMapCount];

            for (var i = 0; i < ddsFile.Header.MipMapCount; i++)
            {
                mipMapData[i] = new TextureMipMapData
                {
                    Data        = ddsFile.MipMaps[i].Data,
                    BytesPerRow = (int)ddsFile.MipMaps[i].RowPitch
                };
            }

            return(Texture.CreateTexture2D(
                       graphicsDevice,
                       uploadBatch,
                       ToPixelFormat(ddsFile.ImageFormat),
                       (int)ddsFile.Header.Width,
                       (int)ddsFile.Header.Height,
                       mipMapData));
        }
コード例 #20
0
 protected abstract T LoadEntry(FileSystemEntry entry, ContentManager contentManager, ResourceUploadBatch uploadBatch);
コード例 #21
0
ファイル: ContentLoader.cs プロジェクト: ElonGame/OpenSAGE
 public abstract object Load(FileSystemEntry entry, ContentManager contentManager, ResourceUploadBatch uploadBatch);
コード例 #22
0
ファイル: MapLoader.cs プロジェクト: ElonGame/OpenSAGE
        private static StaticBuffer <TerrainVertex> CreateVertexBuffer(
            GraphicsDevice graphicsDevice,
            ResourceUploadBatch uploadBatch,
            HeightMap heightMap,
            Int32Rect patchBounds,
            ushort[] indices,
            out BoundingBox boundingBox,
            out Triangle[] triangles)
        {
            var numVertices = patchBounds.Width * patchBounds.Height;

            var vertices = new TerrainVertex[numVertices];
            var points   = new Vector3[numVertices];

            var vertexIndex = 0;

            for (var y = patchBounds.Y; y < patchBounds.Y + patchBounds.Height; y++)
            {
                for (var x = patchBounds.X; x < patchBounds.X + patchBounds.Width; x++)
                {
                    var position = heightMap.GetPosition(x, y);
                    points[vertexIndex]     = position;
                    vertices[vertexIndex++] = new TerrainVertex
                    {
                        Position = position,
                        Normal   = heightMap.Normals[x, y],
                        UV       = new Vector2(x, y)
                    };
                }
            }

            boundingBox = BoundingBox.CreateFromPoints(points);

            triangles = new Triangle[(patchBounds.Width - 1) * (patchBounds.Height) * 2];

            var triangleIndex = 0;
            var indexIndex    = 0;

            for (var y = 0; y < patchBounds.Height - 1; y++)
            {
                for (var x = 0; x < patchBounds.Width - 1; x++)
                {
                    // Triangle 1
                    triangles[triangleIndex++] = new Triangle
                    {
                        V0 = points[indices[indexIndex++]],
                        V1 = points[indices[indexIndex++]],
                        V2 = points[indices[indexIndex++]]
                    };

                    // Triangle 2
                    triangles[triangleIndex++] = new Triangle
                    {
                        V0 = points[indices[indexIndex++]],
                        V1 = points[indices[indexIndex++]],
                        V2 = points[indices[indexIndex++]]
                    };
                }
            }

            return(StaticBuffer.Create(
                       graphicsDevice,
                       uploadBatch,
                       vertices));
        }
コード例 #23
0
ファイル: ModelLoader.cs プロジェクト: ElonGame/OpenSAGE
        protected override Model LoadEntry(FileSystemEntry entry, ContentManager contentManager, ResourceUploadBatch uploadBatch)
        {
            var w3dFile = W3dFile.FromFileSystemEntry(entry);

            var w3dHierarchy = w3dFile.Hierarchy;

            if (w3dFile.HLod != null && w3dHierarchy == null)
            {
                // Load referenced hierarchy.
                var hierarchyFileName  = w3dFile.HLod.Header.HierarchyName + ".W3D";
                var hierarchyFilePath  = Path.Combine(Path.GetDirectoryName(w3dFile.FilePath), hierarchyFileName);
                var hierarchyFileEntry = contentManager.FileSystem.GetFile(hierarchyFilePath);
                var hierarchyFile      = W3dFile.FromFileSystemEntry(hierarchyFileEntry);
                w3dHierarchy = hierarchyFile.Hierarchy;
            }

            return(CreateModel(
                       contentManager,
                       uploadBatch,
                       w3dFile,
                       w3dHierarchy));
        }
コード例 #24
0
ファイル: ModelLoader.cs プロジェクト: ElonGame/OpenSAGE
        // One ModelMeshMaterialPass for each W3D_CHUNK_MATERIAL_PASS
        private static ModelMeshMaterialPass CreateModelMeshMaterialPass(
            GraphicsDevice graphicsDevice,
            ResourceUploadBatch uploadBatch,
            W3dMesh w3dMesh,
            W3dMaterialPass w3dMaterialPass)
        {
            var hasTextureStage0 = w3dMaterialPass.TextureStages.Count > 0;
            var textureStage0    = hasTextureStage0
                ? w3dMaterialPass.TextureStages[0]
                : null;

            var hasTextureStage1 = w3dMaterialPass.TextureStages.Count > 1;
            var textureStage1    = hasTextureStage1
                ? w3dMaterialPass.TextureStages[1]
                : null;

            var numTextureStages = hasTextureStage0 && hasTextureStage1
                ? 2u
                : hasTextureStage0 ? 1u : 0u;

            var texCoords = new MeshTexCoords[w3dMesh.Header.NumVertices];

            if (hasTextureStage0)
            {
                for (var i = 0; i < texCoords.Length; i++)
                {
                    // TODO: What to do when this is null?
                    if (textureStage0.TexCoords != null)
                    {
                        texCoords[i].UV0 = textureStage0.TexCoords[i];
                    }

                    if (hasTextureStage1)
                    {
                        texCoords[i].UV1 = textureStage1.TexCoords[i];
                    }
                }
            }

            var textureIndices = new MeshTextureIndex[w3dMesh.Header.NumTris];

            if (hasTextureStage0)
            {
                if (textureStage0.TextureIds.Length == 1)
                {
                    var textureID = textureStage0.TextureIds[0];
                    for (var i = 0; i < textureIndices.Length; i++)
                    {
                        textureIndices[i].IndexStage0 = textureID;
                    }
                }
                else
                {
                    for (var i = 0; i < textureIndices.Length; i++)
                    {
                        textureIndices[i].IndexStage0 = textureStage0.TextureIds[i];
                    }
                }
            }

            if (hasTextureStage1)
            {
                if (textureStage1.TextureIds.Length == 1)
                {
                    var textureID = textureStage1.TextureIds[0];
                    for (var i = 0; i < textureIndices.Length; i++)
                    {
                        textureIndices[i].IndexStage1 = textureID;
                    }
                }
                else
                {
                    for (var i = 0; i < textureIndices.Length; i++)
                    {
                        textureIndices[i].IndexStage1 = textureStage1.TextureIds[i];
                    }
                }
            }

            var materialIndices = w3dMaterialPass.VertexMaterialIds;

            if (materialIndices.Length == 1)
            {
                var materialID = materialIndices[0];
                materialIndices = new uint[w3dMesh.Header.NumVertices];
                for (var i = 0; i < w3dMesh.Header.NumVertices; i++)
                {
                    materialIndices[i] = materialID;
                }
            }

            var meshParts = new List <ModelMeshPart>();

            if (w3dMaterialPass.ShaderIds.Length == 1)
            {
                meshParts.Add(CreateModelMeshPart(
                                  0,
                                  w3dMesh.Header.NumTris * 3,
                                  w3dMesh,
                                  w3dMesh.Shaders[w3dMaterialPass.ShaderIds[0]]));
            }
            else
            {
                var shaderID   = w3dMaterialPass.ShaderIds[0];
                var startIndex = 0u;
                var indexCount = 0u;
                for (var i = 0; i < w3dMaterialPass.ShaderIds.Length; i++)
                {
                    var newShaderID = w3dMaterialPass.ShaderIds[i];

                    if (shaderID != newShaderID)
                    {
                        meshParts.Add(CreateModelMeshPart(
                                          startIndex,
                                          indexCount,
                                          w3dMesh,
                                          w3dMesh.Shaders[shaderID]));

                        startIndex = (uint)(i * 3);
                        indexCount = 0;
                    }

                    shaderID = newShaderID;

                    indexCount += 3;
                }

                if (indexCount > 0)
                {
                    meshParts.Add(CreateModelMeshPart(
                                      startIndex,
                                      indexCount,
                                      w3dMesh,
                                      w3dMesh.Shaders[shaderID]));
                }
            }

            return(new ModelMeshMaterialPass(
                       graphicsDevice,
                       uploadBatch,
                       numTextureStages,
                       texCoords,
                       textureIndices,
                       materialIndices,
                       meshParts));
        }
コード例 #25
0
ファイル: MapLoader.cs プロジェクト: ElonGame/OpenSAGE
        protected override Scene LoadEntry(FileSystemEntry entry, ContentManager contentManager, ResourceUploadBatch uploadBatch)
        {
            contentManager.IniDataContext.LoadIniFile(@"Data\INI\Terrain.ini");

            var mapFile = MapFile.FromFileSystemEntry(entry);

            var result = new Scene();

            result.Settings.LightingConfigurations = mapFile.GlobalLighting.LightingConfigurations.ToLightSettingsDictionary();
            result.Settings.TimeOfDay = mapFile.GlobalLighting.Time;

            var heightMap = new HeightMap(mapFile.HeightMapData);

            result.HeightMap = heightMap;

            var terrainEntity = new Entity();

            result.Entities.Add(terrainEntity);

            terrainEntity.Components.Add(new TerrainComponent
            {
                HeightMap = heightMap
            });

            var terrainEffect = AddDisposable(new TerrainEffect(
                                                  contentManager.GraphicsDevice,
                                                  mapFile.BlendTileData.Textures.Length));

            var pipelineStateSolid = new EffectPipelineState(
                RasterizerStateDescription.CullBackSolid,
                DepthStencilStateDescription.Default,
                BlendStateDescription.Opaque)
                                     .GetHandle();

            var indexBufferCache = AddDisposable(new TerrainPatchIndexBufferCache(contentManager.GraphicsDevice));

            CreatePatches(
                contentManager.GraphicsDevice,
                uploadBatch,
                terrainEntity,
                heightMap,
                mapFile.BlendTileData,
                terrainEffect,
                pipelineStateSolid,
                indexBufferCache);

            var tileDataTexture = AddDisposable(CreateTileDataTexture(
                                                    contentManager.GraphicsDevice,
                                                    uploadBatch,
                                                    mapFile,
                                                    heightMap));

            var cliffDetailsBuffer = AddDisposable(CreateCliffDetails(
                                                       contentManager.GraphicsDevice,
                                                       uploadBatch,
                                                       mapFile));

            CreateTextures(
                contentManager,
                uploadBatch,
                mapFile.BlendTileData,
                out var textures,
                out var textureDetails);

            var textureDetailsBuffer = AddDisposable(StaticBuffer.Create(
                                                         contentManager.GraphicsDevice,
                                                         uploadBatch,
                                                         textureDetails));

            var textureSet = AddDisposable(new TextureSet(
                                               contentManager.GraphicsDevice,
                                               textures));

            terrainEffect.SetTileData(tileDataTexture);
            terrainEffect.SetCliffDetails(cliffDetailsBuffer);
            terrainEffect.SetTextureDetails(textureDetailsBuffer);
            terrainEffect.SetTextures(textureSet);

            var objectsEntity = new Entity();

            result.Entities.Add(objectsEntity);
            LoadObjects(
                contentManager,
                objectsEntity,
                heightMap,
                mapFile.ObjectsList.Objects,
                result.Settings);

            foreach (var team in mapFile.SidesList.Teams)
            {
                var name        = (string)team.Properties["teamName"].Value;
                var owner       = (string)team.Properties["teamOwner"].Value;
                var isSingleton = (bool)team.Properties["teamIsSingleton"].Value;
            }

            foreach (var waypointPath in mapFile.WaypointsList.WaypointPaths)
            {
                var start = result.Settings.Waypoints[waypointPath.StartWaypointID];
                var end   = result.Settings.Waypoints[waypointPath.EndWaypointID];

                result.Settings.WaypointPaths[start.Name] = new Settings.WaypointPath(
                    start, end);
            }

            var scriptsEntity = new Entity();

            result.Entities.Add(scriptsEntity);

            // TODO: Don't hardcode this.
            // Perhaps add one ScriptComponent for the neutral player,
            // and one for the active player.
            var scriptList = mapFile.SidesList.PlayerScripts.ScriptLists[0];

            AddScripts(scriptsEntity, scriptList, result.Settings);

            return(result);
        }
コード例 #26
0
ファイル: TextureLoader.cs プロジェクト: ElonGame/OpenSAGE
        protected override Texture LoadEntry(FileSystemEntry entry, ContentManager contentManager, ResourceUploadBatch uploadBatch)
        {
            switch (Path.GetExtension(entry.FilePath).ToLower())
            {
            case ".dds":
                var ddsFile = DdsFile.FromFileSystemEntry(entry);
                return(CreateTextureFromDds(
                           contentManager.GraphicsDevice,
                           uploadBatch,
                           ddsFile));

            case ".tga":
                var tgaFile = TgaFile.FromFileSystemEntry(entry);
                return(CreateTextureFromTga(
                           contentManager.GraphicsDevice,
                           uploadBatch,
                           tgaFile,
                           true)); // TODO: Don't need to generate mipmaps for GUI textures.

            default:
                throw new InvalidOperationException();
            }
        }
コード例 #27
0
ファイル: ModelLoader.cs プロジェクト: ElonGame/OpenSAGE
        private static Model CreateModel(
            ContentManager contentManager,
            ResourceUploadBatch uploadBatch,
            W3dFile w3dFile,
            W3dHierarchyDef w3dHierarchy)
        {
            ModelBone[] bones;
            if (w3dHierarchy != null)
            {
                if (w3dHierarchy.Pivots.Length > ModelMesh.MaxBones)
                {
                    throw new NotSupportedException();
                }

                bones = new ModelBone[w3dHierarchy.Pivots.Length];

                for (var i = 0; i < w3dHierarchy.Pivots.Length; i++)
                {
                    var pivot = w3dHierarchy.Pivots[i];

                    var parent = pivot.ParentIdx == -1
                        ? null
                        : bones[pivot.ParentIdx];

                    bones[i] = new ModelBone(
                        i,
                        pivot.Name,
                        parent,
                        pivot.Translation,
                        pivot.Rotation);
                }
            }
            else
            {
                bones    = new ModelBone[1];
                bones[0] = new ModelBone(0, null, null, Vector3.Zero, Quaternion.Identity);
            }

            //BoundingSphere boundingSphere = default(BoundingSphere);

            var meshes = new ModelMesh[w3dFile.Meshes.Count];

            for (var i = 0; i < w3dFile.Meshes.Count; i++)
            {
                var w3dMesh = w3dFile.Meshes[i];

                ModelBone bone;
                if (w3dFile.HLod != null)
                {
                    var hlodSubObject = w3dFile.HLod.Lods[0].SubObjects.Single(x => x.Name == w3dMesh.Header.ContainerName + "." + w3dMesh.Header.MeshName);
                    bone = bones[(int)hlodSubObject.BoneIndex];
                }
                else
                {
                    bone = bones[0];
                }

                meshes[i] = CreateModelMesh(
                    contentManager,
                    uploadBatch,
                    w3dMesh,
                    bone,
                    bones.Length);

                //var meshBoundingSphere = mesh.BoundingSphere.Transform(bone.Transform);

                //boundingSphere = (i == 0)
                //    ? meshBoundingSphere
                //    : BoundingSphere.CreateMerged(boundingSphere, meshBoundingSphere);
            }

            var animations = new Animation[w3dFile.Animations.Count + w3dFile.CompressedAnimations.Count];

            for (var i = 0; i < w3dFile.Animations.Count; i++)
            {
                animations[i] = CreateAnimation(w3dFile.Animations[i]);
            }
            for (var i = 0; i < w3dFile.CompressedAnimations.Count; i++)
            {
                animations[w3dFile.Animations.Count + i] = CreateAnimation(w3dFile.CompressedAnimations[i]);
            }

            return(new Model(
                       bones,
                       meshes,
                       animations));
        }
コード例 #28
0
 public sealed override object Load(FileSystemEntry entry, ContentManager contentManager, ResourceUploadBatch uploadBatch)
 {
     return(LoadEntry(entry, contentManager, uploadBatch));
 }