mirror of
https://github.com/redstrate/Novus.git
synced 2025-05-16 05:17:45 +00:00
Begin loading BG objects from the LGB
It "works" but it's too slow to actually all of them and takes way too much memory.
This commit is contained in:
parent
58425c1ae0
commit
75a094134a
16 changed files with 182 additions and 104 deletions
|
@ -12,6 +12,7 @@ class AppState : public QObject
|
|||
public:
|
||||
explicit AppState(QObject *parent = nullptr);
|
||||
|
||||
QString basePath;
|
||||
std::vector<std::pair<QString, physis_LayerGroup>> lgbFiles;
|
||||
|
||||
Q_SIGNALS:
|
||||
|
|
|
@ -27,6 +27,7 @@ public Q_SLOTS:
|
|||
private:
|
||||
MDLPart *mdlPart = nullptr;
|
||||
|
||||
GameData *data;
|
||||
FileCache &cache;
|
||||
GameData *m_data;
|
||||
FileCache &m_cache;
|
||||
AppState *m_appState;
|
||||
};
|
||||
|
|
|
@ -74,14 +74,8 @@ void MainWindow::setupActions()
|
|||
void MainWindow::openMap(const QString &basePath)
|
||||
{
|
||||
QString base2Path = basePath.left(basePath.lastIndexOf(QStringLiteral("/level/")));
|
||||
QString bgPath = QStringLiteral("bg/%1/bgplate/").arg(base2Path);
|
||||
|
||||
std::string bgPathStd = bgPath.toStdString() + "terrain.tera";
|
||||
|
||||
auto tera_buffer = physis_gamedata_extract_file(data, bgPathStd.c_str());
|
||||
|
||||
auto tera = physis_parse_tera(tera_buffer);
|
||||
mapView->addTerrain(bgPath, tera);
|
||||
m_appState->basePath = basePath;
|
||||
|
||||
setWindowTitle(basePath);
|
||||
|
||||
|
|
|
@ -6,13 +6,15 @@
|
|||
#include <QThreadPool>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "appstate.h"
|
||||
#include "filecache.h"
|
||||
#include "objectpass.h"
|
||||
|
||||
MapView::MapView(GameData *data, FileCache &cache, AppState *appState, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, data(data)
|
||||
, cache(cache)
|
||||
, m_data(data)
|
||||
, m_cache(cache)
|
||||
, m_appState(appState)
|
||||
{
|
||||
mdlPart = new MDLPart(data, cache);
|
||||
mdlPart->enableFreemode();
|
||||
|
@ -24,6 +26,71 @@ MapView::MapView(GameData *data, FileCache &cache, AppState *appState, QWidget *
|
|||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->addWidget(mdlPart);
|
||||
setLayout(layout);
|
||||
|
||||
connect(appState, &AppState::mapLoaded, this, [this] {
|
||||
mdlPart->clear();
|
||||
|
||||
QString base2Path = m_appState->basePath.left(m_appState->basePath.lastIndexOf(QStringLiteral("/level/")));
|
||||
QString bgPath = QStringLiteral("bg/%1/bgplate/").arg(base2Path);
|
||||
|
||||
std::string bgPathStd = bgPath.toStdString() + "terrain.tera";
|
||||
|
||||
auto tera_buffer = physis_gamedata_extract_file(m_data, bgPathStd.c_str());
|
||||
|
||||
auto tera = physis_parse_tera(tera_buffer);
|
||||
addTerrain(bgPath, tera);
|
||||
|
||||
// add bg models
|
||||
for (const auto &[name, lgb] : m_appState->lgbFiles) {
|
||||
// only load the bg models for now
|
||||
if (name != QStringLiteral("bg")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < lgb.num_chunks; i++) {
|
||||
const auto chunk = lgb.chunks[i];
|
||||
for (int j = 0; j < chunk.num_layers; j++) {
|
||||
const auto layer = chunk.layers[j];
|
||||
for (int z = 0; z < layer.num_objects; z++) {
|
||||
const auto object = layer.objects[z];
|
||||
|
||||
switch (object.data.tag) {
|
||||
case physis_LayerEntry::Tag::BG: {
|
||||
std::string assetPath = object.data.bg._0.asset_path;
|
||||
if (!assetPath.empty()) {
|
||||
auto plateMdlFile = physis_gamedata_extract_file(m_data, assetPath.c_str());
|
||||
if (plateMdlFile.size == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto plateMdl = physis_mdl_parse(plateMdlFile);
|
||||
if (plateMdl.p_ptr != nullptr) {
|
||||
std::vector<physis_Material> materials;
|
||||
for (uint32_t j = 0; j < plateMdl.num_material_names; j++) {
|
||||
const char *material_name = plateMdl.material_names[j];
|
||||
|
||||
auto mat = physis_material_parse(m_cache.lookupFile(QLatin1String(material_name)));
|
||||
materials.push_back(mat);
|
||||
}
|
||||
|
||||
mdlPart->addModel(
|
||||
plateMdl,
|
||||
false,
|
||||
glm::vec3(object.transform.translation[0], object.transform.translation[1], object.transform.translation[2]),
|
||||
QString::fromStdString(assetPath),
|
||||
materials,
|
||||
0);
|
||||
|
||||
numLoadedBgModels++;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
MDLPart &MapView::part() const
|
||||
|
@ -33,20 +100,18 @@ MDLPart &MapView::part() const
|
|||
|
||||
void MapView::addTerrain(QString basePath, physis_Terrain terrain)
|
||||
{
|
||||
mdlPart->clear();
|
||||
|
||||
for (int i = 0; i < terrain.num_plates; i++) {
|
||||
QString mdlPath = QStringLiteral("%1%2").arg(basePath, QString::fromStdString(terrain.plates[i].filename));
|
||||
std::string mdlPathStd = mdlPath.toStdString();
|
||||
|
||||
auto plateMdlFile = physis_gamedata_extract_file(data, mdlPathStd.c_str());
|
||||
auto plateMdlFile = physis_gamedata_extract_file(m_data, mdlPathStd.c_str());
|
||||
auto plateMdl = physis_mdl_parse(plateMdlFile);
|
||||
if (plateMdl.p_ptr != nullptr) {
|
||||
std::vector<physis_Material> materials;
|
||||
for (uint32_t j = 0; j < plateMdl.num_material_names; j++) {
|
||||
const char *material_name = plateMdl.material_names[j];
|
||||
|
||||
auto mat = physis_material_parse(cache.lookupFile(QLatin1String(material_name)));
|
||||
auto mat = physis_material_parse(m_cache.lookupFile(QLatin1String(material_name)));
|
||||
materials.push_back(mat);
|
||||
}
|
||||
|
||||
|
|
2
extern/libphysis
vendored
2
extern/libphysis
vendored
|
@ -1 +1 @@
|
|||
Subproject commit f0b53912ef8ef9361aaede623ae0a38d1bd833bb
|
||||
Subproject commit 5946c315e39f6909b71787bc344ba0d879479d73
|
|
@ -50,25 +50,25 @@ MDLPart::MDLPart(GameData *data, FileCache &cache, QWidget *parent)
|
|||
|
||||
void MDLPart::exportModel(const QString &fileName)
|
||||
{
|
||||
auto &model = models[0];
|
||||
::exportModel(model.name, model.model, *skeleton, boneData, fileName);
|
||||
auto &model = vkWindow->models[0];
|
||||
::exportModel(model.name, model.sourceObject->model, *skeleton, boneData, fileName);
|
||||
}
|
||||
|
||||
DrawObject &MDLPart::getModel(const int index)
|
||||
{
|
||||
return models[index];
|
||||
return *vkWindow->models[index].sourceObject;
|
||||
}
|
||||
|
||||
void MDLPart::reloadModel(const int index)
|
||||
{
|
||||
renderer->reloadDrawObject(models[index], 0);
|
||||
renderer->reloadDrawObject(*vkWindow->models[index].sourceObject, 0);
|
||||
|
||||
Q_EMIT modelChanged();
|
||||
}
|
||||
|
||||
void MDLPart::clear()
|
||||
{
|
||||
models.clear();
|
||||
vkWindow->models.clear();
|
||||
|
||||
Q_EMIT modelChanged();
|
||||
}
|
||||
|
@ -82,24 +82,27 @@ void MDLPart::addModel(physis_MDL mdl,
|
|||
uint16_t fromBodyId,
|
||||
uint16_t toBodyId)
|
||||
{
|
||||
qDebug() << "Adding model to MDLPart";
|
||||
DrawObject *model;
|
||||
if (vkWindow->sourceModels.contains(name)) {
|
||||
model = vkWindow->sourceModels[name];
|
||||
} else {
|
||||
model = renderer->addDrawObject(mdl, lod);
|
||||
model->from_body_id = fromBodyId;
|
||||
model->to_body_id = toBodyId;
|
||||
model->skinned = skinned;
|
||||
|
||||
auto model = renderer->addDrawObject(mdl, lod);
|
||||
model.name = name;
|
||||
model.from_body_id = fromBodyId;
|
||||
model.to_body_id = toBodyId;
|
||||
model.position = position;
|
||||
model.skinned = skinned;
|
||||
std::transform(materials.begin(), materials.end(), std::back_inserter(model->materials), [this](const physis_Material &mat) {
|
||||
return createOrCacheMaterial(mat);
|
||||
});
|
||||
|
||||
std::transform(materials.begin(), materials.end(), std::back_inserter(model.materials), [this](const physis_Material &mat) {
|
||||
return createOrCacheMaterial(mat);
|
||||
});
|
||||
if (materials.empty()) {
|
||||
model->materials.push_back(createOrCacheMaterial(physis_Material{}));
|
||||
}
|
||||
|
||||
if (materials.empty()) {
|
||||
model.materials.push_back(createOrCacheMaterial(physis_Material{}));
|
||||
vkWindow->sourceModels[name] = model;
|
||||
}
|
||||
|
||||
models.push_back(model);
|
||||
vkWindow->models.push_back(DrawObjectInstance{name, model, position});
|
||||
|
||||
Q_EMIT modelChanged();
|
||||
}
|
||||
|
@ -125,8 +128,6 @@ void MDLPart::clearSkeleton()
|
|||
void MDLPart::reloadRenderer()
|
||||
{
|
||||
reloadBoneData();
|
||||
|
||||
vkWindow->models = models;
|
||||
}
|
||||
|
||||
void MDLPart::enableFreemode()
|
||||
|
@ -166,31 +167,32 @@ void MDLPart::reloadBoneData()
|
|||
// update data
|
||||
calculateBone(*skeleton, *skeleton->root_bone, nullptr);
|
||||
|
||||
for (auto &model : models) {
|
||||
// TODO: this applies to all instances
|
||||
for (auto &[_, model] : vkWindow->sourceModels) {
|
||||
// we want to map the actual affected bones to bone ids
|
||||
std::map<int, int> boneMapping;
|
||||
for (uint32_t i = 0; i < model.model.num_affected_bones; i++) {
|
||||
for (uint32_t i = 0; i < model->model.num_affected_bones; i++) {
|
||||
for (uint32_t k = 0; k < skeleton->num_bones; k++) {
|
||||
if (std::string_view{skeleton->bones[k].name} == std::string_view{model.model.affected_bone_names[i]}) {
|
||||
if (std::string_view{skeleton->bones[k].name} == std::string_view{model->model.affected_bone_names[i]}) {
|
||||
boneMapping[i] = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<glm::mat4> deformBones(model.model.num_affected_bones);
|
||||
for (uint32_t i = 0; i < model.model.num_affected_bones; i++) {
|
||||
std::vector<glm::mat4> deformBones(model->model.num_affected_bones);
|
||||
for (uint32_t i = 0; i < model->model.num_affected_bones; i++) {
|
||||
deformBones[i] = glm::mat4(1.0f);
|
||||
}
|
||||
|
||||
// get deform matrices
|
||||
if (enableRacialDeform) {
|
||||
auto deform = physis_pbd_get_deform_matrix(pbd, model.from_body_id, model.to_body_id);
|
||||
auto deform = physis_pbd_get_deform_matrix(pbd, model->from_body_id, model->to_body_id);
|
||||
if (deform.num_bones != 0) {
|
||||
for (int i = 0; i < deform.num_bones; i++) {
|
||||
auto deformBone = deform.bones[i];
|
||||
|
||||
for (uint32_t k = 0; k < model.model.num_affected_bones; k++) {
|
||||
if (std::string_view{model.model.affected_bone_names[k]} == std::string_view{deformBone.name}) {
|
||||
for (uint32_t k = 0; k < model->model.num_affected_bones; k++) {
|
||||
if (std::string_view{model->model.affected_bone_names[k]} == std::string_view{deformBone.name}) {
|
||||
deformBones[k] =
|
||||
glm::rowMajor4(glm::vec4{deformBone.deform[0], deformBone.deform[1], deformBone.deform[2], deformBone.deform[3]},
|
||||
glm::vec4{deformBone.deform[4], deformBone.deform[5], deformBone.deform[6], deformBone.deform[7]},
|
||||
|
@ -202,9 +204,9 @@ void MDLPart::reloadBoneData()
|
|||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < model.model.num_affected_bones; i++) {
|
||||
for (uint32_t i = 0; i < model->model.num_affected_bones; i++) {
|
||||
const int originalBoneId = boneMapping[i];
|
||||
model.boneData[i] = deformBones[i] * boneData[originalBoneId].localTransform * boneData[originalBoneId].inversePose;
|
||||
model->boneData[i] = deformBones[i] * boneData[originalBoneId].localTransform * boneData[originalBoneId].inversePose;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -397,12 +399,14 @@ void MDLPart::calculateBone(physis_Skeleton &skeleton, physis_Bone &bone, const
|
|||
|
||||
void MDLPart::removeModel(const physis_MDL &mdl)
|
||||
{
|
||||
models.erase(std::remove_if(models.begin(),
|
||||
models.end(),
|
||||
// TODO: restore this functionality
|
||||
qWarning() << "MDLPart::removeModel needs to be reimplemented!";
|
||||
/*vkWindow->models.erase(std::remove_if(vkWindow->models.begin(),
|
||||
vkWindow->models.end(),
|
||||
[mdl](const DrawObject &other) {
|
||||
return mdl.p_ptr == other.model.p_ptr;
|
||||
}),
|
||||
models.end());
|
||||
vkWindow->models.end());*/
|
||||
Q_EMIT modelChanged();
|
||||
}
|
||||
|
||||
|
@ -420,7 +424,7 @@ bool MDLPart::wireframe() const
|
|||
|
||||
int MDLPart::numModels() const
|
||||
{
|
||||
return models.size();
|
||||
return vkWindow->models.size();
|
||||
}
|
||||
|
||||
RenderManager *MDLPart::manager() const
|
||||
|
|
|
@ -102,7 +102,6 @@ private:
|
|||
GameData *data = nullptr;
|
||||
FileCache &cache;
|
||||
|
||||
std::vector<DrawObject> models;
|
||||
std::unordered_map<uint64_t, RenderMaterial> renderMaterialCache;
|
||||
|
||||
RenderManager *renderer = nullptr;
|
||||
|
|
|
@ -20,7 +20,8 @@ public:
|
|||
|
||||
void render();
|
||||
|
||||
std::vector<DrawObject> models;
|
||||
std::vector<DrawObjectInstance> models;
|
||||
std::unordered_map<QString, DrawObject *> sourceModels;
|
||||
bool freeMode = false;
|
||||
|
||||
private:
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include <vulkan/vulkan.h>
|
||||
|
||||
class Renderer;
|
||||
struct DrawObject;
|
||||
struct DrawObjectInstance;
|
||||
struct Camera;
|
||||
struct Texture;
|
||||
struct Scene;
|
||||
|
@ -31,7 +31,7 @@ public:
|
|||
virtual void resize() = 0;
|
||||
|
||||
/// Render a frame into @p commandBuffer. @p currentFrame is the same value as SwapChain::currentFrame for convenience.
|
||||
virtual void render(VkCommandBuffer commandBuffer, Camera &camera, Scene &scene, const std::vector<DrawObject> &models) = 0;
|
||||
virtual void render(VkCommandBuffer commandBuffer, Camera &camera, Scene &scene, const std::vector<DrawObjectInstance> &models) = 0;
|
||||
|
||||
/// The final composite texture that is drawn into with render()
|
||||
virtual Texture &getCompositeTexture() = 0;
|
||||
|
|
|
@ -34,13 +34,10 @@ struct RenderMaterial {
|
|||
};
|
||||
|
||||
struct DrawObject {
|
||||
QString name;
|
||||
|
||||
physis_MDL model;
|
||||
std::vector<RenderPart> parts;
|
||||
std::array<glm::mat4, 768> boneData; // JOINT_MATRIX_SIZE_DAWNTRAIL
|
||||
std::vector<RenderMaterial> materials;
|
||||
glm::vec3 position;
|
||||
bool skinned = false;
|
||||
|
||||
uint16_t from_body_id = 101;
|
||||
|
@ -48,3 +45,9 @@ struct DrawObject {
|
|||
|
||||
Buffer boneInfoBuffer;
|
||||
};
|
||||
|
||||
struct DrawObjectInstance {
|
||||
QString name;
|
||||
DrawObject *sourceObject = nullptr;
|
||||
glm::vec3 position;
|
||||
};
|
||||
|
|
|
@ -31,7 +31,7 @@ public:
|
|||
|
||||
void resize() override;
|
||||
|
||||
void render(VkCommandBuffer commandBuffer, Camera &camera, Scene &scene, const std::vector<DrawObject> &models) override;
|
||||
void render(VkCommandBuffer commandBuffer, Camera &camera, Scene &scene, const std::vector<DrawObjectInstance> &models) override;
|
||||
|
||||
Texture &getCompositeTexture() override;
|
||||
|
||||
|
|
|
@ -33,11 +33,11 @@ public:
|
|||
|
||||
void destroySwapchain();
|
||||
|
||||
DrawObject addDrawObject(const physis_MDL &model, int lod);
|
||||
DrawObject *addDrawObject(const physis_MDL &model, int lod);
|
||||
void reloadDrawObject(DrawObject &model, uint32_t lod);
|
||||
Texture addGameTexture(VkFormat format, physis_Texture gameTexture);
|
||||
|
||||
void render(const std::vector<DrawObject> &models);
|
||||
void render(const std::vector<DrawObjectInstance> &models);
|
||||
|
||||
VkRenderPass presentationRenderPass() const;
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ public:
|
|||
|
||||
void resize() override;
|
||||
|
||||
void render(VkCommandBuffer commandBuffer, Camera &camera, Scene &scene, const std::vector<DrawObject> &models) override;
|
||||
void render(VkCommandBuffer commandBuffer, Camera &camera, Scene &scene, const std::vector<DrawObjectInstance> &models) override;
|
||||
|
||||
Texture &getCompositeTexture() override;
|
||||
|
||||
|
|
|
@ -255,7 +255,7 @@ GameRenderer::GameRenderer(Device &device, GameData *data)
|
|||
createImageResources();
|
||||
}
|
||||
|
||||
void GameRenderer::render(VkCommandBuffer commandBuffer, Camera &camera, Scene &scene, const std::vector<DrawObject> &models)
|
||||
void GameRenderer::render(VkCommandBuffer commandBuffer, Camera &camera, Scene &scene, const std::vector<DrawObjectInstance> &models)
|
||||
{
|
||||
Q_UNUSED(scene)
|
||||
|
||||
|
@ -299,29 +299,29 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, Camera &camera, Scene &
|
|||
const int jointMatrixSize = m_dawntrailMode ? JOINT_MATRIX_SIZE_DAWNTRAIL : JOINT_MATRIX_SIZE_ARR;
|
||||
const size_t bufferSize = sizeof(glm::mat3x4) * jointMatrixSize;
|
||||
void *mapped_data = nullptr;
|
||||
vkMapMemory(m_device.device, model.boneInfoBuffer.memory, 0, bufferSize, 0, &mapped_data);
|
||||
vkMapMemory(m_device.device, model.sourceObject->boneInfoBuffer.memory, 0, bufferSize, 0, &mapped_data);
|
||||
|
||||
std::vector<glm::mat3x4> newBoneData(model.boneData.size());
|
||||
std::vector<glm::mat3x4> newBoneData(model.sourceObject->boneData.size());
|
||||
for (int i = 0; i < jointMatrixSize; i++) {
|
||||
newBoneData[i] = glm::transpose(model.boneData[i]);
|
||||
newBoneData[i] = glm::transpose(model.sourceObject->boneData[i]);
|
||||
}
|
||||
|
||||
memcpy(mapped_data, newBoneData.data(), bufferSize);
|
||||
|
||||
VkMappedMemoryRange range = {};
|
||||
range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
|
||||
range.memory = model.boneInfoBuffer.memory;
|
||||
range.memory = model.sourceObject->boneInfoBuffer.memory;
|
||||
range.size = bufferSize;
|
||||
vkFlushMappedMemoryRanges(m_device.device, 1, &range);
|
||||
|
||||
vkUnmapMemory(m_device.device, model.boneInfoBuffer.memory);
|
||||
vkUnmapMemory(m_device.device, model.sourceObject->boneInfoBuffer.memory);
|
||||
}
|
||||
|
||||
for (const auto &part : model.parts) {
|
||||
RenderMaterial renderMaterial = model.materials[part.materialIndex];
|
||||
for (const auto &part : model.sourceObject->parts) {
|
||||
RenderMaterial renderMaterial = model.sourceObject->materials[part.materialIndex];
|
||||
|
||||
if (static_cast<size_t>(part.materialIndex + 1) > model.materials.size()) {
|
||||
renderMaterial = model.materials[0]; // TODO: better fallback
|
||||
if (static_cast<size_t>(part.materialIndex + 1) > model.sourceObject->materials.size()) {
|
||||
renderMaterial = model.sourceObject->materials[0]; // TODO: better fallback
|
||||
}
|
||||
|
||||
if (renderMaterial.shaderPackage.p_ptr == nullptr) {
|
||||
|
@ -341,7 +341,7 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, Camera &camera, Scene &
|
|||
|
||||
bool found = false;
|
||||
if (id == physis_shpk_crc("TransformView")) {
|
||||
if (model.skinned) {
|
||||
if (model.sourceObject->skinned) {
|
||||
sceneKeys.push_back(physis_shpk_crc("TransformViewSkin"));
|
||||
} else {
|
||||
sceneKeys.push_back(physis_shpk_crc("TransformViewRigid"));
|
||||
|
@ -400,9 +400,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, &model.model, &part.originalPart);
|
||||
bindDescriptorSets(commandBuffer, pipeline, &model, &renderMaterial, pass);
|
||||
auto &pipeline = bindPipeline(commandBuffer,
|
||||
pass,
|
||||
vertexShader,
|
||||
pixelShader,
|
||||
renderMaterial.mat.shpk_name,
|
||||
&model.sourceObject->model,
|
||||
&part.originalPart);
|
||||
bindDescriptorSets(commandBuffer, pipeline, model.sourceObject, &renderMaterial, pass);
|
||||
|
||||
VkDeviceSize offsets[] = {0};
|
||||
for (int j = 0; j < part.originalPart.num_streams; j++) {
|
||||
|
@ -541,11 +546,11 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, Camera &camera, Scene &
|
|||
beginPass(commandBuffer, pass);
|
||||
|
||||
for (auto &model : models) {
|
||||
for (const auto &part : model.parts) {
|
||||
RenderMaterial renderMaterial = model.materials[part.materialIndex];
|
||||
for (const auto &part : model.sourceObject->parts) {
|
||||
RenderMaterial renderMaterial = model.sourceObject->materials[part.materialIndex];
|
||||
|
||||
if (static_cast<size_t>(part.materialIndex + 1) > model.materials.size()) {
|
||||
renderMaterial = model.materials[0]; // TODO: better fallback
|
||||
if (static_cast<size_t>(part.materialIndex + 1) > model.sourceObject->materials.size()) {
|
||||
renderMaterial = model.sourceObject->materials[0]; // TODO: better fallback
|
||||
}
|
||||
|
||||
if (renderMaterial.shaderPackage.p_ptr == nullptr) {
|
||||
|
@ -564,7 +569,7 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, Camera &camera, Scene &
|
|||
|
||||
bool found = false;
|
||||
if (id == physis_shpk_crc("TransformView")) {
|
||||
if (model.skinned) {
|
||||
if (model.sourceObject->skinned) {
|
||||
sceneKeys.push_back(physis_shpk_crc("TransformViewSkin"));
|
||||
} else {
|
||||
sceneKeys.push_back(physis_shpk_crc("TransformViewRigid"));
|
||||
|
@ -623,9 +628,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, &model.model, &part.originalPart);
|
||||
bindDescriptorSets(commandBuffer, pipeline, &model, &renderMaterial, pass);
|
||||
auto &pipeline = bindPipeline(commandBuffer,
|
||||
pass,
|
||||
vertexShader,
|
||||
pixelShader,
|
||||
renderMaterial.mat.shpk_name,
|
||||
&model.sourceObject->model,
|
||||
&part.originalPart);
|
||||
bindDescriptorSets(commandBuffer, pipeline, model.sourceObject, &renderMaterial, pass);
|
||||
|
||||
VkDeviceSize offsets[] = {0};
|
||||
for (int j = 0; j < part.originalPart.num_streams; j++) {
|
||||
|
|
|
@ -397,7 +397,7 @@ void RenderManager::destroySwapchain()
|
|||
}
|
||||
}
|
||||
|
||||
void RenderManager::render(const std::vector<DrawObject> &models)
|
||||
void RenderManager::render(const std::vector<DrawObjectInstance> &models)
|
||||
{
|
||||
vkWaitForFences(m_device->device,
|
||||
1,
|
||||
|
@ -509,12 +509,12 @@ VkRenderPass RenderManager::presentationRenderPass() const
|
|||
return m_renderPass;
|
||||
}
|
||||
|
||||
DrawObject RenderManager::addDrawObject(const physis_MDL &model, int lod)
|
||||
DrawObject *RenderManager::addDrawObject(const physis_MDL &model, int lod)
|
||||
{
|
||||
DrawObject DrawObject;
|
||||
DrawObject.model = model;
|
||||
auto DrawObject = new ::DrawObject();
|
||||
DrawObject->model = model;
|
||||
|
||||
reloadDrawObject(DrawObject, lod);
|
||||
reloadDrawObject(*DrawObject, lod);
|
||||
|
||||
return DrawObject;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ void SimpleRenderer::resize()
|
|||
m_device.nameObject(VK_OBJECT_TYPE_FRAMEBUFFER, reinterpret_cast<uint64_t>(m_framebuffer), "simple renderer framebuffer");
|
||||
}
|
||||
|
||||
void SimpleRenderer::render(VkCommandBuffer commandBuffer, Camera &camera, Scene &scene, const std::vector<DrawObject> &models)
|
||||
void SimpleRenderer::render(VkCommandBuffer commandBuffer, Camera &camera, Scene &scene, const std::vector<DrawObjectInstance> &models)
|
||||
{
|
||||
Q_UNUSED(scene)
|
||||
|
||||
|
@ -72,7 +72,7 @@ void SimpleRenderer::render(VkCommandBuffer commandBuffer, Camera &camera, Scene
|
|||
vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
for (const auto &model : models) {
|
||||
if (model.skinned) {
|
||||
if (model.sourceObject->skinned) {
|
||||
if (m_wireframe) {
|
||||
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_skinnedPipelineWireframe);
|
||||
} else {
|
||||
|
@ -90,33 +90,33 @@ void SimpleRenderer::render(VkCommandBuffer commandBuffer, Camera &camera, Scene
|
|||
{
|
||||
const size_t bufferSize = sizeof(glm::mat4) * 128;
|
||||
void *mapped_data = nullptr;
|
||||
vkMapMemory(m_device.device, model.boneInfoBuffer.memory, 0, bufferSize, 0, &mapped_data);
|
||||
vkMapMemory(m_device.device, model.sourceObject->boneInfoBuffer.memory, 0, bufferSize, 0, &mapped_data);
|
||||
|
||||
memcpy(mapped_data, model.boneData.data(), bufferSize);
|
||||
memcpy(mapped_data, model.sourceObject->boneData.data(), bufferSize);
|
||||
|
||||
VkMappedMemoryRange range = {};
|
||||
range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
|
||||
range.memory = model.boneInfoBuffer.memory;
|
||||
range.memory = model.sourceObject->boneInfoBuffer.memory;
|
||||
range.size = bufferSize;
|
||||
vkFlushMappedMemoryRanges(m_device.device, 1, &range);
|
||||
|
||||
vkUnmapMemory(m_device.device, model.boneInfoBuffer.memory);
|
||||
vkUnmapMemory(m_device.device, model.sourceObject->boneInfoBuffer.memory);
|
||||
}
|
||||
|
||||
for (const auto &part : model.parts) {
|
||||
for (const auto &part : model.sourceObject->parts) {
|
||||
RenderMaterial defaultMaterial = {};
|
||||
|
||||
RenderMaterial *material = nullptr;
|
||||
|
||||
if (static_cast<size_t>(part.materialIndex) >= model.materials.size()) {
|
||||
if (static_cast<size_t>(part.materialIndex) >= model.sourceObject->materials.size()) {
|
||||
material = &defaultMaterial;
|
||||
} else {
|
||||
material = const_cast<RenderMaterial *>(&model.materials[part.materialIndex]);
|
||||
material = const_cast<RenderMaterial *>(&model.sourceObject->materials[part.materialIndex]);
|
||||
}
|
||||
|
||||
const auto h = hash(model, *material);
|
||||
const auto h = hash(*model.sourceObject, *material);
|
||||
if (!cachedDescriptors.count(h)) {
|
||||
if (auto descriptor = createDescriptorFor(model, *material); descriptor != VK_NULL_HANDLE) {
|
||||
if (auto descriptor = createDescriptorFor(*model.sourceObject, *material); descriptor != VK_NULL_HANDLE) {
|
||||
cachedDescriptors[h] = descriptor;
|
||||
} else {
|
||||
continue;
|
||||
|
|
Loading…
Add table
Reference in a new issue