Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
Texture2D.cs
浏览该文件的文档.
1#if DIRECT3D11
2using SharpDX.DXGI;
3using SharpDX;
4using SharpDX.Direct3D11;
5#else
6using Silk.NET.OpenGLES;
7#endif
8using System.Runtime.InteropServices;
9using Engine.Media;
10using SixLabors.ImageSharp;
11using SixLabors.ImageSharp.PixelFormats;
12using Image = Engine.Media.Image;
13
14namespace Engine.Graphics {
15 public class Texture2D : GraphicsResource {
20 object m_tag;
22#if DIRECT3D11
23 public SharpDX.Direct3D11.Texture2D m_texture;
24 public ShaderResourceView m_textureView;
25
26 public IntPtr NativeHandle => m_texture.NativePointer;
27#else
28 public int m_texture;
29 public PixelFormat m_pixelFormat;
30 public PixelType m_pixelType;
31
32 public IntPtr NativeHandle => m_texture;
33#endif
34
35 public string DebugName {
36 get {
37#if DIRECT3D11
38 return m_texture.DebugName;
39#else
40 return m_debugName;
41#endif
42 }
43 set {
44#if DIRECT3D11
45 m_texture.DebugName = value;
46#else
47 m_debugName = value;
48#endif
49 }
50 }
51
52 public int Width {
53 get => m_width;
54 set => m_width = value;
55 }
56
57 public int Height {
58 get => m_height;
59 set => m_height = value;
60 }
61
63 get => m_colorFormat;
64 set => m_colorFormat = value;
65 }
66
67 public int MipLevelsCount {
68 get => m_mipLevelsCount;
69 set => m_mipLevelsCount = value;
70 }
71
72 public object Tag {
73 get => m_tag;
74 set => m_tag = value;
75 }
76
77 public Texture2D() { }
78
79 public Texture2D(int width, int height, int mipLevelsCount, ColorFormat colorFormat) {
80 InitializeTexture2D(width, height, mipLevelsCount, colorFormat);
81#if !DIRECT3D11
82 switch (ColorFormat) {
83 case ColorFormat.Rgba8888:
84 m_pixelFormat = PixelFormat.Rgba;
85 m_pixelType = PixelType.UnsignedByte;
86 break;
87 case ColorFormat.Rgb565:
88 m_pixelFormat = PixelFormat.Rgb;
89 m_pixelType = PixelType.UnsignedShort565;
90 break;
91 case ColorFormat.Rgba5551:
92 m_pixelFormat = PixelFormat.Rgba;
93 m_pixelType = PixelType.UnsignedShort5551;
94 break;
95 case ColorFormat.R8:
96 m_pixelFormat = (PixelFormat)6409; // GL_LUMINANCE, avoid warning "Deprecated in version 3.2"
97 m_pixelType = PixelType.UnsignedByte;
98 break;
99 default: throw new InvalidOperationException("Unsupported surface format.");
100 }
101#endif
103 }
104
105 public override void Dispose() {
106 base.Dispose();
108 }
109
110 public virtual void SetData<T>(int mipLevel, T[] source, int sourceStartIndex = 0) where T : unmanaged {
111 VerifyParametersSetData(mipLevel, source, sourceStartIndex);
112 GCHandle gCHandle = GCHandle.Alloc(source, GCHandleType.Pinned);
113 try {
114 int num = Utilities.SizeOf<T>();
115 SetDataInternal(mipLevel, gCHandle.AddrOfPinnedObject() + sourceStartIndex * num);
116 }
117 finally {
118 gCHandle.Free();
119 }
120 }
121
122 public virtual void SetData(int mipLevel, nint source) {
123 VerifyParametersSetData(mipLevel, source);
124 SetDataInternal(mipLevel, source);
125 }
126
127 public virtual void SetDataInternal(int mipLevel, nint source) {
128#if DIRECT3D11
129 int num = ColorFormat.GetSize() * Math.Max(Width >> mipLevel, 1);
130 DataBox dataBox = new(source, num, 0);
131 DXWrapper.Context.UpdateSubresource(dataBox, m_texture, mipLevel);
132#else
133 int width = MathUtils.Max(Width >> mipLevel, 1);
134 int height = MathUtils.Max(Height >> mipLevel, 1);
135 GLWrapper.BindTexture(TextureTarget.Texture2D, m_texture, false);
136 GLWrapper.GL.TexImage2D(
137 TextureTarget.Texture2D,
138 mipLevel,
139 (InternalFormat)m_pixelFormat,
140 (uint)width,
141 (uint)height,
142 0,
145 in source
146 );
147#endif
148 }
149
150 public virtual unsafe void SetDataInternal(int mipLevel, void* source) {
151#if DIRECT3D11
152 int num = ColorFormat.GetSize() * Math.Max(Width >> mipLevel, 1);
153 DataBox dataBox = new((nint)source, num, 0);
154 DXWrapper.Context.UpdateSubresource(dataBox, m_texture, mipLevel);
155#else
156 int width = MathUtils.Max(Width >> mipLevel, 1);
157 int height = MathUtils.Max(Height >> mipLevel, 1);
158 GLWrapper.BindTexture(TextureTarget.Texture2D, m_texture, false);
159 GLWrapper.GL.TexImage2D(
160 TextureTarget.Texture2D,
161 mipLevel,
162 (InternalFormat)m_pixelFormat,
163 (uint)width,
164 (uint)height,
165 0,
168 source
169 );
170#endif
171 }
172
173 public virtual void SetData(Image<Rgba32> source) {
174 SetData(0, source);
175 }
176
177 public virtual unsafe void SetData(int mipLevel, Image<Rgba32> source) {
179 source.DangerousTryGetSinglePixelMemory(out Memory<Rgba32> memory);
180 SetDataInternal(mipLevel, memory.Pin().Pointer);
181 }
182
183 public static void Swap(Texture2D texture1, Texture2D texture2) {
184 VerifyParametersSwap(texture1, texture2);
185 SwapTexture2D(texture1, texture2);
186 Utilities.Swap(ref texture1.m_texture, ref texture2.m_texture);
187#if DIRECT3D11
188 Utilities.Swap(ref texture1.m_textureView, ref texture2.m_textureView);
189#else
190 Utilities.Swap(ref texture1.m_pixelFormat, ref texture2.m_pixelFormat);
191 Utilities.Swap(ref texture1.m_pixelType, ref texture2.m_pixelType);
192#endif
193 Utilities.Swap(ref texture1.m_debugName, ref texture2.m_debugName);
194 }
195
196 public static void SwapTexture2D(Texture2D texture1, Texture2D texture2) {
197 Utilities.Swap(ref texture1.m_width, ref texture2.m_width);
198 Utilities.Swap(ref texture1.m_height, ref texture2.m_height);
199 Utilities.Swap(ref texture1.m_colorFormat, ref texture2.m_colorFormat);
200 Utilities.Swap(ref texture1.m_mipLevelsCount, ref texture2.m_mipLevelsCount);
201 Utilities.Swap(ref texture1.m_tag, ref texture2.m_tag);
202 }
203
204 public override void HandleDeviceLost() {
206 }
207
208 public override void HandleDeviceReset() {
210 }
211
212 public virtual void AllocateTexture() {
213#if DIRECT3D11
214 bool flag = this is RenderTarget2D || MipLevelsCount > 1;
215 Texture2DDescription texture2DDescription = new() {
216 ArraySize = 1,
217 BindFlags = flag ? BindFlags.ShaderResource | BindFlags.RenderTarget : BindFlags.ShaderResource,
218 CpuAccessFlags = CpuAccessFlags.None,
220 MipLevels = MipLevelsCount,
221 OptionFlags = flag ? ResourceOptionFlags.GenerateMipMaps : ResourceOptionFlags.None,
222 SampleDescription = new SampleDescription(1, 0),
223 Usage = ResourceUsage.Default,
224 Width = Width,
225 Height = Height
226 };
227 m_texture = new SharpDX.Direct3D11.Texture2D(DXWrapper.Device, texture2DDescription);
228 m_textureView = new ShaderResourceView(DXWrapper.Device, m_texture);
229#else
230 unsafe {
231 GLWrapper.GL.GenTextures(1, out uint texture);
232 m_texture = (int)texture;
233 GLWrapper.BindTexture(TextureTarget.Texture2D, m_texture, false);
234 for (int i = 0; i < MipLevelsCount; i++) {
235 int width = MathUtils.Max(Width >> i, 1);
236 int height = MathUtils.Max(Height >> i, 1);
237 GLWrapper.GL.TexImage2D(
238 TextureTarget.Texture2D,
239 i,
240 (InternalFormat)m_pixelFormat,
241 (uint)width,
242 (uint)height,
243 0,
246 null
247 );
248 }
249 }
250#endif
251 }
252
253 public void DeleteTexture() {
254#if DIRECT3D11
255 Utilities.Dispose(ref m_texture);
256 Utilities.Dispose(ref m_textureView);
257#else
258 if (m_texture != 0) {
260 m_texture = 0;
261 }
262#endif
263 }
264
265 public override int GetGpuMemoryUsage() {
266 int num = 0;
267 for (int i = 0; i < MipLevelsCount; i++) {
268 int num2 = MathUtils.Max(Width >> i, 1);
269 int num3 = MathUtils.Max(Height >> i, 1);
270 num += ColorFormat.GetSize() * num2 * num3;
271 }
272 return num;
273 }
274
275 public static Texture2D Load(LegacyImage image, int mipLevelsCount = 1) {
276 Texture2D texture2D = new(image.Width, image.Height, mipLevelsCount, ColorFormat.Rgba8888);
277 if (mipLevelsCount > 1) {
278 LegacyImage[] array = LegacyImage.GenerateMipmaps(image, mipLevelsCount).ToArray();
279 for (int i = 0; i < array.Length; i++) {
280 texture2D.SetData(i, array[i].Pixels);
281 }
282 }
283 else {
284 texture2D.SetData(0, image.Pixels);
285 }
286 texture2D.Tag = image;
287 return texture2D;
288 }
289
290 public static Texture2D Load(Image image, int mipLevelsCount = 1) {
291 Texture2D texture2D = new(image.Width, image.Height, mipLevelsCount, ColorFormat.Rgba8888);
292 texture2D.SetData(image.m_trueImage);
293 if (mipLevelsCount > 1) {
294#if DIRECT3D11
295 DXWrapper.Context.GenerateMips(texture2D.m_textureView);
296#else
297 GLWrapper.BindTexture(TextureTarget.Texture2D, texture2D.m_texture, false);
298 GLWrapper.GL.GenerateMipmap(TextureTarget.Texture2D);
299#endif
300 }
301 texture2D.Tag = image;
302 return texture2D;
303 }
304
305 public static Texture2D Load(Image<Rgba32> image, int mipLevelsCount = 1) {
306 Texture2D texture2D = new(image.Width, image.Height, mipLevelsCount, ColorFormat.Rgba8888);
307 texture2D.SetData(image);
308 if (mipLevelsCount > 1) {
309#if DIRECT3D11
310 DXWrapper.Context.GenerateMips(texture2D.m_textureView);
311#else
312 GLWrapper.BindTexture(TextureTarget.Texture2D, texture2D.m_texture, false);
313 GLWrapper.GL.GenerateMipmap(TextureTarget.Texture2D);
314#endif
315 }
316 texture2D.Tag = new Image(image);
317 return texture2D;
318 }
319
320 public static Texture2D Load(Stream stream, bool premultiplyAlpha = false, int mipLevelsCount = 1) {
321 Image image = Image.Load(stream);
322 if (premultiplyAlpha) {
323 Image.PremultiplyAlpha(image);
324 }
325 return Load(image, mipLevelsCount);
326 }
327
328 public static Texture2D Load(string fileName, bool premultiplyAlpha = false, int mipLevelsCount = 1) {
329 using (Stream stream = Storage.OpenFile(fileName, OpenFileMode.Read)) {
330 return Load(stream, premultiplyAlpha, mipLevelsCount);
331 }
332 }
333
334 public static Texture2D Load(Color color, int width, int height) {
335 Texture2D texture2D = new(width, height, 1, ColorFormat.Rgba8888);
336 Color[] array = new Color[width * height];
337 for (int i = 0; i < array.Length; i++) {
338 array[i] = color;
339 }
340 texture2D.SetData(0, array);
341 return texture2D;
342 }
343
344 public virtual void InitializeTexture2D(int width, int height, int mipLevelsCount, ColorFormat colorFormat) {
345 if (width < 1) {
346 throw new ArgumentOutOfRangeException(nameof(width));
347 }
348 if (height < 1) {
349 throw new ArgumentOutOfRangeException(nameof(height));
350 }
351 if (mipLevelsCount < 1) {
352 throw new ArgumentOutOfRangeException(nameof(mipLevelsCount));
353 }
354 if (colorFormat == ColorFormat.LinearLDR || colorFormat == ColorFormat.SrgbLDR) {
355 throw new ArgumentException(nameof(colorFormat));
356 }
357 Width = width;
358 Height = height;
359 ColorFormat = colorFormat;
360 if (mipLevelsCount > 1) {
361 int num = 0;
362 for (int num2 = MathUtils.Max(width, height); num2 >= 1; num2 /= 2) {
363 num++;
364 }
365 MipLevelsCount = MathUtils.Min(num, mipLevelsCount);
366 }
367 else {
368 MipLevelsCount = 1;
369 }
370 }
371
372 public virtual void VerifyParametersSetData<T>(int mipLevel, T[] source, int sourceStartIndex = 0) where T : unmanaged {
374 int num = Utilities.SizeOf<T>();
375 int size = ColorFormat.GetSize();
376 int num2 = MathUtils.Max(Width >> mipLevel, 1);
377 int num3 = MathUtils.Max(Height >> mipLevel, 1);
378 int num4 = size * num2 * num3;
379 ArgumentNullException.ThrowIfNull(source);
380 if (mipLevel < 0
381 || mipLevel >= MipLevelsCount) {
382 throw new ArgumentOutOfRangeException(nameof(mipLevel));
383 }
384 if (num > size) {
385 throw new ArgumentException("Source array element size is larger than pixel size.");
386 }
387 if (size % num != 0) {
388 throw new ArgumentException("Pixel size is not an integer multiple of source array element size.");
389 }
390 if (sourceStartIndex < 0
391 || (source.Length - sourceStartIndex) * num < num4) {
392 throw new InvalidOperationException("Not enough data in source array.");
393 }
394 }
395
396 public virtual void VerifyParametersSetData(int mipLevel, nint source) {
398 if (source == IntPtr.Zero) {
399 throw new ArgumentNullException(nameof(source));
400 }
401 if (mipLevel < 0
402 || mipLevel >= MipLevelsCount) {
403 throw new ArgumentOutOfRangeException(nameof(mipLevel));
404 }
405 }
406
407 static void VerifyParametersSwap(Texture2D texture1, Texture2D texture2) {
408 if (texture1 == null) {
409 throw new ArgumentNullException(nameof(texture1));
410 }
411 if (texture2 == null) {
412 throw new ArgumentNullException(nameof(texture2));
413 }
414 if (texture1.GetType() != typeof(Texture2D)) {
415 throw new ArgumentException("texture1");
416 }
417 if (texture2.GetType() != typeof(Texture2D)) {
418 throw new ArgumentException("texture2");
419 }
420 texture1.VerifyNotDisposed();
421 texture2.VerifyNotDisposed();
422 }
423
426 ArgumentNullException.ThrowIfNull(source);
427 }
428 }
429}
unsafe
定义 Main.cs:15
Engine.Media.Image Image
static DeviceContext2 Context
static Format TranslateColorFormat(ColorFormat colorFormat)
static void BindTexture(TextureTarget target, int texture, bool forceBind)
static void DeleteTexture(int texture)
override void HandleDeviceLost()
virtual void VerifyParametersSetData(int mipLevel, nint source)
static Texture2D Load(Stream stream, bool premultiplyAlpha=false, int mipLevelsCount=1)
static Texture2D Load(string fileName, bool premultiplyAlpha=false, int mipLevelsCount=1)
virtual void SetData(Image< Rgba32 > source)
virtual void VerifyParametersSetData< T >(int mipLevel, T[] source, int sourceStartIndex=0)
static void SwapTexture2D(Texture2D texture1, Texture2D texture2)
virtual void SetDataInternal(int mipLevel, nint source)
virtual unsafe void SetData(int mipLevel, Image< Rgba32 > source)
virtual void SetData(int mipLevel, nint source)
Texture2D(int width, int height, int mipLevelsCount, ColorFormat colorFormat)
static void VerifyParametersSwap(Texture2D texture1, Texture2D texture2)
static Texture2D Load(LegacyImage image, int mipLevelsCount=1)
static Texture2D Load(Image image, int mipLevelsCount=1)
static Texture2D Load(Image< Rgba32 > image, int mipLevelsCount=1)
static Texture2D Load(Color color, int width, int height)
virtual unsafe void SetDataInternal(int mipLevel, void *source)
override void HandleDeviceReset()
virtual void InitializeTexture2D(int width, int height, int mipLevelsCount, ColorFormat colorFormat)
static void Swap(Texture2D texture1, Texture2D texture2)
void VerifyParametersSetData(Image< Rgba32 > source)
virtual void SetData< T >(int mipLevel, T[] source, int sourceStartIndex=0)
static int Min(int x1, int x2)
static int Max(int x1, int x2)
static Image Load(Stream stream, ImageFileFormat format)
readonly Image< Rgba32 > m_trueImage
static void PremultiplyAlpha(Image image)
static IEnumerable< LegacyImage > GenerateMipmaps(LegacyImage image, int maxLevelsCount=int.MaxValue)
static Stream OpenFile(string path, OpenFileMode openFileMode)