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