1 /**
2  * Texture
3  */
4 module d2d.sdl2.Texture;
5 
6 import d2d.sdl2;
7 
8 /**
9  * Textures are a rectangular collection of pixels
10  * Textures are fast and can be drawn using a renderer
11  * Textures can be created from a more easily edited surface
12  * Textures are handled in hardware as opposed to surfaces which are handled in software
13  * When used repeatedly and stored, textures should be preferred, but surfaces should be used when flexibility is desired
14  */
15 class Texture {
16 
17     private SDL_Texture* texture;
18 
19     /**
20      * Returns the raw SDL data of this object
21      */
22     @property SDL_Texture* handle() {
23         return this.texture;
24     }
25 
26     /**
27      * Gets the texture's dimensions as a point with the width being the x coordinate and the height being the y coordinate
28      */
29     @property iVector dimensions() {
30         iVector dim = new iVector(0, 0);
31         SDL_QueryTexture(this.texture, null, null, &dim.x, &dim.y);
32         return dim;
33     }
34 
35     /**
36      * Gets the texture's pixel format
37      * The pixel format is the format in which information about the pixels is stored (e.g. RGBA)
38      */
39     @property uint format() {
40         uint format;
41         SDL_QueryTexture(this.texture, &format, null, null, null);
42         return format;
43     }
44 
45     /**
46      * Gets the texture's access value
47      * Acces value determines how the texture can be accessed or modified 
48      * Potential values are: 
49      * SDL_TEXTUREACCESS_STATIC: texture changes rarely, and is not lockable
50      * SDL_TEXTUREACCESS_STREAMING: texture changes frequently, and is lockable
51      * SDL_TEXTUREACCESS_TARGET: texturecan be used as a render target
52      */
53     @property int access() {
54         int access;
55         SDL_QueryTexture(this.texture, null, &access, null, null);
56         return access;
57     }
58 
59     /** 
60      * Sets the texture's alpha value, or transparency, if possible
61      * Alpha varies from 0 to 255
62      */
63     @property void alphaMod(ubyte alphaMultiplier) {
64         ensureSafe(SDL_SetTextureAlphaMod(this.texture, alphaMultiplier));
65     }
66 
67     /**
68      * Gets the texture's alpha value, or transparency, if possible
69      * Alpha varies from 0 to 255
70      */
71     @property ubyte alphaMod() {
72         ubyte alphaMultiplier;
73         ensureSafe(SDL_GetTextureAlphaMod(this.texture, &alphaMultiplier));
74         return alphaMultiplier;
75     }
76 
77     /**
78      * Sets the texture's blend mode
79      * Modes include:
80      * SDL_BLENDMODE_NONE: no blending
81      * SDL_BLENDMODE_BLEND: alpha blending
82      * SDL_BLENDMODE_ADD: additive blending
83      * SDL_BLENDMODE_MOD: color modulate
84      */
85     @property void blendMode(SDL_BlendMode blend) {
86         ensureSafe(SDL_SetTextureBlendMode(this.texture, blend));
87     }
88 
89     /**
90      * Gets the texture's blend mode
91      * Modes include:
92      * SDL_BLENDMODE_NONE: no blending
93      * SDL_BLENDMODE_BLEND: alpha blending
94      * SDL_BLENDMODE_ADD: additive blending
95      * SDL_BLENDMODE_MOD: color modulate
96      */
97     @property SDL_BlendMode* blendMode() {
98         SDL_BlendMode* blend;
99         ensureSafe(SDL_GetTextureBlendMode(this.texture, blend));
100         return blend;
101     }
102 
103     /**
104      * Sets the color modifier for the surface
105      * Color modification works by multiplying the colorMultiplier / 255 into the surface pixels
106      */
107     @property void colorMod(Color colorMultiplier) {
108         ensureSafe(SDL_SetTextureColorMod(this.texture, colorMultiplier.r,
109                 colorMultiplier.g, colorMultiplier.b));
110     }
111 
112     /**
113      * Gets the color modifier for the surface
114      * Color modification works by multiplying the colorMultiplier / 255 into the surface pixels
115      */
116     @property Color colorMod() {
117         Color colorMultiplier;
118         ensureSafe(SDL_GetTextureColorMod(this.texture, &colorMultiplier.r,
119                 &colorMultiplier.g, &colorMultiplier.b));
120         return colorMultiplier;
121     }
122 
123     /**
124      * Creates a texture given explicit parameters that are required by SDL CreateTexture
125      * Allows for more control over how the texture works
126      */
127     this(Renderer renderer, uint format, SDL_TextureAccess access, int width, int height) {
128         this.texture = ensureSafe(SDL_CreateTexture(renderer.handle, format,
129                 access, width, height));
130     }
131 
132     /**
133      * Constructs a new texture from a surface
134      */
135     this(Surface surface, Renderer renderer) {
136         this.texture = ensureSafe(SDL_CreateTextureFromSurface(renderer.handle, surface.handle));
137     }
138 
139     /**
140      * Creates a texture from an already existing SDL_Texture
141      */
142     this(SDL_Texture* alreadyExisting) {
143         this.texture = alreadyExisting;
144     }
145 
146     /**
147      * Ensures that SDL can properly dispose of the texture
148      */
149     ~this() {
150         SDL_DestroyTexture(this.texture);
151     }
152 
153     /**
154      * Locks a texture from editing
155      */
156     void lock(void** pixels, int* pitch, iRectangle location = null) {
157         ensureSafe(SDL_LockTexture(this.texture, (location is null) ? null
158                 : location.handle, pixels, pitch));
159     }
160 
161     /**
162      * Unlocks a texture to edit
163      */
164     void unlock() {
165         SDL_UnlockTexture(this.texture);
166     }
167 
168     /**
169      * Updates a texture with new pixel data
170      */
171     void update(void* pixels, int pitch, iRectangle location = null) {
172         ensureSafe(SDL_UpdateTexture(this.texture, (location is null) ? null
173                 : location.handle, pixels, pitch));
174     }
175 
176 }