Use GE::GERenderInfo to draw ghost kart and ctf flag in vulkan

This commit is contained in:
Benau 2022-09-06 15:46:05 +08:00
parent 885e08c559
commit 4207714352
15 changed files with 109 additions and 63 deletions

View File

@ -2,6 +2,7 @@
#include "ge_culling_tool.hpp"
#include "ge_main.hpp"
#include "ge_render_info.hpp"
#include "ge_spm.hpp"
#include "ge_spm_buffer.hpp"
#include "ge_vulkan_animated_mesh_scene_node.hpp"
@ -302,6 +303,9 @@ std::string GEVulkanDrawCall::getShader(irr::scene::ISceneNode* node,
int material_id)
{
irr::video::SMaterial& m = node->getMaterial(material_id);
auto& ri = m.getRenderInfo();
if (ri && ri->isTransparent())
return "ghost";
switch (m.MaterialType)
{
case irr::video::EMT_TRANSPARENT_ADD_COLOR: return "additive";
@ -309,7 +313,6 @@ std::string GEVulkanDrawCall::getShader(irr::scene::ISceneNode* node,
case irr::video::EMT_ONETEXTURE_BLEND: return "alphablend";
case irr::video::EMT_SOLID_2_LAYER: return "decal";
case irr::video::EMT_STK_GRASS: return "grass";
case irr::video::EMT_STK_GHOST: return "ghost";
default: return "solid";
}
} // getShader

View File

@ -195,9 +195,6 @@ namespace video
//! Alphatest material for grass without using vertex color in stk. */
EMT_STK_GRASS,
//! Render objects like ghost in stk (used by ghost karts for now). */
EMT_STK_GHOST,
//! This value is not used. It only forces this enumeration to compile to 32 bit.
EMT_FORCE_32BIT = 0x7fffffff
};

View File

@ -18,6 +18,12 @@
#include "irrList.h"
#include "IAttributes.h"
#include <memory>
namespace GE
{
class GERenderInfo;
}
namespace irr
{
namespace scene
@ -786,6 +792,7 @@ namespace scene
bool getUpdatedAbsTrans() const { return UpdatedAbsTrans; }
void setNeedsUpdateAbsTrans(bool val) { NeedsUpdateAbsTrans = val; }
void setUpdatedAbsTrans(bool val) { UpdatedAbsTrans = val; }
virtual void resetFirstRenderInfo(std::shared_ptr<GE::GERenderInfo> ri) {}
protected:

View File

@ -13,6 +13,12 @@
#include "EMaterialFlags.h"
#include "SMaterialLayer.h"
#include <memory>
namespace GE
{
class GERenderInfo;
}
namespace irr
{
namespace video
@ -236,7 +242,7 @@ namespace video
PolygonOffsetFactor(0), PolygonOffsetDirection(EPO_FRONT),
Wireframe(false), PointCloud(false), GouraudShading(true),
Lighting(true), ZWriteEnable(true), BackfaceCulling(true), FrontfaceCulling(false),
FogEnable(false), NormalizeNormals(false), UseMipMaps(true)
FogEnable(false), NormalizeNormals(false), UseMipMaps(true), m_colorizable(false)
{ }
//! Copy constructor
@ -289,6 +295,8 @@ namespace video
PolygonOffsetFactor = other.PolygonOffsetFactor;
PolygonOffsetDirection = other.PolygonOffsetDirection;
UseMipMaps = other.UseMipMaps;
m_colorizable = other.m_colorizable;
m_render_info = other.m_render_info;
return *this;
}
@ -438,6 +446,30 @@ namespace video
/** Sometimes, disabling mipmap usage can be useful. Default: true */
bool UseMipMaps:1;
bool m_colorizable:1;
std::shared_ptr<GE::GERenderInfo> m_render_info;
bool isColorizable() const
{
return m_colorizable;
}
void setColorizable(bool val)
{
m_colorizable = val;
}
std::shared_ptr<GE::GERenderInfo>& getRenderInfo()
{
return m_render_info;
}
void setRenderInfo(std::shared_ptr<GE::GERenderInfo> ri)
{
m_render_info = ri;
}
//! Gets the texture transformation matrix for level i
/** \param i The desired level. Must not be larger than MATERIAL_MAX_TEXTURES.
\return Texture matrix for texture level i. */
@ -655,7 +687,9 @@ namespace video
BlendOperation != b.BlendOperation ||
PolygonOffsetFactor != b.PolygonOffsetFactor ||
PolygonOffsetDirection != b.PolygonOffsetDirection ||
UseMipMaps != b.UseMipMaps;
UseMipMaps != b.UseMipMaps ||
m_colorizable != b.m_colorizable ||
m_render_info != b.m_render_info;
for (u32 i=0; (i<MATERIAL_MAX_TEXTURES) && !different; ++i)
{
different |= (TextureLayer[i] != b.TextureLayer[i]);

View File

@ -17,6 +17,7 @@
#include "quaternion.h"
#include "IFileSystem.h"
#include <ge_render_info.hpp>
namespace irr
{
@ -784,6 +785,8 @@ void CAnimatedMeshSceneNode::setMesh(IAnimatedMesh* mesh)
// get start and begin time
// setAnimationSpeed(Mesh->getAnimationSpeed());
setFrameLoop(0, Mesh->getFrameCount());
if (m_first_render_info)
resetFirstRenderInfo(m_first_render_info);
}
//! updates the absolute position based on the relative and the parents position
@ -1065,6 +1068,17 @@ s32 CAnimatedMeshSceneNode::getAnimationSet() const
return -1;
}
void CAnimatedMeshSceneNode::resetFirstRenderInfo(std::shared_ptr<GE::GERenderInfo> ri)
{
m_first_render_info = ri;
for (u32 i = 0; i < Materials.size(); i++)
Materials[i].setRenderInfo(nullptr);
for (u32 i = 0; i < Materials.size(); i++)
{
if (Materials[i].isColorizable() || (ri && ri->isTransparent()))
Materials[i].setRenderInfo(ri);
}
}
} // end namespace scene
} // end namespace irr

