1 /* 2 ******************************************************************************************* 3 * Dgame (a D game framework) - Copyright (c) Randy Schütt 4 * 5 * This software is provided 'as-is', without any express or implied warranty. 6 * In no event will the authors be held liable for any damages arising from 7 * the use of this software. 8 * 9 * Permission is granted to anyone to use this software for any purpose, 10 * including commercial applications, and to alter it and redistribute it 11 * freely, subject to the following restrictions: 12 * 13 * 1. The origin of this software must not be misrepresented; you must not claim 14 * that you wrote the original software. If you use this software in a product, 15 * an acknowledgment in the product documentation would be appreciated but is 16 * not required. 17 * 18 * 2. Altered source versions must be plainly marked as such, and must not be 19 * misrepresented as being the original software. 20 * 21 * 3. This notice may not be removed or altered from any source distribution. 22 ******************************************************************************************* 23 */ 24 module Dgame.Graphics.Blend; 25 26 private { 27 import derelict.opengl3.gl; 28 29 import Dgame.Graphics.Color; 30 } 31 32 /** 33 * Enable blending 34 */ 35 interface Blendable { 36 /** 37 * Set (or reset) the current Blend instance. 38 */ 39 void setBlend(Blend blend) pure nothrow; 40 /** 41 * Returns the current Blend instance, or null. 42 */ 43 inout(Blend) getBlend() inout pure nothrow; 44 } 45 46 /** 47 * The Blend class. If you want that a blendable object get some blend, 48 * create an instance of this class and give it to your blendable. 49 * 50 * Author: rschuett 51 */ 52 class Blend { 53 /** 54 * Supported BlendModes 55 */ 56 enum Mode : ubyte { 57 None, /// No blending. 58 Alpha, /// Pixel = Src * a + Dest * (1 - a) 59 Add, /// Pixel = Src + Dest 60 Multiply /// Pixel = Src * Dest 61 } 62 63 private: 64 Mode _mode; 65 Color _color; 66 bool _isBlendColor; 67 68 public: 69 /** 70 * Apply the blending 71 */ 72 void applyBlending() const { 73 this.enable(true); 74 75 if (this._isBlendColor) { 76 const float[4] col = this._color.asGLColor(); 77 78 version(all) 79 glBlendColor(col[0], col[1], col[2], col[3]); 80 else 81 glColor4f(col[0], col[1], col[2], col[3]); 82 } 83 84 final switch (this._mode) { 85 case Mode.Alpha: // Alpha blending 86 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 87 break; 88 case Mode.Add: // Additive blending 89 glBlendFunc(GL_SRC_ALPHA, GL_ONE); 90 break; 91 case Mode.Multiply: // Multiplicative blending 92 glBlendFunc(GL_DST_COLOR, GL_ZERO); 93 break; 94 case Mode.None: // No blending 95 glBlendFunc(GL_ONE, GL_ZERO); 96 break; 97 } 98 } 99 100 final: 101 /** 102 * CTor 103 */ 104 this(Mode mode) { 105 this.setBlendMode(mode); 106 } 107 108 /** 109 * CTor 110 */ 111 this(Mode mode, ref const Color col) { 112 this(mode); 113 114 this.setBlendColor(col); 115 } 116 117 /** 118 * Rvalue version 119 */ 120 this(Mode mode, const Color col) { 121 this(mode, col); 122 } 123 124 /** 125 * Enable or Disable blending 126 */ 127 void enable(bool enable) const { 128 const bool isEnabled = glIsEnabled(GL_BLEND) == GL_TRUE; 129 130 if (enable && !isEnabled) 131 glEnable(GL_BLEND); 132 else if (!enable && isEnabled) 133 glDisable(GL_BLEND); 134 } 135 136 /** 137 * Activate or deactivate the using of the blend color. 138 */ 139 void enableColor(bool enable) pure nothrow { 140 this._isBlendColor = enable; 141 } 142 143 /** 144 * Set the Blendmode. 145 */ 146 void setBlendMode(Mode mode) pure nothrow { 147 this._mode = mode; 148 } 149 150 /** 151 * Returns the current Blendmode. 152 */ 153 Mode getBlendMode() const pure nothrow { 154 return this._mode; 155 } 156 157 /** 158 * Set the Blend Color. 159 */ 160 void setBlendColor(ref const Color col) pure nothrow { 161 this._isBlendColor = true; 162 this._color = col; 163 } 164 165 /** 166 * Rvalue version 167 */ 168 void setBlendColor(const Color col) pure nothrow { 169 this.setBlendColor(col); 170 } 171 172 /** 173 * Returns the current Blend Color. 174 */ 175 ref const(Color) getBlendColor() const pure nothrow { 176 return this._color; 177 } 178 }