Mercurial > sdl-ios-xcode
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 + |