View File

@ -10,6 +10,11 @@
#include "matrix4.h"
#include <memory>
namespace GE
{
class GERenderInfo;
}
namespace irr
{
@ -21,6 +26,7 @@ namespace scene
{
private:
core::array<u32> m_animation_set;
std::shared_ptr<GE::GERenderInfo> m_first_render_info;
public:
//! constructor
@ -171,6 +177,7 @@ namespace scene
virtual void useAnimationSet(u32 set_num);
virtual void setFrameLoopOnce(s32 begin, s32 end);
virtual core::array<u32>& getAnimationSetFrames() { return m_animation_set; }
virtual void resetFirstRenderInfo(std::shared_ptr<GE::GERenderInfo> ri);
protected:
//! Get a static mesh for the current frame of this animated mesh

View File

@ -12,6 +12,8 @@
#include "IMaterialRenderer.h"
#include "IFileSystem.h"
#include <ge_render_info.hpp>
namespace irr
{
namespace scene
@ -278,6 +280,8 @@ void CMeshSceneNode::setMesh(IMesh* mesh)
Mesh = mesh;
copyMaterials();
if (m_first_render_info)
resetFirstRenderInfo(m_first_render_info);
}
}
@ -408,6 +412,19 @@ ISceneNode* CMeshSceneNode::clone(ISceneNode* newParent, ISceneManager* newManag
}
void CMeshSceneNode::resetFirstRenderInfo(std::shared_ptr<GE::GERenderInfo> ri)
{
m_first_render_info = ri;
for (u32 i = 0; i < Materials.size(); i++)
Materials[i].setRenderInfo(nullptr);
for (u32 i = 0; i < Materials.size(); i++)
{
if (Materials[i].isColorizable() || (ri && ri->isTransparent()))
Materials[i].setRenderInfo(ri);
}
}
} // end namespace scene
} // end namespace irr

View File

