diff --git a/data/models/materials.xml b/data/models/materials.xml index d8d2af8d0..7c9fa26eb 100644 --- a/data/models/materials.xml +++ b/data/models/materials.xml @@ -3,7 +3,10 @@ - + + + + diff --git a/data/shaders/spheremap.frag b/data/shaders/spheremap.frag new file mode 100644 index 000000000..d6f5c4023 --- /dev/null +++ b/data/shaders/spheremap.frag @@ -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); +} diff --git a/data/shaders/spheremap.vert b/data/shaders/spheremap.vert new file mode 100644 index 000000000..873bf0e42 --- /dev/null +++ b/data/shaders/spheremap.vert @@ -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); +} diff --git a/src/graphics/material.cpp b/src/graphics/material.cpp index f9483ba96..d69ee590b 100644 --- a/src/graphics/material.cpp +++ b/src/graphics/material.cpp @@ -70,6 +70,7 @@ public: } }; + //----------------------------------------------------------------------------- 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 #pragma mark - @@ -290,6 +322,7 @@ Material::Material(const XMLNode *node, int index) node->get("alpha", &m_alpha_blending ); node->get("light", &m_lighting ); node->get("sphere", &m_sphere_map ); + node->get("smooth-reflection",&m_smooth_reflection_shader); node->get("high-adhesion", &m_high_tire_adhesion); node->get("reset", &m_drive_reset ); @@ -506,6 +539,7 @@ void Material::init(unsigned int index) m_lighting = true; m_backface_culling = true; m_sphere_map = false; + m_smooth_reflection_shader = false; m_high_tire_adhesion = false; m_below_surface = false; m_falling_effect = false; @@ -806,10 +840,53 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m 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) { 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) @@ -853,8 +930,7 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m 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) && - video_driver->queryFeature(video::EVDF_RENDER_TO_TARGET)) + video_driver->queryFeature(video::EVDF_PIXEL_SHADER_2_0)) { ITexture* tex = irr_driver->getTexture(m_normal_map_tex); if (m_is_heightmap) diff --git a/src/graphics/material.hpp b/src/graphics/material.hpp index 83e0ef025..1e618f976 100644 --- a/src/graphics/material.hpp +++ b/src/graphics/material.hpp @@ -78,6 +78,7 @@ private: NORMAL_MAP, SPLATTING, WATER_SHADER, + SPHERE_MAP, SHADER_COUNT }; @@ -147,6 +148,7 @@ private: bool m_lighting; bool m_sphere_map; + bool m_smooth_reflection_shader; bool m_alpha_testing; bool m_alpha_blending; bool m_alpha_to_coverage; diff --git a/src/states_screens/main_menu_screen.cpp b/src/states_screens/main_menu_screen.cpp index 2c2716ae8..8b50c4679 100644 --- a/src/states_screens/main_menu_screen.cpp +++ b/src/states_screens/main_menu_screen.cpp @@ -15,7 +15,7 @@ // along with this program; if not, write to the Free Software // 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" @@ -189,6 +189,10 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name, FeatureUnlockedCutScene* scene = FeatureUnlockedCutScene::getInstance(); + scene->addTrophy(RaceManager::RD_HARD); + StateManager::get()->pushScreen(scene); + + /* static int i = 1; i++; @@ -221,15 +225,7 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name, ->getScreenshotFile().c_str())); 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); } else if (i % 4 == 2) @@ -249,6 +245,7 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name, losers.push_back("wilber"); scene->setKarts( losers ); } + */ } else #endif