protected internal override Texture3D Read(ContentReader reader, Texture3D existingInstance) { var format = (SurfaceFormat)reader.ReadInt32(); int width = reader.ReadInt32(); int height = reader.ReadInt32(); int depth = reader.ReadInt32(); int levelCount = reader.ReadInt32(); var texture = existingInstance ?? new Texture3D( reader.GetGraphicsDevice(), width, height, depth, levelCount > 1, format); for (int i = 0; i < levelCount; i++) { int dataSize = reader.ReadInt32(); using (var buffer = reader.ContentManager.GetScratchBuffer(dataSize)) { reader.Read(buffer.AsSpan(0, dataSize)); texture.SetData(i, 0, 0, width, height, 0, depth, buffer.AsSpan(0, dataSize)); } // Calculate dimensions of next mip level. width = Math.Max(width / 2, 1); height = Math.Max(height / 2, 1); depth = Math.Max(depth / 2, 1); } return(texture); }
protected internal override TextureCube Read(ContentReader reader, TextureCube existingInstance) { var surfaceFormat = (SurfaceFormat)reader.ReadInt32(); int size = reader.ReadInt32(); int levels = reader.ReadInt32(); TextureCube textureCube = existingInstance ?? new TextureCube(reader.GetGraphicsDevice(), size, levels > 1, surfaceFormat); for (int face = 0; face < 6; face++) { for (int i = 0; i < levels; i++) { int faceSize = reader.ReadInt32(); using (var buffer = reader.ContentManager.GetScratchBuffer(faceSize)) { if (reader.Read(buffer.AsSpan(0, faceSize)) != faceSize) { throw new InvalidDataException(); } textureCube.SetData((CubeMapFace)face, i, null, buffer.AsSpan(0, faceSize)); } } } return(textureCube); }
protected internal override VertexBuffer Read(ContentReader input, VertexBuffer existingInstance) { var vertexBuffer = existingInstance; var declaration = input.ReadRawObject <VertexDeclaration>(); int elementCount = (int)input.ReadUInt32(); int dataSize = elementCount * declaration.VertexStride; using (var data = input.ContentManager.GetScratchBuffer(dataSize)) { if (input.Read(data.AsSpan(0, dataSize)) != dataSize) { throw new InvalidDataException(); } if (vertexBuffer == null || vertexBuffer.VertexDeclaration != declaration || vertexBuffer.Capacity < elementCount) { vertexBuffer = new VertexBuffer( input.GetGraphicsDevice(), declaration, elementCount, BufferUsage.None); } vertexBuffer.SetData(data.AsSpan(0, dataSize)); return(vertexBuffer); } }
protected internal override IndexBuffer Read(ContentReader input, IndexBuffer existingInstance) { IndexBuffer indexBuffer = existingInstance; bool sixteenBits = input.ReadBoolean(); int dataSize = input.ReadInt32(); var elementType = sixteenBits ? IndexElementType.Int16 : IndexElementType.Int32; int elementCount = dataSize / elementType.TypeSize(); using (var buffer = input.ContentManager.GetScratchBuffer(dataSize)) { if (input.Read(buffer.AsSpan(0, dataSize)) != dataSize) { throw new InvalidDataException(); } if (indexBuffer == null || indexBuffer.ElementType != elementType || indexBuffer.Capacity < elementCount) { indexBuffer = new IndexBuffer( input.GetGraphicsDevice(), elementType, elementCount, BufferUsage.None); } indexBuffer.SetData(buffer.AsSpan().Slice(0, dataSize)); return(indexBuffer); } }
protected internal override Effect Read(ContentReader input, Effect existingInstance) { int dataSize = input.ReadInt32(); using (var buffer = input.ContentManager.GetScratchBuffer(dataSize)) { if (input.Read(buffer.AsSpan(0, dataSize)) != dataSize) { throw new InvalidDataException(); } var effect = new Effect(input.GetGraphicsDevice(), buffer.AsSpan(0, dataSize)) { Name = input.AssetName }; return(effect); } }
protected internal override Texture2D Read(ContentReader reader, Texture2D existingInstance) { var surfaceFormat = (SurfaceFormat)reader.ReadInt32(); int width = reader.ReadInt32(); int height = reader.ReadInt32(); int levelCount = reader.ReadInt32(); int levelCountOutput = levelCount; // If the system does not fully support Power of Two textures, // skip any mip maps supplied with any non PoT textures. if (levelCount > 1 && !reader.GetGraphicsDevice().Capabilities.SupportsNonPowerOfTwo&& (!MathHelper.IsPowerOfTwo(width) || !MathHelper.IsPowerOfTwo(height))) { levelCountOutput = 1; System.Diagnostics.Debug.WriteLine( "Device does not support non Power of Two textures. Skipping mipmaps."); } SurfaceFormat convertedFormat = surfaceFormat; switch (surfaceFormat) { case SurfaceFormat.Dxt1: case SurfaceFormat.Dxt1a: if (!reader.GetGraphicsDevice().Capabilities.SupportsDxt1) { convertedFormat = SurfaceFormat.Rgba32; } break; case SurfaceFormat.Dxt1SRgb: if (!reader.GetGraphicsDevice().Capabilities.SupportsDxt1) { convertedFormat = SurfaceFormat.Rgba32SRgb; } break; case SurfaceFormat.Dxt3: case SurfaceFormat.Dxt5: if (!reader.GetGraphicsDevice().Capabilities.SupportsS3tc) { convertedFormat = SurfaceFormat.Rgba32; } break; case SurfaceFormat.Dxt3SRgb: case SurfaceFormat.Dxt5SRgb: if (!reader.GetGraphicsDevice().Capabilities.SupportsS3tc) { convertedFormat = SurfaceFormat.Rgba32SRgb; } break; case SurfaceFormat.NormalizedByte4: convertedFormat = SurfaceFormat.Rgba32; break; } var texture = existingInstance ?? new Texture2D( reader.GetGraphicsDevice(), width, height, levelCountOutput > 1, convertedFormat); for (int level = 0; level < levelCountOutput; level++) { int levelDataSizeInBytes = reader.ReadInt32(); using (var levelDataBuffer = reader.ContentManager.GetScratchBuffer(levelDataSizeInBytes)) { byte[] levelData = levelDataBuffer.Buffer; if (reader.Read(levelData.AsSpan(0, levelDataSizeInBytes)) != levelDataSizeInBytes) { throw new InvalidDataException(); } int levelWidth = Math.Max(width >> level, 1); int levelHeight = Math.Max(height >> level, 1); //Convert the image data if required switch (surfaceFormat) { case SurfaceFormat.Dxt1: case SurfaceFormat.Dxt1SRgb: case SurfaceFormat.Dxt1a: if (!reader.GetGraphicsDevice().Capabilities.SupportsDxt1&& convertedFormat == SurfaceFormat.Rgba32) { levelData = DxtUtil.DecompressDxt1(levelData, levelWidth, levelHeight); levelDataSizeInBytes = levelData.Length; } break; case SurfaceFormat.Dxt3: case SurfaceFormat.Dxt3SRgb: if (!reader.GetGraphicsDevice().Capabilities.SupportsS3tc&& convertedFormat == SurfaceFormat.Rgba32) { levelData = DxtUtil.DecompressDxt3(levelData, levelWidth, levelHeight); levelDataSizeInBytes = levelData.Length; } break; case SurfaceFormat.Dxt5: case SurfaceFormat.Dxt5SRgb: if (!reader.GetGraphicsDevice().Capabilities.SupportsS3tc&& convertedFormat == SurfaceFormat.Rgba32) { levelData = DxtUtil.DecompressDxt5(levelData, levelWidth, levelHeight); levelDataSizeInBytes = levelData.Length; } break; case SurfaceFormat.NormalizedByte4: { int bytesPerPixel = surfaceFormat.GetSize(); int pitch = levelWidth * bytesPerPixel; for (int y = 0; y < levelHeight; y++) { for (int x = 0; x < levelWidth; x++) { int color = BinaryPrimitives.ReadInt32LittleEndian( levelData.AsSpan(y * pitch + x * bytesPerPixel)); levelData[y * pitch + x * 4] = (byte)((color >> 16) & 0xff); //R:=W levelData[y * pitch + x * 4 + 1] = (byte)((color >> 8) & 0xff); //G:=V levelData[y * pitch + x * 4 + 2] = (byte)((color) & 0xff); //B:=U levelData[y * pitch + x * 4 + 3] = (byte)((color >> 24) & 0xff); //A:=Q } } } break; #if OPENGL case SurfaceFormat.Bgra5551: { // Shift the channels to suit OpenGL int offset = 0; for (int y = 0; y < levelHeight; y++) { for (int x = 0; x < levelWidth; x++) { ushort pixel = BinaryPrimitives.ReadUInt16LittleEndian(levelData.AsSpan(offset)); pixel = (ushort)(((pixel & 0x7FFF) << 1) | ((pixel & 0x8000) >> 15)); levelData[offset] = (byte)pixel; levelData[offset + 1] = (byte)(pixel >> 8); offset += 2; } } } break; case SurfaceFormat.Bgra4444: { // Shift the channels to suit OpenGL int offset = 0; for (int y = 0; y < levelHeight; y++) { for (int x = 0; x < levelWidth; x++) { ushort pixel = BinaryPrimitives.ReadUInt16LittleEndian(levelData.AsSpan(offset)); pixel = (ushort)(((pixel & 0x0FFF) << 4) | ((pixel & 0xF000) >> 12)); levelData[offset] = (byte)pixel; levelData[offset + 1] = (byte)(pixel >> 8); offset += 2; } } } break; #endif } texture.SetData(levelData.AsSpan(0, levelDataSizeInBytes), null, level); } } return(texture); }