Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
CompressedTexture2D.cs
浏览该文件的文档.
1#if !DIRECT3D11
2using System.Runtime.InteropServices;
3using Silk.NET.OpenGLES;
4using SixLabors.ImageSharp;
5using SixLabors.ImageSharp.PixelFormats;
6#pragma warning disable CS0809 // 过时成员重写未过时成员
7namespace Engine.Graphics {
8 // Only ASTC support
10 InternalFormat m_internalFormat;
13
15
16 public CompressedTexture2D(int width, int height, int mipLevelsCount, ColorFormat colorFormat, int blockWidth, int blockHeight) {
18 throw new NotSupportedException("ASTC texture is not supported on this device.");
19 }
20 InitializeTexture2D(width, height, mipLevelsCount, colorFormat);
21 m_blockWidth = blockWidth;
22 m_blockHeight = blockHeight;
23 m_internalFormat = (ColorFormat, footprintWidth: blockWidth, footprintHeight: blockHeight) switch {
24 (ColorFormat.LinearLDR, 4, 4) => InternalFormat.CompressedRgbaAstc4x4,
25 (ColorFormat.SrgbLDR, 4, 4) => InternalFormat.CompressedSrgb8Alpha8Astc4x4,
26 (ColorFormat.LinearLDR, 5, 4) => InternalFormat.CompressedRgbaAstc5x4,
27 (ColorFormat.SrgbLDR, 5, 4) => InternalFormat.CompressedSrgb8Alpha8Astc5x4,
28 (ColorFormat.LinearLDR, 5, 5) => InternalFormat.CompressedRgbaAstc5x5,
29 (ColorFormat.SrgbLDR, 5, 5) => InternalFormat.CompressedSrgb8Alpha8Astc5x5,
30 (ColorFormat.LinearLDR, 6, 5) => InternalFormat.CompressedRgbaAstc6x5,
31 (ColorFormat.SrgbLDR, 6, 5) => InternalFormat.CompressedSrgb8Alpha8Astc6x5,
32 (ColorFormat.LinearLDR, 6, 6) => InternalFormat.CompressedRgbaAstc6x6,
33 (ColorFormat.SrgbLDR, 6, 6) => InternalFormat.CompressedSrgb8Alpha8Astc6x6,
34 (ColorFormat.LinearLDR, 8, 5) => InternalFormat.CompressedRgbaAstc8x5,
35 (ColorFormat.SrgbLDR, 8, 5) => InternalFormat.CompressedSrgb8Alpha8Astc8x5,
36 (ColorFormat.LinearLDR, 8, 6) => InternalFormat.CompressedRgbaAstc8x6,
37 (ColorFormat.SrgbLDR, 8, 6) => InternalFormat.CompressedSrgb8Alpha8Astc8x6,
38 (ColorFormat.LinearLDR, 8, 8) => InternalFormat.CompressedRgbaAstc8x8,
39 (ColorFormat.SrgbLDR, 8, 8) => InternalFormat.CompressedSrgb8Alpha8Astc8x8,
40 (ColorFormat.LinearLDR, 10, 5) => InternalFormat.CompressedRgbaAstc10x5,
41 (ColorFormat.SrgbLDR, 10, 5) => InternalFormat.CompressedSrgb8Alpha8Astc10x5,
42 (ColorFormat.LinearLDR, 10, 6) => InternalFormat.CompressedRgbaAstc10x6,
43 (ColorFormat.SrgbLDR, 10, 6) => InternalFormat.CompressedSrgb8Alpha8Astc10x6,
44 (ColorFormat.LinearLDR, 10, 8) => InternalFormat.CompressedRgbaAstc10x8,
45 (ColorFormat.SrgbLDR, 10, 8) => InternalFormat.CompressedSrgb8Alpha8Astc10x8,
46 (ColorFormat.LinearLDR, 10, 10) => InternalFormat.CompressedRgbaAstc10x10,
47 (ColorFormat.SrgbLDR, 10, 10) => InternalFormat.CompressedSrgb8Alpha8Astc10x10,
48 (ColorFormat.LinearLDR, 12, 10) => InternalFormat.CompressedRgbaAstc12x10,
49 (ColorFormat.SrgbLDR, 12, 10) => InternalFormat.CompressedSrgb8Alpha8Astc12x10,
50 (ColorFormat.LinearLDR, 12, 12) => InternalFormat.CompressedRgbaAstc12x12,
51 (ColorFormat.SrgbLDR, 12, 12) => InternalFormat.CompressedSrgb8Alpha8Astc12x12,
52 _ => throw new InvalidOperationException("Unsupported surface format.")
53 };
55 }
56
57 public override void AllocateTexture() {
58 GLWrapper.GL.GenTextures(1, out uint texture);
59 m_texture = (int)texture;
60 GLWrapper.BindTexture(TextureTarget.Texture2D, m_texture, false);
61 }
62
63 [Obsolete("Invalid", true)]
64 public override void SetData<T>(int mipLevel, T[] source, int sourceStartIndex = 0) where T : struct => throw new InvalidOperationException();
65
66 [Obsolete("Invalid", true)]
67 public override void SetData(int mipLevel, nint source) => throw new InvalidOperationException();
68
69 [Obsolete("Invalid", true)]
70 public override void SetDataInternal(int mipLevel, nint source) => throw new InvalidOperationException();
71
72 [Obsolete("Invalid", true)]
73 public override unsafe void SetDataInternal(int mipLevel, void* source) => throw new InvalidOperationException();
74
75 [Obsolete("Invalid", true)]
76 public override void SetData(Image<Rgba32> source) => throw new InvalidOperationException();
77
78 [Obsolete("Invalid", true)]
79 public override void SetData(int mipLevel, Image<Rgba32> source) => throw new InvalidOperationException();
80
81 public void SetData(int mipLevel, int imageSize, nint source) {
82 VerifyParametersSetData(mipLevel, imageSize, source);
83 SetDataInternal(mipLevel, imageSize, source);
84 }
85
86 public unsafe void SetData(int mipLevel, int imageSize, void* source) {
87 VerifyParametersSetData(mipLevel, imageSize, source);
88 SetDataInternal(mipLevel, imageSize, source);
89 }
90
91 public void SetData(int mipLevel, Span<byte> source) {
92 VerifyParametersSetData(mipLevel, source);
93 SetDataInternal(mipLevel, source);
94 }
95
96 public void SetDataInternal(int mipLevel, int imageSize, nint source) {
97 int width = MathUtils.Max(Width >> mipLevel, 1);
98 int height = MathUtils.Max(Height >> mipLevel, 1);
99 GLWrapper.GL.CompressedTexImage2D(
100 TextureTarget.Texture2D,
101 mipLevel,
103 (uint)width,
104 (uint)height,
105 0,
106 (uint)imageSize,
107 in source
108 );
109 }
110
111 public unsafe void SetDataInternal(int mipLevel, int imageSize, void* source) {
112 int width = MathUtils.Max(Width >> mipLevel, 1);
113 int height = MathUtils.Max(Height >> mipLevel, 1);
114 GLWrapper.GL.CompressedTexImage2D(
115 TextureTarget.Texture2D,
116 mipLevel,
118 (uint)width,
119 (uint)height,
120 0,
121 (uint)imageSize,
122 source
123 );
124 }
125
126 public unsafe void SetDataInternal(int mipLevel, Span<byte> source) {
127 int width = MathUtils.Max(Width >> mipLevel, 1);
128 int height = MathUtils.Max(Height >> mipLevel, 1);
129 fixed (byte* p = &MemoryMarshal.GetReference(source)) {
130 uint imageSize = (uint)source.Length;
131 GLWrapper.GL.CompressedTexImage2D(
132 TextureTarget.Texture2D,
133 mipLevel,
135 (uint)width,
136 (uint)height,
137 0,
138 imageSize,
139 p
140 );
141 }
142 }
143
144 public override int GetGpuMemoryUsage() {
145 int result = 0;
146 int width = Width;
147 int height = Height;
148 while (width > 0
149 || height > 0) {
150 int blocksX = (width + m_blockWidth - 1) / m_blockWidth;
151 int blocksY = (height + m_blockHeight - 1) / m_blockHeight;
152 result += blocksX * blocksY * 16;
153 width = Math.Max(1, width >> 1);
154 height = Math.Max(1, height >> 1);
155 if (width == 1
156 && height == 1) {
157 break;
158 }
159 }
160 return result;
161 }
162
163 public new static CompressedTexture2D Load(Stream stream, bool linear = true, int mipLevelsCount = 1) {
164 if (stream.Length < 16) {
165 throw new Exception("Invalid ASTC stream.");
166 }
167 byte[] buffer = new byte[stream.Length];
168 stream.Position = 0;
169 if (stream.Read(buffer) != stream.Length) {
170 throw new Exception($"Failed to read stream. The stream length is {stream.Length} bytes, but the stream was only read {stream.Position} bytes.");
171 }
172 if (buffer[0] != 0x13 || buffer[1] != 0xAB ||
173 buffer[2] != 0xA1 || buffer[3] != 0x5C) {
174 throw new Exception("Invalid ASTC stream.");
175 }
176 byte blockWidth = buffer[4];
177 byte blockHeight = buffer[5];
178 int width = buffer[7] | (buffer[8] << 8) | (buffer[9] << 16);
179 int height = buffer[10] | (buffer[11] << 8) | (buffer[12] << 16);
181 width,
182 height,
183 mipLevelsCount,
184 linear ? ColorFormat.LinearLDR : ColorFormat.SrgbLDR,
185 blockWidth,
186 blockHeight
187 );
188 texture2D.SetData(0, buffer.AsSpan().Slice(16));
189 if (mipLevelsCount > 1) {
190 //下面代码对于 ASTC 来说不可用,必须手动生成 Mipmap 然后 SetData
191 //GLWrapper.BindTexture(TextureTarget.Texture2D, texture2D.m_texture, false);
192 //GLWrapper.GL.GenerateMipmap(TextureTarget.Texture2D);
193 }
194 return texture2D;
195 }
196
197 public static bool GetParameters(Stream stream, out int width, out int height, out int blockWidth, out int blockHeight) {
198 if (stream.Length < 16) {
199 width = 0;
200 height = 0;
201 blockWidth = 0;
202 blockHeight = 0;
203 return false;
204 }
205 byte[] buffer = new byte[13];
206 stream.Position = 0;
207 stream.ReadExactly(buffer, 0, 12);
208 if (buffer[0] != 0x13 || buffer[1] != 0xAB ||
209 buffer[2] != 0xA1 || buffer[3] != 0x5C) {
210 width = 0;
211 height = 0;
212 blockWidth = 0;
213 blockHeight = 0;
214 return false;
215 }
216 blockWidth = buffer[4];
217 blockHeight = buffer[5];
218 width = buffer[7] | (buffer[8] << 8) | (buffer[9] << 16);
219 height = buffer[10] | (buffer[11] << 8) | (buffer[12] << 16);
220 return true;
221 }
222
223 public override void InitializeTexture2D(int width, int height, int mipLevelsCount, ColorFormat colorFormat) {
224 if (width < 1) {
225 throw new ArgumentOutOfRangeException(nameof(width));
226 }
227 if (height < 1) {
228 throw new ArgumentOutOfRangeException(nameof(height));
229 }
230 if (mipLevelsCount < 1) {
231 throw new ArgumentOutOfRangeException(nameof(mipLevelsCount));
232 }
233 if (colorFormat != ColorFormat.LinearLDR && colorFormat != ColorFormat.SrgbLDR) {
234 throw new ArgumentException(nameof(colorFormat));
235 }
236 Width = width;
237 Height = height;
238 ColorFormat = colorFormat;
239 if (mipLevelsCount > 1) {
240 int num = 0;
241 for (int num2 = MathUtils.Max(width, height); num2 >= 1; num2 /= 2) {
242 num++;
243 }
244 MipLevelsCount = MathUtils.Min(num, mipLevelsCount);
245 }
246 else {
247 MipLevelsCount = 1;
248 }
249 }
250
251 public void VerifyParametersSetData(int mipLevel, int imageSize, nint source) {
252 VerifyParametersSetData(mipLevel, source);
253 if (imageSize <= 0) {
254 throw new ArgumentNullException(nameof(imageSize));
255 }
256 }
257
258 public unsafe void VerifyParametersSetData(int mipLevel, int imageSize, void* source) {
260 if (mipLevel < 0
261 || mipLevel >= MipLevelsCount) {
262 throw new ArgumentOutOfRangeException(nameof(mipLevel));
263 }
264 if (imageSize <= 0) {
265 throw new ArgumentNullException(nameof(imageSize));
266 }
267 if (source == null) {
268 throw new ArgumentNullException(nameof(source));
269 }
270 }
271
272 public void VerifyParametersSetData(int mipLevel, Span<byte> source) {
274 if (mipLevel < 0
275 || mipLevel >= MipLevelsCount) {
276 throw new ArgumentOutOfRangeException(nameof(mipLevel));
277 }
278 if (source.IsEmpty) {
279 throw new ArgumentNullException(nameof(source));
280 }
281 }
282 }
283}
284#endif
unsafe
定义 Main.cs:15
Engine.Media.Image Image
void SetData(int mipLevel, Span< byte > source)
void VerifyParametersSetData(int mipLevel, Span< byte > source)
override void SetData(int mipLevel, nint source)
static new CompressedTexture2D Load(Stream stream, bool linear=true, int mipLevelsCount=1)
unsafe void SetData(int mipLevel, int imageSize, void *source)
override void SetDataInternal(int mipLevel, nint source)
unsafe void VerifyParametersSetData(int mipLevel, int imageSize, void *source)
void VerifyParametersSetData(int mipLevel, int imageSize, nint source)
void SetDataInternal(int mipLevel, int imageSize, nint source)
override void SetData< T >(int mipLevel, T[] source, int sourceStartIndex=0)
override void InitializeTexture2D(int width, int height, int mipLevelsCount, ColorFormat colorFormat)
CompressedTexture2D(int width, int height, int mipLevelsCount, ColorFormat colorFormat, int blockWidth, int blockHeight)
static bool GetParameters(Stream stream, out int width, out int height, out int blockWidth, out int blockHeight)
unsafe void SetDataInternal(int mipLevel, int imageSize, void *source)
unsafe void SetDataInternal(int mipLevel, Span< byte > source)
static bool GL_KHR_texture_compression_astc_ldr
static void BindTexture(TextureTarget target, int texture, bool forceBind)
static int Min(int x1, int x2)
static int Max(int x1, int x2)