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