From f61c6262f752146db80872ef1c08114a9d599264 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 14 Jun 2007 20:58:43 +0000 Subject: [PATCH] Included shaders directly into source, added support for toggle lighting on/off --- src/osgSim/OverlayNode.cpp | 246 +++++++++++++++++++++++++++++-------- 1 file changed, 194 insertions(+), 52 deletions(-) diff --git a/src/osgSim/OverlayNode.cpp b/src/osgSim/OverlayNode.cpp index ee5cbb04d..6cb1db4ad 100644 --- a/src/osgSim/OverlayNode.cpp +++ b/src/osgSim/OverlayNode.cpp @@ -974,21 +974,14 @@ OverlayNode::OverlayData& OverlayNode::getOverlayData(osgUtil::CullVisitor* cv) overlayData._texgenNode->setTextureUnit(_textureUnit); } - if (!overlayData._exponent_scale) - { - overlayData._exponent_scale = new osg::Uniform("exponent_scale",-2.0f); - } - - if (!overlayData._exponent_offset) - { - overlayData._exponent_offset = new osg::Uniform("exponent_offset",-1.0f/3.0f); - } + if (!overlayData._y0) overlayData._y0 = new osg::Uniform("y0",0.0f); + if (!overlayData._lightingEnabled) overlayData._lightingEnabled = new osg::Uniform("lightingEnabled",true); if (!overlayData._overlayStateSet) { overlayData._overlayStateSet = new osg::StateSet; - overlayData._overlayStateSet->addUniform(overlayData._exponent_scale.get()); - overlayData._overlayStateSet->addUniform(overlayData._exponent_offset.get()); + overlayData._overlayStateSet->addUniform(overlayData._y0.get()); + overlayData._overlayStateSet->addUniform(overlayData._lightingEnabled.get()); osg::Program* program = new osg::Program; overlayData._overlayStateSet->setAttribute(program); @@ -999,22 +992,84 @@ OverlayNode::OverlayData& OverlayNode::getOverlayData(osgUtil::CullVisitor* cv) { program->addShader(osg::Shader::readShaderFile(osg::Shader::VERTEX, vertexShaderFile)); } -#if 0 else { char vertexShaderSource[] = - "varying vec3 texcoord;\n" - "\n" - "void main(void)\n" - "{\n" - " texcoord = gl_MultiTexCoord0.xyz;\n" - " gl_Position = ftransform(); \n" - "}\n"; + "uniform float y0; \n" + "uniform bool lightingEnabled; \n" + " \n" + "vec4 warp(in vec4 source) \n" + "{ \n" + " float divisor = source.y + y0; \n" + " return vec4(source.x * (1.0 + y0 ), source.y * y0 + 1.0, (source.z * y0 + 1.0)*0.01, source.w * divisor); \n" + "} \n" + " \n" + "vec3 fnormal(void) \n" + "{ \n" + " //Compute the normal \n" + " vec3 normal = gl_NormalMatrix * gl_Normal; \n" + " normal = normalize(normal); \n" + " return normal; \n" + "} \n" + " \n" + "void directionalLight(in int i, \n" + " in vec3 normal, \n" + " inout vec4 ambient, \n" + " inout vec4 diffuse, \n" + " inout vec4 specular) \n" + "{ \n" + " float nDotVP; // normal . light direction \n" + " float nDotHV; // normal . light half vector \n" + " float pf; // power factor \n" + " \n" + " nDotVP = max(0.0, dot(normal, normalize(vec3 (gl_LightSource[i].position)))); \n" + " nDotHV = max(0.0, dot(normal, vec3 (gl_LightSource[i].halfVector))); \n" + " \n" + " if (nDotVP == 0.0) \n" + " { \n" + " pf = 0.0; \n" + " } \n" + " else \n" + " { \n" + " pf = pow(nDotHV, gl_FrontMaterial.shininess); \n" + " \n" + " } \n" + " ambient += gl_LightSource[i].ambient; \n" + " diffuse += gl_LightSource[i].diffuse * nDotVP; \n" + " specular += gl_LightSource[i].specular * pf; \n" + "} \n" + "void main() \n" + "{ \n" + " gl_Position = warp(ftransform()); \n" + " \n" + " if (lightingEnabled) \n" + " { \n" + " vec4 ambient = vec4(0.0); \n" + " vec4 diffuse = vec4(0.0); \n" + " vec4 specular = vec4(0.0); \n" + " \n" + " vec3 normal = fnormal(); \n" + " \n" + " directionalLight(0, normal, ambient, diffuse, specular); \n" + " \n" + " vec4 color = gl_FrontLightModelProduct.sceneColor + \n" + " ambient * gl_FrontMaterial.ambient + \n" + " diffuse * gl_FrontMaterial.diffuse + \n" + " specular * gl_FrontMaterial.specular; \n" + " \n" + " gl_FrontColor = color; \n" + " \n" + " } \n" + " else \n" + " { \n" + " gl_FrontColor = gl_Color; \n" + " } \n" + " \n" + "} \n"; osg::Shader* vertex_shader = new osg::Shader(osg::Shader::VERTEX, vertexShaderSource); program->addShader(vertex_shader); } -#endif } @@ -1034,14 +1089,46 @@ OverlayNode::OverlayData& OverlayNode::getOverlayData(osgUtil::CullVisitor* cv) { overlayData._mainSubgraphProgram->addShader(osg::Shader::readShaderFile(osg::Shader::FRAGMENT, fragmentShaderFile)); } + else + { + char fragmentShaderSource[] = + "uniform sampler2D texture_0; \n" + "uniform sampler2D texture_1; \n" + " \n" + "uniform float y0; \n" + " \n" + "vec2 warp(in vec2 source) \n" + "{ \n" + " float inv_divisor = 1.0 / (source.y + y0); \n" + " return vec2(source.x * (1.0 + y0 ) * inv_divisor , (source.y * y0 + 1.0 ) * inv_divisor); \n" + "} \n" + " \n" + "void main() \n" + "{ \n" + " vec2 coord = gl_TexCoord[1].xy; \n" + " coord.x = coord.x*2.0 - 1.0; \n" + " coord.y = coord.y*2.0 - 1.0; \n" + " \n" + " vec2 warped = warp(coord); \n" + " warped.x = (warped.x + 1.0)*0.5; \n" + " warped.y = (warped.y + 1.0)*0.5; \n" + " \n" + " vec4 base_color = texture2D(texture_0, gl_TexCoord[0].xy); \n" + " vec4 overlay_color = texture2D(texture_1, warped ); \n" + " vec3 mixed_color = mix(base_color.rgb, overlay_color.rgb, overlay_color.a); \n" + " gl_FragColor = vec4(mixed_color, base_color.a); \n" + "} \n"; + + osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource); + overlayData._mainSubgraphProgram->addShader(fragment_shader); + } } if (!overlayData._mainSubgraphStateSet) { overlayData._mainSubgraphStateSet = new osg::StateSet; - overlayData._mainSubgraphStateSet->addUniform(overlayData._exponent_scale.get()); - overlayData._mainSubgraphStateSet->addUniform(overlayData._exponent_offset.get()); + overlayData._mainSubgraphStateSet->addUniform(overlayData._y0.get()); overlayData._mainSubgraphStateSet->addUniform(new osg::Uniform("texture_0",0)); overlayData._mainSubgraphStateSet->addUniform(new osg::Uniform("texture_1",1)); @@ -1450,19 +1537,15 @@ void OverlayNode::traverse_VIEW_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY(osg::NodeVis double mid_side = (min_side + max_side) * 0.5; double ratio = min_distanceEye / max_distanceEye; - bool usePerspectiveShaders = (_overlayTechnique==VIEW_DEPENDENT_WITH_PERSPECTIVE_OVERLAY) && - (ratio<0.95); - + bool usePerspectiveShaders = (_overlayTechnique==VIEW_DEPENDENT_WITH_PERSPECTIVE_OVERLAY); if (usePerspectiveShaders) { // osg::notify(osg::NOTICE)<<"ratio = "<