mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-03 00:03:50 +00:00
Port UI icon textures from OpenGL to Vulkan, fix loading screen clear values
Replace all glGenTextures/glTexImage2D calls in UI code with Vulkan texture uploads via new VkContext::uploadImGuiTexture() helper. This fixes segfaults from calling OpenGL functions without a GL context (null GLEW function pointers). - Add uploadImGuiTexture() to VkContext with staging buffer upload pattern - Convert game_screen, inventory_screen, spellbook_screen, talent_screen from GLuint/GL calls to VkDescriptorSet/Vulkan uploads - Fix loading_screen clearValueCount (was 1, needs 2 or 3 for MSAA)
This commit is contained in:
parent
b1a9d231c7
commit
325254dfcb
11 changed files with 314 additions and 136 deletions
|
|
@ -1,5 +1,6 @@
|
|||
#include "ui/game_screen.hpp"
|
||||
#include "rendering/character_preview.hpp"
|
||||
#include "rendering/vk_context.hpp"
|
||||
#include "core/application.hpp"
|
||||
#include "core/coordinates.hpp"
|
||||
#include "core/spawn_presets.hpp"
|
||||
|
|
@ -854,7 +855,7 @@ void GameScreen::renderChatWindow(game::GameHandler& gameHandler) {
|
|||
if (const auto* eq = findComparableEquipped(static_cast<uint8_t>(info->inventoryType))) {
|
||||
ImGui::Separator();
|
||||
ImGui::TextDisabled("Equipped:");
|
||||
GLuint eqIcon = inventoryScreen.getItemIcon(eq->item.displayInfoId);
|
||||
VkDescriptorSet eqIcon = inventoryScreen.getItemIcon(eq->item.displayInfoId);
|
||||
if (eqIcon) {
|
||||
ImGui::Image((ImTextureID)(uintptr_t)eqIcon, ImVec2(18.0f, 18.0f));
|
||||
ImGui::SameLine();
|
||||
|
|
@ -3217,8 +3218,8 @@ void GameScreen::renderWorldMap(game::GameHandler& gameHandler) {
|
|||
// Action Bar (Phase 3)
|
||||
// ============================================================
|
||||
|
||||
GLuint GameScreen::getSpellIcon(uint32_t spellId, pipeline::AssetManager* am) {
|
||||
if (spellId == 0 || !am) return 0;
|
||||
VkDescriptorSet GameScreen::getSpellIcon(uint32_t spellId, pipeline::AssetManager* am) {
|
||||
if (spellId == 0 || !am) return VK_NULL_HANDLE;
|
||||
|
||||
// Check cache first
|
||||
auto cit = spellIconCache_.find(spellId);
|
||||
|
|
@ -3276,43 +3277,41 @@ GLuint GameScreen::getSpellIcon(uint32_t spellId, pipeline::AssetManager* am) {
|
|||
// Look up spellId -> SpellIconID -> icon path
|
||||
auto iit = spellIconIds_.find(spellId);
|
||||
if (iit == spellIconIds_.end()) {
|
||||
spellIconCache_[spellId] = 0;
|
||||
return 0;
|
||||
spellIconCache_[spellId] = VK_NULL_HANDLE;
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
auto pit = spellIconPaths_.find(iit->second);
|
||||
if (pit == spellIconPaths_.end()) {
|
||||
spellIconCache_[spellId] = 0;
|
||||
return 0;
|
||||
spellIconCache_[spellId] = VK_NULL_HANDLE;
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
// Path from DBC has no extension — append .blp
|
||||
std::string iconPath = pit->second + ".blp";
|
||||
auto blpData = am->readFile(iconPath);
|
||||
if (blpData.empty()) {
|
||||
spellIconCache_[spellId] = 0;
|
||||
return 0;
|
||||
spellIconCache_[spellId] = VK_NULL_HANDLE;
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
auto image = pipeline::BLPLoader::load(blpData);
|
||||
if (!image.isValid()) {
|
||||
spellIconCache_[spellId] = 0;
|
||||
return 0;
|
||||
spellIconCache_[spellId] = VK_NULL_HANDLE;
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
GLuint texId = 0;
|
||||
glGenTextures(1, &texId);
|
||||
glBindTexture(GL_TEXTURE_2D, texId);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.width, image.height, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, image.data.data());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
// Upload to Vulkan via VkContext
|
||||
auto* window = core::Application::getInstance().getWindow();
|
||||
auto* vkCtx = window ? window->getVkContext() : nullptr;
|
||||
if (!vkCtx) {
|
||||
spellIconCache_[spellId] = VK_NULL_HANDLE;
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
spellIconCache_[spellId] = texId;
|
||||
return texId;
|
||||
VkDescriptorSet ds = vkCtx->uploadImGuiTexture(image.data.data(), image.width, image.height);
|
||||
spellIconCache_[spellId] = ds;
|
||||
return ds;
|
||||
}
|
||||
|
||||
void GameScreen::renderActionBar(game::GameHandler& gameHandler) {
|
||||
|
|
@ -3362,7 +3361,7 @@ void GameScreen::renderActionBar(game::GameHandler& gameHandler) {
|
|||
};
|
||||
|
||||
// Try to get icon texture for this slot
|
||||
GLuint iconTex = 0;
|
||||
VkDescriptorSet iconTex = VK_NULL_HANDLE;
|
||||
const game::ItemDef* barItemDef = nullptr;
|
||||
uint32_t itemDisplayInfoId = 0;
|
||||
std::string itemNameFromQuery;
|
||||
|
|
@ -3655,22 +3654,17 @@ void GameScreen::renderBagBar(game::GameHandler& gameHandler) {
|
|||
if (!blpData.empty()) {
|
||||
auto image = pipeline::BLPLoader::load(blpData);
|
||||
if (image.isValid()) {
|
||||
glGenTextures(1, &backpackIconTexture_);
|
||||
glBindTexture(GL_TEXTURE_2D, backpackIconTexture_);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.width, image.height, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, image.data.data());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
auto* w = core::Application::getInstance().getWindow();
|
||||
auto* vkCtx = w ? w->getVkContext() : nullptr;
|
||||
if (vkCtx)
|
||||
backpackIconTexture_ = vkCtx->uploadImGuiTexture(image.data.data(), image.width, image.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Track bag slot screen rects for drop detection
|
||||
ImVec2 bagSlotMins[4], bagSlotMaxs[4];
|
||||
GLuint bagIcons[4] = {};
|
||||
VkDescriptorSet bagIcons[4] = {};
|
||||
|
||||
// Slots 1-4: Bag slots (leftmost)
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
|
|
@ -3680,7 +3674,7 @@ void GameScreen::renderBagBar(game::GameHandler& gameHandler) {
|
|||
game::EquipSlot bagSlot = static_cast<game::EquipSlot>(static_cast<int>(game::EquipSlot::BAG1) + i);
|
||||
const auto& bagItem = inv.getEquipSlot(bagSlot);
|
||||
|
||||
GLuint bagIcon = 0;
|
||||
VkDescriptorSet bagIcon = VK_NULL_HANDLE;
|
||||
if (!bagItem.empty() && bagItem.item.displayInfoId != 0) {
|
||||
bagIcon = inventoryScreen.getItemIcon(bagItem.item.displayInfoId);
|
||||
}
|
||||
|
|
@ -3844,7 +3838,7 @@ void GameScreen::renderBagBar(game::GameHandler& gameHandler) {
|
|||
auto pickedEquip = static_cast<game::EquipSlot>(
|
||||
static_cast<int>(game::EquipSlot::BAG1) + bagBarPickedSlot_);
|
||||
const auto& pickedItem = inv2.getEquipSlot(pickedEquip);
|
||||
GLuint pickedIcon = 0;
|
||||
VkDescriptorSet pickedIcon = VK_NULL_HANDLE;
|
||||
if (!pickedItem.empty() && pickedItem.item.displayInfoId != 0) {
|
||||
pickedIcon = inventoryScreen.getItemIcon(pickedItem.item.displayInfoId);
|
||||
}
|
||||
|
|
@ -4429,7 +4423,7 @@ void GameScreen::renderBuffBar(game::GameHandler& gameHandler) {
|
|||
ImVec4 borderColor = isBuff ? ImVec4(0.2f, 0.8f, 0.2f, 0.9f) : ImVec4(0.8f, 0.2f, 0.2f, 0.9f);
|
||||
|
||||
// Try to get spell icon
|
||||
GLuint iconTex = 0;
|
||||
VkDescriptorSet iconTex = VK_NULL_HANDLE;
|
||||
if (assetMgr) {
|
||||
iconTex = getSpellIcon(aura.spellId, assetMgr);
|
||||
}
|
||||
|
|
@ -4534,7 +4528,7 @@ void GameScreen::renderLootWindow(game::GameHandler& gameHandler) {
|
|||
// Get item icon
|
||||
uint32_t displayId = item.displayInfoId;
|
||||
if (displayId == 0 && info) displayId = info->displayInfoId;
|
||||
GLuint iconTex = inventoryScreen.getItemIcon(displayId);
|
||||
VkDescriptorSet iconTex = inventoryScreen.getItemIcon(displayId);
|
||||
|
||||
ImVec2 cursor = ImGui::GetCursorScreenPos();
|
||||
float rowH = std::max(iconSize, ImGui::GetTextLineHeight() * 2.0f);
|
||||
|
|
@ -4963,7 +4957,7 @@ void GameScreen::renderQuestOfferRewardWindow(game::GameHandler& gameHandler) {
|
|||
bool selected = (selectedChoice == static_cast<int>(i));
|
||||
|
||||
// Get item icon if we have displayInfoId
|
||||
uint32_t iconTex = 0;
|
||||
VkDescriptorSet iconTex = VK_NULL_HANDLE;
|
||||
if (info && info->valid && info->displayInfoId != 0) {
|
||||
iconTex = inventoryScreen.getItemIcon(info->displayInfoId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "ui/inventory_screen.hpp"
|
||||
#include "game/game_handler.hpp"
|
||||
#include "core/application.hpp"
|
||||
#include "rendering/vk_context.hpp"
|
||||
#include "core/input.hpp"
|
||||
#include "rendering/character_preview.hpp"
|
||||
#include "rendering/character_renderer.hpp"
|
||||
|
|
@ -72,10 +73,7 @@ const game::ItemSlot* findComparableEquipped(const game::Inventory& inventory, u
|
|||
} // namespace
|
||||
|
||||
InventoryScreen::~InventoryScreen() {
|
||||
// Clean up icon textures
|
||||
for (auto& [id, tex] : iconCache_) {
|
||||
if (tex) glDeleteTextures(1, &tex);
|
||||
}
|
||||
// Vulkan textures are owned by VkContext and cleaned up on shutdown
|
||||
iconCache_.clear();
|
||||
}
|
||||
|
||||
|
|
@ -95,8 +93,8 @@ ImVec4 InventoryScreen::getQualityColor(game::ItemQuality quality) {
|
|||
// Item Icon Loading
|
||||
// ============================================================
|
||||
|
||||
GLuint InventoryScreen::getItemIcon(uint32_t displayInfoId) {
|
||||
if (displayInfoId == 0 || !assetManager_) return 0;
|
||||
VkDescriptorSet InventoryScreen::getItemIcon(uint32_t displayInfoId) {
|
||||
if (displayInfoId == 0 || !assetManager_) return VK_NULL_HANDLE;
|
||||
|
||||
auto it = iconCache_.find(displayInfoId);
|
||||
if (it != iconCache_.end()) return it->second;
|
||||
|
|
@ -104,50 +102,48 @@ GLuint InventoryScreen::getItemIcon(uint32_t displayInfoId) {
|
|||
// Load ItemDisplayInfo.dbc
|
||||
auto displayInfoDbc = assetManager_->loadDBC("ItemDisplayInfo.dbc");
|
||||
if (!displayInfoDbc) {
|
||||
iconCache_[displayInfoId] = 0;
|
||||
return 0;
|
||||
iconCache_[displayInfoId] = VK_NULL_HANDLE;
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
int32_t recIdx = displayInfoDbc->findRecordById(displayInfoId);
|
||||
if (recIdx < 0) {
|
||||
iconCache_[displayInfoId] = 0;
|
||||
return 0;
|
||||
iconCache_[displayInfoId] = VK_NULL_HANDLE;
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
// Field 5 = inventoryIcon_1
|
||||
const auto* dispL = pipeline::getActiveDBCLayout() ? pipeline::getActiveDBCLayout()->getLayout("ItemDisplayInfo") : nullptr;
|
||||
std::string iconName = displayInfoDbc->getString(static_cast<uint32_t>(recIdx), dispL ? (*dispL)["InventoryIcon"] : 5);
|
||||
if (iconName.empty()) {
|
||||
iconCache_[displayInfoId] = 0;
|
||||
return 0;
|
||||
iconCache_[displayInfoId] = VK_NULL_HANDLE;
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
std::string iconPath = "Interface\\Icons\\" + iconName + ".blp";
|
||||
auto blpData = assetManager_->readFile(iconPath);
|
||||
if (blpData.empty()) {
|
||||
iconCache_[displayInfoId] = 0;
|
||||
return 0;
|
||||
iconCache_[displayInfoId] = VK_NULL_HANDLE;
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
auto image = pipeline::BLPLoader::load(blpData);
|
||||
if (!image.isValid()) {
|
||||
iconCache_[displayInfoId] = 0;
|
||||
return 0;
|
||||
iconCache_[displayInfoId] = VK_NULL_HANDLE;
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
GLuint texId = 0;
|
||||
glGenTextures(1, &texId);
|
||||
glBindTexture(GL_TEXTURE_2D, texId);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.width, image.height, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, image.data.data());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
// Upload to Vulkan via VkContext
|
||||
auto* window = core::Application::getInstance().getWindow();
|
||||
auto* vkCtx = window ? window->getVkContext() : nullptr;
|
||||
if (!vkCtx) {
|
||||
iconCache_[displayInfoId] = VK_NULL_HANDLE;
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
iconCache_[displayInfoId] = texId;
|
||||
return texId;
|
||||
VkDescriptorSet ds = vkCtx->uploadImGuiTexture(image.data.data(), image.width, image.height);
|
||||
iconCache_[displayInfoId] = ds;
|
||||
return ds;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
|
|
@ -507,7 +503,7 @@ void InventoryScreen::renderHeldItem() {
|
|||
ImU32 borderCol = ImGui::ColorConvertFloat4ToU32(qColor);
|
||||
|
||||
// Try to show icon
|
||||
GLuint iconTex = getItemIcon(heldItem.displayInfoId);
|
||||
VkDescriptorSet iconTex = getItemIcon(heldItem.displayInfoId);
|
||||
if (iconTex) {
|
||||
drawList->AddImage((ImTextureID)(uintptr_t)iconTex, pos,
|
||||
ImVec2(pos.x + size, pos.y + size));
|
||||
|
|
@ -1351,7 +1347,7 @@ void InventoryScreen::renderItemSlot(game::Inventory& inventory, const game::Ite
|
|||
}
|
||||
|
||||
// Try to show icon
|
||||
GLuint iconTex = getItemIcon(item.displayInfoId);
|
||||
VkDescriptorSet iconTex = getItemIcon(item.displayInfoId);
|
||||
if (iconTex) {
|
||||
drawList->AddImage((ImTextureID)(uintptr_t)iconTex, pos,
|
||||
ImVec2(pos.x + size, pos.y + size));
|
||||
|
|
@ -1559,7 +1555,7 @@ void InventoryScreen::renderItemTooltip(const game::ItemDef& item, const game::I
|
|||
if (const game::ItemSlot* eq = findComparableEquipped(*inventory, item.inventoryType)) {
|
||||
ImGui::Separator();
|
||||
ImGui::TextDisabled("Equipped:");
|
||||
GLuint eqIcon = getItemIcon(eq->item.displayInfoId);
|
||||
VkDescriptorSet eqIcon = getItemIcon(eq->item.displayInfoId);
|
||||
if (eqIcon) {
|
||||
ImGui::Image((ImTextureID)(uintptr_t)eqIcon, ImVec2(18.0f, 18.0f));
|
||||
ImGui::SameLine();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "ui/spellbook_screen.hpp"
|
||||
#include "core/input.hpp"
|
||||
#include "core/application.hpp"
|
||||
#include "rendering/vk_context.hpp"
|
||||
#include "pipeline/asset_manager.hpp"
|
||||
#include "pipeline/dbc_loader.hpp"
|
||||
#include "pipeline/blp_loader.hpp"
|
||||
|
|
@ -201,44 +202,41 @@ void SpellbookScreen::categorizeSpells(const std::unordered_set<uint32_t>& known
|
|||
lastKnownSpellCount = knownSpells.size();
|
||||
}
|
||||
|
||||
GLuint SpellbookScreen::getSpellIcon(uint32_t iconId, pipeline::AssetManager* assetManager) {
|
||||
if (iconId == 0 || !assetManager) return 0;
|
||||
VkDescriptorSet SpellbookScreen::getSpellIcon(uint32_t iconId, pipeline::AssetManager* assetManager) {
|
||||
if (iconId == 0 || !assetManager) return VK_NULL_HANDLE;
|
||||
|
||||
auto cit = spellIconCache.find(iconId);
|
||||
if (cit != spellIconCache.end()) return cit->second;
|
||||
|
||||
auto pit = spellIconPaths.find(iconId);
|
||||
if (pit == spellIconPaths.end()) {
|
||||
spellIconCache[iconId] = 0;
|
||||
return 0;
|
||||
spellIconCache[iconId] = VK_NULL_HANDLE;
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
std::string iconPath = pit->second + ".blp";
|
||||
auto blpData = assetManager->readFile(iconPath);
|
||||
if (blpData.empty()) {
|
||||
spellIconCache[iconId] = 0;
|
||||
return 0;
|
||||
spellIconCache[iconId] = VK_NULL_HANDLE;
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
auto image = pipeline::BLPLoader::load(blpData);
|
||||
if (!image.isValid()) {
|
||||
spellIconCache[iconId] = 0;
|
||||
return 0;
|
||||
spellIconCache[iconId] = VK_NULL_HANDLE;
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
GLuint texId = 0;
|
||||
glGenTextures(1, &texId);
|
||||
glBindTexture(GL_TEXTURE_2D, texId);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.width, image.height, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, image.data.data());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
auto* window = core::Application::getInstance().getWindow();
|
||||
auto* vkCtx = window ? window->getVkContext() : nullptr;
|
||||
if (!vkCtx) {
|
||||
spellIconCache[iconId] = VK_NULL_HANDLE;
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
spellIconCache[iconId] = texId;
|
||||
return texId;
|
||||
VkDescriptorSet ds = vkCtx->uploadImGuiTexture(image.data.data(), image.width, image.height);
|
||||
spellIconCache[iconId] = ds;
|
||||
return ds;
|
||||
}
|
||||
|
||||
const SpellInfo* SpellbookScreen::getSpellInfo(uint32_t spellId) const {
|
||||
|
|
@ -320,7 +318,7 @@ void SpellbookScreen::render(game::GameHandler& gameHandler, pipeline::AssetMana
|
|||
bool isPassive = info->isPassive();
|
||||
bool isDim = isPassive || onCooldown;
|
||||
|
||||
GLuint iconTex = getSpellIcon(info->iconId, assetManager);
|
||||
VkDescriptorSet iconTex = getSpellIcon(info->iconId, assetManager);
|
||||
|
||||
// Selectable consumes clicks properly (prevents window drag)
|
||||
ImGui::Selectable("##row", false,
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
#include "core/input.hpp"
|
||||
#include "core/application.hpp"
|
||||
#include "core/logger.hpp"
|
||||
#include "rendering/vk_context.hpp"
|
||||
#include "pipeline/asset_manager.hpp"
|
||||
#include "pipeline/blp_loader.hpp"
|
||||
#include "pipeline/dbc_layout.hpp"
|
||||
#include <algorithm>
|
||||
#include <GL/glew.h>
|
||||
|
||||
namespace wowee { namespace ui {
|
||||
|
||||
|
|
@ -260,7 +260,7 @@ void TalentScreen::renderTalent(game::GameHandler& gameHandler,
|
|||
|
||||
// Get spell icon
|
||||
uint32_t spellId = talent.rankSpells[0];
|
||||
GLuint iconTex = 0;
|
||||
VkDescriptorSet iconTex = VK_NULL_HANDLE;
|
||||
if (spellId != 0) {
|
||||
auto it = spellIconIds.find(spellId);
|
||||
if (it != spellIconIds.end()) {
|
||||
|
|
@ -491,47 +491,41 @@ void TalentScreen::loadSpellIconDBC(pipeline::AssetManager* assetManager) {
|
|||
LOG_INFO("Talent screen: Loaded ", spellIconPaths.size(), " spell icon paths from SpellIcon.dbc");
|
||||
}
|
||||
|
||||
GLuint TalentScreen::getSpellIcon(uint32_t iconId, pipeline::AssetManager* assetManager) {
|
||||
if (iconId == 0 || !assetManager) return 0;
|
||||
VkDescriptorSet TalentScreen::getSpellIcon(uint32_t iconId, pipeline::AssetManager* assetManager) {
|
||||
if (iconId == 0 || !assetManager) return VK_NULL_HANDLE;
|
||||
|
||||
// Check cache
|
||||
auto cit = spellIconCache.find(iconId);
|
||||
if (cit != spellIconCache.end()) return cit->second;
|
||||
|
||||
// Look up icon path
|
||||
auto pit = spellIconPaths.find(iconId);
|
||||
if (pit == spellIconPaths.end()) {
|
||||
spellIconCache[iconId] = 0;
|
||||
return 0;
|
||||
spellIconCache[iconId] = VK_NULL_HANDLE;
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
// Load BLP file
|
||||
std::string iconPath = pit->second + ".blp";
|
||||
auto blpData = assetManager->readFile(iconPath);
|
||||
if (blpData.empty()) {
|
||||
spellIconCache[iconId] = 0;
|
||||
return 0;
|
||||
spellIconCache[iconId] = VK_NULL_HANDLE;
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
// Decode BLP
|
||||
auto image = pipeline::BLPLoader::load(blpData);
|
||||
if (!image.isValid()) {
|
||||
spellIconCache[iconId] = 0;
|
||||
return 0;
|
||||
spellIconCache[iconId] = VK_NULL_HANDLE;
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
// Create OpenGL texture
|
||||
GLuint texId = 0;
|
||||
glGenTextures(1, &texId);
|
||||
glBindTexture(GL_TEXTURE_2D, texId);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.width, image.height, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, image.data.data());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
auto* window = core::Application::getInstance().getWindow();
|
||||
auto* vkCtx = window ? window->getVkContext() : nullptr;
|
||||
if (!vkCtx) {
|
||||
spellIconCache[iconId] = VK_NULL_HANDLE;
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
spellIconCache[iconId] = texId;
|
||||
return texId;
|
||||
VkDescriptorSet ds = vkCtx->uploadImGuiTexture(image.data.data(), image.width, image.height);
|
||||
spellIconCache[iconId] = ds;
|
||||
return ds;
|
||||
}
|
||||
|
||||
}} // namespace wowee::ui
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue