diff --git a/code/nel/include/nel/3d/i_program_object.h b/code/nel/include/nel/3d/i_program_object.h index 04cf0a77f..3537e1fe7 100644 --- a/code/nel/include/nel/3d/i_program_object.h +++ b/code/nel/include/nel/3d/i_program_object.h @@ -91,6 +91,38 @@ namespace NL3D Light5Shininess, Light6Shininess, Light7Shininess, + Light0Pos, + Light1Pos, + Light2Pos, + Light3Pos, + Light4Pos, + Light5Pos, + Light6Pos, + Light7Pos, + Light0ConstAttn, + Light1ConstAttn, + Light2ConstAttn, + Light3ConstAttn, + Light4ConstAttn, + Light5ConstAttn, + Light6ConstAttn, + Light7ConstAttn, + Light0LinAttn, + Light1LinAttn, + Light2LinAttn, + Light3LinAttn, + Light4LinAttn, + Light5LinAttn, + Light6LinAttn, + Light7LinAttn, + Light0QuadAttn, + Light1QuadAttn, + Light2QuadAttn, + Light3QuadAttn, + Light4QuadAttn, + Light5QuadAttn, + Light6QuadAttn, + Light7QuadAttn, NUM_UNIFORMS }; diff --git a/code/nel/src/3d/driver/OpenGL3/driver_glsl_program.cpp b/code/nel/src/3d/driver/OpenGL3/driver_glsl_program.cpp index 547b808fe..14427ec83 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_glsl_program.cpp +++ b/code/nel/src/3d/driver/OpenGL3/driver_glsl_program.cpp @@ -236,7 +236,39 @@ namespace NL3D "light4Shininess", "light5Shininess", "light6Shininess", - "light7Shininess" + "light7Shininess", + "light0Pos", + "light1Pos", + "light2Pos", + "light3Pos", + "light4Pos", + "light5Pos", + "light6Pos", + "light7Pos", + "light0ConstAttn", + "light1ConstAttn", + "light2ConstAttn", + "light3ConstAttn", + "light4ConstAttn", + "light5ConstAttn", + "light6ConstAttn", + "light7ConstAttn", + "light0LinAttn", + "light1LinAttn", + "light2LinAttn", + "light3LinAttn", + "light4LinAttn", + "light5LinAttn", + "light6LinAttn", + "light7LinAttn", + "light0QuadAttn", + "light1QuadAttn", + "light2QuadAttn", + "light3QuadAttn", + "light4QuadAttn", + "light5QuadAttn", + "light6QuadAttn", + "light7QuadAttn" }; void CGLSLProgram::cacheUniformIndices() diff --git a/code/nel/src/3d/driver/OpenGL3/driver_glsl_shader_generator.cpp b/code/nel/src/3d/driver/OpenGL3/driver_glsl_shader_generator.cpp index a006d64bf..dd3744fdd 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_glsl_shader_generator.cpp +++ b/code/nel/src/3d/driver/OpenGL3/driver_glsl_shader_generator.cpp @@ -367,6 +367,17 @@ namespace NL3D ss << "uniform vec4 light" << i << "ColSpec;" << std::endl; ss << "uniform float light" << i << "Shininess;" << std::endl; break; + + case CShaderDesc::Point: + ss << "uniform vec3 light" << i << "Pos;" << std::endl; + ss << "uniform vec4 light" << i << "ColDiff;" << std::endl; + ss << "uniform vec4 light" << i << "ColAmb;" << std::endl; + ss << "uniform vec4 light" << i << "ColSpec;" << std::endl; + ss << "uniform float light" << i << "Shininess;" << std::endl; + ss << "uniform float light" << i << "ConstAttn;" << std::endl; + ss << "uniform float light" << i << "LinAttn;" << std::endl; + ss << "uniform float light" << i << "QuadAttn;" << std::endl; + break; } } } @@ -390,36 +401,12 @@ namespace NL3D void CGLSLShaderGenerator::addLightOutsVS() { - for( int i = 0; i < SHADER_MAX_LIGHTS; i++ ) - { - switch( desc->getLight( i ) ) - { - case CShaderDesc::Nolight: - continue; - break; - - case CShaderDesc::Directional: - ss << "smooth out vec4 lightColor;" << std::endl; - break; - } - } + ss << "smooth out vec4 lightColor;" << std::endl; } void CGLSLShaderGenerator::addLightInsFS() { - for( int i = 0; i < SHADER_MAX_LIGHTS; i++ ) - { - switch( desc->getLight( i ) ) - { - case CShaderDesc::Nolight: - continue; - break; - - case CShaderDesc::Directional: - ss << "smooth in vec4 lightColor;" << std::endl; - break; - } - } + ss << "smooth in vec4 lightColor;" << std::endl; } void CGLSLShaderGenerator::addDirectionalFunctionVS( int num ) @@ -438,9 +425,7 @@ namespace NL3D ss << "{" << std::endl; ss << "vec3 normal3 = vnormal.xyz / vnormal.w;" << std::endl; ss << "normal3 = normalMatrix * normal3;" << std::endl; - //ss << "vec3 reflection = reflect( normalize( -light" << num << "Dir ), normal3 );" << std::endl; ss << "vec3 halfVector = normalize( light" << num << "Dir + normal3 );" << std::endl; - //ss << "float angle = dot( normal3, reflection );" << std::endl; ss << "float angle = dot( normal3, halfVector );" << std::endl; ss << "angle = max( 0.0, angle );" << std::endl; ss << "float si = pow( angle, light" << num << "Shininess );" << std::endl; @@ -449,6 +434,50 @@ namespace NL3D ss << std::endl; } + void CGLSLShaderGenerator::addPointLightFunctionVS( int num ) + { + ss << "float getIntensity" << num << "( vec3 normal3, vec3 direction3 )" << std::endl; + ss << "{" << std::endl; + ss << "float angle = dot( normalize( direction3 ), normal3 );" << std::endl; + ss << "angle = max( 0.0, angle );" << std::endl; + ss << "return angle;" << std::endl; + ss << "}" << std::endl; + ss << std::endl; + + ss << "float getSpecIntensity" << num << "( vec3 normal3, vec3 direction3 )" << std::endl; + ss << "{" << std::endl; + ss << "vec3 halfVector = normalize( direction3 + normal3 );" << std::endl; + ss << "float angle = dot( normal3, halfVector );" << std::endl; + ss << "angle = max( 0.0, angle );" << std::endl; + ss << "float si = pow( angle, light" << num << "Shininess );" << std::endl; + ss << "return si;" << std::endl; + ss << "}" << std::endl; + ss << std::endl; + + ss << "vec4 getLight" << num << "Color()" << std::endl; + ss << "{" << std::endl; + ss << "vec3 ecPos3 = ecPos4.xyz / ecPos4.w;" << std::endl; + ss << "vec3 lightDirection = light" << num << "Pos - ecPos3;" << std::endl; + ss << "float lightDistance = length( lightDirection );" << std::endl; + ss << "lightDirection = normalize( lightDirection );" << std::endl; + + ss << "float attenuation = light" << num << "ConstAttn + "; + ss << "light" << num << "LinAttn * lightDistance +"; + ss << "light" << num << "QuadAttn * lightDistance * lightDistance;" << std::endl; + + ss << "vec3 normal3 = vnormal.xyz / vnormal.w;" << std::endl; + ss << "normal3 = normalMatrix * normal3;" << std::endl; + + ss << "vec4 lc = getIntensity" << num << "( normal3, lightDirection ) * light" << num << "ColDiff + "; + ss << "getSpecIntensity" << num << "( normal3, lightDirection ) * light" << num << "ColSpec + "; + ss << "light" << num << "ColAmb;" << std::endl; + + ss << "lc = lc / attenuation;" << std::endl; + ss << "return lc;" << std::endl; + ss << "}" << std::endl; + ss << std::endl; + } + void CGLSLShaderGenerator::addLightsFunctionVS() { for( int i = 0; i < SHADER_MAX_LIGHTS; i++ ) @@ -462,7 +491,13 @@ namespace NL3D case CShaderDesc::Directional: addDirectionalFunctionVS( i ); break; + + case CShaderDesc::Point: + addPointLightFunctionVS( i ); + break; + } + } } @@ -476,7 +511,7 @@ namespace NL3D void CGLSLShaderGenerator::addLightsVS() { - ss << "lightColor = vec4( 1.0, 1.0, 1.0, 1.0 );" << std::endl; + ss << "lightColor = vec4( 0.0, 0.0, 0.0, 1.0 );" << std::endl; for( int i = 0; i < SHADER_MAX_LIGHTS; i++ ) { @@ -487,12 +522,16 @@ namespace NL3D break; case CShaderDesc::Directional: - ss << "lightColor = lightColor * ("; + ss << "lightColor = lightColor + ("; ss << "getIntensity" << i << "() * light" << i << "ColDiff + "; ss << "getSpecIntensity" << i << "() * light" << i << "ColSpec + "; ss << "light" << i << "ColAmb );"; ss << std::endl; break; + + case CShaderDesc::Point: + ss << "lightColor = lightColor + getLight" << i << "Color();" << std::endl; + break; } } } @@ -510,8 +549,14 @@ namespace NL3D { ss << "uniform mat4 mvMatrix;" << std::endl; } + if( desc->fogEnabled() || desc->hasPointLight() ) + { + ss << "vec4 ecPos4;" << std::endl; + } + if( desc->fogEnabled() ) ss << "smooth out vec4 ecPos;" << std::endl; + ss << std::endl; if( desc->lightingEnabled() ) @@ -533,13 +578,16 @@ namespace NL3D if( desc->lightingEnabled() ) ss << "calcNMFromMV();" << std::endl; - if( desc->lightingEnabled() ) - addLightsVS(); - ss << "gl_Position = mvpMatrix * " << "v" << attribNames[ 0 ] << ";" << std::endl; + if( desc->fogEnabled() || desc->hasPointLight() ) + ss << "ecPos4 = mvMatrix * v" << attribNames[ 0 ] << ";" << std::endl; + if( desc->fogEnabled() ) - ss << "ecPos = mvMatrix * v" << attribNames[ 0 ] << ";" << std::endl; + ss << "ecPos = ecPos4;" << std::endl; + + if( desc->lightingEnabled() ) + addLightsVS(); for( int i = Weight; i < NumOffsets; i++ ) { @@ -1201,7 +1249,7 @@ namespace NL3D //ss << "vec4 texel = diffuse;" << std::endl; //ss << "vec4 texel = vec4( 1.0, 1.0, 1.0, 1.0 );" << std::endl; - ss << "vec4 texel = vec4( 0.0, 0.0, 0.0, 0.0 );" << std::endl; + ss << "vec4 texel = vec4( 0.0, 0.0, 0.0, 1.0 );" << std::endl; // Lightmaps for( int i = 0; i < ntextures - 1; i++ ) diff --git a/code/nel/src/3d/driver/OpenGL3/driver_glsl_shader_generator.h b/code/nel/src/3d/driver/OpenGL3/driver_glsl_shader_generator.h index 11683a4e6..371fd144b 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_glsl_shader_generator.h +++ b/code/nel/src/3d/driver/OpenGL3/driver_glsl_shader_generator.h @@ -60,6 +60,7 @@ namespace NL3D void addLightOutsVS(); void addLightInsFS(); void addDirectionalFunctionVS( int num ); + void addPointLightFunctionVS( int num ); void addLightsFunctionVS(); void addLightsFunctionFS(); void addLightsVS(); diff --git a/code/nel/src/3d/driver/OpenGL3/driver_opengl_program.cpp b/code/nel/src/3d/driver/OpenGL3/driver_opengl_program.cpp index 885fde8fe..3c302db84 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_opengl_program.cpp +++ b/code/nel/src/3d/driver/OpenGL3/driver_opengl_program.cpp @@ -377,7 +377,7 @@ namespace NL3D continue; ////////////////// Temporary insanity /////////////////////////////// - if( _LightMode[ i ] != CLight::DirectionalLight ) + if( _LightMode[ i ] != CLight::DirectionalLight && _LightMode[ i ] != CLight::PointLight ) continue; ////////////////////////////////////////////////////////////////////// @@ -388,6 +388,13 @@ namespace NL3D setUniform3f( ld, v.x, v.y, v.z ); } + int lp = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Light0Pos + i ) ); + if( lp != -1 ) + { + CVector v = _UserLight[ i ].getPosition(); + setUniform3f( lp, v.x, v.y, v.z ); + } + int ldc = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Light0ColDiff + i ) ); if( ldc != -1 ) { @@ -435,6 +442,23 @@ namespace NL3D setUniform4f( lac, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); } + int lca = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Light0ConstAttn + i ) ); + if( lca != -1 ) + { + setUniform1f( lca, _UserLight[ i ].getConstantAttenuation() ); + } + + int lla = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Light0LinAttn + i ) ); + if( lla != -1 ) + { + setUniform1f( lla, _UserLight[ i ].getLinearAttenuation() ); + } + + int lqa = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Light0QuadAttn + i ) ); + if( lqa != -1 ) + { + setUniform1f( lqa, _UserLight[ i ].getQuadraticAttenuation() ); + } } diff --git a/code/nel/src/3d/driver/OpenGL3/driver_opengl_shader_desc.h b/code/nel/src/3d/driver/OpenGL3/driver_opengl_shader_desc.h index 3f5a5c565..c646576ab 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_opengl_shader_desc.h +++ b/code/nel/src/3d/driver/OpenGL3/driver_opengl_shader_desc.h @@ -73,6 +73,7 @@ namespace NL3D nlightmaps = 0; alphaTestTreshold = 0.5f; fogMode = Linear; + pointLight = false; } ~CShaderDesc(){ @@ -179,10 +180,14 @@ namespace NL3D void setLight( int idx, TLightMode mode ) { lightMode[ idx ] = mode; + if( mode == Point ) + pointLight = true; } TLightMode getLight( int idx ) const{ return lightMode[ idx ]; } + bool hasPointLight() const{ return pointLight; } + IProgramObject* getProgram() const{ return program; } private: @@ -203,6 +208,7 @@ namespace NL3D float alphaTestTreshold; uint32 fogMode; TLightMode lightMode[ SHADER_MAX_LIGHTS ]; + bool pointLight; IProgramObject *program; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/nel3d_interface.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/nel3d_interface.cpp index 09f2b5c4d..71573a10a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/nel3d_interface.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/nel3d_interface.cpp @@ -411,18 +411,35 @@ namespace MaterialEditor driver->enableFog( true ); driver->setupFog( 1.0f, 5.0f, NLMISC::CRGBA::White ); - NL3D::ULight *l = NL3D::ULight::createLight(); + NL3D::ULight *ld; - l->setMode( NL3D::ULight::DirectionalLight ); - l->setDirection( NLMISC::CVector( -100.0f, 100.0f, 100.0f ) ); - l->setAmbiant( NLMISC::CRGBA::CRGBA( 0.1f, 0.1f, 0.1f, 0.1f ) ); - l->setSpecular( NLMISC::CRGBA::White ); - l->setDiffuse( NLMISC::CRGBA::White ); - driver->setLight( 0, *l ); + /* + // Let's add a directional light! + ld = NL3D::ULight::createLight(); + ld->setMode( NL3D::ULight::DirectionalLight ); + ld->setDirection( NLMISC::CVector( -100.0f, 100.0f, 100.0f ) ); + ld->setAmbiant( NLMISC::CRGBA::CRGBA( 0.1f, 0.1f, 0.1f, 0.1f ) ); + ld->setSpecular( NLMISC::CRGBA::White ); + ld->setDiffuse( NLMISC::CRGBA::White ); + driver->setLight( 0, *ld ); driver->enableLight( 0, true ); - - delete l; - l = NULL; + delete ld; + */ + + // Let's add a point light as well! + ld = NL3D::ULight::createLight(); + ld->setMode( NL3D::ULight::PointLight ); + ld->setPosition( NLMISC::CVector( 0.0f, 0.0f, 0.0f ) ); + ld->setAmbiant( NLMISC::CRGBA::CRGBA( 0.1f, 0.1f, 0.1f, 0.1f ) ); + ld->setSpecular( NLMISC::CRGBA::White ); + ld->setDiffuse( NLMISC::CRGBA::White ); + ld->setConstantAttenuation( 1.0f ); + ld->setLinearAttenuation( 0.0f ); + ld->setQuadraticAttenuation( 0.0f ); + driver->setLight( 1, *ld ); + driver->enableLight( 1, true ); + delete ld; + ld = NULL; scene->enableLightingSystem( false );