add avatar texture handling

This commit is contained in:
Green Sky 2023-08-01 18:25:56 +02:00
parent 2e28ad7bb9
commit 95b77cb696
No known key found for this signature in database
5 changed files with 99 additions and 6 deletions

@ -1 +1 @@
Subproject commit 65d253afeaf7e39594ecc0a07864a4f4a87086fd
Subproject commit 738d2abe7b4d6088412e56b89f4e26aab1a8bdba

View File

@ -31,6 +31,18 @@ ChatGui4::ChatGui4(
}
void ChatGui4::render(void) {
if (!_cr.storage<Contact::Components::TagAvatarInvalidate>().empty()) { // handle force-reloads for avatars
std::vector<Contact3> to_purge;
_cr.view<Contact::Components::TagAvatarInvalidate>().each([&to_purge](const Contact3 c) {
to_purge.push_back(c);
});
_cr.remove<Contact::Components::TagAvatarInvalidate>(to_purge.cbegin(), to_purge.cend());
_contact_tc.invalidate(to_purge);
}
// ACTUALLY NOT IF RENDERED, MOVED LOGIC TO ABOVE
// it might unload textures, so it needs to be done before rendering
_contact_tc.update();
const ImGuiViewport* viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->WorkPos);
ImGui::SetNextWindowSize(viewport->WorkSize);
@ -122,6 +134,11 @@ void ChatGui4::render(void) {
if (ImGui::BeginChild("message_log", {0, -100}, false, ImGuiWindowFlags_MenuBar)) {
if (ImGui::BeginMenuBar()) {
ImGui::Checkbox("show extra info", &_show_chat_extra_info);
if (ImGui::SmallButton("test")) {
_cr.emplace_or_replace<Contact::Components::AvatarFile>(*_selected_contact, "tomato_v1_256.bmp");
_cr.emplace_or_replace<Contact::Components::TagAvatarInvalidate>(*_selected_contact);
std::cout << "DEBUG: added AvatarFile comp to contact\n";
}
ImGui::EndMenuBar();
}
@ -276,7 +293,6 @@ void ChatGui4::render(void) {
_fss.render();
_contact_tc.update();
_contact_tc.workLoadQueue();
}

View File

@ -136,14 +136,18 @@ struct TextureCache {
}
}
invalidate(to_purge);
_default_texture.doAnimation(ts_now);
}
void invalidate(const std::vector<KeyType>& to_purge) {
for (const auto& key : to_purge) {
for (const auto& tex_id : _cache.at(key).textures) {
_tu.destroy(tex_id);
}
_cache.erase(key);
}
_default_texture.doAnimation(ts_now);
}
void workLoadQueue(void) {

View File

@ -1,13 +1,23 @@
#include "./tox_avatar_loader.hpp"
#include "./image_loader_sdl_bmp.hpp"
#include <solanaceae/contact/components.hpp>
#include <solanaceae/tox_contacts/components.hpp>
#include <sodium/crypto_hash_sha256.h>
#include <iostream>
#include <fstream>
#include <cassert>
#include <vector>
ToxAvatarLoader::ToxAvatarLoader(Contact3Registry& cr) : _cr(cr) {
_image_loaders.push_back(std::make_unique<ImageLoaderSDLBMP>());
//_image_loaders.push_back(std::make_unique<ImageLoaderWebP>());
//_image_loaders.push_back(std::make_unique<ImageLoaderSTB>());
}
static float getHue_6bytes(const uint8_t* data) {
uint64_t hue_uint = 0x00;
for (size_t i = 0; i < 6; i++) {
@ -105,6 +115,66 @@ std::optional<TextureEntry> ToxAvatarLoader::load(TextureUploaderI& tu, Contact3
return std::nullopt;
}
if (_cr.all_of<Contact::Components::AvatarMemory>(c)) {
const auto& a_m = _cr.get<Contact::Components::AvatarMemory>(c);
TextureEntry new_entry;
new_entry.timestamp_last_rendered = getNowMS();
new_entry.current_texture = 0;
new_entry.width = a_m.width;
new_entry.height = a_m.height;
const auto n_t = tu.uploadRGBA(a_m.data.data(), a_m.width, a_m.height);
new_entry.textures.push_back(n_t);
new_entry.frame_duration.push_back(250);
std::cout << "TAL: loaded memory buffer\n";
return new_entry;
}
if (_cr.all_of<Contact::Components::AvatarFile>(c)) {
const auto& a_f = _cr.get<Contact::Components::AvatarFile>(c);
std::ifstream file(a_f.file_path, std::ios::binary);
if (file.is_open()) {
std::vector<uint8_t> tmp_buffer;
while (file.good()) {
auto ch = file.get();
if (ch == EOF) {
break;
} else {
tmp_buffer.push_back(ch);
}
}
// try all loaders after another
for (auto& il : _image_loaders) {
auto res = il->loadFromMemoryRGBA(tmp_buffer.data(), tmp_buffer.size());
if (res.frames.empty() || res.height == 0 || res.width == 0) {
continue;
}
TextureEntry new_entry;
new_entry.timestamp_last_rendered = getNowMS();
new_entry.current_texture = 0;
for (const auto& [ms, data] : res.frames) {
const auto n_t = tu.uploadRGBA(data.data(), res.width, res.height);
new_entry.textures.push_back(n_t);
new_entry.frame_duration.push_back(ms);
}
new_entry.width = res.width;
new_entry.height = res.height;
std::cout << "TAL: loaded image file " << a_f.file_path << "\n";
return new_entry;
}
}
}
if (!_cr.any_of<
Contact::Components::ToxFriendPersistent,
Contact::Components::ToxGroupPersistent,
@ -133,7 +203,7 @@ std::optional<TextureEntry> ToxAvatarLoader::load(TextureUploaderI& tu, Contact3
new_entry.width = 5;
new_entry.height = 5;
std::cout << "TAL: generateToxIdenticon\n";
std::cout << "TAL: generated ToxIdenticon\n";
return new_entry;
}

View File

@ -2,6 +2,7 @@
#include <solanaceae/contact/contact_model3.hpp>
#include "./image_loader.hpp"
#include "./texture_cache.hpp"
#include <optional>
@ -9,8 +10,10 @@
class ToxAvatarLoader {
Contact3Registry& _cr;
std::vector<std::unique_ptr<ImageLoaderI>> _image_loaders;
public:
ToxAvatarLoader(Contact3Registry& cr) : _cr(cr) {}
ToxAvatarLoader(Contact3Registry& cr);
std::optional<TextureEntry> load(TextureUploaderI& tu, Contact3 c);
};