Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
BlendState.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 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
6 using OpenTK.Graphics.ES30;
7 #else
8 using OpenTK.Graphics.OpenGL;
9 #endif
10 
11 namespace SiliconStudio.Paradox.Graphics
12 {
13  public partial class BlendState
14  {
15  private readonly bool blendEnable;
16  private readonly BlendEquationMode blendEquationModeColor;
17  private readonly BlendEquationMode blendEquationModeAlpha;
18  private readonly BlendingFactorSrc blendFactorSrcColor;
19  private readonly BlendingFactorSrc blendFactorSrcAlpha;
20  private readonly BlendingFactorDest blendFactorDestColor;
21  private readonly BlendingFactorDest blendFactorDestAlpha;
22  private readonly uint blendEquationHash;
23  private readonly uint blendFuncHash;
24  internal readonly bool[] EnabledColors = new bool[4];
25 
26  internal BlendState(GraphicsDevice device, BlendStateDescription blendStateDescription) : base(device)
27  {
28  Description = blendStateDescription;
29 
30  for (int i = 1; i < Description.RenderTargets.Length; ++i)
31  {
32  if (Description.RenderTargets[i].BlendEnable || Description.RenderTargets[i].ColorWriteChannels != ColorWriteChannels.All)
33  throw new NotSupportedException();
34  }
35 
36  blendEnable = Description.RenderTargets[0].BlendEnable;
37 
38  blendEquationModeColor = ToOpenGL(Description.RenderTargets[0].ColorBlendFunction);
39  blendEquationModeAlpha = ToOpenGL(Description.RenderTargets[0].AlphaBlendFunction);
40  blendFactorSrcColor = ToOpenGL(Description.RenderTargets[0].ColorSourceBlend);
41  blendFactorSrcAlpha = ToOpenGL(Description.RenderTargets[0].AlphaSourceBlend);
42  blendFactorDestColor = (BlendingFactorDest)ToOpenGL(Description.RenderTargets[0].ColorDestinationBlend);
43  blendFactorDestAlpha = (BlendingFactorDest)ToOpenGL(Description.RenderTargets[0].AlphaDestinationBlend);
44  EnabledColors[0] = (Description.RenderTargets[0].ColorWriteChannels & ColorWriteChannels.Red ) != 0;
45  EnabledColors[1] = (Description.RenderTargets[0].ColorWriteChannels & ColorWriteChannels.Green) != 0;
46  EnabledColors[2] = (Description.RenderTargets[0].ColorWriteChannels & ColorWriteChannels.Blue ) != 0;
47  EnabledColors[3] = (Description.RenderTargets[0].ColorWriteChannels & ColorWriteChannels.Alpha) != 0;
48 
49  blendEquationHash = (uint)Description.RenderTargets[0].ColorBlendFunction
50  | ((uint)Description.RenderTargets[0].AlphaBlendFunction << 8);
51 
52  blendFuncHash = (uint)Description.RenderTargets[0].ColorSourceBlend
53  | ((uint)Description.RenderTargets[0].AlphaSourceBlend << 8)
54  | ((uint)Description.RenderTargets[0].ColorDestinationBlend << 16)
55  | ((uint)Description.RenderTargets[0].AlphaDestinationBlend << 24);
56  }
57 
58  /// <inheritdoc/>
59  protected internal override bool OnRecreate()
60  {
61  base.OnRecreate();
62  return true;
63  }
64 
65  public static BlendEquationMode ToOpenGL(BlendFunction blendFunction)
66  {
67  switch (blendFunction)
68  {
69  case BlendFunction.Subtract:
70  return BlendEquationMode.FuncSubtract;
71  case BlendFunction.Add:
72  return BlendEquationMode.FuncAdd;
73 #if !SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
74  case BlendFunction.Max:
75  return BlendEquationMode.Max;
76  case BlendFunction.Min:
77  return BlendEquationMode.Min;
78 #endif
79  case BlendFunction.ReverseSubtract:
80  return BlendEquationMode.FuncReverseSubtract;
81  default:
82  throw new NotSupportedException();
83  }
84  }
85 
86  public static BlendingFactorSrc ToOpenGL(Blend blend)
87  {
88  switch (blend)
89  {
90  case Blend.Zero:
91  return BlendingFactorSrc.Zero;
92  case Blend.One:
93  return BlendingFactorSrc.One;
94  case Blend.SourceColor:
95  return (BlendingFactorSrc)BlendingFactorDest.SrcColor;
96  case Blend.InverseSourceColor:
97  return (BlendingFactorSrc)BlendingFactorDest.OneMinusSrcColor;
98  case Blend.SourceAlpha:
99  return BlendingFactorSrc.SrcAlpha;
100  case Blend.InverseSourceAlpha:
101  return BlendingFactorSrc.OneMinusSrcAlpha;
102  case Blend.DestinationAlpha:
103  return BlendingFactorSrc.DstAlpha;
104  case Blend.InverseDestinationAlpha:
105  return BlendingFactorSrc.OneMinusDstAlpha;
106  case Blend.DestinationColor:
107  return BlendingFactorSrc.DstColor;
108  case Blend.InverseDestinationColor:
109  return BlendingFactorSrc.OneMinusDstColor;
110  case Blend.SourceAlphaSaturate:
111  return BlendingFactorSrc.SrcAlphaSaturate;
112  case Blend.BlendFactor:
113  return BlendingFactorSrc.ConstantColor;
114  case Blend.InverseBlendFactor:
115  return BlendingFactorSrc.OneMinusConstantColor;
116  case Blend.SecondarySourceColor:
117  case Blend.InverseSecondarySourceColor:
118  case Blend.SecondarySourceAlpha:
119  case Blend.InverseSecondarySourceAlpha:
120  throw new NotSupportedException();
121  default:
122  throw new ArgumentOutOfRangeException("blend");
123  }
124  }
125 
126  public void Apply(BlendState oldBlendState)
127  {
128  // note: need to update blend equation, blend function and color mask even when the blend state is disable in order to keep the hash based caching system valid
129 
130  if (blendEnable && !oldBlendState.blendEnable)
131  GL.Enable(EnableCap.Blend);
132 
133  if (blendEquationHash != oldBlendState.blendEquationHash)
134  GL.BlendEquationSeparate(blendEquationModeColor, blendEquationModeAlpha);
135 
136  if (blendFuncHash != oldBlendState.blendFuncHash)
137  GL.BlendFuncSeparate(blendFactorSrcColor, blendFactorDestColor, blendFactorSrcAlpha, blendFactorDestAlpha);
138 
139  if (Description.RenderTargets[0].ColorWriteChannels != oldBlendState.Description.RenderTargets[0].ColorWriteChannels)
140  ApplyColorMask();
141 
142  if(!blendEnable && oldBlendState.blendEnable)
143  GL.Disable(EnableCap.Blend);
144  }
145 
146  internal void ApplyColorMask()
147  {
148  bool hasRenderTarget = GraphicsDevice.hasRenderTarget;
149  GL.ColorMask(hasRenderTarget && EnabledColors[0], hasRenderTarget && EnabledColors[1], hasRenderTarget && EnabledColors[2], hasRenderTarget && EnabledColors[3]);
150  }
151  }
152 }
153 #endif
BlendFunction
RGB or alpha blending operation.
ColorWriteChannels
Identify which components of each pixel of a render target are writable during blending.
Blend
Blend option. A blend option identifies the data source and an optional pre-blend operation...
Definition: Blend.cs:14