src/video/ataricommon/SDL_atarigl.c
author Patrice Mandin
Thu, 25 Nov 2004 15:47:49 +0000
changeset 989 475166d13b44
child 991 12b13601a544
permissions -rw-r--r--
Factorize OSMesa OpenGL code for Atari drivers
patmandin@989
     1
/*
patmandin@989
     2
    SDL - Simple DirectMedia Layer
patmandin@989
     3
    Copyright (C) 1997-2004 Sam Lantinga
patmandin@989
     4
patmandin@989
     5
    This library is free software; you can redistribute it and/or
patmandin@989
     6
    modify it under the terms of the GNU Library General Public
patmandin@989
     7
    License as published by the Free Software Foundation; either
patmandin@989
     8
    version 2 of the License, or (at your option) any later version.
patmandin@989
     9
patmandin@989
    10
    This library is distributed in the hope that it will be useful,
patmandin@989
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
patmandin@989
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
patmandin@989
    13
    Library General Public License for more details.
patmandin@989
    14
patmandin@989
    15
    You should have received a copy of the GNU Library General Public
patmandin@989
    16
    License along with this library; if not, write to the Free
patmandin@989
    17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
patmandin@989
    18
patmandin@989
    19
    Sam Lantinga
patmandin@989
    20
    slouken@libsdl.org
patmandin@989
    21
*/
patmandin@989
    22
patmandin@989
    23
/* Atari OSMesa.ldg implementation of SDL OpenGL support */
patmandin@989
    24
patmandin@989
    25
/*--- Includes ---*/
patmandin@989
    26
patmandin@989
    27
#ifdef HAVE_OPENGL
patmandin@989
    28
#include <GL/osmesa.h>
patmandin@989
    29
#endif
patmandin@989
    30
patmandin@989
    31
#include "SDL_video.h"
patmandin@989
    32
#include "SDL_error.h"
patmandin@989
    33
#include "SDL_endian.h"
patmandin@989
    34
#include "SDL_atarigl_c.h"
patmandin@989
    35
patmandin@989
    36
/*--- Variables ---*/
patmandin@989
    37
patmandin@989
    38
/*--- Functions prototypes ---*/
patmandin@989
    39
patmandin@989
    40
static void ConvertNull(SDL_Surface *surface);
patmandin@989
    41
static void Convert565To555be(SDL_Surface *surface);
patmandin@989
    42
static void Convert565To555le(SDL_Surface *surface);
patmandin@989
    43
static void Convert565le(SDL_Surface *surface);
patmandin@989
    44
static void ConvertBGRAToABGR(SDL_Surface *surface);
patmandin@989
    45
patmandin@989
    46
/*--- Public functions ---*/
patmandin@989
    47
patmandin@989
    48
