1 /*(LGPL)
2 ------------------------------------------------------------
3 	glSDL 0.9 - SDL 2D API on top of OpenGL
4 ------------------------------------------------------------
5  * Copyright (C) 2001-2004, 2006-2007 David Olofson
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  * NOTE:
18  *	See README about using this glSDL wrapper with
19  *	SDL versions that have the glSDL backend!
20  */
21 
22 /* We're still using SDL datatypes here - we just add some stuff. */
23 #include "SDL.h"
24 
25 /*
26  * Ignore the flag from SDL w/ glSDL backend, since we're going
27  * to use glSDL/wrapper by default.
28  */
29 #ifdef	SDL_GLSDL
30 #undef	SDL_GLSDL
31 #endif
32 
33 #ifndef HAVE_OPENGL
34 
35 /* Fakes to make glSDL code compile with SDL. */
36 #define SDL_GLSDL		0
37 #define	GLSDL_FIX_SURFACE(s)
38 
39 #else	/* HAVE_OPENGL */
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
45 #if (SDL_MAJOR_VERSION <= 1) && (SDL_MINOR_VERSION <= 2) &&	\
46 		(SDL_PATCHLEVEL < 5)
47 #warning glSDL: Using SDL version 1.2.5 or later is strongly recommended!
48 #endif
49 
50 /*----------------------------------------------------------
51 	SDL style API
52 ----------------------------------------------------------*/
53 
54 typedef enum glSDL_TileModes
55 {
56 	GLSDL_TM_SINGLE,
57 	GLSDL_TM_HORIZONTAL,
58 	GLSDL_TM_VERTICAL,
59 	GLSDL_TM_HUGE
60 } glSDL_TileModes;
61 
62 
63 typedef struct glSDL_TexInfo
64 {
65 	int		textures;
66 	int		*texture;
67 	int		texsize;	/* width/height of OpenGL texture */
68 	glSDL_TileModes	tilemode;
69 	int		tilew, tileh;	/* At least one must equal texsize! */
70 	int		tilespertex;
71 
72 	/* Area of surface to download when/after unlocking */
73 	SDL_Rect	invalid_area;
74 } glSDL_TexInfo;
75 
76 #define	GLSDL_FIX_SURFACE(s)	(s)->unused1 = 0;
77 #define	IS_GLSDL_SURFACE(s)	((s) && texinfotab && glSDL_GetTexInfo(s))
78 
79 #ifdef	SDL_GLSDL
80 #undef	SDL_GLSDL	/* In case SDL has the glSDL backend...  */
81 #endif
82 #define SDL_GLSDL	0x00100000	/* Create an OpenGL 2D rendering context */
83 
84 
85 /*
86  * Wraps SDL_SetVideoMode(), and adds support for the SDL_GLSDL flag.
87  *
88  * If 'flags' contains SDL_GLSDL, glSDL_SetVideoMode() sets up a "pure"
89  * OpenGL rendering context for use with the glSDL_ calls.
90  *
91  * SDL can be closed as usual (using SDL_ calls), but you should call
92  * glSDL_Quit() (kludge) to allow glSDL to clean up it's internal stuff.
93  */
94 SDL_Surface *glSDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);
95 void glSDL_Quit(void);
96 
97 void glSDL_QuitSubSystem(Uint32 flags);
98 
99 /* Replaces SDL_Quit() entirely, when using the override defines */
100 void glSDL_FullQuit(void);
101 
102 SDL_Surface *glSDL_GetVideoSurface(void);
103 
104 void glSDL_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects);
105 void glSDL_UpdateRect(SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h);
106 
107 /*
108  * Works like SDL_Flip(), but may also perform enqueued blits.
109  * (That is, it's possible that the implementation renders
110  * *nothing* until glSDL_Flip() is called.)
111  */
112 int glSDL_Flip(SDL_Surface *screen);
113 
114 void glSDL_FreeSurface(SDL_Surface *surface);
115 
116 int glSDL_LockSurface(SDL_Surface *surface);
117 void glSDL_UnlockSurface(SDL_Surface *surface);
118 
119 /*
120  * Like the respective SDL functions, although they ignore
121  * SDL_RLEACCEL, as it makes no sense in this context.
122  */
123 int glSDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key);
124 int glSDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha);
125 
126 /*
127  * Sets up clipping for the screen, or a SDL_Surface.
128  *
129  * Note that this function takes both SDL_Surfaces and
130  * glSDL_Surfaces.
131  */
132 SDL_bool glSDL_SetClipRect(SDL_Surface *surface, SDL_Rect *rect);
133 
134 int glSDL_BlitSurface(SDL_Surface *src, SDL_Rect *srcrect,
135 			 SDL_Surface *dst, SDL_Rect *dstrect);
136 
137 int glSDL_FillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color);
138 
139 /*
140  * Convert the given surface into a SDL_Surface (if it isn't
141  * one already), and makes sure that the underlying SDL_Surface
142  * is of a pixel format suitable for fast texture downloading.
143  *
144  * Note that you *only* have to use this function if you want
145  * fast pixel access to surfaces (ie "procedural textures").
146  * Any surfaces that aren't converted will be downloaded
147  * automatically upon the first call to glSDL_BlitSurface(),
148  * but if conversion is required, it will be required for
149  * every glSDL_UnlockSurface() call.
150  *
151  * IMPORTANT:
152  *	You *can* pass an SDL_Surface directly to this function,
153  *	and it will try to deal with it nicely. However, this
154  *	requires that a temporary SDL_Surface is created, and
155  *	this surface is cached only until the texture memory is
156  *	needed for new surfaces.
157  */
158 SDL_Surface *glSDL_DisplayFormat(SDL_Surface *surface);
159 SDL_Surface *glSDL_DisplayFormatAlpha(SDL_Surface *surface);
160 
161 SDL_Surface *glSDL_ConvertSurface
162 			(SDL_Surface *src, SDL_PixelFormat *fmt, Uint32 flags);
163 SDL_Surface *glSDL_CreateRGBSurface
164 			(Uint32 flags, int width, int height, int depth,
165 			Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
166 SDL_Surface *glSDL_CreateRGBSurfaceFrom(void *pixels,
167 			int width, int height, int depth, int pitch,
168 			Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
169 SDL_Surface *glSDL_LoadBMP(const char *file);
170 int glSDL_SaveBMP(SDL_Surface *surface, const char *file);
171 
172 #ifdef __cplusplus
173 }
174 #endif
175 
176 /* Some ugly "overriding"... */
177 #ifndef	_GLSDL_NO_REDEFINES_
178 /*
179  * You *always* need to lock and unlock a glSDL surface in
180  * order to get glSDL to update the OpenGL texture!
181  */
182 #undef	SDL_MUSTLOCK
183 #define SDL_MUSTLOCK(surface)   \
184   (surface->offset ||           \
185   ((surface->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_RLEACCEL)) != 0) ||	\
186   IS_GLSDL_SURFACE(surface))
187 
188 #define	SDL_SetVideoMode		glSDL_SetVideoMode
189 #define	SDL_GetVideoSurface		glSDL_GetVideoSurface
190 #define	SDL_Quit			glSDL_FullQuit
191 #define	SDL_QuitSubSystem		glSDL_QuitSubSystem
192 #define	SDL_UpdateRects			glSDL_UpdateRects
193 #define	SDL_UpdateRect			glSDL_UpdateRect
194 #define	SDL_Flip			glSDL_Flip
195 #define	SDL_FreeSurface			glSDL_FreeSurface
196 #define	SDL_LockSurface			glSDL_LockSurface
197 #define	SDL_UnlockSurface		glSDL_UnlockSurface
198 #define	SDL_SetColorKey			glSDL_SetColorKey
199 #define	SDL_SetAlpha			glSDL_SetAlpha
200 #define	SDL_SetClipRect			glSDL_SetClipRect
201 #undef	SDL_BlitSurface
202 #define	SDL_BlitSurface			glSDL_BlitSurface
203 #define	SDL_FillRect			glSDL_FillRect
204 #define	SDL_DisplayFormat		glSDL_DisplayFormat
205 #define	SDL_DisplayFormatAlpha		glSDL_DisplayFormatAlpha
206 #define	SDL_ConvertSurface		glSDL_ConvertSurface
207 #define	SDL_CreateRGBSurface		glSDL_CreateRGBSurface
208 #define	SDL_CreateRGBSurfaceFrom	glSDL_CreateRGBSurfaceFrom
209 #undef	SDL_AllocSurface
210 #define SDL_AllocSurface		glSDL_CreateRGBSurface
211 #undef	SDL_LoadBMP
212 #define	SDL_LoadBMP			glSDL_LoadBMP
213 #undef	SDL_SaveBMP
214 #define	SDL_SaveBMP			glSDL_SaveBMP
215 #define IMG_Load(x)			glSDL_IMG_Load(x)
216 #endif
217 
218 #endif	/* HAVE_OPENGL */
219 
220 
221 #ifdef	HAVE_OPENGL
222 
223 /* Some extra overloading for common external lib calls... */
224 #include "SDL_image.h"
225 #ifdef __cplusplus
226 extern "C" {
227 #endif
228 SDL_Surface *glSDL_IMG_Load(const char *file);
229 #ifdef __cplusplus
230 }
231 #endif
232 
233 #endif	/* HAVE_OPENGL */
234 
235 
236 /*----------------------------------------------------------
237 	glSDL API extensions, transparent
238 ----------------------------------------------------------*/
239 #ifdef __cplusplus
240 extern "C" {
241 #endif
242 /*
243  * Invalidate part of a texture.
244  *
245  * This function can be used either between calls to
246  * glSDL_LockSurface() and glSDL_UnlockSurface(), or before
247  * calling glSDL_DownloadSurface().
248  *
249  * In either case, it causes only the specified area to be
250  * downloaded when unlocking the surface, or calling
251  * glSDL_UnlockSurface(), respectively.
252  *
253  * Note that if this function is not used, glSDL assumes that
254  * the entire surface has to be updated. (That is, it's safe
255  * to ignore this function - it's "just a performance hack.")
256  *
257  * Passing a rectangle with zero height or width cancels the
258  * downloading when/after unlocking the surface. Use if you
259  * just want to read the texture, but feel like being nice and
260  * obeying SDL_MUSTLOCK() - which is a good idea, as things
261  * may change...
262  *
263  * Passing NULL for the 'area' argument results in the entire
264  * surface being invalidated.
265  *
266  * NOTE: This function does NOT perform clipping! Weird or
267  *       even Bad Things may happen if you specify areas
268  *       that protrude outside the edges of the actual
269  *       surface.
270  */
271 void glSDL_Invalidate(SDL_Surface *surface, SDL_Rect *area);
272 
273 /*
274  * Make sure that the texture of the specified surface is up
275  * to date in OpenGL texture memory.
276  *
277  * This can be used together with glSDL_UnloadSurface() to
278  * implement custom texture caching schemes.
279  *
280  * Returns 0 on success, or a negative value if something
281  * went wrong.
282  */
283 int glSDL_UploadSurface(SDL_Surface *surface);
284 
285 /*
286  * Free the texture space used by the specified surface.
287  *
288  * Normally, glSDL should download textures when needed, and
289  * unload the oldest (in terms of use) surfaces, if it runs out
290  * of texture space.
291  */
292 void glSDL_UnloadSurface(SDL_Surface *surface);
293 
294 
295 /*----------------------------------------------------------
296 	glSDL API extensions, OpenGL mode ONLY
297 ----------------------------------------------------------*/
298 
299 /*
300  * Enable, disable or check the state of "vsync" or
301  * vertical retrace synchronization. Note that enabling
302  * this does not *guarantee* that the driver actually
303  * uses vsync; it only instructs OpenGL to do so if
304  * possible.
305  *    Pass 1 for 'use' to enable vsync, '0' to disable
306  * it, and -1 to just return the current state without
307  * changing it.
308  *    Returns the vsync state *before* any change made
309  * by the call.
310  *
311  * NOTE: Ignored when not using OpenGL acceleration!
312  */
313 int glSDL_VSync(int use);
314 
315 /*
316  * Set alpha multiplier. This is multiplied with any full
317  * surface alpha or alpha channels of surfaces.
318  *
319  * The default value is 255, which makes glSDL render like
320  * the standard SDL 2D backends, ie based only on the
321  * surface settings.
322  *
323  * This function affects the global state of glSDL.
324  *
325  * NOTE: NOT available without OpenGL acceleration!
326  */
327 void glSDL_SetBlendAlpha(Uint8 alpha);
328 
329 /*
330  * Set color multipliers. These are multiplied with the
331  * respective color channers of rendered surfaces,
332  * modulating the brightness of the resulting output.
333  *
334  * The default values are 255, which makes glSDL render
335  * like the standard SDL 2D backends.
336  *
337  * This function affects the global state of glSDL.
338  *
339  * NOTE: NOT available without OpenGL acceleration!
340  */
341 void glSDL_SetBlendColor(Uint8 r, Uint8 g, Uint8 b);
342 
343 /*
344  * Set center offset in pixels for scaling and rotation.
345  *
346  * The default is (0, 0), which makes surfaces rotate and
347  * scale around their centers.
348  *
349  * This function affects the global state of glSDL.
350  *
351  * NOTE: NOT available without OpenGL acceleration!
352  */
353 void glSDL_SetCenter(float x, float y);
354 
355 
356 /*
357  * Set rotation angle in degrees. Rotation is done around
358  * the center point, which is defined as
359  *	(w/2 + cx, h/2 + cy)
360  * where w and h are the width and height of the source
361  * surface, and cx and cy are the center offsets set by
362  * glSDL_SetCenter().
363  *
364  * The default value is 0.0f, which makes glSDL render
365  * like a normal SDL 2D backend.
366  *
367  * This function affects the global state of glSDL.
368  *
369  * NOTE: NOT available without OpenGL acceleration!
370  */
371 void glSDL_SetRotation(float angle);
372 
373 /*
374  * Set scale factor. Scaling is centered around around
375  * the point
376  *	(w/2 + cx, h/2 + cy)
377  * where w and h are the width and height of the source
378  * surface, and cx and cy are the center offsets set by
379  * glSDL_SetCenter().
380  *
381  * The default value is 1.0f, which makes glSDL render
382  * like a normal SDL 2D backend.
383  *
384  * This function affects the global state of glSDL.
385  *
386  * NOTE: NOT available without OpenGL acceleration!
387  */
388 void glSDL_SetScale(float x, float y);
389 
390 /*
391  * Reset glSDL global state to defaults.
392  */
393 void glSDL_ResetState(void);
394 #ifdef __cplusplus
395 }
396 #endif
397 
398 
399 #endif	/* _GLSDL_H_ */
400