#include "AppBase.h" #include #ifdef _WIN32 #else #include extern AAssetManager* g_assetManager; #endif // _WIN32 void VK_CHECK(VkResult ret) { assert(ret == VK_SUCCESS); } //std::string AppBase::getPath(const std::string path) //{ //#ifdef _WIN32 // std::string android_path = "app/src/main/assets/" + path; // return android_path; //#endif // return path; //} #ifdef _WIN32 std::vector AppBase::readFileUnsignedCharWin32(const std::wstring path, bool example) { std::vector buffer; std::wstring enginePath = L"app/src/main/assets/" + path; if (example) { enginePath = L"example/src/main/assets/" + path; } std::ifstream file{ enginePath, std::ios::ate | std::ios::binary }; if (!file.is_open()) { throw std::runtime_error("failed to open file: "); } size_t fileSize = static_cast(file.tellg()); buffer.resize(fileSize); file.seekg(0); file.read((char*)buffer.data(), fileSize); file.close(); return buffer; } #endif // _WIN32 std::vector AppBase::readFileUnsignedChar(const std::string& path, bool example) { std::vector buffer; #ifdef _WIN32 std::string enginePath = "app/src/main/assets/" + path; if (example) { enginePath = "example/src/main/assets/" + path; } std::ifstream file{ enginePath, std::ios::ate | std::ios::binary }; if (!file.is_open()) { throw std::runtime_error("failed to open file: " + enginePath); } size_t fileSize = static_cast(file.tellg()); buffer.resize(fileSize); file.seekg(0); file.read((char*)buffer.data(), fileSize); file.close(); #else AAsset* asset = AAssetManager_open(g_assetManager, path.c_str(), AASSET_MODE_BUFFER); if (!asset) { logOut << "Failed to load file: " << path.c_str() << std::endl; return buffer; } size_t length = AAsset_getLength(asset); buffer.resize(length); AAsset_read(asset, (char*)buffer.data(), length); AAsset_close(asset); #endif // _WIN32 return buffer; } std::vector AppBase::readFile(const std::string& path) { std::vector buffer; #ifdef _WIN32 std::string enginePath = "app/src/main/assets/" + path; std::ifstream file{ enginePath, std::ios::ate | std::ios::binary }; if (!file.is_open()) { throw std::runtime_error("failed to open file: " + enginePath); } size_t fileSize = static_cast(file.tellg()); buffer.resize(fileSize); file.seekg(0); file.read(buffer.data(), fileSize); file.close(); #else AAsset* asset = AAssetManager_open(g_assetManager, path.c_str(), AASSET_MODE_BUFFER); if (!asset) { logOut << "Failed to load file: " << path.c_str() << std::endl; return buffer; } size_t length = AAsset_getLength(asset); buffer.resize(length); AAsset_read(asset, buffer.data(), length); AAsset_close(asset); #endif // _WIN32 return buffer; } VkShaderModule AppBase::createShaderModule(VkDevice& device, const std::vector& code) { VkShaderModuleCreateInfo createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; createInfo.codeSize = code.size(); createInfo.pCode = reinterpret_cast(code.data()); VkShaderModule shaderModule; if (vkCreateShaderModule(device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) { throw std::runtime_error("failed to create shader module!"); } return shaderModule; } bool AppBase::checkValidationLayerSupport() { uint32_t layerCount; vkEnumerateInstanceLayerProperties(&layerCount, nullptr); std::vector availableLayers(layerCount); vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data()); for (const char* layerName : validationLayers) { bool layerFound = false; for (const auto& layerProperties : availableLayers) { if (strcmp(layerName, layerProperties.layerName) == 0) { layerFound = true; break; } } if (!layerFound) { return false; } } return true; } void checkInstanceExtensions() { uint32_t extensionCount = 0; vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr); std::vector extensions(extensionCount); vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions.data()); logOut << "Android Available instance extensions:" << std::endl; for (const auto& extension : extensions) { logOut << "ExtensionName:" << extension.extensionName << " Version:" << extension.specVersion << std::endl; } } void AppBase::createInstance() { if (enableValidationLayers && !checkValidationLayerSupport()) { throw std::runtime_error("validation layers requested, but not available!"); } VkApplicationInfo appInfo{}; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.pApplicationName = "example"; appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0); appInfo.pEngineName = "No Engine"; appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0); appInfo.apiVersion = VK_API_VERSION_1_0; VkInstanceCreateInfo createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; createInfo.pApplicationInfo = &appInfo; std::vector extensions; #ifdef _WIN32 // 获取 GLFW 所需的扩展 uint32_t glfwExtensionCount = 0; const char** glfwExtensions; glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); // 添加调试扩展 for(int i = 0; i < glfwExtensionCount; i++) { extensions.push_back(glfwExtensions[i]); } #else checkInstanceExtensions(); // Android: 手动添加必要的扩展 extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME); extensions.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); // 可选:添加这些扩展以获得更好的兼容性 extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); #endif if (enableValidationLayers) { extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); } createInfo.enabledExtensionCount = static_cast(extensions.size()); createInfo.ppEnabledExtensionNames = extensions.data(); if (enableValidationLayers) { createInfo.enabledLayerCount = static_cast(validationLayers.size()); createInfo.ppEnabledLayerNames = validationLayers.data(); } else { createInfo.enabledLayerCount = 0; } if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) { throw std::runtime_error("failed to create instance!"); } } static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback( VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData) { std::cerr << "validation layer: " << pCallbackData->pMessage << std::endl; return VK_FALSE; } VkResult CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pDebugMessenger) { auto func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT"); if (func != nullptr) { return func(instance, pCreateInfo, pAllocator, pDebugMessenger); } else { return VK_ERROR_EXTENSION_NOT_PRESENT; } } void AppBase::setupDebugMessenger() { if (!enableValidationLayers) return; VkDebugUtilsMessengerCreateInfoEXT createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; createInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; createInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; createInfo.pfnUserCallback = debugCallback; createInfo.pUserData = nullptr; // Optional if (CreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &debugMessenger) != VK_SUCCESS) { throw std::runtime_error("failed to set up debug messenger!"); } } QueueFamilyIndices AppBase::findQueueFamilies(VkPhysicalDevice device, VkSurfaceKHR& surface) { QueueFamilyIndices indices; uint32_t queueFamilyCount = 0; vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr); std::vector queueFamilies(queueFamilyCount); vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data()); int i = 0; for (const auto& queueFamily : queueFamilies) { if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) { indices.graphicsFamily = i; } VkBool32 presentSupport = false; VK_CHECK(vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport)); if (presentSupport) { indices.presentFamily = i; } if (indices.isComplete()) { break; } i++; } return indices; } bool AppBase::checkSwapChainSupport(VkPhysicalDevice device, VkSurfaceKHR& surface) { uint32_t formatCount; vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, nullptr); uint32_t presentModeCount; vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, nullptr); return formatCount > 0 && presentModeCount > 0; } bool AppBase::checkDeviceExtensionSupport(VkPhysicalDevice device) { // 获取设备支持的扩展数量 uint32_t extensionCount; vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr); // 获取设备支持的扩展列表 std::vector availableExtensions(extensionCount); vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data()); // 定义需要的扩展 const std::vector requiredExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME }; // 检查所有需要的扩展是否都支持 for (const char* requiredExtension : requiredExtensions) { bool extensionFound = false; for (const auto& extension : availableExtensions) { if (strcmp(requiredExtension, extension.extensionName) == 0) { extensionFound = true; break; } } if (!extensionFound) { return false; // 如果有一个扩展不支持,返回 false } } return true; // 所有扩展都支持 } bool AppBase::isDeviceSuitable(VkPhysicalDevice device, VkSurfaceKHR& surface) { QueueFamilyIndices indices = findQueueFamilies(device, surface); bool extensionsSupported = checkDeviceExtensionSupport(device); bool swapChainAdequate = false; if (extensionsSupported) { swapChainAdequate = checkSwapChainSupport(device, surface); } return indices.isComplete() && extensionsSupported && swapChainAdequate; } void AppBase::pickPhysicalDevice(VkPhysicalDevice& physicalDevice, VkSurfaceKHR& surface) { uint32_t deviceCount = 0; vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr); if (deviceCount == 0) { throw std::runtime_error("failed to find GPUs with Vulkan support!"); } std::vector devices(deviceCount); vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data()); for (const auto& device : devices) { if (isDeviceSuitable(device, surface)) { physicalDevice = device; break; } } if (physicalDevice == VK_NULL_HANDLE) { throw std::runtime_error("failed to find a suitable GPU!"); } } // 计算面的法线 void AppBase::calculateFaceNormal(const TextureLoadingVertexStructure& v0, const TextureLoadingVertexStructure& v1, const TextureLoadingVertexStructure& v2, float* outNormal) { // 计算两个边向量 float edge1[3] = { v1.pos[0] - v0.pos[0], v1.pos[1] - v0.pos[1], v1.pos[2] - v0.pos[2] }; float edge2[3] = { v2.pos[0] - v0.pos[0], v2.pos[1] - v0.pos[1], v2.pos[2] - v0.pos[2] }; // 叉积计算法线 outNormal[0] = edge1[1] * edge2[2] - edge1[2] * edge2[1]; outNormal[1] = edge1[2] * edge2[0] - edge1[0] * edge2[2]; outNormal[2] = edge1[0] * edge2[1] - edge1[1] * edge2[0]; // 归一化 float length = std::sqrt(outNormal[0] * outNormal[0] + outNormal[1] * outNormal[1] + outNormal[2] * outNormal[2]); if (length > 0.0f) { outNormal[0] /= length; outNormal[1] /= length; outNormal[2] /= length; } } // 计算所有顶点的法线 void AppBase::calculateVertexNormals(std::vector& obj_vertices, const std::vector& obj_indices) { // 验证索引数量是3的倍数 if (obj_indices.size() % 3 != 0) { return; // 或者抛出异常 } // 为每个顶点创建法线累加器和计数 std::vector> normalSums(obj_vertices.size(), { 0.0f, 0.0f, 0.0f }); std::vector normalCounts(obj_vertices.size(), 0); // 遍历所有三角形 for (size_t i = 0; i < obj_indices.size(); i += 3) { uint32_t idx0 = obj_indices[i]; uint32_t idx1 = obj_indices[i + 1]; uint32_t idx2 = obj_indices[i + 2]; // 验证索引有效性 if (idx0 >= obj_vertices.size() || idx1 >= obj_vertices.size() || idx2 >= obj_vertices.size()) { continue; } // 获取三角形的三个顶点 const auto& v0 = obj_vertices[idx0]; const auto& v1 = obj_vertices[idx1]; const auto& v2 = obj_vertices[idx2]; // 计算面的法线 float faceNormal[3]; calculateFaceNormal(v0, v1, v2, faceNormal); // 将面法线累加到每个顶点 for (int j = 0; j < 3; j++) { normalSums[idx0][j] += faceNormal[j]; normalSums[idx1][j] += faceNormal[j]; normalSums[idx2][j] += faceNormal[j]; } normalCounts[idx0]++; normalCounts[idx1]++; normalCounts[idx2]++; } // 计算每个顶点的平均法线并归一化 for (size_t i = 0; i < obj_vertices.size(); i++) { if (normalCounts[i] > 0) { // 计算平均值 float avgNormal[3] = { normalSums[i][0] / normalCounts[i], normalSums[i][1] / normalCounts[i], normalSums[i][2] / normalCounts[i] }; // 归一化 float length = std::sqrt(avgNormal[0] * avgNormal[0] + avgNormal[1] * avgNormal[1] + avgNormal[2] * avgNormal[2]); if (length > 0.0f) { obj_vertices[i].normal[0] = avgNormal[0] / length; obj_vertices[i].normal[1] = avgNormal[1] / length; obj_vertices[i].normal[2] = avgNormal[2] / length; } else { // 如果法线长度为0,设置为默认值 obj_vertices[i].normal[0] = 0.0f; obj_vertices[i].normal[1] = 1.0f; obj_vertices[i].normal[2] = 0.0f; } } else { // 如果没有面使用这个顶点,设置默认法线 obj_vertices[i].normal[0] = 0.0f; obj_vertices[i].normal[1] = 1.0f; obj_vertices[i].normal[2] = 0.0f; } } }