From a3d193516c8adf4ff4e47330ceea4f97d8080a15 Mon Sep 17 00:00:00 2001 From: Green Sky Date: Fri, 8 Mar 2024 22:04:58 +0100 Subject: [PATCH] add updating to textures --- src/sdlrenderer_texture_uploader.cpp | 33 +++++++++++++++++++++++++++- src/sdlrenderer_texture_uploader.hpp | 3 ++- src/texture_uploader.hpp | 15 +++++++++++-- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/sdlrenderer_texture_uploader.cpp b/src/sdlrenderer_texture_uploader.cpp index da05832..267eec9 100644 --- a/src/sdlrenderer_texture_uploader.cpp +++ b/src/sdlrenderer_texture_uploader.cpp @@ -1,13 +1,15 @@ #include "./sdlrenderer_texture_uploader.hpp" #include +#include +#include SDLRendererTextureUploader::SDLRendererTextureUploader(SDL_Renderer* renderer_) : renderer(renderer_) { } -uint64_t SDLRendererTextureUploader::uploadRGBA(const uint8_t* data, uint32_t width, uint32_t height, Filter filter) { +uint64_t SDLRendererTextureUploader::uploadRGBA(const uint8_t* data, uint32_t width, uint32_t height, Filter filter, Access access) { // TODO: test if pitch is 4 or 4*width SDL_Surface* surf = SDL_CreateSurfaceFrom( (void*)data, @@ -17,6 +19,14 @@ uint64_t SDLRendererTextureUploader::uploadRGBA(const uint8_t* data, uint32_t wi ); assert(surf); // TODO: add error reporting + // 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 + SDL_Texture* tex = SDL_CreateTextureFromSurface(renderer, surf); assert(tex); // TODO: add error reporting @@ -31,6 +41,27 @@ uint64_t SDLRendererTextureUploader::uploadRGBA(const uint8_t* data, uint32_t wi return reinterpret_cast(tex); } +bool SDLRendererTextureUploader::updateRGBA(uint64_t tex_id, const uint8_t* data, size_t size) { + auto* texture = static_cast(reinterpret_cast(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; +} + void SDLRendererTextureUploader::destroy(uint64_t tex_id) { SDL_DestroyTexture(static_cast(reinterpret_cast(tex_id))); } diff --git a/src/sdlrenderer_texture_uploader.hpp b/src/sdlrenderer_texture_uploader.hpp index 64bc390..6e028d0 100644 --- a/src/sdlrenderer_texture_uploader.hpp +++ b/src/sdlrenderer_texture_uploader.hpp @@ -10,7 +10,8 @@ struct SDLRendererTextureUploader : public TextureUploaderI { SDLRendererTextureUploader(SDL_Renderer* renderer_); ~SDLRendererTextureUploader(void) = default; - uint64_t uploadRGBA(const uint8_t* data, uint32_t width, uint32_t height, Filter filter) override; + uint64_t uploadRGBA(const uint8_t* data, uint32_t width, uint32_t height, Filter filter, Access access) override; + bool updateRGBA(uint64_t tex_id, const uint8_t* data, size_t size) override; void destroy(uint64_t tex_id) override; }; diff --git a/src/texture_uploader.hpp b/src/texture_uploader.hpp index 3fcc024..1c6668c 100644 --- a/src/texture_uploader.hpp +++ b/src/texture_uploader.hpp @@ -1,18 +1,29 @@ #pragma once #include +#include struct TextureUploaderI { - static constexpr const char* version {"1"}; + static constexpr const char* version {"2"}; enum Filter { NEAREST, LINEAR, }; + enum Access { + STATIC, + STREAMING, + // target? + }; + virtual ~TextureUploaderI(void) {} - virtual uint64_t uploadRGBA(const uint8_t* data, uint32_t width, uint32_t height, Filter filter = LINEAR) = 0; + virtual uint64_t uploadRGBA(const uint8_t* data, uint32_t width, uint32_t height, Filter filter = LINEAR, Access access = STATIC) = 0; + + // keeps width height filter + // TODO: wh instead of size? + virtual bool updateRGBA(uint64_t tex_id, const uint8_t* data, size_t size) = 0; virtual void destroy(uint64_t tex_id) = 0; };