mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
ALlow texture filtering to be changed
This commit is contained in:
parent
ea51d669d9
commit
6e45aba65b
@ -35,6 +35,12 @@ namespace engine::gfx {
|
|||||||
NEAREST,
|
NEAREST,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class MipmapSetting {
|
||||||
|
OFF,
|
||||||
|
NEAREST,
|
||||||
|
LINEAR,
|
||||||
|
};
|
||||||
|
|
||||||
struct VertexBufferDesc {
|
struct VertexBufferDesc {
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
};
|
};
|
||||||
|
@ -35,7 +35,14 @@ namespace engine {
|
|||||||
gfx::Buffer* createBuffer(gfx::BufferType type, uint64_t size, const void* data);
|
gfx::Buffer* createBuffer(gfx::BufferType type, uint64_t size, const void* data);
|
||||||
void destroyBuffer(const gfx::Buffer* buffer);
|
void destroyBuffer(const gfx::Buffer* buffer);
|
||||||
|
|
||||||
gfx::Texture* createTexture(const void* imageData, uint32_t w, uint32_t h, gfx::TextureFilter minFilter, gfx::TextureFilter magFilter);
|
gfx::Texture* createTexture(
|
||||||
|
const void* imageData,
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
gfx::TextureFilter minFilter,
|
||||||
|
gfx::TextureFilter magFilter,
|
||||||
|
gfx::MipmapSetting mipmapSetting,
|
||||||
|
bool useAnisotropy = false);
|
||||||
void destroyTexture(const gfx::Texture* texture);
|
void destroyTexture(const gfx::Texture* texture);
|
||||||
|
|
||||||
// wait until all the active GPU queues have finished working
|
// wait until all the active GPU queues have finished working
|
||||||
|
@ -9,7 +9,14 @@ namespace engine::resources {
|
|||||||
class Texture {
|
class Texture {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Texture(GFXDevice* gfxDevice, const std::string& path);
|
enum class Filtering {
|
||||||
|
OFF,
|
||||||
|
BILINEAR,
|
||||||
|
TRILINEAR,
|
||||||
|
ANISOTROPIC,
|
||||||
|
};
|
||||||
|
|
||||||
|
Texture(GFXDevice* gfxDevice, const std::string& path, Filtering filtering, bool useMipmaps, bool useLinearMagFilter);
|
||||||
~Texture();
|
~Texture();
|
||||||
Texture(const Texture&) = delete;
|
Texture(const Texture&) = delete;
|
||||||
Texture& operator=(const Texture&) = delete;
|
Texture& operator=(const Texture&) = delete;
|
||||||
|
@ -67,17 +67,17 @@ namespace engine {
|
|||||||
m_resourcesPath = getResourcesPath();
|
m_resourcesPath = getResourcesPath();
|
||||||
|
|
||||||
// register resource managers
|
// register resource managers
|
||||||
registerResourceManager<engine::resources::Texture>();
|
registerResourceManager<resources::Texture>();
|
||||||
registerResourceManager<engine::resources::Shader>();
|
registerResourceManager<resources::Shader>();
|
||||||
registerResourceManager<engine::resources::Material>();
|
registerResourceManager<resources::Material>();
|
||||||
registerResourceManager<engine::resources::Mesh>();
|
registerResourceManager<resources::Mesh>();
|
||||||
|
|
||||||
// default resources
|
// default resources
|
||||||
{
|
{
|
||||||
resources::Shader::VertexParams vertParams{};
|
resources::Shader::VertexParams vertParams{};
|
||||||
vertParams.hasNormal = true;
|
vertParams.hasNormal = true;
|
||||||
vertParams.hasUV0 = true;
|
vertParams.hasUV0 = true;
|
||||||
auto texturedShader = std::make_unique<engine::resources::Shader>(
|
auto texturedShader = std::make_unique<resources::Shader>(
|
||||||
gfx(),
|
gfx(),
|
||||||
getResourcePath("engine/shaders/texture.vert").c_str(),
|
getResourcePath("engine/shaders/texture.vert").c_str(),
|
||||||
getResourcePath("engine/shaders/texture.frag").c_str(),
|
getResourcePath("engine/shaders/texture.frag").c_str(),
|
||||||
@ -85,14 +85,17 @@ namespace engine {
|
|||||||
false,
|
false,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
getResourceManager<engine::resources::Shader>()->addPersistent("engine.textured", std::move(texturedShader));
|
getResourceManager<resources::Shader>()->addPersistent("engine.textured", std::move(texturedShader));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto whiteTexture = std::make_unique<engine::resources::Texture>(
|
auto whiteTexture = std::make_unique<resources::Texture>(
|
||||||
gfx(),
|
gfx(),
|
||||||
getResourcePath("engine/textures/white.png")
|
getResourcePath("engine/textures/white.png"),
|
||||||
|
resources::Texture::Filtering::OFF,
|
||||||
|
false,
|
||||||
|
false
|
||||||
);
|
);
|
||||||
getResourceManager<engine::resources::Texture>()->addPersistent("engine.white", std::move(whiteTexture));
|
getResourceManager<resources::Texture>()->addPersistent("engine.white", std::move(whiteTexture));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,7 +488,6 @@ namespace engine {
|
|||||||
|
|
||||||
static VkSampleCountFlagBits getMaxSampleCount(VkPhysicalDevice physicalDevice)
|
static VkSampleCountFlagBits getMaxSampleCount(VkPhysicalDevice physicalDevice)
|
||||||
{
|
{
|
||||||
|
|
||||||
VkPhysicalDeviceProperties physicalDeviceProperties;
|
VkPhysicalDeviceProperties physicalDeviceProperties;
|
||||||
vkGetPhysicalDeviceProperties(physicalDevice, &physicalDeviceProperties);
|
vkGetPhysicalDeviceProperties(physicalDevice, &physicalDeviceProperties);
|
||||||
|
|
||||||
@ -500,7 +499,7 @@ namespace engine {
|
|||||||
if (counts & VK_SAMPLE_COUNT_8_BIT) { return VK_SAMPLE_COUNT_8_BIT; }
|
if (counts & VK_SAMPLE_COUNT_8_BIT) { return VK_SAMPLE_COUNT_8_BIT; }
|
||||||
if (counts & VK_SAMPLE_COUNT_4_BIT) { return VK_SAMPLE_COUNT_4_BIT; }
|
if (counts & VK_SAMPLE_COUNT_4_BIT) { return VK_SAMPLE_COUNT_4_BIT; }
|
||||||
if (counts & VK_SAMPLE_COUNT_2_BIT) { return VK_SAMPLE_COUNT_2_BIT; }
|
if (counts & VK_SAMPLE_COUNT_2_BIT) { return VK_SAMPLE_COUNT_2_BIT; }
|
||||||
return VK_SAMPLE_COUNT_1_BIT;
|
throw std::runtime_error("MSAA is not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is called not just on initialisation, but also when the window is resized.
|
// This is called not just on initialisation, but also when the window is resized.
|
||||||
@ -636,6 +635,7 @@ namespace engine {
|
|||||||
res = vkGetSwapchainImagesKHR(device, swapchain->swapchain, &swapchainImageCount, swapchain->images.data());
|
res = vkGetSwapchainImagesKHR(device, swapchain->swapchain, &swapchainImageCount, swapchain->images.data());
|
||||||
assert(res == VK_SUCCESS);
|
assert(res == VK_SUCCESS);
|
||||||
|
|
||||||
|
// Use multisample anti-aliasing
|
||||||
swapchain->msaaSamples = getMaxSampleCount(physicalDevice);
|
swapchain->msaaSamples = getMaxSampleCount(physicalDevice);
|
||||||
|
|
||||||
// create depth buffer if old depth buffer is wrong size.
|
// create depth buffer if old depth buffer is wrong size.
|
||||||
@ -1004,6 +1004,8 @@ namespace engine {
|
|||||||
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
||||||
VkDevice device = VK_NULL_HANDLE;
|
VkDevice device = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
Swapchain swapchain{};
|
||||||
|
|
||||||
std::vector<Queue> queues{};
|
std::vector<Queue> queues{};
|
||||||
Queue gfxQueue{};
|
Queue gfxQueue{};
|
||||||
Queue presentQueue{};
|
Queue presentQueue{};
|
||||||
@ -1011,20 +1013,17 @@ namespace engine {
|
|||||||
|
|
||||||
VmaAllocator allocator = nullptr;
|
VmaAllocator allocator = nullptr;
|
||||||
|
|
||||||
|
// device settings
|
||||||
bool vsync = false;
|
bool vsync = false;
|
||||||
|
float maxSamplerAnisotropy;
|
||||||
|
|
||||||
Swapchain swapchain{};
|
// render loop
|
||||||
|
|
||||||
uint64_t FRAMECOUNT = 0;
|
uint64_t FRAMECOUNT = 0;
|
||||||
|
|
||||||
std::array<VkCommandBuffer, FRAMES_IN_FLIGHT> commandBuffers{};
|
std::array<VkCommandBuffer, FRAMES_IN_FLIGHT> commandBuffers{};
|
||||||
std::array<VkFence, FRAMES_IN_FLIGHT> inFlightFences{};
|
std::array<VkFence, FRAMES_IN_FLIGHT> inFlightFences{};
|
||||||
|
|
||||||
std::queue<DrawCall> drawQueue{};
|
std::queue<DrawCall> drawQueue{};
|
||||||
|
|
||||||
VkDescriptorSetLayoutBinding uboLayoutBinding{};
|
VkDescriptorSetLayoutBinding uboLayoutBinding{};
|
||||||
VkDescriptorSetLayout descriptorSetLayout{};
|
VkDescriptorSetLayout descriptorSetLayout{};
|
||||||
|
|
||||||
VkDescriptorSetLayoutBinding samplerLayoutBinding{};
|
VkDescriptorSetLayoutBinding samplerLayoutBinding{};
|
||||||
VkDescriptorSetLayout samplerSetLayout{};
|
VkDescriptorSetLayout samplerSetLayout{};
|
||||||
|
|
||||||
@ -1043,14 +1042,13 @@ namespace engine {
|
|||||||
// initialise vulkan
|
// initialise vulkan
|
||||||
|
|
||||||
res = volkInitialize();
|
res = volkInitialize();
|
||||||
if (res == VK_ERROR_INITIALIZATION_FAILED) {
|
if (res != VK_SUCCESS) {
|
||||||
throw std::runtime_error("Unable to load vulkan, is it installed?");
|
throw std::runtime_error("Unable to load vulkan, is it installed?");
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(res == VK_SUCCESS);
|
|
||||||
|
|
||||||
uint32_t vulkanVersion = volkGetInstanceVersion();
|
uint32_t vulkanVersion = volkGetInstanceVersion();
|
||||||
if (vulkanVersion < VK_MAKE_VERSION(1, 3, 0)) {
|
assert(vulkanVersion != 0);
|
||||||
|
if (vulkanVersion < VK_API_VERSION_1_3) {
|
||||||
throw std::runtime_error("The loaded Vulkan version must be at least 1.3");
|
throw std::runtime_error("The loaded Vulkan version must be at least 1.3");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1122,17 +1120,16 @@ namespace engine {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
for (const char* ext : extensions) {
|
for (const char* ext : extensions) {
|
||||||
TRACE("Using Vulkan instance extension: {}", ext);
|
DEBUG("Using Vulkan instance extension: {}", ext);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
res = vkCreateInstance(&instanceInfo, nullptr, &pimpl->instance);
|
res = vkCreateInstance(&instanceInfo, nullptr, &pimpl->instance);
|
||||||
if (res == VK_ERROR_INCOMPATIBLE_DRIVER) {
|
if (res == VK_ERROR_INCOMPATIBLE_DRIVER) {
|
||||||
throw std::runtime_error("The graphics driver is incompatible with vulkan");
|
throw std::runtime_error("The graphics driver is incompatible with vulkan");
|
||||||
|
} else if (res != VK_SUCCESS) {
|
||||||
|
throw std::runtime_error("vkCreateInstance failed: " + std::to_string(res));
|
||||||
}
|
}
|
||||||
assert(res == VK_SUCCESS);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1145,9 +1142,11 @@ namespace engine {
|
|||||||
{
|
{
|
||||||
VkDebugUtilsMessengerCreateInfoEXT createInfo = getDebugMessengerCreateInfo();
|
VkDebugUtilsMessengerCreateInfoEXT createInfo = getDebugMessengerCreateInfo();
|
||||||
|
|
||||||
[[maybe_unused]] VkResult res;
|
VkResult res;
|
||||||
res = vkCreateDebugUtilsMessengerEXT(pimpl->instance, &createInfo, nullptr, &pimpl->debugMessenger);
|
res = vkCreateDebugUtilsMessengerEXT(pimpl->instance, &createInfo, nullptr, &pimpl->debugMessenger);
|
||||||
assert(res == VK_SUCCESS);
|
if (res != VK_SUCCESS) {
|
||||||
|
throw std::runtime_error("vkCreateDebugUtilsMessengerExt failed: " + std::to_string(res));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1188,7 +1187,7 @@ namespace engine {
|
|||||||
res = vkEnumerateDeviceExtensionProperties(dev, nullptr, &extensionCount, availableExtensions.data());
|
res = vkEnumerateDeviceExtensionProperties(dev, nullptr, &extensionCount, availableExtensions.data());
|
||||||
assert(res == VK_SUCCESS);
|
assert(res == VK_SUCCESS);
|
||||||
|
|
||||||
for (const auto& extToFind : requiredDeviceExtensions) {
|
for (const char* extToFind : requiredDeviceExtensions) {
|
||||||
bool extFound = false;
|
bool extFound = false;
|
||||||
for (const auto& ext : availableExtensions) {
|
for (const auto& ext : availableExtensions) {
|
||||||
if (strcmp(extToFind, ext.extensionName) == 0) {
|
if (strcmp(extToFind, ext.extensionName) == 0) {
|
||||||
@ -1216,6 +1215,7 @@ namespace engine {
|
|||||||
vkGetPhysicalDeviceFeatures(dev, &devFeatures);
|
vkGetPhysicalDeviceFeatures(dev, &devFeatures);
|
||||||
// anisotropic filtering is needed
|
// anisotropic filtering is needed
|
||||||
if (devFeatures.samplerAnisotropy == VK_FALSE) continue;
|
if (devFeatures.samplerAnisotropy == VK_FALSE) continue;
|
||||||
|
pimpl->maxSamplerAnisotropy = devProps.limits.maxSamplerAnisotropy;
|
||||||
|
|
||||||
// check for linear filtering for mipmaps
|
// check for linear filtering for mipmaps
|
||||||
VkFormatProperties formatProperties{};
|
VkFormatProperties formatProperties{};
|
||||||
@ -1342,7 +1342,6 @@ namespace engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pimpl->presentQueue = getQueueSupporting(pimpl->queues, QueueFlags::TRANSFER);
|
pimpl->presentQueue = getQueueSupporting(pimpl->queues, QueueFlags::TRANSFER);
|
||||||
|
|
||||||
pimpl->gfxQueue = getQueueSupporting(pimpl->queues, QueueFlags::GRAPHICS);
|
pimpl->gfxQueue = getQueueSupporting(pimpl->queues, QueueFlags::GRAPHICS);
|
||||||
|
|
||||||
VkCommandPoolCreateInfo gfxCmdPoolInfo{
|
VkCommandPoolCreateInfo gfxCmdPoolInfo{
|
||||||
@ -2064,15 +2063,26 @@ namespace engine {
|
|||||||
delete buffer;
|
delete buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::Texture* GFXDevice::createTexture(const void* imageData, uint32_t w, uint32_t h, gfx::TextureFilter minFilter, gfx::TextureFilter magFilter)
|
gfx::Texture* GFXDevice::createTexture(
|
||||||
|
const void* imageData,
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
gfx::TextureFilter minFilter,
|
||||||
|
gfx::TextureFilter magFilter,
|
||||||
|
gfx::MipmapSetting mipmapSetting,
|
||||||
|
bool useAnisotropy)
|
||||||
{
|
{
|
||||||
auto out = new gfx::Texture;
|
auto out = new gfx::Texture;
|
||||||
|
|
||||||
[[maybe_unused]] VkResult res;
|
[[maybe_unused]] VkResult res;
|
||||||
|
|
||||||
size_t imageSize = w * h * 4;
|
size_t imageSize = width * height * 4;
|
||||||
|
|
||||||
out->mipLevels = static_cast<uint32_t>(std::floor(std::log2(std::max(w, h)))) + 1;
|
if (mipmapSetting == gfx::MipmapSetting::OFF) {
|
||||||
|
out->mipLevels = 1;
|
||||||
|
} else {
|
||||||
|
out->mipLevels = static_cast<uint32_t>(std::floor(std::log2(std::max(width, height)))) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
// first load image into staging buffer
|
// first load image into staging buffer
|
||||||
VkBuffer stagingBuffer;
|
VkBuffer stagingBuffer;
|
||||||
@ -2104,8 +2114,8 @@ namespace engine {
|
|||||||
VkImageCreateInfo imageInfo{};
|
VkImageCreateInfo imageInfo{};
|
||||||
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||||
imageInfo.imageType = VK_IMAGE_TYPE_2D;
|
imageInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||||
imageInfo.extent.width = w;
|
imageInfo.extent.width = width;
|
||||||
imageInfo.extent.height = h;
|
imageInfo.extent.height = height;
|
||||||
imageInfo.extent.depth = 1;
|
imageInfo.extent.depth = 1;
|
||||||
imageInfo.mipLevels = out->mipLevels;
|
imageInfo.mipLevels = out->mipLevels;
|
||||||
imageInfo.arrayLayers = 1;
|
imageInfo.arrayLayers = 1;
|
||||||
@ -2140,14 +2150,14 @@ namespace engine {
|
|||||||
region.imageSubresource.baseArrayLayer = 0;
|
region.imageSubresource.baseArrayLayer = 0;
|
||||||
region.imageSubresource.layerCount = 1;
|
region.imageSubresource.layerCount = 1;
|
||||||
region.imageOffset = { 0, 0, 0 };
|
region.imageOffset = { 0, 0, 0 };
|
||||||
region.imageExtent.width = w;
|
region.imageExtent.width = width;
|
||||||
region.imageExtent.height = h;
|
region.imageExtent.height = height;
|
||||||
region.imageExtent.depth = 1;
|
region.imageExtent.depth = 1;
|
||||||
|
|
||||||
vkCmdCopyBufferToImage(commandBuffer, stagingBuffer, out->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
vkCmdCopyBufferToImage(commandBuffer, stagingBuffer, out->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||||
|
|
||||||
// Mipmap generation handles the transition to SHADER_READ_ONLY_OPTIMAL
|
// Mipmap generation handles the transition to SHADER_READ_ONLY_OPTIMAL
|
||||||
cmdGenerateMipmaps(commandBuffer, out->image, w, h, out->mipLevels);
|
cmdGenerateMipmaps(commandBuffer, out->image, width, height, out->mipLevels);
|
||||||
|
|
||||||
// end cmd buffer
|
// end cmd buffer
|
||||||
endOneTimeCommands(pimpl->device, pimpl->commandPool, commandBuffer, pimpl->gfxQueue.handle);
|
endOneTimeCommands(pimpl->device, pimpl->commandPool, commandBuffer, pimpl->gfxQueue.handle);
|
||||||
@ -2174,12 +2184,12 @@ namespace engine {
|
|||||||
res = vkCreateImageView(pimpl->device, &imageViewInfo, nullptr, &out->imageView);
|
res = vkCreateImageView(pimpl->device, &imageViewInfo, nullptr, &out->imageView);
|
||||||
assert(res == VK_SUCCESS);
|
assert(res == VK_SUCCESS);
|
||||||
|
|
||||||
// create texture sampler
|
|
||||||
{
|
|
||||||
|
|
||||||
VkFilter magFilterInternal = vkinternal::getTextureFilter(magFilter);
|
VkFilter magFilterInternal = vkinternal::getTextureFilter(magFilter);
|
||||||
VkFilter minFilterInternal = vkinternal::getTextureFilter(minFilter);
|
VkFilter minFilterInternal = vkinternal::getTextureFilter(minFilter);
|
||||||
|
|
||||||
|
// create texture sampler
|
||||||
|
{
|
||||||
|
|
||||||
VkSamplerCreateInfo samplerInfo{};
|
VkSamplerCreateInfo samplerInfo{};
|
||||||
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||||
samplerInfo.magFilter = magFilterInternal;
|
samplerInfo.magFilter = magFilterInternal;
|
||||||
@ -2187,19 +2197,21 @@ namespace engine {
|
|||||||
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||||
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||||
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||||
samplerInfo.anisotropyEnable = VK_FALSE;
|
if (useAnisotropy) {
|
||||||
if (magFilterInternal == VK_FILTER_LINEAR && minFilterInternal == VK_FILTER_LINEAR) {
|
|
||||||
// Find max anisotropic filtering level
|
|
||||||
VkPhysicalDeviceProperties properties{};
|
|
||||||
vkGetPhysicalDeviceProperties(pimpl->physicalDevice, &properties);
|
|
||||||
samplerInfo.anisotropyEnable = VK_TRUE;
|
samplerInfo.anisotropyEnable = VK_TRUE;
|
||||||
samplerInfo.maxAnisotropy = properties.limits.maxSamplerAnisotropy;
|
} else {
|
||||||
|
samplerInfo.anisotropyEnable = VK_FALSE;
|
||||||
}
|
}
|
||||||
|
samplerInfo.maxAnisotropy = pimpl->maxSamplerAnisotropy;
|
||||||
samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
|
samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
|
||||||
samplerInfo.unnormalizedCoordinates = VK_FALSE;
|
samplerInfo.unnormalizedCoordinates = VK_FALSE;
|
||||||
samplerInfo.compareEnable = VK_FALSE;
|
samplerInfo.compareEnable = VK_FALSE;
|
||||||
samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
|
samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
|
||||||
|
if (mipmapSetting == gfx::MipmapSetting::LINEAR) {
|
||||||
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||||
|
} else {
|
||||||
|
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||||
|
}
|
||||||
samplerInfo.minLod = 0.0f;
|
samplerInfo.minLod = 0.0f;
|
||||||
samplerInfo.maxLod = static_cast<float>(out->mipLevels);
|
samplerInfo.maxLod = static_cast<float>(out->mipLevels);
|
||||||
samplerInfo.mipLodBias = 0.0f;
|
samplerInfo.mipLodBias = 0.0f;
|
||||||
|
@ -7,19 +7,54 @@
|
|||||||
|
|
||||||
namespace engine::resources {
|
namespace engine::resources {
|
||||||
|
|
||||||
Texture::Texture(GFXDevice* gfxDevice, const std::string& path)
|
Texture::Texture(GFXDevice* gfxDevice, const std::string& path, Filtering filtering, bool useMipmaps, bool useLinearMagFilter)
|
||||||
: m_gfxDevice(gfxDevice)
|
: m_gfxDevice(gfxDevice)
|
||||||
{
|
{
|
||||||
|
|
||||||
int width, height;
|
int width, height;
|
||||||
auto texbuf = util::readImageFile(path, &width, &height);
|
auto texbuf = util::readImageFile(path, &width, &height);
|
||||||
|
|
||||||
gfx::TextureFilter filter = gfx::TextureFilter::LINEAR;
|
gfx::TextureFilter minFilter, magFilter;
|
||||||
if (width <= 8 || height <= 8) {
|
gfx::MipmapSetting mipmapSetting;
|
||||||
filter = gfx::TextureFilter::NEAREST;
|
bool anisotropyEnable;
|
||||||
|
|
||||||
|
if (useLinearMagFilter) {
|
||||||
|
magFilter = gfx::TextureFilter::LINEAR;
|
||||||
|
} else {
|
||||||
|
magFilter = gfx::TextureFilter::NEAREST;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_gpuTexture = m_gfxDevice->createTexture(texbuf->data(), (uint32_t)width, (uint32_t)height, gfx::TextureFilter::LINEAR, filter);
|
switch (filtering) {
|
||||||
|
case Filtering::OFF:
|
||||||
|
minFilter = gfx::TextureFilter::NEAREST;
|
||||||
|
mipmapSetting = gfx::MipmapSetting::NEAREST;
|
||||||
|
anisotropyEnable = false;
|
||||||
|
break;
|
||||||
|
case Filtering::BILINEAR:
|
||||||
|
minFilter = gfx::TextureFilter::LINEAR;
|
||||||
|
mipmapSetting = gfx::MipmapSetting::NEAREST;
|
||||||
|
anisotropyEnable = false;
|
||||||
|
break;
|
||||||
|
case Filtering::TRILINEAR:
|
||||||
|
minFilter = gfx::TextureFilter::LINEAR;
|
||||||
|
mipmapSetting = gfx::MipmapSetting::LINEAR;
|
||||||
|
anisotropyEnable = false;
|
||||||
|
break;
|
||||||
|
case Filtering::ANISOTROPIC:
|
||||||
|
minFilter = gfx::TextureFilter::LINEAR;
|
||||||
|
mipmapSetting = gfx::MipmapSetting::LINEAR;
|
||||||
|
anisotropyEnable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useMipmaps == false) {
|
||||||
|
mipmapSetting = gfx::MipmapSetting::OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_gpuTexture = m_gfxDevice->createTexture(
|
||||||
|
texbuf->data(), (uint32_t)width, (uint32_t)height,
|
||||||
|
minFilter, magFilter,
|
||||||
|
mipmapSetting,
|
||||||
|
anisotropyEnable);
|
||||||
|
|
||||||
INFO("Loaded texture: {}, width: {} height: {}", path, width, height);
|
INFO("Loaded texture: {}, width: {} height: {}", path, width, height);
|
||||||
|
|
||||||
|
@ -148,11 +148,11 @@ namespace engine::util {
|
|||||||
|
|
||||||
const char* errString = importer.GetErrorString();
|
const char* errString = importer.GetErrorString();
|
||||||
if (errString[0] != '\0' || scene == nullptr) {
|
if (errString[0] != '\0' || scene == nullptr) {
|
||||||
throw std::runtime_error(errString);
|
throw std::runtime_error("assimp error: " + std::string(errString));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE) {
|
if (scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE) {
|
||||||
throw std::runtime_error(errString);
|
throw std::runtime_error("assimp error (incomplete): " + std::string(errString));
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(scene->HasAnimations() == false);
|
assert(scene->HasAnimations() == false);
|
||||||
@ -181,7 +181,9 @@ namespace engine::util {
|
|||||||
absPath = absPath.parent_path();
|
absPath = absPath.parent_path();
|
||||||
absPath /= texPath.C_Str();
|
absPath /= texPath.C_Str();
|
||||||
try {
|
try {
|
||||||
textures[i] = std::make_shared<resources::Texture>(parent->app()->gfx(), absPath.string());
|
textures[i] = std::make_shared<resources::Texture>(
|
||||||
|
parent->app()->gfx(), absPath.string(),
|
||||||
|
resources::Texture::Filtering::TRILINEAR, true, true);
|
||||||
} catch (const std::runtime_error&) {
|
} catch (const std::runtime_error&) {
|
||||||
textures[i] = parent->app()->getResource<resources::Texture>("engine.white");
|
textures[i] = parent->app()->getResource<resources::Texture>("engine.white");
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,8 @@ void playGame()
|
|||||||
{
|
{
|
||||||
engine::Application app(PROJECT_NAME, PROJECT_VERSION);
|
engine::Application app(PROJECT_NAME, PROJECT_VERSION);
|
||||||
|
|
||||||
|
app.setFrameLimiter(true);
|
||||||
|
|
||||||
// configure window
|
// configure window
|
||||||
app.window()->setRelativeMouseMode(true);
|
app.window()->setRelativeMouseMode(true);
|
||||||
|
|
||||||
@ -61,11 +63,14 @@ void playGame()
|
|||||||
|
|
||||||
myScene->getSystem<engine::RenderSystem>()->setCameraEntity(camera);
|
myScene->getSystem<engine::RenderSystem>()->setCameraEntity(camera);
|
||||||
|
|
||||||
// engine::util::loadMeshFromFile(myScene, app.getResourcePath("models/astronaut/astronaut.dae"));
|
engine::util::loadMeshFromFile(myScene, app.getResourcePath("models/van/van.dae"));
|
||||||
|
|
||||||
auto grassTexture = std::make_shared<engine::resources::Texture>(
|
auto grassTexture = std::make_shared<engine::resources::Texture>(
|
||||||
app.gfx(),
|
app.gfx(),
|
||||||
app.getResourcePath("textures/grass.jpg")
|
app.getResourcePath("textures/grass.jpg"),
|
||||||
|
engine::resources::Texture::Filtering::ANISOTROPIC,
|
||||||
|
true,
|
||||||
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
uint32_t enemy = myScene->createEntity("enemy");
|
uint32_t enemy = myScene->createEntity("enemy");
|
||||||
|
Loading…
Reference in New Issue
Block a user