Make bubble force fields fade in softly insetad of just popping up

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@10638 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
auria 2012-01-10 23:40:14 +00:00
parent dde12fb6a7
commit c29c91da21
12 changed files with 249 additions and 28 deletions

View File

@ -1,9 +1,11 @@
uniform sampler2D main_texture;
uniform float transparency;
varying vec2 uv;
void main()
{
gl_FragColor = texture2D(main_texture, uv);
gl_FragColor.a *= transparency;
}

View File

@ -55,7 +55,7 @@ BillboardAnimation::BillboardAnimation(const XMLNode &xml_node)
m_node = irr_driver->addBillboard(core::dimension2df(width, height),
texture);
Material *stk_material = material_manager->getMaterial(texture_name);
stk_material->setMaterialProperties(&(m_node->getMaterial(0)));
stk_material->setMaterialProperties(&(m_node->getMaterial(0)), NULL);
m_node->setPosition(m_init_xyz);
} // BillboardAnimation

View File

@ -45,7 +45,7 @@ Explosion::Explosion(const Vec3& coord, const char* explosion_sound)
m_node->setPosition(coord.toIrrVector());
Material* m = material_manager->getMaterial("explode.png");
m_node->setMaterialTexture(0, m->getTexture());
m->setMaterialProperties(&(m_node->getMaterial(0)));
m->setMaterialProperties(&(m_node->getMaterial(0)), NULL);
m_node->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR );
scene::IParticleEmitter* em =

View File

