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  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1305  return NULL;
1306 
1307  return _gpu_current_renderer->impl->LoadTarget(_gpu_current_renderer, image);
1308 }
1309 
1310 
1311 
1313 {
1314  if(_gpu_current_renderer == NULL)
1315  return;
1316 
1317  _gpu_current_renderer->impl->FreeTarget(_gpu_current_renderer, target);
1318 }
1319 
1320 
1321 
1322 void GPU_Blit(GPU_Image* image, GPU_Rect* src_rect, GPU_Target* target, float x, float y)
1323 {
1324  if(!CHECK_RENDERER)
1325  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
1326  MAKE_CURRENT_IF_NONE(target);
1327  if(!CHECK_CONTEXT)
1328  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
1329 
1330  if(image == NULL)
1332  if(target == NULL)
1334 
1335  _gpu_current_renderer->impl->Blit(_gpu_current_renderer, image, src_rect, target, x, y);
1336 }
1337 
1338 
1339 void GPU_BlitRotate(GPU_Image* image, GPU_Rect* src_rect, GPU_Target* target, float x, float y, float degrees)
1340 {
1341  if(!CHECK_RENDERER)
1342  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
1343  MAKE_CURRENT_IF_NONE(target);
1344  if(!CHECK_CONTEXT)
1345  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
1346 
1347  if(image == NULL)
1349  if(target == NULL)
1351 
1352  _gpu_current_renderer->impl->BlitRotate(_gpu_current_renderer, image, src_rect, target, x, y, degrees);
1353 }
1354 
1355 void GPU_BlitScale(GPU_Image* image, GPU_Rect* src_rect, GPU_Target* target, float x, float y, float scaleX, float scaleY)
1356 {
1357  if(!CHECK_RENDERER)
1358  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
1359  MAKE_CURRENT_IF_NONE(target);
1360  if(!CHECK_CONTEXT)
1361  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
1362 
1363  if(image == NULL)
1365  if(target == NULL)
1367 
1368  _gpu_current_renderer->impl->BlitScale(_gpu_current_renderer, image, src_rect, target, x, y, scaleX, scaleY);
1369 }
1370 
1371 void GPU_BlitTransform(GPU_Image* image, GPU_Rect* src_rect, GPU_Target* target, float x, float y, float degrees, float scaleX, float scaleY)
1372 {
1373  if(!CHECK_RENDERER)
1374  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
1375  MAKE_CURRENT_IF_NONE(target);
1376  if(!CHECK_CONTEXT)
1377  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
1378 
1379  if(image == NULL)
1381  if(target == NULL)
1383 
1384  _gpu_current_renderer->impl->BlitTransform(_gpu_current_renderer, image, src_rect, target, x, y, degrees, scaleX, scaleY);
1385 }
1386 
1387 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)
1388 {
1389  if(!CHECK_RENDERER)
1390  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
1391  MAKE_CURRENT_IF_NONE(target);
1392  if(!CHECK_CONTEXT)
1393  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
1394 
1395  if(image == NULL)
1397  if(target == NULL)
1399 
1400  _gpu_current_renderer->impl->BlitTransformX(_gpu_current_renderer, image, src_rect, target, x, y, pivot_x, pivot_y, degrees, scaleX, scaleY);
1401 }
1402 
1403 void GPU_BlitRect(GPU_Image* image, GPU_Rect* src_rect, GPU_Target* target, GPU_Rect* dest_rect)
1404 {
1405  float w = 0.0f;
1406  float h = 0.0f;
1407 
1408  if(image == NULL)
1409  return;
1410 
1411  if(src_rect == NULL)
1412  {
1413  w = image->w;
1414  h = image->h;
1415  }
1416  else
1417  {
1418  w = src_rect->w;
1419  h = src_rect->h;
1420  }
1421 
1422  GPU_BlitRectX(image, src_rect, target, dest_rect, 0.0f, w*0.5f, h*0.5f, GPU_FLIP_NONE);
1423 }
1424 
1425 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)
1426 {
1427  float w, h;
1428  float dx, dy;
1429  float dw, dh;
1430  float scale_x, scale_y;
1431 
1432  if(image == NULL || target == NULL)
1433  return;
1434 
1435  if(src_rect == NULL)
1436  {
1437  w = image->w;
1438  h = image->h;
1439  }
1440  else
1441  {
1442  w = src_rect->w;
1443  h = src_rect->h;
1444  }
1445 
1446  if(dest_rect == NULL)
1447  {
1448  dx = 0.0f;
1449  dy = 0.0f;
1450  dw = target->w;
1451  dh = target->h;
1452  }
1453  else
1454  {
1455  dx = dest_rect->x;
1456  dy = dest_rect->y;
1457  dw = dest_rect->w;
1458  dh = dest_rect->h;
1459  }
1460 
1461  scale_x = dw / w;
1462  scale_y = dh / h;
1463 
1464  if(flip_direction & GPU_FLIP_HORIZONTAL)
1465  scale_x = -scale_x;
1466  if(flip_direction & GPU_FLIP_VERTICAL)
1467  scale_y = -scale_y;
1468 
1469  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);
1470 }
1471 
1472 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)
1473 {
1474  GPU_TriangleBatchX(image, target, num_vertices, (void*)values, num_indices, indices, flags);
1475 }
1476 
1477 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)
1478 {
1479  if(!CHECK_RENDERER)
1480  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
1481  MAKE_CURRENT_IF_NONE(target);
1482  if(!CHECK_CONTEXT)
1483  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
1484 
1485  if(target == NULL)
1487 
1488  if(num_vertices == 0)
1489  return;
1490 
1491 
1492  _gpu_current_renderer->impl->TriangleBatchX(_gpu_current_renderer, image, target, num_vertices, values, num_indices, indices, flags);
1493 }
1494 
1495 
1496 
1497 
1499 {
1500  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1501  return;
1502 
1503  _gpu_current_renderer->impl->GenerateMipmaps(_gpu_current_renderer, image);
1504 }
1505 
1506 
1507 
1508 
1510 {
1511  if(target == NULL || _gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1512  {
1513  GPU_Rect r = {0,0,0,0};
1514  return r;
1515  }
1516 
1517  return _gpu_current_renderer->impl->SetClip(_gpu_current_renderer, target, (Sint16)rect.x, (Sint16)rect.y, (Uint16)rect.w, (Uint16)rect.h);
1518 }
1519 
1520 GPU_Rect GPU_SetClip(GPU_Target* target, Sint16 x, Sint16 y, Uint16 w, Uint16 h)
1521 {
1522  if(target == NULL || _gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1523  {
1524  GPU_Rect r = {0,0,0,0};
1525  return r;
1526  }
1527 
1528  return _gpu_current_renderer->impl->SetClip(_gpu_current_renderer, target, x, y, w, h);
1529 }
1530 
1532 {
1533  if(target == NULL || _gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1534  return;
1535 
1536  _gpu_current_renderer->impl->UnsetClip(_gpu_current_renderer, target);
1537 }
1538 
1539 /* Adapted from SDL_IntersectRect() */
1541 {
1542  GPU_bool has_horiz_intersection = GPU_FALSE;
1543  float Amin, Amax, Bmin, Bmax;
1544  GPU_Rect intersection;
1545 
1546  // Special case for empty rects
1547  if (A.w <= 0.0f || A.h <= 0.0f || B.w <= 0.0f || B.h <= 0.0f)
1548  return GPU_FALSE;
1549 
1550  // Horizontal intersection
1551  Amin = A.x;
1552  Amax = Amin + A.w;
1553  Bmin = B.x;
1554  Bmax = Bmin + B.w;
1555  if (Bmin > Amin)
1556  Amin = Bmin;
1557  if (Bmax < Amax)
1558  Amax = Bmax;
1559 
1560  intersection.x = Amin;
1561  intersection.w = Amax - Amin;
1562 
1563  has_horiz_intersection = (Amax > Amin);
1564 
1565  // Vertical intersection
1566  Amin = A.y;
1567  Amax = Amin + A.h;
1568  Bmin = B.y;
1569  Bmax = Bmin + B.h;
1570  if (Bmin > Amin)
1571  Amin = Bmin;
1572  if (Bmax < Amax)
1573  Amax = Bmax;
1574 
1575  intersection.y = Amin;
1576  intersection.h = Amax - Amin;
1577 
1578  if(has_horiz_intersection && Amax > Amin)
1579  {
1580  if(result != NULL)
1581  *result = intersection;
1582  return GPU_TRUE;
1583  }
1584  else
1585  return GPU_FALSE;
1586 }
1587 
1588 
1590 {
1591  if(target == NULL)
1592  return GPU_FALSE;
1593 
1594  if(!target->use_clip_rect)
1595  {
1596  GPU_Rect A = {0, 0, target->w, target->h};
1597  return GPU_IntersectRect(A, B, result);
1598  }
1599 
1600  return GPU_IntersectRect(target->clip_rect, B, result);
1601 }
1602 
1603 
1604 void GPU_SetColor(GPU_Image* image, SDL_Color color)
1605 {
1606  if(image == NULL)
1607  return;
1608 
1609  image->color = color;
1610 }
1611 
1612 void GPU_SetRGB(GPU_Image* image, Uint8 r, Uint8 g, Uint8 b)
1613 {
1614  SDL_Color c;
1615  c.r = r;
1616  c.g = g;
1617  c.b = b;
1618  GET_ALPHA(c) = 255;
1619 
1620  if(image == NULL)
1621  return;
1622 
1623  image->color = c;
1624 }
1625 
1626 void GPU_SetRGBA(GPU_Image* image, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
1627 {
1628  SDL_Color c;
1629  c.r = r;
1630  c.g = g;
1631  c.b = b;
1632  GET_ALPHA(c) = a;
1633 
1634  if(image == NULL)
1635  return;
1636 
1637  image->color = c;
1638 }
1639 
1641 {
1642  SDL_Color c = {255, 255, 255, 255};
1643  if(image == NULL)
1644  return;
1645 
1646  image->color = c;
1647 }
1648 
1649 void GPU_SetTargetColor(GPU_Target* target, SDL_Color color)
1650 {
1651  if(target == NULL)
1652  return;
1653 
1654  target->use_color = 1;
1655  target->color = color;
1656 }
1657 
1658 void GPU_SetTargetRGB(GPU_Target* target, Uint8 r, Uint8 g, Uint8 b)
1659 {
1660  SDL_Color c;
1661  c.r = r;
1662  c.g = g;
1663  c.b = b;
1664  GET_ALPHA(c) = 255;
1665 
1666  if(target == NULL)
1667  return;
1668 
1669  target->use_color = !(r == 255 && g == 255 && b == 255);
1670  target->color = c;
1671 }
1672 
1673 void GPU_SetTargetRGBA(GPU_Target* target, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
1674 {
1675  SDL_Color c;
1676  c.r = r;
1677  c.g = g;
1678  c.b = b;
1679  GET_ALPHA(c) = a;
1680 
1681  if(target == NULL)
1682  return;
1683 
1684  target->use_color = !(r == 255 && g == 255 && b == 255 && a == 255);
1685  target->color = c;
1686 }
1687 
1689 {
1690  SDL_Color c = {255, 255, 255, 255};
1691  if(target == NULL)
1692  return;
1693 
1694  target->use_color = GPU_FALSE;
1695  target->color = c;
1696 }
1697 
1699 {
1700  if(image == NULL)
1701  return GPU_FALSE;
1702 
1703  return image->use_blending;
1704 }
1705 
1706 
1707 void GPU_SetBlending(GPU_Image* image, GPU_bool enable)
1708 {
1709  if(image == NULL)
1710  return;
1711 
1712  image->use_blending = enable;
1713 }
1714 
1716 {
1717  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1718  return;
1719 
1720  _gpu_current_renderer->current_context_target->context->shapes_use_blending = enable;
1721 }
1722 
1723 
1725 {
1726  switch(preset)
1727  {
1728  case GPU_BLEND_NORMAL:
1729  {
1731  return b;
1732  }
1733  break;
1735  {
1737  return b;
1738  }
1739  break;
1740  case GPU_BLEND_MULTIPLY:
1741  {
1743  return b;
1744  }
1745  break;
1746  case GPU_BLEND_ADD:
1747  {
1749  return b;
1750  }
1751  break;
1752  case GPU_BLEND_SUBTRACT:
1753  // FIXME: Use src alpha for source components?
1754  {
1756  return b;
1757  }
1758  break;
1759  case GPU_BLEND_MOD_ALPHA:
1760  // Don't disturb the colors, but multiply the dest alpha by the src alpha
1761  {
1763  return b;
1764  }
1765  break;
1766  case GPU_BLEND_SET_ALPHA:
1767  // Don't disturb the colors, but set the alpha to the src alpha
1768  {
1770  return b;
1771  }
1772  break;
1773  case GPU_BLEND_SET:
1774  {
1776  return b;
1777  }
1778  break;
1780  {
1782  return b;
1783  }
1784  break;
1786  {
1788  return b;
1789  }
1790  break;
1792  {
1794  return b;
1795  }
1796  break;
1797  default:
1798  GPU_PushErrorCode(__func__, GPU_ERROR_USER_ERROR, "Blend preset not supported: %d", preset);
1799  {
1801  return b;
1802  }
1803  break;
1804  }
1805 }
1806 
1807 
1808 void GPU_SetBlendFunction(GPU_Image* image, GPU_BlendFuncEnum source_color, GPU_BlendFuncEnum dest_color, GPU_BlendFuncEnum source_alpha, GPU_BlendFuncEnum dest_alpha)
1809 {
1810  if(image == NULL)
1811  return;
1812 
1813  image->blend_mode.source_color = source_color;
1814  image->blend_mode.dest_color = dest_color;
1815  image->blend_mode.source_alpha = source_alpha;
1816  image->blend_mode.dest_alpha = dest_alpha;
1817 }
1818 
1819 void GPU_SetBlendEquation(GPU_Image* image, GPU_BlendEqEnum color_equation, GPU_BlendEqEnum alpha_equation)
1820 {
1821  if(image == NULL)
1822  return;
1823 
1824  image->blend_mode.color_equation = color_equation;
1825  image->blend_mode.alpha_equation = alpha_equation;
1826 }
1827 
1829 {
1830  GPU_BlendMode b;
1831  if(image == NULL)
1832  return;
1833 
1834  b = GPU_GetBlendModeFromPreset(preset);
1837 }
1838 
1840 {
1841  GPU_Context* context;
1842  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1843  return;
1844 
1845  context = _gpu_current_renderer->current_context_target->context;
1846 
1847  context->shapes_blend_mode.source_color = source_color;
1848  context->shapes_blend_mode.dest_color = dest_color;
1849  context->shapes_blend_mode.source_alpha = source_alpha;
1850  context->shapes_blend_mode.dest_alpha = dest_alpha;
1851 }
1852 
1853 void GPU_SetShapeBlendEquation(GPU_BlendEqEnum color_equation, GPU_BlendEqEnum alpha_equation)
1854 {
1855  GPU_Context* context;
1856  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1857  return;
1858 
1859  context = _gpu_current_renderer->current_context_target->context;
1860 
1861  context->shapes_blend_mode.color_equation = color_equation;
1862  context->shapes_blend_mode.alpha_equation = alpha_equation;
1863 }
1864 
1866 {
1867  GPU_BlendMode b;
1868  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1869  return;
1870 
1871  b = GPU_GetBlendModeFromPreset(preset);
1874 }
1875 
1877 {
1878  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1879  return;
1880  if(image == NULL)
1881  return;
1882 
1883  _gpu_current_renderer->impl->SetImageFilter(_gpu_current_renderer, image, filter);
1884 }
1885 
1886 
1887 void GPU_SetDefaultAnchor(float anchor_x, float anchor_y)
1888 {
1889  if(_gpu_current_renderer == NULL)
1890  return;
1891 
1892  _gpu_current_renderer->default_image_anchor_x = anchor_x;
1893  _gpu_current_renderer->default_image_anchor_y = anchor_y;
1894 }
1895 
1896 void GPU_GetDefaultAnchor(float* anchor_x, float* anchor_y)
1897 {
1898  if(_gpu_current_renderer == NULL)
1899  return;
1900 
1901  if(anchor_x != NULL)
1902  *anchor_x = _gpu_current_renderer->default_image_anchor_x;
1903 
1904  if(anchor_y != NULL)
1905  *anchor_y = _gpu_current_renderer->default_image_anchor_y;
1906 }
1907 
1908 void GPU_SetAnchor(GPU_Image* image, float anchor_x, float anchor_y)
1909 {
1910  if(image == NULL)
1911  return;
1912 
1913  image->anchor_x = anchor_x;
1914  image->anchor_y = anchor_y;
1915 }
1916 
1917 void GPU_GetAnchor(GPU_Image* image, float* anchor_x, float* anchor_y)
1918 {
1919  if(image == NULL)
1920  return;
1921 
1922  if(anchor_x != NULL)
1923  *anchor_x = image->anchor_x;
1924 
1925  if(anchor_y != NULL)
1926  *anchor_y = image->anchor_y;
1927 }
1928 
1930 {
1931  if(image == NULL)
1932  return 0;
1933 
1934  return image->snap_mode;
1935 }
1936 
1938 {
1939  if(image == NULL)
1940  return;
1941 
1942  image->snap_mode = mode;
1943 }
1944 
1945 void GPU_SetWrapMode(GPU_Image* image, GPU_WrapEnum wrap_mode_x, GPU_WrapEnum wrap_mode_y)
1946 {
1947  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1948  return;
1949  if(image == NULL)
1950  return;
1951 
1952  _gpu_current_renderer->impl->SetWrapMode(_gpu_current_renderer, image, wrap_mode_x, wrap_mode_y);
1953 }
1954 
1955 
1956 SDL_Color GPU_GetPixel(GPU_Target* target, Sint16 x, Sint16 y)
1957 {
1958  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
1959  {
1960  SDL_Color c = {0,0,0,0};
1961  return c;
1962  }
1963 
1964  return _gpu_current_renderer->impl->GetPixel(_gpu_current_renderer, target, x, y);
1965 }
1966 
1967 
1968 
1969 
1970 
1971 
1972 
1974 {
1975  if(!CHECK_RENDERER)
1976  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
1977  MAKE_CURRENT_IF_NONE(target);
1978  if(!CHECK_CONTEXT)
1979  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
1980 
1981  _gpu_current_renderer->impl->ClearRGBA(_gpu_current_renderer, target, 0, 0, 0, 0);
1982 }
1983 
1984 void GPU_ClearColor(GPU_Target* target, SDL_Color color)
1985 {
1986  if(!CHECK_RENDERER)
1987  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
1988  MAKE_CURRENT_IF_NONE(target);
1989  if(!CHECK_CONTEXT)
1990  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
1991 
1992  _gpu_current_renderer->impl->ClearRGBA(_gpu_current_renderer, target, color.r, color.g, color.b, GET_ALPHA(color));
1993 }
1994 
1995 void GPU_ClearRGB(GPU_Target* target, Uint8 r, Uint8 g, Uint8 b)
1996 {
1997  if(!CHECK_RENDERER)
1998  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
1999  MAKE_CURRENT_IF_NONE(target);
2000  if(!CHECK_CONTEXT)
2001  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
2002 
2003  _gpu_current_renderer->impl->ClearRGBA(_gpu_current_renderer, target, r, g, b, 255);
2004 }
2005 
2006 void GPU_ClearRGBA(GPU_Target* target, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
2007 {
2008  if(!CHECK_RENDERER)
2009  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
2010  MAKE_CURRENT_IF_NONE(target);
2011  if(!CHECK_CONTEXT)
2012  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
2013 
2014  _gpu_current_renderer->impl->ClearRGBA(_gpu_current_renderer, target, r, g, b, a);
2015 }
2016 
2018 {
2019  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2020  return;
2021 
2022  _gpu_current_renderer->impl->FlushBlitBuffer(_gpu_current_renderer);
2023 }
2024 
2026 {
2027  if(!CHECK_RENDERER)
2028  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL renderer");
2029 
2030  if(target != NULL && target->context == NULL)
2031  {
2032  _gpu_current_renderer->impl->FlushBlitBuffer(_gpu_current_renderer);
2033  return;
2034  }
2035 
2036  MAKE_CURRENT_IF_NONE(target);
2037  if(!CHECK_CONTEXT)
2038  RETURN_ERROR(GPU_ERROR_USER_ERROR, "NULL context");
2039 
2040  _gpu_current_renderer->impl->Flip(_gpu_current_renderer, target);
2041 }
2042 
2043 
2044 
2045 
2046 
2047 // Shader API
2048 
2049 
2050 Uint32 GPU_CompileShader_RW(GPU_ShaderEnum shader_type, SDL_RWops* shader_source, GPU_bool free_rwops)
2051 {
2052  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2053  {
2054  if(free_rwops)
2055  SDL_RWclose(shader_source);
2056  return GPU_FALSE;
2057  }
2058 
2059  return _gpu_current_renderer->impl->CompileShader_RW(_gpu_current_renderer, shader_type, shader_source, free_rwops);
2060 }
2061 
2062 Uint32 GPU_LoadShader(GPU_ShaderEnum shader_type, const char* filename)
2063 {
2064  SDL_RWops* rwops;
2065 
2066  if(filename == NULL)
2067  {
2068  GPU_PushErrorCode(__func__, GPU_ERROR_NULL_ARGUMENT, "filename");
2069  return 0;
2070  }
2071 
2072  rwops = SDL_RWFromFile(filename, "r");
2073  if(rwops == NULL)
2074  {
2075  GPU_PushErrorCode(__func__, GPU_ERROR_FILE_NOT_FOUND, "%s", filename);
2076  return 0;
2077  }
2078 
2079  return GPU_CompileShader_RW(shader_type, rwops, 1);
2080 }
2081 
2082 Uint32 GPU_CompileShader(GPU_ShaderEnum shader_type, const char* shader_source)
2083 {
2084  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2085  return 0;
2086 
2087  return _gpu_current_renderer->impl->CompileShader(_gpu_current_renderer, shader_type, shader_source);
2088 }
2089 
2090 GPU_bool GPU_LinkShaderProgram(Uint32 program_object)
2091 {
2092  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2093  return GPU_FALSE;
2094 
2095  return _gpu_current_renderer->impl->LinkShaderProgram(_gpu_current_renderer, program_object);
2096 }
2097 
2099 {
2100  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2101  return 0;
2102 
2103  return _gpu_current_renderer->impl->CreateShaderProgram(_gpu_current_renderer);
2104 }
2105 
2106 Uint32 GPU_LinkShaders(Uint32 shader_object1, Uint32 shader_object2)
2107 {
2108  Uint32 shaders[2];
2109  shaders[0] = shader_object1;
2110  shaders[1] = shader_object2;
2111  return GPU_LinkManyShaders(shaders, 2);
2112 }
2113 
2114 Uint32 GPU_LinkManyShaders(Uint32 *shader_objects, int count)
2115 {
2116  Uint32 p;
2117  int i;
2118 
2119  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2120  return 0;
2121 
2122  if((_gpu_current_renderer->enabled_features & GPU_FEATURE_BASIC_SHADERS) != GPU_FEATURE_BASIC_SHADERS)
2123  return 0;
2124 
2125  p = _gpu_current_renderer->impl->CreateShaderProgram(_gpu_current_renderer);
2126 
2127  for (i = 0; i < count; i++)
2128  _gpu_current_renderer->impl->AttachShader(_gpu_current_renderer, p, shader_objects[i]);
2129 
2130  if(_gpu_current_renderer->impl->LinkShaderProgram(_gpu_current_renderer, p))
2131  return p;
2132 
2133  _gpu_current_renderer->impl->FreeShaderProgram(_gpu_current_renderer, p);
2134  return 0;
2135 }
2136 
2137 void GPU_FreeShader(Uint32 shader_object)
2138 {
2139  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2140  return;
2141 
2142  _gpu_current_renderer->impl->FreeShader(_gpu_current_renderer, shader_object);
2143 }
2144 
2145 void GPU_FreeShaderProgram(Uint32 program_object)
2146 {
2147  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2148  return;
2149 
2150  _gpu_current_renderer->impl->FreeShaderProgram(_gpu_current_renderer, program_object);
2151 }
2152 
2153 void GPU_AttachShader(Uint32 program_object, Uint32 shader_object)
2154 {
2155  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2156  return;
2157 
2158  _gpu_current_renderer->impl->AttachShader(_gpu_current_renderer, program_object, shader_object);
2159 }
2160 
2161 void GPU_DetachShader(Uint32 program_object, Uint32 shader_object)
2162 {
2163  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2164  return;
2165 
2166  _gpu_current_renderer->impl->DetachShader(_gpu_current_renderer, program_object, shader_object);
2167 }
2168 
2169 GPU_bool GPU_IsDefaultShaderProgram(Uint32 program_object)
2170 {
2171  GPU_Context* context;
2172 
2173  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2174  return GPU_FALSE;
2175 
2176  context = _gpu_current_renderer->current_context_target->context;
2177  return (program_object == context->default_textured_shader_program || program_object == context->default_untextured_shader_program);
2178 }
2179 
2180 void GPU_ActivateShaderProgram(Uint32 program_object, GPU_ShaderBlock* block)
2181 {
2182  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2183  return;
2184 
2185  _gpu_current_renderer->impl->ActivateShaderProgram(_gpu_current_renderer, program_object, block);
2186 }
2187 
2189 {
2190  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2191  return;
2192 
2193  _gpu_current_renderer->impl->DeactivateShaderProgram(_gpu_current_renderer);
2194 }
2195 
2196 const char* GPU_GetShaderMessage(void)
2197 {
2198  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2199  return NULL;
2200 
2201  return _gpu_current_renderer->impl->GetShaderMessage(_gpu_current_renderer);
2202 }
2203 
2204 int GPU_GetAttributeLocation(Uint32 program_object, const char* attrib_name)
2205 {
2206  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2207  return 0;
2208 
2209  return _gpu_current_renderer->impl->GetAttributeLocation(_gpu_current_renderer, program_object, attrib_name);
2210 }
2211 
2212 GPU_AttributeFormat GPU_MakeAttributeFormat(int num_elems_per_vertex, GPU_TypeEnum type, GPU_bool normalize, int stride_bytes, int offset_bytes)
2213 {
2216  f.num_elems_per_value = num_elems_per_vertex;
2217  f.type = type;
2218  f.normalize = normalize;
2219  f.stride_bytes = stride_bytes;
2220  f.offset_bytes = offset_bytes;
2221  return f;
2222 }
2223 
2224 GPU_Attribute GPU_MakeAttribute(int location, void* values, GPU_AttributeFormat format)
2225 {
2226  GPU_Attribute a;
2227  a.location = location;
2228  a.values = values;
2229  a.format = format;
2230  return a;
2231 }
2232 
2233 int GPU_GetUniformLocation(Uint32 program_object, const char* uniform_name)
2234 {
2235  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2236  return 0;
2237 
2238  return _gpu_current_renderer->impl->GetUniformLocation(_gpu_current_renderer, program_object, uniform_name);
2239 }
2240 
2241 GPU_ShaderBlock GPU_LoadShaderBlock(Uint32 program_object, const char* position_name, const char* texcoord_name, const char* color_name, const char* modelViewMatrix_name)
2242 {
2243  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2244  {
2245  GPU_ShaderBlock b;
2246  b.position_loc = -1;
2247  b.texcoord_loc = -1;
2248  b.color_loc = -1;
2249  b.modelViewProjection_loc = -1;
2250  return b;
2251  }
2252 
2253  return _gpu_current_renderer->impl->LoadShaderBlock(_gpu_current_renderer, program_object, position_name, texcoord_name, color_name, modelViewMatrix_name);
2254 }
2255 
2257 {
2258  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2259  return;
2260 
2261  _gpu_current_renderer->current_context_target->context->current_shader_block = block;
2262 }
2263 
2265 {
2266  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2267  {
2268  GPU_ShaderBlock b;
2269  b.position_loc = -1;
2270  b.texcoord_loc = -1;
2271  b.color_loc = -1;
2272  b.modelViewProjection_loc = -1;
2273  return b;
2274  }
2275 
2276  return _gpu_current_renderer->current_context_target->context->current_shader_block;
2277 }
2278 
2279 void GPU_SetShaderImage(GPU_Image* image, int location, int image_unit)
2280 {
2281  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2282  return;
2283 
2284  _gpu_current_renderer->impl->SetShaderImage(_gpu_current_renderer, image, location, image_unit);
2285 }
2286 
2287 void GPU_GetUniformiv(Uint32 program_object, int location, int* values)
2288 {
2289  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2290  return;
2291 
2292  _gpu_current_renderer->impl->GetUniformiv(_gpu_current_renderer, program_object, location, values);
2293 }
2294 
2295 void GPU_SetUniformi(int location, int value)
2296 {
2297  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2298  return;
2299 
2300  _gpu_current_renderer->impl->SetUniformi(_gpu_current_renderer, location, value);
2301 }
2302 
2303 void GPU_SetUniformiv(int location, int num_elements_per_value, int num_values, int* values)
2304 {
2305  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2306  return;
2307 
2308  _gpu_current_renderer->impl->SetUniformiv(_gpu_current_renderer, location, num_elements_per_value, num_values, values);
2309 }
2310 
2311 
2312 void GPU_GetUniformuiv(Uint32 program_object, int location, unsigned int* values)
2313 {
2314  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2315  return;
2316 
2317  _gpu_current_renderer->impl->GetUniformuiv(_gpu_current_renderer, program_object, location, values);
2318 }
2319 
2320 void GPU_SetUniformui(int location, unsigned int value)
2321 {
2322  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2323  return;
2324 
2325  _gpu_current_renderer->impl->SetUniformui(_gpu_current_renderer, location, value);
2326 }
2327 
2328 void GPU_SetUniformuiv(int location, int num_elements_per_value, int num_values, unsigned int* values)
2329 {
2330  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2331  return;
2332 
2333  _gpu_current_renderer->impl->SetUniformuiv(_gpu_current_renderer, location, num_elements_per_value, num_values, values);
2334 }
2335 
2336 
2337 void GPU_GetUniformfv(Uint32 program_object, int location, float* values)
2338 {
2339  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2340  return;
2341 
2342  _gpu_current_renderer->impl->GetUniformfv(_gpu_current_renderer, program_object, location, values);
2343 }
2344 
2345 void GPU_SetUniformf(int location, float value)
2346 {
2347  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2348  return;
2349 
2350  _gpu_current_renderer->impl->SetUniformf(_gpu_current_renderer, location, value);
2351 }
2352 
2353 void GPU_SetUniformfv(int location, int num_elements_per_value, int num_values, float* values)
2354 {
2355  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2356  return;
2357 
2358  _gpu_current_renderer->impl->SetUniformfv(_gpu_current_renderer, location, num_elements_per_value, num_values, values);
2359 }
2360 
2361 // Same as GPU_GetUniformfv()
2362 void GPU_GetUniformMatrixfv(Uint32 program_object, int location, float* values)
2363 {
2364  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2365  return;
2366 
2367  _gpu_current_renderer->impl->GetUniformfv(_gpu_current_renderer, program_object, location, values);
2368 }
2369 
2370 void GPU_SetUniformMatrixfv(int location, int num_matrices, int num_rows, int num_columns, GPU_bool transpose, float* values)
2371 {
2372  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2373  return;
2374 
2375  _gpu_current_renderer->impl->SetUniformMatrixfv(_gpu_current_renderer, location, num_matrices, num_rows, num_columns, transpose, values);
2376 }
2377 
2378 
2379 void GPU_SetAttributef(int location, float value)
2380 {
2381  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2382  return;
2383 
2384  _gpu_current_renderer->impl->SetAttributef(_gpu_current_renderer, location, value);
2385 }
2386 
2387 void GPU_SetAttributei(int location, int value)
2388 {
2389  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2390  return;
2391 
2392  _gpu_current_renderer->impl->SetAttributei(_gpu_current_renderer, location, value);
2393 }
2394 
2395 void GPU_SetAttributeui(int location, unsigned int value)
2396 {
2397  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2398  return;
2399 
2400  _gpu_current_renderer->impl->SetAttributeui(_gpu_current_renderer, location, value);
2401 }
2402 
2403 void GPU_SetAttributefv(int location, int num_elements, float* value)
2404 {
2405  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2406  return;
2407 
2408  _gpu_current_renderer->impl->SetAttributefv(_gpu_current_renderer, location, num_elements, value);
2409 }
2410 
2411 void GPU_SetAttributeiv(int location, int num_elements, int* value)
2412 {
2413  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2414  return;
2415 
2416  _gpu_current_renderer->impl->SetAttributeiv(_gpu_current_renderer, location, num_elements, value);
2417 }
2418 
2419 void GPU_SetAttributeuiv(int location, int num_elements, unsigned int* value)
2420 {
2421  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2422  return;
2423 
2424  _gpu_current_renderer->impl->SetAttributeuiv(_gpu_current_renderer, location, num_elements, value);
2425 }
2426 
2427 void GPU_SetAttributeSource(int num_values, GPU_Attribute source)
2428 {
2429  if(_gpu_current_renderer == NULL || _gpu_current_renderer->current_context_target == NULL)
2430  return;
2431 
2432  _gpu_current_renderer->impl->SetAttributeSource(_gpu_current_renderer, num_values, source);
2433 }
2434 
2435 
2436 
2437 
2438 // gpu_strcasecmp()
2439 // A portable strcasecmp() from UC Berkeley
2440 /*
2441  * Copyright (c) 1987 Regents of the University of California.
2442  * All rights reserved.
2443  *
2444  * Redistribution and use in source and binary forms are permitted
2445  * provided that this notice is preserved and that due credit is given
2446  * to the University of California at Berkeley. The name of the University
2447  * may not be used to endorse or promote products derived from this
2448  * software without specific written prior permission. This software
2449  * is provided ``as is'' without express or implied warranty.
2450  */
2451 
2452 /*
2453  * This array is designed for mapping upper and lower case letter
2454  * together for a case independent comparison. The mappings are
2455  * based upon ascii character sequences.
2456  */
2457 static const unsigned char caseless_charmap[] =
2458 {
2459  '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
2460  '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
2461  '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
2462  '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
2463  '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
2464  '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
2465  '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
2466  '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
2467  '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
2468  '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
2469  '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
2470  '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
2471  '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
2472  '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
2473  '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
2474  '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
2475  '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
2476  '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
2477  '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
2478  '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
2479  '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
2480  '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
2481  '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
2482  '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
2483  '\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
2484  '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
2485  '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
2486  '\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337',
2487  '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
2488  '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
2489  '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
2490  '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
2491 };
2492 
2493 int gpu_strcasecmp(const char* s1, const char* s2)
2494 {
2495  unsigned char u1, u2;
2496 
2497  for (;;)
2498  {
2499  u1 = (unsigned char) *s1++;
2500  u2 = (unsigned char) *s2++;
2501  if (caseless_charmap[u1] != caseless_charmap[u2])
2502  return caseless_charmap[u1] - caseless_charmap[u2];
2503  if (u1 == '\0')
2504  return 0;
2505  }
2506  return 0;
2507 }
2508 
2509 
2510 #ifdef _MSC_VER
2511  #pragma warning(pop)
2512 #endif
2513 
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:2411
int minor_version
Definition: SDL_gpu.h:124
Uint16 w
Definition: SDL_gpu.h:404
void GPU_SetTargetColor(GPU_Target *target, SDL_Color color)
Definition: SDL_gpu.c:1649
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:1707
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:2403
GPU_Target *SDLCALL * CreateTargetFromWindow(GPU_Renderer *renderer, Uint32 windowID, GPU_Target *target)
void * values
Definition: SDL_gpu.h:573
GPU_FilterEnum
Definition: SDL_gpu.h:193
void GPU_UnsetTargetColor(GPU_Target *target)
Definition: SDL_gpu.c:1688
GPU_FileFormatEnum
Definition: SDL_gpu.h:244
void GPU_GetUniformuiv(Uint32 program_object, int location, unsigned int *values)
Definition: SDL_gpu.c:2312
void GPU_SetShapeBlendMode(GPU_BlendPresetEnum preset)
Definition: SDL_gpu.c:1865
Uint16 base_h
Definition: SDL_gpu.h:273
GPU_WrapEnum
Definition: SDL_gpu.h:216
GPU_BlendFuncEnum dest_alpha
Definition: SDL_gpu.h:164
int location
Definition: SDL_gpu.h:572
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:621
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:2050
int position_loc
Definition: SDL_gpu.h:316
void GPU_FreeTarget(GPU_Target *target)
Definition: SDL_gpu.c:1312
Uint16 base_w
Definition: SDL_gpu.h:273
GPU_bool use_clip_rect
Definition: SDL_gpu.h:407
Uint16 h
Definition: SDL_gpu.h:268
GPU_Target * GPU_Init(Uint16 w, Uint16 h, GPU_WindowFlagEnum SDL_flags)
Definition: SDL_gpu.c:405
Uint32 windowID
Definition: SDL_gpu.h:352
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:284
void GPU_UnsetVirtualResolution(GPU_Target *target)
Definition: SDL_gpu.c:565
void GPU_AttachShader(Uint32 program_object, Uint32 shader_object)
Definition: SDL_gpu.c:2153
void GPU_GetUniformfv(Uint32 program_object, int location, float *values)
Definition: SDL_gpu.c:2337
void GPU_SetUniformMatrixfv(int location, int num_matrices, int num_rows, int num_columns, GPU_bool transpose, float *values)
Definition: SDL_gpu.c:2370
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:367
#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:1477
GPU_Rect viewport
Definition: SDL_gpu.h:412
GPU_FeatureEnum GPU_GetRequiredFeatures(void)
Definition: SDL_gpu.c:235
GPU_TypeEnum type
Definition: SDL_gpu.h:563
void GPU_DetachShader(Uint32 program_object, Uint32 shader_object)
Definition: SDL_gpu.c:2161
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:448
GPU_RendererID id
Definition: SDL_gpu.h:648
int modelViewProjection_loc
Definition: SDL_gpu.h:320
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:1371
int window_w
Definition: SDL_gpu.h:355
#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:1839
Uint32 GPU_InitFlagEnum
Definition: SDL_gpu.h:460
void GPU_Flip(GPU_Target *target)
Definition: SDL_gpu.c:2025
SDL_Color color
Definition: SDL_gpu.h:280
GPU_Target * GPU_CreateAliasTarget(GPU_Target *target)
Definition: SDL_gpu.c:486
GPU_BlendMode shapes_blend_mode
Definition: SDL_gpu.h:376
GPU_bool shapes_use_blending
Definition: SDL_gpu.h:375
#define GPU_DEFAULT_INIT_FLAGS
Definition: SDL_gpu.h:467
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:2279
#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:1808
void GPU_SetAttributeSource(int num_values, GPU_Attribute source)
Definition: SDL_gpu.c:2427
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:2287
GPU_bool using_virtual_resolution
Definition: SDL_gpu.h:269
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:1819
GPU_Target * current_context_target
Definition: SDL_gpu.h:659
void GPU_SetRGB(GPU_Image *image, Uint8 r, Uint8 g, Uint8 b)
Definition: SDL_gpu.c:1612
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:2090
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:2145
GPU_bool normalize
Definition: SDL_gpu.h:564
SDL_Surface * GPU_LoadSurface_RW(SDL_RWops *rwops, GPU_bool free_rwops)
Definition: SDL_gpu.c:1089
Uint32 GPU_BatchFlagEnum
Definition: SDL_gpu.h:477
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:2353
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:1425
GPU_DebugLevelEnum GPU_GetDebugLevel(void)
Definition: SDL_gpu.c:687
Uint32 GPU_LinkManyShaders(Uint32 *shader_objects, int count)
Definition: SDL_gpu.c:2114
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:2395
void GPU_SetSnapMode(GPU_Image *image, GPU_SnapEnum mode)
Definition: SDL_gpu.c:1937
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:1956
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:2196
void GPU_SetRGBA(GPU_Image *image, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
Definition: SDL_gpu.c:1626
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:2303
void GPU_SetUniformuiv(int location, int num_elements_per_value, int num_values, unsigned int *values)
Definition: SDL_gpu.c:2328
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:2345
Uint32 GPU_CreateShaderProgram(void)
Definition: SDL_gpu.c:2098
void GPU_ClearRGB(GPU_Target *target, Uint8 r, Uint8 g, Uint8 b)
Definition: SDL_gpu.c:1995
void GPU_SetAttributei(int location, int value)
Definition: SDL_gpu.c:2387
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:416
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:574
void GPU_SetBlendMode(GPU_Image *image, GPU_BlendPresetEnum preset)
Definition: SDL_gpu.c:1828
GPU_bool coordinate_mode
Definition: SDL_gpu.h:662
void GPU_BlitRotate(GPU_Image *image, GPU_Rect *src_rect, GPU_Target *target, float x, float y, float degrees)
Definition: SDL_gpu.c:1339
#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:281
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:612
int GPU_GetAttributeLocation(Uint32 program_object, const char *attrib_name)
Definition: SDL_gpu.c:2204
Uint32 GPU_LinkShaders(Uint32 shader_object1, Uint32 shader_object2)
Definition: SDL_gpu.c:2106
Uint16 w
Definition: SDL_gpu.h:268
void GPU_SetAttributef(int location, float value)
Definition: SDL_gpu.c:2379
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:1604
GPU_Target *SDLCALL * LoadTarget(GPU_Renderer *renderer, GPU_Image *image)
int texcoord_loc
Definition: SDL_gpu.h:317
void GPU_UnsetClip(GPU_Target *target)
Definition: SDL_gpu.c:1531
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:452
void GPU_SetShaderBlock(GPU_ShaderBlock block)
Definition: SDL_gpu.c:2256
GPU_ShaderBlock current_shader_block
Definition: SDL_gpu.h:371
GPU_BlendMode blend_mode
Definition: SDL_gpu.h:282
GPU_InitFlagEnum GPU_GetPreInitFlags(void)
Definition: SDL_gpu.c:225
void GPU_GetAnchor(GPU_Image *image, float *anchor_x, float *anchor_y)
Definition: SDL_gpu.c:1917
void GPU_BlitRect(GPU_Image *image, GPU_Rect *src_rect, GPU_Target *target, GPU_Rect *dest_rect)
Definition: SDL_gpu.c:1403
GPU_bool GPU_IntersectClipRect(GPU_Target *target, GPU_Rect B, GPU_Rect *result)
Definition: SDL_gpu.c:1589
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:2224
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:1673
void GPU_Clear(GPU_Target *target)
Definition: SDL_gpu.c:1973
GPU_Image *SDLCALL * CopyImage(GPU_Renderer *renderer, GPU_Image *image)
float anchor_y
Definition: SDL_gpu.h:278
char * function
Definition: SDL_gpu.h:610
GPU_BlendMode GPU_GetBlendModeFromPreset(GPU_BlendPresetEnum preset)
Definition: SDL_gpu.c:1724
Uint32 GPU_LoadShader(GPU_ShaderEnum shader_type, const char *filename)
Definition: SDL_gpu.c:2062
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:1876
void GPU_SetInitWindow(Uint32 windowID)
Definition: SDL_gpu.c:210
GPU_ErrorEnum error
Definition: SDL_gpu.h:611
void GPU_Blit(GPU_Image *image, GPU_Rect *src_rect, GPU_Target *target, float x, float y)
Definition: SDL_gpu.c:1322
GPU_SnapEnum GPU_GetSnapMode(GPU_Image *image)
Definition: SDL_gpu.c:1929
int window_h
Definition: SDL_gpu.h:356
#define GET_ALPHA(sdl_color)
Definition: SDL_gpu.c:25
GPU_bool is_per_sprite
Definition: SDL_gpu.h:561
Uint32 default_untextured_shader_program
Definition: SDL_gpu.h:369
Uint32 GPU_TypeEnum
Definition: SDL_gpu.h:515
void GPU_ActivateShaderProgram(Uint32 program_object, GPU_ShaderBlock *block)
Definition: SDL_gpu.c:2180
Uint32 GPU_CompileShader(GPU_ShaderEnum shader_type, const char *shader_source)
Definition: SDL_gpu.c:2082
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:2241
float default_image_anchor_y
Definition: SDL_gpu.h:666
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:1520
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:410
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:1387
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:2419
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:2493
GPU_ErrorEnum
Definition: SDL_gpu.h:597
void GPU_GetVirtualResolution(GPU_Target *target, Uint16 *w, Uint16 *h)
Definition: SDL_gpu.c:538
void GPU_DeactivateShaderProgram(void)
Definition: SDL_gpu.c:2188
void GPU_SetTargetRGB(GPU_Target *target, Uint8 r, Uint8 g, Uint8 b)
Definition: SDL_gpu.c:1658
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:2137
void GPU_ClearColor(GPU_Target *target, SDL_Color color)
Definition: SDL_gpu.c:1984
int GPU_GetUniformLocation(Uint32 program_object, const char *uniform_name)
Definition: SDL_gpu.c:2233
GPU_LogLevelEnum
Definition: SDL_gpu.h:634
void GPU_SetErrorQueueMax(unsigned int max)
Definition: SDL_gpu.c:624
GPU_Image * image
Definition: SDL_gpu.h:402
#define GPU_INITIAL_WINDOW_MAPPINGS_SIZE
Definition: SDL_gpu.c:60
void GPU_SetShapeBlending(GPU_bool enable)
Definition: SDL_gpu.c:1715
Uint32 GPU_FlipEnum
Definition: SDL_gpu.h:506
void GPU_UnsetColor(GPU_Image *image)
Definition: SDL_gpu.c:1640
void GPU_ClearRGBA(GPU_Target *target, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
Definition: SDL_gpu.c:2006
struct GPU_RendererImpl * impl
Definition: SDL_gpu.h:668
float anchor_x
Definition: SDL_gpu.h:277
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:1540
void GPU_SetAnchor(GPU_Image *image, float anchor_x, float anchor_y)
Definition: SDL_gpu.c:1908
#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:409
void GPU_GenerateMipmaps(GPU_Image *image)
Definition: SDL_gpu.c:1498
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:1853
GPU_Target * GPU_CreateTargetFromWindow(Uint32 windowID)
Definition: SDL_gpu.c:478
GPU_bool GPU_GetBlending(GPU_Image *image)
Definition: SDL_gpu.c:1698
float default_image_anchor_x
Definition: SDL_gpu.h:665
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:2320
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:1472
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:2169
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:2017
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:656
void GPU_SetDefaultAnchor(float anchor_x, float anchor_y)
Definition: SDL_gpu.c:1887
Uint16 h
Definition: SDL_gpu.h:404
float h
Definition: SDL_gpu.h:92
GPU_Rect GPU_SetClipRect(GPU_Target *target, GPU_Rect rect)
Definition: SDL_gpu.c:1509
GPU_Image * GPU_CopyImageFromSurface(SDL_Surface *surface)
Definition: SDL_gpu.c:1246
Uint32 GPU_FeatureEnum
Definition: SDL_gpu.h:429
GPU_Context * context
Definition: SDL_gpu.h:419
GPU_Image * GPU_LoadImage_RW(SDL_RWops *rwops, GPU_bool free_rwops)
Definition: SDL_gpu.c:927
GPU_ShaderEnum
Definition: SDL_gpu.h:537
GPU_Rect clip_rect
Definition: SDL_gpu.h:408
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:2362
GPU_ShaderBlock GPU_GetShaderBlock(void)
Definition: SDL_gpu.c:2264
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:1355
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:368
void GPU_SetUniformi(int location, int value)
Definition: SDL_gpu.c:2295
void GPU_SetCurrentRenderer(GPU_RendererID id)
Definition: SDL_gpu.c:81
GPU_Camera camera
Definition: SDL_gpu.h:415
void GPU_SetWrapMode(GPU_Image *image, GPU_WrapEnum wrap_mode_x, GPU_WrapEnum wrap_mode_y)
Definition: SDL_gpu.c:1945
#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:1896
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:2212