cleanups
[supertux.git] / src / texture.c
1 //
2 // C Implementation: texture
3 //
4 // Description: 
5 //
6 //
7 // Author: Tobias Glaesser <tobi.web@gmx.de>, (C) 2004
8 //
9 // Copyright: See COPYING file that comes with this distribution
10 //
11 //
12
13 #include <SDL/SDL.h>
14 #include <SDL/SDL_image.h>
15 #include "globals.h"
16 #include "screen.h"
17 #include "setup.h"
18 #include "texture.h"
19
20 void texture_setup(void)
21 {
22 #ifdef NOOPENGL
23 texture_load = texture_load_sdl;
24 texture_free = texture_free_sdl;
25 texture_draw = texture_draw_sdl;
26 texture_draw_bg = texture_draw_bg_sdl;
27 texture_draw_part = texture_draw_part_sdl;
28 #else
29 if(use_gl)
30 {
31 texture_load = texture_load_gl;
32 texture_free = texture_free_gl;
33 texture_draw = texture_draw_gl;
34 texture_draw_bg = texture_draw_bg_gl;
35 texture_draw_part = texture_draw_part_gl;
36 }
37 else
38 {
39 texture_load = texture_load_sdl;
40 texture_free = texture_free_sdl;
41 texture_draw = texture_draw_sdl;
42 texture_draw_bg = texture_draw_bg_sdl;
43 texture_draw_part = texture_draw_part_sdl;
44 }
45 #endif
46 }
47
48 #ifndef NOOPENGL
49 void texture_load_gl(texture_type* ptexture, char * file, int use_alpha)
50 {
51 texture_load_sdl(ptexture,file,use_alpha);
52 texture_create_gl(ptexture->sdl_surface,&ptexture->gl_texture);
53 }
54
55 void texture_draw_gl(texture_type* ptexture, float x, float y, int update)
56 {
57       glColor4ub(255, 255, 255,255);
58       glBlendFunc (GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
59       glEnable (GL_BLEND);
60       glBindTexture(GL_TEXTURE_RECTANGLE_NV, ptexture->gl_texture);
61
62       glBegin(GL_QUADS);
63       glTexCoord2f(0, 0);
64       glVertex2f(x, y);
65       glTexCoord2f((float)ptexture->w, 0);
66       glVertex2f((float)ptexture->w+x, y);
67       glTexCoord2f((float)ptexture->w, (float)ptexture->h);
68       glVertex2f((float)ptexture->w+x, (float)ptexture->h+y);
69       glTexCoord2f(0, (float)ptexture->h);
70       glVertex2f(x, (float)ptexture->h+y);
71       glEnd();
72 }
73
74 void texture_draw_bg_gl(texture_type* ptexture, int update)
75 {
76     //glColor3ub(255, 255, 255);
77
78     glEnable(GL_TEXTURE_RECTANGLE_NV);
79     glBindTexture(GL_TEXTURE_RECTANGLE_NV, ptexture->gl_texture);
80
81     glBegin(GL_QUADS);
82         glTexCoord2f(0, 0);    glVertex2f(0, 0);
83         glTexCoord2f((float)ptexture->w, 0);    glVertex2f(screen->w, 0);
84         glTexCoord2f((float)ptexture->w, (float)ptexture->h);    glVertex2f(screen->w, screen->h);
85         glTexCoord2f(0, (float)ptexture->h); glVertex2f(0, screen->h);
86     glEnd();
87 }
88
89 void texture_draw_part_gl(texture_type* ptexture, float x, float y, float w, float h, int update)
90 {
91       glColor3ub(255, 255, 255);
92
93       glEnable(GL_TEXTURE_RECTANGLE_NV);
94       glBindTexture(GL_TEXTURE_RECTANGLE_NV, ptexture->gl_texture);
95
96       glBegin(GL_QUADS);
97       glTexCoord2f(x, y);
98       glVertex2f(x, y);
99       glTexCoord2f(x+w, y);
100       glVertex2f(w+x, y);
101       glTexCoord2f(x+w, y+h);
102       glVertex2f(w+x, h+y);
103       glTexCoord2f(x, y+h);
104       glVertex2f(x, h+y);
105       glEnd();
106 }
107
108 void texture_create_gl(SDL_Surface * surf, GLint * tex)
109 {
110 SDL_Surface *conv;
111 conv = SDL_CreateRGBSurface(SDL_SWSURFACE , surf->w, surf->h, 32,
112 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
113             0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
114 #else
115             0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
116 #endif
117     SDL_BlitSurface(surf, 0, conv, 0);
118                      glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
119        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
120     
121   glGenTextures(1, &*tex);
122
123     glBindTexture(GL_TEXTURE_RECTANGLE_NV , *tex);
124              glEnable(GL_TEXTURE_RECTANGLE_NV);
125     glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
126     glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
127     glPixelStorei(GL_UNPACK_ROW_LENGTH, conv->pitch / conv->format->BytesPerPixel);
128     glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, 3, conv->w, conv->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, conv->pixels);
129     //glCopyTexSubImage2D(GL_TEXTURE_RECTANGLE_NV, 0, 0, 0, 0, 0, conv->w, conv->h);
130     glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
131     SDL_FreeSurface(conv);
132 }
133
134 void texture_free_gl(texture_type* ptexture)
135 {
136   SDL_FreeSurface(ptexture->sdl_surface);
137   glDeleteTextures(1, &ptexture->gl_texture);
138 }
139 #endif
140
141 void texture_load_sdl(texture_type* ptexture, char * file, int use_alpha)
142 {
143   SDL_Surface * temp;
144
145   temp = IMG_Load(file);
146
147   if (temp == NULL)
148     st_abort("Can't load", file);
149
150   ptexture->sdl_surface = SDL_DisplayFormatAlpha(temp);
151
152   if (ptexture->sdl_surface == NULL)
153     st_abort("Can't covert to display format", file);
154
155   if (use_alpha == IGNORE_ALPHA)
156     SDL_SetAlpha(ptexture->sdl_surface, 0, 0);
157
158   SDL_FreeSurface(temp);
159
160   ptexture->w = ptexture->sdl_surface->w;
161   ptexture->h = ptexture->sdl_surface->h;
162
163 }
164
165 void texture_from_sdl_surface(texture_type* ptexture, SDL_Surface* sdl_surf, int use_alpha)
166 {
167
168  /* SDL_Surface * temp;
169
170   temp = IMG_Load(file);
171
172   if (temp == NULL)
173     st_abort("Can't load", file);*/
174
175   ptexture->sdl_surface = SDL_DisplayFormatAlpha(sdl_surf);
176
177   if (ptexture->sdl_surface == NULL)
178     st_abort("Can't covert to display format", "SURFACE");
179
180   if (use_alpha == IGNORE_ALPHA)
181     SDL_SetAlpha(ptexture->sdl_surface, 0, 0);
182
183   ptexture->w = ptexture->sdl_surface->w;
184   ptexture->h = ptexture->sdl_surface->h;
185
186   #ifndef NOOPENGL
187   if(use_gl)
188     {
189       texture_create_gl(ptexture->sdl_surface,&ptexture->gl_texture);
190     }
191   #endif
192 }
193
194 void texture_draw_sdl(texture_type* ptexture, float x, float y, int update)
195 {
196       SDL_Rect dest;
197
198       dest.x = x;
199       dest.y = y;
200       dest.w = ptexture->w;
201       dest.h = ptexture->h;
202
203       SDL_BlitSurface(ptexture->sdl_surface, NULL, screen, &dest);
204
205       if (update == UPDATE)
206         SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h);
207 }
208
209
210 void texture_draw_bg_sdl(texture_type* ptexture, int update)
211 {
212   SDL_Rect dest;
213   
214   dest.x = 0;
215   dest.y = 0;
216   dest.w = screen->w;
217   dest.h = screen->h;
218   
219   SDL_BlitSurface(ptexture->sdl_surface, NULL, screen, &dest);
220   
221   if (update == UPDATE)
222     SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h);
223 }
224
225 void texture_draw_part_sdl(texture_type* ptexture, float x, float y, float w, float h, int update)
226 {
227       SDL_Rect src, dest;
228
229       src.x = x;
230       src.y = y;
231       src.w = w;
232       src.h = h;
233
234       dest.x = x;
235       dest.y = y;
236       dest.w = w;
237       dest.h = h;
238
239
240       SDL_BlitSurface(ptexture->sdl_surface, &src, screen, &dest);
241
242       if (update == UPDATE)
243         update_rect(screen, dest.x, dest.y, dest.w, dest.h);
244 }
245
246 void texture_free_sdl(texture_type* ptexture)
247 {
248   SDL_FreeSurface(ptexture->sdl_surface);
249 }
250