int SDL_AtariGL_Init(_THIS, SDL_Surface *current)
patmandin@989
    49
{
patmandin@989
    50
#ifdef HAVE_OPENGL
patmandin@989
    51
	GLenum osmesa_format;
patmandin@989
    52
	SDL_PixelFormat *pixel_format;
patmandin@989
    53
	Uint32	redmask;
patmandin@989
    54
patmandin@989
    55
	SDL_AtariGL_Quit(this);	/* Destroy previous context if exist */
patmandin@989
    56
patmandin@989
    57
	/* Init OpenGL context using OSMesa */
patmandin@989
    58
	gl_convert = ConvertNull;
patmandin@989
    59
patmandin@989
    60
	pixel_format = current->format;
patmandin@989
    61
	redmask = pixel_format->Rmask;
patmandin@989
    62
	switch (pixel_format->BitsPerPixel) {
patmandin@989
    63
		case 15:
patmandin@989
    64
			/* 1555, big and little endian, unsupported */
patmandin@989
    65
			osmesa_format = OSMESA_RGB_565;
patmandin@989
    66
			if (redmask == 31<<10) {
patmandin@989
    67
				gl_convert = Convert565To555be;
patmandin@989
    68
			} else {
patmandin@989
    69
				gl_convert = Convert565To555le;
patmandin@989
    70
			}
patmandin@989
    71
			break;
patmandin@989
    72
		case 16:
patmandin@989
    73
			if (redmask == 31<<11) {
patmandin@989
    74
				osmesa_format = OSMESA_RGB_565;
patmandin@989
    75
			} else {
patmandin@989
    76
				/* 565, little endian, unsupported */
patmandin@989
    77
				osmesa_format = OSMESA_RGB_565;
patmandin@989
    78
				gl_convert = Convert565le;
patmandin@989
    79
			}
patmandin@989
    80
			break;
patmandin@989
    81
		case 24:
patmandin@989
    82
			if (redmask == 255<<16) {
patmandin@989
    83
				osmesa_format = OSMESA_RGB;
patmandin@989
    84
			} else {
patmandin@989
    85
				osmesa_format = OSMESA_BGR;
patmandin@989
    86
			}
patmandin@989
    87
			break;
patmandin@989
    88
		case 32:
patmandin@989
    89
			if (redmask == 255<<16) {
patmandin@989
    90
				osmesa_format = OSMESA_ARGB;
patmandin@989
    91
			} else if (redmask == 255<<8) {
patmandin@989
    92
				osmesa_format = OSMESA_BGRA;
patmandin@989
    93
			} else if (redmask == 255<<24) {
patmandin@989
    94
				osmesa_format = OSMESA_RGBA;
patmandin@989
    95
			} else {
patmandin@989
    96
				/* ABGR format unsupported */
patmandin@989
    97
				osmesa_format = OSMESA_BGRA;
patmandin@989
    98
				gl_convert = ConvertBGRAToABGR;
patmandin@989
    99
			}
patmandin@989
   100
			break;
patmandin@989
   101
		default:
patmandin@989
   102
			osmesa_format = OSMESA_COLOR_INDEX;
patmandin@989
   103
			break;
patmandin@989
   104
	}
patmandin@989
   105
patmandin@989
   106
	gl_ctx = OSMesaCreateContextExt( osmesa_format, this->gl_config.depth_size,
patmandin@989
   107
		this->gl_config.stencil_size, this->gl_config.accum_red_size +
patmandin@989
   108
		this->gl_config.accum_green_size + this->gl_config.accum_blue_size +
patmandin@989
   109
		this->gl_config.accum_alpha_size, NULL );
patmandin@989
   110
patmandin@989
   111
	gl_active = (gl_ctx != NULL);
patmandin@989
   112
	return (gl_active);
patmandin@989
   113
#else
patmandin@989
   114
	return 0;
patmandin@989
   115
#endif
patmandin@989
   116
}
patmandin@989
   117
patmandin@989
   118
void SDL_AtariGL_Quit(_THIS)
patmandin@989
   119
{
patmandin@989
   120
#ifdef HAVE_OPENGL
patmandin@989
   121
	/* Shutdown OpenGL context */
patmandin@989
   122
	if (gl_ctx) {
patmandin@989
   123
		OSMesaDestroyContext(gl_ctx);
patmandin@989
   124
		gl_ctx = NULL;
patmandin@989
   125
	}
patmandin@989
   126
#endif
patmandin@989
   127
	gl_active = 0;
patmandin@989
   128
}
patmandin@989
   129
patmandin@989
   130
int SDL_AtariGL_LoadLibrary(_THIS, const char *path)
patmandin@989
   131
{
patmandin@989
   132
#ifdef HAVE_OPENGL
patmandin@989
   133
	/* Library is always opened */
patmandin@989
   134
	this->gl_config.driver_loaded = 1;
patmandin@989
   135
#endif
patmandin@989
   136
	return 0;
patmandin@989
   137
}
patmandin@989
   138
patmandin@989
   139
void *SDL_AtariGL_GetProcAddress(_THIS, const char *proc)
patmandin@989
   140
{
patmandin@989
   141
	void *func = NULL;
patmandin@989
   142
#ifdef HAVE_OPENGL
patmandin@989
   143
	if (gl_ctx != NULL) {
patmandin@989
   144
		func = OSMesaGetProcAddress(proc);
patmandin@989
   145
	}
patmandin@989
   146
#endif
patmandin@989
   147
	return func;
patmandin@989
   148
}
patmandin@989
   149
patmandin@989
   150
