SDL_gpu  0.11.0
A hardware-accelerated, cross-platform 2D graphics API
SDL_gpu.c
Go to the documentation of this file.
1 #include "SDL_gpu.h"
2 #include "SDL_gpu_RendererImpl.h"
3 #include "SDL_platform.h"
4 #include "stb_image.h"
5 #include "stb_image_write.h"
6 #include <stdlib.h>
7 #include <string.h>
8 
9 #ifdef __ANDROID__
10 #include <android/log.h>
11 #endif
12 
13 #ifdef _MSC_VER
14  #define __func__ __FUNCTION__
15  #pragma warning(push)
16  // Visual Studio wants to complain about while(0)
17  #pragma warning(disable: 4127)
18 #endif
19 
20 #include "stb_image.h"
21 
22 #ifdef SDL_GPU_USE_SDL2
23  #define GET_ALPHA(sdl_color) ((sdl_color).a)
24 #else
25  #define GET_ALPHA(sdl_color) ((sdl_color).unused)
26 #endif
27 
28 #define CHECK_RENDERER (_gpu_current_renderer != NULL)
29 #define MAKE_CURRENT_IF_NONE(target) do{ if(_gpu_current_renderer->current_context_target == NULL && target != NULL && target->context != NULL) GPU_MakeCurrent(target, target->context->windowID); } while(0)
30 #define CHECK_CONTEXT (_gpu_current_renderer->current_context_target != NULL)
31 #define RETURN_ERROR(code, details) do{ GPU_PushErrorCode(__func__, code, "%s", details); return; } while(0)
32 
33 int gpu_strcasecmp(const char* s1, const char* s2);
34 
38 
39 int gpu_default_print(GPU_LogLevelEnum log_level, const char* format, va_list args);
40 
42 typedef struct GPU_WindowMapping
43 {
44  Uint32 windowID;
47 
48 static GPU_Renderer* _gpu_current_renderer = NULL;
49 
50 static GPU_DebugLevelEnum _gpu_debug_level = GPU_DEBUG_LEVEL_0;
51 
52 #define GPU_DEFAULT_MAX_NUM_ERRORS 20
53 #define GPU_ERROR_FUNCTION_STRING_MAX 128
54 #define GPU_ERROR_DETAILS_STRING_MAX 512
55 static GPU_ErrorObject* _gpu_error_code_queue = NULL;
56 static unsigned int _gpu_num_error_codes = 0;
57 static unsigned int _gpu_error_code_queue_size = GPU_DEFAULT_MAX_NUM_ERRORS;
58 static GPU_ErrorObject _gpu_error_code_result;
59 
60 #define GPU_INITIAL_WINDOW_MAPPINGS_SIZE 10
61 static GPU_WindowMapping* _gpu_window_mappings = NULL;
62 static int _gpu_window_mappings_size = 0;
63 static int _gpu_num_window_mappings = 0;
64 
65 static Uint32 _gpu_init_windowID = 0;
66 
67 static GPU_InitFlagEnum _gpu_preinit_flags = GPU_DEFAULT_INIT_FLAGS;
68 static GPU_InitFlagEnum _gpu_required_features = 0;
69 
70 static GPU_bool _gpu_initialized_SDL_core = GPU_FALSE;
71 static GPU_bool _gpu_initialized_SDL = GPU_FALSE;
72 
73 static int (*_gpu_print)(GPU_LogLevelEnum log_level, const char* format, va_list args) = &gpu_default_print;
74 
75 
76 SDL_version GPU_GetLinkedVersion(void)
77 {
78  return GPU_GetCompiledVersion();
79 }
80 
82 {
83  _gpu_current_renderer = GPU_GetRenderer(id);
84 
85  if(_gpu_current_renderer != NULL)
86  _gpu_current_renderer->impl->SetAsCurrent(_gpu_current_renderer);
87 }
88 
90 {
91  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
92  return;
93 
94  _gpu_current_renderer->impl->ResetRendererState(_gpu_current_renderer);
95 }
96 
97 void GPU_SetCoordinateMode(GPU_bool use_math_coords)
98 {
99  if(_gpu_current_renderer == NULL)
100  return;
101 
102  _gpu_current_renderer->coordinate_mode = use_math_coords;
103 }
104 
106 {
107  if(_gpu_current_renderer == NULL)
108  return GPU_FALSE;
109 
110  return _gpu_current_renderer->coordinate_mode;
111 }
112 
114 {
115  return _gpu_current_renderer;
116 }
117 
119 {
120  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
121  return 0;
122 
123  return _gpu_current_renderer->current_context_target->context->current_shader_program;
124 }
125 
126 
127 int gpu_default_print(GPU_LogLevelEnum log_level, const char* format, va_list args)
128 {
129  switch(log_level)
130  {
131 #ifdef __ANDROID__
132  case GPU_LOG_INFO:
133  return __android_log_vprint((GPU_GetDebugLevel() >= GPU_DEBUG_LEVEL_3? ANDROID_LOG_ERROR : ANDROID_LOG_INFO), "APPLICATION", format, args);
134  case GPU_LOG_WARNING:
135  return __android_log_vprint((GPU_GetDebugLevel() >= GPU_DEBUG_LEVEL_2? ANDROID_LOG_ERROR : ANDROID_LOG_WARN), "APPLICATION", format, args);
136  case GPU_LOG_ERROR:
137  return __android_log_vprint(ANDROID_LOG_ERROR, "APPLICATION", format, args);
138 #else
139  case GPU_LOG_INFO:
140  return vfprintf((GPU_GetDebugLevel() >= GPU_DEBUG_LEVEL_3? stderr : stdout), format, args);
141  case GPU_LOG_WARNING:
142  return vfprintf((GPU_GetDebugLevel() >= GPU_DEBUG_LEVEL_2? stderr : stdout), format, args);
143  case GPU_LOG_ERROR:
144  return vfprintf(stderr, format, args);
145 #endif
146  default:
147  return 0;
148  }
149 }
150 
151 void GPU_SetLogCallback(int (*callback)(GPU_LogLevelEnum log_level, const char* format, va_list args))
152 {
153  if(callback == NULL)
154  _gpu_print = &gpu_default_print;
155  else
156  _gpu_print = callback;
157 }
158 
159 void GPU_LogInfo(const char* format, ...)
160 {
161  va_list args;
162  va_start(args, format);
163  _gpu_print(GPU_LOG_INFO, format, args);
164  va_end(args);
165 }
166 
167 void GPU_LogWarning(const char* format, ...)
168 {
169  va_list args;
170  va_start(args, format);
171  _gpu_print(GPU_LOG_WARNING, format, args);
172  va_end(args);
173 }
174 
175 void GPU_LogError(const char* format, ...)
176 {
177  va_list args;
178  va_start(args, format);
179  _gpu_print(GPU_LOG_ERROR, format, args);
180  va_end(args);
181 }
182 
183 
184 static GPU_bool gpu_init_SDL(void)
185 {
186  if(!_gpu_initialized_SDL)
187  {
188  if(!_gpu_initialized_SDL_core && !SDL_WasInit(SDL_INIT_EVERYTHING))
189  {
190  // Nothing has been set up, so init SDL and the video subsystem.
191  if(SDL_Init(SDL_INIT_VIDEO) < 0)
192  {
193  GPU_PushErrorCode("GPU_Init", GPU_ERROR_BACKEND_ERROR, "Failed to initialize SDL video subsystem");
194  return GPU_FALSE;
195  }
196  _gpu_initialized_SDL_core = GPU_TRUE;
197  }
198 
199  // SDL is definitely ready now, but we're going to init the video subsystem to be sure that SDL_gpu keeps it available until GPU_Quit().
200  if(SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
201  {
202  GPU_PushErrorCode("GPU_Init", GPU_ERROR_BACKEND_ERROR, "Failed to initialize SDL video subsystem");
203  return GPU_FALSE;
204  }
205  _gpu_initialized_SDL = GPU_TRUE;
206  }
207  return GPU_TRUE;
208 }
209 
211 {
212  _gpu_init_windowID = windowID;
213 }
214 
215 Uint32 GPU_GetInitWindow(void)
216 {
217  return _gpu_init_windowID;
218 }
219 
221 {
222  _gpu_preinit_flags = GPU_flags;
223 }
224 
226 {
227  return _gpu_preinit_flags;
228 }
229 
231 {
232  _gpu_required_features = features;
233 }
234 
236 {
237  return _gpu_required_features;
238 }
239 
240 static void gpu_init_error_queue(void)
241 {
242  if(_gpu_error_code_queue == NULL)
243  {
244  unsigned int i;
245  _gpu_error_code_queue = (GPU_ErrorObject*)SDL_malloc(sizeof(GPU_ErrorObject)*_gpu_error_code_queue_size);
246 
247  for(i = 0; i < _gpu_error_code_queue_size; i++)
248  {
249  _gpu_error_code_queue[i].function = (char*)SDL_malloc(GPU_ERROR_FUNCTION_STRING_MAX+1);
250  _gpu_error_code_queue[i].error = GPU_ERROR_NONE;
251  _gpu_error_code_queue[i].details = (char*)SDL_malloc(GPU_ERROR_DETAILS_STRING_MAX+1);
252  }
253  _gpu_num_error_codes = 0;
254 
255  _gpu_error_code_result.function = (char*)SDL_malloc(GPU_ERROR_FUNCTION_STRING_MAX+1);
256  _gpu_error_code_result.error = GPU_ERROR_NONE;
257  _gpu_error_code_result.details = (char*)SDL_malloc(GPU_ERROR_DETAILS_STRING_MAX+1);
258  }
259 }
260 
261 static void gpu_init_window_mappings(void)
262 {
263  if(_gpu_window_mappings == NULL)
264  {
265  _gpu_window_mappings_size = GPU_INITIAL_WINDOW_MAPPINGS_SIZE;
266  _gpu_window_mappings = (GPU_WindowMapping*)SDL_malloc(_gpu_window_mappings_size * sizeof(GPU_WindowMapping));
267  _gpu_num_window_mappings = 0;
268  }
269 }
270 
272 {
273  Uint32 windowID;
274  int i;
275 
276  if(_gpu_window_mappings == NULL)
277  gpu_init_window_mappings();
278 
279  if(target == NULL || target->context == NULL)
280  return;
281 
282  windowID = target->context->windowID;
283  if(windowID == 0) // Invalid window ID
284  return;
285 
286  // Check for duplicates
287  for(i = 0; i < _gpu_num_window_mappings; i++)
288  {
289  if(_gpu_window_mappings[i].windowID == windowID)
290  {
291  if(_gpu_window_mappings[i].target != target)
292  GPU_PushErrorCode(__func__, GPU_ERROR_DATA_ERROR, "WindowID %u already has a mapping.", windowID);
293  return;
294  }
295  // Don't check the target because it's okay for a single target to be used with multiple windows
296  }
297 
298  // Check if list is big enough to hold another
299  if(_gpu_num_window_mappings >= _gpu_window_mappings_size)
300  {
301  GPU_WindowMapping* new_array;
302  _gpu_window_mappings_size *= 2;
303  new_array = (GPU_WindowMapping*)SDL_malloc(_gpu_window_mappings_size * sizeof(GPU_WindowMapping));
304  memcpy(new_array, _gpu_window_mappings, _gpu_num_window_mappings * sizeof(GPU_WindowMapping));
305  SDL_free(_gpu_window_mappings);
306  _gpu_window_mappings = new_array;
307  }
308 
309  // Add to end of list
310  {
312  m.windowID = windowID;
313  m.target = target;
314  _gpu_window_mappings[_gpu_num_window_mappings] = m;
315  }
316  _gpu_num_window_mappings++;
317 }
318 
320 {
321  int i;
322 
323  if(_gpu_window_mappings == NULL)
324  gpu_init_window_mappings();
325 
326  if(windowID == 0) // Invalid window ID
327  return;
328 
329  // Find the occurrence
330  for(i = 0; i < _gpu_num_window_mappings; i++)
331  {
332  if(_gpu_window_mappings[i].windowID == windowID)
333  {
334  int num_to_move;
335 
336  // Unset the target's window
337  _gpu_window_mappings[i].target->context->windowID = 0;
338 
339  // Move the remaining entries to replace the removed one
340  _gpu_num_window_mappings--;
341  num_to_move = _gpu_num_window_mappings - i;
342  if(num_to_move > 0)
343  memmove(&_gpu_window_mappings[i], &_gpu_window_mappings[i+1], num_to_move * sizeof(GPU_WindowMapping));
344  return;
345  }
346  }
347 
348 }
349 
351 {
352  Uint32 windowID;
353  int i;
354 
355  if(_gpu_window_mappings == NULL)
356  gpu_init_window_mappings();
357 
358  if(target == NULL || target->context == NULL)
359  return;
360 
361  windowID = target->context->windowID;
362  if(windowID == 0) // Invalid window ID
363  return;
364 
365  // Unset the target's window
366  target->context->windowID = 0;
367 
368  // Find the occurrences
369  for(i = 0; i < _gpu_num_window_mappings; ++i)
370  {
371  if(_gpu_window_mappings[i].target == target)
372  {
373  // Move the remaining entries to replace the removed one
374  int num_to_move;
375  _gpu_num_window_mappings--;
376  num_to_move = _gpu_num_window_mappings - i;
377  if(num_to_move > 0)
378  memmove(&_gpu_window_mappings[i], &_gpu_window_mappings[i+1], num_to_move * sizeof(GPU_WindowMapping));
379  return;
380  }
381  }
382 
383 }
384 
386 {
387  int i;
388 
389  if(_gpu_window_mappings == NULL)
390  gpu_init_window_mappings();
391 
392  if(windowID == 0) // Invalid window ID
393  return NULL;
394 
395  // Find the occurrence
396  for(i = 0; i < _gpu_num_window_mappings; ++i)
397  {
398  if(_gpu_window_mappings[i].windowID == windowID)
399  return _gpu_window_mappings[i].target;
400  }
401 
402  return NULL;
403 }
404 
405 GPU_Target* GPU_Init(Uint16 w, Uint16 h, GPU_WindowFlagEnum SDL_flags)
406 {
407  int renderer_order_size;
408  int i;
409  GPU_RendererID renderer_order[GPU_RENDERER_ORDER_MAX];
410 
411  gpu_init_error_queue();
412 
414 
415  if(!gpu_init_SDL())
416  return NULL;
417 
418  renderer_order_size = 0;
419  GPU_GetRendererOrder(&renderer_order_size, renderer_order);
420 
421  // Init the renderers in order
422  for(i = 0; i < renderer_order_size; i++)
423  {
424  GPU_Target* screen = GPU_InitRendererByID(renderer_order[i], w, h, SDL_flags);
425  if(screen != NULL)
426  return screen;
427  }
428 
429  GPU_PushErrorCode("GPU_Init", GPU_ERROR_BACKEND_ERROR, "No renderer out of %d was able to initialize properly", renderer_order_size);
430  return NULL;
431 }
432 
433 GPU_Target* GPU_InitRenderer(GPU_RendererEnum renderer_enum, Uint16 w, Uint16 h, GPU_WindowFlagEnum SDL_flags)
434 {
435  // Search registry for this renderer and use that id
436  return GPU_InitRendererByID(GPU_GetRendererID(renderer_enum), w, h, SDL_flags);
437 }
438 
439 GPU_Target* GPU_InitRendererByID(GPU_RendererID renderer_request, Uint16 w, Uint16 h, GPU_WindowFlagEnum SDL_flags)
440 {
441  GPU_Renderer* renderer;
442  GPU_Target* screen;
443 
444  gpu_init_error_queue();
446 
447  if(!gpu_init_SDL())
448  return NULL;
449 
450  renderer = gpu_create_and_add_renderer(renderer_request);
451  if(renderer == NULL)
452  return NULL;
453 
454  GPU_SetCurrentRenderer(renderer->id);
455 
456  screen = renderer->impl->Init(renderer, renderer_request, w, h, SDL_flags);
457  if(screen == NULL)
458  {
459  GPU_PushErrorCode("GPU_InitRendererByID", GPU_ERROR_BACKEND_ERROR, "Renderer %s failed to initialize properly", renderer->id.name);
460  // Init failed, destroy the renderer...
461  // Erase the window mappings
462  _gpu_num_window_mappings = 0;
464  }
465  else
467  return screen;
468 }
469 
471 {
472  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
473  return GPU_FALSE;
474 
475  return ((_gpu_current_renderer->enabled_features & feature) == feature);
476 }
477 
479 {
480  if(_gpu_current_renderer == NULL)
481  return NULL;
482 
483  return _gpu_current_renderer->impl->CreateTargetFromWindow(_gpu_current_renderer, windowID, NULL);
484 }
485 
487 {
488  if(!CHECK_RENDERER)
489  return NULL;
490  MAKE_CURRENT_IF_NONE(target);
491  if(!CHECK_CONTEXT)
492  return NULL;
493 
494  return _gpu_current_renderer->impl->CreateAliasTarget(_gpu_current_renderer, target);
495 }
496 
498 {
499  if(_gpu_current_renderer == NULL)
500  return;
501 
502  _gpu_current_renderer->impl->MakeCurrent(_gpu_current_renderer, target, windowID);
503 }
504 
505 GPU_bool GPU_SetFullscreen(GPU_bool enable_fullscreen, GPU_bool use_desktop_resolution)
506 {
507  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
508  return GPU_FALSE;
509 
510  return _gpu_current_renderer->impl->SetFullscreen(_gpu_current_renderer, enable_fullscreen, use_desktop_resolution);
511 }
512 
514 {
515 #ifdef SDL_GPU_USE_SDL2
517  if(target == NULL)
518  return GPU_FALSE;
519  return (SDL_GetWindowFlags(SDL_GetWindowFromID(target->context->windowID))
520  & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_FULLSCREEN_DESKTOP)) != 0;
521 #else
522  SDL_Surface* surf = SDL_GetVideoSurface();
523  if(surf == NULL)
524  return GPU_FALSE;
525  return (surf->flags & SDL_FULLSCREEN) != 0;
526 #endif
527 }
528 
530 {
531  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL || w == 0 || h == 0)
532  return GPU_FALSE;
533 
534  return _gpu_current_renderer->impl->SetWindowResolution(_gpu_current_renderer, w, h);
535 }
536 
537 
538 void GPU_GetVirtualResolution(GPU_Target* target, Uint16* w, Uint16* h)
539 {
540  // No checking here for NULL w or h... Should we?
541  if (target == NULL)
542  {
543  *w = 0;
544  *h = 0;
545  }
546  else {
547  *w = target->w;
548  *h = target->h;
549  }
550 }
551 
552 void GPU_SetVirtualResolution(GPU_Target* target, Uint16 w, Uint16 h)
553 {
554  if(!CHECK_RENDERER)
555  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
556  MAKE_CURRENT_IF_NONE(target);
557  if(!CHECK_CONTEXT)
558  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
559  if(w == 0 || h == 0)
560  return;
561 
562  _gpu_current_renderer->impl->SetVirtualResolution(_gpu_current_renderer, target, w, h);
563 }
564 
566 {
567  if(!CHECK_RENDERER)
568  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
569  MAKE_CURRENT_IF_NONE(target);
570  if(!CHECK_CONTEXT)
571  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
572 
573  _gpu_current_renderer->impl->UnsetVirtualResolution(_gpu_current_renderer, target);
574 }
575 
576 void GPU_SetImageVirtualResolution(GPU_Image* image, Uint16 w, Uint16 h)
577 {
578  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL || w == 0 || h == 0)
579  return;
580 
581  if(image == NULL)
582  return;
583 
584  image->w = w;
585  image->h = h;
586  image->using_virtual_resolution = 1;
587 }
588 
590 {
591  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
592  return;
593 
594  if(image == NULL)
595  return;
596 
597  image->w = image->base_w;
598  image->h = image->base_h;
599  image->using_virtual_resolution = 0;
600 }
601 
603 {
604  unsigned int i;
605  // Free the error queue
606  for(i = 0; i < _gpu_error_code_queue_size; i++)
607  {
608  SDL_free(_gpu_error_code_queue[i].function);
609  _gpu_error_code_queue[i].function = NULL;
610  SDL_free(_gpu_error_code_queue[i].details);
611  _gpu_error_code_queue[i].details = NULL;
612  }
613  SDL_free(_gpu_error_code_queue);
614  _gpu_error_code_queue = NULL;
615  _gpu_num_error_codes = 0;
616 
617  SDL_free(_gpu_error_code_result.function);
618  _gpu_error_code_result.function = NULL;
619  SDL_free(_gpu_error_code_result.details);
620  _gpu_error_code_result.details = NULL;
621 }
622 
623 // Deletes all existing errors
624 void GPU_SetErrorQueueMax(unsigned int max)
625 {
627 
628  // Reallocate with new size
629  _gpu_error_code_queue_size = max;
630  gpu_init_error_queue();
631 }
632 
634 {
635  if(_gpu_current_renderer == NULL)
636  return;
637 
638  _gpu_current_renderer->impl->Quit(_gpu_current_renderer);
639  GPU_FreeRenderer(_gpu_current_renderer);
640 }
641 
642 void GPU_Quit(void)
643 {
644  if(_gpu_num_error_codes > 0 && GPU_GetDebugLevel() >= GPU_DEBUG_LEVEL_1)
645  GPU_LogError("GPU_Quit: %d uncleared error%s.\n", _gpu_num_error_codes, (_gpu_num_error_codes > 1? "s" : ""));
646 
648 
649  if(_gpu_current_renderer == NULL)
650  return;
651 
652  _gpu_current_renderer->impl->Quit(_gpu_current_renderer);
653  GPU_FreeRenderer(_gpu_current_renderer);
654  // FIXME: Free all renderers
655  _gpu_current_renderer = NULL;
656 
657  _gpu_init_windowID = 0;
658 
659  // Free window mappings
660  SDL_free(_gpu_window_mappings);
661  _gpu_window_mappings = NULL;
662  _gpu_window_mappings_size = 0;
663  _gpu_num_window_mappings = 0;
664 
666 
667  if(_gpu_initialized_SDL)
668  {
669  SDL_QuitSubSystem(SDL_INIT_VIDEO);
670  _gpu_initialized_SDL = 0;
671 
672  if(_gpu_initialized_SDL_core)
673  {
674  SDL_Quit();
675  _gpu_initialized_SDL_core = 0;
676  }
677  }
678 }
679 
681 {
682  if(level > GPU_DEBUG_LEVEL_MAX)
683  level = GPU_DEBUG_LEVEL_MAX;
684  _gpu_debug_level = level;
685 }
686 
688 {
689  return _gpu_debug_level;
690 }
691 
692 void GPU_PushErrorCode(const char* function, GPU_ErrorEnum error, const char* details, ...)
693 {
694  gpu_init_error_queue();
695 
697  {
698  // Print the message
699  if(details != NULL)
700  {
702  va_list lst;
703  va_start(lst, details);
704  vsnprintf(buf, GPU_ERROR_DETAILS_STRING_MAX, details, lst);
705  va_end(lst);
706 
707  GPU_LogError("%s: %s - %s\n", (function == NULL? "NULL" : function), GPU_GetErrorString(error), buf);
708  }
709  else
710  GPU_LogError("%s: %s\n", (function == NULL? "NULL" : function), GPU_GetErrorString(error));
711  }
712 
713  if(_gpu_num_error_codes < _gpu_error_code_queue_size)
714  {
715  if(function == NULL)
716  _gpu_error_code_queue[_gpu_num_error_codes].function[0] = '\0';
717  else
718  {
719  strncpy(_gpu_error_code_queue[_gpu_num_error_codes].function, function, GPU_ERROR_FUNCTION_STRING_MAX);
720  _gpu_error_code_queue[_gpu_num_error_codes].function[GPU_ERROR_FUNCTION_STRING_MAX] = '\0';
721  }
722  _gpu_error_code_queue[_gpu_num_error_codes].error = error;
723  if(details == NULL)
724  _gpu_error_code_queue[_gpu_num_error_codes].details[0] = '\0';
725  else
726  {
727  va_list lst;
728  va_start(lst, details);
729  vsnprintf(_gpu_error_code_queue[_gpu_num_error_codes].details, GPU_ERROR_DETAILS_STRING_MAX, details, lst);
730  va_end(lst);
731  }
732  _gpu_num_error_codes++;
733  }
734 }
735 
737 {
738  unsigned int i;
739  GPU_ErrorObject result = {NULL, GPU_ERROR_NONE, NULL};
740 
741  gpu_init_error_queue();
742 
743  if(_gpu_num_error_codes <= 0)
744  return result;
745 
746  // Pop the oldest
747  strcpy(_gpu_error_code_result.function, _gpu_error_code_queue[0].function);
748  _gpu_error_code_result.error = _gpu_error_code_queue[0].error;
749  strcpy(_gpu_error_code_result.details, _gpu_error_code_queue[0].details);
750 
751  // We'll be returning that one
752  result = _gpu_error_code_result;
753 
754  // Move the rest down
755  _gpu_num_error_codes--;
756  for(i = 0; i < _gpu_num_error_codes; i++)
757  {
758  strcpy(_gpu_error_code_queue[i].function, _gpu_error_code_queue[i+1].function);
759  _gpu_error_code_queue[i].error = _gpu_error_code_queue[i+1].error;
760  strcpy(_gpu_error_code_queue[i].details, _gpu_error_code_queue[i+1].details);
761  }
762  return result;
763 }
764 
766 {
767  switch(error)
768  {
769  case GPU_ERROR_NONE:
770  return "NO ERROR";
772  return "BACKEND ERROR";
774  return "DATA ERROR";
776  return "USER ERROR";
778  return "UNSUPPORTED FUNCTION";
780  return "NULL ARGUMENT";
782  return "FILE NOT FOUND";
783  }
784  return "UNKNOWN ERROR";
785 }
786 
787 
788 void GPU_GetVirtualCoords(GPU_Target* target, float* x, float* y, float displayX, float displayY)
789 {
790  if(target == NULL || _gpu_current_renderer == NULL)
791  return;
792 
793  // Scale from raw window/image coords to the virtual scale
794  if(target->context != NULL)
795  {
796  if(x != NULL)
797  *x = (displayX*target->w)/target->context->window_w;
798  if(y != NULL)
799  *y = (displayY*target->h)/target->context->window_h;
800  }
801  else if(target->image != NULL)
802  {
803  if(x != NULL)
804  *x = (displayX*target->w)/target->image->w;
805  if(y != NULL)
806  *y = (displayY*target->h)/target->image->h;
807  }
808  else
809  {
810  // What is the backing for this target?!
811  if(x != NULL)
812  *x = displayX;
813  if(y != NULL)
814  *y = displayY;
815  }
816 
817  // Invert coordinates to math coords
818  if(_gpu_current_renderer->coordinate_mode)
819  *y = target->h - *y;
820 }
821 
822 GPU_Rect GPU_MakeRect(float x, float y, float w, float h)
823 {
824  GPU_Rect r;
825  r.x = x;
826  r.y = y;
827  r.w = w;
828  r.h = h;
829 
830  return r;
831 }
832 
833 SDL_Color GPU_MakeColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a)
834 {
835  SDL_Color c;
836  c.r = r;
837  c.g = g;
838  c.b = b;
839  GET_ALPHA(c) = a;
840 
841  return c;
842 }
843 
844 GPU_RendererID GPU_MakeRendererID(const char* name, GPU_RendererEnum renderer, int major_version, int minor_version)
845 {
846  GPU_RendererID r;
847  r.name = name;
848  r.renderer = renderer;
849  r.major_version = major_version;
850  r.minor_version = minor_version;
851 
852  return r;
853 }
854 
856 {
857  if(target != NULL)
858  target->viewport = viewport;
859 }
860 
862 {
863  if(target != NULL)
864  target->viewport = GPU_MakeRect(0, 0, target->w, target->h);
865 }
866 
868 {
869  GPU_Camera cam = {0.0f, 0.0f, -10.0f, 0.0f, 1.0f};
870  return cam;
871 }
872 
874 {
875  if(target == NULL)
876  return GPU_GetDefaultCamera();
877  return target->camera;
878 }
879 
881 {
882  if(_gpu_current_renderer == NULL)
883  return GPU_GetDefaultCamera();
884  MAKE_CURRENT_IF_NONE(target);
885  if(_gpu_current_renderer->current_context_target == NULL)
886  return GPU_GetDefaultCamera();
887  // TODO: Remove from renderer and flush here
888  return _gpu_current_renderer->impl->SetCamera(_gpu_current_renderer, target, cam);
889 }
890 
892 {
893  if (target == NULL)
894  return;
895  // TODO: Flush here
896  target->use_camera = use_camera;
897 }
898 
900 {
901  if (target == NULL)
902  return GPU_FALSE;
903  return target->use_camera;
904 }
905 
906 GPU_Image* GPU_CreateImage(Uint16 w, Uint16 h, GPU_FormatEnum format)
907 {
908  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
909  return NULL;
910 
911  return _gpu_current_renderer->impl->CreateImage(_gpu_current_renderer, w, h, format);
912 }
913 
914 GPU_Image* GPU_CreateImageUsingTexture(Uint32 handle, GPU_bool take_ownership)
915 {
916  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
917  return NULL;
918 
919  return _gpu_current_renderer->impl->CreateImageUsingTexture(_gpu_current_renderer, handle, take_ownership);
920 }
921 
922 GPU_Image* GPU_LoadImage(const char* filename)
923 {
924  return GPU_LoadImage_RW(SDL_RWFromFile(filename, "r"), 1);
925 }
926 
927 GPU_Image* GPU_LoadImage_RW(SDL_RWops* rwops, GPU_bool free_rwops)
928 {
929  GPU_Image* result;
930  SDL_Surface* surface;
931  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
932  return NULL;
933 
934  surface = GPU_LoadSurface_RW(rwops, free_rwops);
935  if(surface == NULL)
936  {
937  GPU_PushErrorCode("GPU_LoadImage_RW", GPU_ERROR_DATA_ERROR, "Failed to load image data.");
938  return NULL;
939  }
940 
941  result = _gpu_current_renderer->impl->CopyImageFromSurface(_gpu_current_renderer, surface);
942  SDL_FreeSurface(surface);
943 
944  return result;
945 }
946 
948 {
949  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
950  return NULL;
951 
952  return _gpu_current_renderer->impl->CreateAliasImage(_gpu_current_renderer, image);
953 }
954 
955 GPU_bool GPU_SaveImage(GPU_Image* image, const char* filename, GPU_FileFormatEnum format)
956 {
957  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
958  return GPU_FALSE;
959 
960  return _gpu_current_renderer->impl->SaveImage(_gpu_current_renderer, image, filename, format);
961 }
962 
963 GPU_bool GPU_SaveImage_RW(GPU_Image* image, SDL_RWops* rwops, GPU_bool free_rwops, GPU_FileFormatEnum format)
964 {
965  GPU_bool result;
966  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
967  return GPU_FALSE;
968 
969  SDL_Surface* surface = GPU_CopySurfaceFromImage(image);
970  result = GPU_SaveSurface_RW(surface, rwops, free_rwops, format);
971  SDL_FreeSurface(surface);
972  return result;
973 }
974 
976 {
977  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
978  return NULL;
979 
980  return _gpu_current_renderer->impl->CopyImage(_gpu_current_renderer, image);
981 }
982 
983 void GPU_UpdateImage(GPU_Image* image, const GPU_Rect* image_rect, SDL_Surface* surface, const GPU_Rect* surface_rect)
984 {
985  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
986  return;
987 
988  _gpu_current_renderer->impl->UpdateImage(_gpu_current_renderer, image, image_rect, surface, surface_rect);
989 }
990 
991 void GPU_UpdateImageBytes(GPU_Image* image, const GPU_Rect* image_rect, const unsigned char* bytes, int bytes_per_row)
992 {
993  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
994  return;
995 
996  _gpu_current_renderer->impl->UpdateImageBytes(_gpu_current_renderer, image, image_rect, bytes, bytes_per_row);
997 }
998 
999 GPU_bool GPU_ReplaceImage(GPU_Image* image, SDL_Surface* surface, const GPU_Rect* surface_rect)
1000 {
1001  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1002  return GPU_FALSE;
1003 
1004  return _gpu_current_renderer->impl->ReplaceImage(_gpu_current_renderer, image, surface, surface_rect);
1005 }
1006 
1007 static SDL_Surface* gpu_copy_raw_surface_data(unsigned char* data, int width, int height, int channels)
1008 {
1009  int i;
1010  Uint32 Rmask, Gmask, Bmask, Amask = 0;
1011  SDL_Surface* result;
1012 
1013  if(data == NULL)
1014  {
1015  GPU_PushErrorCode(__func__, GPU_ERROR_DATA_ERROR, "Got NULL data");
1016  return NULL;
1017  }
1018 
1019  switch(channels)
1020  {
1021  case 1:
1022  Rmask = Gmask = Bmask = 0; // Use default RGB masks for 8-bit
1023  break;
1024  case 2:
1025  Rmask = Gmask = Bmask = 0; // Use default RGB masks for 16-bit
1026  break;
1027  case 3:
1028  // These are reversed from what SDL_image uses... That is bad. :( Needs testing.
1029 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
1030  Rmask = 0xff0000;
1031  Gmask = 0x00ff00;
1032  Bmask = 0x0000ff;
1033 #else
1034  Rmask = 0x0000ff;
1035  Gmask = 0x00ff00;
1036  Bmask = 0xff0000;
1037 #endif
1038  break;
1039  case 4:
1040  Rmask = 0x000000ff;
1041  Gmask = 0x0000ff00;
1042  Bmask = 0x00ff0000;
1043  Amask = 0xff000000;
1044  break;
1045  default:
1046  Rmask = Gmask = Bmask = 0;
1047  GPU_PushErrorCode(__func__, GPU_ERROR_DATA_ERROR, "Invalid number of channels: %d", channels);
1048  return NULL;
1049  break;
1050  }
1051 
1052  result = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, channels*8, Rmask, Gmask, Bmask, Amask);
1053  if(result == NULL)
1054  {
1055  GPU_PushErrorCode(__func__, GPU_ERROR_DATA_ERROR, "Failed to create new %dx%d surface", width, height);
1056  return NULL;
1057  }
1058 
1059  // Copy row-by-row in case the pitch doesn't match
1060  for(i = 0; i < height; ++i)
1061  {
1062  memcpy((Uint8*)result->pixels + i*result->pitch, data + channels*width*i, channels*width);
1063  }
1064 
1065  if(result != NULL && result->format->palette != NULL)
1066  {
1067  // SDL_CreateRGBSurface has no idea what palette to use, so it uses a blank one.
1068  // We'll at least create a grayscale one, but it's not ideal...
1069  // Better would be to get the palette from stbi, but stbi doesn't do that!
1070  SDL_Color colors[256];
1071  int i;
1072 
1073  for(i = 0; i < 256; i++)
1074  {
1075  colors[i].r = colors[i].g = colors[i].b = (Uint8)i;
1076  }
1077 
1078  /* Set palette */
1079 #ifdef SDL_GPU_USE_SDL2
1080  SDL_SetPaletteColors(result->format->palette, colors, 0, 256);
1081 #else
1082  SDL_SetPalette(result, SDL_LOGPAL, colors, 0, 256);
1083 #endif
1084  }
1085 
1086  return result;
1087 }
1088 
1089 SDL_Surface* GPU_LoadSurface_RW(SDL_RWops* rwops, GPU_bool free_rwops)
1090 {
1091  int width, height, channels;
1092  unsigned char* data;
1093  SDL_Surface* result;
1094 
1095  int data_bytes;
1096  unsigned char* c_data;
1097 
1098  if(rwops == NULL)
1099  {
1100  GPU_PushErrorCode(__func__, GPU_ERROR_NULL_ARGUMENT, "rwops");
1101  return NULL;
1102  }
1103 
1104  // Get count of bytes
1105  SDL_RWseek(rwops, 0, SEEK_SET);
1106  data_bytes = SDL_RWseek(rwops, 0, SEEK_END);
1107  SDL_RWseek(rwops, 0, SEEK_SET);
1108 
1109  // Read in the rwops data
1110  c_data = (unsigned char*)SDL_malloc(data_bytes);
1111  SDL_RWread(rwops, c_data, 1, data_bytes);
1112 
1113  // Load image
1114  data = stbi_load_from_memory(c_data, data_bytes, &width, &height, &channels, 0);
1115 
1116  // Clean up temp data
1117  SDL_free(c_data);
1118  if(free_rwops)
1119  SDL_RWclose(rwops);
1120 
1121  if(data == NULL)
1122  {
1123  GPU_PushErrorCode(__func__, GPU_ERROR_DATA_ERROR, "Failed to load from rwops: %s", stbi_failure_reason());
1124  return NULL;
1125  }
1126 
1127  // Copy into a surface
1128  result = gpu_copy_raw_surface_data(data, width, height, channels);
1129 
1130  stbi_image_free(data);
1131 
1132  return result;
1133 }
1134 
1135 SDL_Surface* GPU_LoadSurface(const char* filename)
1136 {
1137  return GPU_LoadSurface_RW(SDL_RWFromFile(filename, "r"), 1);
1138 }
1139 
1140 // From http://stackoverflow.com/questions/5309471/getting-file-extension-in-c
1141 static const char *get_filename_ext(const char *filename)
1142 {
1143  const char *dot = strrchr(filename, '.');
1144  if(!dot || dot == filename)
1145  return "";
1146  return dot + 1;
1147 }
1148 
1149 GPU_bool GPU_SaveSurface(SDL_Surface* surface, const char* filename, GPU_FileFormatEnum format)
1150 {
1151  GPU_bool result;
1152  unsigned char* data;
1153 
1154  if(surface == NULL || filename == NULL ||
1155  surface->w < 1 || surface->h < 1)
1156  {
1157  return GPU_FALSE;
1158  }
1159 
1160 
1161  data = surface->pixels;
1162 
1163  if(format == GPU_FILE_AUTO)
1164  {
1165  const char* extension = get_filename_ext(filename);
1166  if(gpu_strcasecmp(extension, "png") == 0)
1167  format = GPU_FILE_PNG;
1168  else if(gpu_strcasecmp(extension, "bmp") == 0)
1169  format = GPU_FILE_BMP;
1170  else if(gpu_strcasecmp(extension, "tga") == 0)
1171  format = GPU_FILE_TGA;
1172  else
1173  {
1174  GPU_PushErrorCode(__func__, GPU_ERROR_DATA_ERROR, "Could not detect output file format from file name");
1175  return GPU_FALSE;
1176  }
1177  }
1178 
1179  switch(format)
1180  {
1181  case GPU_FILE_PNG:
1182  result = (stbi_write_png(filename, surface->w, surface->h, surface->format->BytesPerPixel, (const unsigned char *const)data, 0) > 0);
1183  break;
1184  case GPU_FILE_BMP:
1185  result = (stbi_write_bmp(filename, surface->w, surface->h, surface->format->BytesPerPixel, (void*)data) > 0);
1186  break;
1187  case GPU_FILE_TGA:
1188  result = (stbi_write_tga(filename, surface->w, surface->h, surface->format->BytesPerPixel, (void*)data) > 0);
1189  break;
1190  default:
1191  GPU_PushErrorCode(__func__, GPU_ERROR_DATA_ERROR, "Unsupported output file format");
1192  result = GPU_FALSE;
1193  break;
1194  }
1195 
1196  return result;
1197 }
1198 
1199 static void write_func(void *context, void *data, int size)
1200 {
1201  SDL_RWwrite((SDL_RWops*)context, data, 1, size);
1202 }
1203 
1204 GPU_bool GPU_SaveSurface_RW(SDL_Surface* surface, SDL_RWops* rwops, GPU_bool free_rwops, GPU_FileFormatEnum format)
1205 {
1206  GPU_bool result;
1207  unsigned char* data;
1208 
1209  if(surface == NULL || rwops == NULL ||
1210  surface->w < 1 || surface->h < 1)
1211  {
1212  return GPU_FALSE;
1213  }
1214 
1215  data = surface->pixels;
1216 
1217  if(format == GPU_FILE_AUTO)
1218  {
1219  GPU_PushErrorCode(__func__, GPU_ERROR_DATA_ERROR, "Invalid output file format (GPU_FILE_AUTO)");
1220  return GPU_FALSE;
1221  }
1222 
1223  // FIXME: The limitations here are not communicated clearly. BMP and TGA won't support arbitrary row length/pitch.
1224  switch(format)
1225  {
1226  case GPU_FILE_PNG:
1227  result = (stbi_write_png_to_func(write_func, rwops, surface->w, surface->h, surface->format->BytesPerPixel, (const unsigned char *const)data, surface->pitch) > 0);
1228  break;
1229  case GPU_FILE_BMP:
1230  result = (stbi_write_bmp_to_func(write_func, rwops, surface->w, surface->h, surface->format->BytesPerPixel, (const unsigned char *const)data) > 0);
1231  break;
1232  case GPU_FILE_TGA:
1233  result = (stbi_write_tga_to_func(write_func, rwops, surface->w, surface->h, surface->format->BytesPerPixel, (const unsigned char *const)data) > 0);
1234  break;
1235  default:
1236  GPU_PushErrorCode(__func__, GPU_ERROR_DATA_ERROR, "Unsupported output file format");
1237  result = GPU_FALSE;
1238  break;
1239  }
1240 
1241  if(result && free_rwops)
1242  SDL_RWclose(rwops);
1243  return result;
1244 }
1245 
1246 GPU_Image* GPU_CopyImageFromSurface(SDL_Surface* surface)
1247 {
1248  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1249  return NULL;
1250 
1251  return _gpu_current_renderer->impl->CopyImageFromSurface(_gpu_current_renderer, surface);
1252 }
1253 
1255 {
1256  if(_gpu_current_renderer == NULL)
1257  return NULL;
1258  MAKE_CURRENT_IF_NONE(target);
1259  if(_gpu_current_renderer->current_context_target == NULL)
1260  return NULL;
1261 
1262  return _gpu_current_renderer->impl->CopyImageFromTarget(_gpu_current_renderer, target);
1263 }
1264 
1266 {
1267  if(_gpu_current_renderer == NULL)
1268  return NULL;
1269  MAKE_CURRENT_IF_NONE(target);
1270  if(_gpu_current_renderer->current_context_target == NULL)
1271  return NULL;
1272 
1273  return _gpu_current_renderer->impl->CopySurfaceFromTarget(_gpu_current_renderer, target);
1274 }
1275 
1277 {
1278  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1279  return NULL;
1280 
1281  return _gpu_current_renderer->impl->CopySurfaceFromImage(_gpu_current_renderer, image);
1282 }
1283 
1285 {
1286  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1287  return;
1288 
1289  _gpu_current_renderer->impl->FreeImage(_gpu_current_renderer, image);
1290 }
1291 
1292 
1294 {
1295  if(_gpu_current_renderer == NULL)
1296  return NULL;
1297 
1298  return _gpu_current_renderer->current_context_target;
1299 }
1300 
1301 
1303 {
1304  GPU_Target* result = GPU_GetTarget(image);
1305 
1306  if(result != NULL)
1307  result->refcount++;
1308 
1309  return result;
1310 }
1311 
1312 
1314 {
1315  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1316  return NULL;
1317 
1318  return _gpu_current_renderer->impl->GetTarget(_gpu_current_renderer, image);
1319 }
1320 
1321 
1322 
1324 {
1325  if(_gpu_current_renderer == NULL)
1326  return;
1327 
1328  _gpu_current_renderer->impl->FreeTarget(_gpu_current_renderer, target);
1329 }
1330 
1331 
1332 
1333 void GPU_Blit(GPU_Image* image, GPU_Rect* src_rect, GPU_Target* target, float x, float y)
1334 {
1335  if(!CHECK_RENDERER)
1336  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
1337  MAKE_CURRENT_IF_NONE(target);
1338  if(!CHECK_CONTEXT)
1339  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
1340 
1341  if(image == NULL)
1343  if(target == NULL)
1345 
1346  _gpu_current_renderer->impl->Blit(_gpu_current_renderer, image, src_rect, target, x, y);
1347 }
1348 
1349 
1350 void GPU_BlitRotate(GPU_Image* image, GPU_Rect* src_rect, GPU_Target* target, float x, float y, float degrees)
1351 {
1352  if(!CHECK_RENDERER)
1353  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
1354  MAKE_CURRENT_IF_NONE(target);
1355  if(!CHECK_CONTEXT)
1356  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
1357 
1358  if(image == NULL)
1360  if(target == NULL)
1362 
1363  _gpu_current_renderer->impl->BlitRotate(_gpu_current_renderer, image, src_rect, target, x, y, degrees);
1364 }
1365 
1366 void GPU_BlitScale(GPU_Image* image, GPU_Rect* src_rect, GPU_Target* target, float x, float y, float scaleX, float scaleY)
1367 {
1368  if(!CHECK_RENDERER)
1369  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
1370  MAKE_CURRENT_IF_NONE(target);
1371  if(!CHECK_CONTEXT)
1372  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
1373 
1374  if(image == NULL)
1376  if(target == NULL)
1378 
1379  _gpu_current_renderer->impl->BlitScale(_gpu_current_renderer, image, src_rect, target, x, y, scaleX, scaleY);
1380 }
1381 
1382 void GPU_BlitTransform(GPU_Image* image, GPU_Rect* src_rect, GPU_Target* target, float x, float y, float degrees, float scaleX, float scaleY)
1383 {
1384  if(!CHECK_RENDERER)
1385  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
1386  MAKE_CURRENT_IF_NONE(target);
1387  if(!CHECK_CONTEXT)
1388  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
1389 
1390  if(image == NULL)
1392  if(target == NULL)
1394 
1395  _gpu_current_renderer->impl->BlitTransform(_gpu_current_renderer, image, src_rect, target, x, y, degrees, scaleX, scaleY);
1396 }
1397 
1398 void GPU_BlitTransformX(GPU_Image* image, GPU_Rect* src_rect, GPU_Target* target, float x, float y, float pivot_x, float pivot_y, float degrees, float scaleX, float scaleY)
1399 {
1400  if(!CHECK_RENDERER)
1401  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
1402  MAKE_CURRENT_IF_NONE(target);
1403  if(!CHECK_CONTEXT)
1404  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
1405 
1406  if(image == NULL)
1408  if(target == NULL)
1410 
1411  _gpu_current_renderer->impl->BlitTransformX(_gpu_current_renderer, image, src_rect, target, x, y, pivot_x, pivot_y, degrees, scaleX, scaleY);
1412 }
1413 
1414 void GPU_BlitRect(GPU_Image* image, GPU_Rect* src_rect, GPU_Target* target, GPU_Rect* dest_rect)
1415 {
1416  float w = 0.0f;
1417  float h = 0.0f;
1418 
1419  if(image == NULL)
1420  return;
1421 
1422  if(src_rect == NULL)
1423  {
1424  w = image->w;
1425  h = image->h;
1426  }
1427  else
1428  {
1429  w = src_rect->w;
1430  h = src_rect->h;
1431  }
1432 
1433  GPU_BlitRectX(image, src_rect, target, dest_rect, 0.0f, w*0.5f, h*0.5f, GPU_FLIP_NONE);
1434 }
1435 
1436 void GPU_BlitRectX(GPU_Image* image, GPU_Rect* src_rect, GPU_Target* target, GPU_Rect* dest_rect, float degrees, float pivot_x, float pivot_y, GPU_FlipEnum flip_direction)
1437 {
1438  float w, h;
1439  float dx, dy;
1440  float dw, dh;
1441  float scale_x, scale_y;
1442 
1443  if(image == NULL || target == NULL)
1444  return;
1445 
1446  if(src_rect == NULL)
1447  {
1448  w = image->w;
1449  h = image->h;
1450  }
1451  else
1452  {
1453  w = src_rect->w;
1454  h = src_rect->h;
1455  }
1456 
1457  if(dest_rect == NULL)
1458  {
1459  dx = 0.0f;
1460  dy = 0.0f;
1461  dw = target->w;
1462  dh = target->h;
1463  }
1464  else
1465  {
1466  dx = dest_rect->x;
1467  dy = dest_rect->y;
1468  dw = dest_rect->w;
1469  dh = dest_rect->h;
1470  }
1471 
1472  scale_x = dw / w;
1473  scale_y = dh / h;
1474 
1475  if(flip_direction & GPU_FLIP_HORIZONTAL)
1476  {
1477  scale_x = -scale_x;
1478  dx += dw;
1479  pivot_x = w - pivot_x;
1480  }
1481  if(flip_direction & GPU_FLIP_VERTICAL)
1482  {
1483  scale_y = -scale_y;
1484  dy += dh;
1485  pivot_y = h - pivot_y;
1486  }
1487 
1488  GPU_BlitTransformX(image, src_rect, target, dx + pivot_x * scale_x, dy + pivot_y * scale_y, pivot_x, pivot_y, degrees, scale_x, scale_y);
1489 }
1490 
1491 void GPU_TriangleBatch(GPU_Image* image, GPU_Target* target, unsigned short num_vertices, float* values, unsigned int num_indices, unsigned short* indices, GPU_BatchFlagEnum flags)
1492 {
1493  GPU_TriangleBatchX(image, target, num_vertices, (void*)values, num_indices, indices, flags);
1494 }
1495 
1496 void GPU_TriangleBatchX(GPU_Image* image, GPU_Target* target, unsigned short num_vertices, void* values, unsigned int num_indices, unsigned short* indices, GPU_BatchFlagEnum flags)
1497 {
1498  if(!CHECK_RENDERER)
1499  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
1500  MAKE_CURRENT_IF_NONE(target);
1501  if(!CHECK_CONTEXT)
1502  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
1503 
1504  if(target == NULL)
1506 
1507  if(num_vertices == 0)
1508  return;
1509 
1510 
1511  _gpu_current_renderer->impl->TriangleBatchX(_gpu_current_renderer, image, target, num_vertices, values, num_indices, indices, flags);
1512 }
1513 
1514 
1515 
1516 
1518 {
1519  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1520  return;
1521 
1522  _gpu_current_renderer->impl->GenerateMipmaps(_gpu_current_renderer, image);
1523 }
1524 
1525 
1526 
1527 
1529 {
1530  if(target == NULL || _gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1531  {
1532  GPU_Rect r = {0,0,0,0};
1533  return r;
1534  }
1535 
1536  return _gpu_current_renderer->impl->SetClip(_gpu_current_renderer, target, (Sint16)rect.x, (Sint16)rect.y, (Uint16)rect.w, (Uint16)rect.h);
1537 }
1538 
1539 GPU_Rect GPU_SetClip(GPU_Target* target, Sint16 x, Sint16 y, Uint16 w, Uint16 h)
1540 {
1541  if(target == NULL || _gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1542  {
1543  GPU_Rect r = {0,0,0,0};
1544  return r;
1545  }
1546 
1547  return _gpu_current_renderer->impl->SetClip(_gpu_current_renderer, target, x, y, w, h);
1548 }
1549 
1551 {
1552  if(target == NULL || _gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1553  return;
1554 
1555  _gpu_current_renderer->impl->UnsetClip(_gpu_current_renderer, target);
1556 }
1557 
1558 /* Adapted from SDL_IntersectRect() */
1560 {
1561  GPU_bool has_horiz_intersection = GPU_FALSE;
1562  float Amin, Amax, Bmin, Bmax;
1563  GPU_Rect intersection;
1564 
1565  // Special case for empty rects
1566  if (A.w <= 0.0f || A.h <= 0.0f || B.w <= 0.0f || B.h <= 0.0f)
1567  return GPU_FALSE;
1568 
1569  // Horizontal intersection
1570  Amin = A.x;
1571  Amax = Amin + A.w;
1572  Bmin = B.x;
1573  Bmax = Bmin + B.w;
1574  if (Bmin > Amin)
1575  Amin = Bmin;
1576  if (Bmax < Amax)
1577  Amax = Bmax;
1578 
1579  intersection.x = Amin;
1580  intersection.w = Amax - Amin;
1581 
1582  has_horiz_intersection = (Amax > Amin);
1583 
1584  // Vertical intersection
1585  Amin = A.y;
1586  Amax = Amin + A.h;
1587  Bmin = B.y;
1588  Bmax = Bmin + B.h;
1589  if (Bmin > Amin)
1590  Amin = Bmin;
1591  if (Bmax < Amax)
1592  Amax = Bmax;
1593 
1594  intersection.y = Amin;
1595  intersection.h = Amax - Amin;
1596 
1597  if(has_horiz_intersection && Amax > Amin)
1598  {
1599  if(result != NULL)
1600  *result = intersection;
1601  return GPU_TRUE;
1602  }
1603  else
1604  return GPU_FALSE;
1605 }
1606 
1607 
1609 {
1610  if(target == NULL)
1611  return GPU_FALSE;
1612 
1613  if(!target->use_clip_rect)
1614  {
1615  GPU_Rect A = {0, 0, target->w, target->h};
1616  return GPU_IntersectRect(A, B, result);
1617  }
1618 
1619  return GPU_IntersectRect(target->clip_rect, B, result);
1620 }
1621 
1622 
1623 void GPU_SetColor(GPU_Image* image, SDL_Color color)
1624 {
1625  if(image == NULL)
1626  return;
1627 
1628  image->color = color;
1629 }
1630 
1631 void GPU_SetRGB(GPU_Image* image, Uint8 r, Uint8 g, Uint8 b)
1632 {
1633  SDL_Color c;
1634  c.r = r;
1635  c.g = g;
1636  c.b = b;
1637  GET_ALPHA(c) = 255;
1638 
1639  if(image == NULL)
1640  return;
1641 
1642  image->color = c;
1643 }
1644 
1645 void GPU_SetRGBA(GPU_Image* image, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
1646 {
1647  SDL_Color c;
1648  c.r = r;
1649  c.g = g;
1650  c.b = b;
1651  GET_ALPHA(c) = a;
1652 
1653  if(image == NULL)
1654  return;
1655 
1656  image->color = c;
1657 }
1658 
1660 {
1661  SDL_Color c = {255, 255, 255, 255};
1662  if(image == NULL)
1663  return;
1664 
1665  image->color = c;
1666 }
1667 
1668 void GPU_SetTargetColor(GPU_Target* target, SDL_Color color)
1669 {
1670  if(target == NULL)
1671  return;
1672 
1673  target->use_color = 1;
1674  target->color = color;
1675 }
1676 
1677 void GPU_SetTargetRGB(GPU_Target* target, Uint8 r, Uint8 g, Uint8 b)
1678 {
1679  SDL_Color c;
1680  c.r = r;
1681  c.g = g;
1682  c.b = b;
1683  GET_ALPHA(c) = 255;
1684 
1685  if(target == NULL)
1686  return;
1687 
1688  target->use_color = !(r == 255 && g == 255 && b == 255);
1689  target->color = c;
1690 }
1691 
1692 void GPU_SetTargetRGBA(GPU_Target* target, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
1693 {
1694  SDL_Color c;
1695  c.r = r;
1696  c.g = g;
1697  c.b = b;
1698  GET_ALPHA(c) = a;
1699 
1700  if(target == NULL)
1701  return;
1702 
1703  target->use_color = !(r == 255 && g == 255 && b == 255 && a == 255);
1704  target->color = c;
1705 }
1706 
1708 {
1709  SDL_Color c = {255, 255, 255, 255};
1710  if(target == NULL)
1711  return;
1712 
1713  target->use_color = GPU_FALSE;
1714  target->color = c;
1715 }
1716 
1718 {
1719  if(image == NULL)
1720  return GPU_FALSE;
1721 
1722  return image->use_blending;
1723 }
1724 
1725 
1726 void GPU_SetBlending(GPU_Image* image, GPU_bool enable)
1727 {
1728  if(image == NULL)
1729  return;
1730 
1731  image->use_blending = enable;
1732 }
1733 
1735 {
1736  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1737  return;
1738 
1739  _gpu_current_renderer->current_context_target->context->shapes_use_blending = enable;
1740 }
1741 
1742 
1744 {
1745  switch(preset)
1746  {
1747  case GPU_BLEND_NORMAL:
1748  {
1750  return b;
1751  }
1752  break;
1754  {
1756  return b;
1757  }
1758  break;
1759  case GPU_BLEND_MULTIPLY:
1760  {
1762  return b;
1763  }
1764  break;
1765  case GPU_BLEND_ADD:
1766  {
1768  return b;
1769  }
1770  break;
1771  case GPU_BLEND_SUBTRACT:
1772  // FIXME: Use src alpha for source components?
1773  {
1775  return b;
1776  }
1777  break;
1778  case GPU_BLEND_MOD_ALPHA:
1779  // Don't disturb the colors, but multiply the dest alpha by the src alpha
1780  {
1782  return b;
1783  }
1784  break;
1785  case GPU_BLEND_SET_ALPHA:
1786  // Don't disturb the colors, but set the alpha to the src alpha
1787  {
1789  return b;
1790  }
1791  break;
1792  case GPU_BLEND_SET:
1793  {
1795  return b;
1796  }
1797  break;
1799  {
1801  return b;
1802  }
1803  break;
1805  {
1807  return b;
1808  }
1809  break;
1811  {
1813  return b;
1814  }
1815  break;
1816  default:
1817  GPU_PushErrorCode(__func__, GPU_ERROR_USER_ERROR, "Blend preset not supported: %d", preset);
1818  {
1820  return b;
1821  }
1822  break;
1823  }
1824 }
1825 
1826 
1827 void GPU_SetBlendFunction(GPU_Image* image, GPU_BlendFuncEnum source_color, GPU_BlendFuncEnum dest_color, GPU_BlendFuncEnum source_alpha, GPU_BlendFuncEnum dest_alpha)
1828 {
1829  if(image == NULL)
1830  return;
1831 
1832  image->blend_mode.source_color = source_color;
1833  image->blend_mode.dest_color = dest_color;
1834  image->blend_mode.source_alpha = source_alpha;
1835  image->blend_mode.dest_alpha = dest_alpha;
1836 }
1837 
1838 void GPU_SetBlendEquation(GPU_Image* image, GPU_BlendEqEnum color_equation, GPU_BlendEqEnum alpha_equation)
1839 {
1840  if(image == NULL)
1841  return;
1842 
1843  image->blend_mode.color_equation = color_equation;
1844  image->blend_mode.alpha_equation = alpha_equation;
1845 }
1846 
1848 {
1849  GPU_BlendMode b;
1850  if(image == NULL)
1851  return;
1852 
1853  b = GPU_GetBlendModeFromPreset(preset);
1856 }
1857 
1859 {
1860  GPU_Context* context;
1861  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1862  return;
1863 
1864  context = _gpu_current_renderer->current_context_target->context;
1865 
1866  context->shapes_blend_mode.source_color = source_color;
1867  context->shapes_blend_mode.dest_color = dest_color;
1868  context->shapes_blend_mode.source_alpha = source_alpha;
1869  context->shapes_blend_mode.dest_alpha = dest_alpha;
1870 }
1871 
1872 void GPU_SetShapeBlendEquation(GPU_BlendEqEnum color_equation, GPU_BlendEqEnum alpha_equation)
1873 {
1874  GPU_Context* context;
1875  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1876  return;
1877 
1878  context = _gpu_current_renderer->current_context_target->context;
1879 
1880  context->shapes_blend_mode.color_equation = color_equation;
1881  context->shapes_blend_mode.alpha_equation = alpha_equation;
1882 }
1883 
1885 {
1886  GPU_BlendMode b;
1887  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1888  return;
1889 
1890  b = GPU_GetBlendModeFromPreset(preset);
1893 }
1894 
1896 {
1897  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1898  return;
1899  if(image == NULL)
1900  return;
1901 
1902  _gpu_current_renderer->impl->SetImageFilter(_gpu_current_renderer, image, filter);
1903 }
1904 
1905 
1906 void GPU_SetDefaultAnchor(float anchor_x, float anchor_y)
1907 {
1908  if(_gpu_current_renderer == NULL)
1909  return;
1910 
1911  _gpu_current_renderer->default_image_anchor_x = anchor_x;
1912  _gpu_current_renderer->default_image_anchor_y = anchor_y;
1913 }
1914 
1915 void GPU_GetDefaultAnchor(float* anchor_x, float* anchor_y)
1916 {
1917  if(_gpu_current_renderer == NULL)
1918  return;
1919 
1920  if(anchor_x != NULL)
1921  *anchor_x = _gpu_current_renderer->default_image_anchor_x;
1922 
1923  if(anchor_y != NULL)
1924  *anchor_y = _gpu_current_renderer->default_image_anchor_y;
1925 }
1926 
1927 void GPU_SetAnchor(GPU_Image* image, float anchor_x, float anchor_y)
1928 {
1929  if(image == NULL)
1930  return;
1931 
1932  image->anchor_x = anchor_x;
1933  image->anchor_y = anchor_y;
1934 }
1935 
1936 void GPU_GetAnchor(GPU_Image* image, float* anchor_x, float* anchor_y)
1937 {
1938  if(image == NULL)
1939  return;
1940 
1941  if(anchor_x != NULL)
1942  *anchor_x = image->anchor_x;
1943 
1944  if(anchor_y != NULL)
1945  *anchor_y = image->anchor_y;
1946 }
1947 
1949 {
1950  if(image == NULL)
1951  return 0;
1952 
1953  return image->snap_mode;
1954 }
1955 
1957 {
1958  if(image == NULL)
1959  return;
1960 
1961  image->snap_mode = mode;
1962 }
1963 
1964 void GPU_SetWrapMode(GPU_Image* image, GPU_WrapEnum wrap_mode_x, GPU_WrapEnum wrap_mode_y)
1965 {
1966  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1967  return;
1968  if(image == NULL)
1969  return;
1970 
1971  _gpu_current_renderer->impl->SetWrapMode(_gpu_current_renderer, image, wrap_mode_x, wrap_mode_y);
1972 }
1973 
1974 
1975 SDL_Color GPU_GetPixel(GPU_Target* target, Sint16 x, Sint16 y)
1976 {
1977  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1978  {
1979  SDL_Color c = {0,0,0,0};
1980  return c;
1981  }
1982 
1983  return _gpu_current_renderer->impl->GetPixel(_gpu_current_renderer, target, x, y);
1984 }
1985 
1986 
1987 
1988 
1989 
1990 
1991 
1993 {
1994  if(!CHECK_RENDERER)
1995  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
1996  MAKE_CURRENT_IF_NONE(target);
1997  if(!CHECK_CONTEXT)
1998  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
1999 
2000  _gpu_current_renderer->impl->ClearRGBA(_gpu_current_renderer, target, 0, 0, 0, 0);
2001 }
2002 
2003 void GPU_ClearColor(GPU_Target* target, SDL_Color color)
2004 {
2005  if(!CHECK_RENDERER)
2006  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
2007  MAKE_CURRENT_IF_NONE(target);
2008  if(!CHECK_CONTEXT)
2009  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
2010 
2011  _gpu_current_renderer->impl->ClearRGBA(_gpu_current_renderer, target, color.r, color.g, color.b, GET_ALPHA(color));
2012 }
2013 
2014 void GPU_ClearRGB(GPU_Target* target, Uint8 r, Uint8 g, Uint8 b)
2015 {
2016  if(!CHECK_RENDERER)
2017  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
2018  MAKE_CURRENT_IF_NONE(target);
2019  if(!CHECK_CONTEXT)
2020  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
2021 
2022  _gpu_current_renderer->impl->ClearRGBA(_gpu_current_renderer, target, r, g, b, 255);
2023 }
2024 
2025 void GPU_ClearRGBA(GPU_Target* target, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
2026 {
2027  if(!CHECK_RENDERER)
2028  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
2029  MAKE_CURRENT_IF_NONE(target);
2030  if(!CHECK_CONTEXT)
2031  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
2032 
2033  _gpu_current_renderer->impl->ClearRGBA(_gpu_current_renderer, target, r, g, b, a);
2034 }
2035 
2037 {
2038  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2039  return;
2040 
2041  _gpu_current_renderer->impl->FlushBlitBuffer(_gpu_current_renderer);
2042 }
2043 
2045 {
2046  if(!CHECK_RENDERER)
2047  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
2048 
2049  if(target != NULL && target->context == NULL)
2050  {
2051  _gpu_current_renderer->impl->FlushBlitBuffer(_gpu_current_renderer);
2052  return;
2053  }
2054 
2055  MAKE_CURRENT_IF_NONE(target);
2056  if(!CHECK_CONTEXT)
2057  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
2058 
2059  _gpu_current_renderer->impl->Flip(_gpu_current_renderer, target);
2060 }
2061 
2062 
2063 
2064 
2065 
2066 // Shader API
2067 
2068 
2069 Uint32 GPU_CompileShader_RW(GPU_ShaderEnum shader_type, SDL_RWops* shader_source, GPU_bool free_rwops)
2070 {
2071  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2072  {
2073  if(free_rwops)
2074  SDL_RWclose(shader_source);
2075  return GPU_FALSE;
2076  }
2077 
2078  return _gpu_current_renderer->impl->CompileShader_RW(_gpu_current_renderer, shader_type, shader_source, free_rwops);
2079 }
2080 
2081 Uint32 GPU_LoadShader(GPU_ShaderEnum shader_type, const char* filename)
2082 {
2083  SDL_RWops* rwops;
2084 
2085  if(filename == NULL)
2086  {
2087  GPU_PushErrorCode(__func__, GPU_ERROR_NULL_ARGUMENT, "filename");
2088  return 0;
2089  }
2090 
2091  rwops = SDL_RWFromFile(filename, "r");
2092  if(rwops == NULL)
2093  {
2094  GPU_PushErrorCode(__func__, GPU_ERROR_FILE_NOT_FOUND, "%s", filename);
2095  return 0;
2096  }
2097 
2098  return GPU_CompileShader_RW(shader_type, rwops, 1);
2099 }
2100 
2101 Uint32 GPU_CompileShader(GPU_ShaderEnum shader_type, const char* shader_source)
2102 {
2103  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2104  return 0;
2105 
2106  return _gpu_current_renderer->impl->CompileShader(_gpu_current_renderer, shader_type, shader_source);
2107 }
2108 
2109 GPU_bool GPU_LinkShaderProgram(Uint32 program_object)
2110 {
2111  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2112  return GPU_FALSE;
2113 
2114  return _gpu_current_renderer->impl->LinkShaderProgram(_gpu_current_renderer, program_object);
2115 }
2116 
2118 {
2119  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2120  return 0;
2121 
2122  return _gpu_current_renderer->impl->CreateShaderProgram(_gpu_current_renderer);
2123 }
2124 
2125 Uint32 GPU_LinkShaders(Uint32 shader_object1, Uint32 shader_object2)
2126 {
2127  Uint32 shaders[2];
2128  shaders[0] = shader_object1;
2129  shaders[1] = shader_object2;
2130  return GPU_LinkManyShaders(shaders, 2);
2131 }
2132 
2133 Uint32 GPU_LinkManyShaders(Uint32 *shader_objects, int count)
2134 {
2135  Uint32 p;
2136  int i;
2137 
2138  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2139  return 0;
2140 
2141  if((_gpu_current_renderer->enabled_features & GPU_FEATURE_BASIC_SHADERS) != GPU_FEATURE_BASIC_SHADERS)
2142  return 0;
2143 
2144  p = _gpu_current_renderer->impl->CreateShaderProgram(_gpu_current_renderer);
2145 
2146  for (i = 0; i < count; i++)
2147  _gpu_current_renderer->impl->AttachShader(_gpu_current_renderer, p, shader_objects[i]);
2148 
2149  if(_gpu_current_renderer->impl->LinkShaderProgram(_gpu_current_renderer, p))
2150  return p;
2151 
2152  _gpu_current_renderer->impl->FreeShaderProgram(_gpu_current_renderer, p);
2153  return 0;
2154 }
2155 
2156 void GPU_FreeShader(Uint32 shader_object)
2157 {
2158  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2159  return;
2160 
2161  _gpu_current_renderer->impl->FreeShader(_gpu_current_renderer, shader_object);
2162 }
2163 
2164 void GPU_FreeShaderProgram(Uint32 program_object)
2165 {
2166  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2167  return;
2168 
2169  _gpu_current_renderer->impl->FreeShaderProgram(_gpu_current_renderer, program_object);
2170 }
2171 
2172 void GPU_AttachShader(Uint32 program_object, Uint32 shader_object)
2173 {
2174  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2175  return;
2176 
2177  _gpu_current_renderer->impl->AttachShader(_gpu_current_renderer, program_object, shader_object);
2178 }
2179 
2180 void GPU_DetachShader(Uint32 program_object, Uint32 shader_object)
2181 {
2182  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2183  return;
2184 
2185  _gpu_current_renderer->impl->DetachShader(_gpu_current_renderer, program_object, shader_object);
2186 }
2187 
2188 GPU_bool GPU_IsDefaultShaderProgram(Uint32 program_object)
2189 {
2190  GPU_Context* context;
2191 
2192  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2193  return GPU_FALSE;
2194 
2195  context = _gpu_current_renderer->current_context_target->context;
2196  return (program_object == context->default_textured_shader_program || program_object == context->default_untextured_shader_program);
2197 }
2198 
2199 void GPU_ActivateShaderProgram(Uint32 program_object, GPU_ShaderBlock* block)
2200 {
2201  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2202  return;
2203 
2204  _gpu_current_renderer->impl->ActivateShaderProgram(_gpu_current_renderer, program_object, block);
2205 }
2206 
2208 {
2209  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2210  return;
2211 
2212  _gpu_current_renderer->impl->DeactivateShaderProgram(_gpu_current_renderer);
2213 }
2214 
2215 const char* GPU_GetShaderMessage(void)
2216 {
2217  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2218  return NULL;
2219 
2220  return _gpu_current_renderer->impl->GetShaderMessage(_gpu_current_renderer);
2221 }
2222 
2223 int GPU_GetAttributeLocation(Uint32 program_object, const char* attrib_name)
2224 {
2225  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2226  return 0;
2227 
2228  return _gpu_current_renderer->impl->GetAttributeLocation(_gpu_current_renderer, program_object, attrib_name);
2229 }
2230 
2231 GPU_AttributeFormat GPU_MakeAttributeFormat(int num_elems_per_vertex, GPU_TypeEnum type, GPU_bool normalize, int stride_bytes, int offset_bytes)
2232 {
2235  f.num_elems_per_value = num_elems_per_vertex;
2236  f.type = type;
2237  f.normalize = normalize;
2238  f.stride_bytes = stride_bytes;
2239  f.offset_bytes = offset_bytes;
2240  return f;
2241 }
2242 
2243 GPU_Attribute GPU_MakeAttribute(int location, void* values, GPU_AttributeFormat format)
2244 {
2245  GPU_Attribute a;
2246  a.location = location;
2247  a.values = values;
2248  a.format = format;
2249  return a;
2250 }
2251 
2252 int GPU_GetUniformLocation(Uint32 program_object, const char* uniform_name)
2253 {
2254  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2255  return 0;
2256 
2257  return _gpu_current_renderer->impl->GetUniformLocation(_gpu_current_renderer, program_object, uniform_name);
2258 }
2259 
2260 GPU_ShaderBlock GPU_LoadShaderBlock(Uint32 program_object, const char* position_name, const char* texcoord_name, const char* color_name, const char* modelViewMatrix_name)
2261 {
2262  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2263  {
2264  GPU_ShaderBlock b;
2265  b.position_loc = -1;
2266  b.texcoord_loc = -1;
2267  b.color_loc = -1;
2268  b.modelViewProjection_loc = -1;
2269  return b;
2270  }
2271 
2272  return _gpu_current_renderer->impl->LoadShaderBlock(_gpu_current_renderer, program_object, position_name, texcoord_name, color_name, modelViewMatrix_name);
2273 }
2274 
2276 {
2277  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2278  return;
2279 
2280  _gpu_current_renderer->current_context_target->context->current_shader_block = block;
2281 }
2282 
2284 {
2285  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2286  {
2287  GPU_ShaderBlock b;
2288  b.position_loc = -1;
2289  b.texcoord_loc = -1;
2290  b.color_loc = -1;
2291  b.modelViewProjection_loc = -1;
2292  return b;
2293  }
2294 
2295  return _gpu_current_renderer->current_context_target->context->current_shader_block;
2296 }
2297 
2298 void GPU_SetShaderImage(GPU_Image* image, int location, int image_unit)
2299 {
2300  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2301  return;
2302 
2303  _gpu_current_renderer->impl->SetShaderImage(_gpu_current_renderer, image, location, image_unit);
2304 }
2305 
2306 void GPU_GetUniformiv(Uint32 program_object, int location, int* values)
2307 {
2308  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2309  return;
2310 
2311  _gpu_current_renderer->impl->GetUniformiv(_gpu_current_renderer, program_object, location, values);
2312 }
2313 
2314 void GPU_SetUniformi(int location, int value)
2315 {
2316  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2317  return;
2318 
2319  _gpu_current_renderer->impl->SetUniformi(_gpu_current_renderer, location, value);
2320 }
2321 
2322 void GPU_SetUniformiv(int location, int num_elements_per_value, int num_values, int* values)
2323 {
2324  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2325  return;
2326 
2327  _gpu_current_renderer->impl->SetUniformiv(_gpu_current_renderer, location, num_elements_per_value, num_values, values);
2328 }
2329 
2330 
2331 void GPU_GetUniformuiv(Uint32 program_object, int location, unsigned int* values)
2332 {
2333  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2334  return;
2335 
2336  _gpu_current_renderer->impl->GetUniformuiv(_gpu_current_renderer, program_object, location, values);
2337 }
2338 
2339 void GPU_SetUniformui(int location, unsigned int value)
2340 {
2341  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2342  return;
2343 
2344  _gpu_current_renderer->impl->SetUniformui(_gpu_current_renderer, location, value);
2345 }
2346 
2347 void GPU_SetUniformuiv(int location, int num_elements_per_value, int num_values, unsigned int* values)
2348 {
2349  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2350  return;
2351 
2352  _gpu_current_renderer->impl->SetUniformuiv(_gpu_current_renderer, location, num_elements_per_value, num_values, values);
2353 }
2354 
2355 
2356 void GPU_GetUniformfv(Uint32 program_object, int location, float* values)
2357 {
2358  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2359  return;
2360 
2361  _gpu_current_renderer->impl->GetUniformfv(_gpu_current_renderer, program_object, location, values);
2362 }
2363 
2364 void GPU_SetUniformf(int location, float value)
2365 {
2366  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2367  return;
2368 
2369  _gpu_current_renderer->impl->SetUniformf(_gpu_current_renderer, location, value);
2370 }
2371 
2372 void GPU_SetUniformfv(int location, int num_elements_per_value, int num_values, float* values)
2373 {
2374  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2375  return;
2376 
2377  _gpu_current_renderer->impl->SetUniformfv(_gpu_current_renderer, location, num_elements_per_value, num_values, values);
2378 }
2379 
2380 // Same as GPU_GetUniformfv()
2381 void GPU_GetUniformMatrixfv(Uint32 program_object, int location, float* values)
2382 {
2383  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2384  return;
2385 
2386  _gpu_current_renderer->impl->GetUniformfv(_gpu_current_renderer, program_object, location, values);
2387 }
2388 
2389 void GPU_SetUniformMatrixfv(int location, int num_matrices, int num_rows, int num_columns, GPU_bool transpose, float* values)
2390 {
2391  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2392  return;
2393 
2394  _gpu_current_renderer->impl->SetUniformMatrixfv(_gpu_current_renderer, location, num_matrices, num_rows, num_columns, transpose, values);
2395 }
2396 
2397 
2398 void GPU_SetAttributef(int location, float value)
2399 {
2400  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2401  return;
2402 
2403  _gpu_current_renderer->impl->SetAttributef(_gpu_current_renderer, location, value);
2404 }
2405 
2406 void GPU_SetAttributei(int location, int value)
2407 {
2408  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2409  return;
2410 
2411  _gpu_current_renderer->impl->SetAttributei(_gpu_current_renderer, location, value);
2412 }
2413 
2414 void GPU_SetAttributeui(int location, unsigned int value)
2415 {
2416  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2417  return;
2418 
2419  _gpu_current_renderer->impl->SetAttributeui(_gpu_current_renderer, location, value);
2420 }
2421 
2422 void GPU_SetAttributefv(int location, int num_elements, float* value)
2423 {
2424  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2425  return;
2426 
2427  _gpu_current_renderer->impl->SetAttributefv(_gpu_current_renderer, location, num_elements, value);
2428 }
2429 
2430 void GPU_SetAttributeiv(int location, int num_elements, int* value)
2431 {
2432  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2433  return;
2434 
2435  _gpu_current_renderer->impl->SetAttributeiv(_gpu_current_renderer, location, num_elements, value);
2436 }
2437 
2438 void GPU_SetAttributeuiv(int location, int num_elements, unsigned int* value)
2439 {
2440  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2441  return;
2442 
2443  _gpu_current_renderer->impl->SetAttributeuiv(_gpu_current_renderer, location, num_elements, value);
2444 }
2445 
2446 void GPU_SetAttributeSource(int num_values, GPU_Attribute source)
2447 {
2448  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2449  return;
2450 
2451  _gpu_current_renderer->impl->SetAttributeSource(_gpu_current_renderer, num_values, source);
2452 }
2453 
2454 
2455 
2456 
2457 // gpu_strcasecmp()
2458 // A portable strcasecmp() from UC Berkeley
2459 /*
2460  * Copyright (c) 1987 Regents of the University of California.
2461  * All rights reserved.
2462  *
2463  * Redistribution and use in source and binary forms are permitted
2464  * provided that this notice is preserved and that due credit is given
2465  * to the University of California at Berkeley. The name of the University
2466  * may not be used to endorse or promote products derived from this
2467  * software without specific written prior permission. This software
2468  * is provided ``as is'' without express or implied warranty.
2469  */
2470 
2471 /*
2472  * This array is designed for mapping upper and lower case letter
2473  * together for a case independent comparison. The mappings are
2474  * based upon ascii character sequences.
2475  */
2476 static const unsigned char caseless_charmap[] =
2477 {
2478  '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
2479  '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
2480  '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
2481  '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
2482  '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
2483  '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
2484  '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
2485  '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
2486  '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
2487  '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
2488  '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
2489  '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
2490  '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
2491  '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
2492  '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
2493  '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
2494  '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
2495  '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
2496  '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
2497  '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
2498  '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
2499  '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
2500  '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
2501  '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
2502  '\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
2503  '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
2504  '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
2505  '\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337',
2506  '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
2507  '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
2508  '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
2509  '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
2510 };
2511 
2512 int gpu_strcasecmp(const char* s1, const char* s2)
2513 {
2514  unsigned char u1, u2;
2515 
2516  for (;;)
2517  {
2518  u1 = (unsigned char) *s1++;
2519  u2 = (unsigned char) *s2++;
2520  if (caseless_charmap[u1] != caseless_charmap[u2])
2521  return caseless_charmap[u1] - caseless_charmap[u2];
2522  if (u1 == '\0')
2523  return 0;
2524  }
2525  return 0;
2526 }
2527 
2528 
2529 #ifdef _MSC_VER
2530  #pragma warning(pop)
2531 #endif
2532 
GPU_bool GPU_SaveSurface_RW(SDL_Surface *surface, SDL_RWops *rwops, GPU_bool free_rwops, GPU_FileFormatEnum format)
Definition: SDL_gpu.c:1204
GPU_Image *SDLCALL * CopyImageFromSurface(GPU_Renderer *renderer, SDL_Surface *surface)
const char * GPU_GetErrorString(GPU_ErrorEnum error)
Definition: SDL_gpu.c:765
void GPU_SetAttributeiv(int location, int num_elements, int *value)
Definition: SDL_gpu.c:2430
int minor_version
Definition: SDL_gpu.h:124
Uint16 w
Definition: SDL_gpu.h:409
void GPU_SetTargetColor(GPU_Target *target, SDL_Color color)
Definition: SDL_gpu.c:1668
GPU_Image * GPU_CopyImage(GPU_Image *image)
Definition: SDL_gpu.c:975
void GPU_SetBlending(GPU_Image *image, GPU_bool enable)
Definition: SDL_gpu.c:1726
void GPU_LogInfo(const char *format,...)
Definition: SDL_gpu.c:159
GPU_bool GPU_IsCameraEnabled(GPU_Target *target)
Definition: SDL_gpu.c:899
GPU_Camera GPU_GetDefaultCamera(void)
Definition: SDL_gpu.c:867
void GPU_SetAttributefv(int location, int num_elements, float *value)
Definition: SDL_gpu.c:2422
GPU_Target *SDLCALL * CreateTargetFromWindow(GPU_Renderer *renderer, Uint32 windowID, GPU_Target *target)
void * values
Definition: SDL_gpu.h:581
GPU_FilterEnum
Definition: SDL_gpu.h:193
void GPU_UnsetTargetColor(GPU_Target *target)
Definition: SDL_gpu.c:1707
GPU_FileFormatEnum
Definition: SDL_gpu.h:247
void GPU_GetUniformuiv(Uint32 program_object, int location, unsigned int *values)
Definition: SDL_gpu.c:2331
void GPU_SetShapeBlendMode(GPU_BlendPresetEnum preset)
Definition: SDL_gpu.c:1884
Uint16 base_h
Definition: SDL_gpu.h:276
GPU_WrapEnum
Definition: SDL_gpu.h:216
GPU_BlendFuncEnum dest_alpha
Definition: SDL_gpu.h:164
int location
Definition: SDL_gpu.h:580
GPU_BlendEqEnum color_equation
Definition: SDL_gpu.h:166
SDL_Surface * GPU_LoadSurface(const char *filename)
Definition: SDL_gpu.c:1135
GPU_bool GPU_GetCoordinateMode(void)
Definition: SDL_gpu.c:105
void gpu_init_renderer_register(void)
void GPU_SetRequiredFeatures(GPU_FeatureEnum features)
Definition: SDL_gpu.c:230
GPU_DebugLevelEnum
Definition: SDL_gpu.h:629
SDL_Surface * GPU_CopySurfaceFromTarget(GPU_Target *target)
Definition: SDL_gpu.c:1265
Uint32 GPU_CompileShader_RW(GPU_ShaderEnum shader_type, SDL_RWops *shader_source, GPU_bool free_rwops)
Definition: SDL_gpu.c:2069
int position_loc
Definition: SDL_gpu.h:319
void GPU_FreeTarget(GPU_Target *target)
Definition: SDL_gpu.c:1323
Uint16 base_w
Definition: SDL_gpu.h:276
GPU_bool use_clip_rect
Definition: SDL_gpu.h:412
Uint16 h
Definition: SDL_gpu.h:271
GPU_Target * GPU_Init(Uint16 w, Uint16 h, GPU_WindowFlagEnum SDL_flags)
Definition: SDL_gpu.c:405
Uint32 windowID
Definition: SDL_gpu.h:355
GPU_Image *SDLCALL * CreateImage(GPU_Renderer *renderer, Uint16 w, Uint16 h, GPU_FormatEnum format)
GPU_BlendEqEnum
Definition: SDL_gpu.h:151
GPU_Image * GPU_CreateAliasImage(GPU_Image *image)
Definition: SDL_gpu.c:947
SDL_version GPU_GetLinkedVersion(void)
Definition: SDL_gpu.c:76
GPU_SnapEnum snap_mode
Definition: SDL_gpu.h:287
void GPU_UnsetVirtualResolution(GPU_Target *target)
Definition: SDL_gpu.c:565
void GPU_AttachShader(Uint32 program_object, Uint32 shader_object)
Definition: SDL_gpu.c:2172
void GPU_GetUniformfv(Uint32 program_object, int location, float *values)
Definition: SDL_gpu.c:2356
void GPU_SetUniformMatrixfv(int location, int num_matrices, int num_rows, int num_columns, GPU_bool transpose, float *values)
Definition: SDL_gpu.c:2389
void GPU_CloseCurrentRenderer(void)
Definition: SDL_gpu.c:633
void GPU_RemoveWindowMapping(Uint32 windowID)
Definition: SDL_gpu.c:319
Uint32 current_shader_program
Definition: SDL_gpu.h:370
#define GPU_ERROR_DETAILS_STRING_MAX
Definition: SDL_gpu.c:54
void GPU_TriangleBatchX(GPU_Image *image, GPU_Target *target, unsigned short num_vertices, void *values, unsigned int num_indices, unsigned short *indices, GPU_BatchFlagEnum flags)
Definition: SDL_gpu.c:1496
GPU_Rect viewport
Definition: SDL_gpu.h:417
GPU_FeatureEnum GPU_GetRequiredFeatures(void)
Definition: SDL_gpu.c:235
GPU_TypeEnum type
Definition: SDL_gpu.h:571
void GPU_DetachShader(Uint32 program_object, Uint32 shader_object)
Definition: SDL_gpu.c:2180
GPU_Image * GPU_CopyImageFromTarget(GPU_Target *target)
Definition: SDL_gpu.c:1254
void GPU_LogWarning(const char *format,...)
Definition: SDL_gpu.c:167
#define GPU_FEATURE_BASIC_SHADERS
Definition: SDL_gpu.h:454
GPU_RendererID id
Definition: SDL_gpu.h:656
int modelViewProjection_loc
Definition: SDL_gpu.h:323
const char *SDLCALL * GetShaderMessage(GPU_Renderer *renderer)
void GPU_BlitTransform(GPU_Image *image, GPU_Rect *src_rect, GPU_Target *target, float x, float y, float degrees, float scaleX, float scaleY)
Definition: SDL_gpu.c:1382
int window_w
Definition: SDL_gpu.h:358
#define GPU_ERROR_FUNCTION_STRING_MAX
Definition: SDL_gpu.c:53
void GPU_SetShapeBlendFunction(GPU_BlendFuncEnum source_color, GPU_BlendFuncEnum dest_color, GPU_BlendFuncEnum source_alpha, GPU_BlendFuncEnum dest_alpha)
Definition: SDL_gpu.c:1858
Uint32 GPU_InitFlagEnum
Definition: SDL_gpu.h:466
void GPU_Flip(GPU_Target *target)
Definition: SDL_gpu.c:2044
SDL_Color color
Definition: SDL_gpu.h:283
GPU_Target * GPU_CreateAliasTarget(GPU_Target *target)
Definition: SDL_gpu.c:486
GPU_BlendMode shapes_blend_mode
Definition: SDL_gpu.h:379
GPU_bool shapes_use_blending
Definition: SDL_gpu.h:378
#define GPU_DEFAULT_INIT_FLAGS
Definition: SDL_gpu.h:475
GPU_Target * GPU_GetContextTarget(void)
Definition: SDL_gpu.c:1293
void GPU_LogError(const char *format,...)
Definition: SDL_gpu.c:175
float w
Definition: SDL_gpu.h:92
void GPU_SetShaderImage(GPU_Image *image, int location, int image_unit)
Definition: SDL_gpu.c:2298
#define CHECK_CONTEXT
Definition: SDL_gpu.c:30
GPU_BlendFuncEnum source_color
Definition: SDL_gpu.h:161
void GPU_SetBlendFunction(GPU_Image *image, GPU_BlendFuncEnum source_color, GPU_BlendFuncEnum dest_color, GPU_BlendFuncEnum source_alpha, GPU_BlendFuncEnum dest_alpha)
Definition: SDL_gpu.c:1827
void GPU_SetAttributeSource(int num_values, GPU_Attribute source)
Definition: SDL_gpu.c:2446
GPU_Image * GPU_CreateImage(Uint16 w, Uint16 h, GPU_FormatEnum format)
Definition: SDL_gpu.c:906
void GPU_GetUniformiv(Uint32 program_object, int location, int *values)
Definition: SDL_gpu.c:2306
GPU_bool using_virtual_resolution
Definition: SDL_gpu.h:272
void GPU_GetVirtualCoords(GPU_Target *target, float *x, float *y, float displayX, float displayY)
Definition: SDL_gpu.c:788
#define GPU_TRUE
Definition: SDL_gpu.h:63
#define CHECK_RENDERER
Definition: SDL_gpu.c:28
void GPU_SetBlendEquation(GPU_Image *image, GPU_BlendEqEnum color_equation, GPU_BlendEqEnum alpha_equation)
Definition: SDL_gpu.c:1838
GPU_Target * current_context_target
Definition: SDL_gpu.h:667
void GPU_SetRGB(GPU_Image *image, Uint8 r, Uint8 g, Uint8 b)
Definition: SDL_gpu.c:1631
void GPU_SetViewport(GPU_Target *target, GPU_Rect viewport)
Definition: SDL_gpu.c:855
GPU_bool GPU_LinkShaderProgram(Uint32 program_object)
Definition: SDL_gpu.c:2109
float y
Definition: SDL_gpu.h:91
void gpu_free_error_queue(void)
Definition: SDL_gpu.c:602
void GPU_FreeShaderProgram(Uint32 program_object)
Definition: SDL_gpu.c:2164
GPU_bool normalize
Definition: SDL_gpu.h:572
SDL_Surface * GPU_LoadSurface_RW(SDL_RWops *rwops, GPU_bool free_rwops)
Definition: SDL_gpu.c:1089
Uint32 GPU_BatchFlagEnum
Definition: SDL_gpu.h:485
GPU_Target * target
Definition: SDL_gpu.c:45
GPU_bool GPU_SetWindowResolution(Uint16 w, Uint16 h)
Definition: SDL_gpu.c:529
void GPU_SetUniformfv(int location, int num_elements_per_value, int num_values, float *values)
Definition: SDL_gpu.c:2372
void GPU_BlitRectX(GPU_Image *image, GPU_Rect *src_rect, GPU_Target *target, GPU_Rect *dest_rect, float degrees, float pivot_x, float pivot_y, GPU_FlipEnum flip_direction)
Definition: SDL_gpu.c:1436
GPU_DebugLevelEnum GPU_GetDebugLevel(void)
Definition: SDL_gpu.c:687
Uint32 GPU_LinkManyShaders(Uint32 *shader_objects, int count)
Definition: SDL_gpu.c:2133
void GPU_SetPreInitFlags(GPU_InitFlagEnum GPU_flags)
Definition: SDL_gpu.c:220
float x
Definition: SDL_gpu.h:91
void GPU_RemoveWindowMappingByTarget(GPU_Target *target)
Definition: SDL_gpu.c:350
void GPU_SetAttributeui(int location, unsigned int value)
Definition: SDL_gpu.c:2414
void GPU_SetSnapMode(GPU_Image *image, GPU_SnapEnum mode)
Definition: SDL_gpu.c:1956
void GPU_UnsetViewport(GPU_Target *target)
Definition: SDL_gpu.c:861
GPU_Target * GPU_GetWindowTarget(Uint32 windowID)
Definition: SDL_gpu.c:385
SDL_Color GPU_GetPixel(GPU_Target *target, Sint16 x, Sint16 y)
Definition: SDL_gpu.c:1975
void GPU_FreeImage(GPU_Image *image)
Definition: SDL_gpu.c:1284
GPU_Camera GPU_GetCamera(GPU_Target *target)
Definition: SDL_gpu.c:873
GPU_SnapEnum
Definition: SDL_gpu.h:204
const char * GPU_GetShaderMessage(void)
Definition: SDL_gpu.c:2215
void GPU_SetRGBA(GPU_Image *image, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
Definition: SDL_gpu.c:1645
GPU_Target *SDLCALL * CreateAliasTarget(GPU_Renderer *renderer, GPU_Target *target)
void GPU_SetUniformiv(int location, int num_elements_per_value, int num_values, int *values)
Definition: SDL_gpu.c:2322
void GPU_SetUniformuiv(int location, int num_elements_per_value, int num_values, unsigned int *values)
Definition: SDL_gpu.c:2347
void GPU_MakeCurrent(GPU_Target *target, Uint32 windowID)
Definition: SDL_gpu.c:497
const char * name
Definition: SDL_gpu.h:121
void GPU_SetUniformf(int location, float value)
Definition: SDL_gpu.c:2364
static GLenum GLenum GLuint GLint level
Uint32 GPU_CreateShaderProgram(void)
Definition: SDL_gpu.c:2117
void GPU_ClearRGB(GPU_Target *target, Uint8 r, Uint8 g, Uint8 b)
Definition: SDL_gpu.c:2014
void GPU_SetAttributei(int location, int value)
Definition: SDL_gpu.c:2406
GPU_Renderer * gpu_create_and_add_renderer(GPU_RendererID id)
GPU_FormatEnum
Definition: SDL_gpu.h:226
GPU_Target *SDLCALL * Init(GPU_Renderer *renderer, GPU_RendererID renderer_request, Uint16 w, Uint16 h, GPU_WindowFlagEnum SDL_flags)
GPU_bool use_camera
Definition: SDL_gpu.h:421
GPU_bool GPU_SaveImage(GPU_Image *image, const char *filename, GPU_FileFormatEnum format)
Definition: SDL_gpu.c:955
GPU_AttributeFormat format
Definition: SDL_gpu.h:582
void GPU_SetBlendMode(GPU_Image *image, GPU_BlendPresetEnum preset)
Definition: SDL_gpu.c:1847
GPU_bool coordinate_mode
Definition: SDL_gpu.h:670
void GPU_BlitRotate(GPU_Image *image, GPU_Rect *src_rect, GPU_Target *target, float x, float y, float degrees)
Definition: SDL_gpu.c:1350
#define MAKE_CURRENT_IF_NONE(target)
Definition: SDL_gpu.c:29
void GPU_SetImageVirtualResolution(GPU_Image *image, Uint16 w, Uint16 h)
Definition: SDL_gpu.c:576
GPU_bool GPU_ReplaceImage(GPU_Image *image, SDL_Surface *surface, const GPU_Rect *surface_rect)
Definition: SDL_gpu.c:999
GPU_BlendFuncEnum
Definition: SDL_gpu.h:133
GPU_bool use_blending
Definition: SDL_gpu.h:284
void GPU_PushErrorCode(const char *function, GPU_ErrorEnum error, const char *details,...)
Definition: SDL_gpu.c:692
GPU_BlendPresetEnum
Definition: SDL_gpu.h:175
char * details
Definition: SDL_gpu.h:620
int GPU_GetAttributeLocation(Uint32 program_object, const char *attrib_name)
Definition: SDL_gpu.c:2223
Uint32 GPU_LinkShaders(Uint32 shader_object1, Uint32 shader_object2)
Definition: SDL_gpu.c:2125
Uint16 w
Definition: SDL_gpu.h:271
void GPU_SetAttributef(int location, float value)
Definition: SDL_gpu.c:2398
SDL_Surface *SDLCALL * CopySurfaceFromImage(GPU_Renderer *renderer, GPU_Image *image)
#define GPU_DEFAULT_MAX_NUM_ERRORS
Definition: SDL_gpu.c:52
void GPU_SetColor(GPU_Image *image, SDL_Color color)
Definition: SDL_gpu.c:1623
int texcoord_loc
Definition: SDL_gpu.h:320
void GPU_UnsetClip(GPU_Target *target)
Definition: SDL_gpu.c:1550
GPU_Image *SDLCALL * CopyImageFromTarget(GPU_Renderer *renderer, GPU_Target *target)
GPU_Camera GPU_SetCamera(GPU_Target *target, GPU_Camera *cam)
Definition: SDL_gpu.c:880
void GPU_ResetRendererState(void)
Definition: SDL_gpu.c:89
Uint32 GPU_WindowFlagEnum
Definition: SDL_gpu.h:458
void GPU_SetShaderBlock(GPU_ShaderBlock block)
Definition: SDL_gpu.c:2275
GPU_ShaderBlock current_shader_block
Definition: SDL_gpu.h:374
GPU_BlendMode blend_mode
Definition: SDL_gpu.h:285
GPU_InitFlagEnum GPU_GetPreInitFlags(void)
Definition: SDL_gpu.c:225
GPU_Target *SDLCALL * GetTarget(GPU_Renderer *renderer, GPU_Image *image)
void GPU_GetAnchor(GPU_Image *image, float *anchor_x, float *anchor_y)
Definition: SDL_gpu.c:1936
void GPU_BlitRect(GPU_Image *image, GPU_Rect *src_rect, GPU_Target *target, GPU_Rect *dest_rect)
Definition: SDL_gpu.c:1414
GPU_bool GPU_IntersectClipRect(GPU_Target *target, GPU_Rect B, GPU_Rect *result)
Definition: SDL_gpu.c:1608
GPU_Target * GPU_LoadTarget(GPU_Image *image)
Definition: SDL_gpu.c:1302
GPU_Attribute GPU_MakeAttribute(int location, void *values, GPU_AttributeFormat format)
Definition: SDL_gpu.c:2243
int major_version
Definition: SDL_gpu.h:123
void GPU_SetTargetRGBA(GPU_Target *target, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
Definition: SDL_gpu.c:1692
void GPU_Clear(GPU_Target *target)
Definition: SDL_gpu.c:1992
GPU_Image *SDLCALL * CopyImage(GPU_Renderer *renderer, GPU_Image *image)
float anchor_y
Definition: SDL_gpu.h:281
char * function
Definition: SDL_gpu.h:618
GPU_BlendMode GPU_GetBlendModeFromPreset(GPU_BlendPresetEnum preset)
Definition: SDL_gpu.c:1743
Uint32 GPU_LoadShader(GPU_ShaderEnum shader_type, const char *filename)
Definition: SDL_gpu.c:2081
GPU_bool GPU_IsFeatureEnabled(GPU_FeatureEnum feature)
Definition: SDL_gpu.c:470
void GPU_UnsetImageVirtualResolution(GPU_Image *image)
Definition: SDL_gpu.c:589
void GPU_SetImageFilter(GPU_Image *image, GPU_FilterEnum filter)
Definition: SDL_gpu.c:1895
void GPU_SetInitWindow(Uint32 windowID)
Definition: SDL_gpu.c:210
GPU_ErrorEnum error
Definition: SDL_gpu.h:619
void GPU_Blit(GPU_Image *image, GPU_Rect *src_rect, GPU_Target *target, float x, float y)
Definition: SDL_gpu.c:1333
GPU_SnapEnum GPU_GetSnapMode(GPU_Image *image)
Definition: SDL_gpu.c:1948
int window_h
Definition: SDL_gpu.h:359
GPU_Target * GPU_GetTarget(GPU_Image *image)
Definition: SDL_gpu.c:1313
#define GET_ALPHA(sdl_color)
Definition: SDL_gpu.c:25
GPU_bool is_per_sprite
Definition: SDL_gpu.h:569
Uint32 default_untextured_shader_program
Definition: SDL_gpu.h:372
Uint32 GPU_TypeEnum
Definition: SDL_gpu.h:523
void GPU_ActivateShaderProgram(Uint32 program_object, GPU_ShaderBlock *block)
Definition: SDL_gpu.c:2199
Uint32 GPU_CompileShader(GPU_ShaderEnum shader_type, const char *shader_source)
Definition: SDL_gpu.c:2101
GPU_bool GPU_SetFullscreen(GPU_bool enable_fullscreen, GPU_bool use_desktop_resolution)
Definition: SDL_gpu.c:505
GPU_ShaderBlock GPU_LoadShaderBlock(Uint32 program_object, const char *position_name, const char *texcoord_name, const char *color_name, const char *modelViewMatrix_name)
Definition: SDL_gpu.c:2260
float default_image_anchor_y
Definition: SDL_gpu.h:674
SDL_Color GPU_MakeColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a)
Definition: SDL_gpu.c:833
GPU_Target * GPU_InitRendererByID(GPU_RendererID renderer_request, Uint16 w, Uint16 h, GPU_WindowFlagEnum SDL_flags)
Definition: SDL_gpu.c:439
void GPU_UpdateImageBytes(GPU_Image *image, const GPU_Rect *image_rect, const unsigned char *bytes, int bytes_per_row)
Definition: SDL_gpu.c:991
GPU_Rect GPU_SetClip(GPU_Target *target, Sint16 x, Sint16 y, Uint16 w, Uint16 h)
Definition: SDL_gpu.c:1539
DECLSPEC GPU_Renderer *SDLCALL GPU_GetRenderer(GPU_RendererID id)
Uint32 GPU_GetCurrentShaderProgram(void)
Definition: SDL_gpu.c:118
GPU_Image * GPU_LoadImage(const char *filename)
Definition: SDL_gpu.c:922
SDL_Color color
Definition: SDL_gpu.h:415
void GPU_BlitTransformX(GPU_Image *image, GPU_Rect *src_rect, GPU_Target *target, float x, float y, float pivot_x, float pivot_y, float degrees, float scaleX, float scaleY)
Definition: SDL_gpu.c:1398
GPU_Image *SDLCALL * CreateImageUsingTexture(GPU_Renderer *renderer, Uint32 handle, GPU_bool take_ownership)
void gpu_free_renderer_register(void)
GPU_Image *SDLCALL * CreateAliasImage(GPU_Renderer *renderer, GPU_Image *image)
GPU_RendererID GPU_MakeRendererID(const char *name, GPU_RendererEnum renderer, int major_version, int minor_version)
Definition: SDL_gpu.c:844
SDL_Surface * GPU_CopySurfaceFromImage(GPU_Image *image)
Definition: SDL_gpu.c:1276
Uint32 GPU_RendererEnum
Definition: SDL_gpu.h:97
SDL_Surface *SDLCALL * CopySurfaceFromTarget(GPU_Renderer *renderer, GPU_Target *target)
void GPU_SetAttributeuiv(int location, int num_elements, unsigned int *value)
Definition: SDL_gpu.c:2438
void GPU_SetCoordinateMode(GPU_bool use_math_coords)
Definition: SDL_gpu.c:97
Uint32 GPU_GetInitWindow(void)
Definition: SDL_gpu.c:215
int gpu_strcasecmp(const char *s1, const char *s2)
Definition: SDL_gpu.c:2512
GPU_ErrorEnum
Definition: SDL_gpu.h:605
void GPU_GetVirtualResolution(GPU_Target *target, Uint16 *w, Uint16 *h)
Definition: SDL_gpu.c:538
void GPU_DeactivateShaderProgram(void)
Definition: SDL_gpu.c:2207
void GPU_SetTargetRGB(GPU_Target *target, Uint8 r, Uint8 g, Uint8 b)
Definition: SDL_gpu.c:1677
GPU_Rect GPU_MakeRect(float x, float y, float w, float h)
Definition: SDL_gpu.c:822
GPU_BlendEqEnum alpha_equation
Definition: SDL_gpu.h:167
void GPU_FreeShader(Uint32 shader_object)
Definition: SDL_gpu.c:2156
void GPU_ClearColor(GPU_Target *target, SDL_Color color)
Definition: SDL_gpu.c:2003
int GPU_GetUniformLocation(Uint32 program_object, const char *uniform_name)
Definition: SDL_gpu.c:2252
GPU_LogLevelEnum
Definition: SDL_gpu.h:642
void GPU_SetErrorQueueMax(unsigned int max)
Definition: SDL_gpu.c:624
GPU_Image * image
Definition: SDL_gpu.h:407
#define GPU_INITIAL_WINDOW_MAPPINGS_SIZE
Definition: SDL_gpu.c:60
void GPU_SetShapeBlending(GPU_bool enable)
Definition: SDL_gpu.c:1734
Uint32 GPU_FlipEnum
Definition: SDL_gpu.h:514
void GPU_UnsetColor(GPU_Image *image)
Definition: SDL_gpu.c:1659
void GPU_ClearRGBA(GPU_Target *target, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
Definition: SDL_gpu.c:2025
struct GPU_RendererImpl * impl
Definition: SDL_gpu.h:676
float anchor_x
Definition: SDL_gpu.h:280
void GPU_UpdateImage(GPU_Image *image, const GPU_Rect *image_rect, SDL_Surface *surface, const GPU_Rect *surface_rect)
Definition: SDL_gpu.c:983
GPU_bool GPU_GetFullscreen(void)
Definition: SDL_gpu.c:513
GPU_BlendFuncEnum source_alpha
Definition: SDL_gpu.h:163
GPU_bool GPU_IntersectRect(GPU_Rect A, GPU_Rect B, GPU_Rect *result)
Definition: SDL_gpu.c:1559
void GPU_SetAnchor(GPU_Image *image, float anchor_x, float anchor_y)
Definition: SDL_gpu.c:1927
#define GPU_FALSE
Definition: SDL_gpu.h:62
void GPU_SetVirtualResolution(GPU_Target *target, Uint16 w, Uint16 h)
Definition: SDL_gpu.c:552
GPU_bool use_color
Definition: SDL_gpu.h:414
void GPU_GenerateMipmaps(GPU_Image *image)
Definition: SDL_gpu.c:1517
void GPU_Quit(void)
Definition: SDL_gpu.c:642
GPU_BlendFuncEnum dest_color
Definition: SDL_gpu.h:162
GPU_bool GPU_SaveSurface(SDL_Surface *surface, const char *filename, GPU_FileFormatEnum format)
Definition: SDL_gpu.c:1149
void GPU_SetShapeBlendEquation(GPU_BlendEqEnum color_equation, GPU_BlendEqEnum alpha_equation)
Definition: SDL_gpu.c:1872
GPU_Target * GPU_CreateTargetFromWindow(Uint32 windowID)
Definition: SDL_gpu.c:478
GPU_bool GPU_GetBlending(GPU_Image *image)
Definition: SDL_gpu.c:1717
float default_image_anchor_x
Definition: SDL_gpu.h:673
void GPU_EnableCamera(GPU_Target *target, GPU_bool use_camera)
Definition: SDL_gpu.c:891
GPU_RendererEnum renderer
Definition: SDL_gpu.h:122
void GPU_SetUniformui(int location, unsigned int value)
Definition: SDL_gpu.c:2339
void GPU_TriangleBatch(GPU_Image *image, GPU_Target *target, unsigned short num_vertices, float *values, unsigned int num_indices, unsigned short *indices, GPU_BatchFlagEnum flags)
Definition: SDL_gpu.c:1491
int gpu_default_print(GPU_LogLevelEnum log_level, const char *format, va_list args)
Definition: SDL_gpu.c:127
GPU_bool GPU_IsDefaultShaderProgram(Uint32 program_object)
Definition: SDL_gpu.c:2188
DECLSPEC void SDLCALL GPU_GetRendererOrder(int *order_size, GPU_RendererID *order)
void GPU_SetLogCallback(int(*callback)(GPU_LogLevelEnum log_level, const char *format, va_list args))
Definition: SDL_gpu.c:151
void GPU_FlushBlitBuffer(void)
Definition: SDL_gpu.c:2036
void GPU_AddWindowMapping(GPU_Target *target)
Definition: SDL_gpu.c:271
#define RETURN_ERROR(code, details)
Definition: SDL_gpu.c:31
GPU_FeatureEnum enabled_features
Definition: SDL_gpu.h:664
void GPU_SetDefaultAnchor(float anchor_x, float anchor_y)
Definition: SDL_gpu.c:1906
Uint16 h
Definition: SDL_gpu.h:409
float h
Definition: SDL_gpu.h:92
GPU_Rect GPU_SetClipRect(GPU_Target *target, GPU_Rect rect)
Definition: SDL_gpu.c:1528
GPU_Image * GPU_CopyImageFromSurface(SDL_Surface *surface)
Definition: SDL_gpu.c:1246
Uint32 GPU_FeatureEnum
Definition: SDL_gpu.h:434
GPU_Context * context
Definition: SDL_gpu.h:424
GPU_Image * GPU_LoadImage_RW(SDL_RWops *rwops, GPU_bool free_rwops)
Definition: SDL_gpu.c:927
GPU_ShaderEnum
Definition: SDL_gpu.h:545
GPU_Rect clip_rect
Definition: SDL_gpu.h:413
GPU_Target * GPU_InitRenderer(GPU_RendererEnum renderer_enum, Uint16 w, Uint16 h, GPU_WindowFlagEnum SDL_flags)
Definition: SDL_gpu.c:433
void GPU_GetUniformMatrixfv(Uint32 program_object, int location, float *values)
Definition: SDL_gpu.c:2381
GPU_ShaderBlock GPU_GetShaderBlock(void)
Definition: SDL_gpu.c:2283
void GPU_BlitScale(GPU_Image *image, GPU_Rect *src_rect, GPU_Target *target, float x, float y, float scaleX, float scaleY)
Definition: SDL_gpu.c:1366
Uint32 windowID
Definition: SDL_gpu.c:44
DECLSPEC GPU_RendererID SDLCALL GPU_GetRendererID(GPU_RendererEnum renderer)
DECLSPEC void SDLCALL GPU_FreeRenderer(GPU_Renderer *renderer)
void GPU_SetDebugLevel(GPU_DebugLevelEnum level)
Definition: SDL_gpu.c:680
#define GPU_RENDERER_ORDER_MAX
Definition: SDL_gpu.h:95
Uint32 default_textured_shader_program
Definition: SDL_gpu.h:371
void GPU_SetUniformi(int location, int value)
Definition: SDL_gpu.c:2314
void GPU_SetCurrentRenderer(GPU_RendererID id)
Definition: SDL_gpu.c:81
GPU_Camera camera
Definition: SDL_gpu.h:420
int refcount
Definition: SDL_gpu.h:425
void GPU_SetWrapMode(GPU_Image *image, GPU_WrapEnum wrap_mode_x, GPU_WrapEnum wrap_mode_y)
Definition: SDL_gpu.c:1964
#define GPU_bool
Definition: SDL_gpu.h:59
GPU_Image * GPU_CreateImageUsingTexture(Uint32 handle, GPU_bool take_ownership)
Definition: SDL_gpu.c:914
GPU_Renderer * GPU_GetCurrentRenderer(void)
Definition: SDL_gpu.c:113
GPU_bool GPU_SaveImage_RW(GPU_Image *image, SDL_RWops *rwops, GPU_bool free_rwops, GPU_FileFormatEnum format)
Definition: SDL_gpu.c:963
GPU_ErrorObject GPU_PopErrorCode(void)
Definition: SDL_gpu.c:736
void GPU_GetDefaultAnchor(float *anchor_x, float *anchor_y)
Definition: SDL_gpu.c:1915
GPU_AttributeFormat GPU_MakeAttributeFormat(int num_elems_per_vertex, GPU_TypeEnum type, GPU_bool normalize, int stride_bytes, int offset_bytes)
Definition: SDL_gpu.c:2231