@ -19,10 +19,14 @@
#include "graphics/irr_driver.hpp"
#include "graphics/lod_node.hpp"
#include "graphics/hardware_skinning.hpp"
#include "graphics/material_manager.hpp"
#include "graphics/material.hpp"
#include "config/user_config.hpp"
#include <ISceneManager.h>
#include <ICameraSceneNode.h>
#include <IMeshSceneNode.h>
#include <IAnimatedMeshSceneNode.h>
/**
* @param group_name Only useful for getGroupName()
@ -36,6 +40,8 @@ LODNode::LODNode(std::string group_name, scene::ISceneNode* parent,
m_group_name = group_name;
m_previous_visibility = FIRST_PASS;
// At this stage refcount is two: one because of the object being
// created, and once because it is a child of the parent. Drop once,
// so that only the reference from the parent is active, causing this
@ -64,16 +70,120 @@ void LODNode::OnRegisterSceneNode()
// Assumes all children are at the same location
const int dist =
(int)((getPosition() + m_nodes[0]->getPosition()).getDistanceFromSQ( curr_cam->getPosition() ));
bool shown = false;
for (unsigned int n=0; n<m_detail.size(); n++)
{
if (dist < m_detail[n])
{
m_nodes[n]->OnRegisterSceneNode();
shown = true;
break;
}
}
//printf("m_group_name = %s, m_nodes.size() = %i\n, type is mesh = %i\n", m_group_name.c_str(), (int)m_nodes.size(),
// m_nodes[0]->getType() == scene::ESNT_MESH);
// support an optional, mostly hard-coded fade-in/out effect for objects with a single level
if (m_nodes.size() == 1 && (m_nodes[0]->getType() == scene::ESNT_MESH ||
m_nodes[0]->getType() == scene::ESNT_ANIMATED_MESH))
{
if (m_previous_visibility == WAS_HIDDEN && shown)
{
printf("== Show '%s' ==\n", m_group_name.c_str());
scene::IMesh* mesh;
if (m_nodes[0]->getType() == scene::ESNT_MESH)
{
scene::IMeshSceneNode* node = (scene::IMeshSceneNode*)(m_nodes[0]);
mesh = node->getMesh();
}
else
{
assert(m_nodes[0]->getType() == scene::ESNT_ANIMATED_MESH);
scene::IAnimatedMeshSceneNode* node =
(scene::IAnimatedMeshSceneNode*)(m_nodes[0]);
assert(node != NULL);
mesh = node->getMesh();
}
for (unsigned int n=0; n<mesh->getMeshBufferCount(); n++)
{
scene::IMeshBuffer* mb = mesh->getMeshBuffer(n);
video::ITexture* t = mb->getMaterial().getTexture(0);
Material* m = material_manager->getMaterialFor(t, mb);
if (m != NULL)
{
m->onMadeVisible(mb);
}
}
}
else if (m_previous_visibility == WAS_SHOWN && !shown)
{
printf("== Hide '%s' ==\n", m_group_name.c_str());
scene::IMesh* mesh;
if (m_nodes[0]->getType() == scene::ESNT_MESH)
{
scene::IMeshSceneNode* node = (scene::IMeshSceneNode*)(m_nodes[0]);
mesh = node->getMesh();
}
else
{
assert(m_nodes[0]->getType() == scene::ESNT_ANIMATED_MESH);
scene::IAnimatedMeshSceneNode* node =
(scene::IAnimatedMeshSceneNode*)(m_nodes[0]);
assert(node != NULL);
mesh = node->getMesh();
}
for (unsigned int n=0; n<mesh->getMeshBufferCount(); n++)
{
scene::IMeshBuffer* mb = mesh->getMeshBuffer(n);
video::ITexture* t = mb->getMaterial().getTexture(0);
Material* m = material_manager->getMaterialFor(t, mb);
if (m != NULL)
{
m->onHidden(mb);
}
}
}
else if (m_previous_visibility == FIRST_PASS && !shown)
{
scene::IMesh* mesh;
if (m_nodes[0]->getType() == scene::ESNT_MESH)
{
scene::IMeshSceneNode* node = (scene::IMeshSceneNode*)(m_nodes[0]);
mesh = node->getMesh();
}
else
{
assert(m_nodes[0]->getType() == scene::ESNT_ANIMATED_MESH);
scene::IAnimatedMeshSceneNode* node =
(scene::IAnimatedMeshSceneNode*)(m_nodes[0]);
assert(node != NULL);
mesh = node->getMesh();
}
for (unsigned int n=0; n<mesh->getMeshBufferCount(); n++)
{
scene::IMeshBuffer* mb = mesh->getMeshBuffer(n);
video::ITexture* t = mb->getMaterial().getTexture(0);
Material* m = material_manager->getMaterialFor(t, mb);
if (m != NULL)
{
m->isInitiallyHidden(mb);
}
}
}
}
m_previous_visibility = (shown ? WAS_SHOWN : WAS_HIDDEN);
// If this node has children other than the LOD nodes, draw them
core::list<ISceneNode*>::Iterator it;

View File

@ -55,6 +55,15 @@ private:
std::string m_group_name;
enum PreviousVisibility
{
FIRST_PASS,
WAS_SHOWN,
WAS_HIDDEN
};
PreviousVisibility m_previous_visibility;
public:
LODNode(std::string group_name, scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id=-1);

View File

@ -26,6 +26,7 @@
#include "audio/sfx_buffer.hpp"
#include "config/user_config.hpp"
#include "config/stk_config.hpp"
#include "guiengine/engine.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/particle_kind_manager.hpp"
#include "io/file_manager.hpp"
@ -42,6 +43,7 @@ using namespace irr::video;
const unsigned int UCLAMP = 1;
const unsigned int VCLAMP = 2;
//-----------------------------------------------------------------------------
class NormalMapProvider : public video::IShaderConstantSetCallBack
{
@ -73,6 +75,10 @@ public:
//-----------------------------------------------------------------------------
#if 0
#pragma mark -
#endif
class SplattingProvider : public video::IShaderConstantSetCallBack
{
core::vector3df m_light_direction;
@ -121,10 +127,15 @@ public:
};
//-----------------------------------------------------------------------------
#if 0
#pragma mark -
#endif
class BubbleEffectProvider : public video::IShaderConstantSetCallBack
{
irr::u32 initial_time;
float m_transparency;
bool m_is_visible;
public:
LEAK_CHECK()
@ -132,17 +143,51 @@ public:
BubbleEffectProvider()
{
initial_time = irr_driver->getDevice()->getTimer()->getRealTime();
m_transparency = 1.0f;
m_is_visible = true;
}
virtual void OnSetConstants(
irr::video::IMaterialRendererServices *services,
s32 userData)
{
if (m_is_visible && m_transparency < 1.0f)
{
m_transparency += GUIEngine::getLatestDt()*0.3f;
if (m_transparency > 1.0f) m_transparency = 1.0f;
}
else if (!m_is_visible && m_transparency > 0.0f)
{
m_transparency -= GUIEngine::getLatestDt()*0.3f;
if (m_transparency < 0.0f) m_transparency = 0.0f;
}
float time = (irr_driver->getDevice()->getTimer()->getRealTime() - initial_time) / 1000.0f;
services->setVertexShaderConstant("time", &time, 1);
services->setVertexShaderConstant("transparency", &m_transparency, 1);
}
void onMadeVisible()
{
m_is_visible = true;
}
void onHidden()
{
m_is_visible = false;
m_transparency = 0.0f;
}
void isInitiallyHidden()
{
m_is_visible = false;
m_transparency = 0.0f;
}
};
#if 0
#pragma mark -
#endif
//-----------------------------------------------------------------------------
/** Create a new material using the parameters specified in the xml file.
@ -422,7 +467,6 @@ void Material::init(unsigned int index)
m_alpha_to_coverage = false;
m_normal_map_provider = NULL;
m_splatting_provider = NULL;
m_bubble_provider = NULL;
m_splatting = false;
for (int n=0; n<EMIT_KINDS_COUNT; n++)
@ -489,10 +533,11 @@ Material::~Material()
m_splatting_provider->drop();
m_splatting_provider = NULL;
}
if (m_bubble_provider != NULL)
for (std::map<scene::IMeshBuffer*, BubbleEffectProvider*>::iterator it = m_bubble_provider.begin();
it != m_bubble_provider.end(); it++)
{
m_bubble_provider->drop();
m_bubble_provider = NULL;
it->second->drop();
}
// If a special sfx is installed (that isn't part of stk itself), the
@ -648,7 +693,7 @@ void Material::setSFXSpeed(SFXBase *sfx, float speed) const
/** Sets the appropriate flags in an irrlicht SMaterial.
* \param material The irrlicht SMaterial which gets the flags set.
*/
void Material::setMaterialProperties(video::SMaterial *m)
void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* mb)
{
// !!======== This method is only called for materials that can be found in
// materials.xml, if you want to set flags for all surfaces, see
@ -837,16 +882,16 @@ void Material::setMaterialProperties(video::SMaterial *m)
m->MaterialType = (E_MATERIAL_TYPE)material_type;
}
if (m_graphical_effect == GE_BUBBLE)
if (m_graphical_effect == GE_BUBBLE && mb != NULL)
{
IVideoDriver* video_driver = irr_driver->getVideoDriver();
if (UserConfigParams::m_pixel_shaders &&
video_driver->queryFeature(video::EVDF_ARB_GLSL) &&
video_driver->queryFeature(video::EVDF_PIXEL_SHADER_2_0))
{
if (m_bubble_provider == NULL)
if (m_bubble_provider.find(mb) == m_bubble_provider.end())
{
m_bubble_provider = new BubbleEffectProvider();
m_bubble_provider[mb] = new BubbleEffectProvider();
}
// Material and shaders
@ -858,7 +903,7 @@ void Material::setMaterialProperties(video::SMaterial *m)
(file_manager->getDataDir() + "shaders/bubble.frag").c_str(),
"main",
video::EPST_PS_2_0,
m_bubble_provider,
m_bubble_provider[mb],
(m_alpha_blending ?
video::EMT_TRANSPARENT_ALPHA_CHANNEL :
video::EMT_SOLID)
@ -974,3 +1019,37 @@ void Material::adjustForFog(scene::ISceneNode* parent, video::SMaterial *m,
} // adjustForFog
//-----------------------------------------------------------------------------
/** Callback from LOD nodes to create some effects */
void Material::onMadeVisible(scene::IMeshBuffer* who)
{
printf("onMadeVisible %s\n", m_texname.c_str());
if (m_bubble_provider.find(who) != m_bubble_provider.end())
{
m_bubble_provider[who]->onMadeVisible();
}
}
//-----------------------------------------------------------------------------
/** Callback from LOD nodes to create some effects */
void Material::onHidden(scene::IMeshBuffer* who)
{
printf("onHidden %s\n", m_texname.c_str());
if (m_bubble_provider.find(who) != m_bubble_provider.end())
{
m_bubble_provider[who]->onHidden();
}
}
//-----------------------------------------------------------------------------
void Material::isInitiallyHidden(scene::IMeshBuffer* who)
{
if (m_bubble_provider.find(who) != m_bubble_provider.end())
{
m_bubble_provider[who]->isInitiallyHidden();
}
}
//-----------------------------------------------------------------------------

View File

@ -22,6 +22,7 @@
#include "utils/no_copy.hpp"
#include <string>
#include <map>
#define LIGHTMAP_VISUALISATION 0
@ -29,7 +30,7 @@
namespace irr
{
namespace video { class ITexture; class SMaterial; }
namespace scene { class ISceneNode; }
namespace scene { class ISceneNode; class IMeshBuffer; }
}
using namespace irr;
@ -198,7 +199,7 @@ private:
SplattingProvider* m_splatting_provider;
/** Only used if bubble effect is enabled */
BubbleEffectProvider* m_bubble_provider;
std::map<scene::IMeshBuffer*, BubbleEffectProvider*> m_bubble_provider;
void init (unsigned int index);
void install (bool is_full_path=false);
@ -212,7 +213,7 @@ public:
~Material ();
void setSFXSpeed(SFXBase *sfx, float speed) const;
void setMaterialProperties(video::SMaterial *m);
void setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* mb);
void adjustForFog(scene::ISceneNode* parent, video::SMaterial *m, bool use_fog) const;
/** Returns the ITexture associated with this material. */
@ -297,6 +298,10 @@ public:
} // getZipperParameter
bool isNormalMap() const { return m_normal_map; }
void onMadeVisible(scene::IMeshBuffer* who);
void onHidden(scene::IMeshBuffer* who);
void isInitiallyHidden(scene::IMeshBuffer* who);
} ;

