mirror of
https://github.com/redstrate/Novus.git
synced 2025-04-24 04:57:45 +00:00
Make Dawntrail geometry rendering work
The biggest change is making the model data read from vertex streams, like how the retail client is doing. The vertex bindings/locations should be fixed, resilient for the future and work across more shader packages.
This commit is contained in:
parent
a3f3437742
commit
f63dcbe9b0
8 changed files with 234 additions and 107 deletions
2
extern/libphysis
vendored
2
extern/libphysis
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 394e83d36b5428ae3f70b0aed98c80aa97f8796c
|
||||
Subproject commit e4251ed59f7d7d4c0ad5f028044d27486f45844f
|
|
@ -8,9 +8,12 @@
|
|||
struct RenderPart {
|
||||
size_t numIndices;
|
||||
|
||||
Buffer vertexBuffer, indexBuffer;
|
||||
Buffer vertexBuffer; // Only used in the simple renderer
|
||||
Buffer indexBuffer;
|
||||
std::vector<Buffer> streamBuffer; // Only used in the game renderer
|
||||
|
||||
int materialIndex = 0;
|
||||
physis_Part originalPart;
|
||||
};
|
||||
|
||||
enum class MaterialType { Object, Skin };
|
||||
|
|
|
@ -63,7 +63,9 @@ private:
|
|||
std::string_view passName,
|
||||
physis_Shader &vertexShader,
|
||||
physis_Shader &pixelShader,
|
||||
std::string_view shaderName);
|
||||
std::string_view shaderName,
|
||||
const physis_MDL *mdl,
|
||||
const physis_Part *part);
|
||||
|
||||
void createImageResources();
|
||||
|
||||
|
|
|
@ -18,7 +18,8 @@ class ShaderManager
|
|||
public:
|
||||
explicit ShaderManager(Device &device);
|
||||
|
||||
spirv_cross::CompilerGLSL getShaderModuleResources(const physis_Shader &shader);
|
||||
spirv_cross::CompilerGLSL getShaderModuleTest(const physis_Shader &shader);
|
||||
std::string getShaderModuleResources(const physis_Shader &shader, int i);
|
||||
VkShaderModule convertShaderModule(const physis_Shader &shader, spv::ExecutionModel executionModel);
|
||||
|
||||
private:
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
|
||||
// Structure definitions from https://github.com/Shaderlayan/Ouroboros
|
||||
struct CameraParameter {
|
||||
glm::mat3x4 m_ViewMatrix; // TODO: does it need alignment?
|
||||
glm::mat3x4 m_InverseViewMatrix;
|
||||
glm::mat3x4 m_ViewMatrix; // TODO: does it need alignment?
|
||||
glm::mat4 m_ViewProjectionMatrix;
|
||||
glm::mat4 m_InverseViewProjectionMatrix;
|
||||
glm::mat4 m_InverseProjectionMatrix; // used for view position recalc
|
||||
|
@ -14,6 +14,11 @@ struct CameraParameter {
|
|||
glm::mat4 m_MainViewToProjectionMatrix;
|
||||
glm::vec4 m_EyePosition;
|
||||
glm::vec4 m_LookAtVector;
|
||||
glm::vec4 m_unknown1[12];
|
||||
glm::mat4 m_unknownMatrix; // used in a vertex shader in characterlegacy.shpk
|
||||
glm::vec4 m_unknown2[11];
|
||||
// Dawntrail: something accesses the z and w of this
|
||||
glm::vec4 m_unknown3;
|
||||
};
|
||||
|
||||
const int JOINT_MATRIX_SIZE_ARR = 64;
|
||||
|
@ -29,6 +34,8 @@ struct InstanceParameterStruct {
|
|||
glm::vec4 m_EnvParameter;
|
||||
CameraLight m_CameraLight;
|
||||
glm::vec4 m_Wetness;
|
||||
// New in Dawntrail
|
||||
glm::vec4 unknown[5];
|
||||
};
|
||||
|
||||
struct InstanceParameter {
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include "rendermanager.h"
|
||||
#include "swapchain.h"
|
||||
|
||||
#include <magic_enum/include/magic_enum.hpp>
|
||||
|
||||
// TODO: maybe need UV?
|
||||
// note: SQEX passes the vertice positions as UV coordinates (yes, -1 to 1.) the shaders then transform them back with the g_CommonParameter.m_RenderTarget vec4
|
||||
const std::vector<glm::vec4> planeVertices = {
|
||||
|
@ -262,8 +264,11 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, Camera &camera, Scene &
|
|||
|
||||
const glm::mat4 viewProjectionMatrix = camera.perspective * camera.view;
|
||||
|
||||
// unknown
|
||||
cameraParameter.m_unknownMatrix = glm::transpose(glm::inverse(camera.view));
|
||||
|
||||
cameraParameter.m_ViewMatrix = glm::transpose(camera.view);
|
||||
cameraParameter.m_InverseViewMatrix = glm::transpose(glm::inverse(camera.view));
|
||||
cameraParameter.m_InverseViewMatrix = cameraParameter.m_unknownMatrix;
|
||||
cameraParameter.m_ViewProjectionMatrix = glm::transpose(viewProjectionMatrix);
|
||||
cameraParameter.m_InverseViewProjectionMatrix = glm::transpose(glm::inverse(viewProjectionMatrix));
|
||||
|
||||
|
@ -394,11 +399,14 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, Camera &camera, Scene &
|
|||
physis_Shader vertexShader = renderMaterial.shaderPackage.vertex_shaders[vertexShaderIndice];
|
||||
physis_Shader pixelShader = renderMaterial.shaderPackage.pixel_shaders[pixelShaderIndice];
|
||||
|
||||
auto &pipeline = bindPipeline(commandBuffer, pass, vertexShader, pixelShader, renderMaterial.mat.shpk_name);
|
||||
auto &pipeline =
|
||||
bindPipeline(commandBuffer, pass, vertexShader, pixelShader, renderMaterial.mat.shpk_name, &model.model, &part.originalPart);
|
||||
bindDescriptorSets(commandBuffer, pipeline, &model, &renderMaterial, pass);
|
||||
|
||||
VkDeviceSize offsets[] = {0};
|
||||
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &part.vertexBuffer.buffer, offsets);
|
||||
for (int j = 0; j < part.originalPart.num_streams; j++) {
|
||||
vkCmdBindVertexBuffers(commandBuffer, j, 1, &part.streamBuffer[j].buffer, offsets);
|
||||
}
|
||||
vkCmdBindIndexBuffer(commandBuffer, part.indexBuffer.buffer, 0, VK_INDEX_TYPE_UINT16);
|
||||
|
||||
vkCmdDrawIndexed(commandBuffer, part.numIndices, 1, 0, 0, 0);
|
||||
|
@ -451,7 +459,13 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, Camera &camera, Scene &
|
|||
physis_Shader vertexShader = createViewPositionShpk.vertex_shaders[vertexShaderIndice];
|
||||
physis_Shader pixelShader = createViewPositionShpk.pixel_shaders[pixelShaderIndice];
|
||||
|
||||
auto &pipeline = bindPipeline(commandBuffer, "PASS_LIGHTING_OPAQUE_VIEWPOSITION", vertexShader, pixelShader, "createviewposition.shpk");
|
||||
auto &pipeline = bindPipeline(commandBuffer,
|
||||
"PASS_LIGHTING_OPAQUE_VIEWPOSITION",
|
||||
vertexShader,
|
||||
pixelShader,
|
||||
"createviewposition.shpk",
|
||||
nullptr,
|
||||
nullptr);
|
||||
bindDescriptorSets(commandBuffer, pipeline, nullptr, nullptr, pass);
|
||||
|
||||
VkDeviceSize offsets[] = {0};
|
||||
|
@ -506,7 +520,7 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, Camera &camera, Scene &
|
|||
physis_Shader vertexShader = directionalLightningShpk.vertex_shaders[vertexShaderIndice];
|
||||
physis_Shader pixelShader = directionalLightningShpk.pixel_shaders[pixelShaderIndice];
|
||||
|
||||
auto &pipeline = bindPipeline(commandBuffer, pass, vertexShader, pixelShader, "directionallighting.shpk");
|
||||
auto &pipeline = bindPipeline(commandBuffer, pass, vertexShader, pixelShader, "directionallighting.shpk", nullptr, nullptr);
|
||||
bindDescriptorSets(commandBuffer, pipeline, nullptr, nullptr, pass);
|
||||
|
||||
VkDeviceSize offsets[] = {0};
|
||||
|
@ -607,11 +621,14 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, Camera &camera, Scene &
|
|||
physis_Shader vertexShader = renderMaterial.shaderPackage.vertex_shaders[vertexShaderIndice];
|
||||
physis_Shader pixelShader = renderMaterial.shaderPackage.pixel_shaders[pixelShaderIndice];
|
||||
|
||||
auto &pipeline = bindPipeline(commandBuffer, pass, vertexShader, pixelShader, renderMaterial.mat.shpk_name);
|
||||
auto &pipeline =
|
||||
bindPipeline(commandBuffer, pass, vertexShader, pixelShader, renderMaterial.mat.shpk_name, &model.model, &part.originalPart);
|
||||
bindDescriptorSets(commandBuffer, pipeline, &model, &renderMaterial, pass);
|
||||
|
||||
VkDeviceSize offsets[] = {0};
|
||||
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &part.vertexBuffer.buffer, offsets);
|
||||
for (int j = 0; j < part.originalPart.num_streams; j++) {
|
||||
vkCmdBindVertexBuffers(commandBuffer, j, 1, &part.streamBuffer[j].buffer, offsets);
|
||||
}
|
||||
vkCmdBindIndexBuffer(commandBuffer, part.indexBuffer.buffer, 0, VK_INDEX_TYPE_UINT16);
|
||||
|
||||
vkCmdDrawIndexed(commandBuffer, part.numIndices, 1, 0, 0, 0);
|
||||
|
@ -809,7 +826,9 @@ GameRenderer::CachedPipeline &GameRenderer::bindPipeline(VkCommandBuffer command
|
|||
std::string_view passName,
|
||||
physis_Shader &vertexShader,
|
||||
physis_Shader &pixelShader,
|
||||
std::string_view shaderName)
|
||||
std::string_view shaderName,
|
||||
const physis_MDL *mdl,
|
||||
const physis_Part *part)
|
||||
{
|
||||
const uint32_t hash = vertexShader.len + pixelShader.len + physis_shpk_crc(passName.data());
|
||||
if (!m_cachedPipelines.contains(hash)) {
|
||||
|
@ -833,19 +852,24 @@ GameRenderer::CachedPipeline &GameRenderer::bindPipeline(VkCommandBuffer command
|
|||
|
||||
std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages = {vertexShaderStageInfo, fragmentShaderStageInfo};
|
||||
|
||||
VkVertexInputBindingDescription binding = {};
|
||||
|
||||
// TODO: temporary
|
||||
if (passName == "PASS_G_OPAQUE" || passName == "PASS_Z_OPAQUE" || passName == "PASS_COMPOSITE_SEMITRANSPARENCY") {
|
||||
binding.stride = sizeof(Vertex);
|
||||
} else if (passName == "PASS_LIGHTING_OPAQUE" || passName == "PASS_LIGHTING_OPAQUE_VIEWPOSITION") {
|
||||
std::vector<VkVertexInputBindingDescription> bindings;
|
||||
if (passName == "PASS_LIGHTING_OPAQUE" || passName == "PASS_LIGHTING_OPAQUE_VIEWPOSITION") {
|
||||
VkVertexInputBindingDescription binding = {};
|
||||
binding.stride = sizeof(glm::vec4);
|
||||
bindings.push_back(binding);
|
||||
} else {
|
||||
for (int i = 0; i < part->num_streams; i++) {
|
||||
VkVertexInputBindingDescription binding = {};
|
||||
binding.stride = part->stream_strides[i];
|
||||
binding.binding = i;
|
||||
bindings.push_back(binding);
|
||||
}
|
||||
}
|
||||
|
||||
auto vertex_glsl = m_shaderManager.getShaderModuleResources(vertexShader);
|
||||
auto vertex_glsl = m_shaderManager.getShaderModuleTest(vertexShader);
|
||||
auto vertex_resources = vertex_glsl.get_shader_resources();
|
||||
|
||||
auto fragment_glsl = m_shaderManager.getShaderModuleResources(pixelShader);
|
||||
auto fragment_glsl = m_shaderManager.getShaderModuleTest(pixelShader);
|
||||
auto fragment_resources = fragment_glsl.get_shader_resources();
|
||||
|
||||
std::vector<RequestedSet> requestedSets;
|
||||
|
@ -924,62 +948,134 @@ GameRenderer::CachedPipeline &GameRenderer::bindPipeline(VkCommandBuffer command
|
|||
for (auto texture : vertex_resources.stage_inputs) {
|
||||
unsigned binding = vertex_glsl.get_decoration(texture.id, spv::DecorationLocation);
|
||||
|
||||
auto name = vertex_glsl.get_name(texture.id);
|
||||
|
||||
VkVertexInputAttributeDescription uv0Attribute = {};
|
||||
|
||||
auto type = vertex_glsl.get_type(texture.type_id);
|
||||
if (type.basetype == spirv_cross::SPIRType::Int) {
|
||||
switch (type.vecsize) {
|
||||
case 1:
|
||||
uv0Attribute.format = VK_FORMAT_R32_SINT;
|
||||
break;
|
||||
case 2:
|
||||
uv0Attribute.format = VK_FORMAT_R32G32_SINT;
|
||||
break;
|
||||
case 3:
|
||||
uv0Attribute.format = VK_FORMAT_R32G32B32_SINT;
|
||||
break;
|
||||
case 4:
|
||||
uv0Attribute.format = VK_FORMAT_R8G8B8A8_UINT; // supposed to be VK_FORMAT_R32G32B32A32_SINT, but our bone_id is uint8_t currently
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (type.vecsize) {
|
||||
case 1:
|
||||
uv0Attribute.format = VK_FORMAT_R32_SFLOAT;
|
||||
break;
|
||||
case 2:
|
||||
uv0Attribute.format = VK_FORMAT_R32G32_SFLOAT;
|
||||
break;
|
||||
case 3:
|
||||
uv0Attribute.format = VK_FORMAT_R32G32B32_SFLOAT;
|
||||
break;
|
||||
case 4:
|
||||
uv0Attribute.format = VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uv0Attribute.location = binding;
|
||||
|
||||
// TODO: temporary
|
||||
if (name == "v0") {
|
||||
uv0Attribute.offset = offsetof(Vertex, position);
|
||||
} else if (name == "v1") {
|
||||
uv0Attribute.offset = offsetof(Vertex, color);
|
||||
} else if (name == "v2") {
|
||||
uv0Attribute.offset = offsetof(Vertex, normal);
|
||||
} else if (name == "v3") {
|
||||
uv0Attribute.offset = offsetof(Vertex, uv0);
|
||||
} else if (name == "v4") {
|
||||
uv0Attribute.offset = offsetof(Vertex, bitangent); // FIXME: should be tangent
|
||||
} else if (name == "v5") {
|
||||
uv0Attribute.offset = offsetof(Vertex, bitangent);
|
||||
} else if (name == "v6") {
|
||||
uv0Attribute.offset = offsetof(Vertex, bone_weight);
|
||||
} else if (name == "v7") {
|
||||
uv0Attribute.offset = offsetof(Vertex, bone_id);
|
||||
if (mdl != nullptr) {
|
||||
std::string semanticName = m_shaderManager.getShaderModuleResources(vertexShader, binding);
|
||||
|
||||
for (int i = 0; i < mdl->lods[0].num_vertex_elements; i++) {
|
||||
auto element = mdl->lods[0].vertex_elements[i];
|
||||
|
||||
auto fromVertexType = [](VertexType type) -> VkFormat {
|
||||
switch (type) {
|
||||
case VertexType::Single1:
|
||||
return VK_FORMAT_R32_SFLOAT;
|
||||
case VertexType::Single2:
|
||||
return VK_FORMAT_R32G32_SFLOAT;
|
||||
case VertexType::Single3:
|
||||
return VK_FORMAT_R32G32B32_SFLOAT;
|
||||
case VertexType::Single4:
|
||||
return VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
case VertexType::Byte4:
|
||||
return VK_FORMAT_R8G8B8A8_UINT;
|
||||
case VertexType::Short2:
|
||||
break;
|
||||
case VertexType::Short4:
|
||||
break;
|
||||
case VertexType::ByteFloat4:
|
||||
return VK_FORMAT_R8G8B8A8_UNORM;
|
||||
case VertexType::Short2n:
|
||||
break;
|
||||
case VertexType::Short4n:
|
||||
break;
|
||||
case VertexType::Half2:
|
||||
return VK_FORMAT_R16G16_SFLOAT;
|
||||
case VertexType::Half4:
|
||||
return VK_FORMAT_R16G16B16A16_UNORM;
|
||||
case VertexType::UnsignedShort2:
|
||||
break;
|
||||
case VertexType::UnsignedShort4:
|
||||
break;
|
||||
}
|
||||
|
||||
qInfo() << "Unhandled type" << magic_enum::enum_name(type);
|
||||
return VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
};
|
||||
|
||||
if (semanticName == "POSITION" && mdl->lods[0].vertex_elements[i].vertex_usage == VertexUsage::Position) {
|
||||
uv0Attribute.binding = element.stream;
|
||||
uv0Attribute.offset = mdl->lods[0].vertex_elements[i].offset;
|
||||
uv0Attribute.format = fromVertexType(element.vertex_type);
|
||||
} else if (semanticName == "COLOR" && mdl->lods[0].vertex_elements[i].vertex_usage == VertexUsage::Color) {
|
||||
uv0Attribute.binding = element.stream;
|
||||
uv0Attribute.offset = mdl->lods[0].vertex_elements[i].offset;
|
||||
uv0Attribute.format = fromVertexType(element.vertex_type);
|
||||
} else if (semanticName == "TEXCOORD" && mdl->lods[0].vertex_elements[i].vertex_usage == VertexUsage::UV) {
|
||||
uv0Attribute.binding = element.stream;
|
||||
uv0Attribute.offset = mdl->lods[0].vertex_elements[i].offset;
|
||||
uv0Attribute.format = fromVertexType(element.vertex_type);
|
||||
} else if (semanticName == "NORMAL" && mdl->lods[0].vertex_elements[i].vertex_usage == VertexUsage::Normal) {
|
||||
uv0Attribute.binding = element.stream;
|
||||
uv0Attribute.offset = mdl->lods[0].vertex_elements[i].offset;
|
||||
uv0Attribute.format = fromVertexType(element.vertex_type);
|
||||
} else if (semanticName == "BINORMAL"
|
||||
&& mdl->lods[0].vertex_elements[i].vertex_usage == VertexUsage::BiTangent) { // TODO: Bitangent is here twice lol
|
||||
uv0Attribute.binding = element.stream;
|
||||
uv0Attribute.offset = mdl->lods[0].vertex_elements[i].offset;
|
||||
uv0Attribute.format = fromVertexType(element.vertex_type);
|
||||
} else if (semanticName == "BLENDWEIGHT" && mdl->lods[0].vertex_elements[i].vertex_usage == VertexUsage::BlendWeights) {
|
||||
uv0Attribute.binding = element.stream;
|
||||
uv0Attribute.offset = mdl->lods[0].vertex_elements[i].offset;
|
||||
uv0Attribute.format = fromVertexType(element.vertex_type);
|
||||
} else if (semanticName == "BLENDINDICES" && mdl->lods[0].vertex_elements[i].vertex_usage == VertexUsage::BlendIndices) {
|
||||
uv0Attribute.binding = element.stream;
|
||||
uv0Attribute.offset = mdl->lods[0].vertex_elements[i].offset;
|
||||
uv0Attribute.format = fromVertexType(element.vertex_type);
|
||||
}
|
||||
}
|
||||
|
||||
if (uv0Attribute.format == VK_FORMAT_UNDEFINED) {
|
||||
qWarning() << "Unhandled input name:" << semanticName;
|
||||
}
|
||||
} else {
|
||||
auto type = vertex_glsl.get_type(texture.type_id);
|
||||
if (type.basetype == spirv_cross::SPIRType::Int) {
|
||||
switch (type.vecsize) {
|
||||
case 1:
|
||||
uv0Attribute.format = VK_FORMAT_R32_SINT;
|
||||
break;
|
||||
case 2:
|
||||
uv0Attribute.format = VK_FORMAT_R32G32_SINT;
|
||||
break;
|
||||
case 3:
|
||||
uv0Attribute.format = VK_FORMAT_R32G32B32_SINT;
|
||||
break;
|
||||
case 4:
|
||||
uv0Attribute.format = VK_FORMAT_R8G8B8A8_UINT; // supposed to be VK_FORMAT_R32G32B32A32_SINT, but our bone_id is uint8_t currently
|
||||
break;
|
||||
}
|
||||
} else if (type.basetype == spirv_cross::SPIRType::Float) {
|
||||
switch (type.vecsize) {
|
||||
case 1:
|
||||
uv0Attribute.format = VK_FORMAT_R32_SFLOAT;
|
||||
break;
|
||||
case 2:
|
||||
uv0Attribute.format = VK_FORMAT_R32G32_SFLOAT;
|
||||
break;
|
||||
case 3:
|
||||
uv0Attribute.format = VK_FORMAT_R32G32B32_SFLOAT;
|
||||
break;
|
||||
case 4:
|
||||
uv0Attribute.format = VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
break;
|
||||
}
|
||||
} else if (type.basetype == spirv_cross::SPIRType::Half) {
|
||||
switch (type.vecsize) {
|
||||
case 1:
|
||||
uv0Attribute.format = VK_FORMAT_R16_SFLOAT;
|
||||
break;
|
||||
case 2:
|
||||
uv0Attribute.format = VK_FORMAT_R16G16_SFLOAT;
|
||||
break;
|
||||
case 3:
|
||||
uv0Attribute.format = VK_FORMAT_R16G16B16_SFLOAT;
|
||||
break;
|
||||
case 4:
|
||||
uv0Attribute.format = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
attributeDescs.push_back(uv0Attribute);
|
||||
|
@ -987,8 +1083,8 @@ GameRenderer::CachedPipeline &GameRenderer::bindPipeline(VkCommandBuffer command
|
|||
|
||||
VkPipelineVertexInputStateCreateInfo vertexInputState = {};
|
||||
vertexInputState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||
vertexInputState.vertexBindingDescriptionCount = 1;
|
||||
vertexInputState.pVertexBindingDescriptions = &binding;
|
||||
vertexInputState.vertexBindingDescriptionCount = bindings.size();
|
||||
vertexInputState.pVertexBindingDescriptions = bindings.data();
|
||||
vertexInputState.vertexAttributeDescriptionCount = attributeDescs.size();
|
||||
vertexInputState.pVertexAttributeDescriptions = attributeDescs.data();
|
||||
|
||||
|
@ -1192,7 +1288,7 @@ GameRenderer::createDescriptorFor(const DrawObject *object, const CachedPipeline
|
|||
info->imageView = m_viewPositionBuffer.imageView;
|
||||
} else if (strcmp(name, "g_SamplerDepth") == 0) {
|
||||
info->imageView = m_depthBuffer.imageView;
|
||||
} else if (strcmp(name, "g_SamplerNormal") == 0 || strcmp(name, "g_SamplerIndex") == 0) {
|
||||
} else if ((strcmp(name, "g_SamplerNormal") == 0 || strcmp(name, "g_SamplerIndex") == 0) && material->normalTexture.has_value()) {
|
||||
Q_ASSERT(material);
|
||||
info->imageView = material->normalTexture->imageView;
|
||||
} else if (strcmp(name, "g_SamplerLightDiffuse") == 0) {
|
||||
|
@ -1201,13 +1297,13 @@ GameRenderer::createDescriptorFor(const DrawObject *object, const CachedPipeline
|
|||
} else if (strcmp(name, "g_SamplerLightSpecular") == 0) {
|
||||
Q_ASSERT(material);
|
||||
info->imageView = m_lightSpecularBuffer.imageView;
|
||||
} else if (strcmp(name, "g_SamplerDiffuse") == 0) {
|
||||
} else if (strcmp(name, "g_SamplerDiffuse") == 0 && material->diffuseTexture.has_value()) {
|
||||
Q_ASSERT(material);
|
||||
info->imageView = material->diffuseTexture->imageView;
|
||||
} else if (strcmp(name, "g_SamplerSpecular") == 0) {
|
||||
} else if (strcmp(name, "g_SamplerSpecular") == 0 && material->specularTexture.has_value()) {
|
||||
Q_ASSERT(material);
|
||||
info->imageView = material->specularTexture->imageView;
|
||||
} else if (strcmp(name, "g_SamplerMask") == 0) {
|
||||
} else if (strcmp(name, "g_SamplerMask") == 0 && material->multiTexture.has_value()) {
|
||||
Q_ASSERT(material);
|
||||
info->imageView = material->multiTexture->imageView;
|
||||
} else if (strcmp(name, "g_SamplerTileNormal") == 0) {
|
||||
|
@ -1218,6 +1314,7 @@ GameRenderer::createDescriptorFor(const DrawObject *object, const CachedPipeline
|
|||
Q_ASSERT(material);
|
||||
if (!material->tableTexture.has_value()) {
|
||||
qWarning() << "Attempted to use table texture for a non-dyeable material. Something has went wrong!";
|
||||
info->imageView = m_dummyTex.imageView;
|
||||
} else {
|
||||
info->imageView = material->tableTexture->imageView;
|
||||
}
|
||||
|
@ -1253,7 +1350,7 @@ GameRenderer::createDescriptorFor(const DrawObject *object, const CachedPipeline
|
|||
|
||||
if (strcmp(name, "g_CameraParameter") == 0) {
|
||||
useUniformBuffer(g_CameraParameter);
|
||||
} else if (strcmp(name, "g_JointMatrixArray") == 0) {
|
||||
} else if (strcmp(name, "g_JointMatrixArray") == 0 || strcmp(name, "g_JointMatrixArrayPrev") == 0) {
|
||||
Q_ASSERT(object != nullptr);
|
||||
useUniformBuffer(object->boneInfoBuffer);
|
||||
} else if (strcmp(name, "g_InstanceParameter") == 0) {
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include "simplerenderer.h"
|
||||
#include "swapchain.h"
|
||||
|
||||
#include <magic_enum/include/magic_enum.hpp>
|
||||
|
||||
VkResult CreateDebugUtilsMessengerEXT(VkInstance instance,
|
||||
const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
|
@ -516,11 +518,23 @@ void RenderManager::reloadDrawObject(DrawObject &DrawObject, uint32_t lod)
|
|||
|
||||
const physis_Part part = DrawObject.model.lods[lod].parts[i];
|
||||
|
||||
renderPart.originalPart = part;
|
||||
renderPart.materialIndex = part.material_index;
|
||||
|
||||
size_t vertexSize = part.num_vertices * sizeof(Vertex);
|
||||
renderPart.vertexBuffer = m_device->createBuffer(vertexSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
|
||||
m_device->copyToBuffer(renderPart.vertexBuffer, (void *)part.vertices, vertexSize);
|
||||
if (qgetenv("NOVUS_USE_NEW_RENDERER") == QByteArrayLiteral("1")) {
|
||||
renderPart.streamBuffer.resize(DrawObject.model.lods[lod].num_vertex_elements);
|
||||
for (uint32_t j = 0; j < part.num_streams; j++) {
|
||||
size_t size = part.stream_sizes[j];
|
||||
auto buffer = m_device->createBuffer(size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
|
||||
m_device->copyToBuffer(buffer, (void *)part.streams[j], size);
|
||||
|
||||
renderPart.streamBuffer[j] = buffer;
|
||||
}
|
||||
} else {
|
||||
size_t vertexSize = part.num_vertices * sizeof(Vertex);
|
||||
renderPart.vertexBuffer = m_device->createBuffer(vertexSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
|
||||
m_device->copyToBuffer(renderPart.vertexBuffer, (void *)part.vertices, vertexSize);
|
||||
}
|
||||
|
||||
size_t indexSize = part.num_indices * sizeof(uint16_t);
|
||||
renderPart.indexBuffer = m_device->createBuffer(indexSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
|
||||
|
|
|
@ -17,12 +17,14 @@
|
|||
|
||||
#include "device.h"
|
||||
|
||||
#include <ranges>
|
||||
|
||||
ShaderManager::ShaderManager(Device &device)
|
||||
: m_device(device)
|
||||
{
|
||||
}
|
||||
|
||||
spirv_cross::CompilerGLSL ShaderManager::getShaderModuleResources(const physis_Shader &shader)
|
||||
spirv_cross::CompilerGLSL ShaderManager::getShaderModuleTest(const physis_Shader &shader)
|
||||
{
|
||||
dxvk::DxbcReader reader(reinterpret_cast<const char *>(shader.bytecode), shader.len);
|
||||
|
||||
|
@ -34,6 +36,20 @@ spirv_cross::CompilerGLSL ShaderManager::getShaderModuleResources(const physis_S
|
|||
return {result.code.data(), result.code.dwords()};
|
||||
}
|
||||
|
||||
std::string ShaderManager::getShaderModuleResources(const physis_Shader &shader, int i)
|
||||
{
|
||||
dxvk::DxbcReader reader(reinterpret_cast<const char *>(shader.bytecode), shader.len);
|
||||
|
||||
dxvk::DxbcModule module(reader);
|
||||
|
||||
dxvk::DxbcModuleInfo info;
|
||||
auto result = module.compile(info, "test");
|
||||
|
||||
std::ranges::subrange entries(module.isgn()->begin(), module.isgn()->end());
|
||||
|
||||
return module.isgn()->findByRegister(i)->semanticName;
|
||||
}
|
||||
|
||||
VkShaderModule ShaderManager::convertShaderModule(const physis_Shader &shader, spv::ExecutionModel executionModel)
|
||||
{
|
||||
dxvk::DxbcReader reader(reinterpret_cast<const char *>(shader.bytecode), shader.len);
|
||||
|
@ -52,25 +68,12 @@ VkShaderModule ShaderManager::convertShaderModule(const physis_Shader &shader, s
|
|||
|
||||
auto resources = glsl.get_shader_resources();
|
||||
|
||||
std::ranges::subrange entries(module.isgn()->begin(), module.isgn()->end());
|
||||
|
||||
int i = 0;
|
||||
for (auto texture : resources.stage_inputs) {
|
||||
if (texture.name == "v0") {
|
||||
glsl.set_name(texture.id, "Position");
|
||||
} else if (texture.name == "v1") {
|
||||
glsl.set_name(texture.id, "Color");
|
||||
} else if (texture.name == "v2") {
|
||||
glsl.set_name(texture.id, "Normal");
|
||||
} else if (texture.name == "v3") {
|
||||
glsl.set_name(texture.id, "TexCoord");
|
||||
} else if (texture.name == "v4") {
|
||||
glsl.set_name(texture.id, "Tangent");
|
||||
} else if (texture.name == "v5") {
|
||||
glsl.set_name(texture.id, "Bitangent");
|
||||
} else if (texture.name == "v6") {
|
||||
glsl.set_name(texture.id, "BoneWeight");
|
||||
} else if (texture.name == "v7") {
|
||||
glsl.set_name(texture.id, "BoneId");
|
||||
}
|
||||
unsigned binding = glsl.get_decoration(texture.id, spv::DecorationLocation);
|
||||
glsl.set_name(texture.id, module.isgn()->findByRegister(binding)->semanticName);
|
||||
i++;
|
||||
}
|
||||
|
||||
|
@ -141,14 +144,14 @@ std::vector<uint32_t> ShaderManager::compileGLSL(const std::string_view sourceSt
|
|||
shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_3);
|
||||
shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_6);
|
||||
|
||||
if (!shader.parse(GetDefaultResources(), 100, false, EShMsgDefault)) {
|
||||
if (!shader.parse(GetDefaultResources(), 100, false, EShMsgDebugInfo)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
glslang::TProgram Program;
|
||||
Program.addShader(&shader);
|
||||
|
||||
if (!Program.link(EShMsgDefault)) {
|
||||
if (!Program.link(EShMsgDebugInfo)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue