[WIP - Textures] Changed preload system to load on the fly

This commit is contained in:
KiritoDev 2021-05-08 19:04:56 -05:00
parent 1224f89d3a
commit f13b32f363
9 changed files with 107 additions and 87 deletions

View File

@ -191,8 +191,8 @@ Vtx *make_skybox_rect(s32 tileIndex, s8 colorIndex) {
s16 ty = ((tileIndex / SKYBOX_COLS) * h) % SKYBOX_IMAGE_SIZE;
if (verts != NULL) {
make_vertex(verts, 0, x, y, -1, tx << 5, ty << 5, sSkyboxColors[colorIndex][0], sSkyboxColors[colorIndex][1], sSkyboxColors[colorIndex][2], 255);
make_vertex(verts, 1, x, y - SKYBOX_TILE_HEIGHT, -1, tx << 5, (ty + w) << 5, sSkyboxColors[colorIndex][0], sSkyboxColors[colorIndex][1], sSkyboxColors[colorIndex][2], 255);
make_vertex(verts, 0, x, y, -1, tx << 5, ty << 5, sSkyboxColors[colorIndex][0], sSkyboxColors[colorIndex][1], sSkyboxColors[colorIndex][2], 255);
make_vertex(verts, 1, x, y - SKYBOX_TILE_HEIGHT, -1, tx << 5, (ty + w) << 5, sSkyboxColors[colorIndex][0], sSkyboxColors[colorIndex][1], sSkyboxColors[colorIndex][2], 255);
make_vertex(verts, 2, x + tw, y - SKYBOX_TILE_HEIGHT, -1, (tx + w) << 5, (ty + h) << 5, sSkyboxColors[colorIndex][0], sSkyboxColors[colorIndex][1], sSkyboxColors[colorIndex][2], 255);
make_vertex(verts, 3, x + tw, y, -1, (tx + w) << 5, ty << 5, sSkyboxColors[colorIndex][0], sSkyboxColors[colorIndex][1], sSkyboxColors[colorIndex][2], 255);
}

View File

@ -15,21 +15,27 @@ using json = nlohmann::json;
#include <stdlib.h>
#include <dirent.h>
#include <map>
#include <chrono>
#define STB_IMAGE_IMPLEMENTATION
#include <stb/stb_image.h>
using namespace std;
vector<BitModule*> addons;
map<string, TextureData*> textureMap;
map<string, TextureFileEntry*> baseGameTextures;
map<string, TextureFileEntry*> textureCache;
std::map<std::string, TextureFileEntry*> baseGameTextures;
map<string, BitModule*> textureCache;
extern "C" {
#include "moon/libs/lua/lualib.h"
#include "moon/libs/lua/lauxlib.h"
#include "moon/libs/lua/lua.h"
#include "text/libs/io_utils.h"
#include "pc/gfx/gfx_rendering_api.h"
#include "pc/platform.h"
#include "pc/fs/fs.h"
}
void Moon_LoadDefaultAddon(){
@ -59,6 +65,7 @@ void Moon_LoadAddon(string path){
bit->website = j["bit"]["website"];
bit->icon = j["bit"]["icon"];
bit->main = j["bit"]["main"];
bit->path = path;
bit->readOnly = false;
if(file.has_file(bit->main)){
@ -68,9 +75,7 @@ void Moon_LoadAddon(string path){
if(file.has_file(bit->icon)){
vector<string> allowedTextures = {"png", "jpg", "jpeg"};
if(std::count(allowedTextures.begin(), allowedTextures.end(), string(get_filename_ext(bit->icon.c_str())))){
TextureFileEntry *entry = new TextureFileEntry();
file.read_texture(bit->icon, &entry);
bit->textures.insert(pair<string, TextureFileEntry*>("mod-icons://"+bit->name, entry));
bit->textures.insert(pair<string, TextureFileEntry*>("mod-icons://"+bit->name, new TextureFileEntry({.path = bit->icon})));
}
}
@ -84,6 +89,7 @@ void Moon_LoadAddon(string path){
if(std::count(allowedTextures.begin(), allowedTextures.end(), string(get_filename_ext(name.c_str())))){
string texName = name.substr(graphicsPath.length());
string rawname = texName.substr(0, texName.find_last_of("."));
TextureFileEntry *entry = new TextureFileEntry();
file.read_texture(name, &entry);
bit->textures.insert(pair<string, TextureFileEntry*>(rawname, entry));
@ -105,35 +111,83 @@ void Moon_LoadAddon(string path){
}
}
void Moon_BakeTextureCache(){
textureMap.clear();
void Moon_BakeTextureCache(vector<int> order){
textureCache.clear();
for(auto &addon : addons){
// BitModule *addon = addons[order[i]];
for(int i=0; i < order.size(); i++){
BitModule *addon = addons[order[i]];
for (map<string, TextureFileEntry*>::iterator entry = addon->textures.begin(); entry != addon->textures.end(); ++entry) {
map<string, TextureFileEntry*>::iterator texIt = textureCache.find(entry->first);
auto texIt = textureCache.find(entry->first);
if(texIt != textureCache.end()) textureCache.erase(texIt);
TextureFileEntry* texEntry = entry->second;
if(texEntry->data != nullptr)
textureCache.insert(pair<string, TextureFileEntry*>(entry->first, texEntry));
textureCache.insert(pair<string, BitModule*>(entry->first, addon));
}
}
//for(auto &addon: addons){
//}
textureMap.clear();
}
void Moon_UploadCacheToGPU(){
for (map<string, TextureFileEntry*>::iterator entry = textureCache.begin(); entry != textureCache.end(); ++entry) {
TextureFileEntry* texEntry = entry->second;
if(texEntry->data != nullptr) {
overload_memory_texture(texEntry->data, texEntry->size, entry->first.c_str());
// free(entry->second);
TextureFileEntry *Moon_getTextureData(const char *fullpath){
char texname[SYS_MAX_PATH];
strncpy(texname, fullpath, sizeof(texname));
texname[sizeof(texname)-1] = 0;
char *dot = strrchr(texname, '.');
if (dot) *dot = 0;
char *actualname = texname;
if (!strncmp(FS_TEXTUREDIR "/", actualname, 4)) actualname += 4;
actualname = sys_strdup(actualname);
assert(actualname);
auto cacheEntry = textureCache.find(actualname);
BitModule *addon = cacheEntry->second;
TextureFileEntry * data = NULL;
if(addon != NULL){
TextureFileEntry *fileEntry = addon->textures.find(actualname)->second;
if(fileEntry != NULL){
if(fileEntry->data != NULL) data = fileEntry;
else if(!fileEntry->path.empty()){
miniz_cpp::zip_file file(addon->path);
TextureFileEntry *newData = new TextureFileEntry();
file.read_texture(fileEntry->path, &newData);
data = newData;
}
}
}
textureCache.clear();
return data;
}
void Moon_LoadTexture(int tile, const char *fullpath, struct GfxRenderingAPI *gfx_rapi){
int w, h;
u64 imgsize = 0;
TextureFileEntry * imgdata = Moon_getTextureData(fullpath);
if (imgdata) {
u8 *data = stbi_load_from_memory(reinterpret_cast<const stbi_uc *>(imgdata->data), imgdata->size, &w, &h, NULL, 4);
if (data) {
gfx_rapi->upload_texture(data, w, h);
stbi_image_free(data);
return;
} else {
cout << "Failed to convert texture" << endl;
std::cout << stbi_failure_reason() << std::endl;
}
} else {
cout << "Failed to load texture" << endl;
}
int missingW = 2;
int missingH = 2;
vector<uint8_t> missingTexture = {
0x00, 0x00, 0xFF, 0xFF,
0xFF, 0xFF, 0x00, 0x00,
};
gfx_rapi->upload_texture(missingTexture.data(), missingW, missingH);
}
void Moon_ScanAddonsDirectory( char *exePath, char *gamedir ){
@ -142,7 +196,6 @@ void Moon_ScanAddonsDirectory( char *exePath, char *gamedir ){
string languages_dir = l_path.substr(0, l_path.find_last_of("/\\")) + "/addons/";
printf("Loading Directory: %s\n", languages_dir.c_str());
// Scan directory for JSON files
DIR *dir = opendir(languages_dir.c_str());
if (dir) {
struct dirent *de;
@ -164,7 +217,7 @@ void Moon_SaveTexture(TextureData* data, string tex){
void Moon_LoadBaseTexture(char* data, long size, string texture){
if(baseGameTextures.find(texture) == baseGameTextures.end()){
baseGameTextures.insert(pair<string, TextureFileEntry*>(texture, new TextureFileEntry({.size = size, .data = data})));
baseGameTextures.insert(pair<string, TextureFileEntry*>(texture, new TextureFileEntry({.path = "", .size = size, .data = data})));
}
}
@ -173,32 +226,7 @@ TextureData* Moon_GetTexture(string texture){
}
void Moon_TextFlyLoad(int id){
switch(id){
case 0:
Moon_LoadDefaultAddon();
break;
case 1:
Moon_LoadDefaultAddon();
Moon_LoadAddon("/home/alex/Downloads/packs/converted/mc.bit");
Moon_LoadAddon("/home/alex/Downloads/packs/converted/beta-hud.bit");
Moon_LoadAddon("/home/alex/Downloads/packs/converted/moon64-demo.bit");
break;
case 2:
Moon_LoadDefaultAddon();
Moon_LoadAddon("/home/alex/Downloads/packs/converted/owo.bit");
Moon_LoadAddon("/home/alex/Downloads/packs/converted/beta-hud.bit");
Moon_LoadAddon("/home/alex/Downloads/packs/converted/moon64-demo.bit");
break;
case 3:
Moon_LoadDefaultAddon();
Moon_LoadAddon("/home/alex/Downloads/packs/converted/r96-hd.bit");
Moon_LoadAddon("/home/alex/Downloads/packs/converted/beta-hud.bit");
Moon_LoadAddon("/home/alex/Downloads/packs/converted/moon64-demo.bit");
break;
}
}
void Moon_PreInitModEngine(){
@ -206,11 +234,19 @@ void Moon_PreInitModEngine(){
}
void Moon_TestRebuildOrder(vector<int> order){
Moon_BakeTextureCache(order);
}
using namespace std::chrono;
void Moon_InitModEngine( char *exePath, char *gamedir ){
Moon_ScanAddonsDirectory(exePath, gamedir);
Moon_BakeTextureCache();
Moon_UploadCacheToGPU();
milliseconds start_ms = duration_cast< milliseconds >( system_clock::now().time_since_epoch() );
Moon_LoadAddon("/home/alex/Music/Moon64-Packs/converted/minecraft.bit");
Moon_LoadAddon("/home/alex/Music/Moon64-Packs/converted/beta-hud.bit");
Moon_LoadAddon("/home/alex/disks/uwu/Projects/UnderVolt/Moon64-Packs/converted/owo.bit");
Moon_BakeTextureCache({1, 0, 2, 3});
milliseconds end_ms = duration_cast< milliseconds >( system_clock::now().time_since_epoch() );
std::cout << "Finised loading in " << ((end_ms.count() - start_ms.count()) / 1000) << " seconds" << std::endl;
}

View File

@ -21,5 +21,6 @@ void Moon_LoadBaseTexture(char* data, long size, std::string texture);
// TESTS
void Moon_TextFlyLoad(int id);
void Moon_TestRebuildOrder(std::vector<int> order);
void Moon_LoadTexture(int tile, const char *fullpath, struct GfxRenderingAPI *gfx_rapi);
#endif

View File

@ -6,6 +6,8 @@
#include <vector>
#include <string>
class zip_file;
extern "C" {
#include "pc/gfx/gfx_pc.h"
}
@ -18,8 +20,8 @@ public:
std::string website;
std::string icon;
std::string main;
std::string path;
std::map<std::string, TextureFileEntry*> textures;
// GFXTextureCache* textureCache;
bool readOnly;
bool enabled;
};

View File

@ -1,7 +1,9 @@
#ifndef Moon64FileEntry
#define Moon64FileEntry
#include <string>
struct TextureFileEntry {
std::string path;
long size;
char* data;
};

View File

@ -102,4 +102,8 @@ void moon_load_base_texture(char* data, long size, char* texture){
Moon_LoadBaseTexture(data, size, string(texture));
}
void moon_load_texture(int tile, const char *fullpath, struct GfxRenderingAPI *gfx_rapi){
Moon_LoadTexture(tile, fullpath, gfx_rapi);
}
}

View File

@ -26,6 +26,7 @@ void moon_engine_save_texture(struct TextureData* data, char* tex);
struct TextureData* moon_engine_get_texture(char* tex);
struct TextureData* moon_engine_init_texture();
void moon_load_base_texture(char* data, long size, char* texture);
void moon_load_texture(int tile, const char *fullpath, struct GfxRenderingAPI *gfx_rapi);
#endif
#endif

View File

@ -12,9 +12,7 @@ extern "C" {
#include "pc/configfile.h"
}
std::vector<int> order = {
0, 2, 1
};
std::vector<int> order = {1, 0, 2, 3};
MWValue *tmpButton;

View File

@ -6,9 +6,6 @@
#include <stdbool.h>
#include <assert.h>
#define STB_IMAGE_IMPLEMENTATION
#include <stb/stb_image.h>
#ifndef _LANGUAGE_C
#define _LANGUAGE_C
#endif
@ -278,7 +275,7 @@ static bool gfx_texture_cache_lookup(int tile, struct TextureData **n, const uin
node->fmt = fmt;
node->siz = siz;
moon_engine_save_texture(node, orig_addr);
if(n != NULL) *n = node;
return false;
}
@ -304,27 +301,6 @@ static bool preload_base_texture(void* user, const char *fullpath) {
return true;
}
static inline void load_texture(const char *fullpath) {
int w, h;
u64 imgsize = 0;
u8 *imgdata = fs_load_file(fullpath, &imgsize);
if (imgdata) {
// TODO: implement stbi_callbacks or some shit instead of loading the whole texture
u8 *data = stbi_load_from_memory(imgdata, imgsize, &w, &h, NULL, 4);
free(imgdata);
if (data) {
gfx_rapi->upload_texture(data, w, h);
stbi_image_free(data); // don't need this anymore
return;
}
}
fprintf(stderr, "could not load texture: `%s`\n", fullpath);
// replace with missing texture
gfx_rapi->upload_texture(missing_texture, MISSING_W, MISSING_H);
}
static inline void load_memory_texture(void *imgdata, long size) {
int w, h;
@ -417,7 +393,7 @@ static void import_texture(int tile) {
// load it from an external image in our data path
char texname[SYS_MAX_PATH];
snprintf(texname, sizeof(texname), FS_TEXTUREDIR "/%s.png", (const char*)rdp.loaded_texture[tile].addr);
load_texture(texname);
moon_load_texture(tile, texname, gfx_rapi);
}
static void gfx_normalize_vector(float v[3]) {