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;
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++) {
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.
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()
virtual Texture &getCompositeTexture() = 0;
};

View file

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

View file

@ -19,7 +19,6 @@
#include "texture.h"
class Device;
struct RenderModel;
struct DrawObject;
/// 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 addDrawObject(const DrawObject &drawObject) override;
Texture &getCompositeTexture() override;
private:
@ -69,21 +66,14 @@ private:
physis_SHPK directionalLightningShpk;
physis_SHPK createViewPositionShpk;
struct RenderModel {
physis_SHPK shpk;
::DrawObject *internal_model = nullptr;
};
std::vector<RenderModel> m_renderModels;
// combined vertex + pixel code length
std::unordered_map<uint32_t, CachedPipeline> m_cachedPipelines;
Device &m_device;
GameData *m_data = nullptr;
VkDescriptorSet createDescriptorFor(const RenderModel *object, const CachedPipeline &cachedPipeline, int i);
void bindDescriptorSets(VkCommandBuffer commandBuffer, CachedPipeline &pipeline, const RenderModel *object);
VkDescriptorSet createDescriptorFor(const DrawObject *object, const CachedPipeline &cachedPipeline, int i);
void bindDescriptorSets(VkCommandBuffer commandBuffer, CachedPipeline &pipeline, const DrawObject *object);
Buffer g_CameraParameter;
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 addDrawObject(const DrawObject &drawObject) override;
Texture &getCompositeTexture() override;
private:

View file

@ -135,13 +135,6 @@ GameRenderer::GameRenderer(Device &device, GameData *data)
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)
{
// TODO: this shouldn't be here
@ -171,19 +164,6 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, uint32_t imageIndex, Ca
beginPass(imageIndex, commandBuffer, pass);
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
{
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());
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);
@ -206,56 +186,62 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, uint32_t imageIndex, Ca
vkUnmapMemory(m_device.device, model.boneInfoBuffer.memory);
}
std::vector<uint32_t> systemKeys;
std::vector<uint32_t> sceneKeys = {
physis_shpk_crc("TransformViewSkin"),
physis_shpk_crc("GetAmbientLight_SH"),
physis_shpk_crc("GetReflectColor_Texture"),
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);
for (const auto &part : model.parts) {
auto &renderMaterial = model.materials[part.materialIndex];
if (renderMaterial.shaderPackage.p_ptr == nullptr) {
qWarning() << "Invalid shader package!";
}
}
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(),
systemKeys.size(),
sceneKeys.data(),
sceneKeys.size(),
materialKeys.data(),
materialKeys.size(),
subviewKeys.data(),
subviewKeys.size());
const physis_SHPKNode node = physis_shpk_get_node(&renderModel->shpk, selector);
std::vector<uint32_t> systemKeys;
std::vector<uint32_t> sceneKeys = {
physis_shpk_crc("TransformViewSkin"),
physis_shpk_crc("GetAmbientLight_SH"),
physis_shpk_crc("GetReflectColor_Texture"),
physis_shpk_crc("GetAmbientOcclusion_None"),
physis_shpk_crc("ApplyDitherClipOff"),
};
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
if (node.pass_count == 0) {
continue;
}
const u_int32_t selector = physis_shpk_build_selector_from_all_keys(systemKeys.data(),
systemKeys.size(),
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.
const int passIndice = node.pass_indices[i];
if (passIndice != INVALID_PASS) {
const Pass currentPass = node.passes[passIndice];
// check if invalid
if (node.pass_count == 0) {
continue;
}
const uint32_t vertexShaderIndice = currentPass.vertex_shader;
const uint32_t pixelShaderIndice = currentPass.pixel_shader;
// this is an index into the node's pass array, not to get confused with the global one we always follow.
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];
physis_Shader pixelShader = renderModel->shpk.pixel_shaders[pixelShaderIndice];
const uint32_t vertexShaderIndice = currentPass.vertex_shader;
const uint32_t pixelShaderIndice = currentPass.pixel_shader;
auto &pipeline = bindPipeline(commandBuffer, pass, vertexShader, pixelShader);
bindDescriptorSets(commandBuffer, pipeline, &renderModel.value());
physis_Shader vertexShader = renderMaterial.shaderPackage.vertex_shaders[vertexShaderIndice];
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};
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &part.vertexBuffer.buffer, offsets);
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());
}
VkDescriptorSet GameRenderer::createDescriptorFor(const RenderModel *object, const CachedPipeline &pipeline, int i)
VkDescriptorSet GameRenderer::createDescriptorFor(const DrawObject *object, const CachedPipeline &pipeline, int i)
{
VkDescriptorSet set;
@ -995,7 +981,7 @@ VkDescriptorSet GameRenderer::createDescriptorFor(const RenderModel *object, con
useUniformBuffer(g_CameraParameter);
} else if (strcmp(name, "g_JointMatrixArray") == 0) {
Q_ASSERT(object != nullptr);
useUniformBuffer(object->internal_model->boneInfoBuffer);
useUniformBuffer(object->boneInfoBuffer);
} else if (strcmp(name, "g_InstanceParameter") == 0) {
useUniformBuffer(g_InstanceParameter);
} else if (strcmp(name, "g_ModelParameter") == 0) {
@ -1072,7 +1058,7 @@ Texture &GameRenderer::getCompositeTexture()
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;
for (auto setLayout : pipeline.setLayouts) {

View file

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

View file

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