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         ~this()
40         {
41             close();
42         }
43 
44         /// Releases the SDL resource.
45         void close() 
46         {
47             if (_handle !is null)
48             {
49                 SDL_DestroyTexture(_handle);
50                 _handle = null;
51             }
52         }
53 
54         /// See_also: $(LINK http://wiki.libsdl.org/SDL_SetTextureBlendMode)
55         /// Throws: $(D SDL2Exception) on error.
56         void setBlendMode(SDL_BlendMode blendMode)
57         {
58             if (SDL_SetTextureBlendMode(_handle, blendMode) != 0)
59                 _sdl2.throwSDL2Exception("SDL_SetTextureBlendMode");
60         }
61 
62         /// See_also: $(LINK http://wiki.libsdl.org/SDL_SetTextureColorMod)
63         /// Throws: $(D SDL2Exception) on error.
64         void setColorMod(int r, int g, int b)
65         {
66             if (SDL_SetTextureColorMod(_handle, cast(ubyte)r, cast(ubyte)g, cast(ubyte)b) != 0)
67                 _sdl2.throwSDL2Exception("SDL_SetTextureColorMod");
68         }
69 
70         /// See_also: $(LINK http://wiki.libsdl.org/SDL_SetTextureAlphaMod)
71         /// Throws: $(D SDL2Exception) on error.
72         void setAlphaMod(int a)
73         {
74 
75             // #Workaround SDL software renderer bug with alpha = 255
76             if (_renderer.info().isSoftware())
77             {
78                 if (a >= 255)
79                     a = 254;
80             }
81 
82             if (SDL_SetTextureAlphaMod(_handle, cast(ubyte)a) != 0)
83                 _sdl2.throwSDL2Exception("SDL_SetTextureAlphaMod");
84         }
85 
86         /// Returns: Texture format.
87         /// See_also: $(LINK http://wiki.libsdl.org/SDL_QueryTexture)
88         /// Throws: $(D SDL2Exception) on error.
89         uint format()
90         {
91             uint res;
92             int err = SDL_QueryTexture(_handle, &res, null, null, null);
93             if (err != 0)
94                 _sdl2.throwSDL2Exception("SDL_QueryTexture");
95 
96             return res;
97         }
98 
99         /// Returns: Texture access.
100         /// See_also: $(LINK http://wiki.libsdl.org/SDL_QueryTexture)
101         /// Throws: $(D SDL2Exception) on error.
102         int access()
103         {
104             int res;
105             int err = SDL_QueryTexture(_handle, null, &res, null, null);
106             if (err != 0)
107                 _sdl2.throwSDL2Exception("SDL_QueryTexture");
108 
109             return res;
110         }
111 
112         /// Returns: Width of texture.
113         /// See_also: $(LINK http://wiki.libsdl.org/SDL_QueryTexture)
114         /// Throws: $(D SDL2Exception) on error.
115         int width()
116         {
117             int res;
118             int err = SDL_QueryTexture(_handle, null, null, &res, null);
119             if (err != 0)
120                 _sdl2.throwSDL2Exception("SDL_QueryTexture");
121             return res;
122         }
123 
124         /// Returns: Height of texture.
125         /// See_also: $(LINK http://wiki.libsdl.org/SDL_QueryTexture)
126         /// Throws: $(D SDL2Exception) on error.
127         int height()
128         {
129             int res;
130             int err = SDL_QueryTexture(_handle, null, null, null, &res);
131             if (err != 0)
132                 _sdl2.throwSDL2Exception("SDL_QueryTexture");
133             return res;
134         }
135 
136         /// Updates the whole texture with new pixel data.
137         /// See_also: $(LINK http://wiki.libsdl.org/SDL_UpdateTexture)
138         /// Throws: $(D SDL2Exception) on error.
139         void updateTexture(const(void)* pixels, int pitch)
140         {
141             int err = SDL_UpdateTexture(_handle, null, pixels, pitch);
142             if (err != 0)
143                 _sdl2.throwSDL2Exception("SDL_UpdateTexture");
144         }
145 
146         /// Updates a part of a texture with new pixel data.
147         /// See_also: $(LINK http://wiki.libsdl.org/SDL_UpdateTexture)
148         /// Throws: $(D SDL2Exception) on error.
149         void updateTexture(const(SDL_Rect)* rect, const(void)* pixels, int pitch)
150         {
151             int err = SDL_UpdateTexture(_handle, rect, pixels, pitch);
152             if (err != 0)
153                 _sdl2.throwSDL2Exception("SDL_UpdateTexture");
154         }
155 
156         /// Update a planar YV12 or IYUV texture with new pixel data. 
157         /// See_also: $(LINK http://wiki.libsdl.org/SDL_UpdateYUVTexture)
158         /// Throws: $(D SDL2Exception) on error.
159         void updateYUVTexture(const(ubyte)* Yplane, int Ypitch, const(ubyte)* Uplane, int Upitch, const Uint8* Vplane, int Vpitch)
160         {
161             int err = SDL_UpdateYUVTexture(_handle, null, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch);
162             if (err != 0)
163                 _sdl2.throwSDL2Exception("SDL_UpdateYUVTexture");
164         }
165 
166         /// Update a part of a planar YV12 or IYUV texture with new pixel data.
167         /// See_also: $(LINK http://wiki.libsdl.org/SDL_UpdateYUVTexture)
168         /// Throws: $(D SDL2Exception) on error.
169         void updateYUVTexture(const(SDL_Rect)* rect, const(ubyte)* Yplane, int Ypitch, const(ubyte)* Uplane, int Upitch, const Uint8* Vplane, int Vpitch)
170         {
171             int err = SDL_UpdateYUVTexture(_handle, rect, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch);
172             if (err != 0)
173                 _sdl2.throwSDL2Exception("SDL_UpdateYUVTexture");
174         }
175 
176     }
177 
178     package
179     {
180         SDL_Texture* _handle;
181     }
182 
183     private
184     {
185         SDL2 _sdl2;
186         SDL2Renderer _renderer;
187     }
188 }
189