@ -8,6 +8,12 @@
#include "IMeshSceneNode.h"
#include "IMesh.h"
#include <memory>
namespace GE
{
class GERenderInfo;
}
namespace irr
{
namespace scene
@ -15,8 +21,9 @@ namespace scene
class CMeshSceneNode : public IMeshSceneNode
{
private:
std::shared_ptr<GE::GERenderInfo> m_first_render_info;
public:
//! constructor
CMeshSceneNode(IMesh* mesh, ISceneNode* parent, ISceneManager* mgr, s32 id,
const core::vector3df& position = core::vector3df(0,0,0),
@ -76,6 +83,7 @@ namespace scene
//! or to remove attached childs.
virtual bool removeChild(ISceneNode* child);
virtual void resetFirstRenderInfo(std::shared_ptr<GE::GERenderInfo> ri);
protected:
void copyMaterials();

View File

@ -1405,7 +1405,11 @@ scene::ISceneNode *IrrDriver::addMesh(scene::IMesh *mesh,
return m_scene_manager->addMeshSceneNode(mesh, parent);
#else
if (!CVS->isGLSL())
return m_scene_manager->addMeshSceneNode(mesh, parent);
{
scene::ISceneNode* node = m_scene_manager->addMeshSceneNode(mesh, parent);
node->resetFirstRenderInfo(render_info);
return node;
}
if (!parent)
parent = m_scene_manager->getRootSceneNode();
@ -1642,6 +1646,7 @@ scene::IAnimatedMeshSceneNode *IrrDriver::addAnimatedMesh(scene::IAnimatedMesh *
core::vector3df(0, 0, 0),
core::vector3df(1, 1, 1),
/*addIfMeshIsZero*/true);
node->resetFirstRenderInfo(render_info);
}
return node;

View File

@ -785,6 +785,7 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
m_texname.c_str());
}
m->setColorizable(m_colorizable);
bool is_vk = irr_driver->getVideoDriver()->getDriverType() == EDT_VULKAN;
// Default solid
m->MaterialType = video::EMT_SOLID;

View File

@ -140,7 +140,7 @@ public:
return NULL;
}
// ------------------------------------------------------------------------
void resetFirstRenderInfo(std::shared_ptr<GE::GERenderInfo> ri)
virtual void resetFirstRenderInfo(std::shared_ptr<GE::GERenderInfo> ri)
{
m_render_info.clear();
m_first_render_info = ri;

View File

@ -22,8 +22,6 @@
#include "karts/controller/ghost_controller.hpp"
#include "karts/kart_gfx.hpp"
#include "karts/kart_model.hpp"
#include "graphics/irr_driver.hpp"
#include <ge_render_info.hpp>
#include "modes/easter_egg_hunt.hpp"
#include "modes/linear_world.hpp"
#include "modes/world.hpp"
@ -32,6 +30,8 @@
#include "LinearMath/btQuaternion.h"
#include <ge_render_info.hpp>
GhostKart::GhostKart(const std::string& ident, unsigned int world_kart_id,
int position, float color_hue,
const ReplayPlay::ReplayData& rd)
@ -39,14 +39,13 @@ GhostKart::GhostKart(const std::string& ident, unsigned int world_kart_id,
position, btTransform(btQuaternion(0, 0, 0, 1)),
HANDICAP_NONE,
std::make_shared<GE::GERenderInfo>(color_hue, true/*transparent*/)),
m_replay_data(rd)
m_replay_data(rd), m_last_egg_idx(0)
{
} // GhostKart
// ----------------------------------------------------------------------------
void GhostKart::reset()
{
m_current_attachment = -1;
m_graphical_y_offset = 0;
m_node->setVisible(true);
Kart::reset();
@ -83,44 +82,6 @@ void GhostKart::addReplayEvent(float time,
} // addReplayEvent
// ----------------------------------------------------------------------------
void GhostKart::setGhostKartMaterial()
{
if (irr_driver->getVideoDriver()->getDriverType() != video::EDT_VULKAN ||
m_current_attachment == (int)m_attachment->getType())
return;
m_current_attachment = (int)m_attachment->getType();
std::function<void(core::array<scene::ISceneNode*>&)> set_ghost =
[&](core::array<scene::ISceneNode*>& child)
{
for (unsigned i = 0; i < child.size(); i++)
{
scene::ISceneNode* node = child[i];
if (node->getType() != irr::scene::ESNT_ANIMATED_MESH &&
node->getType() != irr::scene::ESNT_MESH)
continue;
if (node->getType() == scene::ESNT_ANIMATED_MESH)
{
scene::IAnimatedMeshSceneNode* anode = static_cast<
scene::IAnimatedMeshSceneNode*>(node);
anode->setReadOnlyMaterials(false);
for (unsigned j = 0; j < anode->getJointCount(); j++)
set_ghost(anode->getJointNode(j)->getChildren());
}
else if (node->getType() == scene::ESNT_MESH)
{
static_cast<scene::IMeshSceneNode*>(node)
->setReadOnlyMaterials(false);
}
for (unsigned j = 0; j < node->getMaterialCount(); j++)
node->getMaterial(j).MaterialType = video::EMT_STK_GHOST;
set_ghost(node->getChildren());
}
};
set_ghost(m_node->getChildren());
} // setGhostKartMaterial
// ----------------------------------------------------------------------------
/** Called once per rendered frame. It is used to only update any graphical
* effects.
@ -137,7 +98,6 @@ void GhostKart::updateGraphics(float dt)
Moveable::updateGraphics(center_shift, btQuaternion(0, 0, 0, 1));
// Also update attachment's graphics
m_attachment->updateGraphics(dt);
setGhostKartMaterial();
} // updateGraphics
// ----------------------------------------------------------------------------

View File

@ -48,14 +48,11 @@ private:
ReplayPlay::ReplayData m_replay_data;
unsigned int m_last_egg_idx = 0;
unsigned int m_last_egg_idx;
int m_current_attachment;
// ----------------------------------------------------------------------------
/** Compute the time at which the ghost finished the race */
void computeFinishTime();
// ----------------------------------------------------------------------------
void setGhostKartMaterial();
public:
GhostKart(const std::string& ident, unsigned int world_kart_id,
int position, float color_hue,

View File

@ -452,7 +452,6 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models, bool human_playe
m_wheel_graphics_radius[i] = 0.5f*(wheel_max.getY() - wheel_min.getY());
m_wheel_node[i]->grab();
((scene::IMeshSceneNode *) m_wheel_node[i])->setReadOnlyMaterials(true);
#ifdef DEBUG
std::string debug_name = m_wheel_filename[i]+" (wheel)";
m_wheel_node[i]->setName(debug_name.c_str());

View File

@ -17,8 +17,6 @@
#include "modes/ctf_flag.hpp"
#include "graphics/irr_driver.hpp"
#include <ge_render_info.hpp>
#include "graphics/sp/sp_mesh_node.hpp"
#include "karts/abstract_kart.hpp"
#include "modes/world.hpp"
#include "network/network_string.hpp"
@ -26,6 +24,8 @@
#include "LinearMath/btQuaternion.h"
#include <ge_render_info.hpp>
// ============================================================================
// Position offset to attach in kart model
const Vec3 g_kart_flag_offset(0.0, 0.2f, -0.5f);
@ -144,11 +144,8 @@ void CTFFlag::updateFlagGraphics(irr::scene::IAnimatedMeshSceneNode* flag_node)
// ----------------------------------------------------------------------------
void CTFFlag::initFlagRenderInfo(irr::scene::IAnimatedMeshSceneNode* flag_node)
{
SP::SPMeshNode* spmn = dynamic_cast<SP::SPMeshNode*>(flag_node);
if (!spmn)
return;
m_flag_render_info = std::make_shared<GE::GERenderInfo>(0.0f, true);
spmn->resetFirstRenderInfo(m_flag_render_info);
flag_node->resetFirstRenderInfo(m_flag_render_info);
} // initFlagRenderInfo
// ----------------------------------------------------------------------------