Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
Texture2DBase.OpenGL.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGL
4 using System;
5 using System.IO;
6 using System.Runtime.InteropServices;
7 using OpenTK.Graphics;
8 
9 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
10 using OpenTK.Graphics.ES30;
11 using PixelFormatGl = OpenTK.Graphics.ES30.PixelFormat;
12 using RenderbufferStorage = OpenTK.Graphics.ES30.RenderbufferInternalFormat;
13 #else
14 using OpenTK.Graphics.OpenGL;
15 using PixelFormatGl = OpenTK.Graphics.OpenGL.PixelFormat;
16 #endif
17 
18 namespace SiliconStudio.Paradox.Graphics
19 {
20  /// <summary>
21  /// Represents a 2D grid of texels.
22  /// </summary>
23  public partial class Texture2DBase
24  {
25  // For depth stencil buffer, we might need to separate depth from stencil storage, so we will have one additional resource id.
26  internal int ResouceIdStencil;
27 
28  internal bool IsRenderbuffer
29  {
30  get
31  {
32  return (Description.Flags & TextureFlags.ShaderResource) == 0
33  && (Description.Flags & TextureFlags.DepthStencil) == TextureFlags.DepthStencil;
34  }
35  }
36 
37  protected internal Texture2DBase(GraphicsDevice device, TextureDescription description2D, TextureTarget textureTarget, DataBox[] dataBoxes = null, bool initialize = true) : base(device, description2D, ViewType.Full, 0, 0)
38  {
39  Target = textureTarget;
40  if (initialize)
41  Init(dataBoxes);
42  }
43 
44  protected internal Texture2DBase(GraphicsDevice device, Texture2DBase texture) : base(device, texture, ViewType.Full, 0, 0)
45  {
46  this.Target = texture.Target;
47  this.resourceId = texture.ResourceId;
48  }
49 
50 
51  /// <summary>
52  /// Inits this instance with the specified texture datas.
53  /// </summary>
54  /// <param name="textureDatas">The texture datas.</param>
55  protected virtual void Init(DataBox[] textureDatas)
56  {
57  using (var creationContext = GraphicsDevice.UseOpenGLCreationContext())
58  {
59  // Can we just do a renderbuffer?
60  if ((Description.Flags & TextureFlags.ShaderResource) == 0)
61  {
62  if ((Description.Flags & TextureFlags.DepthStencil) == TextureFlags.DepthStencil)
63  {
64  RenderbufferStorage depth, stencil;
65  ConvertDepthFormat(GraphicsDevice, Description.Format, out depth, out stencil);
66 
67  // Create depth render buffer (might contain stencil data too)
68  GL.GenRenderbuffers(1, out resourceId);
69  GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, resourceId);
70  GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, depth, Description.Width, Description.Height);
71  if (OpenGLConvertExtensions.GetErrorCode() != ErrorCode.NoError)
72  throw new InvalidOperationException("Could not create render buffer");
73 
74  // If stencil buffer is separate, create it as well
75  if (stencil != 0)
76  {
77  GL.GenRenderbuffers(1, out ResouceIdStencil);
78  GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, ResouceIdStencil);
79  GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, stencil, Description.Width, Description.Height);
80  if (OpenGLConvertExtensions.GetErrorCode() != ErrorCode.NoError)
81  throw new InvalidOperationException("Could not create render buffer");
82  }
83 
84  GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, 0);
85  return;
86  }
87  }
88 
89  PixelInternalFormat internalFormat;
90  PixelFormatGl format;
91  PixelType type;
92  int pixelSize;
93  bool compressed;
94  ConvertPixelFormat(GraphicsDevice, Description.Format, out internalFormat, out format, out type, out pixelSize, out compressed);
95 
96  InternalFormat = internalFormat;
97  FormatGl = format;
98  Type = type;
99  DepthPitch = Description.Width*Description.Height*pixelSize;
100  RowPitch = Description.Width*pixelSize;
101 
102  if (Description.Usage == GraphicsResourceUsage.Staging)
103  {
104 #if !SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
105  GL.GenBuffers(1, out resourceId);
106  GL.BindBuffer(BufferTarget.PixelPackBuffer, resourceId);
107  GL.BufferData(BufferTarget.PixelPackBuffer, (IntPtr)DepthPitch, IntPtr.Zero,
108  BufferUsageHint.StreamRead);
109  GL.BindBuffer(BufferTarget.PixelPackBuffer, 0);
110 #else
111  StagingData = Marshal.AllocHGlobal(DepthPitch);
112 #endif
113  }
114  else
115  {
116  int textureId;
117 
118  // If we're on main context, change internal states so that texture is bound again
119  if (!creationContext.UseDeviceCreationContext)
120  GraphicsDevice.UseTemporaryFirstTexture();
121 
122  GL.GenTextures(1, out textureId);
123  GL.BindTexture(TextureTarget.Texture2D, textureId);
124 
125  // No filtering on depth buffer
126  if ((Description.Flags & (TextureFlags.RenderTarget | TextureFlags.DepthStencil)) !=
127  TextureFlags.None)
128  {
129  GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter,
130  (int)TextureMinFilter.Nearest);
131  GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter,
132  (int)TextureMagFilter.Nearest);
133  GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS,
134  (int)TextureWrapMode.ClampToEdge);
135  GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT,
136  (int)TextureWrapMode.ClampToEdge);
137  }
138 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
139  else if (Description.MipLevels <= 1)
140  {
141  GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
142  GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
143  }
144 #endif
145 
146 #if !SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
147  GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBaseLevel, 0);
148  GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMaxLevel, Description.MipLevels - 1);
149 #endif
150 
151  if (Description.MipLevels == 0)
152  throw new NotImplementedException();
153 
154  for (int i = 0; i < Description.MipLevels; ++i)
155  {
156  IntPtr data = IntPtr.Zero;
157  var width = CalculateMipSize(Description.Width, i);
158  var height = CalculateMipSize(Description.Height, i);
159  if (textureDatas != null && i < textureDatas.Length)
160  {
161  if (!compressed && textureDatas[i].RowPitch != width * pixelSize)
162  throw new NotSupportedException("Can't upload texture with pitch in glTexImage2D.");
163  // Might be possible, need to check API better.
164  data = textureDatas[i].DataPointer;
165  }
166  if (compressed)
167  {
168  GL.CompressedTexImage2D(TextureTarget.Texture2D, i, internalFormat,
169  width, height, 0, textureDatas[i].SlicePitch, data);
170  }
171  else
172  {
173  GL.TexImage2D(TextureTarget.Texture2D, i, internalFormat,
174  width, height, 0, format, type, data);
175  }
176  }
177  GL.BindTexture(TextureTarget.Texture2D, 0);
178 
179  resourceId = textureId;
180  }
181  }
182  }
183 
184  public override void Recreate(DataBox[] dataBoxes = null)
185  {
186  Init(dataBoxes);
187  }
188 
189  /// <inheritdoc/>
190  protected internal override bool OnRecreate()
191  {
192  // Dependency: wait for underlying texture to be recreated
193  if (ParentTexture != null && ParentTexture.LifetimeState != GraphicsResourceLifetimeState.Active)
194  return false;
195 
196  if (ParentTexture != null)
197  {
198  // TODO: Test
199  throw new NotImplementedException();
200 
201  resourceId = ParentTexture.ResourceId;
202  }
203  else
204  {
205  // Render Target / Depth Stencil are considered as "dynamic"
206  if ((Description.Usage == GraphicsResourceUsage.Immutable
207  || Description.Usage == GraphicsResourceUsage.Default)
208  && (Description.Flags & (TextureFlags.RenderTarget | TextureFlags.DepthStencil)) == 0)
209  return false;
210 
211  Init(null);
212  }
213 
214  return true;
215  }
216 
217  /// <summary>
218  /// Computes the mip level count.
219  /// </summary>
220  /// <param name="mipLevels">The mip levels.</param>
221  /// <returns></returns>
222  protected int ComputeLevelCount(int mipLevels)
223  {
224  if (mipLevels > 0)
225  return mipLevels;
226  return (int)Math.Ceiling(Math.Log(Math.Max(Description.Width, Description.Height)) / Math.Log(2.0));
227  }
228  }
229 }
230 
231 #endif
_In_ size_t pixelSize
Definition: DirectXTexP.h:116
GraphicsResourceUsage
Identifies expected resource use during rendering. The usage directly reflects whether a resource is ...
The type of the serialized type will be passed as a generic arguments of the serializer. Example: serializer of A becomes instantiated as Serializer{A}.
ViewType
Defines how a view is selected from a resource.
Definition: ViewType.cs:31
Gets a texture view for the whole texture for all mips/arrays dimensions.
GraphicsResourceLifetimeState
Describes the lifetime state of a graphics resource.
_In_ size_t _In_ size_t _In_ DXGI_FORMAT format
Definition: DirectXTexP.h:175
PixelFormat
Defines various types of pixel formats.
Definition: PixelFormat.cs:32