// Create a new renderer based on a registered id and store it in the map. GPU_Renderer* gpu_create_and_add_renderer(GPU_RendererID id) { int i; for(i = 0; i < GPU_MAX_ACTIVE_RENDERERS; i++) { if(_gpu_renderer_map[i] == NULL) { // Create GPU_Renderer* renderer = GPU_CreateRenderer(id); if(renderer == NULL) { GPU_PushErrorCode(__func__, GPU_ERROR_BACKEND_ERROR, "Failed to create new renderer."); return NULL; } // Add _gpu_renderer_map[i] = renderer; // Return return renderer; } } GPU_PushErrorCode(__func__, GPU_ERROR_BACKEND_ERROR, "Couldn't create a new renderer. Too many active renderers for GPU_MAX_ACTIVE_RENDERERS (%d).", GPU_MAX_ACTIVE_RENDERERS); return NULL; }
void GPU_RegisterRenderer(GPU_RendererID id, GPU_Renderer* (*create_renderer)(GPU_RendererID request), void (*free_renderer)(GPU_Renderer* renderer)) { int i = GPU_GetNumRegisteredRenderers(); if(i >= GPU_MAX_REGISTERED_RENDERERS) return; if(id.renderer == GPU_RENDERER_UNKNOWN) { GPU_PushErrorCode(__func__, GPU_ERROR_USER_ERROR, "Invalid renderer ID"); return; } if(create_renderer == NULL) { GPU_PushErrorCode(__func__, GPU_ERROR_USER_ERROR, "NULL renderer create callback"); return; } if(free_renderer == NULL) { GPU_PushErrorCode(__func__, GPU_ERROR_USER_ERROR, "NULL renderer free callback"); return; } _gpu_renderer_register[i].id = id; _gpu_renderer_register[i].createFn = create_renderer; _gpu_renderer_register[i].freeFn = free_renderer; }
GPU_Renderer* GPU_CreateRenderer(GPU_RendererID id) { GPU_Renderer* result = NULL; int i; for(i = 0; i < GPU_MAX_REGISTERED_RENDERERS; i++) { if(_gpu_renderer_register[i].id.renderer == GPU_RENDERER_UNKNOWN) continue; if(id.renderer == _gpu_renderer_register[i].id.renderer) { if(_gpu_renderer_register[i].createFn != NULL) { // Use the registered name id.name = _gpu_renderer_register[i].id.name; result = _gpu_renderer_register[i].createFn(id); } break; } } if(result == NULL) { GPU_PushErrorCode(__func__, GPU_ERROR_DATA_ERROR, "Renderer was not found in the renderer registry."); } return result; }
// Create a new renderer based on a registered id and store it in the map. GPU_Renderer* GPU_AddRenderer(GPU_RendererID id) { int i; for(i = 0; i < MAX_ACTIVE_RENDERERS; i++) { if(rendererMap[i] == NULL) { // Create GPU_Renderer* renderer = GPU_CreateRenderer(id); if(renderer == NULL) { GPU_PushErrorCode(__func__, GPU_ERROR_BACKEND_ERROR, "Failed to create new renderer."); return NULL; } // Add rendererMap[i] = renderer; renderer->id.index = i; // Return return renderer; } } return NULL; }
static GPU_Target* Init(GPU_Renderer* renderer, GPU_RendererID renderer_request, Uint16 w, Uint16 h, GPU_WindowFlagEnum SDL_flags) { SDL_Window* window; GPU_Log(" %s (dummy)\n", __func__); renderer->requested_id = renderer_request; renderer->GPU_init_flags = GPU_GetPreInitFlags(); renderer->SDL_init_flags = SDL_flags; window = NULL; // Is there a window already set up that we are supposed to use? if(renderer->current_context_target != NULL) window = SDL_GetWindowFromID(renderer->current_context_target->context->windowID); else window = SDL_GetWindowFromID(GPU_GetInitWindow()); if(window == NULL) { // Set up window flags if(!(renderer->SDL_init_flags & SDL_WINDOW_HIDDEN)) renderer->SDL_init_flags |= SDL_WINDOW_SHOWN; window = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, w, h, renderer->SDL_init_flags); if(window == NULL) { GPU_PushErrorCode("GPU_Init", GPU_ERROR_BACKEND_ERROR, "Window creation failed."); return NULL; } GPU_SetInitWindow(SDL_GetWindowID(window)); } else renderer->SDL_init_flags = SDL_flags; renderer->enabled_features = 0xFFFFFFFF; // Pretend to support them all renderer->current_context_target = renderer->impl->CreateTargetFromWindow(renderer, SDL_GetWindowID(window), renderer->current_context_target); if(renderer->current_context_target == NULL) return NULL; // If the dimensions of the window don't match what we asked for, then set up a virtual resolution to pretend like they are. if(!(renderer->GPU_init_flags & GPU_INIT_DISABLE_AUTO_VIRTUAL_RESOLUTION) && w != 0 && h != 0 && (w != renderer->current_context_target->w || h != renderer->current_context_target->h)) renderer->impl->SetVirtualResolution(renderer, renderer->current_context_target, w, h); return renderer->current_context_target; }
void GPU_PopMatrix(void) { GPU_Target* target = GPU_GetContextTarget(); GPU_MatrixStack* stack; if(target == NULL || target->context == NULL) return; stack = (target->context->matrix_mode == GPU_MODELVIEW? &target->context->modelview_matrix : &target->context->projection_matrix); if(stack->size == 0) { GPU_PushErrorCode(__func__, GPU_ERROR_USER_ERROR, "Matrix stack is empty."); return; } stack->size--; }
void GPU_PushMatrix(void) { GPU_Target* target = GPU_GetContextTarget(); GPU_MatrixStack* stack; if(target == NULL || target->context == NULL) return; stack = (target->context->matrix_mode == GPU_MODELVIEW? &target->context->modelview_matrix : &target->context->projection_matrix); if(stack->size + 1 >= GPU_MATRIX_STACK_MAX) { GPU_PushErrorCode(__func__, GPU_ERROR_USER_ERROR, "Matrix stack is full (%d)", GPU_MATRIX_STACK_MAX); return; } GPU_MatrixCopy(stack->matrix[stack->size], stack->matrix[stack->size-1]); stack->size++; }
static GPU_Camera SetCamera(GPU_Renderer* renderer, GPU_Target* target, GPU_Camera* cam) { GPU_Camera new_camera; GPU_Camera old_camera; GPU_Log(" %s (dummy)\n", __func__); if(target == NULL) { GPU_PushErrorCode("GPU_SetCamera", GPU_ERROR_NULL_ARGUMENT, "target"); return GPU_GetDefaultCamera(); } if(cam == NULL) new_camera = GPU_GetDefaultCamera(); else new_camera = *cam; old_camera = target->camera; target->camera = new_camera; return old_camera; }
void GPU_SetRendererOrder(int order_size, GPU_RendererID* order) { if(order == NULL) { // Restore the default order int count = 0; GPU_RendererID default_order[GPU_RENDERER_ORDER_MAX]; GPU_GetDefaultRendererOrder(&count, default_order); GPU_SetRendererOrder(count, default_order); // Call us again with the default order return; } if(order_size <= 0) return; if(order_size > GPU_RENDERER_ORDER_MAX) { GPU_PushErrorCode(__func__, GPU_ERROR_USER_ERROR, "Given order_size (%d) is greater than GPU_RENDERER_ORDER_MAX (%d)", order_size, GPU_RENDERER_ORDER_MAX); order_size = GPU_RENDERER_ORDER_MAX; } memcpy(_gpu_renderer_order, order, order_size*sizeof(GPU_RendererID)); _gpu_renderer_order_size = order_size; }
static GPU_Image* CreateImage(GPU_Renderer* renderer, Uint16 w, Uint16 h, GPU_FormatEnum format) { int num_layers, bytes_per_pixel; GPU_Image* result; SDL_Color white = { 255, 255, 255, 255 }; GPU_Log(" %s (dummy)\n", __func__); if(format < 1) { GPU_PushErrorCode("GPU_CreateImage", GPU_ERROR_DATA_ERROR, "Unsupported image format (0x%x)", format); return NULL; } switch(format) { case GPU_FORMAT_LUMINANCE: num_layers = 1; bytes_per_pixel = 1; break; case GPU_FORMAT_LUMINANCE_ALPHA: num_layers = 1; bytes_per_pixel = 2; break; case GPU_FORMAT_RGB: num_layers = 1; bytes_per_pixel = 3; break; case GPU_FORMAT_RGBA: num_layers = 1; bytes_per_pixel = 4; break; case GPU_FORMAT_ALPHA: num_layers = 1; bytes_per_pixel = 1; break; case GPU_FORMAT_RG: num_layers = 1; bytes_per_pixel = 2; break; case GPU_FORMAT_YCbCr420P: num_layers = 3; bytes_per_pixel = 1; break; case GPU_FORMAT_YCbCr422: num_layers = 3; bytes_per_pixel = 1; break; default: GPU_PushErrorCode("GPU_CreateUninitializedImage", GPU_ERROR_DATA_ERROR, "Unsupported image format (0x%x)", format); return NULL; } if(bytes_per_pixel < 1 || bytes_per_pixel > 4) { GPU_PushErrorCode("GPU_CreateUninitializedImage", GPU_ERROR_DATA_ERROR, "Unsupported number of bytes per pixel (%d)", bytes_per_pixel); return NULL; } result = (GPU_Image*)malloc(sizeof(GPU_Image)); result->refcount = 1; result->target = NULL; result->renderer = renderer; result->format = format; result->num_layers = num_layers; result->bytes_per_pixel = bytes_per_pixel; result->has_mipmaps = 0; result->color = white; result->use_blending = 1; result->blend_mode = GPU_GetBlendModeFromPreset(GPU_BLEND_NORMAL); result->filter_mode = GPU_FILTER_LINEAR; result->snap_mode = GPU_SNAP_POSITION_AND_DIMENSIONS; result->wrap_mode_x = GPU_WRAP_NONE; result->wrap_mode_y = GPU_WRAP_NONE; result->data = NULL; // Allocate a data structure as needed for other image data result->is_alias = 0; result->using_virtual_resolution = 0; result->w = w; result->h = h; result->base_w = w; result->base_h = h; result->texture_w = w; result->texture_h = h; return result; }