I’m not sure what cause this problem, I’m sorry to pass more code then probably needed.
So I thought what I try to do is fairly simple, what I want is fixed resolution renderer with aspect ratio scaling.
1 Switch render target to target texture and draw objects.
2. Switch render target to window and draw target texture.
And my renderer pipeline has been working just fine before I changed the rendering target. I mean the visual effect is no different when you remove the second step completely,
- objects are being drawn to the window,
- target is empty.
const SDL_AppResult
PT_Render(PT_Renderer *restrict self, PT_Scene scene)
{
SDL_Renderer *r = self->renderer;
PT_Camera *c = scene.camera;
SDL_Color bg = self->bg;
// -- 1. Draw camera objects to target
SDL_SetRenderTarget(r, self->target);
SDL_SetRenderDrawColor(r, bg.r, bg.g, bg.b, bg.a);
SDL_RenderClear(r);
const Uint16 n = scene.sprites_n;
if (n == 0) {
SDL_RenderPresent(r);
return SDL_APP_CONTINUE;
}
RenderItem *items = SDL_calloc(n, sizeof(*items));
if (!items)
return dlog(ERROR_MEMORY_ALLOCATION, SDL_GetError());
Uint16 count = 0;
// --- Projection
for (Uint16 i = 0; i < n; ++i) {
const PT_Sprite *s = &scene.sprites[i];
if (s->id == PT_TEXTURE_INVALID) continue;
PT_CamPoint p = c->project(c, s->x, s->y, s->z, s->r);
if (!p.visible) continue;
items[count++] = (RenderItem){
.rect = {
p.sx - p.size * 0.5f,
p.sy - p.size,
p.size,
p.size
},
.depth = p.depth,
.texture = self->reg.textures[s->id]
};
}
// --- Sort z buffer (painter's algorithm)
if (c->type == PTR_CAMERA_P9E && count > 1)
SDL_qsort(items, count, sizeof *items, cmp_depth);
// --- Draw
for (Uint16 i = 0; i < count; ++i) {
SDL_RenderTexture(r, items[i].texture, NULL, &items[i].rect);
}
// --- Draw camera debug border
SDL_SetRenderDrawColor(r, 255, 0, 0, 255);
SDL_FRect cam_rect = {
0.0f,
0.0f,
c->width,
c->height
};
SDL_RenderRect(r, &cam_rect);
// --- 2. Switch back to window
SDL_SetRenderTarget(r, NULL);
// If you would clean it here the window is black
//SDL_SetRenderDrawColor(r, 0, 0, 0, 255);
//SDL_RenderClear(r);
SDL_FRect dst = {0, 0, 1920, 1080};
SDL_RenderTexture(r, self->target, NULL, &dst);
SDL_RenderPresent(r);
SDL_free(items);
return SDL_APP_CONTINUE;
}
Please ignore the camera perojection details, you can see on what’s being draw to the window it’s correct. With camera set to 640 x 320:
The scene appears in the upper right corner and not scaled to the window (hardcoded here to 1920 x 1080). My suspect is the custom image format I use index to INDEX8 pixel format:
#define PIXELFORMAT SDL_PIXELFORMAT_INDEX8
#define TEXTUREACCESS SDL_TEXTUREACCESS_STATIC
Here is how I create the textures in my renderer:
typedef struct {
SDL_FRect rect;
float depth;
SDL_Texture *texture;
} RenderItem;
/* CPU to GPU texture data unit */
typedef struct {
PT_ImageData *in;
SDL_Texture *out;
} PT_TextureEntry;
struct PT_TextureRegistry {
SDL_Texture *textures[TEXTURES_MAX];
Uint16 textures_n;
};
struct PT_Renderer {
SDL_Renderer *renderer;
PT_TextureRegistry reg;
SDL_Palette *palette;
SDL_Color bg;
SDL_Texture *target;
};
const PT_TextureID
PT_RegisterTexture(PT_Renderer *restrict self, const char *restrict const path)
{
if (self->reg.textures_n >= TEXTURES_MAX) {
plog("Reached textures limit (%i)", self->reg.textures_n);
return PT_TEXTURE_INVALID;
}
SDL_AppResult e = SDL_APP_CONTINUE;
PT_ImageData *img = PT_LoadImageData(path, &e);
if (!img) {
plog("Failed to load image data");
return PT_TEXTURE_INVALID;
}
SDL_Texture *t = image2texture(self, img);
PT_FreeImageData(img);
if (!t) {
plog("Failed to convert image to SDL surface");
return PT_TEXTURE_INVALID;
}
const PT_TextureID id = self->reg.textures_n++;
self->reg.textures[id] = t;
return id;
}
PT_Renderer *restrict
PT_CreateRenderer(SDL_Window *restrict window, SDL_AppResult *restrict e, const Uint16 cam_w, const Uint16 cam_h) {
PT_Renderer *self = SDL_malloc(sizeof *self);
if (!self) {
*e = elog(ERROR_SDL_CREATE_RENDERER);
return NULL;
}
self->renderer = SDL_CreateRenderer(window, NULL);
SDL_SetRenderDrawBlendMode(self->renderer, SDL_BLENDMODE_BLEND);
self->reg.textures_n = 0;
self->palette = PT_CreatePalette(e);
self->bg = PT_GetColor(0x8D);
self->target = SDL_CreateTexture(
self->renderer,
PIXELFORMAT,
SDL_TEXTUREACCESS_TARGET,
cam_w,
cam_h
);
SDL_SetTextureScaleMode(self->target, SDL_SCALEMODE_NEAREST);
return self;
}
Is this a known problem with indexed textures or am I completely in the weeds with my suspicions?

