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