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