1 module gfm.sdl2.renderer; 2 3 import std..string; 4 5 import derelict.sdl2.sdl; 6 7 static if( __VERSION__ >= 2067 ) 8 import std.experimental.logger; 9 else 10 import std.historical.logger; 11 12 import gfm.sdl2.sdl, 13 gfm.sdl2.window, 14 gfm.sdl2.texture, 15 gfm.sdl2.surface; 16 17 /// SDL Renderer wrapper. 18 final class SDL2Renderer 19 { 20 public 21 { 22 /// Creates a SDL renderer which targets a window. 23 /// See_also: $(LINK http://wiki.libsdl.org/SDL_CreateRenderer) 24 /// Throws: $(D SDL2Exception) on error. 25 this(SDL2Window window, int flags = 0) 26 { 27 _sdl2 = window._sdl2; 28 _renderer = SDL_CreateRenderer(window._window, -1, flags); 29 if (_renderer is null) 30 _sdl2.throwSDL2Exception("SDL_CreateRenderer"); 31 32 readCapabilities(); 33 } 34 35 /// Create a software renderer which targets a surface. 36 /// See_also: $(LINK http://wiki.libsdl.org/SDL_CreateSoftwareRenderer) 37 /// Throws: $(D SDL2Exception) on error. 38 this(SDL2Surface surface) 39 { 40 _sdl2 = surface._sdl2; 41 _renderer = SDL_CreateSoftwareRenderer(surface._surface); 42 if (_renderer is null) 43 _sdl2.throwSDL2Exception("SDL_CreateSoftwareRenderer"); 44 45 readCapabilities(); 46 } 47 48 /// Releases the SDL ressource. 49 /// See_also: $(LINK http://wiki.libsdl.org/SDL_DestroyRenderer) 50 ~this() 51 { 52 if (_renderer !is null) 53 { 54 debug ensureNotInGC("SDL2Renderer"); 55 SDL_DestroyRenderer(_renderer); 56 _renderer = null; 57 } 58 } 59 60 deprecated("Use .destroy instead") void close(){} 61 62 /// Clear the current rendering target with the drawing color. 63 /// See_also: $(LINK http://wiki.libsdl.org/SDL_RenderClear) 64 /// Throws: $(D SDL2Exception) on error. 65 void clear() 66 { 67 if (0 != SDL_RenderClear(_renderer)) 68 _sdl2.throwSDL2Exception("SDL_RenderClear"); 69 } 70 71 /// Update the screen with rendering performed. 72 /// See_also: $(LINK http://wiki.libsdl.org/SDL_RenderPresent) 73 void present() 74 { 75 SDL_RenderPresent(_renderer); 76 } 77 78 /// Sets the color used for drawing operations. 79 /// See_also: $(LINK http://wiki.libsdl.org/SDL_SetRenderDrawColor) 80 /// Throws: $(D SDL2Exception) on error. 81 void setColor(int r, int g, int b, int a = 255) 82 { 83 if (0 != SDL_SetRenderDrawColor(_renderer, cast(ubyte)r, cast(ubyte)g, cast(ubyte)b, cast(ubyte)a)) 84 _sdl2.throwSDL2Exception("SDL_SetRenderDrawColor"); 85 } 86 87 /// Sets the window drawing area. 88 /// See_also: $(LINK http://wiki.libsdl.org/SDL_RenderSetViewport) 89 /// Throws: $(D SDL2Exception) on error. 90 void setViewport(int x, int y, int w, int h) 91 { 92 SDL_Rect r = SDL_Rect(x, y, w, h); 93 if (0 != SDL_RenderSetViewport(_renderer, &r)) 94 _sdl2.throwSDL2Exception("SDL_RenderSetViewport"); 95 } 96 97 /// Sets the whole window as drawing area. 98 /// See_also: $(LINK http://wiki.libsdl.org/SDL_RenderSetViewport) 99 /// Throws: $(D SDL2Exception) on error. 100 void setViewportFull() 101 { 102 if (0 != SDL_RenderSetViewport(_renderer, null)) 103 _sdl2.throwSDL2Exception("SDL_RenderSetViewport"); 104 } 105 106 /// Sets the scale of the renderer. 107 /// See_also: $(LINK http://wiki.libsdl.org/SDL_RenderSetScale) 108 /// Throws: $(D SDL2Exception) on error. 109 void setScale(float x, float y) 110 { 111 if (0 != SDL_RenderSetScale(_renderer, x, y)) 112 _sdl2.throwSDL2Exception("SDL_RenderSetScale"); 113 } 114 115 /// Sets a device independent resolution of the renderer. 116 /// See_also: $(LINK http://wiki.libsdl.org/SDL_RenderSetLogicalSize) 117 /// Throws: $(D SDL2Exception) on error. 118 void setLogicalSize(int w, int h) 119 { 120 if (0 != SDL_RenderSetLogicalSize(_renderer, w, h)) 121 _sdl2.throwSDL2Exception("SDL_RenderSetLogicalSize"); 122 } 123 124 /// Sets SDL blend mode. 125 /// See_also: $(LINK http://wiki.libsdl.org/SDL_SetRenderDrawBlendMode) 126 /// Throws: $(D SDL2Exception) on error. 127 void setBlend(int blendMode) 128 { 129 if (0 != SDL_SetRenderDrawBlendMode(_renderer, blendMode)) 130 _sdl2.throwSDL2Exception("SDL_SetRenderDrawBlendMode"); 131 } 132 133 /// Draw a line. 134 /// See_also: $(LINK http://wiki.libsdl.org/SDL_RenderDrawLine) 135 /// Throws: $(D SDL2Exception) on error. 136 void drawLine(int x1, int y1, int x2, int y2) 137 { 138 if (0 != SDL_RenderDrawLine(_renderer, x1, y1, x2, y2)) 139 _sdl2.throwSDL2Exception("SDL_RenderDrawLine"); 140 141 } 142 143 /// Draw several lines at once. 144 /// See_also: $(LINK http://wiki.libsdl.org/SDL_RenderDrawLines) 145 /// Throws: $(D SDL2Exception) on error. 146 void drawLines(SDL_Point[] points) 147 { 148 if (0 != SDL_RenderDrawLines(_renderer, points.ptr, cast(int)(points.length))) 149 _sdl2.throwSDL2Exception("SDL_RenderDrawLines"); 150 } 151 152 /// Draw a point. 153 /// See_also: $(LINK http://wiki.libsdl.org/SDL_RenderDrawPoint) 154 /// Throws: $(D SDL2Exception) on error. 155 void drawPoint(int x, int y) 156 { 157 if (0 != SDL_RenderDrawPoint(_renderer, x, y)) 158 _sdl2.throwSDL2Exception("SDL_RenderDrawPoint"); 159 } 160 161 /// Draw several point at once. 162 /// See_also: $(LINK http://wiki.libsdl.org/SDL_RenderDrawPoints) 163 /// Throws: $(D SDL2Exception) on error. 164 void drawPoints(SDL_Point[] points) 165 { 166 if (0 != SDL_RenderDrawPoints(_renderer, points.ptr, cast(int)(points.length))) 167 _sdl2.throwSDL2Exception("SDL_RenderDrawPoints"); 168 } 169 170 /// Draw a rectangle outline. 171 /// See_also: $(LINK http://wiki.libsdl.org/SDL_RenderDrawRect) 172 /// Throws: $(D SDL2Exception) on error. 173 void drawRect(int x, int y, int width, int height) 174 { 175 SDL_Rect r = SDL_Rect(x, y, width, height); 176 if (0 != SDL_RenderDrawRect(_renderer, &r)) 177 _sdl2.throwSDL2Exception("SDL_RenderDrawRect"); 178 } 179 180 /// Draw a filled rectangle. 181 /// See_also: $(LINK http://wiki.libsdl.org/SDL_RenderFillRect) 182 /// Throws: $(D SDL2Exception) on error. 183 void fillRect(int x, int y, int width, int height) 184 { 185 SDL_Rect r = SDL_Rect(x, y, width, height); 186 if (0 != SDL_RenderFillRect(_renderer, &r)) 187 _sdl2.throwSDL2Exception("SDL_RenderFillRect"); 188 } 189 190 /// Blit a rectangle from a texture. 191 /// See_also: $(LINK http://wiki.libsdl.org/SDL_RenderCopy) 192 /// Throws: $(D SDL2Exception) on error. 193 void copy(SDL2Texture texture, SDL_Rect srcRect, SDL_Rect dstRect) 194 { 195 if (0 != SDL_RenderCopy(_renderer, texture._handle, &srcRect, &dstRect)) 196 _sdl2.throwSDL2Exception("SDL_RenderCopy"); 197 } 198 199 /// Draws a whole texture. 200 /// See_also: $(LINK http://wiki.libsdl.org/SDL_RenderCopy) 201 /// Throws: $(D SDL2Exception) on error. 202 void copy(SDL2Texture texture, int x, int y) 203 { 204 int w = texture.width(); 205 int h = texture.height(); 206 SDL_Rect source = SDL_Rect(0, 0, w, h); 207 SDL_Rect dest = SDL_Rect(x, y, w, h); 208 copy(texture, source, dest); 209 } 210 211 /// Blits a rectangle from a texture and apply rotation/reflection. 212 /// See_also: $(LINK http://wiki.libsdl.org/SDL_RenderCopyEx) 213 /// Throws: $(D SDL2Exception) on error. 214 void copyEx(SDL2Texture texture, SDL_Rect srcRect, SDL_Rect dstRect, double rotangle, SDL_Point* rotcenter, SDL_RendererFlip flip) 215 { 216 if (0 != SDL_RenderCopyEx(_renderer, texture._handle, &srcRect, &dstRect, rotangle, rotcenter, flip)) 217 _sdl2.throwSDL2Exception("SDL_RenderCopyEx"); 218 } 219 220 /// Returns: Renderer information. 221 /// See_also: $(LINK http://wiki.libsdl.org/SDL_GetRendererInfo) 222 /// Throws: $(D SDL2Exception) on error. 223 SDL2RendererInfo info() 224 { 225 return _info; 226 } 227 } 228 229 package 230 { 231 SDL2 _sdl2; 232 SDL_Renderer* _renderer; 233 SDL2RendererInfo _info; 234 } 235 236 private 237 { 238 void readCapabilities() 239 { 240 SDL_RendererInfo info; 241 int res = SDL_GetRendererInfo(_renderer, &info); 242 if (res != 0) 243 _sdl2.throwSDL2Exception("SDL_GetRendererInfo"); 244 _info = new SDL2RendererInfo(info); 245 } 246 } 247 } 248 249 /// SDL Renderer information. 250 final class SDL2RendererInfo 251 { 252 public 253 { 254 this(SDL_RendererInfo info) 255 { 256 _info = info; 257 } 258 259 /// Returns: Renderer name. 260 const(char)[] name() 261 { 262 return fromStringz(_info.name); 263 } 264 265 /// Returns: true if this renderer is software. 266 bool isSoftware() 267 { 268 return (_info.flags & SDL_RENDERER_SOFTWARE) != 0; 269 } 270 271 /// Returns: true if this renderer is accelerated. 272 bool isAccelerated() 273 { 274 return (_info.flags & SDL_RENDERER_ACCELERATED) != 0; 275 } 276 277 /// Returns: true if this renderer can render to a texture. 278 bool hasRenderToTexture() 279 { 280 return (_info.flags & SDL_RENDERER_TARGETTEXTURE) != 0; 281 } 282 283 /// Returns: true if this renderer support vertical synchronization. 284 bool isVsyncEnabled() 285 { 286 return (_info.flags & SDL_RENDERER_PRESENTVSYNC) != 0; 287 } 288 289 /// Returns: Pretty string describing the renderer. 290 override string toString() 291 { 292 string res = format("renderer: %s [flags:", name()); 293 if (isSoftware()) res ~= " software"; 294 if (isAccelerated()) res ~= " accelerated"; 295 if (hasRenderToTexture()) res ~= " render-to-texture"; 296 if (isVsyncEnabled()) res ~= " vsync"; 297 res ~= "]\n"; 298 res ~= format("max. texture: %sx%s", _info.max_texture_width, _info.max_texture_height); 299 return res; 300 } 301 } 302 303 private 304 { 305 SDL_RendererInfo _info; 306 } 307 }