mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
add support for different texture samplers
This commit is contained in:
parent
424d22cf69
commit
15d62ecf6b
@ -47,7 +47,7 @@ namespace engine {
|
|||||||
|
|
||||||
/* this descriptor set is bound per-material */
|
/* this descriptor set is bound per-material */
|
||||||
const gfx::DescriptorSetLayout* materialSetLayout;
|
const gfx::DescriptorSetLayout* materialSetLayout;
|
||||||
const gfx::Sampler* materialSetSampler;
|
std::unordered_map<gfx::SamplerInfo, const gfx::Sampler*> samplers{};
|
||||||
};
|
};
|
||||||
|
|
||||||
class Application {
|
class Application {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
// Enums and structs for the graphics abstraction
|
// Enums and structs for the graphics abstraction
|
||||||
|
|
||||||
@ -70,17 +71,11 @@ namespace engine::gfx {
|
|||||||
FLOAT4
|
FLOAT4
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class TextureFilter {
|
enum class Filter : int {
|
||||||
LINEAR,
|
LINEAR,
|
||||||
NEAREST,
|
NEAREST,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class MipmapSetting {
|
|
||||||
OFF,
|
|
||||||
NEAREST,
|
|
||||||
LINEAR,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class DescriptorType {
|
enum class DescriptorType {
|
||||||
UNIFORM_BUFFER,
|
UNIFORM_BUFFER,
|
||||||
COMBINED_IMAGE_SAMPLER,
|
COMBINED_IMAGE_SAMPLER,
|
||||||
@ -123,4 +118,35 @@ namespace engine::gfx {
|
|||||||
ShaderStageFlags::Flags stageFlags = 0;
|
ShaderStageFlags::Flags stageFlags = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SamplerInfo {
|
||||||
|
Filter minify;
|
||||||
|
Filter magnify;
|
||||||
|
Filter mipmap;
|
||||||
|
bool anisotropicFiltering;
|
||||||
|
|
||||||
|
bool operator==(const SamplerInfo&) const = default;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
template<>
|
||||||
|
struct std::hash<engine::gfx::SamplerInfo>
|
||||||
|
{
|
||||||
|
std::size_t operator()(const engine::gfx::SamplerInfo& k) const
|
||||||
|
{
|
||||||
|
using std::hash;
|
||||||
|
|
||||||
|
size_t h1 = hash<int>()(static_cast<int>(k.minify));
|
||||||
|
size_t h2 = hash<int>()(static_cast<int>(k.magnify));
|
||||||
|
size_t h3 = hash<int>()(static_cast<int>(k.mipmap));
|
||||||
|
size_t h4 = hash<bool>()(k.anisotropicFiltering);
|
||||||
|
|
||||||
|
return ((h1 & 0xFF) << 24) |
|
||||||
|
((h2 & 0xFF) << 16) |
|
||||||
|
((h3 & 0xFF) << 8) |
|
||||||
|
((h4 & 0xFF) << 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -52,7 +52,7 @@ namespace engine {
|
|||||||
gfx::Image* createImage(uint32_t w, uint32_t h, const void* imageData);
|
gfx::Image* createImage(uint32_t w, uint32_t h, const void* imageData);
|
||||||
void destroyImage(const gfx::Image* image);
|
void destroyImage(const gfx::Image* image);
|
||||||
|
|
||||||
gfx::Sampler* createSampler();
|
const gfx::Sampler* createSampler(const gfx::SamplerInfo& info);
|
||||||
void destroySampler(const gfx::Sampler* sampler);
|
void destroySampler(const gfx::Sampler* sampler);
|
||||||
|
|
||||||
uint64_t getFrameCount();
|
uint64_t getFrameCount();
|
||||||
|
@ -4,6 +4,10 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
namespace engine {
|
||||||
|
struct RenderData;
|
||||||
|
}
|
||||||
|
|
||||||
namespace engine::resources {
|
namespace engine::resources {
|
||||||
|
|
||||||
class Texture {
|
class Texture {
|
||||||
@ -16,7 +20,7 @@ public:
|
|||||||
ANISOTROPIC,
|
ANISOTROPIC,
|
||||||
};
|
};
|
||||||
|
|
||||||
Texture(GFXDevice* gfxDevice, const gfx::DescriptorSetLayout* materialSetLayout, const gfx::Sampler* sampler, const std::string& path, Filtering filtering, bool useMipmaps, bool useLinearMagFilter);
|
Texture(RenderData& renderData, const std::string& path, Filtering filtering);
|
||||||
~Texture();
|
~Texture();
|
||||||
Texture(const Texture&) = delete;
|
Texture(const Texture&) = delete;
|
||||||
Texture& operator=(const Texture&) = delete;
|
Texture& operator=(const Texture&) = delete;
|
||||||
|
@ -111,7 +111,6 @@ namespace engine {
|
|||||||
binding0.stageFlags = gfx::ShaderStageFlags::FRAGMENT;
|
binding0.stageFlags = gfx::ShaderStageFlags::FRAGMENT;
|
||||||
}
|
}
|
||||||
renderData.materialSetLayout = gfx()->createDescriptorSetLayout(materialSetBindings);
|
renderData.materialSetLayout = gfx()->createDescriptorSetLayout(materialSetBindings);
|
||||||
renderData.materialSetSampler = gfx()->createSampler();
|
|
||||||
|
|
||||||
// default resources
|
// default resources
|
||||||
{
|
{
|
||||||
@ -144,13 +143,9 @@ namespace engine {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto whiteTexture = std::make_unique<resources::Texture>(
|
auto whiteTexture = std::make_unique<resources::Texture>(
|
||||||
gfx(),
|
renderData,
|
||||||
renderData.materialSetLayout,
|
|
||||||
renderData.materialSetSampler,
|
|
||||||
getResourcePath("engine/textures/white.png"),
|
getResourcePath("engine/textures/white.png"),
|
||||||
resources::Texture::Filtering::OFF,
|
resources::Texture::Filtering::OFF
|
||||||
false,
|
|
||||||
false
|
|
||||||
);
|
);
|
||||||
getResourceManager<resources::Texture>()->addPersistent("builtin.white", std::move(whiteTexture));
|
getResourceManager<resources::Texture>()->addPersistent("builtin.white", std::move(whiteTexture));
|
||||||
}
|
}
|
||||||
@ -158,7 +153,9 @@ namespace engine {
|
|||||||
|
|
||||||
Application::~Application()
|
Application::~Application()
|
||||||
{
|
{
|
||||||
gfx()->destroySampler(renderData.materialSetSampler);
|
for (const auto& [info, sampler] : renderData.samplers) {
|
||||||
|
gfx()->destroySampler(sampler);
|
||||||
|
}
|
||||||
gfx()->destroyDescriptorSetLayout(renderData.materialSetLayout);
|
gfx()->destroyDescriptorSetLayout(renderData.materialSetLayout);
|
||||||
|
|
||||||
gfx()->destroyUniformBuffer(renderData.frameSetUniformBuffer);
|
gfx()->destroyUniformBuffer(renderData.frameSetUniformBuffer);
|
||||||
|
@ -154,15 +154,26 @@ namespace engine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[[maybe_unused]] static VkFilter getTextureFilter(gfx::TextureFilter filter)
|
[[maybe_unused]] static VkFilter getFilter(gfx::Filter filter)
|
||||||
{
|
{
|
||||||
switch (filter) {
|
switch (filter) {
|
||||||
case gfx::TextureFilter::LINEAR:
|
case gfx::Filter::LINEAR:
|
||||||
return VK_FILTER_LINEAR;
|
return VK_FILTER_LINEAR;
|
||||||
case gfx::TextureFilter::NEAREST:
|
case gfx::Filter::NEAREST:
|
||||||
return VK_FILTER_NEAREST;
|
return VK_FILTER_NEAREST;
|
||||||
}
|
}
|
||||||
throw std::runtime_error("Unknown texture filter");
|
throw std::runtime_error("Unknown filter");
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] static VkSamplerMipmapMode getSamplerMipmapMode(gfx::Filter filter)
|
||||||
|
{
|
||||||
|
switch (filter) {
|
||||||
|
case gfx::Filter::LINEAR:
|
||||||
|
return VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||||
|
case gfx::Filter::NEAREST:
|
||||||
|
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||||
|
}
|
||||||
|
throw std::runtime_error("Unknown filter");
|
||||||
}
|
}
|
||||||
|
|
||||||
[[maybe_unused]] static VkSampleCountFlags getSampleCountFlags(gfx::MSAALevel level)
|
[[maybe_unused]] static VkSampleCountFlags getSampleCountFlags(gfx::MSAALevel level)
|
||||||
@ -1537,20 +1548,20 @@ namespace engine {
|
|||||||
delete image;
|
delete image;
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::Sampler *GFXDevice::createSampler()
|
const gfx::Sampler *GFXDevice::createSampler(const gfx::SamplerInfo& info)
|
||||||
{
|
{
|
||||||
gfx::Sampler* out = new gfx::Sampler{};
|
gfx::Sampler* out = new gfx::Sampler{};
|
||||||
|
|
||||||
VkSamplerCreateInfo samplerInfo{};
|
VkSamplerCreateInfo samplerInfo{};
|
||||||
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||||
samplerInfo.magFilter = VK_FILTER_LINEAR;
|
samplerInfo.magFilter = converters::getFilter(info.magnify);
|
||||||
samplerInfo.minFilter = VK_FILTER_LINEAR;
|
samplerInfo.minFilter = converters::getFilter(info.minify);
|
||||||
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
samplerInfo.mipmapMode = converters::getSamplerMipmapMode(info.mipmap);
|
||||||
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.mipLodBias = 0.0f;
|
samplerInfo.mipLodBias = 0.0f;
|
||||||
samplerInfo.anisotropyEnable = VK_TRUE;
|
samplerInfo.anisotropyEnable = info.anisotropicFiltering ? VK_TRUE : VK_FALSE;
|
||||||
samplerInfo.maxAnisotropy = pimpl->device.properties.limits.maxSamplerAnisotropy;
|
samplerInfo.maxAnisotropy = pimpl->device.properties.limits.maxSamplerAnisotropy;
|
||||||
samplerInfo.minLod = 0.0f;
|
samplerInfo.minLod = 0.0f;
|
||||||
samplerInfo.maxLod = VK_LOD_CLAMP_NONE;
|
samplerInfo.maxLod = VK_LOD_CLAMP_NONE;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "resources/texture.hpp"
|
#include "resources/texture.hpp"
|
||||||
|
|
||||||
|
#include "application.hpp"
|
||||||
#include "util/files.hpp"
|
#include "util/files.hpp"
|
||||||
#include "log.hpp"
|
#include "log.hpp"
|
||||||
|
|
||||||
@ -7,58 +8,46 @@
|
|||||||
|
|
||||||
namespace engine::resources {
|
namespace engine::resources {
|
||||||
|
|
||||||
Texture::Texture(GFXDevice* gfxDevice, const gfx::DescriptorSetLayout* materialSetLayout, const gfx::Sampler* sampler, const std::string& path, Filtering filtering, bool useMipmaps, bool useLinearMagFilter)
|
Texture::Texture(RenderData& renderData, const std::string& path, Filtering filtering)
|
||||||
: m_gfxDevice(gfxDevice)
|
: m_gfxDevice(renderData.gfxdev.get())
|
||||||
{
|
{
|
||||||
|
|
||||||
int width, height;
|
int width, height;
|
||||||
std::unique_ptr<std::vector<uint8_t>> texbuf = util::readImageFile(path, &width, &height);
|
std::unique_ptr<std::vector<uint8_t>> texbuf = util::readImageFile(path, &width, &height);
|
||||||
|
|
||||||
gfx::TextureFilter minFilter = gfx::TextureFilter::NEAREST;
|
gfx::SamplerInfo samplerInfo{};
|
||||||
gfx::TextureFilter magFilter = gfx::TextureFilter::NEAREST;
|
|
||||||
gfx::MipmapSetting mipmapSetting = gfx::MipmapSetting::OFF;
|
|
||||||
bool anisotropyEnable = false;
|
|
||||||
|
|
||||||
if (useLinearMagFilter) {
|
samplerInfo.magnify = gfx::Filter::LINEAR;
|
||||||
magFilter = gfx::TextureFilter::LINEAR;
|
|
||||||
} else {
|
|
||||||
magFilter = gfx::TextureFilter::NEAREST;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (filtering) {
|
switch (filtering) {
|
||||||
case Filtering::OFF:
|
case Filtering::OFF:
|
||||||
minFilter = gfx::TextureFilter::NEAREST;
|
samplerInfo.minify = gfx::Filter::NEAREST;
|
||||||
mipmapSetting = gfx::MipmapSetting::NEAREST;
|
samplerInfo.mipmap = gfx::Filter::NEAREST;
|
||||||
anisotropyEnable = false;
|
samplerInfo.anisotropicFiltering = false;
|
||||||
break;
|
break;
|
||||||
case Filtering::BILINEAR:
|
case Filtering::BILINEAR:
|
||||||
minFilter = gfx::TextureFilter::LINEAR;
|
samplerInfo.minify = gfx::Filter::LINEAR;
|
||||||
mipmapSetting = gfx::MipmapSetting::NEAREST;
|
samplerInfo.mipmap = gfx::Filter::NEAREST;
|
||||||
anisotropyEnable = false;
|
samplerInfo.anisotropicFiltering = false;
|
||||||
break;
|
break;
|
||||||
case Filtering::TRILINEAR:
|
case Filtering::TRILINEAR:
|
||||||
minFilter = gfx::TextureFilter::LINEAR;
|
samplerInfo.minify = gfx::Filter::LINEAR;
|
||||||
mipmapSetting = gfx::MipmapSetting::LINEAR;
|
samplerInfo.mipmap = gfx::Filter::LINEAR;
|
||||||
anisotropyEnable = false;
|
samplerInfo.anisotropicFiltering = false;
|
||||||
break;
|
break;
|
||||||
case Filtering::ANISOTROPIC:
|
case Filtering::ANISOTROPIC:
|
||||||
minFilter = gfx::TextureFilter::LINEAR;
|
samplerInfo.minify = gfx::Filter::LINEAR;
|
||||||
mipmapSetting = gfx::MipmapSetting::LINEAR;
|
samplerInfo.mipmap = gfx::Filter::LINEAR;
|
||||||
anisotropyEnable = true;
|
samplerInfo.anisotropicFiltering = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useMipmaps == false) {
|
if (renderData.samplers.contains(samplerInfo) == false) {
|
||||||
mipmapSetting = gfx::MipmapSetting::OFF;
|
renderData.samplers.insert(std::make_pair(samplerInfo, m_gfxDevice->createSampler(samplerInfo)));
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)minFilter;
|
|
||||||
(void)magFilter;
|
|
||||||
(void)mipmapSetting;
|
|
||||||
(void)anisotropyEnable;
|
|
||||||
|
|
||||||
m_image = m_gfxDevice->createImage(width, height, texbuf->data());
|
m_image = m_gfxDevice->createImage(width, height, texbuf->data());
|
||||||
m_descriptorSet = m_gfxDevice->allocateDescriptorSet(materialSetLayout);
|
m_descriptorSet = m_gfxDevice->allocateDescriptorSet(renderData.materialSetLayout);
|
||||||
m_gfxDevice->updateDescriptorCombinedImageSampler(m_descriptorSet, 0, m_image, sampler);
|
m_gfxDevice->updateDescriptorCombinedImageSampler(m_descriptorSet, 0, m_image, renderData.samplers.at(samplerInfo));
|
||||||
|
|
||||||
LOG_INFO("Loaded texture: {}, width: {} height: {}", path, width, height);
|
LOG_INFO("Loaded texture: {}, width: {} height: {}", path, width, height);
|
||||||
|
|
||||||
|
@ -182,8 +182,8 @@ namespace engine::util {
|
|||||||
absPath /= texPath.C_Str();
|
absPath /= texPath.C_Str();
|
||||||
try {
|
try {
|
||||||
textures[i] = std::make_shared<resources::Texture>(
|
textures[i] = std::make_shared<resources::Texture>(
|
||||||
parent->app()->gfx(), parent->app()->renderData.materialSetLayout, parent->app()->renderData.materialSetSampler, absPath.string(),
|
parent->app()->renderData, absPath.string(),
|
||||||
resources::Texture::Filtering::TRILINEAR, true, true);
|
resources::Texture::Filtering::TRILINEAR);
|
||||||
} catch (const std::runtime_error&) {
|
} catch (const std::runtime_error&) {
|
||||||
textures[i] = parent->app()->getResource<resources::Texture>("builtin.white");
|
textures[i] = parent->app()->getResource<resources::Texture>("builtin.white");
|
||||||
}
|
}
|
||||||
|
@ -84,22 +84,14 @@ void playGame(GameSettings settings)
|
|||||||
|
|
||||||
/* shared resources */
|
/* shared resources */
|
||||||
auto grassTexture = std::make_shared<engine::resources::Texture>(
|
auto grassTexture = std::make_shared<engine::resources::Texture>(
|
||||||
app.gfx(),
|
app.renderData,
|
||||||
app.renderData.materialSetLayout,
|
|
||||||
app.renderData.materialSetSampler,
|
|
||||||
app.getResourcePath("textures/grass.jpg"),
|
app.getResourcePath("textures/grass.jpg"),
|
||||||
engine::resources::Texture::Filtering::ANISOTROPIC,
|
engine::resources::Texture::Filtering::ANISOTROPIC
|
||||||
true,
|
|
||||||
true
|
|
||||||
);
|
);
|
||||||
auto spaceTexture = std::make_shared<engine::resources::Texture>(
|
auto spaceTexture = std::make_shared<engine::resources::Texture>(
|
||||||
app.gfx(),
|
app.renderData,
|
||||||
app.renderData.materialSetLayout,
|
|
||||||
app.renderData.materialSetSampler,
|
|
||||||
app.getResourcePath("textures/space2.png"),
|
app.getResourcePath("textures/space2.png"),
|
||||||
engine::resources::Texture::Filtering::ANISOTROPIC,
|
engine::resources::Texture::Filtering::ANISOTROPIC
|
||||||
true,
|
|
||||||
true
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/* cube */
|
/* cube */
|
||||||
|
Loading…
Reference in New Issue
Block a user