1 /*(LGPL)
2 ------------------------------------------------------------
3 	glSDL 0.6 - SDL 2D API on top of OpenGL
4 ------------------------------------------------------------
5  * (c) David Olofson, 2001-2003
6  * This code is released under the terms of the GNU LGPL.
7  */
8 
9 #ifndef	_GLSDL_H_
10 #define	_GLSDL_H_
11 
12 /*
13  * If you don't use GNU autotools or similar, uncomment this to
14  * compile with OpenGL enabled:
15 #define HAVE_OPENGL
16  */
17 
18 /* We're still using SDL datatypes here - we just add some stuff. */
19 #include <SDL/SDL.h>
20 #include <SDL/SDL_image.h>
21 
22 #ifndef HAVE_OPENGL
23 
24 /* Fakes to make glSDL code compile with SDL. */
25 #define SDL_GLSDL		0
26 #define	LOGIC_W(s)		( (s)->w )
27 #define	LOGIC_H(s)		( (s)->h )
28 #define	GLSDL_FIX_SURFACE(s)
29 
30 #else	/* HAVE_OPENGL */
31 
32 #include "begin_code.h"
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
37 #if (SDL_MAJOR_VERSION <= 1) && (SDL_MINOR_VERSION <= 2) &&	\
38 		(SDL_PATCHLEVEL < 5)
39 #warning glSDL: Using SDL version 1.2.5 or later is strongly recommended!
40 #endif
41 
42 /*----------------------------------------------------------
43 	SDL style API
44 ----------------------------------------------------------*/
45 
46 typedef enum glSDL_TileModes
47 {
48 	GLSDL_TM_SINGLE,
49 	GLSDL_TM_HORIZONTAL,
50 	GLSDL_TM_VERTICAL,
51 	GLSDL_TM_HUGE
52 } glSDL_TileModes;
53 
54 
55 typedef struct glSDL_TexInfo
56 {
57 	/* Size of surface in logic screen pixels */
58 	int		lw, lh;
59 
60 	int		textures;
61 	int		*texture;
62 	int		texsize;	/* width/height of OpenGL texture */
63 	glSDL_TileModes	tilemode;
64 	int		tilew, tileh;	/* At least one must equal texsize! */
65 	int		tilespertex;
66 	SDL_Rect	virt;		/* Total size of assembled surface */
67 
68 	/* Area of surface to download when/after unlocking */
69 	SDL_Rect	invalid_area;
70 } glSDL_TexInfo;
71 
72 #define	GLSDL_FIX_SURFACE(s)	(s)->unused1 = 0;
73 #define	IS_GLSDL_SURFACE(s)	((s) && glSDL_GetTexInfo(s))
74 
75 #define	LOGIC_W(s)	( IS_GLSDL_SURFACE(s) ? TEXINFO(s)->lw : (s)->w )
76 #define	LOGIC_H(s)	( IS_GLSDL_SURFACE(s) ? TEXINFO(s)->lh : (s)->h )
77 
78 #define SDL_GLSDL	0x00100000	/* Create an OpenGL 2D rendering context */
79 
80 
81 /*
82  * Wraps SDL_SetVideoMode(), and adds support for the SDL_GLSDL flag.
83  *
84  * If 'flags' contains SDL_GLSDL, glSDL_SetVideoMode() sets up a "pure"
85  * OpenGL rendering context for use with the glSDL_ calls.
86  *
87  * SDL can be closed as usual (using SDL_ calls), but you should call
88  * glSDL_Quit() (kludge) to allow glSDL to clean up it's internal stuff.
89  */
90 SDL_Surface *glSDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);
91 void glSDL_Quit(void);
92 
93 void glSDL_QuitSubSystem(Uint32 flags);
94 
95 /* Replaces SDL_Quit() entirely, when using the override defines */
96 void _glSDL_FullQuit(void);
97 
98 SDL_Surface *glSDL_GetVideoSurface(void);
99 
100 void glSDL_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects);
101 void glSDL_UpdateRect(SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h);
102 
103 /*
104  * Works like SDL_Flip(), but may also perform enqueued blits.
105  * (That is, it's possible that the implementation renders
106  * *nothing* until glSDL_Flip() is called.)
107  */
108 int glSDL_Flip(SDL_Surface *screen);
109 
110 void glSDL_FreeSurface(SDL_Surface *surface);
111 
112 int glSDL_LockSurface(SDL_Surface *surface);
113 void glSDL_UnlockSurface(SDL_Surface *surface);
114 
115 /*
116  * Like the respective SDL functions, although they ignore
117  * SDL_RLEACCEL, as it makes no sense in this context.
118  */
119 int glSDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key);
120 int glSDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha);
121 
122 /*
123  * Sets up clipping for the screen, or a SDL_Surface.
124  *
125  * Note that this function takes both SDL_Surfaces and
126  * glSDL_Surfaces.
127  */
128 SDL_bool glSDL_SetClipRect(SDL_Surface *surface, SDL_Rect *rect);
129 
130 int glSDL_BlitSurface(SDL_Surface *src, SDL_Rect *srcrect,
131 			 SDL_Surface *dst, SDL_Rect *dstrect);
132 
133 int glSDL_FillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color);
134 
135 /*
136  * Convert the given surface into a SDL_Surface (if it isn't
137  * one already), and makes sure that the underlying SDL_Surface
138  * is of a pixel format suitable for fast texture downloading.
139  *
140  * Note that you *only* have to use this function if you want
141  * fast pixel access to surfaces (ie "procedural textures").
142  * Any surfaces that aren't converted will be downloaded
143  * automatically upon the first call to glSDL_BlitSurface(),
144  * but if conversion is required, it will be required for
145  * every glSDL_UnlockSurface() call.
146  *
147  * IMPORTANT:
148  *	You *can* pass an SDL_Surface directly to this function,
149  *	and it will try to deal with it nicely. However, this
150  *	requires that a temporary SDL_Surface is created, and
151  *	this surface is cached only until the texture memory is
152  *	needed for new surfaces.
153  */
154 SDL_Surface *glSDL_DisplayFormat(SDL_Surface *surface);
155 SDL_Surface *glSDL_DisplayFormatAlpha(SDL_Surface *surface);
156 
157 SDL_Surface *glSDL_ConvertSurface
158 			(SDL_Surface *src, SDL_PixelFormat *fmt, Uint32 flags);
159 SDL_Surface *glSDL_CreateRGBSurface
160 			(Uint32 flags, int width, int height, int depth,
161 			Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
162 SDL_Surface *glSDL_CreateRGBSurfaceFrom(void *pixels,
163 			int width, int height, int depth, int pitch,
164 			Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
165 SDL_Surface *glSDL_LoadBMP(const char *file);
166 int glSDL_SaveBMP(SDL_Surface *surface, const char *file);
167 
168 
169 
170 /*----------------------------------------------------------
171 	glSDL specific API extensions
172 ----------------------------------------------------------*/
173 
174 /*
175  * Invalidate part of a texture.
176  *
177  * This function can be used either between calls to
178  * glSDL_LockSurface() and glSDL_UnlockSurface(), or before
179  * calling glSDL_DownloadSurface().
180  *
181  * In either case, it causes only the specified area to be
182  * downloaded when unlocking the surface, or calling
183  * glSDL_UnlockSurface(), respectively.
184  *
185  * Note that if this function is not used, glSDL assumes that
186  * the entire surface has to be updated. (That is, it's safe
187  * to ignore this function - it's "just a performance hack.")
188  *
189  * Passing a rectangle with zero height or width cancels the
190  * downloading when/after unlocking the surface. Use if you
191  * just want to read the texture, but feel like being nice and
192  * obeying SDL_MUSTLOCK() - which is a good idea, as things
193  * may change...
194  *
195  * Passing NULL for the 'area' argument results in the entire
196  * surface being invalidated.
197  *
198  * NOTE: This function does NOT perform clipping! Weird or
199  *       even Bad Things may happen if you specify areas
200  *       that protrude outside the edges of the actual
201  *       surface.
202  */
203 void glSDL_Invalidate(SDL_Surface *surface, SDL_Rect *area);
204 
205 /*
206  * Set logic width and height of a surface.
207  *
208  * When used on the screen surface:
209  *	Changes the OpenGL view coordinate system without
210  *	changing the screen resolution. This is used to
211  *	decouple the rendering coordinate system from the
212  *	physical screen resolution, which is needed to
213  *	achieve sub-pixel resolution without switching to
214  *	float coords.
215  *
216  * When used on a SDL_Surface:
217  *	Normally, surfaces are scaled so that one pixel on
218  *	the surface corresponds to one pixel in the current
219  *	logic screen resolution. This function makes it
220  *	possible to change that relation by specifying the
221  *	desired size of the rendered texture in the current
222  *	logic screen resolution.
223  *
224  * BUG?	WRT blitting *to* surfaces, this call affects
225  *	the screen surface and other surfaces differently!
226  *	As of now, coordinates are *always* treated as real
227  *	pixels when blitting to normal surfaces, whereas
228  *	they are scaled when blitting to the screen.
229  *
230  * Of course, this function can also be "abused" just to
231  * make rendering code independent of screen resolution,
232  * although that can potentially *lower* accuracy, if the
233  * real resolution is higher than the logic resolution.
234  */
235 void glSDL_SetLogicSize(SDL_Surface *surface, int w, int h);
236 
237 /*
238  * Make sure that the texture of the specified surface is up
239  * to date in OpenGL texture memory.
240  *
241  * This can be used together with glSDL_UnloadSurface() to
242  * implement custom texture caching schemes.
243  *
244  * Returns 0 on success, or a negative value if something
245  * went wrong.
246  */
247 int glSDL_UploadSurface(SDL_Surface *surface);
248 
249 /*
250  * Free the texture space used by the specified surface.
251  *
252  * Normally, glSDL should download textures when needed, and
253  * unload the oldest (in terms of use) surfaces, if it runs out
254  * of texture space.
255  */
256 void glSDL_UnloadSurface(SDL_Surface *surface);
257 
258 
259 /*
260  * Get the clSDL_TexInfo struct associated with a surface.
261  */
262 glSDL_TexInfo *glSDL_GetTexInfo(SDL_Surface *surface);
263 
264 
265 
266 #ifdef __cplusplus
267 }
268 #endif
269 #include "close_code.h"
270 
271 /* Some ugly "overriding"... */
272 #ifndef	_GLSDL_NO_REDEFINES_
273 /*
274  * You *always* need to lock and unlock a glSDL surface in
275  * order to get glSDL to update the OpenGL texture!
276  */
277 #undef	SDL_MUSTLOCK
278 #define SDL_MUSTLOCK(surface)   \
279   (surface->offset ||           \
280   ((surface->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_RLEACCEL)) != 0) ||	\
281   IS_GLSDL_SURFACE(surface))
282 
283 #define	SDL_SetVideoMode		glSDL_SetVideoMode
284 #define	SDL_GetVideoSurface		glSDL_GetVideoSurface
285 #define	SDL_Quit			_glSDL_FullQuit
286 #define	SDL_QuitSubSystem		glSDL_QuitSubSystem
287 #define	SDL_UpdateRects			glSDL_UpdateRects
288 #define	SDL_UpdateRect			glSDL_UpdateRect
289 #define	SDL_Flip			glSDL_Flip
290 #define	SDL_FreeSurface			glSDL_FreeSurface
291 #define	SDL_LockSurface			glSDL_LockSurface
292 #define	SDL_UnlockSurface		glSDL_UnlockSurface
293 #define	SDL_SetColorKey			glSDL_SetColorKey
294 #define	SDL_SetAlpha			glSDL_SetAlpha
295 #define	SDL_SetClipRect			glSDL_SetClipRect
296 #undef	SDL_BlitSurface
297 #define	SDL_BlitSurface			glSDL_BlitSurface
298 #define	SDL_FillRect			glSDL_FillRect
299 #define	SDL_DisplayFormat		glSDL_DisplayFormat
300 #define	SDL_DisplayFormatAlpha		glSDL_DisplayFormatAlpha
301 #define	SDL_ConvertSurface		glSDL_ConvertSurface
302 #define	SDL_CreateRGBSurface		glSDL_CreateRGBSurface
303 #define	SDL_CreateRGBSurfaceFrom	glSDL_CreateRGBSurfaceFrom
304 #undef	SDL_AllocSurface
305 #define SDL_AllocSurface		glSDL_CreateRGBSurface
306 #undef	SDL_LoadBMP
307 #define	SDL_LoadBMP			glSDL_LoadBMP
308 #undef	SDL_SaveBMP
309 #define	SDL_SaveBMP			glSDL_SaveBMP
310 #define IMG_Load(x)			glSDL_IMG_Load(x)
311 #endif
312 
313 /* Some extra overloading for common external lib calls... */
314 #include "SDL/SDL_image.h"
315 #ifdef __cplusplus
316 extern "C" {
317 #endif
318 SDL_Surface *glSDL_IMG_Load(const char *file);
319 #ifdef __cplusplus
320 }
321 #endif
322 
323 #endif	/* HAVE_OPENGL */
324 
325 #endif
326