comparison src/video/SDL_renderer_gl.c @ 1927:aeb8263d377a

OpenGL renderer is feature complete! Dynamically load GL functions in the OpenGL renderer.
author Sam Lantinga <slouken@libsdl.org>
date Sat, 22 Jul 2006 23:04:41 +0000
parents 307355678142
children 861bc36f0ab3
comparison
equal deleted inserted replaced
1926:307355678142 1927:aeb8263d377a
96 96
97 typedef struct 97 typedef struct
98 { 98 {
99 SDL_GLContext context; 99 SDL_GLContext context;
100 SDL_bool GL_ARB_texture_rectangle_supported; 100 SDL_bool GL_ARB_texture_rectangle_supported;
101 int blendMode;
102 int scaleMode;
103
104 /* OpenGL functions */
105 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
106 #include "SDL_glfuncs.h"
107 #undef SDL_PROC
101 } GL_RenderData; 108 } GL_RenderData;
102 109
103 typedef struct 110 typedef struct
104 { 111 {
105 GLuint texture; 112 GLuint texture;
147 default: 154 default:
148 error = "UNKNOWN"; 155 error = "UNKNOWN";
149 break; 156 break;
150 } 157 }
151 SDL_SetError("%s: %s", prefix, error); 158 SDL_SetError("%s: %s", prefix, error);
159 }
160
161 static int
162 GL_LoadFunctions(GL_RenderData * data)
163 {
164 #if defined(__QNXNTO__) && (_NTO_VERSION < 630)
165 #define __SDL_NOGETPROCADDR__
166 #elif defined(__MINT__)
167 #define __SDL_NOGETPROCADDR__
168 #endif
169 #ifdef __SDL_NOGETPROCADDR__
170 #define SDL_PROC(ret,func,params) data->func=func;
171 #else
172 #define SDL_PROC(ret,func,params) \
173 do { \
174 data->func = SDL_GL_GetProcAddress(#func); \
175 if ( ! data->func ) { \
176 SDL_SetError("Couldn't load GL function %s: %s\n", #func, SDL_GetError()); \
177 return -1; \
178 } \
179 } while ( 0 );
180 #endif /* __SDL_NOGETPROCADDR__ */
181
182 #include "SDL_glfuncs.h"
183 #undef SDL_PROC
184 return 0;
152 } 185 }
153 186
154 void 187 void
155 GL_AddRenderDriver(_THIS) 188 GL_AddRenderDriver(_THIS)
156 { 189 {
203 renderer->driverdata = data; 236 renderer->driverdata = data;
204 237
205 renderer->info.flags = 238 renderer->info.flags =
206 (SDL_Renderer_PresentDiscard | SDL_Renderer_Accelerated); 239 (SDL_Renderer_PresentDiscard | SDL_Renderer_Accelerated);
207 240
241 if (GL_LoadFunctions(data) < 0) {
242 GL_DestroyRenderer(renderer);
243 return NULL;
244 }
245
208 data->context = SDL_GL_CreateContext(window->id); 246 data->context = SDL_GL_CreateContext(window->id);
209 if (!data->context) { 247 if (!data->context) {
210 GL_DestroyRenderer(renderer); 248 GL_DestroyRenderer(renderer);
211 return NULL; 249 return NULL;
212 } 250 }
222 } 260 }
223 if (SDL_GL_GetSwapInterval() > 0) { 261 if (SDL_GL_GetSwapInterval() > 0) {
224 renderer->info.flags |= SDL_Renderer_PresentVSync; 262 renderer->info.flags |= SDL_Renderer_PresentVSync;
225 } 263 }
226 264
227 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &renderer->info.max_texture_width); 265 data->glGetIntegerv(GL_MAX_TEXTURE_SIZE,
228 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &renderer->info.max_texture_height); 266 &renderer->info.max_texture_width);
267 data->glGetIntegerv(GL_MAX_TEXTURE_SIZE,
268 &renderer->info.max_texture_height);
229 269
230 if (SDL_GL_ExtensionSupported("GL_ARB_texture_rectangle") 270 if (SDL_GL_ExtensionSupported("GL_ARB_texture_rectangle")
231 || SDL_GL_ExtensionSupported("GL_EXT_texture_rectangle")) { 271 || SDL_GL_ExtensionSupported("GL_EXT_texture_rectangle")) {
232 data->GL_ARB_texture_rectangle_supported = SDL_TRUE; 272 data->GL_ARB_texture_rectangle_supported = SDL_TRUE;
233 } 273 }
234 274
235 /* Set up parameters for rendering */ 275 /* Set up parameters for rendering */
236 glDisable(GL_DEPTH_TEST); 276 data->blendMode = -1;
237 glDisable(GL_CULL_FACE); 277 data->scaleMode = -1;
278 data->glDisable(GL_DEPTH_TEST);
279 data->glDisable(GL_CULL_FACE);
238 if (data->GL_ARB_texture_rectangle_supported) { 280 if (data->GL_ARB_texture_rectangle_supported) {
239 glEnable(GL_TEXTURE_RECTANGLE_ARB); 281 data->glEnable(GL_TEXTURE_RECTANGLE_ARB);
240 } else { 282 } else {
241 glEnable(GL_TEXTURE_2D); 283 data->glEnable(GL_TEXTURE_2D);
242 } 284 }
243 glMatrixMode(GL_PROJECTION); 285 data->glMatrixMode(GL_PROJECTION);
244 glLoadIdentity(); 286 data->glLoadIdentity();
245 glMatrixMode(GL_MODELVIEW); 287 data->glMatrixMode(GL_MODELVIEW);
246 glLoadIdentity(); 288 data->glLoadIdentity();
247 glViewport(0, 0, window->w, window->h); 289 data->glViewport(0, 0, window->w, window->h);
248 glOrtho(0.0, (GLdouble) window->w, (GLdouble) window->h, 0.0, 0.0, 1.0); 290 data->glOrtho(0.0, (GLdouble) window->w, (GLdouble) window->h, 0.0, 0.0,
291 1.0);
249 292
250 return renderer; 293 return renderer;
251 } 294 }
252 295
253 static int 296 static int
369 return -1; 412 return -1;
370 } 413 }
371 414
372 texture->driverdata = data; 415 texture->driverdata = data;
373 416
374 glGetError(); 417 renderdata->glGetError();
375 glGenTextures(1, &data->texture); 418 renderdata->glGenTextures(1, &data->texture);
376 if (renderdata->GL_ARB_texture_rectangle_supported) { 419 if (renderdata->GL_ARB_texture_rectangle_supported) {
377 data->type = GL_TEXTURE_RECTANGLE_ARB; 420 data->type = GL_TEXTURE_RECTANGLE_ARB;
378 texture_w = texture->w; 421 texture_w = texture->w;
379 texture_h = texture->h; 422 texture_h = texture->h;
380 data->texw = (GLfloat) texture->w; 423 data->texw = (GLfloat) texture->w;
386 data->texw = (GLfloat) texture->w / texture_w; 429 data->texw = (GLfloat) texture->w / texture_w;
387 data->texh = (GLfloat) texture->h / texture_h; 430 data->texh = (GLfloat) texture->h / texture_h;
388 } 431 }
389 data->format = format; 432 data->format = format;
390 data->formattype = type; 433 data->formattype = type;
391 glBindTexture(data->type, data->texture); 434 renderdata->glBindTexture(data->type, data->texture);
392 glTexImage2D(data->type, 0, internalFormat, texture_w, texture_h, 0, 435 renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
393 format, type, NULL); 436 texture_h, 0, format, type, NULL);
394 result = glGetError(); 437 result = renderdata->glGetError();
395 if (result != GL_NO_ERROR) { 438 if (result != GL_NO_ERROR) {
396 GL_SetError("glTexImage2D()", result); 439 GL_SetError("glTexImage2D()", result);
397 return -1; 440 return -1;
398 } 441 }
399 return 0; 442 return 0;
417 460
418 return 0; 461 return 0;
419 } 462 }
420 463
421 static void 464 static void
422 SetupTextureUpdate(SDL_Texture * texture, int pitch) 465 SetupTextureUpdate(GL_RenderData * renderdata, SDL_Texture * texture,
466 int pitch)
423 { 467 {
424 if (texture->format == SDL_PixelFormat_Index1LSB) { 468 if (texture->format == SDL_PixelFormat_Index1LSB) {
425 glPixelStorei(GL_UNPACK_LSB_FIRST, 1); 469 renderdata->glPixelStorei(GL_UNPACK_LSB_FIRST, 1);
426 } else if (texture->format == SDL_PixelFormat_Index1MSB) { 470 } else if (texture->format == SDL_PixelFormat_Index1MSB) {
427 glPixelStorei(GL_UNPACK_LSB_FIRST, 0); 471 renderdata->glPixelStorei(GL_UNPACK_LSB_FIRST, 0);
428 } 472 }
429 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 473 renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
430 glPixelStorei(GL_UNPACK_ROW_LENGTH, 474 renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH,
431 pitch / SDL_BYTESPERPIXEL(texture->format)); 475 pitch / SDL_BYTESPERPIXEL(texture->format));
432 } 476 }
433 477
434 static int 478 static int
435 GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, 479 GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
436 const SDL_Rect * rect, const void *pixels, int pitch) 480 const SDL_Rect * rect, const void *pixels, int pitch)
437 { 481 {
482 GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
438 GL_TextureData *data = (GL_TextureData *) texture->driverdata; 483 GL_TextureData *data = (GL_TextureData *) texture->driverdata;
439 GLenum result; 484 GLenum result;
440 485
441 glGetError(); 486 renderdata->glGetError();
442 SetupTextureUpdate(texture, pitch); 487 SetupTextureUpdate(renderdata, texture, pitch);
443 glBindTexture(data->type, data->texture); 488 renderdata->glBindTexture(data->type, data->texture);
444 glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w, rect->h, 489 renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
445 data->format, data->formattype, pixels); 490 rect->h, data->format, data->formattype,
446 result = glGetError(); 491 pixels);
492 result = renderdata->glGetError();
447 if (result != GL_NO_ERROR) { 493 if (result != GL_NO_ERROR) {
448 GL_SetError("glTexSubImage2D()", result); 494 GL_SetError("glTexSubImage2D()", result);
449 return -1; 495 return -1;
450 } 496 }
451 return 0; 497 return 0;
505 a = ((GLclampf) ((color >> 24) & 0xFF)) / 255.0f; 551 a = ((GLclampf) ((color >> 24) & 0xFF)) / 255.0f;
506 r = ((GLclampf) ((color >> 16) & 0xFF)) / 255.0f; 552 r = ((GLclampf) ((color >> 16) & 0xFF)) / 255.0f;
507 g = ((GLclampf) ((color >> 8) & 0xFF)) / 255.0f; 553 g = ((GLclampf) ((color >> 8) & 0xFF)) / 255.0f;
508 b = ((GLclampf) (color & 0xFF)) / 255.0f; 554 b = ((GLclampf) (color & 0xFF)) / 255.0f;
509 555
510 glClearColor(r, g, b, a); 556 data->glClearColor(r, g, b, a);
511 glViewport(rect->x, window->h - rect->y, rect->w, rect->h); 557 data->glViewport(rect->x, window->h - rect->y, rect->w, rect->h);
512 glClear(GL_COLOR_BUFFER_BIT); 558 data->glClear(GL_COLOR_BUFFER_BIT);
513 glViewport(0, 0, window->w, window->h); 559 data->glViewport(0, 0, window->w, window->h);
514 return 0; 560 return 0;
515 } 561 }
516 562
517 static int 563 static int
518 GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, 564 GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
528 SDL_DirtyRect *dirty; 574 SDL_DirtyRect *dirty;
529 void *pixels; 575 void *pixels;
530 int bpp = SDL_BYTESPERPIXEL(texture->format); 576 int bpp = SDL_BYTESPERPIXEL(texture->format);
531 int pitch = texturedata->pitch; 577 int pitch = texturedata->pitch;
532 578
533 SetupTextureUpdate(texture, pitch); 579 SetupTextureUpdate(data, texture, pitch);
534 glBindTexture(texturedata->type, texturedata->texture); 580 data->glBindTexture(texturedata->type, texturedata->texture);
535 for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) { 581 for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) {
536 SDL_Rect *rect = &dirty->rect; 582 SDL_Rect *rect = &dirty->rect;
537 pixels = 583 pixels =
538 (void *) ((Uint8 *) texturedata->pixels + rect->y * pitch + 584 (void *) ((Uint8 *) texturedata->pixels + rect->y * pitch +
539 rect->x * bpp); 585 rect->x * bpp);
540 glTexSubImage2D(texturedata->type, 0, rect->x, rect->y, rect->w, 586 data->glTexSubImage2D(texturedata->type, 0, rect->x, rect->y,
541 rect->h, texturedata->format, 587 rect->w, rect->h, texturedata->format,
542 texturedata->formattype, pixels); 588 texturedata->formattype, pixels);
543 } 589 }
544 SDL_ClearDirtyRects(&texturedata->dirty); 590 SDL_ClearDirtyRects(&texturedata->dirty);
545 } 591 }
546 592
547 minx = dstrect->x; 593 minx = dstrect->x;
556 minv = (GLfloat) srcrect->y / texture->h; 602 minv = (GLfloat) srcrect->y / texture->h;
557 minv *= texturedata->texh; 603 minv *= texturedata->texh;
558 maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h; 604 maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
559 maxv *= texturedata->texh; 605 maxv *= texturedata->texh;
560 606
561 glBindTexture(texturedata->type, texturedata->texture); 607 data->glBindTexture(texturedata->type, texturedata->texture);
562 608
563 switch (blendMode) { 609 if (blendMode != data->blendMode) {
564 case SDL_TextureBlendMode_None: 610 switch (blendMode) {
565 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); 611 case SDL_TextureBlendMode_None:
566 glDisable(GL_BLEND); 612 data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
567 break; 613 data->glDisable(GL_BLEND);
568 case SDL_TextureBlendMode_Mask: 614 break;
569 case SDL_TextureBlendMode_Blend: 615 case SDL_TextureBlendMode_Mask:
570 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 616 case SDL_TextureBlendMode_Blend:
571 glEnable(GL_BLEND); 617 data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
572 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 618 data->glEnable(GL_BLEND);
573 break; 619 data->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
574 case SDL_TextureBlendMode_Add: 620 break;
575 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 621 case SDL_TextureBlendMode_Add:
576 glEnable(GL_BLEND); 622 data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
577 glBlendFunc(GL_SRC_ALPHA, GL_ONE); 623 data->glEnable(GL_BLEND);
578 break; 624 data->glBlendFunc(GL_SRC_ALPHA, GL_ONE);
579 case SDL_TextureBlendMode_Mod: 625 break;
580 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 626 case SDL_TextureBlendMode_Mod:
581 glEnable(GL_BLEND); 627 data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
582 glBlendFunc(GL_ZERO, GL_SRC_COLOR); 628 data->glEnable(GL_BLEND);
583 break; 629 data->glBlendFunc(GL_ZERO, GL_SRC_COLOR);
584 } 630 break;
585 631 }
586 switch (scaleMode) { 632 data->blendMode = blendMode;
587 case SDL_TextureScaleMode_None: 633 }
588 case SDL_TextureScaleMode_Fast: 634
589 glTexParameteri(texturedata->type, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 635 if (scaleMode != data->scaleMode) {
590 glTexParameteri(texturedata->type, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 636 switch (scaleMode) {
591 break; 637 case SDL_TextureScaleMode_None:
592 case SDL_TextureScaleMode_Slow: 638 case SDL_TextureScaleMode_Fast:
593 case SDL_TextureScaleMode_Best: 639 data->glTexParameteri(texturedata->type, GL_TEXTURE_MIN_FILTER,
594 glTexParameteri(texturedata->type, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 640 GL_NEAREST);
595 glTexParameteri(texturedata->type, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 641 data->glTexParameteri(texturedata->type, GL_TEXTURE_MAG_FILTER,
596 break; 642 GL_NEAREST);
597 } 643 break;
598 644 case SDL_TextureScaleMode_Slow:
599 glBegin(GL_TRIANGLE_STRIP); 645 case SDL_TextureScaleMode_Best:
600 glTexCoord2f(minu, minv); 646 data->glTexParameteri(texturedata->type, GL_TEXTURE_MIN_FILTER,
601 glVertex2i(minx, miny); 647 GL_LINEAR);
602 glTexCoord2f(maxu, minv); 648 data->glTexParameteri(texturedata->type, GL_TEXTURE_MAG_FILTER,
603 glVertex2i(maxx, miny); 649 GL_LINEAR);
604 glTexCoord2f(minu, maxv); 650 break;
605 glVertex2i(minx, maxy); 651 }
606 glTexCoord2f(maxu, maxv); 652 data->scaleMode = scaleMode;
607 glVertex2i(maxx, maxy); 653 }
608 glEnd(); 654
655 data->glBegin(GL_TRIANGLE_STRIP);
656 data->glTexCoord2f(minu, minv);
657 data->glVertex2i(minx, miny);
658 data->glTexCoord2f(maxu, minv);
659 data->glVertex2i(maxx, miny);
660 data->glTexCoord2f(minu, maxv);
661 data->glVertex2i(minx, maxy);
662 data->glTexCoord2f(maxu, maxv);
663 data->glVertex2i(maxx, maxy);
664 data->glEnd();
609 665
610 return 0; 666 return 0;
611 } 667 }
612 668
613 static void 669 static void
617 } 673 }
618 674
619 static void 675 static void
620 GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) 676 GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
621 { 677 {
678 GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
622 GL_TextureData *data = (GL_TextureData *) texture->driverdata; 679 GL_TextureData *data = (GL_TextureData *) texture->driverdata;
623 680
624 if (!data) { 681 if (!data) {
625 return; 682 return;
626 } 683 }
627 if (data->texture) { 684 if (data->texture) {
628 glDeleteTextures(1, &data->texture); 685 renderdata->glDeleteTextures(1, &data->texture);
629 } 686 }
630 if (data->pixels) { 687 if (data->pixels) {
631 SDL_free(data->pixels); 688 SDL_free(data->pixels);
632 } 689 }
633 SDL_FreeDirtyRects(&data->dirty); 690 SDL_FreeDirtyRects(&data->dirty);