Add shadow rendering for legacy video drivers
This commit is contained in:
parent
58223928d8
commit
86391e8b8e
@ -19,6 +19,9 @@
|
||||
#include "graphics/shadow.hpp"
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "karts/skidding.hpp"
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
#include "graphics/sp/sp_shader_manager.hpp"
|
||||
#include "graphics/sp/sp_dynamic_draw_call.hpp"
|
||||
#include "physics/btKart.hpp"
|
||||
@ -27,8 +30,14 @@
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
|
||||
#include <array>
|
||||
#include <SMesh.h>
|
||||
#include <SMeshBuffer.h>
|
||||
|
||||
Shadow::Shadow(Material* shadow_mat, const AbstractKart& kart)
|
||||
: m_dy_dc(NULL), m_shadow_enabled(false), m_kart(kart)
|
||||
: m_node(NULL), m_shadow_enabled(false), m_kart(kart)
|
||||
{
|
||||
if (CVS->isGLSL())
|
||||
{
|
||||
m_dy_dc = std::make_shared<SP::SPDynamicDrawCall>
|
||||
(scene::EPT_TRIANGLE_STRIP,
|
||||
@ -47,12 +56,41 @@ Shadow::Shadow(Material* shadow_mat, const AbstractKart& kart)
|
||||
|
||||
m_dy_dc->setVisible(false);
|
||||
SP::addDynamicDrawCall(m_dy_dc);
|
||||
}
|
||||
else
|
||||
{
|
||||
video::S3DVertex v;
|
||||
v.Color = (video::SColor)-1;
|
||||
std::array<video::S3DVertex, 4> vertices = {{ v, v, v, v }};
|
||||
std::array<uint16_t, 6> indices = {{ 0, 1, 2, 0, 2, 3 }};
|
||||
scene::SMeshBuffer* buffer = new scene::SMeshBuffer();
|
||||
buffer->append(vertices.data(), vertices.size(), indices.data(),
|
||||
indices.size());
|
||||
buffer->getTCoords(0) = core::vector2df(0.0f, 0.0f);
|
||||
buffer->getTCoords(1) = core::vector2df(1.0f, 0.0f);
|
||||
buffer->getTCoords(2) = core::vector2df(1.0f, 1.0f);
|
||||
buffer->getTCoords(3) = core::vector2df(0.0f, 1.0f);
|
||||
shadow_mat->setMaterialProperties(&buffer->getMaterial(), buffer);
|
||||
buffer->getMaterial().setTexture(0, shadow_mat->getTexture());
|
||||
buffer->setHardwareMappingHint(scene::EHM_STREAM);
|
||||
scene::SMesh* mesh = new scene::SMesh();
|
||||
mesh->addMeshBuffer(buffer);
|
||||
mesh->setBoundingBox(buffer->getBoundingBox());
|
||||
buffer->drop();
|
||||
std::string debug_name = m_kart.getIdent() + " (shadow)";
|
||||
m_node = static_cast<scene::IMeshSceneNode*>(
|
||||
irr_driver->addMesh(mesh, debug_name));
|
||||
mesh->drop();
|
||||
}
|
||||
} // Shadow
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
Shadow::~Shadow()
|
||||
{
|
||||
if (m_dy_dc)
|
||||
m_dy_dc->removeFromSP();
|
||||
else if (m_node)
|
||||
irr_driver->removeNode(m_node);
|
||||
} // ~Shadow
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -68,14 +106,20 @@ void Shadow::update(bool enabled)
|
||||
m_shadow_enabled = enabled;
|
||||
if (m_shadow_enabled)
|
||||
{
|
||||
if (m_dy_dc)
|
||||
m_dy_dc->setVisible(true);
|
||||
else if (m_node)
|
||||
m_node->setVisible(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_dy_dc)
|
||||
m_dy_dc->setVisible(false);
|
||||
else if (m_node)
|
||||
m_node->setVisible(false);
|
||||
}
|
||||
}
|
||||
if (m_shadow_enabled)
|
||||
if (m_shadow_enabled && m_dy_dc)
|
||||
{
|
||||
video::S3DVertexSkinnedMesh* v = m_dy_dc->getVerticesVector().data();
|
||||
v[0].m_position.X = -1; v[0].m_position.Z = 1; v[0].m_position.Y = 0;
|
||||
@ -101,6 +145,34 @@ void Shadow::update(bool enabled)
|
||||
m_dy_dc->recalculateBoundingBox();
|
||||
m_dy_dc->setUpdateOffset(0);
|
||||
}
|
||||
else if (m_shadow_enabled && m_node)
|
||||
{
|
||||
Vec3 position[4];
|
||||
position[0] = Vec3(-1.0f, 0.0f, 1.0f);
|
||||
position[1] = Vec3( 1.0f, 0.0f, 1.0f);
|
||||
position[2] = Vec3( 1.0f, 0.0f, -1.0f);
|
||||
position[3] = Vec3(-1.0f, 0.0f, -1.0f);
|
||||
btTransform kart_trans = m_kart.getSmoothedTrans();
|
||||
btTransform skidding_rotation;
|
||||
skidding_rotation.setOrigin(Vec3(0, 0, 0));
|
||||
skidding_rotation.setRotation
|
||||
(btQuaternion(m_kart.getSkidding()->getVisualSkidRotation(), 0, 0));
|
||||
kart_trans *= skidding_rotation;
|
||||
scene::IMesh* mesh = m_node->getMesh();
|
||||
scene::IMeshBuffer* buffer = mesh->getMeshBuffer(0);
|
||||
for (unsigned i = 0; i < 4; i++)
|
||||
{
|
||||
const btWheelInfo& wi = m_kart.getVehicle()->getWheelInfo(i);
|
||||
Vec3 up_vector = kart_trans.getBasis().getColumn(1);
|
||||
up_vector = up_vector * (wi.m_raycastInfo.m_suspensionLength - 0.02f);
|
||||
Vec3 pos = kart_trans(position[i]) - up_vector;
|
||||
buffer->getPosition(i) = pos.toIrrVector();
|
||||
buffer->getNormal(i) = Vec3(wi.m_raycastInfo.m_contactNormalWS)
|
||||
.toIrrVector();
|
||||
}
|
||||
buffer->recalculateBoundingBox();
|
||||
mesh->setBoundingBox(buffer->getBoundingBox());
|
||||
}
|
||||
} // update
|
||||
|
||||
#endif
|
||||
|
@ -30,6 +30,14 @@ namespace SP
|
||||
class SPDynamicDrawCall;
|
||||
}
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene
|
||||
{
|
||||
class IMeshSceneNode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief This class is used to enable a shadow for a kart.
|
||||
* For now it uses a simple texture to simulate the shadow, real time shadows might
|
||||
@ -42,6 +50,8 @@ private:
|
||||
/** The dynamic draw call of the shadow. */
|
||||
std::shared_ptr<SP::SPDynamicDrawCall> m_dy_dc;
|
||||
|
||||
irr::scene::IMeshSceneNode* m_node;
|
||||
|
||||
/** If a kart is flying, the shadow is disabled (since it is
|
||||
* stuck to the kart, i.e. the shadow would be flying, too). */
|
||||
bool m_shadow_enabled;
|
||||
|
@ -3012,7 +3012,7 @@ void Kart::loadData(RaceManager::KartType type, bool is_animated_model)
|
||||
}
|
||||
|
||||
if (!GUIEngine::isNoGraphics() &&
|
||||
CVS->isGLSL() && !CVS->isShadowEnabled() && m_kart_properties
|
||||
(!CVS->isGLSL() || !CVS->isShadowEnabled()) && m_kart_properties
|
||||
->getShadowMaterial()->getSamplerPath(0) != "unicolor_white")
|
||||
{
|
||||
m_shadow.reset(new Shadow(m_kart_properties->getShadowMaterial(),
|
||||
|
Loading…
Reference in New Issue
Block a user