mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
Finally get textures working again
This commit is contained in:
parent
8f596c9e15
commit
5a824ee015
@ -30,22 +30,24 @@ namespace engine {
|
||||
gfx::DrawBuffer* drawBuffer = nullptr;
|
||||
|
||||
/* uniforms for engine globals */
|
||||
const gfx::DescriptorSetLayout* setZeroLayout;
|
||||
const gfx::DescriptorSet* setZero;
|
||||
struct SetZeroBuffer {
|
||||
const gfx::DescriptorSetLayout* globalSetLayout;
|
||||
const gfx::DescriptorSet* globalSet;
|
||||
struct GlobalSetUniformBuffer {
|
||||
glm::mat4 proj;
|
||||
};
|
||||
const gfx::Image* myImage = nullptr;
|
||||
const gfx::Sampler* mySampler = nullptr;
|
||||
|
||||
gfx::UniformBuffer* setZeroBuffer;
|
||||
gfx::UniformBuffer* globalSetUniformBuffer;
|
||||
|
||||
/* uniforms for per-frame data */
|
||||
const gfx::DescriptorSetLayout* setOneLayout;
|
||||
const gfx::DescriptorSet* setOne;
|
||||
struct SetOneBuffer {
|
||||
const gfx::DescriptorSetLayout* frameSetLayout;
|
||||
const gfx::DescriptorSet* frameSet;
|
||||
struct FrameSetUniformBuffer {
|
||||
glm::mat4 view;
|
||||
};
|
||||
gfx::UniformBuffer* setOneBuffer;
|
||||
gfx::UniformBuffer* frameSetUniformBuffer;
|
||||
|
||||
/* this descriptor set is bound per-material */
|
||||
const gfx::DescriptorSetLayout* materialSetLayout;
|
||||
const gfx::Sampler* materialSetSampler;
|
||||
};
|
||||
|
||||
class Application {
|
||||
|
@ -12,7 +12,6 @@ namespace engine::gfx {
|
||||
struct Pipeline;
|
||||
struct UniformBuffer;
|
||||
struct Buffer;
|
||||
struct Texture;
|
||||
struct DrawBuffer;
|
||||
struct DescriptorSetLayout;
|
||||
struct DescriptorSet;
|
||||
|
@ -55,16 +55,6 @@ namespace engine {
|
||||
gfx::Sampler* createSampler();
|
||||
void destroySampler(const gfx::Sampler* sampler);
|
||||
|
||||
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);
|
||||
|
||||
uint64_t getFrameCount();
|
||||
|
||||
void logPerformanceInfo();
|
||||
|
@ -16,16 +16,18 @@ public:
|
||||
ANISOTROPIC,
|
||||
};
|
||||
|
||||
Texture(GFXDevice* gfxDevice, const std::string& path, Filtering filtering, bool useMipmaps, bool useLinearMagFilter);
|
||||
Texture(GFXDevice* gfxDevice, const gfx::DescriptorSetLayout* materialSetLayout, const gfx::Sampler* sampler, const std::string& path, Filtering filtering, bool useMipmaps, bool useLinearMagFilter);
|
||||
~Texture();
|
||||
Texture(const Texture&) = delete;
|
||||
Texture& operator=(const Texture&) = delete;
|
||||
|
||||
gfx::Texture* getHandle();
|
||||
const gfx::Image* getImage() { return m_image; }
|
||||
const gfx::DescriptorSet* getDescriptorSet() { return m_descriptorSet; }
|
||||
|
||||
private:
|
||||
GFXDevice* m_gfxDevice;
|
||||
gfx::Texture* m_gpuTexture;
|
||||
const gfx::Image* m_image;
|
||||
const gfx::DescriptorSet* m_descriptorSet;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -8,6 +8,9 @@ namespace engine::util {
|
||||
|
||||
std::unique_ptr<std::vector<char>> readTextFile(const std::string& path);
|
||||
std::unique_ptr<std::vector<uint8_t>> readBinaryFile(const std::string& path);
|
||||
|
||||
// Read an image file into a vector byte buffer. PNG and JPG support at a minimum.
|
||||
// Output format is R8G8B8A8_UINT
|
||||
std::unique_ptr<std::vector<uint8_t>> readImageFile(const std::string& path, int *width, int *height);
|
||||
|
||||
}
|
||||
|
@ -1,16 +1,11 @@
|
||||
#version 450
|
||||
|
||||
layout(set = 2, binding = 0) uniform sampler2D materialSetSampler;
|
||||
|
||||
layout(location = 0) in vec2 fragUV;
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
//layout(set = 1, binding = 0) uniform sampler2D texSampler;
|
||||
|
||||
void main() {
|
||||
|
||||
gl_FragDepth = 0.9999;
|
||||
//outColor = texture(texSampler, fragUV);
|
||||
outColor = vec4(fragUV, 0.0, 1.0);
|
||||
|
||||
}
|
||||
|
||||
outColor = texture(materialSetSampler, fragUV);
|
||||
}
|
@ -1,26 +1,24 @@
|
||||
#version 450
|
||||
|
||||
layout(set = 0, binding = 0) uniform GlobalSetUniformBuffer {
|
||||
mat4 proj;
|
||||
} globalSetUniformBuffer;
|
||||
|
||||
layout(set = 1, binding = 0) uniform FrameSetUniformBuffer {
|
||||
mat4 view;
|
||||
} frameSetUniformBuffer;
|
||||
|
||||
layout( push_constant ) uniform Constants {
|
||||
mat4 model;
|
||||
} constants;
|
||||
|
||||
layout(set = 0, binding = 0) uniform SetZeroBuffer {
|
||||
mat4 proj;
|
||||
} setZeroBuffer;
|
||||
|
||||
layout(set = 1, binding = 0) uniform SetOneBuffer {
|
||||
mat4 view;
|
||||
} setOneBuffer;
|
||||
|
||||
layout(location = 0) in vec3 inPosition;
|
||||
layout(location = 2) in vec2 inUV;
|
||||
|
||||
layout(location = 0) out vec2 fragUV;
|
||||
|
||||
void main() {
|
||||
mat4 myView = setOneBuffer.view;
|
||||
myView[3] = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
vec4 pos = setZeroBuffer.proj * myView * constants.model * vec4(inPosition, 1.0);
|
||||
gl_Position = pos;
|
||||
vec3 position = mat3(frameSetUniformBuffer.view) * vec3(constants.model * vec4(inPosition, 1.0));
|
||||
gl_Position = (globalSetUniformBuffer.proj * vec4(position, 0.0)).xyzz;
|
||||
fragUV = inUV;
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
#version 450
|
||||
|
||||
layout(set = 2, binding = 0) uniform sampler2D materialSetSampler;
|
||||
|
||||
layout(location = 0) in vec3 fragPos;
|
||||
layout(location = 1) in vec3 fragNorm;
|
||||
layout(location = 2) in vec2 fragUV;
|
||||
@ -7,15 +9,13 @@ layout(location = 3) in vec3 fragLightPos;
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
layout(set = 0, binding = 1) uniform sampler2D texSampler;
|
||||
|
||||
void main() {
|
||||
|
||||
// constants
|
||||
vec3 lightColor = vec3(1.0, 1.0, 1.0);
|
||||
vec3 ambientColor = vec3(1.0, 1.0, 1.0);
|
||||
float ambientStrength = 0.05;
|
||||
vec3 baseColor = vec3(texture(texSampler, fragUV));
|
||||
vec3 baseColor = vec3(texture(materialSetSampler, fragUV));
|
||||
vec3 emission = vec3(0.0, 0.0, 0.0);
|
||||
|
||||
// code
|
||||
|
@ -1,17 +1,17 @@
|
||||
#version 450
|
||||
|
||||
layout(set = 0, binding = 0) uniform GlobalSetUniformBuffer {
|
||||
mat4 proj;
|
||||
} globalSetUniformBuffer;
|
||||
|
||||
layout(set = 1, binding = 0) uniform FrameSetUniformBuffer {
|
||||
mat4 view;
|
||||
} frameSetUniformBuffer;
|
||||
|
||||
layout( push_constant ) uniform Constants {
|
||||
mat4 model;
|
||||
} constants;
|
||||
|
||||
layout(set = 0, binding = 0) uniform SetZeroBuffer {
|
||||
mat4 proj;
|
||||
} setZeroBuffer;
|
||||
|
||||
layout(set = 1, binding = 0) uniform SetOneBuffer {
|
||||
mat4 view;
|
||||
} setOneBuffer;
|
||||
|
||||
layout(location = 0) in vec3 inPosition;
|
||||
layout(location = 1) in vec3 inNorm;
|
||||
layout(location = 2) in vec2 inUV;
|
||||
@ -22,12 +22,12 @@ layout(location = 2) out vec2 fragUV;
|
||||
layout(location = 3) out vec3 fragLightPos;
|
||||
|
||||
void main() {
|
||||
gl_Position = setZeroBuffer.proj * setOneBuffer.view * constants.model * vec4(inPosition, 1.0);
|
||||
gl_Position = globalSetUniformBuffer.proj * frameSetUniformBuffer.view * constants.model * vec4(inPosition, 1.0);
|
||||
|
||||
fragPos = vec3(setOneBuffer.view * constants.model * vec4(inPosition, 1.0));
|
||||
fragNorm = mat3(transpose(inverse(setOneBuffer.view * constants.model))) * inNorm;
|
||||
fragPos = vec3(frameSetUniformBuffer.view * constants.model * vec4(inPosition, 1.0));
|
||||
fragNorm = mat3(transpose(inverse(frameSetUniformBuffer.view * constants.model))) * inNorm;
|
||||
fragUV = inUV;
|
||||
|
||||
vec3 lightPos = vec3(2000.0, 2000.0, -2000.0);
|
||||
fragLightPos = vec3(setOneBuffer.view * vec4(lightPos, 1.0));
|
||||
fragLightPos = vec3(frameSetUniformBuffer.view * vec4(lightPos, 1.0));
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "resources/shader.hpp"
|
||||
#include "resources/texture.hpp"
|
||||
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/mat4x4.hpp>
|
||||
|
||||
// To allow the FPS-limiter to put the thread to sleep
|
||||
#include <thread>
|
||||
@ -76,49 +76,42 @@ namespace engine {
|
||||
// initialise the render data
|
||||
renderData.gfxdev = std::make_unique<GFXDevice>(appName, appVersion, m_window->getHandle(), graphicsSettings);
|
||||
|
||||
std::vector<gfx::DescriptorSetLayoutBinding> setZeroLayoutBindings;
|
||||
std::vector<gfx::DescriptorSetLayoutBinding> globalSetBindings;
|
||||
{
|
||||
auto& binding0 = setZeroLayoutBindings.emplace_back();
|
||||
auto& binding0 = globalSetBindings.emplace_back();
|
||||
binding0.descriptorType = gfx::DescriptorType::UNIFORM_BUFFER;
|
||||
binding0.stageFlags = gfx::ShaderStageFlags::VERTEX;
|
||||
auto& binding1 = setZeroLayoutBindings.emplace_back();
|
||||
binding1.descriptorType = gfx::DescriptorType::COMBINED_IMAGE_SAMPLER;
|
||||
binding1.stageFlags = gfx::ShaderStageFlags::FRAGMENT;
|
||||
}
|
||||
renderData.setZeroLayout = gfx()->createDescriptorSetLayout(setZeroLayoutBindings);
|
||||
renderData.setZero = gfx()->allocateDescriptorSet(renderData.setZeroLayout);
|
||||
RenderData::SetZeroBuffer initialSetZeroData{
|
||||
.proj = glm::perspectiveZO(glm::radians(70.0f), 1024.0f / 768.0f, 0.1f, 1000.0f),
|
||||
renderData.globalSetLayout = gfx()->createDescriptorSetLayout(globalSetBindings);
|
||||
renderData.globalSet = gfx()->allocateDescriptorSet(renderData.globalSetLayout);
|
||||
RenderData::GlobalSetUniformBuffer globalSetUniformBufferData{
|
||||
.proj = glm::mat4{ 1.0f },
|
||||
};
|
||||
renderData.setZeroBuffer = gfx()->createUniformBuffer(sizeof(RenderData::SetZeroBuffer), &initialSetZeroData);
|
||||
gfx()->updateDescriptorUniformBuffer(renderData.setZero, 0, renderData.setZeroBuffer, 0, sizeof(RenderData::SetZeroBuffer));
|
||||
renderData.globalSetUniformBuffer = gfx()->createUniformBuffer(sizeof(RenderData::GlobalSetUniformBuffer), &globalSetUniformBufferData);
|
||||
gfx()->updateDescriptorUniformBuffer(renderData.globalSet, 0, renderData.globalSetUniformBuffer, 0, sizeof(RenderData::GlobalSetUniformBuffer));
|
||||
|
||||
uint8_t* imageData = new uint8_t[16*16*4];
|
||||
for (int i = 0; i < 16*16*4; i += 4) {
|
||||
imageData[i + 0] = ((i / 4u) % 16u) * 16u;
|
||||
imageData[i + 1] = (i / 4u) & 0xF0u;
|
||||
imageData[i + 2] = 0x00;
|
||||
imageData[i + 3] = 0xFF;
|
||||
}
|
||||
renderData.myImage = gfx()->createImage(16, 16, imageData);
|
||||
delete[] imageData;
|
||||
|
||||
renderData.mySampler = gfx()->createSampler();
|
||||
gfx()->updateDescriptorCombinedImageSampler(renderData.setZero, 1, renderData.myImage, renderData.mySampler);
|
||||
|
||||
std::vector<gfx::DescriptorSetLayoutBinding> setOneLayoutBindings;
|
||||
std::vector<gfx::DescriptorSetLayoutBinding> frameSetBindings;
|
||||
{
|
||||
auto& binding0 = setOneLayoutBindings.emplace_back();
|
||||
auto& binding0 = frameSetBindings.emplace_back();
|
||||
binding0.descriptorType = gfx::DescriptorType::UNIFORM_BUFFER;
|
||||
binding0.stageFlags = gfx::ShaderStageFlags::VERTEX;
|
||||
}
|
||||
renderData.setOneLayout = gfx()->createDescriptorSetLayout(setOneLayoutBindings);
|
||||
renderData.setOne = gfx()->allocateDescriptorSet(renderData.setOneLayout);
|
||||
RenderData::SetOneBuffer initialSetOneData{
|
||||
renderData.frameSetLayout = gfx()->createDescriptorSetLayout(frameSetBindings);
|
||||
renderData.frameSet = gfx()->allocateDescriptorSet(renderData.frameSetLayout);
|
||||
RenderData::FrameSetUniformBuffer initialSetOneData{
|
||||
.view = glm::mat4{ 1.0f },
|
||||
};
|
||||
renderData.setOneBuffer = gfx()->createUniformBuffer(sizeof(RenderData::SetOneBuffer), &initialSetOneData);
|
||||
gfx()->updateDescriptorUniformBuffer(renderData.setOne, 0, renderData.setOneBuffer, 0, sizeof(RenderData::SetOneBuffer));
|
||||
renderData.frameSetUniformBuffer = gfx()->createUniformBuffer(sizeof(RenderData::FrameSetUniformBuffer), &initialSetOneData);
|
||||
gfx()->updateDescriptorUniformBuffer(renderData.frameSet, 0, renderData.frameSetUniformBuffer, 0, sizeof(RenderData::FrameSetUniformBuffer));
|
||||
|
||||
std::vector<gfx::DescriptorSetLayoutBinding> materialSetBindings;
|
||||
{
|
||||
auto& binding0 = materialSetBindings.emplace_back();
|
||||
binding0.descriptorType = gfx::DescriptorType::COMBINED_IMAGE_SAMPLER;
|
||||
binding0.stageFlags = gfx::ShaderStageFlags::FRAGMENT;
|
||||
}
|
||||
renderData.materialSetLayout = gfx()->createDescriptorSetLayout(materialSetBindings);
|
||||
renderData.materialSetSampler = gfx()->createSampler();
|
||||
|
||||
// default resources
|
||||
{
|
||||
@ -135,11 +128,11 @@ namespace engine {
|
||||
);
|
||||
getResourceManager<resources::Shader>()->addPersistent("builtin.standard", std::move(texturedShader));
|
||||
}
|
||||
if (0) {
|
||||
{
|
||||
resources::Shader::VertexParams vertParams{};
|
||||
vertParams.hasNormal = true;
|
||||
vertParams.hasUV0 = true;
|
||||
auto texturedShader = std::make_unique<resources::Shader>(
|
||||
auto skyboxShader = std::make_unique<resources::Shader>(
|
||||
&renderData,
|
||||
getResourcePath("engine/shaders/skybox.vert").c_str(),
|
||||
getResourcePath("engine/shaders/skybox.frag").c_str(),
|
||||
@ -147,11 +140,13 @@ namespace engine {
|
||||
false,
|
||||
true
|
||||
);
|
||||
getResourceManager<resources::Shader>()->addPersistent("builtin.skybox", std::move(texturedShader));
|
||||
getResourceManager<resources::Shader>()->addPersistent("builtin.skybox", std::move(skyboxShader));
|
||||
}
|
||||
{
|
||||
auto whiteTexture = std::make_unique<resources::Texture>(
|
||||
gfx(),
|
||||
renderData.materialSetLayout,
|
||||
renderData.materialSetSampler,
|
||||
getResourcePath("engine/textures/white.png"),
|
||||
resources::Texture::Filtering::OFF,
|
||||
false,
|
||||
@ -163,13 +158,14 @@ namespace engine {
|
||||
|
||||
Application::~Application()
|
||||
{
|
||||
gfx()->destroyUniformBuffer(renderData.setOneBuffer);
|
||||
gfx()->destroyDescriptorSetLayout(renderData.setOneLayout);
|
||||
gfx()->destroySampler(renderData.materialSetSampler);
|
||||
gfx()->destroyDescriptorSetLayout(renderData.materialSetLayout);
|
||||
|
||||
gfx()->destroySampler(renderData.mySampler);
|
||||
gfx()->destroyImage(renderData.myImage);
|
||||
gfx()->destroyUniformBuffer(renderData.setZeroBuffer);
|
||||
gfx()->destroyDescriptorSetLayout(renderData.setZeroLayout);
|
||||
gfx()->destroyUniformBuffer(renderData.frameSetUniformBuffer);
|
||||
gfx()->destroyDescriptorSetLayout(renderData.frameSetLayout);
|
||||
|
||||
gfx()->destroyUniformBuffer(renderData.globalSetUniformBuffer);
|
||||
gfx()->destroyDescriptorSetLayout(renderData.globalSetLayout);
|
||||
}
|
||||
|
||||
void Application::gameLoop()
|
||||
|
@ -104,10 +104,6 @@ namespace engine {
|
||||
VkSampler sampler = VK_NULL_HANDLE;
|
||||
};
|
||||
|
||||
struct gfx::Texture {
|
||||
|
||||
};
|
||||
|
||||
struct gfx::DrawBuffer {
|
||||
FrameData frameData{};
|
||||
uint32_t currentFrameIndex = 0; // corresponds to the frameData
|
||||
@ -322,7 +318,10 @@ namespace engine {
|
||||
VkDescriptorPool descriptorPool;
|
||||
std::array<std::unordered_set<gfx::UniformBuffer*>, FRAMES_IN_FLIGHT> uniformBufferWriteQueues{};
|
||||
|
||||
// For one-off transfer operations not bound to a specific frame-in-flight
|
||||
VkCommandPool transferCommandPool = VK_NULL_HANDLE;
|
||||
// For one-off operation on the draw queue family not bound to a specific frame-in-flight
|
||||
VkCommandPool graphicsCommandPool = VK_NULL_HANDLE;
|
||||
|
||||
uint64_t FRAMECOUNT = 0;
|
||||
|
||||
@ -483,16 +482,25 @@ namespace engine {
|
||||
.queueFamilyIndex = pimpl->device.queues.transferQueueFamily
|
||||
};
|
||||
VKCHECK(vkCreateCommandPool(pimpl->device.device, &transferPoolInfo, nullptr, &pimpl->transferCommandPool));
|
||||
/* create command pool for one-off draw queue operations */
|
||||
VkCommandPoolCreateInfo graphicsPoolInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // These command buffers don't last very long
|
||||
.queueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily
|
||||
};
|
||||
VKCHECK(vkCreateCommandPool(pimpl->device.device, &graphicsPoolInfo, nullptr, &pimpl->graphicsCommandPool));
|
||||
|
||||
/* create a global descriptor pool */
|
||||
std::vector<VkDescriptorPoolSize> poolSizes{};
|
||||
poolSizes.push_back({ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 100u }); // purposely low limit
|
||||
poolSizes.push_back({ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 100u });
|
||||
poolSizes.push_back({ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 100u });
|
||||
|
||||
VkDescriptorPoolCreateInfo descriptorPoolInfo{};
|
||||
descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||
descriptorPoolInfo.pNext = nullptr;
|
||||
descriptorPoolInfo.flags = 0;
|
||||
descriptorPoolInfo.maxSets = 100; // purposely low limit
|
||||
descriptorPoolInfo.maxSets = 1000u;
|
||||
descriptorPoolInfo.poolSizeCount = (uint32_t)poolSizes.size();
|
||||
descriptorPoolInfo.pPoolSizes = poolSizes.data();
|
||||
VKCHECK(vkCreateDescriptorPool(pimpl->device.device, &descriptorPoolInfo, nullptr, &pimpl->descriptorPool));
|
||||
@ -503,6 +511,7 @@ namespace engine {
|
||||
{
|
||||
vkDestroyDescriptorPool(pimpl->device.device, pimpl->descriptorPool, nullptr);
|
||||
|
||||
vkDestroyCommandPool(pimpl->device.device, pimpl->graphicsCommandPool, nullptr);
|
||||
vkDestroyCommandPool(pimpl->device.device, pimpl->transferCommandPool, nullptr);
|
||||
|
||||
for (uint32_t i = 0; i < FRAMES_IN_FLIGHT; i++) {
|
||||
@ -535,8 +544,6 @@ namespace engine {
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: the descriptor buffer copy command buffers are never freed.
|
||||
* This causes the program to crash on IGPU after around 1 minute. (VK_ERROR_DEVICE_LOST on a vkQueueSubmit) */
|
||||
gfx::DrawBuffer* GFXDevice::beginRender()
|
||||
{
|
||||
VkResult res;
|
||||
@ -951,7 +958,7 @@ namespace engine {
|
||||
depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
||||
depthStencil.depthTestEnable = VK_TRUE;
|
||||
depthStencil.depthWriteEnable = VK_TRUE;
|
||||
depthStencil.depthCompareOp = VK_COMPARE_OP_LESS;
|
||||
depthStencil.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
|
||||
depthStencil.depthBoundsTestEnable = VK_FALSE;
|
||||
depthStencil.minDepthBounds = 0.0f;
|
||||
depthStencil.maxDepthBounds = 1.0f;
|
||||
@ -1315,7 +1322,7 @@ namespace engine {
|
||||
imageInfo.arrayLayers = 1;
|
||||
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
imageInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
imageInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
||||
@ -1343,7 +1350,7 @@ namespace engine {
|
||||
VkCommandBufferAllocateInfo allocInfo{};
|
||||
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||
allocInfo.commandPool = pimpl->transferCommandPool;
|
||||
allocInfo.commandPool = pimpl->graphicsCommandPool;
|
||||
allocInfo.commandBufferCount = 1;
|
||||
|
||||
VkCommandBuffer commandBuffer;
|
||||
@ -1363,8 +1370,8 @@ namespace engine {
|
||||
barrier.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT;
|
||||
barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
barrier.srcQueueFamilyIndex = pimpl->device.queues.transferQueueFamily;
|
||||
barrier.dstQueueFamilyIndex = pimpl->device.queues.transferQueueFamily;
|
||||
barrier.srcQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily;
|
||||
barrier.dstQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily;
|
||||
barrier.image = out->image;
|
||||
barrier.subresourceRange = viewInfo.subresourceRange;
|
||||
|
||||
@ -1397,7 +1404,7 @@ namespace engine {
|
||||
barrier.dstAccessMask = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT;
|
||||
barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
barrier.srcQueueFamilyIndex = pimpl->device.queues.transferQueueFamily;
|
||||
barrier.srcQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily;
|
||||
barrier.dstQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily;
|
||||
|
||||
vkCmdPipelineBarrier2(commandBuffer, &depInfo);
|
||||
@ -1411,11 +1418,11 @@ namespace engine {
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &commandBuffer;
|
||||
|
||||
VKCHECK(vkQueueSubmit(pimpl->device.queues.transferQueues[0], 1, &submitInfo, VK_NULL_HANDLE));
|
||||
VKCHECK(vkQueueSubmit(pimpl->device.queues.drawQueues[0], 1, &submitInfo, VK_NULL_HANDLE));
|
||||
|
||||
VKCHECK(vkQueueWaitIdle(pimpl->device.queues.transferQueues[0]));
|
||||
VKCHECK(vkQueueWaitIdle(pimpl->device.queues.drawQueues[0]));
|
||||
|
||||
vkFreeCommandBuffers(pimpl->device.device, pimpl->transferCommandPool, 1, &commandBuffer);
|
||||
vkFreeCommandBuffers(pimpl->device.device, pimpl->graphicsCommandPool, 1, &commandBuffer);
|
||||
|
||||
vmaDestroyBuffer(pimpl->allocator, stagingBuffer, stagingAllocation);
|
||||
|
||||
@ -1436,15 +1443,15 @@ namespace engine {
|
||||
VkSamplerCreateInfo samplerInfo{};
|
||||
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
samplerInfo.magFilter = VK_FILTER_NEAREST;
|
||||
samplerInfo.minFilter = VK_FILTER_NEAREST;
|
||||
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||
samplerInfo.minFilter = VK_FILTER_LINEAR;
|
||||
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.mipLodBias = 0.0f; // wtf
|
||||
samplerInfo.mipLodBias = 0.0f;
|
||||
samplerInfo.anisotropyEnable = VK_FALSE;
|
||||
samplerInfo.minLod = 0.0f;
|
||||
samplerInfo.maxLod = 0.0f;
|
||||
samplerInfo.maxLod = VK_LOD_CLAMP_NONE;
|
||||
|
||||
VKCHECK(vkCreateSampler(pimpl->device.device, &samplerInfo, nullptr, &out->sampler));
|
||||
|
||||
@ -1457,32 +1464,6 @@ namespace engine {
|
||||
delete sampler;
|
||||
}
|
||||
|
||||
gfx::Texture* GFXDevice::createTexture(
|
||||
const void* imageData,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
gfx::TextureFilter minFilter,
|
||||
gfx::TextureFilter magFilter,
|
||||
gfx::MipmapSetting mipmapSetting,
|
||||
bool useAnisotropy)
|
||||
{
|
||||
(void)imageData;
|
||||
(void)width;
|
||||
(void)height;
|
||||
(void)minFilter;
|
||||
(void)magFilter;
|
||||
(void)mipmapSetting;
|
||||
(void)useAnisotropy;
|
||||
auto out = new gfx::Texture;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void GFXDevice::destroyTexture(const gfx::Texture* texture)
|
||||
{
|
||||
(void)texture;
|
||||
}
|
||||
|
||||
void GFXDevice::logPerformanceInfo()
|
||||
{
|
||||
VmaTotalStatistics pStats{};
|
||||
@ -1517,4 +1498,4 @@ namespace engine {
|
||||
vkDeviceWaitIdle(pimpl->device.device);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -44,8 +44,9 @@ namespace engine::resources {
|
||||
info.vertexFormat = vertFormat;
|
||||
info.alphaBlending = alphaBlending;
|
||||
info.backfaceCulling = cullBackFace;
|
||||
info.descriptorSetLayouts.push_back(renderData->setZeroLayout);
|
||||
info.descriptorSetLayouts.push_back(renderData->setOneLayout);
|
||||
info.descriptorSetLayouts.push_back(renderData->globalSetLayout);
|
||||
info.descriptorSetLayouts.push_back(renderData->frameSetLayout);
|
||||
info.descriptorSetLayouts.push_back(renderData->materialSetLayout);
|
||||
|
||||
m_pipeline = m_gfx->createPipeline(info);
|
||||
|
||||
|
@ -7,12 +7,12 @@
|
||||
|
||||
namespace engine::resources {
|
||||
|
||||
Texture::Texture(GFXDevice* gfxDevice, const std::string& path, Filtering filtering, bool useMipmaps, bool useLinearMagFilter)
|
||||
Texture::Texture(GFXDevice* gfxDevice, const gfx::DescriptorSetLayout* materialSetLayout, const gfx::Sampler* sampler, const std::string& path, Filtering filtering, bool useMipmaps, bool useLinearMagFilter)
|
||||
: m_gfxDevice(gfxDevice)
|
||||
{
|
||||
|
||||
int width, height;
|
||||
auto 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::TextureFilter magFilter = gfx::TextureFilter::NEAREST;
|
||||
@ -51,11 +51,14 @@ Texture::Texture(GFXDevice* gfxDevice, const std::string& path, Filtering filter
|
||||
mipmapSetting = gfx::MipmapSetting::OFF;
|
||||
}
|
||||
|
||||
m_gpuTexture = m_gfxDevice->createTexture(
|
||||
texbuf->data(), (uint32_t)width, (uint32_t)height,
|
||||
minFilter, magFilter,
|
||||
mipmapSetting,
|
||||
anisotropyEnable);
|
||||
(void)minFilter;
|
||||
(void)magFilter;
|
||||
(void)mipmapSetting;
|
||||
(void)anisotropyEnable;
|
||||
|
||||
m_image = m_gfxDevice->createImage(width, height, texbuf->data());
|
||||
m_descriptorSet = m_gfxDevice->allocateDescriptorSet(materialSetLayout);
|
||||
m_gfxDevice->updateDescriptorCombinedImageSampler(m_descriptorSet, 0, m_image, sampler);
|
||||
|
||||
LOG_INFO("Loaded texture: {}, width: {} height: {}", path, width, height);
|
||||
|
||||
@ -63,12 +66,7 @@ Texture::Texture(GFXDevice* gfxDevice, const std::string& path, Filtering filter
|
||||
|
||||
Texture::~Texture()
|
||||
{
|
||||
m_gfxDevice->destroyTexture(m_gpuTexture);
|
||||
}
|
||||
|
||||
gfx::Texture* Texture::getHandle()
|
||||
{
|
||||
return m_gpuTexture;
|
||||
m_gfxDevice->destroyImage(m_image);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -45,16 +45,16 @@ namespace engine {
|
||||
const float verticalFovRadians = glm::radians(m_camera.verticalFovDegrees);
|
||||
const glm::mat4 projMatrix = glm::perspectiveZO(verticalFovRadians, m_viewportAspectRatio, m_camera.clipNear, m_camera.clipFar);
|
||||
/* update SET 0 */
|
||||
RenderData::SetZeroBuffer setZeroBuffer{
|
||||
RenderData::GlobalSetUniformBuffer globalSetUniformBuffer{
|
||||
.proj = projMatrix
|
||||
};
|
||||
m_gfx->writeUniformBuffer(renderData.setZeroBuffer, 0, sizeof(RenderData::SetZeroBuffer), &setZeroBuffer);
|
||||
m_gfx->writeUniformBuffer(renderData.globalSetUniformBuffer, 0, sizeof(RenderData::GlobalSetUniformBuffer), &globalSetUniformBuffer);
|
||||
}
|
||||
|
||||
RenderData::SetOneBuffer setOneBuffer{
|
||||
RenderData::FrameSetUniformBuffer frameSetUniformBuffer{
|
||||
.view = viewMatrix
|
||||
};
|
||||
m_gfx->writeUniformBuffer(renderData.setOneBuffer, 0, sizeof(RenderData::SetOneBuffer), &setOneBuffer);
|
||||
m_gfx->writeUniformBuffer(renderData.frameSetUniformBuffer, 0, sizeof(RenderData::FrameSetUniformBuffer), &frameSetUniformBuffer);
|
||||
|
||||
/* render all renderable entities */
|
||||
|
||||
@ -65,6 +65,7 @@ namespace engine {
|
||||
struct DrawCallData {
|
||||
const gfx::Buffer* vb;
|
||||
const gfx::Buffer* ib;
|
||||
const gfx::DescriptorSet* materialSet;
|
||||
uint32_t indexCount;
|
||||
PushConstants pushConsts;
|
||||
};
|
||||
@ -75,6 +76,7 @@ namespace engine {
|
||||
auto r = m_scene->getComponent<RenderableComponent>(entity);
|
||||
assert(r != nullptr);
|
||||
assert(r->material != nullptr);
|
||||
assert(r->material->m_texture != nullptr);
|
||||
assert(r->mesh != nullptr);
|
||||
if (r->shown == false) continue;
|
||||
|
||||
@ -85,6 +87,7 @@ namespace engine {
|
||||
DrawCallData data{};
|
||||
data.vb = r->mesh->getVB();
|
||||
data.ib = r->mesh->getIB();
|
||||
data.materialSet = r->material->m_texture->getDescriptorSet();
|
||||
data.indexCount = r->mesh->getCount();
|
||||
data.pushConsts.model = t->worldMatrix;
|
||||
|
||||
@ -97,12 +100,15 @@ namespace engine {
|
||||
|
||||
/* these descriptor set bindings should persist across pipeline changes */
|
||||
const gfx::Pipeline* firstPipeline = pipelineDrawCalls.begin()->first;
|
||||
m_gfx->cmdBindDescriptorSet(renderData.drawBuffer, firstPipeline, renderData.setZero, 0);
|
||||
m_gfx->cmdBindDescriptorSet(renderData.drawBuffer, firstPipeline, renderData.setOne, 1);
|
||||
m_gfx->cmdBindDescriptorSet(renderData.drawBuffer, firstPipeline, renderData.globalSet, 0);
|
||||
m_gfx->cmdBindDescriptorSet(renderData.drawBuffer, firstPipeline, renderData.frameSet, 1);
|
||||
|
||||
for (const auto& [pipeline, drawCalls] : pipelineDrawCalls) {
|
||||
m_gfx->cmdBindPipeline(renderData.drawBuffer, pipeline);
|
||||
for (const auto& drawCall : drawCalls) {
|
||||
m_gfx->cmdBindDescriptorSet(renderData.drawBuffer, pipeline, renderData.globalSet, 0);
|
||||
m_gfx->cmdBindDescriptorSet(renderData.drawBuffer, pipeline, renderData.frameSet, 1);
|
||||
m_gfx->cmdBindDescriptorSet(renderData.drawBuffer, pipeline, drawCall.materialSet, 2);
|
||||
m_gfx->cmdPushConstants(renderData.drawBuffer, pipeline, 0, sizeof(PushConstants), &drawCall.pushConsts);
|
||||
m_gfx->cmdBindVertexBuffer(renderData.drawBuffer, 0, drawCall.vb);
|
||||
m_gfx->cmdBindIndexBuffer(renderData.drawBuffer, drawCall.ib);
|
||||
|
@ -51,7 +51,6 @@ namespace engine::util {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// Read an image file into a vector byte buffer. PNG and JPG support at a minimum
|
||||
std::unique_ptr<std::vector<uint8_t>> readImageFile(const std::string& path, int *width, int *height)
|
||||
{
|
||||
int x, y, n;
|
||||
|
@ -182,7 +182,7 @@ namespace engine::util {
|
||||
absPath /= texPath.C_Str();
|
||||
try {
|
||||
textures[i] = std::make_shared<resources::Texture>(
|
||||
parent->app()->gfx(), absPath.string(),
|
||||
parent->app()->gfx(), parent->app()->renderData.materialSetLayout, parent->app()->renderData.materialSetSampler, absPath.string(),
|
||||
resources::Texture::Filtering::TRILINEAR, true, true);
|
||||
} catch (const std::runtime_error&) {
|
||||
textures[i] = parent->app()->getResource<resources::Texture>("builtin.white");
|
||||
|
@ -85,6 +85,8 @@ void playGame(GameSettings settings)
|
||||
/* shared resources */
|
||||
auto grassTexture = std::make_shared<engine::resources::Texture>(
|
||||
app.gfx(),
|
||||
app.renderData.materialSetLayout,
|
||||
app.renderData.materialSetSampler,
|
||||
app.getResourcePath("textures/grass.jpg"),
|
||||
engine::resources::Texture::Filtering::ANISOTROPIC,
|
||||
true,
|
||||
@ -92,29 +94,21 @@ void playGame(GameSettings settings)
|
||||
);
|
||||
auto spaceTexture = std::make_shared<engine::resources::Texture>(
|
||||
app.gfx(),
|
||||
app.renderData.materialSetLayout,
|
||||
app.renderData.materialSetSampler,
|
||||
app.getResourcePath("textures/space2.png"),
|
||||
engine::resources::Texture::Filtering::ANISOTROPIC,
|
||||
true,
|
||||
true
|
||||
);
|
||||
|
||||
/* skybox */
|
||||
if (0) {
|
||||
uint32_t skybox = myScene->createEntity("skybox");
|
||||
auto skyboxRenderable = myScene->addComponent<engine::RenderableComponent>(skybox);
|
||||
skyboxRenderable->material = std::make_unique<engine::resources::Material>(app.getResource<engine::resources::Shader>("builtin.skybox"));
|
||||
skyboxRenderable->material->m_texture = spaceTexture;
|
||||
// skyboxRenderable->mesh = genSphereMesh(app.gfx(), 1.0f, 50, true);
|
||||
skyboxRenderable->mesh = genCuboidMesh(app.gfx(), 10.0f, 10.0f, 10.0f, 1.0f, true);
|
||||
myScene->getComponent<engine::TransformComponent>(skybox)->position = { -5.0f, -5.0f, -5.0f };
|
||||
}
|
||||
|
||||
/* cube */
|
||||
{
|
||||
uint32_t cube = myScene->createEntity("cube");
|
||||
myScene->getComponent<engine::TransformComponent>(cube)->position = glm::vec3{ -0.5f + 5.0f, -0.5f + 5.0f, -0.5f + 5.0f };
|
||||
auto cubeRenderable = myScene->addComponent<engine::RenderableComponent>(cube);
|
||||
cubeRenderable->material = std::make_shared<engine::resources::Material>(app.getResource<engine::resources::Shader>("builtin.standard"));
|
||||
cubeRenderable->material->m_texture = app.getResource<engine::resources::Texture>("builtin.white");
|
||||
cubeRenderable->mesh = genCuboidMesh(app.gfx(), 1.0f, 1.0f, 1.0f, 1);
|
||||
auto cubeCollider = myScene->addComponent<engine::ColliderComponent>(cube);
|
||||
cubeCollider->isStatic = true;
|
||||
@ -137,6 +131,16 @@ void playGame(GameSettings settings)
|
||||
|
||||
//engine::util::loadMeshFromFile(myScene, app.getResourcePath("models/astronaut/astronaut.dae"));
|
||||
|
||||
/* skybox */
|
||||
{
|
||||
uint32_t skybox = myScene->createEntity("skybox");
|
||||
auto skyboxRenderable = myScene->addComponent<engine::RenderableComponent>(skybox);
|
||||
skyboxRenderable->material = std::make_unique<engine::resources::Material>(app.getResource<engine::resources::Shader>("builtin.skybox"));
|
||||
skyboxRenderable->material->m_texture = spaceTexture;
|
||||
skyboxRenderable->mesh = genCuboidMesh(app.gfx(), 10.0f, 10.0f, 10.0f, 1.0f, true);
|
||||
myScene->getComponent<engine::TransformComponent>(skybox)->position = { -5.0f, -5.0f, -5.0f };
|
||||
}
|
||||
|
||||
app.gameLoop();
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user