static Uint32 GetClosestSupportedFormat(SDL_Renderer * renderer, Uint32 format) { Uint32 i; if (SDL_ISPIXELFORMAT_FOURCC(format)) { /* Look for an exact match */ for (i = 0; i < renderer->info.num_texture_formats; ++i) { if (renderer->info.texture_formats[i] == format) { return renderer->info.texture_formats[i]; } } } else { SDL_bool hasAlpha = SDL_ISPIXELFORMAT_ALPHA(format); /* We just want to match the first format that has the same channels */ for (i = 0; i < renderer->info.num_texture_formats; ++i) { if (!SDL_ISPIXELFORMAT_FOURCC(renderer->info.texture_formats[i]) && SDL_ISPIXELFORMAT_ALPHA(renderer->info.texture_formats[i]) == hasAlpha) { return renderer->info.texture_formats[i]; } } } return renderer->info.texture_formats[0]; }
uint32_t SDLFrontend::getDisplayFormat () const { assert(_renderer); SDL_RendererInfo info; SDL_GetRendererInfo(_renderer, &info); for (int i = 0; i < info.num_texture_formats; ++i) { if (!SDL_ISPIXELFORMAT_FOURCC(info.texture_formats[i]) && SDL_ISPIXELFORMAT_ALPHA(info.texture_formats[i])) { return info.texture_formats[i]; } } const uint32_t format = info.texture_formats[0]; return format; }
int main(int argc,char** argv) { Uint8 num_pictures; LoadedPicture* pictures; int i, j; SDL_PixelFormat* format = NULL; SDL_Window *window; SDL_Renderer *renderer; SDL_Color black = {0,0,0,0xff}; SDL_Event event; int event_pending = 0; int should_exit = 0; unsigned int current_picture; int button_down; Uint32 pixelFormat = 0; int access = 0; SDL_Rect texture_dimensions; /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); if(argc < 2) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Shape requires at least one bitmap file as argument."); exit(-1); } if(SDL_VideoInit(NULL) == -1) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not initialize SDL video."); exit(-2); } num_pictures = argc - 1; pictures = (LoadedPicture *)SDL_malloc(sizeof(LoadedPicture)*num_pictures); if (!pictures) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not allocate memory."); exit(1); } for(i=0;i<num_pictures;i++) pictures[i].surface = NULL; for(i=0;i<num_pictures;i++) { pictures[i].surface = SDL_LoadBMP(argv[i+1]); pictures[i].name = argv[i+1]; if(pictures[i].surface == NULL) { for(j=0;j<num_pictures;j++) SDL_FreeSurface(pictures[j].surface); SDL_free(pictures); SDL_VideoQuit(); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not load surface from named bitmap file: %s", argv[i+1]); exit(-3); } format = pictures[i].surface->format; if(SDL_ISPIXELFORMAT_ALPHA(format->format)) { pictures[i].mode.mode = ShapeModeBinarizeAlpha; pictures[i].mode.parameters.binarizationCutoff = 255; } else { pictures[i].mode.mode = ShapeModeColorKey; pictures[i].mode.parameters.colorKey = black; } } window = SDL_CreateShapedWindow("SDL_Shape test", SHAPED_WINDOW_X, SHAPED_WINDOW_Y, SHAPED_WINDOW_DIMENSION,SHAPED_WINDOW_DIMENSION, 0); SDL_SetWindowPosition(window, SHAPED_WINDOW_X, SHAPED_WINDOW_Y); if(window == NULL) { for(i=0;i<num_pictures;i++) SDL_FreeSurface(pictures[i].surface); SDL_free(pictures); SDL_VideoQuit(); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not create shaped window for SDL_Shape."); exit(-4); } renderer = SDL_CreateRenderer(window,-1,0); if (!renderer) { SDL_DestroyWindow(window); for(i=0;i<num_pictures;i++) SDL_FreeSurface(pictures[i].surface); SDL_free(pictures); SDL_VideoQuit(); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not create rendering context for SDL_Shape window."); exit(-5); } for(i=0;i<num_pictures;i++) pictures[i].texture = NULL; for(i=0;i<num_pictures;i++) { pictures[i].texture = SDL_CreateTextureFromSurface(renderer,pictures[i].surface); if(pictures[i].texture == NULL) { for(i=0;i<num_pictures;i++) if(pictures[i].texture != NULL) SDL_DestroyTexture(pictures[i].texture); for(i=0;i<num_pictures;i++) SDL_FreeSurface(pictures[i].surface); SDL_free(pictures); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_VideoQuit(); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not create texture for SDL_shape."); exit(-6); } } event_pending = 0; should_exit = 0; event_pending = SDL_PollEvent(&event); current_picture = 0; button_down = 0; texture_dimensions.h = 0; texture_dimensions.w = 0; texture_dimensions.x = 0; texture_dimensions.y = 0; SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Changing to shaped bmp: %s", pictures[current_picture].name); SDL_QueryTexture(pictures[current_picture].texture,(Uint32 *)&pixelFormat,(int *)&access,&texture_dimensions.w,&texture_dimensions.h); SDL_SetWindowSize(window,texture_dimensions.w,texture_dimensions.h); SDL_SetWindowShape(window,pictures[current_picture].surface,&pictures[current_picture].mode); while(should_exit == 0) { event_pending = SDL_PollEvent(&event); if(event_pending == 1) { if(event.type == SDL_KEYDOWN) { button_down = 1; if(event.key.keysym.sym == SDLK_ESCAPE) { should_exit = 1; break; } } if(button_down && event.type == SDL_KEYUP) { button_down = 0; current_picture += 1; if(current_picture >= num_pictures) current_picture = 0; SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Changing to shaped bmp: %s", pictures[current_picture].name); SDL_QueryTexture(pictures[current_picture].texture,(Uint32 *)&pixelFormat,(int *)&access,&texture_dimensions.w,&texture_dimensions.h); SDL_SetWindowSize(window,texture_dimensions.w,texture_dimensions.h); SDL_SetWindowShape(window,pictures[current_picture].surface,&pictures[current_picture].mode); } if(event.type == SDL_QUIT) should_exit = 1; event_pending = 0; } render(renderer,pictures[current_picture].texture,texture_dimensions); SDL_Delay(10); } /* Free the textures. */ for(i=0;i<num_pictures;i++) SDL_DestroyTexture(pictures[i].texture); SDL_DestroyRenderer(renderer); /* Destroy the window. */ SDL_DestroyWindow(window); /* Free the original surfaces backing the textures. */ for(i=0;i<num_pictures;i++) SDL_FreeSurface(pictures[i].surface); SDL_free(pictures); /* Call SDL_VideoQuit() before quitting. */ SDL_VideoQuit(); return 0; }
SDL_Texture * SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface) { const SDL_PixelFormat *fmt; SDL_bool needAlpha; Uint32 i; Uint32 format; SDL_Texture *texture; CHECK_RENDERER_MAGIC(renderer, NULL); if (!surface) { SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface"); return NULL; } /* See what the best texture format is */ fmt = surface->format; if (fmt->Amask || SDL_GetColorKey(surface, NULL) == 0) { needAlpha = SDL_TRUE; } else { needAlpha = SDL_FALSE; } format = renderer->info.texture_formats[0]; for (i = 0; i < renderer->info.num_texture_formats; ++i) { if (!SDL_ISPIXELFORMAT_FOURCC(renderer->info.texture_formats[i]) && SDL_ISPIXELFORMAT_ALPHA(renderer->info.texture_formats[i]) == needAlpha) { format = renderer->info.texture_formats[i]; break; } } texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STATIC, surface->w, surface->h); if (!texture) { return NULL; } if (format == surface->format->format) { if (SDL_MUSTLOCK(surface)) { SDL_LockSurface(surface); SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch); SDL_UnlockSurface(surface); } else { SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch); } } else { SDL_PixelFormat *dst_fmt; SDL_Surface *temp = NULL; /* Set up a destination surface for the texture update */ dst_fmt = SDL_AllocFormat(format); temp = SDL_ConvertSurface(surface, dst_fmt, 0); SDL_FreeFormat(dst_fmt); if (temp) { SDL_UpdateTexture(texture, NULL, temp->pixels, temp->pitch); SDL_FreeSurface(temp); } else { SDL_DestroyTexture(texture); return NULL; } } { Uint8 r, g, b, a; SDL_BlendMode blendMode; SDL_GetSurfaceColorMod(surface, &r, &g, &b); SDL_SetTextureColorMod(texture, r, g, b); SDL_GetSurfaceAlphaMod(surface, &a); SDL_SetTextureAlphaMod(texture, a); if (SDL_GetColorKey(surface, NULL) == 0) { /* We converted to a texture with alpha format */ SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); } else { SDL_GetSurfaceBlendMode(surface, &blendMode); SDL_SetTextureBlendMode(texture, blendMode); } } return texture; }