Changeset 6981

Show
Ignore:
Timestamp:
06/14/07 22:58:43
Author:
robert
Message:

Included shaders directly into source, added support for toggle lighting on/off

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • OpenSceneGraph/trunk/src/osgSim/OverlayNode.cpp

    r6965 r6981  
    975975    } 
    976976 
    977     if (!overlayData._exponent_scale) 
    978     { 
    979         overlayData._exponent_scale = new osg::Uniform("exponent_scale",-2.0f); 
    980     } 
    981      
    982     if (!overlayData._exponent_offset) 
    983     { 
    984         overlayData._exponent_offset = new osg::Uniform("exponent_offset",-1.0f/3.0f); 
    985     } 
     977    if (!overlayData._y0) overlayData._y0 = new osg::Uniform("y0",0.0f); 
     978    if (!overlayData._lightingEnabled) overlayData._lightingEnabled = new osg::Uniform("lightingEnabled",true); 
    986979 
    987980    if (!overlayData._overlayStateSet)  
    988981    { 
    989982        overlayData._overlayStateSet = new osg::StateSet; 
    990         overlayData._overlayStateSet->addUniform(overlayData._exponent_scale.get()); 
    991         overlayData._overlayStateSet->addUniform(overlayData._exponent_offset.get()); 
     983        overlayData._overlayStateSet->addUniform(overlayData._y0.get()); 
     984        overlayData._overlayStateSet->addUniform(overlayData._lightingEnabled.get()); 
    992985 
    993986        osg::Program* program = new osg::Program; 
     
    1000993            program->addShader(osg::Shader::readShaderFile(osg::Shader::VERTEX, vertexShaderFile)); 
    1001994        } 
    1002 #if 0 
    1003995        else 
    1004996        { 
    1005997            char vertexShaderSource[] =  
    1006                 "varying vec3 texcoord;\n" 
    1007                 "\n" 
    1008                 "void main(void)\n" 
    1009                 "{\n" 
    1010                 "    texcoord = gl_MultiTexCoord0.xyz;\n" 
    1011                 "    gl_Position     = ftransform();  \n" 
    1012                 "}\n"; 
     998                "uniform float y0; \n" 
     999                "uniform bool lightingEnabled; \n" 
     1000                " \n" 
     1001                "vec4 warp(in vec4 source) \n" 
     1002                "{ \n" 
     1003                "    float divisor = source.y + y0; \n" 
     1004                "    return vec4(source.x * (1.0 + y0 ), source.y * y0 + 1.0, (source.z * y0 + 1.0)*0.01, source.w * divisor); \n" 
     1005                "} \n" 
     1006                " \n" 
     1007                "vec3 fnormal(void) \n" 
     1008                "{ \n" 
     1009                "    //Compute the normal  \n" 
     1010                "    vec3 normal = gl_NormalMatrix * gl_Normal; \n" 
     1011                "    normal = normalize(normal); \n" 
     1012                "    return normal; \n" 
     1013                "} \n" 
     1014                " \n" 
     1015                "void directionalLight(in int i, \n" 
     1016                "                      in vec3 normal, \n" 
     1017                "                      inout vec4 ambient, \n" 
     1018                "                      inout vec4 diffuse, \n" 
     1019                "                      inout vec4 specular) \n" 
     1020                "{ \n" 
     1021                "   float nDotVP;         // normal . light direction \n" 
     1022                "   float nDotHV;         // normal . light half vector \n" 
     1023                "   float pf;             // power factor \n" 
     1024                " \n" 
     1025                "   nDotVP = max(0.0, dot(normal, normalize(vec3 (gl_LightSource[i].position)))); \n" 
     1026                "   nDotHV = max(0.0, dot(normal, vec3 (gl_LightSource[i].halfVector))); \n" 
     1027                " \n" 
     1028                "   if (nDotVP == 0.0) \n" 
     1029                "   { \n" 
     1030                "       pf = 0.0; \n" 
     1031                "   } \n" 
     1032                "   else \n" 
     1033                "   { \n" 
     1034                "       pf = pow(nDotHV, gl_FrontMaterial.shininess); \n" 
     1035                " \n" 
     1036                "   } \n" 
     1037                "   ambient  += gl_LightSource[i].ambient; \n" 
     1038                "   diffuse  += gl_LightSource[i].diffuse * nDotVP; \n" 
     1039                "   specular += gl_LightSource[i].specular * pf; \n" 
     1040                "} \n" 
     1041                "void main() \n" 
     1042                "{ \n" 
     1043                "    gl_Position = warp(ftransform()); \n" 
     1044                " \n" 
     1045                "    if (lightingEnabled) \n" 
     1046                "    {     \n" 
     1047                "        vec4 ambient = vec4(0.0); \n" 
     1048                "        vec4 diffuse = vec4(0.0); \n" 
     1049                "        vec4 specular = vec4(0.0); \n" 
     1050                " \n" 
     1051                "        vec3 normal = fnormal(); \n" 
     1052                " \n" 
     1053                "        directionalLight(0, normal, ambient, diffuse, specular); \n" 
     1054                " \n" 
     1055                "        vec4 color = gl_FrontLightModelProduct.sceneColor + \n" 
     1056                "                     ambient  * gl_FrontMaterial.ambient + \n" 
     1057                "                     diffuse  * gl_FrontMaterial.diffuse + \n" 
     1058                "                     specular * gl_FrontMaterial.specular; \n" 
     1059                " \n" 
     1060                "        gl_FrontColor = color; \n" 
     1061                " \n" 
     1062                "    } \n" 
     1063                "    else \n" 
     1064                "    { \n" 
     1065                "        gl_FrontColor = gl_Color; \n" 
     1066                "    } \n" 
     1067                "   \n" 
     1068                "} \n"; 
    10131069 
    10141070            osg::Shader* vertex_shader = new osg::Shader(osg::Shader::VERTEX, vertexShaderSource); 
    10151071            program->addShader(vertex_shader); 
    10161072        } 
    1017 #endif         
    10181073         
    10191074    } 
     
    10351090            overlayData._mainSubgraphProgram->addShader(osg::Shader::readShaderFile(osg::Shader::FRAGMENT, fragmentShaderFile)); 
    10361091        } 
     1092        else 
     1093        { 
     1094            char fragmentShaderSource[] =  
     1095                "uniform sampler2D texture_0; \n" 
     1096                "uniform sampler2D texture_1; \n" 
     1097                " \n" 
     1098                "uniform float y0; \n" 
     1099                " \n" 
     1100                "vec2 warp(in vec2 source) \n" 
     1101                "{ \n" 
     1102                "    float inv_divisor = 1.0 / (source.y + y0); \n" 
     1103                "    return vec2(source.x * (1.0 + y0 ) * inv_divisor , (source.y * y0 + 1.0 ) * inv_divisor); \n" 
     1104                "} \n" 
     1105                " \n" 
     1106                "void main() \n" 
     1107                "{ \n" 
     1108                "    vec2 coord = gl_TexCoord[1].xy; \n" 
     1109                "    coord.x = coord.x*2.0 - 1.0; \n" 
     1110                "    coord.y = coord.y*2.0 - 1.0; \n" 
     1111                " \n" 
     1112                "    vec2 warped = warp(coord); \n" 
     1113                "    warped.x = (warped.x + 1.0)*0.5; \n" 
     1114                "    warped.y = (warped.y + 1.0)*0.5; \n" 
     1115                " \n" 
     1116                "    vec4 base_color = texture2D(texture_0, gl_TexCoord[0].xy); \n" 
     1117                "    vec4 overlay_color = texture2D(texture_1, warped ); \n" 
     1118                "    vec3 mixed_color = mix(base_color.rgb, overlay_color.rgb, overlay_color.a); \n" 
     1119                "    gl_FragColor = vec4(mixed_color, base_color.a); \n" 
     1120                "} \n"; 
     1121 
     1122            osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource); 
     1123            overlayData._mainSubgraphProgram->addShader(fragment_shader); 
     1124        } 
    10371125    } 
    10381126 
     
    10411129        overlayData._mainSubgraphStateSet = new osg::StateSet; 
    10421130 
    1043         overlayData._mainSubgraphStateSet->addUniform(overlayData._exponent_scale.get()); 
    1044         overlayData._mainSubgraphStateSet->addUniform(overlayData._exponent_offset.get()); 
     1131        overlayData._mainSubgraphStateSet->addUniform(overlayData._y0.get()); 
    10451132        overlayData._mainSubgraphStateSet->addUniform(new osg::Uniform("texture_0",0)); 
    10461133        overlayData._mainSubgraphStateSet->addUniform(new osg::Uniform("texture_1",1)); 
     
    14511538        double mid_side = (min_side + max_side) * 0.5; 
    14521539        double ratio = min_distanceEye / max_distanceEye; 
    1453         bool usePerspectiveShaders = (_overlayTechnique==VIEW_DEPENDENT_WITH_PERSPECTIVE_OVERLAY) && 
    1454                                      (ratio<0.95); 
    1455  
     1540        bool usePerspectiveShaders = (_overlayTechnique==VIEW_DEPENDENT_WITH_PERSPECTIVE_OVERLAY); 
    14561541 
    14571542        if (usePerspectiveShaders) 
     
    14601545            double original_width = max_side-min_side; 
    14611546 
    1462             double minRatio = 0.
     1547            double minRatio = 0.02
    14631548            if (ratio<minRatio) ratio = minRatio; 
    1464          
    1465             osg::notify(osg::NOTICE)<<" new ratio = "<<ratio<<std::endl; 
    14661549 
    14671550            double base_up = min_up - (max_up - min_up) * ratio / (1.0 - ratio); 
     
    14741557                if (side_over_up > max_side_over_up) max_side_over_up = side_over_up; 
    14751558            } 
    1476              
    1477             double max_half_width = max_side_over_up*(max_up - base_up); 
    1478             min_side = mid_side - max_half_width; 
    1479             max_side = mid_side + max_half_width; 
    1480              
    1481             double new_width = max_side-min_side; 
    1482 #if 0             
    1483             osg::notify(osg::NOTICE)<<"  width ratio  = "<<new_width/original_width<<std::endl; 
    1484             osg::notify(osg::NOTICE)<<"  near ratio  = "<<ratio * new_width/original_width<<std::endl; 
    1485             osg::notify(osg::NOTICE)<<"  angle  = "<<2.0*osg::RadiansToDegrees(atan(max_side_over_up))<<std::endl; 
    1486 #endif         
    14871559            osg::Vec3d v000 = osg::Vec3d(-1.0, -1.0, -1.0) * inverseMVP;  
    14881560            osg::Vec3d v010 = osg::Vec3d(-1.0, 1.0, -1.0) * inverseMVP;  
     
    15051577            edgeTopRight.normalize(); 
    15061578             
     1579            
     1580            double frustumDiagonal = osg::RadiansToDegrees(acos(edgeBottomLeft * edgeBottomRight)); 
    15071581             
    15081582             
    1509             double frustumDiagonal = osg::RadiansToDegrees(acos(edgeBottomLeft * edgeBottomRight)); 
    1510 #if 1             
    1511             osg::notify(osg::NOTICE)<<"  frustum base angle  = "<<frustumDiagonal<<std::endl; 
    1512 #endif         
    1513          
    1514             double exponent_scale = -log(ratio)/log(4.0); 
    1515             double exponent_offset = -exponent_scale; 
     1583            //osg::notify(osg::NOTICE)<<"  width ratio  = "<<new_width/original_width<<std::endl; 
     1584            //osg::notify(osg::NOTICE)<<"  near ratio  = "<<ratio * new_width/original_width<<std::endl; 
     1585            double angle = 2.0*osg::RadiansToDegrees(atan(max_side_over_up)); 
     1586 
     1587 
     1588            if (angle > frustumDiagonal) 
     1589            { 
     1590                double maxHalfAngle = osg::DegreesToRadians(30.0); 
     1591                 
     1592                // move ratio back 
     1593                max_side_over_up = tan(maxHalfAngle); 
     1594                double lowest_up = min_up; 
     1595                 
     1596                for(i=0; i< projectedVertices.size(); ++i) 
     1597                { 
     1598                    double delta_side = fabs(projectedVertices[i].x() - mid_side); 
     1599                    double delta_up = delta_side / max_side_over_up;                     
     1600                    double local_base_up = projectedVertices[i].y() - delta_up; 
     1601                    if (local_base_up < lowest_up) 
     1602                    { 
     1603                        lowest_up = local_base_up; 
     1604                        double side_over_up = delta_side / delta_up; 
     1605                    } 
     1606                } 
     1607                 
     1608                double new_ratio = (min_up-lowest_up)/(max_up-lowest_up); 
     1609                 
     1610                //osg::notify(osg::NOTICE)<<"  originalRatio  = "<<ratio<<" new_ratio="<<new_ratio<<std::endl; 
     1611                 
     1612                if (new_ratio > ratio) ratio = new_ratio; 
     1613                 
     1614                base_up = lowest_up; 
     1615 
     1616            } 
     1617 
     1618            double max_half_width = max_side_over_up*(max_up - base_up); 
     1619            min_side = mid_side - max_half_width; 
     1620            max_side = mid_side + max_half_width; 
    15161621             
    1517             overlayData._exponent_scale->set(static_cast<float>(exponent_scale)); 
    1518             overlayData._exponent_offset->set(static_cast<float>(exponent_offset)); 
     1622            double new_width = max_side-min_side; 
     1623 
     1624         
     1625            double y0 = (1.0 + ratio) / (1.0 - ratio); 
     1626            overlayData._y0->set(static_cast<float>(y0)); 
    15191627             
    1520             osg::notify(osg::NOTICE)<<"exponent_scale = "<<exponent_scale<<std::endl; 
    1521             osg::notify(osg::NOTICE)<<"exponent_offset = "<<exponent_offset<<std::endl; 
    1522  
     1628 
     1629            // osg::notify(osg::NOTICE)<<"y0 = "<<y0<<std::endl; 
    15231630         
    15241631            overlayData._mainSubgraphStateSet->setAttribute(overlayData._mainSubgraphProgram.get()); 
     
    15791686        unsigned int contextID = cv->getState()!=0 ? cv->getState()->getContextID() : 0; 
    15801687 
    1581         if (usePerspectiveShaders) cv->pushStateSet(overlayData._overlayStateSet.get()); 
     1688        if (usePerspectiveShaders) 
     1689        { 
     1690            cv->pushStateSet(overlayData._overlayStateSet.get()); 
     1691             
     1692            typedef std::list<const osg::StateSet*> StateSetStack; 
     1693            StateSetStack statesetStack; 
     1694             
     1695            osgUtil::StateGraph* sg = cv->getCurrentStateGraph(); 
     1696            while(sg) 
     1697            { 
     1698                const osg::StateSet* stateset = sg->_stateset; 
     1699                if (stateset) 
     1700                { 
     1701                    statesetStack.push_front(stateset); 
     1702                }                 
     1703                sg = sg->_parent; 
     1704            } 
     1705             
     1706            osg::StateAttribute::GLModeValue base_mode = osg::StateAttribute::ON; 
     1707            for(StateSetStack::iterator itr = statesetStack.begin(); 
     1708                itr != statesetStack.end(); 
     1709                ++itr) 
     1710            { 
     1711                osg::StateAttribute::GLModeValue mode = (*itr)->getMode(GL_LIGHTING); 
     1712                if ((mode & ~osg::StateAttribute::INHERIT)!=0) 
     1713                { 
     1714                    if ((mode & osg::StateAttribute::PROTECTED)!=0 || 
     1715                        (base_mode & osg::StateAttribute::OVERRIDE)==0) 
     1716                    { 
     1717                        base_mode = mode; 
     1718                    } 
     1719                } 
     1720            } 
     1721             
     1722            overlayData._lightingEnabled->set((base_mode & osg::StateAttribute::ON)!=0); 
     1723        } 
    15821724         
    15831725        // if we need to redraw then do cull traversal on camera.