added jam build system, please try it out - the advantage would be that it already...
[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 #ifndef SUPERTUX_TEXTURE_H
21 #define SUPERTUX_TEXTURE_H
22
23 #include <string>
24 #include <list>
25
26 #ifndef NOOPENGL
27 #include <SDL_opengl.h>
28 #endif
29
30 #include "SDL.h"
31
32 #include "../math/vector.h"
33 #include "../video/screen.h"
34
35 namespace SuperTux
36   {
37
38   void apply_filter_to_surface(SDL_Surface *surface, int filter, int value);
39   SDL_Surface* sdl_surface_from_sdl_surface(SDL_Surface* sdl_surf, bool use_alpha);
40   SDL_Surface* sdl_surface_from_nothing();
41
42   class SurfaceImpl;
43   class SurfaceSDL;
44   class SurfaceOpenGL;
45   class DrawingContext;
46   
47   /// bitset for drawing effects
48   enum {
49     /** Don't apply anything */
50     NONE_EFFECT       = 0x0000,
51     /** Draw the Surface upside down */
52     VERTICAL_FLIP     = 0x0001,
53     /** Draw the Surface from left to down */
54     HORIZONTAL_FLIP   = 0x0002,
55     /** Draw the Surface with alpha equal to 128 */
56     SEMI_TRANSPARENT  = 0x0004
57   };
58
59   /// types of filters
60   enum {
61     HORIZONTAL_FLIP_FILTER,
62     MASK_FILTER,
63     NONE_FILTER
64   };
65
66   /** This class holds all the data necessary to construct a surface */
67   class SurfaceData
68     {
69     public:
70       enum ConstructorType { LOAD, LOAD_PART, SURFACE, GRADIENT };
71       ConstructorType type;
72       SDL_Surface* surface;
73       std::string file;
74
75       struct Filter { int type; Color color; };
76       std::vector<Filter> applied_filters;
77
78       bool use_alpha;
79       int x;
80       int y;
81       int w;
82       int h;
83       Color top_gradient;
84       Color bottom_gradient;
85
86       SurfaceData(SDL_Surface* surf, bool use_alpha_);
87       SurfaceData(const std::string& file_, bool use_alpha_);
88       SurfaceData(const std::string& file_, int x_, int y_, int w_, int h_, bool use_alpha_);
89       SurfaceData(Color top_gradient_, Color bottom_gradient_, int w_, int h_);
90       ~SurfaceData();
91
92       SurfaceSDL* create_SurfaceSDL();
93       SurfaceOpenGL* create_SurfaceOpenGL();
94       SurfaceImpl* create();
95     };
96
97
98   /// Surface
99   /** Container class that holds a surface, necessary so that we can
100       switch Surface implementations (OpenGL, SDL) on the fly */
101   class Surface
102     {
103     public:
104       SurfaceData data;
105       SurfaceImpl* impl;
106       int w;
107       int h;
108
109       typedef std::list<Surface*> Surfaces;
110       static Surfaces surfaces;
111     public:
112       static void reload_all();
113       static void debug_check();
114
115       Surface(SDL_Surface* surf, bool use_alpha);
116       Surface(const std::string& file, bool use_alpha);
117       Surface(const std::string& file, int x, int y, int w, int h, bool use_alpha);
118       Surface(Color top_gradient, Color bottom_gradient, int w_, int h_);
119       ~Surface();
120
121       /** Reload the surface, which is necesarry in case of a mode swich */
122       void reload();
123
124       void apply_filter(int filter, Color color = Color(0,0,0));
125     };
126
127   /** Surface implementation, all implementation have to inherit from
128       this class */
129   class SurfaceImpl
130     {
131     protected:
132       SDL_Surface* sdl_surface;
133
134     public:
135       int w;
136       int h;
137
138     public:
139       SurfaceImpl();
140       virtual ~SurfaceImpl();
141
142       /** Return 0 on success, -2 if surface needs to be reloaded */
143       virtual int draw(float x, float y, Uint8 alpha, Uint32 effect = NONE_EFFECT) = 0;
144       virtual int draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha, Uint32 effect = NONE_EFFECT) = 0;
145       virtual int draw_stretched(float x, float y, int w, int h, Uint8 alpha, Uint32 effect = NONE_EFFECT) = 0;
146
147
148       SDL_Surface* get_sdl_surface() const; // @evil@ try to avoid this function
149
150       virtual void apply_filter(int filter, Color color = Color(0,0,0)) = 0;
151     };
152
153   class SurfaceSDL : public SurfaceImpl
154     {
155     public:
156       SurfaceSDL(SDL_Surface* surf, bool use_alpha);
157       SurfaceSDL(const std::string& file, bool use_alpha);
158       SurfaceSDL(const std::string& file, int x, int y, int w, int h, bool use_alpha);
159       SurfaceSDL(Color top_gradient, Color bottom_gradient, int w, int h);
160       virtual ~SurfaceSDL();
161
162       int draw(float x, float y, Uint8 alpha, Uint32 effect = NONE_EFFECT);
163       int draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha, Uint32 effect = NONE_EFFECT);
164       int draw_stretched(float x, float y, int w, int h, Uint8 alpha, Uint32 effect = NONE_EFFECT);
165
166       void apply_filter(int filter, Color color);
167     };
168
169 #ifndef NOOPENGL
170   class SurfaceOpenGL : public SurfaceImpl
171     {
172     public:
173       GLuint gl_texture;
174
175     public:
176       SurfaceOpenGL(SDL_Surface* surf, bool use_alpha);
177       SurfaceOpenGL(const std::string& file, bool use_alpha);
178       SurfaceOpenGL(const std::string& file, int x, int y, int w, int h, bool use_alpha);
179       SurfaceOpenGL(Color top_gradient, Color bottom_gradient, int w, int h);
180
181       virtual ~SurfaceOpenGL();
182
183       int draw(float x, float y, Uint8 alpha, Uint32 effect = NONE_EFFECT);
184       int draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha, Uint32 effect = NONE_EFFECT);
185       int draw_stretched(float x, float y, int w, int h, Uint8 alpha, Uint32 effect = NONE_EFFECT);
186
187       void apply_filter(int filter, Color color);
188
189     private:
190       void create_gl(SDL_Surface * surf, GLuint * tex);
191     };
192 #endif
193
194 } //namespace SuperTux
195
196 #endif /*SUPERTUX_TEXTURE_H*/
197
198 /* Local Variables: */
199 /* mode: c++ */
200 /* End: */