int SDL_AtariGL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
patmandin@989
   151
{
patmandin@989
   152
#ifdef HAVE_OPENGL
patmandin@989
   153
	GLenum mesa_attrib;
patmandin@989
   154
	SDL_Surface *surface;
patmandin@989
   155
patmandin@989
   156
	if (gl_ctx == NULL) {
patmandin@989
   157
		return -1;
patmandin@989
   158
	}
patmandin@989
   159
patmandin@989
   160
	switch(attrib) {
patmandin@989
   161
		case SDL_GL_RED_SIZE:
patmandin@989
   162
			mesa_attrib = GL_RED_BITS;
patmandin@989
   163
			break;
patmandin@989
   164
		case SDL_GL_GREEN_SIZE:
patmandin@989
   165
			mesa_attrib = GL_GREEN_BITS;
patmandin@989
   166
			break;
patmandin@989
   167
		case SDL_GL_BLUE_SIZE:
patmandin@989
   168
			mesa_attrib = GL_BLUE_BITS;
patmandin@989
   169
			break;
patmandin@989
   170
		case SDL_GL_ALPHA_SIZE:
patmandin@989
   171
			mesa_attrib = GL_ALPHA_BITS;
patmandin@989
   172
			break;
patmandin@989
   173
		case SDL_GL_DOUBLEBUFFER:
patmandin@989
   174
			surface = this->screen;
patmandin@989
   175
			*value = ((surface->flags & SDL_DOUBLEBUF)==SDL_DOUBLEBUF);
patmandin@989
   176
			return 0;
patmandin@989
   177
		case SDL_GL_DEPTH_SIZE:
patmandin@989
   178
			mesa_attrib = GL_DEPTH_BITS;
patmandin@989
   179
			break;
patmandin@989
   180
		case SDL_GL_STENCIL_SIZE:
patmandin@989
   181
			mesa_attrib = GL_STENCIL_BITS;
patmandin@989
   182
			break;
patmandin@989
   183
		case SDL_GL_ACCUM_RED_SIZE:
patmandin@989
   184
			mesa_attrib = GL_ACCUM_RED_BITS;
patmandin@989
   185
			break;
patmandin@989
   186
		case SDL_GL_ACCUM_GREEN_SIZE:
patmandin@989
   187
			mesa_attrib = GL_ACCUM_GREEN_BITS;
patmandin@989
   188
			break;
patmandin@989
   189
		case SDL_GL_ACCUM_BLUE_SIZE:
patmandin@989
   190
			mesa_attrib = GL_ACCUM_BLUE_BITS;
patmandin@989
   191
			break;
patmandin@989
   192
		case SDL_GL_ACCUM_ALPHA_SIZE:
patmandin@989
   193
			mesa_attrib = GL_ACCUM_ALPHA_BITS;
patmandin@989
   194
			break;
patmandin@989
   195
		default :
patmandin@989
   196
			return -1;
patmandin@989
   197
	}
patmandin@989
   198
patmandin@989
   199
	glGetIntegerv(mesa_attrib, value);
patmandin@989
   200
	return 0;
patmandin@989
   201
#else
patmandin@989
   202
	return -1;
patmandin@989
   203
#endif
patmandin@989
   204
}
patmandin@989
   205
patmandin@989
   206
int SDL_AtariGL_MakeCurrent(_THIS)
patmandin@989
   207
{
patmandin@989
   208
#ifdef HAVE_OPENGL
patmandin@989
   209
	SDL_Surface *surface;
patmandin@989
   210
	GLenum type;
patmandin@989
   211
patmandin@989
   212
	if (gl_ctx == NULL) {
patmandin@989
   213
		SDL_SetError("Invalid OpenGL context");
patmandin@989
   214
		return -1;
patmandin@989
   215
	}
patmandin@989
   216
patmandin@989
   217
	surface = this->screen;
patmandin@989
   218
	
patmandin@989
   219
	if ((surface->format->BitsPerPixel == 15) || (surface->format->BitsPerPixel == 16)) {
patmandin@989
   220
		type = GL_UNSIGNED_SHORT_5_6_5;
patmandin@989
   221
	} else {
patmandin@989
   222
		type = GL_UNSIGNED_BYTE;
patmandin@989
   223
	}
patmandin@989
   224
patmandin@989
   225
	if (!OSMesaMakeCurrent(gl_ctx, surface->pixels, type, surface->w, surface->h)) {
patmandin@989
   226
		SDL_SetError("Can not make OpenGL context current");
patmandin@989
   227
		return -1;
patmandin@989
   228
	}
patmandin@989
   229
patmandin@989
   230
	/* OSMesa draws upside down */
patmandin@989
   231
	OSMesaPixelStore(OSMESA_Y_UP, 0);
patmandin@989
   232
patmandin@989
   233
	return 0;
patmandin@989
   234
#else
patmandin@989
   235
	return -1;
patmandin@989
   236
#endif
patmandin@989
   237
}
patmandin@989
   238
patmandin@989
   239
