Wir möchten eine SDL-Oberfläche erstellen, indem wir ein Bild mit SDL_Image laden. Wenn die Abmessungen einen Grenzwert überschreiten, ändern Sie die Größe der Oberfläche.SDL2 Größe einer Oberfläche ändern
Der Grund, warum wir dies tun müssen, ist auf Raspbian SDL wirft einen Fehler beim Erstellen einer Textur von der Oberfläche ('Textur Abmessungen sind auf 2048x2048 begrenzt'). Während das ein sehr großes Bild ist, wollen wir nicht, dass Benutzer sich Gedanken über die Bildgröße machen, wir wollen die Größe für sie ändern. Obwohl wir dieses Limit für Windows nicht erreicht haben, versuchen wir, die Lösung für Windows zu entwickeln und Probleme bei der Größenänderung der Textur zu haben.
für eine Lösung dort gesucht haben ähnliche Fragen ...:
- 2008 not SDL2 custom blitting
- 2010 use SDL_gfx
- 2008 can't be done use SDL_gfx, 2015 use SDL_BlitScaled, 2015 use SDL_RenderCopyEx
ist ein Brauch blitter oder SDL_gfx notwendig mit Strom SDL2 (diejenigen, antwortet vor dem SDL2-Release von 2013)? SDLRenderCopyEx hilft nicht, da Sie die Textur generieren müssen, wo unser Problem auftritt.
So haben wir versucht, einige der verfügbaren Blitten Funktionen wie SDL_BlitScaled, unten ist ein einfaches Programm eine 2500x2500 PNG ohne Skalierung zu machen:
#include <SDL.h>
#include <SDL_image.h>
#include <sstream>
#include <string>
SDL_Texture * get_texture(
SDL_Renderer * pRenderer,
std::string image_filename) {
SDL_Texture * result = NULL;
SDL_Surface * pSurface = IMG_Load(image_filename.c_str());
if (pSurface == NULL) {
printf("Error image load: %s\n", IMG_GetError());
}
else {
SDL_Texture * pTexture = SDL_CreateTextureFromSurface(pRenderer, pSurface);
if (pTexture == NULL) {
printf("Error image load: %s\n", SDL_GetError());
}
else {
SDL_SetTextureBlendMode(
pTexture,
SDL_BLENDMODE_BLEND);
result = pTexture;
}
SDL_FreeSurface(pSurface);
pSurface = NULL;
}
return result;
}
int main(int argc, char* args[]) {
SDL_Window * pWindow = NULL;
SDL_Renderer * pRenderer = NULL;
// set up
SDL_Init(SDL_INIT_VIDEO);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");
SDL_Rect screenDimensions;
screenDimensions.x = 0;
screenDimensions.y = 0;
screenDimensions.w = 640;
screenDimensions.h = 480;
pWindow = SDL_CreateWindow("Resize Test",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
screenDimensions.w,
screenDimensions.h,
SDL_WINDOW_SHOWN);
pRenderer = SDL_CreateRenderer(pWindow,
-1,
SDL_RENDERER_ACCELERATED);
IMG_Init(IMG_INIT_PNG);
// render
SDL_SetRenderDrawColor(
pRenderer,
0,
0,
0,
0);
SDL_RenderClear(pRenderer);
SDL_Texture * pTexture = get_texture(
pRenderer,
"2500x2500.png");
if (pTexture != NULL) {
SDL_RenderCopy(
pRenderer,
pTexture,
NULL,
&screenDimensions);
SDL_DestroyTexture(pTexture);
pTexture = NULL;
}
SDL_RenderPresent(pRenderer);
// wait for quit
bool quit = false;
while (!quit)
{
// poll input for quit
SDL_Event inputEvent;
while (SDL_PollEvent(&inputEvent) != 0) {
if ((inputEvent.type == SDL_KEYDOWN) &&
(inputEvent.key.keysym.sym == 113)) {
quit = true;
}
}
}
IMG_Quit();
SDL_DestroyRenderer(pRenderer);
pRenderer = NULL;
SDL_DestroyWindow(pWindow);
pWindow = NULL;
return 0;
}
Ändern der get_texture Funktion, so dass es eine Grenze identifiziert und versucht, zu erstellen eine neue Oberfläche:
SDL_Texture * get_texture(
SDL_Renderer * pRenderer,
std::string image_filename) {
SDL_Texture * result = NULL;
SDL_Surface * pSurface = IMG_Load(image_filename.c_str());
if (pSurface == NULL) {
printf("Error image load: %s\n", IMG_GetError());
}
else {
const int limit = 1024;
int width = pSurface->w;
int height = pSurface->h;
if ((width > limit) ||
(height > limit)) {
SDL_Rect sourceDimensions;
sourceDimensions.x = 0;
sourceDimensions.y = 0;
sourceDimensions.w = width;
sourceDimensions.h = height;
float scale = (float)limit/(float)width;
float scaleH = (float)limit/(float)height;
if (scaleH < scale) {
scale = scaleH;
}
SDL_Rect targetDimensions;
targetDimensions.x = 0;
targetDimensions.y = 0;
targetDimensions.w = (int)(width * scale);
targetDimensions.h = (int)(height * scale);
SDL_Surface *pScaleSurface = SDL_CreateRGBSurface(
pSurface->flags,
targetDimensions.w,
targetDimensions.h,
pSurface->format->BitsPerPixel,
pSurface->format->Rmask,
pSurface->format->Gmask,
pSurface->format->Bmask,
pSurface->format->Amask);
if (SDL_BlitScaled(pSurface, NULL, pScaleSurface, &targetDimensions) < 0) {
printf("Error did not scale surface: %s\n", SDL_GetError());
SDL_FreeSurface(pScaleSurface);
pScaleSurface = NULL;
}
else {
SDL_FreeSurface(pSurface);
pSurface = pScaleSurface;
width = pSurface->w;
height = pSurface->h;
}
}
SDL_Texture * pTexture = SDL_CreateTextureFromSurface(pRenderer, pSurface);
if (pTexture == NULL) {
printf("Error image load: %s\n", SDL_GetError());
}
else {
SDL_SetTextureBlendMode(
pTexture,
SDL_BLENDMODE_BLEND);
result = pTexture;
}
SDL_FreeSurface(pSurface);
pSurface = NULL;
}
return result;
}
SDL_BlitScaled schlägt mit einem Fehler andere Variationen haben einen ähnlichen Fehler ‚Blit Kombination nicht unterstützt‘:
Dann haben wir ein nicht skaliertes Blit ausprobiert ... welches keinen Fehler ausgelöst hat, sondern nur weiß (nicht die klare Farbe oder eine Farbe im Bild).
SDL_BlitSurface(pSurface, &targetDimensions, pScaleSurface, &targetDimensions)
Damit blitting Funktion arbeiten wir nicht dann versucht, es mit dem gleichen Bild als Bitmap (nur die .png als .bmp Export), noch die Datei mit SDL_image Laden und beide dieser Funktionen arbeiten mit SDL_BlitScaled Skalierung als erwartet
Nicht sicher, was hier falsch läuft (wir erwarten und brauchen Unterstützung für wichtige Bilddateiformate wie. Png) oder wenn dies der empfohlene Ansatz ist, jede Hilfe geschätzt!
Um Blit-Funktionen verwenden zu können, muss Ihre Hardware GL_EXT_framebuffer_blit unterstützen - integrierte Grafik und einige Workstation-GPUs werden normalerweise nicht unterstützt. –
Was ist das Pixelformat Ihres Quellbildes (Bits pro Pixel und Masken)? Dieser Fehler wird erzeugt, wenn keine Blitting-Implementierung für die Kombination von Quell- und Zieloberflächenformat vorliegt; Ich schlage vor, 'normale' 8 Bits pro Kanal Zieloberfläche zu erstellen (24 Bit für RGB, 32 für RGBA) und Blitting hinein. – keltar
@ bruno-ferreira danke, du hattest Recht, dass Erweiterung wurde nicht unterstützt, also habe ich Treiber für die Grafikkarte installiert und habe es aber leider, wenn nicht auf dieses Problem gerichtet – Paddy