2a27db8708df2a78f46bf4ef4cc706feec0aab6c
[supertux.git] / lib / video / surface.h
1 //  $Id$
2 // 
3 //  SuperTux
4 //  Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
5 //
6 //  This program is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU General Public License
8 //  as published by the Free Software Foundation; either version 2
9 //  of the License, or (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 // 
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 //  02111-1307, USA.
20
21 #ifndef SUPERTUX_TEXTURE_H
22 #define SUPERTUX_TEXTURE_H
23
24 #include <string>
25 #include <list>
26
27 #ifndef NOOPENGL
28 #include "SDL_opengl.h"
29 #endif
30
31 #include "SDL.h"
32
33 #include "../math/vector.h"
34 #include "../video/screen.h"
35
36 namespace SuperTux
37   {
38
39   void apply_filter_to_surface(SDL_Surface *surface, int filter, int value);
40   SDL_Surface* sdl_surface_from_sdl_surface(SDL_Surface* sdl_surf, bool use_alpha);
41   SDL_Surface* sdl_surface_from_nothing();
42
43   class SurfaceImpl;
44   class SurfaceSDL;
45   class SurfaceOpenGL;
46   class DrawingContext;
47   
48   /// bitset for drawing effects
49   enum {
50     /** Don't apply anything */
51     NONE_EFFECT       = 0x0000,
52     /** Draw the Surface upside down */
53     VERTICAL_FLIP     = 0x0001,
54     /** Draw the Surface from left to down */
55     HORIZONTAL_FLIP   = 0x0002,
56     /** Draw the Surface with alpha equal to 128 */
57     SEMI_TRANSPARENT  = 0x0004
58   };
59
60   /// types of filters
61   enum {
62     HORIZONTAL_FLIP_FILTER,
63     MASK_FILTER,
64     NONE_FILTER
65   };
66
67   /** This class holds all the data necessary to construct a surface */
68   class SurfaceData
69     {
70     public:
71       enum ConstructorType { LOAD, LOAD_PART, SURFACE, GRADIENT };
72       ConstructorType type;
73       SDL_Surface* surface;
74       std::string file;
75
76       struct Filter { int type; Color color; };
77       std::vector<Filter> applied_filters;
78
79       bool use_alpha;
80       int x;
81       int y;
82       int w;
83       int h;
84       Color top_gradient;
85       Color bottom_gradient;
86
87       SurfaceData(SDL_Surface* surf, bool use_alpha_);
88       SurfaceData(const std::string& file_, bool use_alpha_);
89       SurfaceData(const std::string& file_, int x_, int y_, int w_, int h_, bool use_alpha_);
90       SurfaceData(Color top_gradient_, Color bottom_gradient_, int w_, int h_);
91       ~SurfaceData();
92
93       SurfaceSDL* create_SurfaceSDL();
94       SurfaceOpenGL* create_SurfaceOpenGL();
95       SurfaceImpl* create();
96     };
97
98
99   /// Surface
100   /** Container class that holds a surface, necessary so that we can
101       switch Surface implementations (OpenGL, SDL) on the fly */
102   class Surface
103     {
104     public:
105       SurfaceData data;
106       SurfaceImpl* impl;
107       int w;
108       int h;
109
110       typedef std::list<Surface*> Surfaces;
111       static Surfaces surfaces;
112     public:
113       static void reload_all();
114       static void debug_check();
115
116       Surface(SDL_Surface* surf, bool use_alpha);
117       Surface(const std::string& file, bool use_alpha);
118       Surface(const std::string& file, int x, int y, int w, int h, bool use_alpha);
119       Surface(Color top_gradient, Color bottom_gradient, int w_, int h_);
120       ~Surface();
121
122       /** Reload the surface, which is necesarry in case of a mode swich */
123       void reload();
124
125       void resize(int widht, int height);
126
127       void apply_filter(int filter, Color color = Color(0,0,0));
128     };
129
130   /** Surface implementation, all implementation have to inherit from
131       this class */
132   class SurfaceImpl
133     {
134     protected:
135       SDL_Surface* sdl_surface;
136
137     public:
138       int w;
139       int h;
140
141     public:
142       SurfaceImpl();
143       virtual ~SurfaceImpl();
144
145       /** Return 0 on success, -2 if surface needs to be reloaded */
146       virtual int draw(float x, float y, Uint8 alpha, Uint32 effect = NONE_EFFECT) = 0;
147       virtual int draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha, Uint32 effect = NONE_EFFECT) = 0;
148       virtual int draw_stretched(float x, float y, int w, int h, Uint8 alpha, Uint32 effect = NONE_EFFECT) = 0;
149
150
151       int resize(int w_, int h_);
152
153       SDL_Surface* get_sdl_surface() const; // @evil@ try to avoid this function
154
155       virtual void apply_filter(int filter, Color color = Color(0,0,0)) = 0;
156     };
157
158   class SurfaceSDL : public SurfaceImpl
159     {
160     public:
161       SurfaceSDL(SDL_Surface* surf, bool use_alpha);
162       SurfaceSDL(const std::string& file, bool use_alpha);
163       SurfaceSDL(const std::string& file, int x, int y, int w, int h, bool use_alpha);
164       SurfaceSDL(Color top_gradient, Color bottom_gradient, int w, int h);
165       virtual ~SurfaceSDL();
166
167       int draw(float x, float y, Uint8 alpha, Uint32 effect = NONE_EFFECT);
168       int draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha, Uint32 effect = NONE_EFFECT);
169       int draw_stretched(float x, float y, int w, int h, Uint8 alpha, Uint32 effect = NONE_EFFECT);
170
171       void apply_filter(int filter, Color color);
172     };
173
174 #ifndef NOOPENGL
175   class SurfaceOpenGL : public SurfaceImpl
176     {
177     public:
178       GLuint gl_texture;
179
180     public:
181       SurfaceOpenGL(SDL_Surface* surf, bool use_alpha);
182       SurfaceOpenGL(const std::string& file, bool use_alpha);
183       SurfaceOpenGL(const std::string& file, int x, int y, int w, int h, bool use_alpha);
184       SurfaceOpenGL(Color top_gradient, Color bottom_gradient, int w, int h);
185
186       virtual ~SurfaceOpenGL();
187
188       int draw(float x, float y, Uint8 alpha, Uint32 effect = NONE_EFFECT);
189       int draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha, Uint32 effect = NONE_EFFECT);
190       int draw_stretched(float x, float y, int w, int h, Uint8 alpha, Uint32 effect = NONE_EFFECT);
191
192       void apply_filter(int filter, Color color);
193
194     private:
195       void create_gl(SDL_Surface * surf, GLuint * tex);
196     };
197 #endif
198
199 } //namespace SuperTux
200
201 #endif /*SUPERTUX_TEXTURE_H*/
202
203 /* Local Variables: */
204 /* mode: c++ */
205 /* End: */