1 module gfm.sdl2.texture;
2 
3 import std.string;
4 
5 import derelict.sdl2.sdl;
6 
7 import gfm.sdl2.sdl,
8        gfm.sdl2.surface,
9        gfm.sdl2.renderer;
10 
11 /// SDL Texture wrapper.
12 final class SDL2Texture
13 {
14     public
15     {
16         /// Creates a SDL Texture for a specific renderer.
17         /// See_also: $(LINK http://wiki.libsdl.org/SDL_CreateTexture)
18         /// Throws: $(D SDL2Exception) on error.
19         this(SDL2Renderer renderer, uint format, uint access, int width, int height)
20         {
21             _sdl2 = renderer._sdl2;
22             _renderer = renderer;
23             _handle = SDL_CreateTexture(renderer._renderer, format, access, width, height);
24             if (_handle is null)
25                 _sdl2.throwSDL2Exception("SDL_CreateTexture");
26         }
27 
28         /// Creates a SDL Texture for a specific renderer, from an existing surface.
29         /// See_also: $(LINK http://wiki.libsdl.org/SDL_CreateTextureFromSurface)
30         /// Throws: $(D SDL2Exception) on error.
31         this(SDL2Renderer renderer, SDL2Surface surface)
32         {
33             _handle = SDL_CreateTextureFromSurface(renderer._renderer, surface._surface);
34             _renderer = renderer;
35             if (_handle is null)
36                 _sdl2.throwSDL2Exception("SDL_CreateTextureFromSurface");
37         }
38 
39         /// Releases the SDL resource.
40         ~this()
41         {
42             if (_handle !is null)
43             {
44                 debug ensureNotInGC("SDL2Texture");
45                 SDL_DestroyTexture(_handle);
46                 _handle = null;
47             }
48         }
49 
50         /// See_also: $(LINK http://wiki.libsdl.org/SDL_SetTextureBlendMode)
51         /// Throws: $(D SDL2Exception) on error.
52         void setBlendMode(SDL_BlendMode blendMode)
53         {
54             if (SDL_SetTextureBlendMode(_handle, blendMode) != 0)
55                 _sdl2.throwSDL2Exception("SDL_SetTextureBlendMode");
56         }
57 
58         /// See_also: $(LINK http://wiki.libsdl.org/SDL_SetTextureColorMod)
59         /// Throws: $(D SDL2Exception) on error.
60         void setColorMod(int r, int g, int b)
61         {
62             if (SDL_SetTextureColorMod(_handle, cast(ubyte)r, cast(ubyte)g, cast(ubyte)b) != 0)
63                 _sdl2.throwSDL2Exception("SDL_SetTextureColorMod");
64         }
65 
66         /// See_also: $(LINK http://wiki.libsdl.org/SDL_SetTextureAlphaMod)
67         /// Throws: $(D SDL2Exception) on error.
68         void setAlphaMod(int a)
69         {
70 
71             // #Workaround SDL software renderer bug with alpha = 255
72             if (_renderer.info().isSoftware())
73             {
74                 if (a >= 255)
75                     a = 254;
76             }
77 
78             if (SDL_SetTextureAlphaMod(_handle, cast(ubyte)a) != 0)
79                 _sdl2.throwSDL2Exception("SDL_SetTextureAlphaMod");
80         }
81 
82         /// Returns: Texture format.
83         /// See_also: $(LINK http://wiki.libsdl.org/SDL_QueryTexture)
84         /// Throws: $(D SDL2Exception) on error.
85         uint format()
86         {
87             uint res;
88             int err = SDL_QueryTexture(_handle, &res, null, null, null);
89             if (err != 0)
90                 _sdl2.throwSDL2Exception("SDL_QueryTexture");
91 
92             return res;
93         }
94 
95         /// Returns: Texture access.
96         /// See_also: $(LINK http://wiki.libsdl.org/SDL_QueryTexture)
97         /// Throws: $(D SDL2Exception) on error.
98         int access()
99         {
100             int res;
101             int err = SDL_QueryTexture(_handle, null, &res, null, null);
102             if (err != 0)
103                 _sdl2.throwSDL2Exception("SDL_QueryTexture");
104 
105             return res;
106         }
107 
108         /// Returns: Width of texture.
109         /// See_also: $(LINK http://wiki.libsdl.org/SDL_QueryTexture)
110         /// Throws: $(D SDL2Exception) on error.
111         int width()
112         {
113             int res;
114             int err = SDL_QueryTexture(_handle, null, null, &res, null);
115             if (err != 0)
116                 _sdl2.throwSDL2Exception("SDL_QueryTexture");
117             return res;
118         }
119 
120         /// Returns: Height of texture.
121         /// See_also: $(LINK http://wiki.libsdl.org/SDL_QueryTexture)
122         /// Throws: $(D SDL2Exception) on error.
123         int height()
124         {
125             int res;
126             int err = SDL_QueryTexture(_handle, null, null, null, &res);
127             if (err != 0)
128                 _sdl2.throwSDL2Exception("SDL_QueryTexture");
129             return res;
130         }
131 
132         /// Updates the whole texture with new pixel data.
133         /// See_also: $(LINK http://wiki.libsdl.org/SDL_UpdateTexture)
134         /// Throws: $(D SDL2Exception) on error.
135         void updateTexture(const(void)* pixels, int pitch)
136         {
137             int err = SDL_UpdateTexture(_handle, null, pixels, pitch);
138             if (err != 0)
139                 _sdl2.throwSDL2Exception("SDL_UpdateTexture");
140         }
141 
142         /// Updates a part of a texture with new pixel data.
143         /// See_also: $(LINK http://wiki.libsdl.org/SDL_UpdateTexture)
144         /// Throws: $(D SDL2Exception) on error.
145         void updateTexture(const(SDL_Rect)* rect, const(void)* pixels, int pitch)
146         {
147             int err = SDL_UpdateTexture(_handle, rect, pixels, pitch);
148             if (err != 0)
149                 _sdl2.throwSDL2Exception("SDL_UpdateTexture");
150         }
151 
152         /// Update a planar YV12 or IYUV texture with new pixel data.
153         /// See_also: $(LINK http://wiki.libsdl.org/SDL_UpdateYUVTexture)
154         /// Throws: $(D SDL2Exception) on error.
155         void updateYUVTexture(const(ubyte)* Yplane, int Ypitch, const(ubyte)* Uplane, int Upitch, const Uint8* Vplane, int Vpitch)
156         {
157             int err = SDL_UpdateYUVTexture(_handle, null, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch);
158             if (err != 0)
159                 _sdl2.throwSDL2Exception("SDL_UpdateYUVTexture");
160         }
161 
162         /// Update a part of a planar YV12 or IYUV texture with new pixel data.
163         /// See_also: $(LINK http://wiki.libsdl.org/SDL_UpdateYUVTexture)
164         /// Throws: $(D SDL2Exception) on error.
165         void updateYUVTexture(const(SDL_Rect)* rect, const(ubyte)* Yplane, int Ypitch, const(ubyte)* Uplane, int Upitch, const Uint8* Vplane, int Vpitch)
166         {
167             int err = SDL_UpdateYUVTexture(_handle, rect, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch);
168             if (err != 0)
169                 _sdl2.throwSDL2Exception("SDL_UpdateYUVTexture");
170         }
171 
172         /// Returns: SDL handle.
173         SDL_Texture* handle()
174         {
175             return _handle;
176         }
177 
178     }
179 
180     package
181     {
182         SDL_Texture* _handle;
183     }
184 
185     private
186     {
187         SDL2 _sdl2;
188         SDL2Renderer _renderer;
189     }
190 }
191