mirror of
https://github.com/redstrate/Novus.git
synced 2025-04-29 06:57:46 +00:00
Support 3D textures, add real tile diffuse/normal and fix lighting
I broke the lighting accidentally while messing around with Dawntrail, it's now restored. Real textures are used for tile diffuse/normal textures which shoud fix the appearances of some gear.
This commit is contained in:
parent
ac3b2e2f7c
commit
5a227971c2
11 changed files with 191 additions and 175 deletions
2
extern/libphysis
vendored
2
extern/libphysis
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 3a1bc2770dd8cb4ccadccb60c1ae20692aaeb00f
|
Subproject commit 47b2c3fbc2159d81e40bcfbaf07687555592f47b
|
|
@ -258,24 +258,16 @@ RenderMaterial MDLPart::createMaterial(const physis_Material &material)
|
||||||
if (texture.rgba != nullptr) {
|
if (texture.rgba != nullptr) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'm': {
|
case 'm': {
|
||||||
auto tex = renderer->addTexture(texture.width, texture.height, texture.rgba, texture.rgba_size);
|
newMaterial.multiTexture = renderer->addGameTexture(texture);
|
||||||
|
|
||||||
newMaterial.multiTexture = new RenderTexture(tex);
|
|
||||||
} break;
|
} break;
|
||||||
case 'd': {
|
case 'd': {
|
||||||
auto tex = renderer->addTexture(texture.width, texture.height, texture.rgba, texture.rgba_size);
|
newMaterial.diffuseTexture = renderer->addGameTexture(texture);
|
||||||
|
|
||||||
newMaterial.diffuseTexture = new RenderTexture(tex);
|
|
||||||
} break;
|
} break;
|
||||||
case 'n': {
|
case 'n': {
|
||||||
auto tex = renderer->addTexture(texture.width, texture.height, texture.rgba, texture.rgba_size);
|
newMaterial.normalTexture = renderer->addGameTexture(texture);
|
||||||
|
|
||||||
newMaterial.normalTexture = new RenderTexture(tex);
|
|
||||||
} break;
|
} break;
|
||||||
case 's': {
|
case 's': {
|
||||||
auto tex = renderer->addTexture(texture.width, texture.height, texture.rgba, texture.rgba_size);
|
newMaterial.specularTexture = renderer->addGameTexture(texture);
|
||||||
|
|
||||||
newMaterial.specularTexture = new RenderTexture(tex);
|
|
||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
qDebug() << "unhandled type" << type;
|
qDebug() << "unhandled type" << type;
|
||||||
|
|
|
@ -7,9 +7,11 @@
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <QtLogging>
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
|
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
#include "physis.hpp"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
|
||||||
class SwapChain;
|
class SwapChain;
|
||||||
|
@ -57,4 +59,6 @@ public:
|
||||||
|
|
||||||
VkResult nameObject(VkObjectType type, uint64_t object, std::string_view name);
|
VkResult nameObject(VkObjectType type, uint64_t object, std::string_view name);
|
||||||
void nameTexture(Texture &texture, std::string_view name);
|
void nameTexture(Texture &texture, std::string_view name);
|
||||||
|
|
||||||
|
Texture addGameTexture(physis_Texture gameTexture);
|
||||||
};
|
};
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "texture.h"
|
||||||
|
|
||||||
struct RenderPart {
|
struct RenderPart {
|
||||||
size_t numIndices;
|
size_t numIndices;
|
||||||
|
|
||||||
|
@ -11,13 +13,6 @@ struct RenderPart {
|
||||||
int materialIndex = 0;
|
int materialIndex = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RenderTexture {
|
|
||||||
VkImage handle = VK_NULL_HANDLE;
|
|
||||||
VkDeviceMemory memory = VK_NULL_HANDLE;
|
|
||||||
VkImageView view = VK_NULL_HANDLE;
|
|
||||||
VkSampler sampler = VK_NULL_HANDLE;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class MaterialType { Object, Skin };
|
enum class MaterialType { Object, Skin };
|
||||||
|
|
||||||
struct RenderMaterial {
|
struct RenderMaterial {
|
||||||
|
@ -25,10 +20,10 @@ struct RenderMaterial {
|
||||||
MaterialType type = MaterialType::Object;
|
MaterialType type = MaterialType::Object;
|
||||||
physis_SHPK shaderPackage;
|
physis_SHPK shaderPackage;
|
||||||
|
|
||||||
RenderTexture *diffuseTexture = nullptr;
|
std::optional<Texture> diffuseTexture;
|
||||||
RenderTexture *normalTexture = nullptr;
|
std::optional<Texture> normalTexture;
|
||||||
RenderTexture *specularTexture = nullptr;
|
std::optional<Texture> specularTexture;
|
||||||
RenderTexture *multiTexture = nullptr;
|
std::optional<Texture> multiTexture;
|
||||||
|
|
||||||
Buffer materialBuffer;
|
Buffer materialBuffer;
|
||||||
};
|
};
|
||||||
|
|
|
@ -107,7 +107,8 @@ private:
|
||||||
VkSampler m_sampler;
|
VkSampler m_sampler;
|
||||||
VkSampler m_normalSampler;
|
VkSampler m_normalSampler;
|
||||||
Buffer m_dummyBuffer;
|
Buffer m_dummyBuffer;
|
||||||
Texture m_placeholderTileNormal;
|
Texture m_tileNormal;
|
||||||
|
Texture m_tileDiffuse;
|
||||||
|
|
||||||
// Dawntrail changes part of the rendering system
|
// Dawntrail changes part of the rendering system
|
||||||
bool m_dawntrailMode = false;
|
bool m_dawntrailMode = false;
|
||||||
|
|
|
@ -34,7 +34,7 @@ public:
|
||||||
|
|
||||||
DrawObject addDrawObject(const physis_MDL &model, int lod);
|
DrawObject addDrawObject(const physis_MDL &model, int lod);
|
||||||
void reloadDrawObject(DrawObject &model, uint32_t lod);
|
void reloadDrawObject(DrawObject &model, uint32_t lod);
|
||||||
RenderTexture addTexture(uint32_t width, uint32_t height, const uint8_t *data, uint32_t data_size);
|
Texture addGameTexture(physis_Texture gameTexture);
|
||||||
|
|
||||||
void render(const std::vector<DrawObject> &models);
|
void render(const std::vector<DrawObject> &models);
|
||||||
|
|
||||||
|
@ -47,6 +47,8 @@ public:
|
||||||
|
|
||||||
Device &device();
|
Device &device();
|
||||||
|
|
||||||
|
VkSampler defaultSampler();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateCamera(Camera &camera);
|
void updateCamera(Camera &camera);
|
||||||
void initBlitPipeline();
|
void initBlitPipeline();
|
||||||
|
|
|
@ -339,3 +339,133 @@ void Device::nameTexture(Texture &texture, std::string_view name)
|
||||||
nameObject(VK_OBJECT_TYPE_IMAGE_VIEW, reinterpret_cast<uint64_t>(texture.imageView), name.data());
|
nameObject(VK_OBJECT_TYPE_IMAGE_VIEW, reinterpret_cast<uint64_t>(texture.imageView), name.data());
|
||||||
nameObject(VK_OBJECT_TYPE_DEVICE_MEMORY, reinterpret_cast<uint64_t>(texture.imageMemory), name.data());
|
nameObject(VK_OBJECT_TYPE_DEVICE_MEMORY, reinterpret_cast<uint64_t>(texture.imageMemory), name.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Texture Device::addGameTexture(physis_Texture gameTexture)
|
||||||
|
{
|
||||||
|
Texture newTexture = {};
|
||||||
|
|
||||||
|
VkImageCreateInfo imageInfo = {};
|
||||||
|
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||||
|
switch (gameTexture.texture_type) {
|
||||||
|
case TextureType::TwoDimensional:
|
||||||
|
imageInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||||
|
break;
|
||||||
|
case TextureType::ThreeDimensional:
|
||||||
|
imageInfo.imageType = VK_IMAGE_TYPE_3D;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
imageInfo.extent.width = gameTexture.width;
|
||||||
|
imageInfo.extent.height = gameTexture.height;
|
||||||
|
imageInfo.extent.depth = gameTexture.depth;
|
||||||
|
imageInfo.mipLevels = 1;
|
||||||
|
imageInfo.arrayLayers = 1;
|
||||||
|
imageInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||||
|
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||||
|
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
|
||||||
|
vkCreateImage(device, &imageInfo, nullptr, &newTexture.image);
|
||||||
|
|
||||||
|
VkMemoryRequirements memRequirements;
|
||||||
|
vkGetImageMemoryRequirements(device, newTexture.image, &memRequirements);
|
||||||
|
|
||||||
|
VkMemoryAllocateInfo allocInfo = {};
|
||||||
|
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||||
|
allocInfo.allocationSize = memRequirements.size;
|
||||||
|
allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||||
|
|
||||||
|
vkAllocateMemory(device, &allocInfo, nullptr, &newTexture.imageMemory);
|
||||||
|
|
||||||
|
vkBindImageMemory(device, newTexture.image, newTexture.imageMemory, 0);
|
||||||
|
|
||||||
|
// copy image data
|
||||||
|
VkBuffer stagingBuffer;
|
||||||
|
VkDeviceMemory stagingBufferMemory;
|
||||||
|
|
||||||
|
VkBufferCreateInfo bufferInfo = {};
|
||||||
|
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||||
|
bufferInfo.size = gameTexture.rgba_size;
|
||||||
|
bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||||
|
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
|
||||||
|
vkCreateBuffer(device, &bufferInfo, nullptr, &stagingBuffer);
|
||||||
|
|
||||||
|
// allocate staging memory
|
||||||
|
vkGetBufferMemoryRequirements(device, stagingBuffer, &memRequirements);
|
||||||
|
|
||||||
|
allocInfo = {};
|
||||||
|
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||||
|
allocInfo.allocationSize = memRequirements.size;
|
||||||
|
allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||||
|
|
||||||
|
vkAllocateMemory(device, &allocInfo, nullptr, &stagingBufferMemory);
|
||||||
|
|
||||||
|
vkBindBufferMemory(device, stagingBuffer, stagingBufferMemory, 0);
|
||||||
|
|
||||||
|
// copy to staging buffer
|
||||||
|
void *mapped_data;
|
||||||
|
vkMapMemory(device, stagingBufferMemory, 0, gameTexture.rgba_size, 0, &mapped_data);
|
||||||
|
memcpy(mapped_data, gameTexture.rgba, gameTexture.rgba_size);
|
||||||
|
vkUnmapMemory(device, stagingBufferMemory);
|
||||||
|
|
||||||
|
// copy staging buffer to image
|
||||||
|
VkCommandBuffer commandBuffer = beginSingleTimeCommands();
|
||||||
|
|
||||||
|
VkImageSubresourceRange range = {};
|
||||||
|
range.baseMipLevel = 0;
|
||||||
|
range.levelCount = 1;
|
||||||
|
range.baseArrayLayer = 0;
|
||||||
|
range.layerCount = 1;
|
||||||
|
|
||||||
|
inlineTransitionImageLayout(commandBuffer,
|
||||||
|
newTexture.image,
|
||||||
|
imageInfo.format,
|
||||||
|
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
range,
|
||||||
|
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
|
|
||||||
|
VkBufferImageCopy region = {};
|
||||||
|
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
region.imageSubresource.mipLevel = 0;
|
||||||
|
region.imageSubresource.baseArrayLayer = 0;
|
||||||
|
region.imageSubresource.layerCount = 1;
|
||||||
|
region.imageExtent = {(uint32_t)gameTexture.width, (uint32_t)gameTexture.height, (uint32_t)gameTexture.depth};
|
||||||
|
|
||||||
|
vkCmdCopyBufferToImage(commandBuffer, stagingBuffer, newTexture.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||||
|
|
||||||
|
inlineTransitionImageLayout(commandBuffer,
|
||||||
|
newTexture.image,
|
||||||
|
imageInfo.format,
|
||||||
|
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
range,
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
|
|
||||||
|
endSingleTimeCommands(commandBuffer);
|
||||||
|
|
||||||
|
range = {};
|
||||||
|
range.levelCount = 1;
|
||||||
|
range.layerCount = 1;
|
||||||
|
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
|
||||||
|
VkImageViewCreateInfo viewInfo = {};
|
||||||
|
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
|
viewInfo.image = newTexture.image;
|
||||||
|
switch (gameTexture.texture_type) {
|
||||||
|
case TextureType::TwoDimensional:
|
||||||
|
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
|
break;
|
||||||
|
case TextureType::ThreeDimensional:
|
||||||
|
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_3D;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
viewInfo.format = imageInfo.format;
|
||||||
|
viewInfo.subresourceRange = range;
|
||||||
|
|
||||||
|
vkCreateImageView(device, &viewInfo, nullptr, &newTexture.imageView);
|
||||||
|
|
||||||
|
return newTexture;
|
||||||
|
}
|
|
@ -63,8 +63,8 @@ GameRenderer::GameRenderer(Device &device, GameData *data)
|
||||||
m_dummyTex = m_device.createDummyTexture();
|
m_dummyTex = m_device.createDummyTexture();
|
||||||
m_dummyBuffer = m_device.createDummyBuffer();
|
m_dummyBuffer = m_device.createDummyBuffer();
|
||||||
|
|
||||||
// don't know how to get tile normal yet
|
m_tileNormal = m_device.addGameTexture(physis_texture_parse(physis_gamedata_extract_file(m_data, "chara/common/texture/-tile_n.tex")));
|
||||||
m_placeholderTileNormal = m_device.createDummyTexture({128, 128, 255, 255});
|
m_tileDiffuse = m_device.addGameTexture(physis_texture_parse(physis_gamedata_extract_file(m_data, "chara/common/texture/-tile_d.tex")));
|
||||||
|
|
||||||
size_t vertexSize = planeVertices.size() * sizeof(glm::vec4);
|
size_t vertexSize = planeVertices.size() * sizeof(glm::vec4);
|
||||||
m_planeVertexBuffer = m_device.createBuffer(vertexSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
|
m_planeVertexBuffer = m_device.createBuffer(vertexSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
|
||||||
|
@ -178,7 +178,7 @@ GameRenderer::GameRenderer(Device &device, GameData *data)
|
||||||
|
|
||||||
AmbientParameters ambientParameters{};
|
AmbientParameters ambientParameters{};
|
||||||
for (int i = 0; i < 6; i++) {
|
for (int i = 0; i < 6; i++) {
|
||||||
ambientParameters.g_AmbientParam[i] = glm::vec4(1.0f);
|
ambientParameters.g_AmbientParam[i] = glm::vec4(0.1f);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
ambientParameters.g_AdditionalAmbientParam[i] = glm::vec4(1.0f);
|
ambientParameters.g_AdditionalAmbientParam[i] = glm::vec4(1.0f);
|
||||||
|
@ -1204,7 +1204,7 @@ GameRenderer::createDescriptorFor(const DrawObject *object, const CachedPipeline
|
||||||
auto info = &imageInfo.emplace_back();
|
auto info = &imageInfo.emplace_back();
|
||||||
descriptorWrite.pImageInfo = info;
|
descriptorWrite.pImageInfo = info;
|
||||||
|
|
||||||
if (binding.stageFlags == VK_SHADER_STAGE_FRAGMENT_BIT && p + 1 < pipeline.pixelShader.num_resource_parameters) {
|
if (binding.stageFlags == VK_SHADER_STAGE_FRAGMENT_BIT && p < pipeline.pixelShader.num_resource_parameters) {
|
||||||
auto name = pipeline.pixelShader.resource_parameters[p].name;
|
auto name = pipeline.pixelShader.resource_parameters[p].name;
|
||||||
qInfo() << "Requesting image" << name << "at" << j;
|
qInfo() << "Requesting image" << name << "at" << j;
|
||||||
if (strcmp(name, "g_SamplerGBuffer") == 0) {
|
if (strcmp(name, "g_SamplerGBuffer") == 0) {
|
||||||
|
@ -1215,7 +1215,7 @@ GameRenderer::createDescriptorFor(const DrawObject *object, const CachedPipeline
|
||||||
info->imageView = m_depthBuffer.imageView;
|
info->imageView = m_depthBuffer.imageView;
|
||||||
} else if (strcmp(name, "g_SamplerNormal") == 0) {
|
} else if (strcmp(name, "g_SamplerNormal") == 0) {
|
||||||
Q_ASSERT(material);
|
Q_ASSERT(material);
|
||||||
info->imageView = material->normalTexture->view;
|
info->imageView = material->normalTexture->imageView;
|
||||||
} else if (strcmp(name, "g_SamplerLightDiffuse") == 0) {
|
} else if (strcmp(name, "g_SamplerLightDiffuse") == 0) {
|
||||||
Q_ASSERT(material);
|
Q_ASSERT(material);
|
||||||
info->imageView = m_lightBuffer.imageView;
|
info->imageView = m_lightBuffer.imageView;
|
||||||
|
@ -1224,12 +1224,14 @@ GameRenderer::createDescriptorFor(const DrawObject *object, const CachedPipeline
|
||||||
info->imageView = m_lightSpecularBuffer.imageView;
|
info->imageView = m_lightSpecularBuffer.imageView;
|
||||||
} else if (strcmp(name, "g_SamplerDiffuse") == 0) {
|
} else if (strcmp(name, "g_SamplerDiffuse") == 0) {
|
||||||
Q_ASSERT(material);
|
Q_ASSERT(material);
|
||||||
info->imageView = material->diffuseTexture->view;
|
info->imageView = material->diffuseTexture->imageView;
|
||||||
} else if (strcmp(name, "g_SamplerSpecular") == 0) {
|
} else if (strcmp(name, "g_SamplerSpecular") == 0) {
|
||||||
Q_ASSERT(material);
|
Q_ASSERT(material);
|
||||||
info->imageView = material->specularTexture->view;
|
info->imageView = material->specularTexture->imageView;
|
||||||
} else if (strcmp(name, "g_SamplerTileNormal") == 0) {
|
} else if (strcmp(name, "g_SamplerTileNormal") == 0) {
|
||||||
info->imageView = m_placeholderTileNormal.imageView;
|
info->imageView = m_tileNormal.imageView;
|
||||||
|
} else if (strcmp(name, "g_SamplerTileDiffuse") == 0) {
|
||||||
|
info->imageView = m_tileDiffuse.imageView;
|
||||||
} else {
|
} else {
|
||||||
info->imageView = m_dummyTex.imageView;
|
info->imageView = m_dummyTex.imageView;
|
||||||
qInfo() << "Unknown image" << name;
|
qInfo() << "Unknown image" << name;
|
||||||
|
|
|
@ -302,9 +302,18 @@ void ImGuiPass::createFontImage()
|
||||||
int width = 0, height = 0;
|
int width = 0, height = 0;
|
||||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||||||
|
|
||||||
auto texture = renderer_.addTexture(width, height, pixels, width * height * 4);
|
// TODO: haha, no
|
||||||
fontImageView_ = texture.view;
|
physis_Texture texture;
|
||||||
fontSampler_ = texture.sampler;
|
texture.texture_type = TextureType::TwoDimensional;
|
||||||
|
texture.width = width;
|
||||||
|
texture.height = height;
|
||||||
|
texture.depth = 1;
|
||||||
|
texture.rgba = pixels;
|
||||||
|
texture.rgba_size = width * height * 4;
|
||||||
|
|
||||||
|
auto tex = renderer_.addGameTexture(texture);
|
||||||
|
fontImageView_ = tex.imageView;
|
||||||
|
fontSampler_ = renderer_.defaultSampler();
|
||||||
|
|
||||||
io.Fonts->SetTexID(static_cast<ImTextureID>(fontImageView_));
|
io.Fonts->SetTexID(static_cast<ImTextureID>(fontImageView_));
|
||||||
}
|
}
|
||||||
|
|
|
@ -520,133 +520,9 @@ void RenderManager::reloadDrawObject(DrawObject &DrawObject, uint32_t lod)
|
||||||
DrawObject.boneInfoBuffer = m_device->createBuffer(bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
|
DrawObject.boneInfoBuffer = m_device->createBuffer(bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderTexture RenderManager::addTexture(const uint32_t width, const uint32_t height, const uint8_t *data, const uint32_t data_size)
|
Texture RenderManager::addGameTexture(physis_Texture gameTexture)
|
||||||
{
|
{
|
||||||
RenderTexture newTexture = {};
|
return m_device->addGameTexture(gameTexture);
|
||||||
|
|
||||||
VkImageCreateInfo imageInfo = {};
|
|
||||||
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
|
||||||
imageInfo.imageType = VK_IMAGE_TYPE_2D;
|
|
||||||
imageInfo.extent.width = width;
|
|
||||||
imageInfo.extent.height = height;
|
|
||||||
imageInfo.extent.depth = 1;
|
|
||||||
imageInfo.mipLevels = 1;
|
|
||||||
imageInfo.arrayLayers = 1;
|
|
||||||
imageInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
|
|
||||||
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
|
||||||
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
|
||||||
imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
|
||||||
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
|
||||||
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
|
||||||
|
|
||||||
vkCreateImage(m_device->device, &imageInfo, nullptr, &newTexture.handle);
|
|
||||||
|
|
||||||
VkMemoryRequirements memRequirements;
|
|
||||||
vkGetImageMemoryRequirements(m_device->device, newTexture.handle, &memRequirements);
|
|
||||||
|
|
||||||
VkMemoryAllocateInfo allocInfo = {};
|
|
||||||
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
|
||||||
allocInfo.allocationSize = memRequirements.size;
|
|
||||||
allocInfo.memoryTypeIndex = m_device->findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
|
||||||
|
|
||||||
vkAllocateMemory(m_device->device, &allocInfo, nullptr, &newTexture.memory);
|
|
||||||
|
|
||||||
vkBindImageMemory(m_device->device, newTexture.handle, newTexture.memory, 0);
|
|
||||||
|
|
||||||
// copy image data
|
|
||||||
VkBuffer stagingBuffer;
|
|
||||||
VkDeviceMemory stagingBufferMemory;
|
|
||||||
|
|
||||||
VkBufferCreateInfo bufferInfo = {};
|
|
||||||
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
|
||||||
bufferInfo.size = data_size;
|
|
||||||
bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
|
||||||
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
|
||||||
|
|
||||||
vkCreateBuffer(m_device->device, &bufferInfo, nullptr, &stagingBuffer);
|
|
||||||
|
|
||||||
// allocate staging memory
|
|
||||||
vkGetBufferMemoryRequirements(m_device->device, stagingBuffer, &memRequirements);
|
|
||||||
|
|
||||||
allocInfo = {};
|
|
||||||
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
|
||||||
allocInfo.allocationSize = memRequirements.size;
|
|
||||||
allocInfo.memoryTypeIndex =
|
|
||||||
m_device->findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
|
||||||
|
|
||||||
vkAllocateMemory(m_device->device, &allocInfo, nullptr, &stagingBufferMemory);
|
|
||||||
|
|
||||||
vkBindBufferMemory(m_device->device, stagingBuffer, stagingBufferMemory, 0);
|
|
||||||
|
|
||||||
// copy to staging buffer
|
|
||||||
void *mapped_data;
|
|
||||||
vkMapMemory(m_device->device, stagingBufferMemory, 0, data_size, 0, &mapped_data);
|
|
||||||
memcpy(mapped_data, data, data_size);
|
|
||||||
vkUnmapMemory(m_device->device, stagingBufferMemory);
|
|
||||||
|
|
||||||
// copy staging buffer to image
|
|
||||||
VkCommandBuffer commandBuffer = m_device->beginSingleTimeCommands();
|
|
||||||
|
|
||||||
VkImageSubresourceRange range = {};
|
|
||||||
range.baseMipLevel = 0;
|
|
||||||
range.levelCount = 1;
|
|
||||||
range.baseArrayLayer = 0;
|
|
||||||
range.layerCount = 1;
|
|
||||||
|
|
||||||
m_device->inlineTransitionImageLayout(commandBuffer,
|
|
||||||
newTexture.handle,
|
|
||||||
imageInfo.format,
|
|
||||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
|
||||||
range,
|
|
||||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
|
||||||
|
|
||||||
VkBufferImageCopy region = {};
|
|
||||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
||||||
region.imageSubresource.mipLevel = 0;
|
|
||||||
region.imageSubresource.baseArrayLayer = 0;
|
|
||||||
region.imageSubresource.layerCount = 1;
|
|
||||||
region.imageExtent = {(uint32_t)width, (uint32_t)height, 1};
|
|
||||||
|
|
||||||
vkCmdCopyBufferToImage(commandBuffer, stagingBuffer, newTexture.handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
|
||||||
|
|
||||||
m_device->inlineTransitionImageLayout(commandBuffer,
|
|
||||||
newTexture.handle,
|
|
||||||
imageInfo.format,
|
|
||||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
|
||||||
range,
|
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
||||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
|
||||||
|
|
||||||
m_device->endSingleTimeCommands(commandBuffer);
|
|
||||||
|
|
||||||
range = {};
|
|
||||||
range.levelCount = 1;
|
|
||||||
range.layerCount = 1;
|
|
||||||
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
||||||
|
|
||||||
VkImageViewCreateInfo viewInfo = {};
|
|
||||||
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
|
||||||
viewInfo.image = newTexture.handle;
|
|
||||||
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
|
||||||
viewInfo.format = imageInfo.format;
|
|
||||||
viewInfo.subresourceRange = range;
|
|
||||||
|
|
||||||
vkCreateImageView(m_device->device, &viewInfo, nullptr, &newTexture.view);
|
|
||||||
|
|
||||||
VkSamplerCreateInfo samplerInfo = {};
|
|
||||||
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
|
||||||
samplerInfo.magFilter = VK_FILTER_LINEAR;
|
|
||||||
samplerInfo.minFilter = VK_FILTER_LINEAR;
|
|
||||||
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
|
||||||
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
|
||||||
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
|
||||||
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
|
||||||
samplerInfo.maxLod = 1.0f;
|
|
||||||
|
|
||||||
vkCreateSampler(m_device->device, &samplerInfo, nullptr, &newTexture.sampler);
|
|
||||||
|
|
||||||
return newTexture;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Device &RenderManager::device()
|
Device &RenderManager::device()
|
||||||
|
@ -654,6 +530,11 @@ Device &RenderManager::device()
|
||||||
return *m_device;
|
return *m_device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkSampler RenderManager::defaultSampler()
|
||||||
|
{
|
||||||
|
return m_sampler;
|
||||||
|
}
|
||||||
|
|
||||||
void RenderManager::updateCamera(Camera &camera)
|
void RenderManager::updateCamera(Camera &camera)
|
||||||
{
|
{
|
||||||
camera.aspectRatio = static_cast<float>(m_device->swapChain->extent.width) / static_cast<float>(m_device->swapChain->extent.height);
|
camera.aspectRatio = static_cast<float>(m_device->swapChain->extent.width) / static_cast<float>(m_device->swapChain->extent.height);
|
||||||
|
|
|
@ -439,13 +439,13 @@ uint64_t SimpleRenderer::hash(const DrawObject &model, const RenderMaterial &mat
|
||||||
uint64_t hash = 0;
|
uint64_t hash = 0;
|
||||||
hash += reinterpret_cast<intptr_t>((void *)&model);
|
hash += reinterpret_cast<intptr_t>((void *)&model);
|
||||||
if (material.diffuseTexture)
|
if (material.diffuseTexture)
|
||||||
hash += reinterpret_cast<intptr_t>((void *)material.diffuseTexture);
|
hash += reinterpret_cast<intptr_t>((void *)&material.diffuseTexture);
|
||||||
if (material.normalTexture)
|
if (material.normalTexture)
|
||||||
hash += reinterpret_cast<intptr_t>((void *)material.normalTexture);
|
hash += reinterpret_cast<intptr_t>((void *)&material.normalTexture);
|
||||||
if (material.specularTexture)
|
if (material.specularTexture)
|
||||||
hash += reinterpret_cast<intptr_t>((void *)material.specularTexture);
|
hash += reinterpret_cast<intptr_t>((void *)&material.specularTexture);
|
||||||
if (material.multiTexture)
|
if (material.multiTexture)
|
||||||
hash += reinterpret_cast<intptr_t>((void *)material.multiTexture);
|
hash += reinterpret_cast<intptr_t>((void *)&material.multiTexture);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,8 +487,8 @@ VkDescriptorSet SimpleRenderer::createDescriptorFor(const DrawObject &model, con
|
||||||
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
|
||||||
if (material.diffuseTexture) {
|
if (material.diffuseTexture) {
|
||||||
imageInfo.imageView = material.diffuseTexture->view;
|
imageInfo.imageView = material.diffuseTexture->imageView;
|
||||||
imageInfo.sampler = material.diffuseTexture->sampler;
|
imageInfo.sampler = m_sampler;
|
||||||
} else {
|
} else {
|
||||||
imageInfo.imageView = m_dummyTex.imageView;
|
imageInfo.imageView = m_dummyTex.imageView;
|
||||||
imageInfo.sampler = m_sampler;
|
imageInfo.sampler = m_sampler;
|
||||||
|
@ -508,8 +508,8 @@ VkDescriptorSet SimpleRenderer::createDescriptorFor(const DrawObject &model, con
|
||||||
normalImageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
normalImageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
|
||||||
if (material.normalTexture) {
|
if (material.normalTexture) {
|
||||||
normalImageInfo.imageView = material.normalTexture->view;
|
normalImageInfo.imageView = material.normalTexture->imageView;
|
||||||
normalImageInfo.sampler = material.normalTexture->sampler;
|
normalImageInfo.sampler = m_sampler;
|
||||||
|
|
||||||
VkWriteDescriptorSet normalDescriptorWrite2 = {};
|
VkWriteDescriptorSet normalDescriptorWrite2 = {};
|
||||||
normalDescriptorWrite2.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
normalDescriptorWrite2.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
|
@ -526,8 +526,8 @@ VkDescriptorSet SimpleRenderer::createDescriptorFor(const DrawObject &model, con
|
||||||
specularImageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
specularImageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
|
||||||
if (material.specularTexture) {
|
if (material.specularTexture) {
|
||||||
specularImageInfo.imageView = material.specularTexture->view;
|
specularImageInfo.imageView = material.specularTexture->imageView;
|
||||||
specularImageInfo.sampler = material.specularTexture->sampler;
|
specularImageInfo.sampler = m_sampler;
|
||||||
|
|
||||||
VkWriteDescriptorSet specularDescriptorWrite2 = {};
|
VkWriteDescriptorSet specularDescriptorWrite2 = {};
|
||||||
specularDescriptorWrite2.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
specularDescriptorWrite2.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
|
@ -544,8 +544,8 @@ VkDescriptorSet SimpleRenderer::createDescriptorFor(const DrawObject &model, con
|
||||||
multiImageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
multiImageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
|
||||||
if (material.multiTexture) {
|
if (material.multiTexture) {
|
||||||
multiImageInfo.imageView = material.multiTexture->view;
|
multiImageInfo.imageView = material.multiTexture->imageView;
|
||||||
multiImageInfo.sampler = material.multiTexture->sampler;
|
multiImageInfo.sampler = m_sampler;
|
||||||
|
|
||||||
VkWriteDescriptorSet multiDescriptorWrite2 = {};
|
VkWriteDescriptorSet multiDescriptorWrite2 = {};
|
||||||
multiDescriptorWrite2.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
multiDescriptorWrite2.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
|
|
Loading…
Add table
Reference in a new issue