void SDL_AtariGL_SwapBuffers(_THIS)
patmandin@989
   240
{
patmandin@989
   241
#ifdef HAVE_OPENGL
patmandin@989
   242
	if (gl_ctx == NULL) {
patmandin@989
   243
		return;
patmandin@989
   244
	}
patmandin@989
   245
patmandin@989
   246
	gl_convert(this->screen);
patmandin@989
   247
#endif
patmandin@989
   248
}
patmandin@989
   249
patmandin@989
   250
/*--- Private functions ---*/
patmandin@989
   251
patmandin@989
   252
static void ConvertNull(SDL_Surface *surface)
patmandin@989
   253
{
patmandin@989
   254
}
patmandin@989
   255
patmandin@989
   256
static void Convert565To555be(SDL_Surface *surface)
patmandin@989
   257
{
patmandin@989
   258
	int x,y, pitch;
patmandin@989
   259
	unsigned short *line, *pixel;
patmandin@989
   260
patmandin@989
   261
	line = surface->pixels;
patmandin@989
   262
	pitch = surface->pitch >> 1;
patmandin@989
   263
	for (y=0; y<surface->h; y++) {
patmandin@989
   264
		pixel = line;
patmandin@989
   265
		for (x=0; x<surface->w; x++) {
patmandin@989
   266
			unsigned short color = *pixel;
patmandin@989
   267
patmandin@989
   268
			*pixel++ = (color & 0x1f)|((color>>1) & 0xffe0);
patmandin@989
   269
		}
patmandin@989
   270
patmandin@989
   271
		line += pitch;
patmandin@989
   272
	}
patmandin@989
   273
}
patmandin@989
   274
patmandin@989
   275
static void Convert565To555le(SDL_Surface *surface)
patmandin@989
   276
{
patmandin@989
   277
	int x,y, pitch;
patmandin@989
   278
	unsigned short *line, *pixel;
patmandin@989
   279
patmandin@989
   280
	line = surface->pixels;
patmandin@989
   281
	pitch = surface->pitch >>1;
patmandin@989
   282
	for (y=0; y<surface->h; y++) {
patmandin@989
   283
		pixel = line;
patmandin@989
   284
		for (x=0; x<surface->w; x++) {
patmandin@989
   285
			unsigned short color = *pixel;
patmandin@989
   286
patmandin@989
   287
			color = (color & 0x1f)|((color>>1) & 0xffe0);
patmandin@989
   288
			*pixel++ = SDL_Swap16(color);
patmandin@989
   289
		}
patmandin@989
   290
patmandin@989
   291
		line += pitch;
patmandin@989
   292
	}
patmandin@989
   293
}
patmandin@989
   294
patmandin@989
   295
static void Convert565le(SDL_Surface *surface)
patmandin@989
   296
{
patmandin@989
   297
	int x,y, pitch;
patmandin@989
   298
	unsigned short *line, *pixel;
patmandin@989
   299
patmandin@989
   300
	line = surface->pixels;
patmandin@989
   301
	pitch = surface->pitch >>1;
patmandin@989
   302
	for (y=0; y<surface->h; y++) {
patmandin@989
   303
		pixel = line;
patmandin@989
   304
		for (x=0; x<surface->w; x++) {
patmandin@989
   305
			unsigned short color = *pixel;
patmandin@989
   306
patmandin@989
   307
			*pixel++ = SDL_Swap16(color);
patmandin@989
   308
		}
patmandin@989
   309
patmandin@989
   310
		line += pitch;
patmandin@989
   311
	}
patmandin@989
   312
}
patmandin@989
   313
patmandin@989
   314
static void ConvertBGRAToABGR(SDL_Surface *surface)
patmandin@989
   315
{
patmandin@989
   316
	int x,y, pitch;
patmandin@989
   317
	unsigned long *line, *pixel;
patmandin@989
   318
patmandin@989
   319
	line = surface->pixels;
patmandin@989
   320
	pitch = surface->pitch >>2;
patmandin@989
   321
	for (y=0; y<surface->h; y++) {
patmandin@989
   322
		pixel = line;
patmandin@989
   323
		for (x=0; x<surface->w; x++) {
patmandin@989
   324
			unsigned long color = *pixel;
patmandin@989
   325
patmandin@989
   326
			*pixel++ = (color<<24)|(color>>8);
patmandin@989
   327
		}
patmandin@989
   328
patmandin@989
   329
		line += pitch;
patmandin@989
   330
	}
patmandin@989
   331
}