2023-07-26 20:09:57 +02:00
|
|
|
#include "./sdlrenderer_texture_uploader.hpp"
|
|
|
|
|
|
|
|
#include <cassert>
|
2024-03-08 22:04:58 +01:00
|
|
|
#include <cstdint>
|
|
|
|
#include <cstring>
|
2023-07-26 20:09:57 +02:00
|
|
|
|
|
|
|
SDLRendererTextureUploader::SDLRendererTextureUploader(SDL_Renderer* renderer_) :
|
|
|
|
renderer(renderer_)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2024-03-08 22:04:58 +01:00
|
|
|
uint64_t SDLRendererTextureUploader::uploadRGBA(const uint8_t* data, uint32_t width, uint32_t height, Filter filter, Access access) {
|
2023-07-26 20:09:57 +02:00
|
|
|
// TODO: test if pitch is 4 or 4*width
|
|
|
|
SDL_Surface* surf = SDL_CreateSurfaceFrom(
|
|
|
|
(void*)data,
|
|
|
|
width, height,
|
|
|
|
4*width,
|
2023-07-30 16:00:55 +02:00
|
|
|
SDL_PIXELFORMAT_RGBA32 // auto big/little
|
2023-07-26 20:09:57 +02:00
|
|
|
);
|
|
|
|
assert(surf); // TODO: add error reporting
|
|
|
|
|
2024-03-08 22:04:58 +01:00
|
|
|
// hacky hint usage
|
|
|
|
if (access == Access::STREAMING) {
|
|
|
|
SDL_SetHint("SDL_TextureAccess", "SDL_TEXTUREACCESS_STREAMING");
|
|
|
|
} else {
|
|
|
|
SDL_SetHint("SDL_TextureAccess", "SDL_TEXTUREACCESS_STATIC");
|
|
|
|
}
|
|
|
|
// TODO: cleanup hints after
|
|
|
|
|
2024-01-21 20:20:32 +01:00
|
|
|
SDL_Texture* tex = SDL_CreateTextureFromSurface(renderer, surf);
|
|
|
|
assert(tex); // TODO: add error reporting
|
|
|
|
|
2024-01-21 13:58:22 +01:00
|
|
|
if (filter == NEAREST) {
|
2024-01-21 20:20:32 +01:00
|
|
|
SDL_SetTextureScaleMode(tex, SDL_SCALEMODE_NEAREST);
|
2024-01-21 13:58:22 +01:00
|
|
|
} else if (filter == LINEAR) {
|
2024-01-21 20:20:32 +01:00
|
|
|
SDL_SetTextureScaleMode(tex, SDL_SCALEMODE_LINEAR);
|
2024-01-21 13:58:22 +01:00
|
|
|
}
|
|
|
|
|
2023-07-26 20:09:57 +02:00
|
|
|
SDL_DestroySurface(surf);
|
|
|
|
|
|
|
|
return reinterpret_cast<uint64_t>(tex);
|
|
|
|
}
|
|
|
|
|
2024-03-08 22:04:58 +01:00
|
|
|
bool SDLRendererTextureUploader::updateRGBA(uint64_t tex_id, const uint8_t* data, size_t size) {
|
|
|
|
auto* texture = static_cast<SDL_Texture*>(reinterpret_cast<void*>(tex_id));
|
|
|
|
if (texture == nullptr) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t* pixels = nullptr;
|
|
|
|
int pitch = 0;
|
|
|
|
|
|
|
|
if (SDL_LockTexture(texture, nullptr, (void**)&pixels, &pitch) != 0) {
|
|
|
|
// TODO: error
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::memcpy(pixels, data, size);
|
|
|
|
|
|
|
|
SDL_UnlockTexture(texture);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2023-07-26 20:09:57 +02:00
|
|
|
void SDLRendererTextureUploader::destroy(uint64_t tex_id) {
|
|
|
|
SDL_DestroyTexture(static_cast<SDL_Texture*>(reinterpret_cast<void*>(tex_id)));
|
|
|
|
}
|
|
|
|
|