1
Fork 0
mirror of https://github.com/redstrate/Novus.git synced 2025-04-25 13:17:46 +00:00

Remove hardcoded character.shpk path

Now the new renderer should load the material's requested shader package
This commit is contained in:
Joshua Goins 2024-04-21 19:07:09 -04:00
parent dcb54cf4e3
commit af806bff63
8 changed files with 62 additions and 89 deletions

View file

@ -220,6 +220,13 @@ RenderMaterial MDLPart::createMaterial(const physis_Material &material)
{ {
RenderMaterial newMaterial; RenderMaterial newMaterial;
std::string shpkPath = "shader/sm5/shpk/" + std::string(material.shpk_name);
auto shpkData = physis_gamedata_extract_file(data, shpkPath.c_str());
if (shpkData.data != nullptr) {
newMaterial.shaderPackage = physis_parse_shpk(shpkData);
}
for (uint32_t i = 0; i < material.num_textures; i++) { for (uint32_t i = 0; i < material.num_textures; i++) {
std::string t = material.textures[i]; std::string t = material.textures[i];

View file

@ -30,9 +30,6 @@ public:
/// Render a frame into @p commandBuffer. @p currentFrame is the same value as SwapChain::currentFrame for convenience. /// Render a frame into @p commandBuffer. @p currentFrame is the same value as SwapChain::currentFrame for convenience.
virtual void render(VkCommandBuffer commandBuffer, uint32_t currentFrame, Camera &camera, const std::vector<DrawObject> &models) = 0; virtual void render(VkCommandBuffer commandBuffer, uint32_t currentFrame, Camera &camera, const std::vector<DrawObject> &models) = 0;
/// Do whatever is needed in the backend to prepare it for drawing
virtual void addDrawObject(const DrawObject &drawObject) = 0;
/// The final composite texture that is drawn into with render() /// The final composite texture that is drawn into with render()
virtual Texture &getCompositeTexture() = 0; virtual Texture &getCompositeTexture() = 0;
}; };

View file

@ -22,6 +22,7 @@ enum class MaterialType { Object, Skin };
struct RenderMaterial { struct RenderMaterial {
MaterialType type = MaterialType::Object; MaterialType type = MaterialType::Object;
physis_SHPK shaderPackage;
RenderTexture *diffuseTexture = nullptr; RenderTexture *diffuseTexture = nullptr;
RenderTexture *normalTexture = nullptr; RenderTexture *normalTexture = nullptr;

View file

@ -19,7 +19,6 @@
#include "texture.h" #include "texture.h"
class Device; class Device;
struct RenderModel;
struct DrawObject; struct DrawObject;
/// Performs rendering by using the game's existing shaders. /// Performs rendering by using the game's existing shaders.
@ -32,8 +31,6 @@ public:
void render(VkCommandBuffer commandBuffer, uint32_t currentFrame, Camera &camera, const std::vector<DrawObject> &models) override; void render(VkCommandBuffer commandBuffer, uint32_t currentFrame, Camera &camera, const std::vector<DrawObject> &models) override;
void addDrawObject(const DrawObject &drawObject) override;
Texture &getCompositeTexture() override; Texture &getCompositeTexture() override;
private: private:
@ -69,21 +66,14 @@ private:
physis_SHPK directionalLightningShpk; physis_SHPK directionalLightningShpk;
physis_SHPK createViewPositionShpk; physis_SHPK createViewPositionShpk;
struct RenderModel {
physis_SHPK shpk;
::DrawObject *internal_model = nullptr;
};
std::vector<RenderModel> m_renderModels;
// combined vertex + pixel code length // combined vertex + pixel code length
std::unordered_map<uint32_t, CachedPipeline> m_cachedPipelines; std::unordered_map<uint32_t, CachedPipeline> m_cachedPipelines;
Device &m_device; Device &m_device;
GameData *m_data = nullptr; GameData *m_data = nullptr;
VkDescriptorSet createDescriptorFor(const RenderModel *object, const CachedPipeline &cachedPipeline, int i); VkDescriptorSet createDescriptorFor(const DrawObject *object, const CachedPipeline &cachedPipeline, int i);
void bindDescriptorSets(VkCommandBuffer commandBuffer, CachedPipeline &pipeline, const RenderModel *object); void bindDescriptorSets(VkCommandBuffer commandBuffer, CachedPipeline &pipeline, const DrawObject *object);
Buffer g_CameraParameter; Buffer g_CameraParameter;
Buffer g_InstanceParameter; Buffer g_InstanceParameter;

View file

@ -32,8 +32,6 @@ public:
void render(VkCommandBuffer commandBuffer, uint32_t currentFrame, Camera &camera, const std::vector<DrawObject> &models) override; void render(VkCommandBuffer commandBuffer, uint32_t currentFrame, Camera &camera, const std::vector<DrawObject> &models) override;
void addDrawObject(const DrawObject &drawObject) override;
Texture &getCompositeTexture() override; Texture &getCompositeTexture() override;
private: private:

View file

@ -135,13 +135,6 @@ GameRenderer::GameRenderer(Device &device, GameData *data)
createImageResources(); createImageResources();
} }
void GameRenderer::addDrawObject(const DrawObject &drawObject)
{
RenderModel model{.shpk = physis_parse_shpk(physis_gamedata_extract_file(m_data, "shader/sm5/shpk/character.shpk")),
.internal_model = new DrawObject(drawObject)};
m_renderModels.push_back(model);
}
void GameRenderer::render(VkCommandBuffer commandBuffer, uint32_t imageIndex, Camera &camera, const std::vector<DrawObject> &models) void GameRenderer::render(VkCommandBuffer commandBuffer, uint32_t imageIndex, Camera &camera, const std::vector<DrawObject> &models)
{ {
// TODO: this shouldn't be here // TODO: this shouldn't be here
@ -171,19 +164,6 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, uint32_t imageIndex, Ca
beginPass(imageIndex, commandBuffer, pass); beginPass(imageIndex, commandBuffer, pass);
for (auto &model : models) { for (auto &model : models) {
std::optional<GameRenderer::RenderModel> renderModel;
// FIXME: this is terrible
auto it = std::find_if(m_renderModels.begin(), m_renderModels.end(), [&model](const RenderModel &a_model) {
return model.model.p_ptr == a_model.internal_model->model.p_ptr;
});
if (it != m_renderModels.end()) {
renderModel = *it;
}
if (!renderModel.has_value()) {
continue;
}
// copy bone data // copy bone data
{ {
const size_t bufferSize = sizeof(glm::mat3x4) * 64; const size_t bufferSize = sizeof(glm::mat3x4) * 64;
@ -192,7 +172,7 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, uint32_t imageIndex, Ca
std::vector<glm::mat3x4> newBoneData(model.boneData.size()); std::vector<glm::mat3x4> newBoneData(model.boneData.size());
for (int i = 0; i < 64; i++) { for (int i = 0; i < 64; i++) {
newBoneData[i] = model.boneData[i]; newBoneData[i] = glm::transpose(model.boneData[i]);
} }
memcpy(mapped_data, newBoneData.data(), bufferSize); memcpy(mapped_data, newBoneData.data(), bufferSize);
@ -206,56 +186,62 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, uint32_t imageIndex, Ca
vkUnmapMemory(m_device.device, model.boneInfoBuffer.memory); vkUnmapMemory(m_device.device, model.boneInfoBuffer.memory);
} }
std::vector<uint32_t> systemKeys; for (const auto &part : model.parts) {
std::vector<uint32_t> sceneKeys = { auto &renderMaterial = model.materials[part.materialIndex];
physis_shpk_crc("TransformViewSkin"),
physis_shpk_crc("GetAmbientLight_SH"), if (renderMaterial.shaderPackage.p_ptr == nullptr) {
physis_shpk_crc("GetReflectColor_Texture"), qWarning() << "Invalid shader package!";
physis_shpk_crc("GetAmbientOcclusion_None"),
physis_shpk_crc("ApplyDitherClipOff"),
};
std::vector<uint32_t> materialKeys;
for (int j = 0; j < renderModel->shpk.num_material_keys; j++) {
auto value = renderModel->shpk.material_keys[j].default_value;
// Replace MODE_DEFAULT with MODE_SIMPLE for now
if (value != 0x5CC605B5) {
materialKeys.push_back(renderModel->shpk.material_keys[j].default_value);
} else {
materialKeys.push_back(0x22A4AABF);
} }
}
std::vector<uint32_t> subviewKeys = {physis_shpk_crc("Default"), physis_shpk_crc("SUB_VIEW_MAIN")};
const u_int32_t selector = physis_shpk_build_selector_from_all_keys(systemKeys.data(), std::vector<uint32_t> systemKeys;
systemKeys.size(), std::vector<uint32_t> sceneKeys = {
sceneKeys.data(), physis_shpk_crc("TransformViewSkin"),
sceneKeys.size(), physis_shpk_crc("GetAmbientLight_SH"),
materialKeys.data(), physis_shpk_crc("GetReflectColor_Texture"),
materialKeys.size(), physis_shpk_crc("GetAmbientOcclusion_None"),
subviewKeys.data(), physis_shpk_crc("ApplyDitherClipOff"),
subviewKeys.size()); };
const physis_SHPKNode node = physis_shpk_get_node(&renderModel->shpk, selector); std::vector<uint32_t> materialKeys;
for (int j = 0; j < renderMaterial.shaderPackage.num_material_keys; j++) {
auto value = renderMaterial.shaderPackage.material_keys[j].default_value;
// Replace MODE_DEFAULT with MODE_SIMPLE for now
if (value != 0x5CC605B5) {
materialKeys.push_back(renderMaterial.shaderPackage.material_keys[j].default_value);
} else {
materialKeys.push_back(0x22A4AABF);
}
}
std::vector<uint32_t> subviewKeys = {physis_shpk_crc("Default"), physis_shpk_crc("SUB_VIEW_MAIN")};
// check if invalid const u_int32_t selector = physis_shpk_build_selector_from_all_keys(systemKeys.data(),
if (node.pass_count == 0) { systemKeys.size(),
continue; sceneKeys.data(),
} sceneKeys.size(),
materialKeys.data(),
materialKeys.size(),
subviewKeys.data(),
subviewKeys.size());
const physis_SHPKNode node = physis_shpk_get_node(&renderMaterial.shaderPackage, selector);
// this is an index into the node's pass array, not to get confused with the global one we always follow. // check if invalid
const int passIndice = node.pass_indices[i]; if (node.pass_count == 0) {
if (passIndice != INVALID_PASS) { continue;
const Pass currentPass = node.passes[passIndice]; }
const uint32_t vertexShaderIndice = currentPass.vertex_shader; // this is an index into the node's pass array, not to get confused with the global one we always follow.
const uint32_t pixelShaderIndice = currentPass.pixel_shader; const int passIndice = node.pass_indices[i];
if (passIndice != INVALID_PASS) {
const Pass currentPass = node.passes[passIndice];
physis_Shader vertexShader = renderModel->shpk.vertex_shaders[vertexShaderIndice]; const uint32_t vertexShaderIndice = currentPass.vertex_shader;
physis_Shader pixelShader = renderModel->shpk.pixel_shaders[pixelShaderIndice]; const uint32_t pixelShaderIndice = currentPass.pixel_shader;
auto &pipeline = bindPipeline(commandBuffer, pass, vertexShader, pixelShader); physis_Shader vertexShader = renderMaterial.shaderPackage.vertex_shaders[vertexShaderIndice];
bindDescriptorSets(commandBuffer, pipeline, &renderModel.value()); physis_Shader pixelShader = renderMaterial.shaderPackage.pixel_shaders[pixelShaderIndice];
auto &pipeline = bindPipeline(commandBuffer, pass, vertexShader, pixelShader);
bindDescriptorSets(commandBuffer, pipeline, &model);
for (const auto &part : renderModel->internal_model->parts) {
VkDeviceSize offsets[] = {0}; VkDeviceSize offsets[] = {0};
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &part.vertexBuffer.buffer, offsets); vkCmdBindVertexBuffers(commandBuffer, 0, 1, &part.vertexBuffer.buffer, offsets);
vkCmdBindIndexBuffer(commandBuffer, part.indexBuffer.buffer, 0, VK_INDEX_TYPE_UINT16); vkCmdBindIndexBuffer(commandBuffer, part.indexBuffer.buffer, 0, VK_INDEX_TYPE_UINT16);
@ -903,7 +889,7 @@ spirv_cross::CompilerGLSL GameRenderer::getShaderModuleResources(const physis_Sh
return spirv_cross::CompilerGLSL(result.code.data(), result.code.dwords()); return spirv_cross::CompilerGLSL(result.code.data(), result.code.dwords());
} }
VkDescriptorSet GameRenderer::createDescriptorFor(const RenderModel *object, const CachedPipeline &pipeline, int i) VkDescriptorSet GameRenderer::createDescriptorFor(const DrawObject *object, const CachedPipeline &pipeline, int i)
{ {
VkDescriptorSet set; VkDescriptorSet set;
@ -995,7 +981,7 @@ VkDescriptorSet GameRenderer::createDescriptorFor(const RenderModel *object, con
useUniformBuffer(g_CameraParameter); useUniformBuffer(g_CameraParameter);
} else if (strcmp(name, "g_JointMatrixArray") == 0) { } else if (strcmp(name, "g_JointMatrixArray") == 0) {
Q_ASSERT(object != nullptr); Q_ASSERT(object != nullptr);
useUniformBuffer(object->internal_model->boneInfoBuffer); useUniformBuffer(object->boneInfoBuffer);
} else if (strcmp(name, "g_InstanceParameter") == 0) { } else if (strcmp(name, "g_InstanceParameter") == 0) {
useUniformBuffer(g_InstanceParameter); useUniformBuffer(g_InstanceParameter);
} else if (strcmp(name, "g_ModelParameter") == 0) { } else if (strcmp(name, "g_ModelParameter") == 0) {
@ -1072,7 +1058,7 @@ Texture &GameRenderer::getCompositeTexture()
return m_compositeBuffer; return m_compositeBuffer;
} }
void GameRenderer::bindDescriptorSets(VkCommandBuffer commandBuffer, GameRenderer::CachedPipeline &pipeline, const RenderModel *object) void GameRenderer::bindDescriptorSets(VkCommandBuffer commandBuffer, GameRenderer::CachedPipeline &pipeline, const DrawObject *object)
{ {
int i = 0; int i = 0;
for (auto setLayout : pipeline.setLayouts) { for (auto setLayout : pipeline.setLayouts) {

View file

@ -468,8 +468,6 @@ DrawObject RenderManager::addDrawObject(const physis_MDL &model, int lod)
reloadDrawObject(DrawObject, lod); reloadDrawObject(DrawObject, lod);
m_renderer->addDrawObject(DrawObject);
return DrawObject; return DrawObject;
} }

View file

@ -563,10 +563,6 @@ VkDescriptorSet SimpleRenderer::createDescriptorFor(const DrawObject &model, con
return set; return set;
} }
void SimpleRenderer::addDrawObject(const DrawObject &drawObject)
{
}
Texture &SimpleRenderer::getCompositeTexture() Texture &SimpleRenderer::getCompositeTexture()
{ {
return m_compositeTexture; return m_compositeTexture;