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