Add my own sphere mapping shader, since irrlicht's one is buggy when the model moves around. Bonus, mine uses pixel shading instead of vertex shading, which makes the shadows much smoother
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@10859 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
49d190defe
commit
c6a2cecc05
@ -3,7 +3,10 @@
|
|||||||
<material name="banana.png"/>
|
<material name="banana.png"/>
|
||||||
<material name="gift-box.png"/>
|
<material name="gift-box.png"/>
|
||||||
<material name="gift-loop.png" sphere="Y"/>
|
<material name="gift-loop.png" sphere="Y"/>
|
||||||
<material name="gold.png" light="Y" sphere="Y"/>
|
<material name="gold.png" light="Y" smooth-reflection="Y"/>
|
||||||
|
<material name="silver.png" light="Y" smooth-reflection="Y"/>
|
||||||
|
<material name="bronze.png" light="Y" smooth-reflection="Y"/>
|
||||||
|
|
||||||
<material name="nitro-tank.png" transparency="Y"/>
|
<material name="nitro-tank.png" transparency="Y"/>
|
||||||
<material name="tank-blue.png" sphere="Y"/>
|
<material name="tank-blue.png" sphere="Y"/>
|
||||||
<material name="tank-green.png" sphere="Y"/>
|
<material name="tank-green.png" sphere="Y"/>
|
||||||
|
24
data/shaders/spheremap.frag
Normal file
24
data/shaders/spheremap.frag
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
|
||||||
|
uniform sampler2D texture;
|
||||||
|
varying vec3 normal;
|
||||||
|
uniform vec3 lightdir;
|
||||||
|
varying vec4 vertex_color;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec3 forward = vec3(0.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
// get the angle between the forward vector and the horizontal portion of the normal
|
||||||
|
vec3 normal_x = normalize(vec3(normal.x, 0.0, normal.z));
|
||||||
|
float sin_theta_x = length(cross( forward, normal_x )) * normal.x/abs(normal.x);
|
||||||
|
|
||||||
|
// get the angle between the forward vector and the vertical portion of the normal
|
||||||
|
vec3 normal_y = normalize(vec3(0.0, normal.y, normal.z));
|
||||||
|
float sin_theta_y = length(cross( forward, normal_y ))* normal.y/abs(normal.y);
|
||||||
|
|
||||||
|
vec4 detail0 = texture2D(texture, vec2(0.5 + sin_theta_x*0.5, 0.5 + sin_theta_y*0.5));
|
||||||
|
|
||||||
|
gl_FragColor = detail0 * (0.5 + dot(lightdir, normal)) * vertex_color; // 0.5 is the ambient light.
|
||||||
|
//gl_FragColor = vec4(sin_theta_y*0.5 + 0.5, 0.0, 1.0 - (sin_theta_y*0.5 + 0.5), 1.0);
|
||||||
|
}
|
15
data/shaders/spheremap.vert
Normal file
15
data/shaders/spheremap.vert
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
varying vec3 normal;
|
||||||
|
varying vec4 vertex_color;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||||
|
gl_Position = ftransform();
|
||||||
|
vertex_color = gl_Color;
|
||||||
|
|
||||||
|
//vec3 normal3 = normalize(gl_Normal);
|
||||||
|
//vec4 normal4 = vec4(normal3.x, normal3.y, normal3.z, 0.0)*gl_ModelViewMatrix;
|
||||||
|
//normal = normal4.xyz;
|
||||||
|
|
||||||
|
normal = normalize(gl_NormalMatrix*gl_Normal);
|
||||||
|
}
|
@ -70,6 +70,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
class WaterShaderProvider : public video::IShaderConstantSetCallBack
|
class WaterShaderProvider : public video::IShaderConstantSetCallBack
|
||||||
@ -186,6 +187,37 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#pragma mark -
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class SphereMapProvider: public video::IShaderConstantSetCallBack
|
||||||
|
{
|
||||||
|
core::vector3df m_light_direction;
|
||||||
|
|
||||||
|
public:
|
||||||
|
LEAK_CHECK()
|
||||||
|
|
||||||
|
SphereMapProvider()
|
||||||
|
{
|
||||||
|
m_light_direction = core::vector3df(-0.6f, -0.5f, -0.63f);
|
||||||
|
//m_light_direction = core::vector3df(-0.315f, 0.91f, -0.3f);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void OnSetConstants(
|
||||||
|
irr::video::IMaterialRendererServices *services,
|
||||||
|
s32 userData)
|
||||||
|
{
|
||||||
|
// Irrlicht knows this is actually a GLint and makes the conversion
|
||||||
|
int texture = 0;
|
||||||
|
services->setPixelShaderConstant("texture", (float*)&texture, 1);
|
||||||
|
|
||||||
|
services->setVertexShaderConstant("lightdir", &m_light_direction.X, 3);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
#if 0
|
#if 0
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
@ -290,6 +322,7 @@ Material::Material(const XMLNode *node, int index)
|
|||||||
node->get("alpha", &m_alpha_blending );
|
node->get("alpha", &m_alpha_blending );
|
||||||
node->get("light", &m_lighting );
|
node->get("light", &m_lighting );
|
||||||
node->get("sphere", &m_sphere_map );
|
node->get("sphere", &m_sphere_map );
|
||||||
|
node->get("smooth-reflection",&m_smooth_reflection_shader);
|
||||||
node->get("high-adhesion", &m_high_tire_adhesion);
|
node->get("high-adhesion", &m_high_tire_adhesion);
|
||||||
node->get("reset", &m_drive_reset );
|
node->get("reset", &m_drive_reset );
|
||||||
|
|
||||||
@ -506,6 +539,7 @@ void Material::init(unsigned int index)
|
|||||||
m_lighting = true;
|
m_lighting = true;
|
||||||
m_backface_culling = true;
|
m_backface_culling = true;
|
||||||
m_sphere_map = false;
|
m_sphere_map = false;
|
||||||
|
m_smooth_reflection_shader = false;
|
||||||
m_high_tire_adhesion = false;
|
m_high_tire_adhesion = false;
|
||||||
m_below_surface = false;
|
m_below_surface = false;
|
||||||
m_falling_effect = false;
|
m_falling_effect = false;
|
||||||
@ -806,10 +840,53 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
|||||||
|
|
||||||
modes++;
|
modes++;
|
||||||
}
|
}
|
||||||
|
if (m_smooth_reflection_shader)
|
||||||
|
{
|
||||||
|
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_shaders[SPHERE_MAP] == NULL)
|
||||||
|
{
|
||||||
|
m_shaders[SPHERE_MAP] = new SphereMapProvider();
|
||||||
|
}
|
||||||
|
// Material and shaders
|
||||||
|
IGPUProgrammingServices* gpu =
|
||||||
|
irr_driver->getVideoDriver()->getGPUProgrammingServices();
|
||||||
|
s32 material_type = gpu->addHighLevelShaderMaterialFromFiles(
|
||||||
|
(file_manager->getDataDir() +
|
||||||
|
"shaders/spheremap.vert").c_str(),
|
||||||
|
"main",
|
||||||
|
video::EVST_VS_2_0,
|
||||||
|
(file_manager->getDataDir() +
|
||||||
|
"shaders/spheremap.frag").c_str(),
|
||||||
|
"main",
|
||||||
|
video::EPST_PS_2_0,
|
||||||
|
m_shaders[SPHERE_MAP],
|
||||||
|
video::EMT_SOLID_2_LAYER );
|
||||||
|
m->MaterialType = (E_MATERIAL_TYPE)material_type;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m->MaterialType = video::EMT_SPHERE_MAP;
|
||||||
|
|
||||||
|
// sphere map + alpha blending is a supported combination so in
|
||||||
|
// this case don't increase mode count
|
||||||
|
if (m_alpha_blending)
|
||||||
|
{
|
||||||
|
m->BlendOperation = video::EBO_ADD;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
modes++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (m_sphere_map)
|
if (m_sphere_map)
|
||||||
{
|
{
|
||||||
m->MaterialType = video::EMT_SPHERE_MAP;
|
m->MaterialType = video::EMT_SPHERE_MAP;
|
||||||
|
|
||||||
// sphere map + alpha blending is a supported combination so in
|
// sphere map + alpha blending is a supported combination so in
|
||||||
// this case don't increase mode count
|
// this case don't increase mode count
|
||||||
if (m_alpha_blending)
|
if (m_alpha_blending)
|
||||||
@ -853,8 +930,7 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
|||||||
IVideoDriver* video_driver = irr_driver->getVideoDriver();
|
IVideoDriver* video_driver = irr_driver->getVideoDriver();
|
||||||
if (UserConfigParams::m_pixel_shaders &&
|
if (UserConfigParams::m_pixel_shaders &&
|
||||||
video_driver->queryFeature(video::EVDF_ARB_GLSL) &&
|
video_driver->queryFeature(video::EVDF_ARB_GLSL) &&
|
||||||
video_driver->queryFeature(video::EVDF_PIXEL_SHADER_2_0) &&
|
video_driver->queryFeature(video::EVDF_PIXEL_SHADER_2_0))
|
||||||
video_driver->queryFeature(video::EVDF_RENDER_TO_TARGET))
|
|
||||||
{
|
{
|
||||||
ITexture* tex = irr_driver->getTexture(m_normal_map_tex);
|
ITexture* tex = irr_driver->getTexture(m_normal_map_tex);
|
||||||
if (m_is_heightmap)
|
if (m_is_heightmap)
|
||||||
|
@ -78,6 +78,7 @@ private:
|
|||||||
NORMAL_MAP,
|
NORMAL_MAP,
|
||||||
SPLATTING,
|
SPLATTING,
|
||||||
WATER_SHADER,
|
WATER_SHADER,
|
||||||
|
SPHERE_MAP,
|
||||||
SHADER_COUNT
|
SHADER_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -147,6 +148,7 @@ private:
|
|||||||
|
|
||||||
bool m_lighting;
|
bool m_lighting;
|
||||||
bool m_sphere_map;
|
bool m_sphere_map;
|
||||||
|
bool m_smooth_reflection_shader;
|
||||||
bool m_alpha_testing;
|
bool m_alpha_testing;
|
||||||
bool m_alpha_blending;
|
bool m_alpha_blending;
|
||||||
bool m_alpha_to_coverage;
|
bool m_alpha_to_coverage;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
// along with this program; if not, write to the Free Software
|
// along with this program; if not, write to the Free Software
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#define DEBUG_MENU_ITEM 0
|
#define DEBUG_MENU_ITEM 1
|
||||||
|
|
||||||
#include "states_screens/main_menu_screen.hpp"
|
#include "states_screens/main_menu_screen.hpp"
|
||||||
|
|
||||||
@ -189,6 +189,10 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name,
|
|||||||
FeatureUnlockedCutScene* scene =
|
FeatureUnlockedCutScene* scene =
|
||||||
FeatureUnlockedCutScene::getInstance();
|
FeatureUnlockedCutScene::getInstance();
|
||||||
|
|
||||||
|
scene->addTrophy(RaceManager::RD_HARD);
|
||||||
|
StateManager::get()->pushScreen(scene);
|
||||||
|
|
||||||
|
/*
|
||||||
static int i = 1;
|
static int i = 1;
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
@ -221,15 +225,7 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name,
|
|||||||
->getScreenshotFile().c_str()));
|
->getScreenshotFile().c_str()));
|
||||||
|
|
||||||
scene->addUnlockedPictures(textures, 1.0, 0.75, L"You did it");
|
scene->addUnlockedPictures(textures, 1.0, 0.75, L"You did it");
|
||||||
|
|
||||||
/*
|
|
||||||
scene->addUnlockedPicture(
|
|
||||||
irr_driver->getTexture(
|
|
||||||
track_manager->getTrack("lighthouse")
|
|
||||||
->getScreenshotFile().c_str()),
|
|
||||||
1.0, 0.75, L"You did it");
|
|
||||||
*/
|
|
||||||
|
|
||||||
StateManager::get()->pushScreen(scene);
|
StateManager::get()->pushScreen(scene);
|
||||||
}
|
}
|
||||||
else if (i % 4 == 2)
|
else if (i % 4 == 2)
|
||||||
@ -249,6 +245,7 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name,
|
|||||||
losers.push_back("wilber");
|
losers.push_back("wilber");
|
||||||
scene->setKarts( losers );
|
scene->setKarts( losers );
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user