1 module gfm.sdl2.texture;
2 
3 import std..string;
4 
5 import bindbc.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, SDL_TextureAccess 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         static if(sdlSupport >= SDLSupport.sdl201)
153         {
154             /// Update a planar YV12 or IYUV texture with new pixel data.
155             /// See_also: $(LINK http://wiki.libsdl.org/SDL_UpdateYUVTexture)
156             /// Throws: $(D SDL2Exception) on error.
157             void updateYUVTexture(const(ubyte)* Yplane, int Ypitch, const(ubyte)* Uplane, int Upitch, const Uint8* Vplane, int Vpitch)
158             {
159                 int err = SDL_UpdateYUVTexture(_handle, null, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch);
160                 if (err != 0)
161                     _sdl2.throwSDL2Exception("SDL_UpdateYUVTexture");
162             }
163 
164             /// Update a part of a planar YV12 or IYUV texture with new pixel data.
165             /// See_also: $(LINK http://wiki.libsdl.org/SDL_UpdateYUVTexture)
166             /// Throws: $(D SDL2Exception) on error.
167             void updateYUVTexture(const(SDL_Rect)* rect, const(ubyte)* Yplane, int Ypitch, const(ubyte)* Uplane, int Upitch, const Uint8* Vplane, int Vpitch)
168             {
169                 int err = SDL_UpdateYUVTexture(_handle, rect, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch);
170                 if (err != 0)
171                     _sdl2.throwSDL2Exception("SDL_UpdateYUVTexture");
172             }
173         }
174 
175         /// Returns: SDL handle.
176         SDL_Texture* handle()
177         {
178             return _handle;
179         }
180 
181     }
182 
183     package
184     {
185         SDL_Texture* _handle;
186     }
187 
188     private
189     {
190         SDL2 _sdl2;
191         SDL2Renderer _renderer;
192     }
193 }
194