Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
RenderTarget2D.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;
13
14namespace Engine.Graphics {
15 public class RenderTarget2D : Texture2D {
17
18#if DIRECT3D11
19 public RenderTargetView m_colorTextureView;
20
21 public SharpDX.Direct3D11.Texture2D m_depthTexture;
22
23 public DepthStencilView m_depthTextureView;
24#else
25 public int m_frameBuffer;
26
27 public int m_depthBuffer;
28#endif
29
31 get => m_depthFormat;
32 set => m_depthFormat = value;
33 }
34
35 public RenderTarget2D(int width, int height, int mipLevelsCount, ColorFormat colorFormat, DepthFormat depthFormat) : base(
36 width,
37 height,
38 mipLevelsCount,
39 colorFormat
40 ) {
41 try {
42 InitializeRenderTarget2D(width, height, mipLevelsCount, colorFormat, depthFormat);
44 }
45 catch {
46 Dispose();
47 throw;
48 }
49 }
50
51 public override void Dispose() {
52 base.Dispose();
54 }
55
56 public void GetData<T>(T[] target, int targetStartIndex, Rectangle sourceRectangle) where T : unmanaged {
57 VerifyParametersGetData(target, targetStartIndex, sourceRectangle);
58 GCHandle gCHandle = GCHandle.Alloc(target, GCHandleType.Pinned);
59 try {
60 int num = Utilities.SizeOf<T>();
61 GetDataInternal(gCHandle.AddrOfPinnedObject() + targetStartIndex * num, sourceRectangle);
62 }
63 finally {
64 gCHandle.Free();
65 }
66 }
67
68 public unsafe Image GetData(Rectangle sourceRectangle) {
70 Image<Rgba32> image = new(Image.DefaultImageSharpConfiguration, sourceRectangle.Width, sourceRectangle.Height);
71 image.DangerousTryGetSinglePixelMemory(out Memory<Rgba32> memory);
72 GetDataInternal((nint)memory.Pin().Pointer, sourceRectangle);
73 return new Image(image);
74 }
75
76 public void GetData(nint target, Rectangle sourceRectangle) {
77 VerifyParametersGetData(target, sourceRectangle);
78 GetDataInternal(target, sourceRectangle);
79 }
80
81 public void GetDataInternal(nint target, Rectangle sourceRectangle) {
82#if DIRECT3D11
83 int size = ColorFormat.GetSize();
84 Texture2DDescription texture2DDescription = new() {
85 ArraySize = 1,
86 BindFlags = BindFlags.None,
87 CpuAccessFlags = CpuAccessFlags.Read,
89 MipLevels = 1,
90 OptionFlags = ResourceOptionFlags.None,
91 SampleDescription = new SampleDescription(1, 0),
92 Usage = ResourceUsage.Staging,
93 Width = sourceRectangle.Width,
94 Height = sourceRectangle.Height
95 };
96 using (SharpDX.Direct3D11.Texture2D texture2D = new(DXWrapper.Device, texture2DDescription)) {
97 ResourceRegion resourceRegion = new(
98 sourceRectangle.Left,
99 sourceRectangle.Top,
100 0,
101 sourceRectangle.Left + sourceRectangle.Width,
102 sourceRectangle.Top + sourceRectangle.Height,
103 1
104 );
105 DXWrapper.Context.CopySubresourceRegion(m_texture, 0, resourceRegion, texture2D, 0);
106 DataStream dataStream = null;
107 try {
108 DataBox dataBox = DXWrapper.Context.MapSubresource(texture2D, 0, MapMode.Read, SharpDX.Direct3D11.MapFlags.None, out dataStream);
109 int num = 0;
110 for (int i = 0; i < sourceRectangle.Height; i++) {
111 dataStream.Position = i * dataBox.RowPitch;
112 dataStream.Read(target, num * size, sourceRectangle.Width * size);
113 num += sourceRectangle.Width;
114 }
115 }
116 finally {
117 dataStream?.Dispose();
118 }
119 }
120#else
121 unsafe {
123 GLWrapper.GL.ReadPixels(
124 sourceRectangle.Left,
125 sourceRectangle.Top,
126 (uint)sourceRectangle.Width,
127 (uint)sourceRectangle.Height,
128 PixelFormat.Rgba,
129 PixelType.UnsignedByte,
130 target.ToPointer()
131 );
132 }
133#endif
134 }
135
136 public void GenerateMipMaps() {
137#if DIRECT3D11
138 DXWrapper.Context.GenerateMips(m_textureView);
139#else
140 GLWrapper.BindTexture(TextureTarget.Texture2D, m_texture, false);
141 GLWrapper.GL.GenerateMipmap(TextureTarget.Texture2D);
142#endif
143 }
144
145 public override void HandleDeviceLost() {
147 }
148
149 public override void HandleDeviceReset() {
150#if DIRECT3D11
151 base.HandleDeviceReset();
152#endif
154 }
155
156 public void AllocateRenderTarget() {
157#if DIRECT3D11
158 m_colorTextureView = new RenderTargetView(DXWrapper.Device, m_texture);
159 if (DepthFormat != DepthFormat.None) {
160 Texture2DDescription texture2DDescription = new() {
161 ArraySize = 1,
162 BindFlags = BindFlags.DepthStencil,
163 CpuAccessFlags = CpuAccessFlags.None,
165 MipLevels = 1,
166 OptionFlags = ResourceOptionFlags.None,
167 SampleDescription = new SampleDescription(1, 0),
168 Usage = ResourceUsage.Default,
169 Width = Width,
170 Height = Height
171 };
172 m_depthTexture = new SharpDX.Direct3D11.Texture2D(DXWrapper.Device, texture2DDescription);
173 m_depthTextureView = new DepthStencilView(DXWrapper.Device, m_depthTexture);
174 }
175#else
176 GLWrapper.GL.GenFramebuffers(1u, out uint frameBuffer);
177 m_frameBuffer = (int)frameBuffer;
179 GLWrapper.GL.FramebufferTexture2D(
180 FramebufferTarget.Framebuffer,
181 FramebufferAttachment.ColorAttachment0,
182 TextureTarget.Texture2D,
183 (uint)m_texture,
184 0
185 );
186 if (DepthFormat != DepthFormat.None) {
187 GLWrapper.GL.GenRenderbuffers(1u, out uint depthBuffer);
188 m_depthBuffer = (int)depthBuffer;
189 GLWrapper.GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, depthBuffer);
190 GLWrapper.GL.RenderbufferStorage(
191 RenderbufferTarget.Renderbuffer,
193 (uint)Width,
194 (uint)Height
195 );
196 GLWrapper.GL.FramebufferRenderbuffer(
197 FramebufferTarget.Framebuffer,
198 FramebufferAttachment.DepthAttachment,
199 RenderbufferTarget.Renderbuffer,
200 depthBuffer
201 );
202 GLWrapper.GL.FramebufferRenderbuffer(
203 FramebufferTarget.Framebuffer,
204 FramebufferAttachment.StencilAttachment,
205 RenderbufferTarget.Renderbuffer,
206 0
207 );
208 }
209 else {
210 GLWrapper.GL.FramebufferRenderbuffer(
211 FramebufferTarget.Framebuffer,
212 FramebufferAttachment.DepthAttachment,
213 RenderbufferTarget.Renderbuffer,
214 0
215 );
216 GLWrapper.GL.FramebufferRenderbuffer(
217 FramebufferTarget.Framebuffer,
218 FramebufferAttachment.StencilAttachment,
219 RenderbufferTarget.Renderbuffer,
220 0
221 );
222 }
223 GLEnum framebufferErrorCode = GLWrapper.GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer);
224 if (framebufferErrorCode != GLEnum.FramebufferComplete) {
225 throw new InvalidOperationException($"Error creating framebuffer ({framebufferErrorCode.ToString()}).");
226 }
227#endif
228 }
229
230 public void DeleteRenderTarget() {
231#if DIRECT3D11
232 Utilities.Dispose(ref m_colorTextureView);
233 Utilities.Dispose(ref m_depthTexture);
234 Utilities.Dispose(ref m_depthTextureView);
235#else
236 if (m_depthBuffer != 0) {
237 uint depthBuffer = (uint)m_depthBuffer;
238 GLWrapper.GL.DeleteRenderbuffers(1, in depthBuffer);
239 m_depthBuffer = 0;
240 }
241 if (m_frameBuffer != 0) {
243 m_frameBuffer = 0;
244 }
245#endif
246 }
247
248 public new static RenderTarget2D Load(Color color, int width, int height) {
249 RenderTarget2D renderTarget2D = new(width, height, 1, ColorFormat.Rgba8888, DepthFormat.None);
250 Color[] array = new Color[width * height];
251 for (int i = 0; i < array.Length; i++) {
252 array[i] = color;
253 }
254 renderTarget2D.SetData(0, array);
255 return renderTarget2D;
256 }
257
258 public new static RenderTarget2D Load(Image image, int mipLevelsCount = 1) {
259 RenderTarget2D renderTarget2D = new(image.Width, image.Height, mipLevelsCount, ColorFormat.Rgba8888, DepthFormat.None);
260 renderTarget2D.SetData(image.m_trueImage);
261 if (mipLevelsCount > 1) {
262#if DIRECT3D11
263 DXWrapper.Context.GenerateMips(renderTarget2D.m_textureView);
264#else
265 GLWrapper.BindTexture(TextureTarget.Texture2D, renderTarget2D.m_texture, false);
266 GLWrapper.GL.GenerateMipmap(TextureTarget.Texture2D);
267#endif
268 }
269 return renderTarget2D;
270 }
271
272 public new static RenderTarget2D Load(Stream stream, bool premultiplyAlpha = false, int mipLevelsCount = 1) {
273 Image image = Image.Load(stream);
274 if (premultiplyAlpha) {
275 Image.PremultiplyAlpha(image);
276 }
277 return Load(image, mipLevelsCount);
278 }
279
280 public new static RenderTarget2D Load(string fileName, bool premultiplyAlpha = false, int mipLevelsCount = 1) {
281 using Stream stream = Storage.OpenFile(fileName, OpenFileMode.Read);
282 return Load(stream, premultiplyAlpha, mipLevelsCount);
283 }
284
285 public static Image Save(RenderTarget2D renderTarget) {
286 if (renderTarget.ColorFormat != ColorFormat.Rgba8888) {
287 throw new InvalidOperationException("Unsupported color format.");
288 }
289 return renderTarget.GetData(new Rectangle(0, 0, renderTarget.Width, renderTarget.Height));
290 }
291
292 public static void Save(RenderTarget2D renderTarget, Stream stream, ImageFileFormat format, bool saveAlpha) {
293 if (renderTarget.ColorFormat != ColorFormat.Rgba8888) {
294 throw new InvalidOperationException("Unsupported color format.");
295 }
296 Image.Save(renderTarget.GetData(new Rectangle(0, 0, renderTarget.Width, renderTarget.Height)), stream, format, saveAlpha);
297 }
298
299 public static void Save(RenderTarget2D renderTarget, string fileName, ImageFileFormat format, bool saveAlpha) {
300 using Stream stream = Storage.OpenFile(fileName, OpenFileMode.Create);
301 Save(renderTarget, stream, format, saveAlpha);
302 }
303
304 public override int GetGpuMemoryUsage() => base.GetGpuMemoryUsage() + DepthFormat.GetSize() * Width * Height;
305
306 // ReSharper disable UnusedParameter.Local
307 void InitializeRenderTarget2D(int width, int height, int mipLevelsCount, ColorFormat colorFormat, DepthFormat depthFormat)
308 // ReSharper restore UnusedParameter.Local
309 {
310 DepthFormat = depthFormat;
311 }
312
313 void VerifyParametersGetData<T>(T[] target, int targetStartIndex, Rectangle sourceRectangle) where T : unmanaged {
315 int size = ColorFormat.GetSize();
316 int num = Utilities.SizeOf<T>();
317 ArgumentNullException.ThrowIfNull(target);
318 if (num > size) {
319 throw new ArgumentException("Target array element size is larger than pixel size.");
320 }
321 if (size % num != 0) {
322 throw new ArgumentException("Pixel size is not an integer multiple of target array element size.");
323 }
324 if (sourceRectangle.Left < 0
325 || sourceRectangle.Width <= 0
326 || sourceRectangle.Top < 0
327 || sourceRectangle.Height <= 0
328 || sourceRectangle.Left + sourceRectangle.Width > Width
329 || sourceRectangle.Top + sourceRectangle.Height > Height) {
330 throw new ArgumentOutOfRangeException(nameof(sourceRectangle));
331 }
332 if (targetStartIndex < 0
333 || targetStartIndex >= target.Length) {
334 throw new ArgumentOutOfRangeException(nameof(targetStartIndex));
335 }
336 if ((target.Length - targetStartIndex) * num < sourceRectangle.Width * sourceRectangle.Height * size) {
337 throw new InvalidOperationException("Not enough space in target array.");
338 }
339 }
340
341 public void VerifyParametersGetData(nint target, Rectangle sourceRectangle) {
343 if (target == IntPtr.Zero) {
344 throw new ArgumentNullException(nameof(target));
345 }
346 if (sourceRectangle.Left < 0
347 || sourceRectangle.Width <= 0
348 || sourceRectangle.Top < 0
349 || sourceRectangle.Height <= 0
350 || sourceRectangle.Left + sourceRectangle.Width > Width
351 || sourceRectangle.Top + sourceRectangle.Height > Height) {
352 throw new ArgumentOutOfRangeException(nameof(sourceRectangle));
353 }
354 }
355
356 public static void VerifyParametersSwap(RenderTarget2D renderTarget1, RenderTarget2D renderTarget2) {
357 if (renderTarget1 == null) {
358 throw new ArgumentNullException(nameof(renderTarget1));
359 }
360 if (renderTarget2 == null) {
361 throw new ArgumentNullException(nameof(renderTarget2));
362 }
363 renderTarget1.VerifyNotDisposed();
364 renderTarget2.VerifyNotDisposed();
365 }
366 }
367}
unsafe
定义 Main.cs:15
Engine.Media.Image Image
static DeviceContext2 Context
static Format TranslateDepthFormat(DepthFormat depthFormat)
static Format TranslateColorFormat(ColorFormat colorFormat)
static void DeleteFramebuffer(int framebuffer)
static void BindFramebuffer(int framebuffer)
static void BindTexture(TextureTarget target, int texture, bool forceBind)
static InternalFormat TranslateDepthFormat(DepthFormat depthFormat)
static void VerifyParametersSwap(RenderTarget2D renderTarget1, RenderTarget2D renderTarget2)
static void Save(RenderTarget2D renderTarget, string fileName, ImageFileFormat format, bool saveAlpha)
static void Save(RenderTarget2D renderTarget, Stream stream, ImageFileFormat format, bool saveAlpha)
void InitializeRenderTarget2D(int width, int height, int mipLevelsCount, ColorFormat colorFormat, DepthFormat depthFormat)
void GetData(nint target, Rectangle sourceRectangle)
unsafe Image GetData(Rectangle sourceRectangle)
static new RenderTarget2D Load(Color color, int width, int height)
static Image Save(RenderTarget2D renderTarget)
void VerifyParametersGetData< T >(T[] target, int targetStartIndex, Rectangle sourceRectangle)
void VerifyParametersGetData(nint target, Rectangle sourceRectangle)
static new RenderTarget2D Load(string fileName, bool premultiplyAlpha=false, int mipLevelsCount=1)
static new RenderTarget2D Load(Image image, int mipLevelsCount=1)
void GetDataInternal(nint target, Rectangle sourceRectangle)
static new RenderTarget2D Load(Stream stream, bool premultiplyAlpha=false, int mipLevelsCount=1)
RenderTarget2D(int width, int height, int mipLevelsCount, ColorFormat colorFormat, DepthFormat depthFormat)
void GetData< T >(T[] target, int targetStartIndex, Rectangle sourceRectangle)
virtual void SetData(int mipLevel, nint source)
static Image Load(Stream stream, ImageFileFormat format)
readonly Image< Rgba32 > m_trueImage
static void PremultiplyAlpha(Image image)
static Configuration DefaultImageSharpConfiguration
static void Save(Image image, Stream stream, ImageFileFormat format, bool saveAlpha, bool sync=false)
static Stream OpenFile(string path, OpenFileMode openFileMode)