我正在使用 SDL 和 C 作为个人项目和学习经验从头开始创建 Gameboy Color 游戏的 PC 端口。游戏使用调色板交换来创建效果,我希望能够做到这一点。我读过 SDL 有调色板功能,但它们已被贬低并且几乎没有功能。
由于我不能使用这些,在我的情况下模拟调色板交换的最佳方法是什么?
我知道 OP 不再寻找答案,但这可能对其他人有所帮助。
有SDL_Surface
一个SDL_PixelFormat
可以SDL_Palette
设置颜色的地方。那么这只是显示表面的问题。
进一步阅读:
已弃用?可以给个链接吗?
也许(未经测试)由于您的桌面配置,您不能直接将其用作输出表面,但是 SDL 支持 AFAIK 8 位索引调色板表面,您可以创建一个索引的离屏表面,调整调色板,然后对其进行 blit到输出表面。
编辑
这是一个 SDL1.2 工作示例,遗憾的是这里使用的 gif 没有正确转换调色板,所以循环只是显示为一些闪光,我没有寻找更好的方法。
注意不能直接戳到表面调色板,需要使用SDL_SetColors()
SDL2.0 添加了一些功能来处理调色板,但我希望它可以工作(未经测试)。
测试.c:
#include "SDL.h"
#include "SDL_image.h"
void cycle(SDL_Color *colors, int first, int ncolors) {
int i;
SDL_Color tmp;
tmp = colors[first];
for (i=first+1; i < first+ncolors; i++)
colors[i-1] = colors[i];
colors[i-1] = tmp;
}
int main (int argc, char *argv[]) {
SDL_Surface *out, *gif;
SDL_Event event;
int gameover = 0, i;
int ncolors;
SDL_Color *palette;
SDL_Init(SDL_INIT_VIDEO);
out = SDL_SetVideoMode(640, 480, 0, 0);
gif = IMG_Load("Grafx2.gif");
if (gif == NULL) {
fprintf(stderr,"IMG_Load(): %s\n",IMG_GetError());
goto err; /* <- evil */
}
printf("Bpp %d\n", gif->format->BytesPerPixel);
printf("bpp %d\n", gif->format->BitsPerPixel);
ncolors = gif->format->palette->ncolors;
printf("ncolors %d\n", ncolors);
palette = malloc(sizeof(SDL_Color)*ncolors); /* error check */
for (i=0; i < ncolors; i++) {
palette[i] = gif->format->palette->colors[i];
printf("[%d] r=%d, g=%d, b=%d\n", i, palette[i].r, palette[i].g,
palette[i].b);
}
while (!gameover) {
if (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT)
gameover = 1;
}
cycle(palette, 192, 64);
SDL_SetColors(gif, palette, 0, ncolors);
SDL_BlitSurface(gif, NULL, out, NULL);
SDL_UpdateRect(out, 0, 0, 0, 0);
}
free(palette);
SDL_FreeSurface(gif);
err:
SDL_Quit();
return 0;
}
生成文件:
CC = gcc
# CFLAGS += $(shell sdl-config --cflags)
# LIBS += $(shell sdl-config --libs)
CFLAGS += $(shell pkg-config SDL_image --cflags)
LIBS += $(shell pkg-config SDL_image --libs)
# CFLAGS += -Wno-switch
all: Grafx2.gif test
test.o: test.c
$(CC) -Wall -O2 $(CFLAGS) -c -o $@ $<
test: test.o
$(CC) -o $@ $< $(LIBS)
Grafx2.gif:
wget http://upload.wikimedia.org/wikipedia/commons/7/77/Grafx2.gif
.PHONY: clean
clean:
-rm -f test *.o
screen=SDL_SetVideoMode(640, 480, 8, SDL_HWPALETTE); SDL_SetPalette(屏幕, SDL_LOGPAL|SDL_PHYSPAL, 颜色, 0, 256); 文章发布 - https://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlsetpalette.html
screen=SDL_SetVideoMode(640, 480, 32, SDL_OPENGL | SDL_FULLSCREEN); 使用像素着色器。文章发布 - https://gamedev.stackexchange.com/questions/43294/creating-a-retro-style-palette-swapping-effect-in-opengl