View File

@ -64,13 +64,9 @@ std::set<scene::IMeshBuffer*> g_processed;
#endif
//-----------------------------------------------------------------------------
/** Searches for the material in the given texture, and calls a function
* in the material to set the irrlicht material flags.
* \param t Pointer to the texture.
* \param mb Pointer to the mesh buffer.
*/
void MaterialManager::setAllMaterialFlags(video::ITexture* t,
scene::IMeshBuffer *mb) const
Material* MaterialManager::getMaterialFor(video::ITexture* t,
scene::IMeshBuffer *mb)
{
const std::string image = StringUtils::getBasename(core::stringc(t->getName()).c_str());
// Search backward so that temporary (track) textures are found first
@ -78,11 +74,29 @@ void MaterialManager::setAllMaterialFlags(video::ITexture* t,
{
if (m_materials[i]->getTexFname()==image)
{
m_materials[i]->setMaterialProperties(&(mb->getMaterial()));
return;
return m_materials[i];
}
} // for i
return NULL;
}
//-----------------------------------------------------------------------------
/** Searches for the material in the given texture, and calls a function
* in the material to set the irrlicht material flags.
* \param t Pointer to the texture.
* \param mb Pointer to the mesh buffer.
*/
void MaterialManager::setAllMaterialFlags(video::ITexture* t,
scene::IMeshBuffer *mb)
{
Material* mat = getMaterialFor(t, mb);
if (mat != NULL)
{
mat->setMaterialProperties(&(mb->getMaterial()), mb);
return;
}
// This material does not appear in materials.xml. Set some common flags...
if (UserConfigParams::m_anisotropic > 0)
{

View File

@ -50,8 +50,10 @@ public:
MaterialManager();
~MaterialManager();
void loadMaterial ();
Material* getMaterialFor(video::ITexture* t,
scene::IMeshBuffer *mb);
void setAllMaterialFlags(video::ITexture* t,
scene::IMeshBuffer *mb) const;
scene::IMeshBuffer *mb);
void adjustForFog(video::ITexture* t,
scene::IMeshBuffer *mb,
scene::ISceneNode* parent,

View File

@ -355,7 +355,7 @@ void ParticleEmitter::setParticleType(const ParticleKind* type)
if (material != NULL)
{
assert(material->getTexture() != NULL);
material->setMaterialProperties(&mat0);
material->setMaterialProperties(&mat0, NULL);
m_node->setMaterialTexture(0, material->getTexture());
mat0.ZWriteEnable = !material->isTransparent(); // disable z-buffer writes if material is transparent

View File

@ -61,7 +61,7 @@ Rain::Rain(irr::scene::ICameraSceneNode* camera, irr::scene::ISceneNode* parent,
scene::SMeshBuffer *buffer = new scene::SMeshBuffer();
buffer->Material.setTexture(0, m->getTexture());
m->setMaterialProperties(&buffer->Material);
m->setMaterialProperties(&buffer->Material, NULL);
buffer->Material.ZWriteEnable = false;
buffer->Material.BackfaceCulling = false;

View File

@ -49,7 +49,7 @@ Stars::Stars(scene::ISceneNode* parentKart, core::vector3df center)
#ifdef DEBUG
billboard->setName("star");
#endif
star_material->setMaterialProperties(&(billboard->getMaterial(0)));
star_material->setMaterialProperties(&(billboard->getMaterial(0)), NULL);
billboard->setMaterialTexture(0, star_material->getTexture());
billboard->setVisible(false);