3 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGL
4 #if SILICONSTUDIO_PLATFORM_ANDROID
5 extern alias opentkold;
8 using System.Collections.Generic;
10 using System.Threading;
11 using OpenTK.Graphics;
12 using OpenTK.Platform;
13 using SiliconStudio.Core;
14 using SiliconStudio.Core.Mathematics;
15 using SiliconStudio.Paradox.Effects.Modules;
16 using SiliconStudio.Paradox.Shaders;
18 #if SILICONSTUDIO_PLATFORM_ANDROID
20 using System.Runtime.InteropServices;
21 using OpenTK.Platform.Android;
22 #elif SILICONSTUDIO_PLATFORM_IOS
23 using OpenTK.Platform.iPhoneOS;
25 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
26 using OpenTK.Graphics.ES30;
27 using FramebufferAttachment = OpenTK.Graphics.ES30.FramebufferSlot;
29 using OpenTK.Graphics.OpenGL;
32 namespace SiliconStudio.
Paradox.Graphics
37 public partial class GraphicsDevice
40 private bool asyncCreationLockTaken;
42 internal bool ApplicationPaused =
false;
44 internal IWindowInfo deviceCreationWindowInfo;
45 internal object asyncCreationLockObject =
new object();
46 internal OpenTK.Graphics.IGraphicsContext deviceCreationContext;
48 #if SILICONSTUDIO_PLATFORM_ANDROID
51 private bool keepContextOnEnd;
53 private IntPtr graphicsContextEglPtr;
54 internal AndroidAsyncGraphicsContext androidAsyncDeviceCreationContext;
55 internal bool AsyncPendingTaskWaiting;
58 internal bool Workaround_VAO_PowerVR_SGX_540;
59 internal bool Workaround_Context_Tegra2_Tegra3;
62 internal SamplerState defaultSamplerState;
63 internal DepthStencilState defaultDepthStencilState;
64 internal BlendState defaultBlendState;
65 internal int versionMajor, versionMinor;
67 internal Texture2D windowProvidedRenderTexture;
68 internal DepthStencilBuffer windowProvidedDepthBuffer;
69 internal Texture2D windowProvidedDepthTexture;
73 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
74 internal bool HasDepth24;
75 internal bool HasPackedDepthStencilExtension;
76 internal bool HasExtTextureFormatBGRA8888;
79 private int windowProvidedFrameBuffer;
82 private GraphicsDevice immediateContext;
83 private GraphicsAdapter _adapter;
84 private SwapChainBackend _defaultSwapChainBackend;
85 private Viewport[] _currentViewports =
new Viewport[16];
86 private int contextBeginCounter = 0;
88 private int activeTexture = 0;
91 internal Dictionary<FBOKey, int> existingFBOs =
new Dictionary<FBOKey,int>();
96 private PrimitiveType _currentPrimitiveType = PrimitiveType.Undefined;
98 private static GraphicsDevice _currentGraphicsDevice;
100 [ThreadStatic]
private static List<GraphicsDevice> _graphicsDevicesInUse;
102 public static GraphicsDevice Current
106 if (_graphicsDevicesInUse != null && _graphicsDevicesInUse.Count > 0)
107 return _graphicsDevicesInUse[_graphicsDevicesInUse.Count - 1];
109 return _currentGraphicsDevice;
114 _currentGraphicsDevice = value;
118 private OpenTK.Graphics.IGraphicsContext graphicsContext;
119 private OpenTK.Platform.IWindowInfo windowInfo;
121 #if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
122 private OpenTK.GameWindow gameWindow;
123 #elif SILICONSTUDIO_PLATFORM_ANDROID
124 private AndroidGameView gameWindow;
125 #elif SILICONSTUDIO_PLATFORM_IOS
126 private iPhoneOSGameView gameWindow;
130 private VertexArrayObject currentVertexArrayObject;
131 private VertexArrayObject boundVertexArrayObject;
132 internal uint enabledVertexAttribArrays;
133 private DepthStencilState boundDepthStencilState;
134 private int boundStencilReference;
135 private BlendState boundBlendState;
136 private RasterizerState boundRasterizerState;
137 private DepthStencilBuffer boundDepthStencilBuffer;
139 private int boundFBO;
140 internal bool hasRenderTarget, hasDepthStencilBuffer;
141 private int boundFBOHeight;
142 private int boundProgram = 0;
143 private bool needUpdateFBO =
true;
144 private DrawElementsType drawElementsType;
145 private int indexElementSize;
146 private IntPtr indexBufferOffset;
147 private bool flipRenderTarget =
false;
148 private FrontFaceDirection currentFrontFace = FrontFaceDirection.Ccw;
149 private FrontFaceDirection boundFrontFace = FrontFaceDirection.Ccw;
151 #if SILICONSTUDIO_PLATFORM_ANDROID
152 [DllImport(
"libEGL.dll", EntryPoint =
"eglGetCurrentContext")]
153 internal static extern IntPtr EglGetCurrentContext();
155 internal EffectProgram effectProgram;
158 private SamplerState[] samplerStates =
new SamplerState[64];
160 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
161 private Buffer constantBuffer;
164 private bool[] hasMipmaps =
new bool[64];
166 private int copyProgram = -1;
167 private int copyProgramOffsetLocation = -1;
168 private int copyProgramScaleLocation = -1;
169 private float[] squareVertices = {
183 #if SILICONSTUDIO_PLATFORM_ANDROID
184 if (graphicsContext != gameWindow.GraphicsContext)
186 return GraphicsDeviceStatus.Reset;
191 return GraphicsDeviceStatus.Normal;
199 public Viewport Viewport
204 EnsureContextActive();
207 return _currentViewports[0];
213 if (_graphicsDevicesInUse == null)
214 _graphicsDevicesInUse =
new List<GraphicsDevice>();
216 if (!_graphicsDevicesInUse.Contains(
this))
217 _graphicsDevicesInUse.Add(
this);
222 if (_graphicsDevicesInUse == null)
225 _graphicsDevicesInUse.Remove(
this);
227 if (_graphicsDevicesInUse.Count == 0)
228 _graphicsDevicesInUse = null;
231 internal UseOpenGLCreationContext UseOpenGLCreationContext()
233 return new UseOpenGLCreationContext(
this);
236 public void ApplyPlatformSpecificParams(Effect effect)
238 effect.Parameters.Set(ShaderBaseKeys.ParadoxFlipRendertarget, flipRenderTarget ? -1.0f : 1.0f);
246 ++contextBeginCounter;
248 #if SILICONSTUDIO_PLATFORM_ANDROID
249 if (contextBeginCounter == 1)
251 if (Workaround_Context_Tegra2_Tegra3)
253 Monitor.Enter(asyncCreationLockObject, ref asyncCreationLockTaken);
259 keepContextOnEnd = graphicsContextEglPtr == EglGetCurrentContext();
261 if (keepContextOnEnd)
269 if (contextBeginCounter == 1)
270 graphicsContext.MakeCurrent(windowInfo);
273 public void BeginProfile(
Color profileColor,
string name)
280 EnsureContextActive();
283 #if SILICONSTUDIO_PLATFORM_ANDROID
285 if (AsyncPendingTaskWaiting)
286 ExecutePendingTasks();
289 var clearFBO = FindOrCreateFBO(depthStencilBuffer);
290 if (clearFBO != boundFBO)
291 GL.BindFramebuffer(FramebufferTarget.Framebuffer, clearFBO);
293 ClearBufferMask clearBufferMask =
294 ((options & DepthStencilClearOptions.DepthBuffer) ==
DepthStencilClearOptions.DepthBuffer ? ClearBufferMask.DepthBufferBit : 0)
295 | ((options & DepthStencilClearOptions.Stencil) ==
DepthStencilClearOptions.Stencil ? ClearBufferMask.StencilBufferBit : 0);
296 GL.ClearDepth(depth);
297 GL.ClearStencil(stencil);
299 var depthStencilState = boundDepthStencilState ?? DepthStencilStates.Default;
300 var depthMask = depthStencilState.Description.DepthBufferWriteEnable && hasDepthStencilBuffer;
304 GL.Clear(clearBufferMask);
308 if (clearFBO != boundFBO)
309 GL.BindFramebuffer(FramebufferTarget.Framebuffer, boundFBO);
312 public void Clear(RenderTarget renderTarget, Color4 color)
315 EnsureContextActive();
318 var clearFBO = FindOrCreateFBO(renderTarget);
319 if (clearFBO != boundFBO)
320 GL.BindFramebuffer(FramebufferTarget.Framebuffer, clearFBO);
322 var blendState = boundBlendState ?? BlendStates.Default;
323 var colorMask = hasRenderTarget && blendState.Description.RenderTargets[0].ColorWriteChannels == ColorWriteChannels.All;
325 GL.ColorMask(
true,
true,
true,
true);
327 GL.ClearColor(color.R, color.G, color.B, color.A);
328 GL.Clear(ClearBufferMask.ColorBufferBit);
332 blendState.ApplyColorMask();
334 if (clearFBO != boundFBO)
335 GL.BindFramebuffer(FramebufferTarget.Framebuffer, boundFBO);
338 public unsafe
void ClearReadWrite(
Buffer buffer, Vector4 value)
341 EnsureContextActive();
344 throw new NotImplementedException();
347 public unsafe
void ClearReadWrite(
Buffer buffer, Int4 value)
350 EnsureContextActive();
353 throw new NotImplementedException();
356 public unsafe
void ClearReadWrite(
Buffer buffer, UInt4 value)
359 EnsureContextActive();
362 throw new NotImplementedException();
365 public unsafe
void ClearReadWrite(Texture texture, Vector4 value)
368 EnsureContextActive();
371 throw new NotImplementedException();
374 public unsafe
void ClearReadWrite(Texture texture, Int4 value)
377 EnsureContextActive();
380 throw new NotImplementedException();
383 public unsafe
void ClearReadWrite(Texture texture, UInt4 value)
386 EnsureContextActive();
389 throw new NotImplementedException();
392 public void ClearState()
395 EnsureContextActive();
397 UnbindVertexArrayObject();
398 currentVertexArrayObject = null;
401 for (
int i = 0; i < samplerStates.Length; ++i)
402 samplerStates[i] = null;
404 for (
int i = 0; i < boundTextures.Length; ++i)
411 GL.ActiveTexture(TextureUnit.Texture0);
415 SetRasterizerState(null);
416 SetDepthStencilState(null);
419 SetRenderTarget(DepthStencilBuffer, BackBuffer);
429 public void CopyRegion(GraphicsResource source,
int sourceSubresource, ResourceRegion? regionSource, GraphicsResource destination,
int destinationSubResource,
int dstX = 0,
int dstY = 0,
int dstZ = 0)
432 EnsureContextActive();
435 var destTexture = destination as Texture2D;
437 if (sourceTexture == null || destTexture == null)
438 throw new NotImplementedException(
"Copy is only implemented for ITexture2D objects.");
440 if (sourceSubresource != 0 || destinationSubResource != 0)
441 throw new NotImplementedException(
"Copy is only implemented for subresource 0 in OpenGL.");
443 var sourceRegion = regionSource.HasValue? regionSource.Value :
new ResourceRegion(0, 0, 0, sourceTexture.Description.Width, sourceTexture.Description.Height, 0);
444 var sourceRectangle =
new Rectangle(sourceRegion.Left, sourceRegion.Top, sourceRegion.Right - sourceRegion.Left, sourceRegion.Bottom - sourceRegion.Top);
446 if (sourceRectangle.Width == 0 || sourceRectangle.Height == 0)
451 if(sourceTexture.Width <= 16 || sourceTexture.Height <= 16)
452 throw new NotSupportedException(
"ReadPixels from texture smaller or equal to 16x16 pixels seems systematically to fails on some android devices (for exp: Galaxy S3)");
454 if (dstX != 0 || dstY != 0 || dstZ != 0)
455 throw new NotSupportedException(
"ReadPixels from staging texture using non-zero destination is not supported");
457 GL.Viewport(0, 0, destTexture.Description.Width, destTexture.Description.Height);
458 GL.BindFramebuffer(FramebufferTarget.Framebuffer, FindOrCreateFBO(source));
459 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
460 GL.ReadPixels(sourceRectangle.Left, sourceRectangle.Top, sourceRectangle.Width, sourceRectangle.Height, destTexture.FormatGl, destTexture.Type, destTexture.StagingData);
462 GL.BindBuffer(BufferTarget.PixelPackBuffer, destTexture.ResourceId);
463 GL.ReadPixels(sourceRectangle.Left, sourceRectangle.Top, sourceRectangle.Width, sourceRectangle.Height, destTexture.FormatGl, destTexture.Type, IntPtr.Zero);
464 GL.BindBuffer(BufferTarget.PixelPackBuffer, 0);
466 GL.BindFramebuffer(FramebufferTarget.Framebuffer, boundFBO);
467 GL.Viewport((int)_currentViewports[0].X, (
int)_currentViewports[0].Y, (
int)_currentViewports[0].Width, (
int)_currentViewports[0].Height);
471 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
473 GL.Viewport(0, 0, destTexture.Description.Width, destTexture.Description.Height);
474 GL.BindFramebuffer(FramebufferTarget.Framebuffer, FindOrCreateFBO(destination));
476 if (copyProgram == -1)
478 const string copyVertexShaderSource =
479 "attribute vec2 aPosition; \n" +
480 "varying vec2 vTexCoord; \n" +
481 "uniform vec4 uScale; \n" +
482 "uniform vec4 uOffset; \n" +
485 " vec4 transformedPosition = aPosition.xyxy * uScale + uOffset;" +
486 " gl_Position = vec4(transformedPosition.zw * 2.0 - 1.0, 0.0, 1.0); \n" +
487 " vTexCoord = transformedPosition.xy; \n" +
490 const string copyFragmentShaderSource =
491 "precision mediump float; \n" +
492 "varying vec2 vTexCoord; \n" +
493 "uniform sampler2D s_texture; \n" +
496 " gl_FragColor = texture2D(s_texture, vTexCoord); \n" +
500 int vertexShader = TryCompileShader(ShaderType.VertexShader, copyVertexShaderSource);
501 int fragmentShader = TryCompileShader(ShaderType.FragmentShader, copyFragmentShaderSource);
503 copyProgram = GL.CreateProgram();
504 GL.AttachShader(copyProgram, vertexShader);
505 GL.AttachShader(copyProgram, fragmentShader);
506 GL.BindAttribLocation(copyProgram, 0,
"aPosition");
507 GL.LinkProgram(copyProgram);
510 GL.GetProgram(copyProgram, ProgramParameter.LinkStatus, out linkStatus);
513 throw new InvalidOperationException(
"Error while linking GLSL shaders.");
515 GL.UseProgram(copyProgram);
516 #if SILICONSTUDIO_PLATFORM_ANDROID
517 var textureLocation = GL.GetUniformLocation(copyProgram,
new StringBuilder(
"s_texture"));
518 copyProgramOffsetLocation = GL.GetUniformLocation(copyProgram,
new StringBuilder(
"uOffset"));
519 copyProgramScaleLocation = GL.GetUniformLocation(copyProgram,
new StringBuilder(
"uScale"));
521 var textureLocation = GL.GetUniformLocation(copyProgram,
"s_texture");
522 copyProgramOffsetLocation = GL.GetUniformLocation(copyProgram,
"uOffset");
523 copyProgramScaleLocation = GL.GetUniformLocation(copyProgram,
"uScale");
525 GL.Uniform1(textureLocation, 0);
528 var regionSize =
new Vector2(sourceRectangle.Width, sourceRectangle.Height);
531 var sourceSize =
new Vector2(sourceTexture.Width, sourceTexture.Height);
532 var sourceRegionLeftTop =
new Vector2(sourceRectangle.Left, sourceRectangle.Top);
533 var sourceScale =
new Vector2(regionSize.X / sourceSize.X, regionSize.Y / sourceSize.Y);
534 var sourceOffset =
new Vector2(sourceRegionLeftTop.X / sourceSize.X, sourceRegionLeftTop.Y / sourceSize.Y);
537 var destSize =
new Vector2(destTexture.Width, destTexture.Height);
538 var destRegionLeftTop =
new Vector2(dstX, dstY);
539 var destScale =
new Vector2(regionSize.X / destSize.X, regionSize.Y / destSize.Y);
540 var destOffset =
new Vector2(destRegionLeftTop.X / destSize.X, destRegionLeftTop.Y / destSize.Y);
542 var enabledColors =
new bool[4];
543 GL.GetBoolean(GetPName.ColorWritemask, enabledColors);
544 var isDepthTestEnabled = GL.IsEnabled(EnableCap.DepthTest);
545 var isCullFaceEnabled = GL.IsEnabled(EnableCap.CullFace);
547 var isStencilEnabled = GL.IsEnabled(EnableCap.StencilTest);
548 GL.Disable(EnableCap.DepthTest);
549 GL.Disable(EnableCap.CullFace);
551 GL.Disable(EnableCap.StencilTest);
552 GL.ColorMask(
true,
true,
true,
true);
554 UnbindVertexArrayObject();
556 GL.UseProgram(copyProgram);
559 GL.ActiveTexture(TextureUnit.Texture0);
560 GL.BindTexture(TextureTarget.Texture2D, sourceTexture.resourceId);
561 boundTextures[0] = null;
562 GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
563 GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
564 GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
565 GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);
566 ((
Texture)source).BoundSamplerState = SamplerStates.PointClamp;
568 GL.EnableVertexAttribArray(0);
569 GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
570 GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float,
false, 0, squareVertices);
571 GL.Uniform4(copyProgramOffsetLocation, sourceOffset.X, sourceOffset.Y, destOffset.X, destOffset.Y);
572 GL.Uniform4(copyProgramScaleLocation, sourceScale.X, sourceScale.Y, destScale.X, destScale.Y);
573 GL.DrawArrays(BeginMode.TriangleStrip, 0, 4);
574 GL.DisableVertexAttribArray(0);
575 GL.UseProgram(boundProgram);
578 if (isDepthTestEnabled)
579 GL.Enable(EnableCap.DepthTest);
580 if (isCullFaceEnabled)
581 GL.Enable(EnableCap.CullFace);
585 GL.Enable(EnableCap.StencilTest);
586 GL.ColorMask(enabledColors[0], enabledColors[1], enabledColors[2], enabledColors[3]);
588 GL.BindFramebuffer(FramebufferTarget.Framebuffer, boundFBO);
589 GL.Viewport((int)_currentViewports[0].X, (
int)_currentViewports[0].Y, (
int)_currentViewports[0].Width, (
int)_currentViewports[0].Height);
592 var sourceFBO = FindOrCreateFBO(source);
593 var destinationFBO = FindOrCreateFBO(destination);
594 GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, sourceFBO);
595 GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, destinationFBO);
596 GL.BlitFramebuffer(sourceRegion.Left, sourceRegion.Top, sourceRegion.Right, sourceRegion.Bottom,
597 dstX, dstY, dstX + sourceRegion.Right - sourceRegion.Left, dstY + sourceRegion.Bottom - sourceRegion.Top,
598 ClearBufferMask.ColorBufferBit, BlitFramebufferFilter.Nearest);
599 GL.BindFramebuffer(FramebufferTarget.Framebuffer, boundFBO);
609 public void Copy(GraphicsResource source, GraphicsResource destination)
611 CopyRegion(source, 0, null, destination, 0);
614 public void CopyCount(
Buffer sourceBuffer,
Buffer destBuffer,
int offsetToDest)
617 EnsureContextActive();
620 throw new NotImplementedException();
623 public void Dispatch(
int threadCountX,
int threadCountY,
int threadCountZ)
626 EnsureContextActive();
629 throw new NotImplementedException();
632 public void Dispatch(
Buffer indirectBuffer,
int offsetInBytes)
635 EnsureContextActive();
638 throw new NotImplementedException();
641 public void Draw(
PrimitiveType primitiveType,
int vertexCount,
int startVertex = 0)
644 EnsureContextActive();
648 GL.DrawArrays(primitiveType.ToOpenGL(), startVertex, vertexCount);
654 EnsureContextActive();
658 throw new NotImplementedException();
668 public void DrawIndexed(
PrimitiveType primitiveType,
int indexCount,
int startIndexLocation = 0,
int baseVertexLocation = 0)
671 EnsureContextActive();
674 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
675 if(baseVertexLocation != 0)
676 throw new NotSupportedException(
"DrawIndexed with no null baseVertexLocation is not supported on OpenGL ES2.");
677 GL.DrawElements(primitiveType.ToOpenGL(), indexCount, drawElementsType, indexBufferOffset + (startIndexLocation * indexElementSize));
679 GL.DrawElementsBaseVertex(primitiveType.ToOpenGL(), indexCount, drawElementsType, indexBufferOffset + (startIndexLocation * indexElementSize), baseVertexLocation);
692 public void DrawIndexedInstanced(
PrimitiveType primitiveType,
int indexCountPerInstance,
int instanceCount,
int startIndexLocation = 0,
int baseVertexLocation = 0,
int startInstanceLocation = 0)
695 EnsureContextActive();
698 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
699 throw new NotImplementedException();
701 GL.DrawElementsInstancedBaseVertex(primitiveType.ToOpenGL(), indexCountPerInstance, DrawElementsType.UnsignedInt, (IntPtr)(startIndexLocation * indexElementSize), instanceCount, baseVertexLocation);
711 public void DrawIndexedInstanced(
PrimitiveType primitiveType,
Buffer argumentsBuffer,
int alignedByteOffsetForArgs = 0)
713 if (argumentsBuffer == null)
throw new ArgumentNullException(
"argumentsBuffer");
716 EnsureContextActive();
719 throw new NotImplementedException();
730 public void DrawInstanced(
PrimitiveType primitiveType,
int vertexCountPerInstance,
int instanceCount,
int startVertexLocation = 0,
int startInstanceLocation = 0)
733 EnsureContextActive();
737 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
738 throw new NotImplementedException();
740 GL.DrawArraysInstanced(primitiveType.ToOpenGL(), startVertexLocation, vertexCountPerInstance, instanceCount);
750 public void DrawInstanced(
PrimitiveType primitiveType,
Buffer argumentsBuffer,
int alignedByteOffsetForArgs = 0)
752 if (argumentsBuffer == null)
throw new ArgumentNullException(
"argumentsBuffer");
755 EnsureContextActive();
758 throw new NotImplementedException();
761 public void EnableProfile(
bool enabledFlag)
771 EnsureContextActive();
774 --contextBeginCounter;
775 if (contextBeginCounter == 0)
777 UnbindVertexArrayObject();
779 #if SILICONSTUDIO_PLATFORM_ANDROID
780 if (Workaround_Context_Tegra2_Tegra3)
782 graphicsContext.MakeCurrent(null);
785 if (asyncCreationLockTaken)
787 Monitor.Exit(asyncCreationLockObject);
788 asyncCreationLockTaken =
false;
791 else if (!keepContextOnEnd)
793 UnbindGraphicsContext(graphicsContext);
796 UnbindGraphicsContext(graphicsContext);
799 else if (contextBeginCounter < 0)
801 throw new Exception(
"End context was called more than Begin");
805 public void EndProfile()
809 internal void EnsureContextActive()
812 #if SILICONSTUDIO_PLATFORM_ANDROID
813 if (EglGetCurrentContext() == IntPtr.Zero)
814 throw new InvalidOperationException(
"No OpenGL context bound.");
816 if (OpenTK.Graphics.GraphicsContext.CurrentContext == null)
817 throw new InvalidOperationException(
"No OpenGL context bound.");
821 public void ExecuteCommandList(ICommandList commandList)
824 EnsureContextActive();
827 throw new NotImplementedException();
830 internal void BindProgram(
int program)
832 if (program != boundProgram)
834 boundProgram = program;
835 GL.UseProgram(program);
839 internal int FindOrCreateFBO(GraphicsResourceBase graphicsResource)
841 if (graphicsResource == RootDevice.windowProvidedRenderTarget
842 || graphicsResource == RootDevice.windowProvidedRenderTexture)
843 return windowProvidedFrameBuffer;
845 if (graphicsResource is DepthStencilBuffer)
846 return FindOrCreateFBO((DepthStencilBuffer)graphicsResource, null);
847 if (graphicsResource is RenderTarget)
848 return FindOrCreateFBO(null,
new[] { (RenderTarget)graphicsResource });
849 if (graphicsResource is Texture)
850 return FindOrCreateFBO(null,
new[] { ((Texture)graphicsResource).GetCachedRenderTarget() });
852 throw new NotSupportedException();
855 internal int FindOrCreateFBO(DepthStencilBuffer depthStencilBuffer)
857 lock (RootDevice.existingFBOs)
859 foreach (var key
in RootDevice.existingFBOs)
861 if (key.Key.DepthStencilBuffer == depthStencilBuffer)
866 return FindOrCreateFBO(depthStencilBuffer, null);
869 internal int FindOrCreateFBO(RenderTarget target)
871 lock (RootDevice.existingFBOs)
873 foreach (var key
in RootDevice.existingFBOs)
875 if (key.Key.LastRenderTarget == 1 && key.Key.RenderTargets[0] == target)
880 return FindOrCreateFBO(null,
new[] { target });
883 internal int FindOrCreateFBO(DepthStencilBuffer depthStencilBuffer, RenderTarget[] renderTargets)
888 lock (RootDevice.existingFBOs)
890 var fboKey =
new FBOKey(depthStencilBuffer, renderTargets);
894 var isProvidedDepthBuffer = (depthStencilBuffer == RootDevice.windowProvidedDepthBuffer);
895 var isProvidedRenderTarget = (fboKey.LastRenderTarget == 1 && renderTargets[0] == RootDevice.windowProvidedRenderTarget);
896 if ((isProvidedDepthBuffer || boundDepthStencilBuffer == null) && (isProvidedRenderTarget || fboKey.LastRenderTarget == 0))
898 return windowProvidedFrameBuffer;
900 if (isProvidedDepthBuffer || isProvidedRenderTarget)
902 throw new InvalidOperationException(
"It is impossible to bind device provided and user created buffers with OpenGL");
905 if (RootDevice.existingFBOs.TryGetValue(fboKey, out framebufferId))
906 return framebufferId;
908 GL.GenFramebuffers(1, out framebufferId);
909 GL.BindFramebuffer(FramebufferTarget.Framebuffer, framebufferId);
910 int firstRenderTargets = -1;
911 if (renderTargets != null)
913 for (
int i = 0; i < renderTargets.Length; ++i)
916 if (renderTargets[i] != null)
918 firstRenderTargets = i;
919 GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0 + i, TextureTarget.Texture2D, renderTargets[i].ResourceId, 0);
924 #if !SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
925 GL.DrawBuffer(firstRenderTargets != -1 ? DrawBufferMode.ColorAttachment0 : DrawBufferMode.None);
926 GL.ReadBuffer(firstRenderTargets != -1 ? ReadBufferMode.ColorAttachment0 : ReadBufferMode.None);
929 if (depthStencilBuffer != null)
931 #if !SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
932 FramebufferAttachment attachmentType;
933 if (depthStencilBuffer.IsDepthBuffer && depthStencilBuffer.IsStencilBuffer)
934 attachmentType = FramebufferAttachment.DepthStencilAttachment;
935 else if(depthStencilBuffer.IsDepthBuffer)
936 attachmentType = FramebufferAttachment.DepthAttachment;
938 attachmentType = FramebufferAttachment.StencilAttachment;
940 if (depthStencilBuffer.Texture.IsRenderbuffer)
941 GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, attachmentType, RenderbufferTarget.Renderbuffer, depthStencilBuffer.ResourceId);
943 GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, attachmentType, TextureTarget.Texture2D, depthStencilBuffer.ResourceId, 0);
945 if (depthStencilBuffer.IsDepthBuffer)
946 GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferSlot.DepthAttachment, RenderbufferTarget.Renderbuffer, depthStencilBuffer.ResourceId);
949 if(depthStencilBuffer.IsStencilBuffer)
950 GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferSlot.StencilAttachment, RenderbufferTarget.Renderbuffer, depthStencilBuffer.Texture.ResouceIdStencil != 0 ? depthStencilBuffer.Texture.ResouceIdStencil : depthStencilBuffer.ResourceId);
954 var framebufferStatus = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer);
955 if (framebufferStatus != FramebufferErrorCode.FramebufferComplete)
957 throw new InvalidOperationException(
string.Format(
"FBO is incomplete: RT {0} Depth {1} (error: {2})", renderTargets != null && renderTargets.Length > 0 ? renderTargets[0].ResourceId : 0, depthStencilBuffer != null ? depthStencilBuffer.ResourceId : 0, framebufferStatus));
960 GL.BindFramebuffer(FramebufferTarget.Framebuffer, boundFBO);
962 RootDevice.existingFBOs.Add(
new GraphicsDevice.FBOKey(depthStencilBuffer, renderTargets != null ? renderTargets.ToArray() : null), framebufferId);
965 return framebufferId;
968 public ICommandList FinishCommandList()
971 EnsureContextActive();
974 throw new NotImplementedException();
977 protected void InitializeFactories()
981 public MappedResource MapSubresource(GraphicsResource resource,
int subResourceIndex,
MapMode mapMode,
bool doNotWait =
false,
int offsetInBytes = 0,
int lengthInBytes = 0)
984 EnsureContextActive();
987 #if !SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
988 BufferAccess bufferAccess;
992 bufferAccess = BufferAccess.ReadOnly;
995 case MapMode.WriteDiscard:
996 case MapMode.WriteNoOverwrite:
997 bufferAccess = BufferAccess.WriteOnly;
999 case MapMode.ReadWrite:
1000 bufferAccess = BufferAccess.ReadWrite;
1003 throw new ArgumentOutOfRangeException(
"mapMode");
1007 var buffer = resource as
Buffer;
1010 if (lengthInBytes == 0)
1011 lengthInBytes = buffer.Description.SizeInBytes;
1013 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
1014 if (buffer.StagingData != IntPtr.Zero)
1028 return new MappedResource(resource, subResourceIndex,
new DataBox { DataPointer = buffer.StagingData + offsetInBytes, SlicePitch = 0, RowPitch = 0 }, offsetInBytes, lengthInBytes);
1032 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
1033 throw new NotImplementedException();
1035 IntPtr mapResult = IntPtr.Zero;
1037 UnbindVertexArrayObject();
1038 GL.BindBuffer(buffer.bufferTarget, buffer.ResourceId);
1040 if (mapMode ==
MapMode.WriteDiscard)
1041 mapResult = GL.MapBufferRange(buffer.bufferTarget, (IntPtr)offsetInBytes, (IntPtr)lengthInBytes, BufferAccessMask.MapWriteBit | BufferAccessMask.MapInvalidateBufferBit);
1042 else if (mapMode ==
MapMode.WriteNoOverwrite)
1043 mapResult = GL.MapBufferRange(buffer.bufferTarget, (IntPtr)offsetInBytes, (IntPtr)lengthInBytes, BufferAccessMask.MapWriteBit | BufferAccessMask.MapUnsynchronizedBit);
1045 mapResult = GL.MapBuffer(buffer.bufferTarget, bufferAccess);
1047 GL.BindBuffer(buffer.bufferTarget, 0);
1049 return new MappedResource(resource, subResourceIndex,
new DataBox { DataPointer = mapResult, SlicePitch = 0, RowPitch = 0 });
1053 var texture = resource as Texture;
1054 if (texture != null)
1059 throw new NotSupportedException(
"Only staging textures can be mapped.");
1061 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
1062 if (lengthInBytes == 0)
1063 lengthInBytes = texture.DepthPitch;
1064 return new MappedResource(resource, subResourceIndex,
new DataBox { DataPointer = texture.StagingData + offsetInBytes, SlicePitch = texture.DepthPitch, RowPitch = texture.RowPitch }, offsetInBytes, lengthInBytes);
1066 GL.BindBuffer(BufferTarget.PixelPackBuffer, texture.ResourceId);
1067 var mapResult = GL.MapBuffer(BufferTarget.PixelPackBuffer, bufferAccess);
1068 GL.BindBuffer(BufferTarget.PixelPackBuffer, 0);
1069 return new MappedResource(resource, subResourceIndex,
new DataBox { DataPointer = mapResult, SlicePitch = texture.DepthPitch, RowPitch = texture.RowPitch });
1074 throw new NotImplementedException();
1077 public GraphicsDevice NewDeferred()
1079 throw new NotImplementedException();
1082 internal void PreDraw()
1084 #if SILICONSTUDIO_PLATFORM_ANDROID
1086 if (AsyncPendingTaskWaiting)
1087 ExecutePendingTasks();
1090 var inputSignature = effectProgram.InputSignature;
1091 if (currentVertexArrayObject != boundVertexArrayObject || (currentVertexArrayObject != null && currentVertexArrayObject.RequiresApply(inputSignature)))
1093 if (currentVertexArrayObject == null)
1095 UnbindVertexArrayObject();
1099 drawElementsType = currentVertexArrayObject.drawElementsType;
1100 indexBufferOffset = currentVertexArrayObject.indexBufferOffset;
1101 indexElementSize = currentVertexArrayObject.indexElementSize;
1102 currentVertexArrayObject.Apply(inputSignature);
1103 boundVertexArrayObject = currentVertexArrayObject;
1107 foreach (var textureInfo
in effectProgram.Textures)
1109 var boundTexture = boundTextures[textureInfo.TextureUnit];
1110 var texture = textures[textureInfo.TextureUnit];
1111 var boundSamplerState = texture.BoundSamplerState ?? defaultSamplerState;
1112 var samplerState = samplerStates[textureInfo.TextureUnit] ?? SamplerStates.LinearClamp;
1114 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
1115 bool hasMipmap = texture.Description.MipLevels > 1;
1117 bool hasMipmap =
false;
1120 bool textureChanged = texture != boundTexture;
1121 bool samplerStateChanged = samplerState != boundSamplerState;
1124 if (textureChanged || samplerStateChanged)
1126 if (activeTexture != textureInfo.TextureUnit)
1128 activeTexture = textureInfo.TextureUnit;
1129 GL.ActiveTexture(TextureUnit.Texture0 + textureInfo.TextureUnit);
1135 boundTextures[textureInfo.TextureUnit] = texture;
1136 GL.BindTexture(texture.Target, texture.resourceId);
1140 if (samplerStateChanged)
1142 samplerState.Apply(hasMipmap, boundSamplerState);
1143 texture.BoundSamplerState = samplerState;
1149 var newFrontFace = currentFrontFace;
1150 if (flipRenderTarget)
1151 newFrontFace = newFrontFace == FrontFaceDirection.Cw ? FrontFaceDirection.Ccw : FrontFaceDirection.Cw;
1153 if (newFrontFace != boundFrontFace)
1155 boundFrontFace = newFrontFace;
1156 GL.FrontFace(boundFrontFace);
1159 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
1162 fixed(byte* boundUniforms = effectProgram.BoundUniforms)
1164 var constantBufferData = constantBuffer.StagingData;
1165 foreach (var uniform
in effectProgram.Uniforms)
1167 var firstUniformIndex = uniform.UniformIndex;
1168 var lastUniformIndex = firstUniformIndex + uniform.Count;
1169 var offset = uniform.Offset;
1170 var boundData = (IntPtr)boundUniforms + offset;
1171 var currentData = constantBufferData + offset;
1176 if (SiliconStudio.Core.Utilities.CompareMemory(boundData, currentData, uniform.CompareSize))
1180 SiliconStudio.Core.Utilities.CopyMemory(boundData, currentData, uniform.CompareSize);
1182 switch (uniform.Type)
1184 case ActiveUniformType.Float:
1185 for (
int uniformIndex = firstUniformIndex; uniformIndex < lastUniformIndex; ++uniformIndex)
1187 GL.Uniform1(uniformIndex, 1, (
float*)currentData);
1191 case ActiveUniformType.FloatVec2:
1192 for (
int uniformIndex = firstUniformIndex; uniformIndex < lastUniformIndex; ++uniformIndex)
1194 GL.Uniform2(uniformIndex, 1, (
float*)currentData);
1198 case ActiveUniformType.FloatVec3:
1199 for (
int uniformIndex = firstUniformIndex; uniformIndex < lastUniformIndex; ++uniformIndex)
1201 GL.Uniform3(uniformIndex, 1, (
float*)currentData);
1205 case ActiveUniformType.FloatVec4:
1206 GL.Uniform4(firstUniformIndex, uniform.Count, (
float*)currentData);
1208 case ActiveUniformType.FloatMat4:
1209 GL.UniformMatrix4(uniform.UniformIndex, uniform.Count,
false, (
float*)currentData);
1211 case ActiveUniformType.Bool:
1212 case ActiveUniformType.Int:
1213 for (
int uniformIndex = firstUniformIndex; uniformIndex < lastUniformIndex; ++uniformIndex)
1215 GL.Uniform1(uniformIndex, 1, (
int*)currentData);
1219 case ActiveUniformType.BoolVec2:
1220 case ActiveUniformType.IntVec2:
1221 for (
int uniformIndex = firstUniformIndex; uniformIndex < lastUniformIndex; ++uniformIndex)
1223 GL.Uniform2(uniformIndex, 1, (
int*)currentData);
1227 case ActiveUniformType.BoolVec3:
1228 case ActiveUniformType.IntVec3:
1229 for (
int uniformIndex = firstUniformIndex; uniformIndex < lastUniformIndex; ++uniformIndex)
1231 GL.Uniform3(uniformIndex, 1, (
int*)currentData);
1235 case ActiveUniformType.BoolVec4:
1236 case ActiveUniformType.IntVec4:
1237 GL.Uniform4(firstUniformIndex, uniform.Count, (
int*)currentData);
1240 throw new NotImplementedException();
1248 public void SetBlendState(BlendState blendState)
1251 EnsureContextActive();
1254 if (blendState == null)
1255 blendState = BlendStates.Default;
1257 if (boundBlendState != blendState)
1259 blendState.Apply(boundBlendState ?? BlendStates.Default);
1260 boundBlendState = blendState;
1264 public void SetBlendState(BlendState blendState,
Color blendFactor,
int multiSampleMask = -1)
1267 EnsureContextActive();
1270 if (multiSampleMask != -1)
1271 throw new NotImplementedException();
1273 SetBlendState(blendState);
1274 GL.BlendColor(blendFactor.R, blendFactor.G, blendFactor.B, blendFactor.A);
1277 public void SetBlendState(BlendState blendState,
Color blendFactor, uint multiSampleMask = 0xFFFFFFFF)
1280 EnsureContextActive();
1283 SetBlendState(blendState, blendFactor, unchecked((
int)multiSampleMask));
1292 internal void SetConstantBuffer(
ShaderStage stage,
int slot, Buffer buffer)
1295 EnsureContextActive();
1298 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
1301 throw new InvalidOperationException(
"Only cbuffer slot 0 of vertex shader stage should be used on OpenGL ES 2.0.");
1303 constantBuffer = buffer;
1305 GL.BindBufferBase(BufferTarget.UniformBuffer, slot, buffer != null ? buffer.resourceId : 0);
1309 public void SetDepthStencilState(DepthStencilState depthStencilState,
int stencilReference = 0)
1312 EnsureContextActive();
1315 if (depthStencilState == null)
1316 depthStencilState = DepthStencilStates.Default;
1319 if (boundDepthStencilState != depthStencilState || boundStencilReference != stencilReference)
1321 boundDepthStencilState = depthStencilState;
1322 boundStencilReference = stencilReference;
1323 boundDepthStencilState.Apply(stencilReference);
1327 public void SetRasterizerState(RasterizerState rasterizerState)
1330 EnsureContextActive();
1333 if (rasterizerState == null)
1334 rasterizerState = RasterizerStates.CullBack;
1336 if (boundRasterizerState != rasterizerState)
1338 boundRasterizerState = rasterizerState;
1339 boundRasterizerState.Apply();
1348 public void SetRenderTarget(DepthStencilBuffer depthStencilBuffer, RenderTarget renderTarget)
1350 SetRenderTargets(depthStencilBuffer, (renderTarget == null) ? null :
new[] { renderTarget });
1352 if (renderTarget != null)
1354 SetViewport(
new Viewport(0, 0, renderTarget.Width, renderTarget.Height));
1356 else if (depthStencilBuffer != null)
1358 SetViewport(
new Viewport(0, 0, depthStencilBuffer.Description.Width, depthStencilBuffer.Description.Height));
1362 public void SetRenderTargets(DepthStencilBuffer depthStencilBuffer, params RenderTarget[] renderTargets)
1364 if (renderTargets == null)
1366 throw new ArgumentNullException(
"renderTargets");
1370 var expectedWidth = renderTargets[0].Width;
1371 var expectedHeight = renderTargets[0].Height;
1372 if (depthStencilBuffer != null)
1374 if (expectedWidth != depthStencilBuffer.Texture.Width || expectedHeight != depthStencilBuffer.Texture.Height)
1375 throw new Exception(
"Depth buffer is not the same size as the render target");
1377 for (
int i = 1; i < renderTargets.Length; ++i)
1379 if (expectedWidth != renderTargets[i].Width || expectedHeight != renderTargets[i].Height)
1380 throw new Exception(
"Render targets do nt have the same size");
1383 flipRenderTarget =
true;
1384 foreach (var rt
in renderTargets)
1386 if (rt == BackBuffer)
1388 flipRenderTarget =
false;
1394 EnsureContextActive();
1397 for (
int i = 0; i < renderTargets.Length; ++i)
1398 boundRenderTargets[i] = renderTargets[i];
1399 for (
int i = renderTargets.Length; i < boundRenderTargets.Length; ++i)
1400 boundRenderTargets[i] = null;
1402 boundDepthStencilBuffer = depthStencilBuffer;
1404 needUpdateFBO =
true;
1408 var renderTarget = renderTargets.Length > 0 ? renderTargets[0] : null;
1409 if (renderTarget != null)
1411 SetViewport(
new Viewport(0, 0, renderTarget.Width, renderTarget.Height));
1413 else if (depthStencilBuffer != null)
1415 SetViewport(
new Viewport(0, 0, depthStencilBuffer.Description.Width, depthStencilBuffer.Description.Height));
1422 public void ResetTargets()
1424 for (
int i = 0; i < boundRenderTargets.Length; ++i)
1425 boundRenderTargets[i] = null;
1434 public void SetSamplerState(
ShaderStage stage,
int slot, SamplerState samplerState)
1437 EnsureContextActive();
1440 samplerStates[slot] = samplerState;
1450 public void SetScissorRectangles(
int left,
int top,
int right,
int bottom)
1453 EnsureContextActive();
1456 GL.Scissor(left, bottom, right-left, top-bottom);
1463 public unsafe
void SetScissorRectangles(params
Rectangle[] scissorRectangles)
1466 EnsureContextActive();
1469 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
1470 throw new NotImplementedException();
1473 var rectangleValues =
new int[4*scissorRectangles.Length];
1475 for (
int i = 0; i < scissorRectangles.Length; ++i)
1477 rectangleValues[4*i] = scissorRectangles[i].X;
1478 rectangleValues[4*i + 1] = scissorRectangles[i].Y;
1479 rectangleValues[4*i + 2] = scissorRectangles[i].Width;
1480 rectangleValues[4*i + 3] = scissorRectangles[i].Height;
1483 GL.ScissorArray(0, scissorRectangles.Length, rectangleValues);
1493 internal void SetShaderResourceView(
ShaderStage stage,
int slot, GraphicsResource shaderResourceView)
1496 EnsureContextActive();
1498 if (textures[slot] != shaderResourceView)
1500 textures[slot] = shaderResourceView as Texture;
1505 public void SetStreamTargets(params Buffer[] buffers)
1508 EnsureContextActive();
1511 throw new NotImplementedException();
1521 internal void SetUnorderedAccessView(
ShaderStage stage,
int slot, GraphicsResource unorderedAccessView)
1524 EnsureContextActive();
1528 throw new ArgumentException(
"Invalid stage.",
"stage");
1530 throw new NotImplementedException();
1533 internal void SetupTargets()
1537 boundFBO = FindOrCreateFBO(boundDepthStencilBuffer, boundRenderTargets);
1539 GL.BindFramebuffer(FramebufferTarget.Framebuffer, boundFBO);
1541 UpdateHasRenderTarget();
1542 UpdateHasDepthStencilBuffer();
1545 if (boundRenderTargets[0] != null)
1546 boundFBOHeight = (boundRenderTargets[0].Description).Height;
1547 else if (boundDepthStencilBuffer != null)
1548 boundFBOHeight = (boundDepthStencilBuffer.Description).Height;
1552 UpdateViewport(_currentViewports[0]);
1555 private void UpdateHasRenderTarget()
1557 var hadRenderTarget = hasRenderTarget;
1558 hasRenderTarget = boundFBO != 0 || boundRenderTargets[0] != null;
1560 if (hasRenderTarget != hadRenderTarget)
1562 var blendState = boundBlendState ?? BlendStates.Default;
1563 blendState.ApplyColorMask();
1567 private void UpdateHasDepthStencilBuffer()
1569 var hadDepthStencilBuffer = hasDepthStencilBuffer;
1570 hasDepthStencilBuffer = boundFBO != 0 || boundDepthStencilBuffer != null;
1572 if (hasDepthStencilBuffer != hadDepthStencilBuffer)
1574 var depthStencilState = boundDepthStencilState ?? DepthStencilStates.Default;
1575 depthStencilState.ApplyDepthMask();
1579 public void SetVertexArrayObject(VertexArrayObject vertexArrayObject)
1581 currentVertexArrayObject = vertexArrayObject;
1584 internal void UnbindVertexArrayObject()
1586 boundVertexArrayObject = null;
1589 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
1590 OpenTK.Graphics.ES20.GL.Oes.BindVertexArray(0);
1592 GL.BindVertexArray(0);
1597 int currentVertexAttribIndex = 0;
1598 while (enabledVertexAttribArrays != 0)
1600 if ((enabledVertexAttribArrays & 1) == 1)
1602 GL.DisableVertexAttribArray(currentVertexAttribIndex);
1605 currentVertexAttribIndex++;
1606 enabledVertexAttribArrays >>= 1;
1615 public void SetViewport(Viewport value)
1618 EnsureContextActive();
1621 _currentViewports[0] = value;
1622 UpdateViewport(value);
1625 public void SetViewport(
int index, Viewport value)
1628 EnsureContextActive();
1631 #if !SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
1632 _currentViewports[index] = value;
1636 throw new NotImplementedException();
1639 internal int TryCompileShader(ShaderType shaderType,
string sourceCode)
1641 int shaderGL = GL.CreateShader(shaderType);
1642 GL.ShaderSource(shaderGL, sourceCode);
1643 GL.CompileShader(shaderGL);
1645 var log = GL.GetShaderInfoLog(shaderGL);
1648 GL.GetShader(shaderGL, ShaderParameter.CompileStatus, out compileStatus);
1650 if (compileStatus != 1)
1651 throw new InvalidOperationException(
"Error while compiling GLSL shader: \n" + log);
1656 public void UnmapSubresource(MappedResource unmapped)
1659 EnsureContextActive();
1662 var texture = unmapped.Resource as Texture;
1663 if (texture != null)
1666 throw new NotSupportedException(
"Only staging textures can be mapped.");
1668 #if !SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
1669 GL.BindBuffer(BufferTarget.PixelPackBuffer, texture.ResourceId);
1670 GL.UnmapBuffer(BufferTarget.PixelPackBuffer);
1671 GL.BindBuffer(BufferTarget.PixelPackBuffer, 0);
1676 var buffer = unmapped.Resource as
Buffer;
1679 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
1681 if (buffer.StagingData == null)
1682 throw new InvalidOperationException();
1685 if (buffer.ResourceId != 0)
1687 UnbindVertexArrayObject();
1688 GL.BindBuffer(buffer.bufferTarget, buffer.ResourceId);
1689 GL.BufferSubData(buffer.bufferTarget, (IntPtr)unmapped.OffsetInBytes, (IntPtr)unmapped.SizeInBytes, unmapped.DataBox.DataPointer);
1690 GL.BindBuffer(buffer.bufferTarget, 0);
1693 UnbindVertexArrayObject();
1694 GL.BindBuffer(buffer.bufferTarget, buffer.ResourceId);
1695 GL.UnmapBuffer(buffer.bufferTarget);
1696 GL.BindBuffer(buffer.bufferTarget, 0);
1701 throw new NotImplementedException();
1706 public void UnsetReadWriteBuffers()
1709 EnsureContextActive();
1713 public void UnsetRenderTargets()
1716 EnsureContextActive();
1719 SetRenderTargets((DepthStencilBuffer)null, null);
1722 internal void UpdateSubresource(GraphicsResource resource,
int subResourceIndex, DataBox databox)
1725 EnsureContextActive();
1727 var buffer = resource as
Buffer;
1730 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
1731 if (buffer.StagingData != IntPtr.Zero)
1734 SiliconStudio.Core.Utilities.CopyMemory(buffer.StagingData, databox.DataPointer, buffer.Description.SizeInBytes);
1739 UnbindVertexArrayObject();
1741 GL.BindBuffer(buffer.bufferTarget, buffer.ResourceId);
1742 GL.BufferData(buffer.bufferTarget, (IntPtr) buffer.Description.SizeInBytes, databox.DataPointer,
1743 buffer.bufferUsageHint);
1744 GL.BindBuffer(buffer.bufferTarget, 0);
1748 var texture = resource as Texture;
1749 if (texture != null)
1751 if (activeTexture != 0)
1754 GL.ActiveTexture(TextureUnit.Texture0);
1758 var desc = texture.Description;
1759 GL.BindTexture(TextureTarget.Texture2D, texture.ResourceId);
1760 boundTextures[0] = null;
1761 GL.TexImage2D(TextureTarget.Texture2D, subResourceIndex, texture.InternalFormat, desc.Width, desc.Height, 0, texture.FormatGl, texture.Type, databox.DataPointer);
1765 throw new NotImplementedException();
1770 internal void UpdateSubresource(GraphicsResource resource,
int subResourceIndex, DataBox databox, ResourceRegion region)
1773 EnsureContextActive();
1775 var texture = resource as Texture;
1777 if (texture != null)
1779 var width = region.Right - region.Left;
1780 var height = region.Bottom - region.Top;
1783 var packAlignment = 0;
1784 if ((databox.RowPitch & 1) != 0)
1786 if (databox.RowPitch == width)
1789 else if ((databox.RowPitch & 2) != 0)
1791 var diff = databox.RowPitch - width;
1792 if (diff >= 0 && diff < 2)
1795 else if ((databox.RowPitch & 4) != 0)
1797 var diff = databox.RowPitch - width;
1798 if (diff >= 0 && diff < 4)
1801 else if ((databox.RowPitch & 8) != 0)
1803 var diff = databox.RowPitch - width;
1804 if (diff >= 0 && diff < 8)
1807 else if(databox.RowPitch == width)
1811 if(packAlignment == 0)
1812 throw new NotImplementedException(
"The data box RowPitch is not compatible with the region width. This requires additional copy to be implemented.");
1815 int previousPackAlignment;
1816 GL.GetInteger(GetPName.UnpackAlignment, out previousPackAlignment);
1817 GL.PixelStore(PixelStoreParameter.UnpackAlignment, packAlignment);
1819 if (activeTexture != 0)
1822 GL.ActiveTexture(TextureUnit.Texture0);
1826 GL.BindTexture(texture.Target, texture.resourceId);
1827 GL.TexSubImage2D(texture.Target, subResourceIndex, region.Left, region.Top, width, height, texture.FormatGl, texture.Type, databox.DataPointer);
1828 boundTextures[0] = null;
1831 GL.PixelStore(PixelStoreParameter.UnpackAlignment, previousPackAlignment);
1835 internal static void UnbindGraphicsContext(IGraphicsContext graphicsContext)
1837 graphicsContext.MakeCurrent(null);
1839 #if SILICONSTUDIO_PLATFORM_IOS
1842 MonoTouch.OpenGLES.EAGLContext.SetCurrentContext(null);
1846 private void OnApplicationPaused(
object sender,
EventArgs e)
1849 Monitor.Enter(asyncCreationLockObject, ref asyncCreationLockTaken);
1851 ApplicationPaused =
true;
1853 using (UseOpenGLCreationContext())
1859 UnbindGraphicsContext(graphicsContext);
1862 private void OnApplicationResumed(
object sender,
EventArgs e)
1864 windowInfo = gameWindow.WindowInfo;
1867 graphicsContext.MakeCurrent(windowInfo);
1869 ApplicationPaused =
false;
1872 if (asyncCreationLockTaken)
1874 Monitor.Exit(asyncCreationLockObject);
1875 asyncCreationLockTaken =
false;
1879 internal void UpdateViewport(Viewport viewport)
1881 GL.Viewport((int)viewport.X, boundFBOHeight - (
int)viewport.Y - (int)viewport.Height, (
int)viewport.Width, (int)viewport.Height);
1884 #if !SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
1885 internal void UpdateViewports()
1887 int nbViewports = _currentViewports.Length;
1888 float[] viewports =
new float[nbViewports * 4];
1889 for (
int i = 0; i < nbViewports; ++i)
1891 var currViewport = _currentViewports[i];
1892 viewports[4 * i] = currViewport.X;
1893 viewports[4 * i + 1] = currViewport.Height - currViewport.Y;
1894 viewports[4 * i + 2] = currViewport.Width;
1895 viewports[4 * i + 3] = currViewport.Height;
1897 GL.ViewportArray(0, nbViewports, viewports);
1903 #if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
1904 gameWindow = (OpenTK.GameWindow)windowHandle.NativeHandle;
1905 graphicsContext = gameWindow.Context;
1906 #elif SILICONSTUDIO_PLATFORM_ANDROID
1908 typeof (opentkold::OpenTK.Platform.Android.AndroidGameView).ToString();
1909 gameWindow = (AndroidGameView)windowHandle.NativeHandle;
1910 graphicsContext = gameWindow.GraphicsContext;
1911 gameWindow.Load += OnApplicationResumed;
1912 gameWindow.Unload += OnApplicationPaused;
1913 #elif SILICONSTUDIO_PLATFORM_IOS
1914 gameWindow = (iPhoneOSGameView)windowHandle.NativeHandle;
1915 graphicsContext = gameWindow.GraphicsContext;
1916 gameWindow.Load += OnApplicationResumed;
1917 gameWindow.Unload += OnApplicationPaused;
1920 windowInfo = gameWindow.WindowInfo;
1923 GraphicsContext.ShareContexts =
true;
1926 var creationFlags = GraphicsContextFlags.Default;
1927 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
1930 #if !SILICONSTUDIO_PLATFORM_MONO_MOBILE
1931 OpenTK.Platform.Utilities.ForceEmbedded =
true;
1933 creationFlags |= GraphicsContextFlags.Embedded;
1940 #if SILICONSTUDIO_PLATFORM_ANDROID
1941 var renderer = GL.GetString(StringName.Renderer);
1942 Workaround_VAO_PowerVR_SGX_540 = renderer ==
"PowerVR SGX 540";
1943 Workaround_Context_Tegra2_Tegra3 = renderer ==
"NVIDIA Tegra 3" || renderer ==
"NVIDIA Tegra 2";
1945 var androidGraphicsContext = (AndroidGraphicsContext)graphicsContext;
1946 if (Workaround_Context_Tegra2_Tegra3)
1951 deviceCreationContext = graphicsContext;
1952 deviceCreationWindowInfo = windowInfo;
1955 gameWindow.AutoSetContextOnRenderFrame =
false;
1959 if (androidAsyncDeviceCreationContext != null)
1961 androidAsyncDeviceCreationContext.Dispose();
1962 deviceCreationContext.Dispose();
1963 deviceCreationWindowInfo.Dispose();
1965 androidAsyncDeviceCreationContext =
new AndroidAsyncGraphicsContext(androidGraphicsContext, (AndroidWindow)windowInfo);
1966 deviceCreationContext = OpenTK.Graphics.GraphicsContext.CreateDummyContext(androidAsyncDeviceCreationContext.Context);
1967 deviceCreationWindowInfo = OpenTK.Platform.Utilities.CreateDummyWindowInfo();
1970 graphicsContextEglPtr = EglGetCurrentContext();
1971 #elif SILICONSTUDIO_PLATFORM_IOS
1972 var asyncContext =
new MonoTouch.OpenGLES.EAGLContext(MonoTouch.OpenGLES.EAGLRenderingAPI.OpenGLES2, gameWindow.EAGLContext.ShareGroup);
1973 MonoTouch.OpenGLES.EAGLContext.SetCurrentContext(asyncContext);
1974 deviceCreationContext =
new OpenTK.Graphics.GraphicsContext(
new OpenTK.ContextHandle(asyncContext.Handle), null, graphicsContext, versionMajor, versionMinor, creationFlags);
1975 deviceCreationWindowInfo = windowInfo;
1976 gameWindow.MakeCurrent();
1978 deviceCreationWindowInfo = windowInfo;
1979 deviceCreationContext =
new GraphicsContext(graphicsContext.GraphicsMode, deviceCreationWindowInfo, versionMajor, versionMinor, creationFlags);
1980 GraphicsContext.CurrentContext.MakeCurrent(null);
1984 defaultSamplerState = SamplerState.New(
this,
new SamplerStateDescription(
TextureFilter.MinPointMagMipLinear,
TextureAddressMode.Wrap) { MaxAnisotropy = 1 }).KeepAliveBy(
this);
1986 this.immediateContext =
this;
1989 protected void DestroyPlatformDevice()
1993 if (ApplicationPaused)
1995 asyncCreationLockObject =
new object();
1998 #if SILICONSTUDIO_PLATFORM_ANDROID || SILICONSTUDIO_PLATFORM_IOS
1999 gameWindow.Load -= OnApplicationResumed;
2000 gameWindow.Unload -= OnApplicationPaused;
2004 internal void OnDestroyed()
2006 EffectInputSignature.OnDestroyed();
2009 lock (RootDevice.existingFBOs)
2011 RootDevice.existingFBOs.Clear();
2012 RootDevice.existingFBOs[
new FBOKey(windowProvidedDepthBuffer,
new[] { windowProvidedRenderTarget })] = windowProvidedFrameBuffer;
2016 for (
int i = 0; i < boundTextures.Length; ++i)
2017 boundTextures[i] = null;
2019 boundFrontFace = FrontFaceDirection.Ccw;
2021 boundVertexArrayObject = null;
2022 enabledVertexAttribArrays = 0;
2023 boundDepthStencilState = null;
2024 boundStencilReference = 0;
2025 boundBlendState = null;
2026 boundRasterizerState = null;
2027 boundDepthStencilBuffer = null;
2029 for (
int i = 0; i < boundRenderTargets.Length; ++i)
2030 boundRenderTargets[i] = null;
2037 private void SetDefaultStates()
2040 SetDepthStencilState(null);
2041 currentFrontFace = FrontFaceDirection.Cw;
2042 boundFrontFace = FrontFaceDirection.Cw;
2043 GL.FrontFace(currentFrontFace);
2047 internal void InitDefaultRenderTarget(PresentationParameters presentationParameters)
2050 windowProvidedRenderTexture =
new Texture2D(
this,
new TextureDescription
2052 Dimension = TextureDimension.Texture2D,
2053 Format = presentationParameters.BackBufferFormat,
2054 Width = presentationParameters.BackBufferWidth,
2055 Height = presentationParameters.BackBufferHeight,
2056 Flags = TextureFlags.RenderTarget,
2061 windowProvidedRenderTexture.Reload = (graphicsResource) => { };
2062 windowProvidedRenderTarget = windowProvidedRenderTexture.ToRenderTarget();
2064 if (presentationParameters.DepthStencilFormat !=
PixelFormat.None)
2066 windowProvidedDepthTexture =
new Texture2D(
this,
new TextureDescription
2068 Dimension = TextureDimension.Texture2D,
2069 Format = presentationParameters.DepthStencilFormat,
2070 Width = presentationParameters.BackBufferWidth,
2071 Height = presentationParameters.BackBufferHeight,
2072 Flags = TextureFlags.DepthStencil,
2077 windowProvidedDepthTexture.Reload = (graphicsResource) => { };
2078 windowProvidedDepthBuffer =
new DepthStencilBuffer(
this, windowProvidedDepthTexture,
false);
2081 #if SILICONSTUDIO_PLATFORM_IOS
2083 windowProvidedFrameBuffer = gameWindow.Framebuffer;
2084 boundFBO = windowProvidedFrameBuffer;
2086 GL.BindFramebuffer(FramebufferTarget.Framebuffer, windowProvidedFrameBuffer);
2089 int renderTargetTextureId;
2090 GL.GetFramebufferAttachmentParameter(FramebufferTarget.Framebuffer, FramebufferSlot.ColorAttachment0, FramebufferParameterName.FramebufferAttachmentObjectName, out renderTargetTextureId);
2091 windowProvidedRenderTexture.resourceId = renderTargetTextureId;
2092 windowProvidedRenderTexture.Reload = (graphicsResource) => {
throw new NotImplementedException(); };
2093 windowProvidedRenderTarget.resourceId = renderTargetTextureId;
2096 GL.GetFramebufferAttachmentParameter(FramebufferTarget.Framebuffer, FramebufferSlot.DepthAttachment, FramebufferParameterName.FramebufferAttachmentObjectName, out renderTargetTextureId);
2097 windowProvidedDepthTexture.resourceId = renderTargetTextureId;
2098 windowProvidedDepthTexture.Reload = (graphicsResource) => {
throw new NotImplementedException(); };
2099 windowProvidedDepthBuffer.resourceId = renderTargetTextureId;
2102 RootDevice.existingFBOs[
new FBOKey(windowProvidedDepthBuffer,
new[] { windowProvidedRenderTarget })] = windowProvidedFrameBuffer;
2109 defaultRenderTarget = windowProvidedRenderTarget;
2112 public GraphicsDevice ImmediateContext
2114 get {
return this.immediateContext; }
2117 public bool IsDeferredContextSupported
2119 get {
return false; }
2122 private class SwapChainBackend
2124 public PresentationParameters PresentationParameters;
2125 public int PresentCount;
2133 SwapChainBackend CreateSwapChainBackend(PresentationParameters presentationParameters)
2135 var swapChainBackend =
new SwapChainBackend();
2136 return swapChainBackend;
2142 public PresentationParameters PresentationParameters
2146 if (_defaultSwapChainBackend == null)
throw new InvalidOperationException(FrameworkResources.NoDefaultRenterTarget);
2147 return _defaultSwapChainBackend.PresentationParameters;
2155 internal RenderTarget DefaultRenderTarget
2159 return defaultRenderTarget;
2183 public bool IsFullScreen
2187 throw new NotImplementedException();
2192 throw new NotImplementedException();
2197 internal void UseTemporaryFirstTexture()
2200 GL.ActiveTexture(TextureUnit.Texture0);
2201 boundTextures[0] = null;
2204 #if SILICONSTUDIO_PLATFORM_ANDROID
2207 internal void ExecutePendingTasks()
2210 graphicsContext.MakeCurrent(null);
2213 Monitor.Wait(asyncCreationLockObject);
2216 graphicsContext.MakeCurrent(windowInfo);
2220 internal struct FBOKey
2222 public readonly DepthStencilBuffer DepthStencilBuffer;
2223 public readonly RenderTarget[] RenderTargets;
2224 public readonly
int LastRenderTarget;
2226 public FBOKey(DepthStencilBuffer depthStencilBuffer, RenderTarget[] renderTargets)
2228 DepthStencilBuffer = depthStencilBuffer;
2230 LastRenderTarget = 0;
2231 if (renderTargets != null)
2233 for (
int i = 0; i < renderTargets.Length; ++i)
2235 if (renderTargets[i] != null)
2237 LastRenderTarget = i + 1;
2243 RenderTargets = LastRenderTarget != 0 ? renderTargets : null;
2246 public override bool Equals(
object obj)
2248 if (!(obj is FBOKey))
return false;
2250 var obj2 = (FBOKey)obj;
2252 if (obj2.DepthStencilBuffer != DepthStencilBuffer)
return false;
2255 if (LastRenderTarget != obj2.LastRenderTarget)
2259 for (
int i = 0; i < LastRenderTarget; ++i)
2260 if (obj2.RenderTargets[i] != RenderTargets[i])
2266 public override int GetHashCode()
2268 var result = DepthStencilBuffer != null ? DepthStencilBuffer.GetHashCode() : 0;
2269 if (RenderTargets != null)
2271 for (
int index = 0; index < LastRenderTarget; index++)
2273 var renderTarget = RenderTargets[index];
2274 result ^= renderTarget != null ? renderTarget.GetHashCode() : 0;
SiliconStudio.Paradox.Games.Mathematics.Vector2 Vector2
GraphicsDeviceStatus
Describes the current status of a GraphicsDevice.
GraphicsResourceUsage
Identifies expected resource use during rendering. The usage directly reflects whether a resource is ...
TextureAddressMode
Identify a technique for resolving texture coordinates that are outside of the boundaries of a textur...
TextureFilter
Filtering options during texture sampling.
Represents a color in the form of rgba.
SiliconStudio.Paradox.Graphics.Buffer Buffer
Flags
Enumeration of the new Assimp's flags.
SiliconStudio.Core.Mathematics.Color Color
Same as Deferred mode, except sprites are sorted by texture prior to drawing. This can improve perfor...
System.Windows.Shapes.Rectangle Rectangle
ShaderStage
Enum to specify shader stage.
SiliconStudio.Paradox.Graphics.PrimitiveType PrimitiveType
Creates a render target buffer.
MapMode
Describes how the cpu is accessing a GraphicsResource with the GraphicsDeviceContext.Map method.
Blend
Blend option. A blend option identifies the data source and an optional pre-blend operation...
GraphicsProfile
Identifies the set of supported devices for the demo based on device capabilities.
PixelFormat
Defines various types of pixel formats.
DepthStencilClearOptions
Specifies the buffer to use when calling Clear.
The texture dimension is 2D.