reepblue Posted February 5, 2022 Share Posted February 5, 2022 I need to load a PNG image from the Steam directory into the GUI. Just using the LoadImage function of the GUI gives me this. Error: Texture file header not found. Error: Failed to load texture "C:/Program Files (x86)/Steam/controller_base/images/api/knockout/sc_rt_md.png" Is there a way of going about this? Do I have to convert this into a Texture first? Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
reepblue Posted February 5, 2022 Author Share Posted February 5, 2022 I don't think I'm storing the buffer right? The SteamUtils call returns false. auto stream = Leadwerks::FileSystem::ReadFile(Input::GetButtonGlyph(actionname)); if (stream == NULL) return NULL; std::vector<uint8_t> data; auto sz = stream->GetSize(); data.resize(sz); int i = stream->Read(data.data(), sz); if (i == 0) return NULL; uint8 pixels[128 * 128 * 32]; if (!SteamUtils()->GetImageRGBA(i, pixels, 128 * 128 * 32)) return NULL; imageref->texture = Texture::Create(128, 128); imageref->texture->SetPixels((const char*)pixels); Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
reepblue Posted February 5, 2022 Author Share Posted February 5, 2022 Made progress, but now I'm getting garbage instead of nothing. //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- Leadwerks::Image* Input::GetActionGlyphTexture(const Action actionname, Leadwerks::GUI* pGUI) { Leadwerks::Image* imageref = NULL; if (g_iCurrentDevice == INPUTDEVICE_KBM) { auto image_path = Input::GetButtonGlyph(actionname); imageref = pGUI->LoadImageA(image_path); } else if (g_iCurrentDevice == INPUTDEVICE_STEAMINPUT) { if (actionname.steamanalog != eControllerAnalogAction_NULL) { // TODO } else if (actionname.steamaction != eControllerDigitalAction_NULL) { auto image_path = Input::GetButtonGlyph(actionname); auto stream = Leadwerks::FileSystem::ReadFile(image_path); if (stream == NULL) { Msg("Warning: Failed to load glyph image \"" + Leadwerks::FileSystem::RealPath(image_path) + "\""); return NULL; } stream->Seek(0); std::vector<uint8_t> data; auto sz = stream->GetSize(); data.resize(sz); uint8 pixels[128 * 128 * 4]; memcpy(&pixels, data.data(), sz); imageref = new Leadwerks::Image(); if (imageref == NULL) Msg("Error: Failed to create image for glyph!!"); imageref->texture = Texture::Create(128, 128); imageref->texture->SetPixels((const char*)pixels); if (imageref->texture == NULL) Msg("Error: Failed to create texture for glyph!!"); } } return imageref; } Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
Josh Posted February 6, 2022 Share Posted February 6, 2022 Where is the pixels data coming from? It looks like you are just reading the contents of the PNG file straight into memory? Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
reepblue Posted February 6, 2022 Author Share Posted February 6, 2022 I ended up doing a batch copy of the images I want from Steam and converted the images using the editor tools. This is only a lazy fix as new devices get supported or the image path can change whenever Valve feels like it. I rewrote the function to make it clearer what I want to do. I have little-to-no experience of reading raw binary data from a file, so I'm just shooting in the dark with samples I'm finding elsewhere. In Ultra, I would just load the png to the GUI with the pixmap class and call it a day. ? Leadwerks::Texture* LoadGlyphTexture(const Action actionname) { // This is the home location for all glyph. const std::string game_glyph_path = "Materials\\GUI\\Glyphs\\"; // Texture Leadwerks::Texture* return_texture = NULL; // The final texture path to load. std::string final_texture_path = ""; // For KBM, this should be staight forward. if (g_iCurrentDevice == INPUTDEVICE_KBM) { if (actionname.key > Key::XButton2) { // Basic key final_texture_path = game_glyph_path + GLYPH_KB_KEY_TEXTURE; } else { if (actionname.key == Key::LButton) { final_texture_path = game_glyph_path + "shared_mouse_l_click_lg.tex"; } else if (actionname.key == Key::RButton) { final_texture_path = game_glyph_path + "shared_mouse_r_click_lg.tex"; } else if (actionname.key == Key::XButton1) { final_texture_path = game_glyph_path + "shared_mouse_4_lg.tex"; } else if (actionname.key == Key::XButton2) { final_texture_path = game_glyph_path + "shared_mouse_5_lg.tex"; } else { // This should also be used for scrolling. final_texture_path = game_glyph_path + "shared_mouse_mid_click_lg.tex"; } } return_texture = LoadTexture(final_texture_path); } #ifdef USE_STEAMWORKS else if (g_iCurrentDevice == INPUTDEVICE_STEAMINPUT) { // Find what Steam wants to load as the Glyph. std::string steaminput_iconpath = ""; if (actionname.steamanalog != eControllerAnalogAction_NULL) { EInputActionOrigin origins[STEAM_CONTROLLER_MAX_ORIGINS]; int nNumOrigins = SteamInput()->GetAnalogActionOrigins(m_ActiveControllerHandle, m_CurrentActionSet, m_ControllerDigitalActionHandles[actionname.steamanalog], origins); if (nNumOrigins) { steaminput_iconpath = std::string(SteamInput()->GetGlyphPNGForActionOrigin(origins[0], k_ESteamInputGlyphSize_Large, 0)); } } else if (actionname.steamaction != eControllerDigitalAction_NULL) { EInputActionOrigin origins[STEAM_CONTROLLER_MAX_ORIGINS]; int nNumOrigins = SteamInput()->GetDigitalActionOrigins(m_ActiveControllerHandle, m_CurrentActionSet, m_ControllerDigitalActionHandles[actionname.steamaction], origins); if (nNumOrigins) { steaminput_iconpath = std::string(SteamInput()->GetGlyphPNGForActionOrigin(origins[0], k_ESteamInputGlyphSize_Large, 0)); } } if (!steaminput_iconpath.empty()) { // Strip the name of the image. auto name = FileSystem::StripAll(steaminput_iconpath); // Build the path with the name of the image of Steam wanted to load. final_texture_path = game_glyph_path + name + ".tex"; // Load the texture off the disk. return_texture = LoadTexture(final_texture_path); // Ok, if the texture doesn't exist (i.e A new controller is supported), build an image from the png. // TODO: This isn't working as of yet.... if (return_texture == NULL) { auto stream = Leadwerks::FileSystem::ReadFile(steaminput_iconpath); if (stream == NULL) { Msg("Warning: Failed to load glyph image \"" + Leadwerks::FileSystem::RealPath(steaminput_iconpath) + "\""); return NULL; } stream->Seek(0); std::vector<uint8_t> data; auto sz = stream->GetSize(); data.resize(sz); uint8 pixels[128 * 128 * 4]; memcpy(&pixels, data.data(), sz); return_texture = Texture::Create(128, 128); return_texture->SetPixels((const char*)pixels); //<- This just makes garbage. } } } #endif return return_texture; } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- Leadwerks::Image* Input::GetActionGlyphTexture(const Action actionname) { Leadwerks::Image* imageref = new Leadwerks::Image(); if (imageref == NULL) { Msg("Error: Failed to create image for glyph!!"); return NULL; } imageref->texture = LoadGlyphTexture(actionname); return imageref; } Other than where I dump garbage data into a texture, the results came out really well. I perfer not to ship my game with all the glyphs for every input device though. Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
Josh Posted February 6, 2022 Share Posted February 6, 2022 PNG is a compressed file format. You need a library to load the PNG image and convert that into raw bits. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
reepblue Posted February 6, 2022 Author Share Posted February 6, 2022 7 minutes ago, Josh said: PNG is a compressed file format. You need a library to load the PNG image and convert that into raw bits. I can use Ultra App Kit! ? I thought there was an in-engine solution for this being the texture converter tool does this. But it makes sense. What I got works for right now and I felt like I spent too much time worrying about what could happen 3 years from now. I don't think loading in UAK would be a good idea if I just need one class from it. Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.