comparison src/video/SDL_renderer_gl.c @ 1924:69217fdd2c0a

If the OpenGL renderer is selected for a non-OpenGL window, recreate the window with OpenGL enabled. Added OpenGL renderer error checking. Use fast-path texture formats in the OpenGL renderer.
author Sam Lantinga <slouken@libsdl.org>
date Sat, 22 Jul 2006 21:02:57 +0000
parents d4572b97b08f
children 307355678142
comparison
equal deleted inserted replaced
1923:d4572b97b08f 1924:69217fdd2c0a
70 (SDL_TextureBlendMode_None | SDL_TextureBlendMode_Mask | 70 (SDL_TextureBlendMode_None | SDL_TextureBlendMode_Mask |
71 SDL_TextureBlendMode_Blend | SDL_TextureBlendMode_Add | 71 SDL_TextureBlendMode_Blend | SDL_TextureBlendMode_Add |
72 SDL_TextureBlendMode_Mod), 72 SDL_TextureBlendMode_Mod),
73 (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast | 73 (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast |
74 SDL_TextureScaleMode_Slow), 74 SDL_TextureScaleMode_Slow),
75 18, 75 16,
76 { 76 {
77 SDL_PixelFormat_Index1LSB, 77 SDL_PixelFormat_Index1LSB,
78 SDL_PixelFormat_Index1MSB, 78 SDL_PixelFormat_Index1MSB,
79 SDL_PixelFormat_Index8, 79 SDL_PixelFormat_Index8,
80 SDL_PixelFormat_RGB332, 80 SDL_PixelFormat_RGB332,
86 SDL_PixelFormat_RGB24, 86 SDL_PixelFormat_RGB24,
87 SDL_PixelFormat_BGR24, 87 SDL_PixelFormat_BGR24,
88 SDL_PixelFormat_RGB888, 88 SDL_PixelFormat_RGB888,
89 SDL_PixelFormat_BGR888, 89 SDL_PixelFormat_BGR888,
90 SDL_PixelFormat_ARGB8888, 90 SDL_PixelFormat_ARGB8888,
91 SDL_PixelFormat_RGBA8888,
92 SDL_PixelFormat_ABGR8888, 91 SDL_PixelFormat_ABGR8888,
93 SDL_PixelFormat_BGRA8888, 92 SDL_PixelFormat_ARGB2101010},
94 SDL_PixelFormat_ARGB2101010}, /* FIXME: YUV texture support */
95 0, 93 0,
96 0} 94 0}
97 }; 95 };
98 96
99 typedef struct 97 typedef struct
113 int pitch; 111 int pitch;
114 SDL_DirtyRectList dirty; 112 SDL_DirtyRectList dirty;
115 } GL_TextureData; 113 } GL_TextureData;
116 114
117 115
116 static void
117 GL_SetError(const char *prefix, GLenum result)
118 {
119 const char *error;
120
121 switch (result) {
122 case GL_NO_ERROR:
123 error = "GL_NO_ERROR";
124 break;
125 case GL_INVALID_ENUM:
126 error = "GL_INVALID_ENUM";
127 break;
128 case GL_INVALID_VALUE:
129 error = "GL_INVALID_VALUE";
130 break;
131 case GL_INVALID_OPERATION:
132 error = "GL_INVALID_OPERATION";
133 break;
134 case GL_STACK_OVERFLOW:
135 error = "GL_STACK_OVERFLOW";
136 break;
137 case GL_STACK_UNDERFLOW:
138 error = "GL_STACK_UNDERFLOW";
139 break;
140 case GL_OUT_OF_MEMORY:
141 error = "GL_OUT_OF_MEMORY";
142 break;
143 case GL_TABLE_TOO_LARGE:
144 error = "GL_TABLE_TOO_LARGE";
145 break;
146 default:
147 error = "UNKNOWN";
148 break;
149 }
150 SDL_SetError("%s: %s", prefix, error);
151 }
152
118 void 153 void
119 GL_AddRenderDriver(_THIS) 154 GL_AddRenderDriver(_THIS)
120 { 155 {
121 if (_this->GL_CreateContext) { 156 if (_this->GL_CreateContext) {
122 SDL_AddRenderDriver(0, &GL_RenderDriver); 157 SDL_AddRenderDriver(0, &GL_RenderDriver);
128 { 163 {
129 SDL_Renderer *renderer; 164 SDL_Renderer *renderer;
130 GL_RenderData *data; 165 GL_RenderData *data;
131 166
132 if (!(window->flags & SDL_WINDOW_OPENGL)) { 167 if (!(window->flags & SDL_WINDOW_OPENGL)) {
133 SDL_SetError 168 window->flags |= SDL_WINDOW_OPENGL;
134 ("The OpenGL renderer can only be used on OpenGL windows"); 169 if (SDL_RecreateWindow(window) < 0) {
135 return NULL; 170 return NULL;
171 }
136 } 172 }
137 173
138 renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); 174 renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
139 if (!renderer) { 175 if (!renderer) {
140 SDL_OutOfMemory(); 176 SDL_OutOfMemory();
237 SDL_Window *window = SDL_GetWindowFromID(renderer->window); 273 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
238 GL_TextureData *data; 274 GL_TextureData *data;
239 GLint internalFormat; 275 GLint internalFormat;
240 GLenum format, type; 276 GLenum format, type;
241 int texture_w, texture_h; 277 int texture_w, texture_h;
278 GLenum result;
242 279
243 switch (texture->format) { 280 switch (texture->format) {
244 case SDL_PixelFormat_Index1LSB: 281 case SDL_PixelFormat_Index1LSB:
245 case SDL_PixelFormat_Index1MSB: 282 case SDL_PixelFormat_Index1MSB:
246 internalFormat = GL_RGB; 283 internalFormat = GL_RGB;
287 format = GL_RGB; 324 format = GL_RGB;
288 type = GL_UNSIGNED_BYTE; 325 type = GL_UNSIGNED_BYTE;
289 break; 326 break;
290 case SDL_PixelFormat_RGB888: 327 case SDL_PixelFormat_RGB888:
291 internalFormat = GL_RGB8; 328 internalFormat = GL_RGB8;
292 format = GL_RGB; 329 format = GL_BGRA;
293 type = GL_UNSIGNED_INT_8_8_8_8; 330 type = GL_UNSIGNED_BYTE;
294 break; 331 break;
295 case SDL_PixelFormat_BGR24: 332 case SDL_PixelFormat_BGR24:
296 internalFormat = GL_RGB8; 333 internalFormat = GL_RGB8;
297 format = GL_BGR; 334 format = GL_BGR;
298 type = GL_UNSIGNED_BYTE; 335 type = GL_UNSIGNED_BYTE;
299 break; 336 break;
300 case SDL_PixelFormat_BGR888: 337 case SDL_PixelFormat_BGR888:
301 internalFormat = GL_RGB8; 338 internalFormat = GL_RGB8;
302 format = GL_BGR; 339 format = GL_RGBA;
303 type = GL_UNSIGNED_INT_8_8_8_8; 340 type = GL_UNSIGNED_BYTE;
304 break; 341 break;
305 case SDL_PixelFormat_ARGB8888: 342 case SDL_PixelFormat_ARGB8888:
306 internalFormat = GL_RGBA8; 343 internalFormat = GL_RGBA8;
307 format = GL_BGRA; 344 format = GL_BGRA;
308 type = GL_UNSIGNED_INT_8_8_8_8_REV; 345 type = GL_UNSIGNED_BYTE;
309 break;
310 case SDL_PixelFormat_RGBA8888:
311 internalFormat = GL_RGBA8;
312 format = GL_RGBA;
313 type = GL_UNSIGNED_INT_8_8_8_8;
314 break; 346 break;
315 case SDL_PixelFormat_ABGR8888: 347 case SDL_PixelFormat_ABGR8888:
316 internalFormat = GL_RGBA8; 348 internalFormat = GL_RGBA8;
317 format = GL_RGBA; 349 format = GL_RGBA;
318 type = GL_UNSIGNED_INT_8_8_8_8_REV; 350 type = GL_UNSIGNED_BYTE;
319 break;
320 case SDL_PixelFormat_BGRA8888:
321 internalFormat = GL_RGBA8;
322 format = GL_BGRA;
323 type = GL_UNSIGNED_INT_8_8_8_8;
324 break; 351 break;
325 case SDL_PixelFormat_ARGB2101010: 352 case SDL_PixelFormat_ARGB2101010:
326 internalFormat = GL_RGB10_A2; 353 internalFormat = GL_RGB10_A2;
327 format = GL_BGRA; 354 format = GL_BGRA;
328 type = GL_UNSIGNED_INT_2_10_10_10_REV; 355 type = GL_UNSIGNED_INT_2_10_10_10_REV;
338 return -1; 365 return -1;
339 } 366 }
340 367
341 texture->driverdata = data; 368 texture->driverdata = data;
342 369
343 /* FIXME: Check for GL_ARB_texture_rectangle and GL_EXT_texture_rectangle */ 370 glGetError();
344 glGenTextures(1, &data->texture); 371 glGenTextures(1, &data->texture);
345 #ifdef USE_GL_TEXTURE_RECTANGLE 372 #ifdef USE_GL_TEXTURE_RECTANGLE
346 data->type = GL_TEXTURE_RECTANGLE_ARB; 373 data->type = GL_TEXTURE_RECTANGLE_ARB;
347 texture_w = texture->w; 374 texture_w = texture->w;
348 texture_h = texture->h; 375 texture_h = texture->h;
358 data->format = format; 385 data->format = format;
359 data->formattype = type; 386 data->formattype = type;
360 glBindTexture(data->type, data->texture); 387 glBindTexture(data->type, data->texture);
361 glTexImage2D(data->type, 0, internalFormat, texture_w, texture_h, 0, 388 glTexImage2D(data->type, 0, internalFormat, texture_w, texture_h, 0,
362 format, type, NULL); 389 format, type, NULL);
363 390 result = glGetError();
391 if (result != GL_NO_ERROR) {
392 GL_SetError("glTexImage2D()", result);
393 return -1;
394 }
364 return 0; 395 return 0;
365 } 396 }
366 397
367 static int 398 static int
368 GL_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, 399 GL_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
381 GL_TextureData *data = (GL_TextureData *) texture->driverdata; 412 GL_TextureData *data = (GL_TextureData *) texture->driverdata;
382 413
383 return 0; 414 return 0;
384 } 415 }
385 416
417 static void
418 SetupTextureUpdate(SDL_Texture * texture, int pitch)
419 {
420 if (texture->format == SDL_PixelFormat_Index1LSB) {
421 glPixelStorei(GL_UNPACK_LSB_FIRST, 1);
422 } else if (texture->format == SDL_PixelFormat_Index1MSB) {
423 glPixelStorei(GL_UNPACK_LSB_FIRST, 0);
424 }
425 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
426 glPixelStorei(GL_UNPACK_ROW_LENGTH,
427 pitch / SDL_BYTESPERPIXEL(texture->format));
428 }
429
386 static int 430 static int
387 GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, 431 GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
388 const SDL_Rect * rect, const void *pixels, int pitch) 432 const SDL_Rect * rect, const void *pixels, int pitch)
389 { 433 {
390 GL_TextureData *data = (GL_TextureData *) texture->driverdata; 434 GL_TextureData *data = (GL_TextureData *) texture->driverdata;
391 435 GLenum result;
392 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); /* FIXME, what to use for RGB 4 byte formats? */ 436
393 glPixelStorei(GL_UNPACK_ROW_LENGTH, 437 glGetError();
394 pitch / SDL_BYTESPERPIXEL(texture->format)); 438 SetupTextureUpdate(texture, pitch);
395 glBindTexture(data->type, data->texture); 439 glBindTexture(data->type, data->texture);
396 glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w, rect->h, 440 glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w, rect->h,
397 data->format, data->formattype, pixels); 441 data->format, data->formattype, pixels);
398 /* FIXME: check for errors */ 442 result = glGetError();
443 if (result != GL_NO_ERROR) {
444 GL_SetError("glTexSubImage2D()", result);
445 return -1;
446 }
399 return 0; 447 return 0;
400 } 448 }
401 449
402 static int 450 static int
403 GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, 451 GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
476 SDL_DirtyRect *dirty; 524 SDL_DirtyRect *dirty;
477 void *pixels; 525 void *pixels;
478 int bpp = SDL_BYTESPERPIXEL(texture->format); 526 int bpp = SDL_BYTESPERPIXEL(texture->format);
479 int pitch = texturedata->pitch; 527 int pitch = texturedata->pitch;
480 528
481 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); /* FIXME, what to use for RGB 4 byte formats? */ 529 SetupTextureUpdate(texture, pitch);
482 glPixelStorei(GL_UNPACK_ROW_LENGTH,
483 pitch / SDL_BYTESPERPIXEL(texture->format));
484 glBindTexture(texturedata->type, texturedata->texture); 530 glBindTexture(texturedata->type, texturedata->texture);
485 for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) { 531 for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) {
486 SDL_Rect *rect = &dirty->rect; 532 SDL_Rect *rect = &dirty->rect;
487 pixels = 533 pixels =
488 (void *) ((Uint8 *) texturedata->pixels + rect->y * pitch + 534 (void *) ((Uint8 *) texturedata->pixels + rect->y * pitch +