SDL
SDL copied to clipboard
SDL 2: Scaled blitting of 8-bit indexed surface shows a black screen
I have an 8-bit indexed surface, in this example, 320x240. I would like to scale it to multiples of that resolution, for example, 640x480, but scaled blitting of the indexed surface shows an empty screen
int main(int argc, char * argv [])
{
SDL_Window *window;
SDL_Surface *screen, *display;
SDL_Event event;
SDL_Palette *palette;
Uint8 *pixels;
/* initialize system */
if (SDL_Init(SDL_INIT_VIDEO) == -1)
{
puts("Cannot initialize SDL video");
return 1;
}
atexit(SDL_Quit);
/* initialize screen */
window = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIDTH * 2, HEIGHT * 2, 0);
if (!window)
{
puts("Cannot set video mode");
return 1;
}
display = SDL_GetWindowSurface(window);
SDL_ShowCursor(SDL_DISABLE);
screen = SDL_CreateRGBSurface(0, WIDTH, HEIGHT, 8, 0, 0, 0, 0);
if (!screen)
{
puts("Cannot allocate screen");
return 1;
}
/* initialize palette */
palette = create_palette();
if (!palette) return 1;
if (SDL_SetSurfacePalette(screen, palette))
{
puts("Unable to set palette");
return 1;
}
SDL_SetSurfaceBlendMode(display, SDL_BLENDMODE_NONE);
SDL_SetSurfaceBlendMode(screen, SDL_BLENDMODE_NONE);
/* draw screen */
pixels = (Uint8 *) screen->pixels;
draw_screen(pixels, screen->pitch);
/*
===============================
HERE IS THE PROBLEM
===============================
*/
/* SDL_BlitSurface(screen, NULL, display, NULL); note that this would work just fine */
SDL_BlitScaled(screen, NULL, display, NULL);
SDL_UpdateWindowSurface(window);
/* event loop */
while (1)
{
while (SDL_PollEvent(&event))
{
if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_q) return 0;
}
SDL_Delay(10);
}
return 0;
}
That's correct, scaled conversion blitting from an 8-bit surface to a non-8-bit surface is not currently supported. You can scale an 8-bit surface and convert to 32-bit or convert to 32-bit and then scale, but currently you can't do both in the same operation.
FYI, here's the SDL 3.0 version of your example program:
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#define WIDTH 320
#define HEIGHT 240
SDL_Palette *create_palette()
{
SDL_Palette *p = SDL_CreatePalette(2);
p->colors[1].r = 0;
p->colors[1].g = 0xff;
p->colors[1].b = 0;
return p;
}
static void draw_screen(Uint8 *pixels, int pitch)
{
SDL_memset(pixels, 1, pitch * HEIGHT);
}
int main(int argc, char *argv[])
{
SDL_Window *window;
SDL_Surface *screen, *display;
SDL_Event event;
SDL_Palette *palette;
Uint8 *pixels;
/* initialize system */
if (SDL_Init(SDL_INIT_VIDEO) == -1) {
SDL_Log("Cannot initialize SDL video");
return 1;
}
/* initialize screen */
window = SDL_CreateWindow("", WIDTH * 2, HEIGHT * 2, 0);
if (!window) {
SDL_Log("Cannot set video mode");
return 1;
}
display = SDL_GetWindowSurface(window);
SDL_HideCursor();
screen = SDL_CreateSurface(WIDTH, HEIGHT, SDL_PIXELFORMAT_INDEX8);
if (!screen) {
SDL_Log("Cannot allocate screen");
return 1;
}
/* initialize palette */
palette = create_palette();
if (!palette)
return 1;
if (!SDL_SetSurfacePalette(screen, palette)) {
SDL_Log("Unable to set palette");
return 1;
}
SDL_SetSurfaceBlendMode(display, SDL_BLENDMODE_NONE);
SDL_SetSurfaceBlendMode(screen, SDL_BLENDMODE_NONE);
/* draw screen */
pixels = (Uint8 *)screen->pixels;
draw_screen(pixels, screen->pitch);
/*
===============================
HERE IS THE PROBLEM
===============================
*/
// SDL_BlitSurface(screen, NULL, display, NULL);
if (!SDL_BlitSurfaceScaled(screen, NULL, display, NULL, SDL_SCALEMODE_NEAREST)) {
SDL_Log("SDL_BlitSurfaceScaled failed: %s\n", SDL_GetError());
}
SDL_UpdateWindowSurface(window);
/* event loop */
while (1) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_EVENT_KEY_DOWN && event.key.key == SDLK_Q)
return 0;
}
SDL_Delay(10);
}
return 0;
}
This now implemented in SDL3.