1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | #define SG_BUILD_LIBRARY |
16 | #include <siege/graphics/texture.h> |
17 | #include <siege/core/window.h> |
18 | |
19 | #include <stdlib.h> |
20 | #include <stdio.h> |
21 | #include <math.h> |
22 | |
23 | #include "../internal/gl.h" |
24 | |
25 | static SGubyte texinfoGL(GLuint* gliformat, GLuint* glformat, GLuint* gltype, SGenum bpp) |
26 | { |
27 | GLuint tmp; |
28 | if(!gliformat) gliformat = &tmp; |
| |
29 | if(!glformat) glformat = &tmp; |
| |
30 | if(!gltype) gltype = &tmp; |
| |
31 | switch(bpp) |
| 6 | | Control jumps to the 'default' case at line 58 | |
|
32 | { |
33 | case 8: |
34 | *gliformat = GL_R3_G3_B20x2A10; |
35 | *glformat = GL_RGB0x1907; |
36 | *gltype = GL_UNSIGNED_BYTE_3_3_20x8032; |
37 | return 1; |
38 | case 15: |
39 | *gliformat = GL_RGB50x8050; |
40 | *glformat = GL_RGB0x1907; |
41 | *gltype = GL_UNSIGNED_SHORT_5_5_5_10x8034; |
42 | return 2; |
43 | case 16: |
44 | *gliformat = GL_RGB50x8050; |
45 | *glformat = GL_RGB0x1907; |
46 | *gltype = GL_UNSIGNED_SHORT_5_6_50x8363; |
47 | return 2; |
48 | case 24: |
49 | *gliformat = GL_RGB80x8051; |
50 | *glformat = GL_RGB0x1907; |
51 | *gltype = GL_UNSIGNED_BYTE0x1401; |
52 | return 3; |
53 | case 32: |
54 | *gliformat = GL_RGBA80x8058; |
55 | *glformat = GL_RGBA0x1908; |
56 | *gltype = GL_UNSIGNED_BYTE0x1401; |
57 | return 4; |
58 | default: |
59 | SG_ASSERT(bpp, "Invalid BPP passed to texture")((bpp) ? (void)0 : _assert("bpp", "src/siege/graphics/texture.c" , 59)); |
| 7 | | Within the expansion of the macro 'SG_ASSERT':
| |
a | Assuming 'bpp' is not equal to 0 |
|
60 | return 0; |
61 | } |
62 | } |
63 | static GLenum wrapSGtoGL(SGenum wrap) |
64 | { |
65 | |
66 | switch(wrap) |
67 | { |
68 | case SG_WRAP_CLAMP0x01: return GL_CLAMP0x2900; |
69 | case SG_WRAP_CLAMP_TO_EDGE0x02: return GL_CLAMP_TO_EDGE0x812F; |
70 | case SG_WRAP_MIRRORED_REPEAT0x03: return GL_MIRRORED_REPEAT0x8370; |
71 | case SG_WRAP_REPEAT0x04: return GL_REPEAT0x2901; |
72 | case SG_WRAP_CURRENT0x00: |
73 | default: |
74 | return 0; |
75 | } |
76 | } |
77 | static GLenum interpSGtoGL(SGenum interp) |
78 | { |
79 | |
80 | switch(interp) |
81 | { |
82 | case SG_INTERP_NEAREST0x01: return GL_NEAREST0x2600; |
83 | case SG_INTERP_LINEAR0x02: return GL_LINEAR0x2601; |
84 | case SG_INTERP_CURRENT0x00: |
85 | default: |
86 | return 0; |
87 | } |
88 | } |
89 | |
90 | SGTexture* SG_CALL__cdecl sgTextureCreateBitmap(SGBitmap* bmp, SGbool delbmp) |
91 | { |
92 | size_t width; |
93 | size_t height; |
94 | SGenum bpp; |
95 | void* data; |
96 | |
97 | sgBitmapGetData(bmp, &width, &height, &bpp, &data); |
98 | |
99 | SGTexture* texture = sgTextureCreateData(width, height, bpp, data); |
100 | if(delbmp) |
101 | sgBitmapDestroy(bmp); |
102 | return texture; |
103 | } |
104 | SGTexture* SG_CALL__cdecl sgTextureCreateStream(SGStream* stream, SGbool delstream) |
105 | { |
106 | SGBitmap* bmp = sgBitmapCreateStream(stream, delstream); |
107 | if(!bmp) return NULL((void*)0); |
108 | return sgTextureCreateBitmap(bmp, SG_TRUE1); |
109 | } |
110 | SGTexture* SG_CALL__cdecl sgTextureCreateFile(const char* fname) |
111 | { |
112 | SGStream* stream = sgStreamCreateFile(fname, "r"); |
113 | if(!stream) |
114 | { |
115 | fprintf(stderr(&_iob[2]), "Could not load image %s\n", fname); |
116 | return NULL((void*)0); |
117 | } |
118 | return sgTextureCreateStream(stream, SG_TRUE1); |
119 | } |
120 | SGTexture* SG_CALL__cdecl sgTextureCreateData(SGuint width, SGuint height, SGenum bpp, void* data) |
121 | { |
122 | SGTexture* texture = malloc(sizeof(SGTexture)); |
123 | if(!texture) return NULL((void*)0); |
124 | |
125 | texture->handle = malloc(sizeof(GLuint)); |
126 | |
127 | glGenTextures(1, texture->handle); |
128 | glBindTexture(GL_TEXTURE_2D0x0DE1, GLTEX(texture)(*(GLuint*)(texture)->handle)); |
129 | |
130 | glTexEnvi(GL_TEXTURE_ENV0x2300, GL_TEXTURE_ENV_MODE0x2200, GL_MODULATE0x2100); |
131 | |
132 | glTexParameteri(GL_TEXTURE_2D0x0DE1, GL_TEXTURE_MIN_FILTER0x2801, GL_LINEAR0x2601); |
133 | glTexParameteri(GL_TEXTURE_2D0x0DE1, GL_TEXTURE_MAG_FILTER0x2800, GL_LINEAR0x2601); |
134 | |
135 | sgTextureSetData(texture, width, height, bpp, data); |
136 | |
137 | return texture; |
138 | } |
139 | SGTexture* SG_CALL__cdecl sgTextureCreate(SGuint width, SGuint height, SGenum bpp) |
140 | { |
141 | return sgTextureCreateData(width, height, bpp, NULL((void*)0)); |
142 | } |
143 | void SG_CALL__cdecl sgTextureDestroy(SGTexture* texture) |
144 | { |
145 | if(!texture) return; |
146 | |
147 | glDeleteTextures(1, texture->handle); |
148 | free(texture->handle); |
149 | free(texture); |
150 | } |
151 | |
152 | void SG_CALL__cdecl sgTextureSetData(SGTexture* texture, size_t width, size_t height, SGenum bpp, void* data) |
153 | { |
154 | texture->width = width; |
155 | texture->height = height; |
156 | texture->bpp = bpp; |
157 | |
158 | glBindTexture(GL_TEXTURE_2D0x0DE1, GLTEX(texture)(*(GLuint*)(texture)->handle)); |
159 | |
160 | GLuint gliformat, glformat, gltype; |
161 | SGubyte bypp = texinfoGL(&gliformat, &glformat, &gltype, bpp); |
162 | |
163 | glTexImage2D(GL_TEXTURE_2D0x0DE1, 0, gliformat, width, height, 0, glformat, gltype, NULL((void*)0)); |
164 | |
165 | |
166 | |
167 | |
168 | size_t i; |
169 | if(data) |
170 | for(i = 0; i < height; i++) |
171 | glTexSubImage2D(GL_TEXTURE_2D0x0DE1, 0, 0, texture->height - i - 1, width, 1, glformat, gltype, ((char*)data) + (i * width) * bypp); |
172 | } |
173 | void SG_CALL__cdecl sgTextureSetSubData(SGTexture* texture, size_t x, size_t y, size_t width, size_t height, SGenum bpp, void* data) |
174 | { |
175 | glBindTexture(GL_TEXTURE_2D0x0DE1, GLTEX(texture)(*(GLuint*)(texture)->handle)); |
176 | |
177 | GLuint glformat, gltype; |
| 1 | 'glformat' declared without an initial value | |
|
178 | SGubyte bypp = texinfoGL(NULL((void*)0), &glformat, &gltype, bpp); |
| |
| 8 | | Returning from 'texinfoGL' | |
|
179 | |
180 | size_t i; |
181 | if(data) |
| 9 | | Assuming 'data' is non-null | |
|
| |
182 | for(i = 0; i < height; i++) |
| 11 | | Assuming 'i' is < 'height' | |
|
| 12 | | Loop condition is true. Entering loop body | |
|
183 | glTexSubImage2D(GL_TEXTURE_2D0x0DE1, 0, x, texture->height - y - i - 1, width, 1, glformat, gltype, ((char*)data) + (i * width) * bypp); |
| 13 | | Function call argument is an uninitialized value |
|
184 | } |
185 | void* SG_CALL__cdecl sgTextureGetData(SGTexture* texture) |
186 | { |
187 | GLuint glformat, gltype; |
188 | GLubyte bypp = texinfoGL(NULL((void*)0), &glformat, &gltype, texture->bpp); |
189 | void* data = malloc(texture->width * texture->height * bypp); |
190 | |
191 | glBindTexture(GL_TEXTURE_2D0x0DE1, GLTEX(texture)(*(GLuint*)(texture)->handle)); |
192 | glGetTexImage(GL_TEXTURE_2D0x0DE1, 0, glformat, gltype, data); |
193 | |
194 | return data; |
195 | } |
196 | void SG_CALL__cdecl sgTextureFreeData(void* data) |
197 | { |
198 | if(data) |
199 | free(data); |
200 | } |
201 | |
202 | void SG_CALL__cdecl sgTextureDrawRads3f2f2f1f(SGTexture* texture, float x, float y, float z, float xscale, float yscale, float xoffset, float yoffset, float angle) |
203 | { |
204 | glPushMatrix(); |
205 | glTranslatef(x, y, 0.0); |
206 | glRotatef(angle * 180.0 / SG_PI3.14159265358979323846, 0.0, 0.0, 1.0); |
207 | glScalef(xscale, yscale, 1.0); |
208 | glTranslatef(-x - xoffset, -y - yoffset, 0.0); |
209 | |
210 | glEnableClientState(GL_VERTEX_ARRAY0x8074); |
211 | glEnableClientState(GL_TEXTURE_COORD_ARRAY0x8078); |
212 | |
213 | float vertices[4*3] = { |
214 | x , y , z, |
215 | x + texture->width, y , z, |
216 | x + texture->width, y + texture->height, z, |
217 | x , y + texture->height, z |
218 | }; |
219 | float texcoords[4*2] = { |
220 | 0.0, 1.0, |
221 | 1.0, 1.0, |
222 | 1.0, 0.0, |
223 | 0.0, 0.0 |
224 | }; |
225 | |
226 | glVertexPointer(3, GL_FLOAT0x1406, 0, vertices); |
227 | glTexCoordPointer(2, GL_FLOAT0x1406, 0, texcoords); |
228 | |
229 | glEnable(GL_TEXTURE_2D0x0DE1); |
230 | glBindTexture(GL_TEXTURE_2D0x0DE1, GLTEX(texture)(*(GLuint*)(texture)->handle)); |
231 | |
232 | glDrawArrays(GL_QUADS0x0007, 0, 4); |
233 | |
234 | glDisable(GL_TEXTURE_2D0x0DE1); |
235 | |
236 | glDisableClientState(GL_TEXTURE_COORD_ARRAY0x8078); |
237 | glDisableClientState(GL_VERTEX_ARRAY0x8074); |
238 | |
239 | glPopMatrix(); |
240 | } |
241 | void SG_CALL__cdecl sgTextureDrawDegs3f2f2f1f(SGTexture* texture, float x, float y, float z, float xscale, float yscale, float xoffset, float yoffset, float angle) |
242 | { |
243 | sgTextureDrawRads3f2f2f1f(texture, x, y, z, xscale, yscale, xoffset, yoffset, angle * SG_PI3.14159265358979323846 / 180.0); |
244 | } |
245 | void SG_CALL__cdecl sgTextureDrawRads2f2f2f1f(SGTexture* texture, float x, float y, float xscale, float yscale, float xoffset, float yoffset, float angle) |
246 | { |
247 | sgTextureDrawRads3f2f2f1f(texture, x, y, 0.0, xscale, yscale, xoffset, yoffset, angle); |
248 | } |
249 | void SG_CALL__cdecl sgTextureDrawDegs2f2f2f1f(SGTexture* texture, float x, float y, float xscale, float yscale, float xoffset, float yoffset, float angle) |
250 | { |
251 | sgTextureDrawDegs3f2f2f1f(texture, x, y, 0.0, xscale, yscale, xoffset, yoffset, angle); |
252 | } |
253 | void SG_CALL__cdecl sgTextureDrawRads3f2f1f(SGTexture* texture, float x, float y, float z, float xscale, float yscale, float angle) |
254 | { |
255 | sgTextureDrawRads3f2f2f1f(texture, x, y, z, xscale, yscale, 0.0, 0.0, angle); |
256 | } |
257 | void SG_CALL__cdecl sgTextureDrawDegs3f2f1f(SGTexture* texture, float x, float y, float z, float xscale, float yscale, float angle) |
258 | { |
259 | sgTextureDrawDegs3f2f2f1f(texture, x, y, z, xscale, yscale, 0.0, 0.0, angle); |
260 | } |
261 | void SG_CALL__cdecl sgTextureDrawRads2f2f1f(SGTexture* texture, float x, float y, float xscale, float yscale, float angle) |
262 | { |
263 | sgTextureDrawRads3f2f2f1f(texture, x, y, 0.0, xscale, yscale, 0.0, 0.0, angle); |
264 | } |
265 | void SG_CALL__cdecl sgTextureDrawDegs2f2f1f(SGTexture* texture, float x, float y, float xscale, float yscale, float angle) |
266 | { |
267 | sgTextureDrawDegs3f2f2f1f(texture, x, y, 0.0, xscale, yscale, 0.0, 0.0, angle); |
268 | } |
269 | void SG_CALL__cdecl sgTextureDrawRads3f1f(SGTexture* texture, float x, float y, float z, float angle) |
270 | { |
271 | sgTextureDrawRads3f2f2f1f(texture, x, y, z, 1.0, 1.0, 0.0, 0.0, angle); |
272 | } |
273 | void SG_CALL__cdecl sgTextureDrawDegs3f1f(SGTexture* texture, float x, float y, float z, float angle) |
274 | { |
275 | sgTextureDrawDegs3f2f2f1f(texture, x, y, z, 1.0, 1.0, 0.0, 0.0, angle); |
276 | } |
277 | void SG_CALL__cdecl sgTextureDrawRads2f1f(SGTexture* texture, float x, float y, float angle) |
278 | { |
279 | sgTextureDrawRads3f2f2f1f(texture, x, y, 0.0, 1.0, 1.0, 0.0, 0.0, angle); |
280 | } |
281 | void SG_CALL__cdecl sgTextureDrawDegs2f1f(SGTexture* texture, float x, float y, float angle) |
282 | { |
283 | sgTextureDrawDegs3f2f2f1f(texture, x, y, 0.0, 1.0, 1.0, 0.0, 0.0, angle); |
284 | } |
285 | void SG_CALL__cdecl sgTextureDraw3f2f2f(SGTexture* texture, float x, float y, float z, float xscale, float yscale, float xoffset, float yoffset) |
286 | { |
287 | sgTextureDrawRads3f2f2f1f(texture, x, y, z, xscale, yscale, xoffset, yoffset, 0.0); |
288 | } |
289 | void SG_CALL__cdecl sgTextureDraw2f2f2f(SGTexture* texture, float x, float y, float xscale, float yscale, float xoffset, float yoffset) |
290 | { |
291 | sgTextureDrawRads3f2f2f1f(texture, x, y, 0.0, xscale, yscale, xoffset, yoffset, 0.0); |
292 | } |
293 | void SG_CALL__cdecl sgTextureDraw3f2f(SGTexture* texture, float x, float y, float z, float xscale, float yscale) |
294 | { |
295 | sgTextureDrawRads3f2f2f1f(texture, x, y, z, xscale, yscale, 0.0, 0.0, 0.0); |
296 | } |
297 | void SG_CALL__cdecl sgTextureDraw2f2f(SGTexture* texture, float x, float y, float xscale, float yscale) |
298 | { |
299 | sgTextureDrawRads3f2f2f1f(texture, x, y, 0.0, xscale, yscale, 0.0, 0.0, 0.0); |
300 | } |
301 | void SG_CALL__cdecl sgTextureDraw3f(SGTexture* texture, float x, float y, float z) |
302 | { |
303 | sgTextureDrawRads3f2f2f1f(texture, x, y, z, 1.0, 1.0, 0.0, 0.0, 0.0); |
304 | } |
305 | void SG_CALL__cdecl sgTextureDraw2f(SGTexture* texture, float x, float y) |
306 | { |
307 | sgTextureDrawRads3f2f2f1f(texture, x, y, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0); |
308 | } |
309 | void SG_CALL__cdecl sgTextureDraw(SGTexture* texture) |
310 | { |
311 | sgTextureDrawRads3f2f2f1f(texture, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f); |
312 | } |
313 | |
314 | void SG_CALL__cdecl sgTextureSetWrap(SGTexture* texture, SGenum swrap, SGenum twrap) |
315 | { |
316 | glBindTexture(GL_TEXTURE_2D0x0DE1, GLTEX(texture)(*(GLuint*)(texture)->handle)); |
317 | |
318 | GLenum glwrap; |
319 | |
320 | glwrap = wrapSGtoGL(swrap); |
321 | if(glwrap) |
322 | glTexParameteri(GL_TEXTURE_2D0x0DE1, GL_TEXTURE_WRAP_S0x2802, glwrap); |
323 | |
324 | glwrap = wrapSGtoGL(twrap); |
325 | if(glwrap) |
326 | glTexParameteri(GL_TEXTURE_2D0x0DE1, GL_TEXTURE_WRAP_T0x2803, glwrap); |
327 | } |
328 | void SG_CALL__cdecl sgTextureSetInterpolation(SGTexture* texture, SGenum interp) |
329 | { |
330 | glBindTexture(GL_TEXTURE_2D0x0DE1, GLTEX(texture)(*(GLuint*)(texture)->handle)); |
331 | |
332 | GLenum glinterp = interpSGtoGL(interp); |
333 | if(glinterp) |
334 | { |
335 | glTexParameteri(GL_TEXTURE_2D0x0DE1, GL_TEXTURE_MIN_FILTER0x2801, glinterp); |
336 | glTexParameteri(GL_TEXTURE_2D0x0DE1, GL_TEXTURE_MAG_FILTER0x2800, glinterp); |
337 | } |
338 | } |
339 | |
340 | void SG_CALL__cdecl sgTextureGetSize(SGTexture* texture, SGuint* width, SGuint* height) |
341 | { |
342 | if(width) *width = texture->width; |
343 | if(height) *height = texture->height; |
344 | } |
345 | SGuint SG_CALL__cdecl sgTextureGetWidth(SGTexture* texture) |
346 | { |
347 | return texture->width; |
348 | } |
349 | SGuint SG_CALL__cdecl sgTextureGetHeight(SGTexture* texture) |
350 | { |
351 | return texture->height; |
352 | } |
353 | SGenum SG_CALL__cdecl sgTextureGetBPP(SGTexture* texture) |
354 | { |
355 | return texture->bpp; |
356 | } |