| 1 | #include <osg/Vec3> |
|---|
| 2 | #include <osg/Vec4> |
|---|
| 3 | #include <osg/Quat> |
|---|
| 4 | #include <osg/Matrix> |
|---|
| 5 | #include <osg/ShapeDrawable> |
|---|
| 6 | #include <osg/Geometry> |
|---|
| 7 | #include <osg/Geode> |
|---|
| 8 | #include <osg/Transform> |
|---|
| 9 | #include <osg/Material> |
|---|
| 10 | #include <osg/NodeCallback> |
|---|
| 11 | #include <osg/Depth> |
|---|
| 12 | #include <osg/CullFace> |
|---|
| 13 | #include <osg/TexMat> |
|---|
| 14 | #include <osg/TexGen> |
|---|
| 15 | #include <osg/TexEnvCombine> |
|---|
| 16 | #include <osg/TextureCubeMap> |
|---|
| 17 | #include <osg/VertexProgram> |
|---|
| 18 | |
|---|
| 19 | #include <osgDB/Registry> |
|---|
| 20 | #include <osgDB/ReadFile> |
|---|
| 21 | |
|---|
| 22 | #include <osgUtil/SmoothingVisitor> |
|---|
| 23 | #include <osgUtil/Optimizer> |
|---|
| 24 | |
|---|
| 25 | #include <osgProducer/Viewer> |
|---|
| 26 | |
|---|
| 27 | |
|---|
| 28 | float refract = 1.02; |
|---|
| 29 | float fresnel = 0.2; |
|---|
| 30 | |
|---|
| 31 | |
|---|
| 32 | const char vpstr[] = |
|---|
| 33 | "!!ARBvp1.0 # Refraction \n" |
|---|
| 34 | " \n" |
|---|
| 35 | "ATTRIB iPos = vertex.position; \n" |
|---|
| 36 | "#ATTRIB iCol = vertex.color.primary; \n" |
|---|
| 37 | "ATTRIB iNormal = vertex.normal; \n" |
|---|
| 38 | "PARAM esEyePos = { 0, 0, 0, 1 }; \n" |
|---|
| 39 | "PARAM const0123 = { 0, 1, 2, 3 }; \n" |
|---|
| 40 | "PARAM fresnel = program.local[0]; \n" |
|---|
| 41 | "PARAM refract = program.local[1]; \n" |
|---|
| 42 | "PARAM itMV[4] = { state.matrix.modelview.invtrans }; \n" |
|---|
| 43 | "PARAM MVP[4] = { state.matrix.mvp }; \n" |
|---|
| 44 | "PARAM MV[4] = { state.matrix.modelview }; \n" |
|---|
| 45 | "PARAM texmat[4] = { state.matrix.texture[0] }; \n" |
|---|
| 46 | "TEMP esPos; # position in eye-space \n" |
|---|
| 47 | "TEMP esNormal; # normal in eye-space \n" |
|---|
| 48 | "TEMP tmp, IdotN, K; \n" |
|---|
| 49 | "TEMP esE; # eye vector \n" |
|---|
| 50 | "TEMP esI; # incident vector (=-E) \n" |
|---|
| 51 | "TEMP esR; # first refract- then reflect-vector \n" |
|---|
| 52 | "OUTPUT oPos = result.position; \n" |
|---|
| 53 | "OUTPUT oColor = result.color; \n" |
|---|
| 54 | "OUTPUT oRefractMap = result.texcoord[0]; \n" |
|---|
| 55 | "OUTPUT oReflectMap = result.texcoord[1]; \n" |
|---|
| 56 | " \n" |
|---|
| 57 | "# transform vertex to clip space \n" |
|---|
| 58 | "DP4 oPos.x, MVP[0], iPos; \n" |
|---|
| 59 | "DP4 oPos.y, MVP[1], iPos; \n" |
|---|
| 60 | "DP4 oPos.z, MVP[2], iPos; \n" |
|---|
| 61 | "DP4 oPos.w, MVP[3], iPos; \n" |
|---|
| 62 | " \n" |
|---|
| 63 | "# Transform the normal to eye space. \n" |
|---|
| 64 | "DP3 esNormal.x, itMV[0], iNormal; \n" |
|---|
| 65 | "DP3 esNormal.y, itMV[1], iNormal; \n" |
|---|
| 66 | "DP3 esNormal.z, itMV[2], iNormal; \n" |
|---|
| 67 | " \n" |
|---|
| 68 | "# normalize normal \n" |
|---|
| 69 | "DP3 esNormal.w, esNormal, esNormal; \n" |
|---|
| 70 | "RSQ esNormal.w, esNormal.w; \n" |
|---|
| 71 | "MUL esNormal, esNormal, esNormal.w; \n" |
|---|
| 72 | " \n" |
|---|
| 73 | "# transform vertex position to eye space \n" |
|---|
| 74 | "DP4 esPos.x, MV[0], iPos; \n" |
|---|
| 75 | "DP4 esPos.y, MV[1], iPos; \n" |
|---|
| 76 | "DP4 esPos.z, MV[2], iPos; \n" |
|---|
| 77 | "DP4 esPos.w, MV[3], iPos; \n" |
|---|
| 78 | " \n" |
|---|
| 79 | "# vertex to eye vector \n" |
|---|
| 80 | "ADD esE, -esPos, esEyePos; \n" |
|---|
| 81 | "#MOV esE, -esPos; \n" |
|---|
| 82 | " \n" |
|---|
| 83 | "# normalize eye vector \n" |
|---|
| 84 | "DP3 esE.w, esE, esE; \n" |
|---|
| 85 | "RSQ esE.w, esE.w; \n" |
|---|
| 86 | "MUL esE, esE, esE.w; \n" |
|---|
| 87 | " \n" |
|---|
| 88 | "# calculate some handy values \n" |
|---|
| 89 | "MOV esI, -esE; \n" |
|---|
| 90 | "DP3 IdotN, esNormal, esI; \n" |
|---|
| 91 | " \n" |
|---|
| 92 | "# calculate refraction vector, Renderman style \n" |
|---|
| 93 | " \n" |
|---|
| 94 | "# k = 1-index*index*(1-(I dot N)^2) \n" |
|---|
| 95 | "MAD tmp, -IdotN, IdotN, const0123.y; \n" |
|---|
| 96 | "MUL tmp, tmp, refract.y; \n" |
|---|
| 97 | "ADD K.x, const0123.y, -tmp; \n" |
|---|
| 98 | " \n" |
|---|
| 99 | "# k<0, R = [0,0,0] \n" |
|---|
| 100 | "# k>=0, R = index*I-(index*(I dot N) + sqrt(k))*N \n" |
|---|
| 101 | "RSQ K.y, K.x; \n" |
|---|
| 102 | "RCP K.y, K.y; # K.y = sqrt(k) \n" |
|---|
| 103 | "MAD tmp.x, refract.x, IdotN, K.y; \n" |
|---|
| 104 | "MUL tmp, esNormal, tmp.x; \n" |
|---|
| 105 | "MAD esR, refract.x, esI, tmp; \n" |
|---|
| 106 | " \n" |
|---|
| 107 | "# transform refracted ray by cubemap transform \n" |
|---|
| 108 | "DP3 oRefractMap.x, texmat[0], esR; \n" |
|---|
| 109 | "DP3 oRefractMap.y, texmat[1], esR; \n" |
|---|
| 110 | "DP3 oRefractMap.z, texmat[2], esR; \n" |
|---|
| 111 | " \n" |
|---|
| 112 | "# calculate reflection vector \n" |
|---|
| 113 | "# R = 2*N*(N dot E)-E \n" |
|---|
| 114 | "MUL tmp, esNormal, const0123.z; \n" |
|---|
| 115 | "DP3 esR.w, esNormal, esE; \n" |
|---|
| 116 | "MAD esR, esR.w, tmp, -esE; \n" |
|---|
| 117 | " \n" |
|---|
| 118 | "# transform reflected ray by cubemap transform \n" |
|---|
| 119 | "DP3 oReflectMap.x, texmat[0], esR; \n" |
|---|
| 120 | "DP3 oReflectMap.y, texmat[1], esR; \n" |
|---|
| 121 | "DP3 oReflectMap.z, texmat[2], esR; \n" |
|---|
| 122 | " \n" |
|---|
| 123 | "# Fresnel approximation = fresnel*(1-(N dot I))^2 \n" |
|---|
| 124 | "ADD tmp.x, const0123.y, -IdotN; \n" |
|---|
| 125 | "MUL tmp.x, tmp.x, tmp.x; \n" |
|---|
| 126 | "MUL oColor, tmp.x, fresnel; \n" |
|---|
| 127 | " \n" |
|---|
| 128 | "END \n"; |
|---|
| 129 | |
|---|
| 130 | |
|---|
| 131 | osg::TextureCubeMap* readCubeMap() |
|---|
| 132 | { |
|---|
| 133 | osg::TextureCubeMap* cubemap = new osg::TextureCubeMap; |
|---|
| 134 | |
|---|
| 135 | |
|---|
| 136 | #define CUBEMAP_FILENAME(face) "Cubemap_snow/" #face ".jpg" |
|---|
| 137 | |
|---|
| 138 | osg::Image* imagePosX = osgDB::readImageFile(CUBEMAP_FILENAME(posx)); |
|---|
| 139 | osg::Image* imageNegX = osgDB::readImageFile(CUBEMAP_FILENAME(negx)); |
|---|
| 140 | osg::Image* imagePosY = osgDB::readImageFile(CUBEMAP_FILENAME(posy)); |
|---|
| 141 | osg::Image* imageNegY = osgDB::readImageFile(CUBEMAP_FILENAME(negy)); |
|---|
| 142 | osg::Image* imagePosZ = osgDB::readImageFile(CUBEMAP_FILENAME(posz)); |
|---|
| 143 | osg::Image* imageNegZ = osgDB::readImageFile(CUBEMAP_FILENAME(negz)); |
|---|
| 144 | |
|---|
| 145 | if (imagePosX && imageNegX && imagePosY && imageNegY && imagePosZ && imageNegZ) |
|---|
| 146 | { |
|---|
| 147 | cubemap->setImage(osg::TextureCubeMap::POSITIVE_X, imagePosX); |
|---|
| 148 | cubemap->setImage(osg::TextureCubeMap::NEGATIVE_X, imageNegX); |
|---|
| 149 | cubemap->setImage(osg::TextureCubeMap::POSITIVE_Y, imagePosY); |
|---|
| 150 | cubemap->setImage(osg::TextureCubeMap::NEGATIVE_Y, imageNegY); |
|---|
| 151 | cubemap->setImage(osg::TextureCubeMap::POSITIVE_Z, imagePosZ); |
|---|
| 152 | cubemap->setImage(osg::TextureCubeMap::NEGATIVE_Z, imageNegZ); |
|---|
| 153 | |
|---|
| 154 | cubemap->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); |
|---|
| 155 | cubemap->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); |
|---|
| 156 | cubemap->setWrap(osg::Texture::WRAP_R, osg::Texture::CLAMP_TO_EDGE); |
|---|
| 157 | |
|---|
| 158 | cubemap->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR); |
|---|
| 159 | cubemap->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); |
|---|
| 160 | } |
|---|
| 161 | |
|---|
| 162 | return cubemap; |
|---|
| 163 | } |
|---|
| 164 | |
|---|
| 165 | |
|---|
| 166 | |
|---|
| 167 | struct TexMatCallback : public osg::NodeCallback |
|---|
| 168 | { |
|---|
| 169 | public: |
|---|
| 170 | |
|---|
| 171 | TexMatCallback(osg::TexMat& tm) : |
|---|
| 172 | _texMat(tm) |
|---|
| 173 | { |
|---|
| 174 | } |
|---|
| 175 | |
|---|
| 176 | virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) |
|---|
| 177 | { |
|---|
| 178 | osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv); |
|---|
| 179 | if (cv) |
|---|
| 180 | { |
|---|
| 181 | const osg::Matrix& MV = cv->getModelViewMatrix(); |
|---|
| 182 | const osg::Matrix R = osg::Matrix::rotate( osg::DegreesToRadians(112.0f), 0.0f,0.0f,1.0f)* |
|---|
| 183 | osg::Matrix::rotate( osg::DegreesToRadians(90.0f), 1.0f,0.0f,0.0f); |
|---|
| 184 | |
|---|
| 185 | osg::Quat q; |
|---|
| 186 | MV.get(q); |
|---|
| 187 | const osg::Matrix C = osg::Matrix::rotate( q.inverse() ); |
|---|
| 188 | |
|---|
| 189 | _texMat.setMatrix( C*R ); |
|---|
| 190 | } |
|---|
| 191 | |
|---|
| 192 | traverse(node,nv); |
|---|
| 193 | } |
|---|
| 194 | |
|---|
| 195 | osg::TexMat& _texMat; |
|---|
| 196 | }; |
|---|
| 197 | |
|---|
| 198 | |
|---|
| 199 | class MoveEarthySkyWithEyePointTransform : public osg::Transform |
|---|
| 200 | { |
|---|
| 201 | public: |
|---|
| 202 | |
|---|
| 203 | virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const |
|---|
| 204 | { |
|---|
| 205 | osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv); |
|---|
| 206 | if (cv) |
|---|
| 207 | { |
|---|
| 208 | osg::Vec3 eyePointLocal = cv->getEyeLocal(); |
|---|
| 209 | matrix.preMult(osg::Matrix::translate(eyePointLocal)); |
|---|
| 210 | } |
|---|
| 211 | return true; |
|---|
| 212 | } |
|---|
| 213 | |
|---|
| 214 | |
|---|
| 215 | virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const |
|---|
| 216 | { |
|---|
| 217 | osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv); |
|---|
| 218 | if (cv) |
|---|
| 219 | { |
|---|
| 220 | osg::Vec3 eyePointLocal = cv->getEyeLocal(); |
|---|
| 221 | matrix.postMult(osg::Matrix::translate(-eyePointLocal)); |
|---|
| 222 | } |
|---|
| 223 | return true; |
|---|
| 224 | } |
|---|
| 225 | }; |
|---|
| 226 | |
|---|
| 227 | |
|---|
| 228 | osg::Node* createSkyBox() |
|---|
| 229 | { |
|---|
| 230 | |
|---|
| 231 | osg::StateSet* stateset = new osg::StateSet(); |
|---|
| 232 | |
|---|
| 233 | osg::TexEnv* te = new osg::TexEnv; |
|---|
| 234 | te->setMode(osg::TexEnv::REPLACE); |
|---|
| 235 | stateset->setTextureAttributeAndModes(0, te, osg::StateAttribute::ON); |
|---|
| 236 | |
|---|
| 237 | osg::TexGen *tg = new osg::TexGen; |
|---|
| 238 | tg->setMode(osg::TexGen::NORMAL_MAP); |
|---|
| 239 | stateset->setTextureAttributeAndModes(0, tg, osg::StateAttribute::ON); |
|---|
| 240 | |
|---|
| 241 | osg::TexMat *tm = new osg::TexMat; |
|---|
| 242 | stateset->setTextureAttribute(0, tm); |
|---|
| 243 | |
|---|
| 244 | osg::TextureCubeMap* skymap = readCubeMap(); |
|---|
| 245 | stateset->setTextureAttributeAndModes(0, skymap, osg::StateAttribute::ON); |
|---|
| 246 | |
|---|
| 247 | stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); |
|---|
| 248 | stateset->setMode( GL_CULL_FACE, osg::StateAttribute::OFF ); |
|---|
| 249 | |
|---|
| 250 | |
|---|
| 251 | osg::Depth* depth = new osg::Depth; |
|---|
| 252 | depth->setFunction(osg::Depth::ALWAYS); |
|---|
| 253 | depth->setRange(1.0,1.0); |
|---|
| 254 | stateset->setAttributeAndModes(depth, osg::StateAttribute::ON ); |
|---|
| 255 | |
|---|
| 256 | stateset->setRenderBinDetails(-1,"RenderBin"); |
|---|
| 257 | |
|---|
| 258 | osg::Drawable* drawable = new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f),1)); |
|---|
| 259 | |
|---|
| 260 | osg::Geode* geode = new osg::Geode; |
|---|
| 261 | geode->setCullingActive(false); |
|---|
| 262 | geode->setStateSet( stateset ); |
|---|
| 263 | geode->addDrawable(drawable); |
|---|
| 264 | |
|---|
| 265 | |
|---|
| 266 | osg::Transform* transform = new MoveEarthySkyWithEyePointTransform; |
|---|
| 267 | transform->setCullingActive(false); |
|---|
| 268 | transform->addChild(geode); |
|---|
| 269 | |
|---|
| 270 | osg::ClearNode* clearNode = new osg::ClearNode; |
|---|
| 271 | |
|---|
| 272 | clearNode->setCullCallback(new TexMatCallback(*tm)); |
|---|
| 273 | clearNode->addChild(transform); |
|---|
| 274 | |
|---|
| 275 | return clearNode; |
|---|
| 276 | } |
|---|
| 277 | |
|---|
| 278 | |
|---|
| 279 | |
|---|
| 280 | |
|---|
| 281 | osg::Node* addRefractStateSet(osg::Node* node) |
|---|
| 282 | { |
|---|
| 283 | osg::StateSet* stateset = new osg::StateSet(); |
|---|
| 284 | |
|---|
| 285 | osg::TextureCubeMap* reflectmap = readCubeMap(); |
|---|
| 286 | stateset->setTextureAttributeAndModes( 0, reflectmap, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE ); |
|---|
| 287 | stateset->setTextureAttributeAndModes( 1, reflectmap, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE ); |
|---|
| 288 | |
|---|
| 289 | osg::TexMat* texMat = new osg::TexMat; |
|---|
| 290 | stateset->setTextureAttribute(0, texMat); |
|---|
| 291 | |
|---|
| 292 | |
|---|
| 293 | |
|---|
| 294 | |
|---|
| 295 | osg::VertexProgram* vp = new osg::VertexProgram(); |
|---|
| 296 | vp->setVertexProgram( vpstr ); |
|---|
| 297 | vp->setProgramLocalParameter( 0, osg::Vec4( fresnel, fresnel, fresnel, 1.0f ) ); |
|---|
| 298 | vp->setProgramLocalParameter( 1, osg::Vec4( refract, refract*refract, 0.0f, 0.0f ) ); |
|---|
| 299 | stateset->setAttributeAndModes( vp, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE ); |
|---|
| 300 | |
|---|
| 301 | |
|---|
| 302 | |
|---|
| 303 | |
|---|
| 304 | |
|---|
| 305 | |
|---|
| 306 | |
|---|
| 307 | |
|---|
| 308 | |
|---|
| 309 | |
|---|
| 310 | |
|---|
| 311 | |
|---|
| 312 | osg::TexEnvCombine *te0 = new osg::TexEnvCombine; |
|---|
| 313 | te0->setCombine_RGB(osg::TexEnvCombine::REPLACE); |
|---|
| 314 | te0->setSource0_RGB(osg::TexEnvCombine::TEXTURE0); |
|---|
| 315 | te0->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR); |
|---|
| 316 | |
|---|
| 317 | |
|---|
| 318 | |
|---|
| 319 | osg::TexEnvCombine *te1 = new osg::TexEnvCombine; |
|---|
| 320 | |
|---|
| 321 | |
|---|
| 322 | te1->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); |
|---|
| 323 | te1->setSource0_RGB(osg::TexEnvCombine::TEXTURE1); |
|---|
| 324 | te1->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR); |
|---|
| 325 | te1->setSource1_RGB(osg::TexEnvCombine::PREVIOUS); |
|---|
| 326 | te1->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR); |
|---|
| 327 | te1->setSource2_RGB(osg::TexEnvCombine::PRIMARY_COLOR); |
|---|
| 328 | te1->setOperand2_RGB(osg::TexEnvCombine::SRC_COLOR); |
|---|
| 329 | |
|---|
| 330 | stateset->setTextureAttributeAndModes(0, te0, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); |
|---|
| 331 | stateset->setTextureAttributeAndModes(1, te1, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); |
|---|
| 332 | |
|---|
| 333 | osg::Group* group = new osg::Group; |
|---|
| 334 | group->addChild(node); |
|---|
| 335 | group->setCullCallback(new TexMatCallback(*texMat)); |
|---|
| 336 | group->setStateSet( stateset ); |
|---|
| 337 | |
|---|
| 338 | return group; |
|---|
| 339 | } |
|---|
| 340 | |
|---|
| 341 | |
|---|
| 342 | int main(int argc, char *argv[]) |
|---|
| 343 | { |
|---|
| 344 | |
|---|
| 345 | osg::ArgumentParser arguments(&argc,argv); |
|---|
| 346 | |
|---|
| 347 | |
|---|
| 348 | arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrate support for ARB_vertex_program."); |
|---|
| 349 | arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); |
|---|
| 350 | arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); |
|---|
| 351 | |
|---|
| 352 | |
|---|
| 353 | osgProducer::Viewer viewer(arguments); |
|---|
| 354 | |
|---|
| 355 | |
|---|
| 356 | viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS); |
|---|
| 357 | |
|---|
| 358 | |
|---|
| 359 | viewer.getUsage(*arguments.getApplicationUsage()); |
|---|
| 360 | |
|---|
| 361 | |
|---|
| 362 | if (arguments.read("-h") || arguments.read("--help")) |
|---|
| 363 | { |
|---|
| 364 | arguments.getApplicationUsage()->write(std::cout); |
|---|
| 365 | return 1; |
|---|
| 366 | } |
|---|
| 367 | |
|---|
| 368 | |
|---|
| 369 | arguments.reportRemainingOptionsAsUnrecognized(); |
|---|
| 370 | |
|---|
| 371 | |
|---|
| 372 | if (arguments.errors()) |
|---|
| 373 | { |
|---|
| 374 | arguments.writeErrorMessages(std::cout); |
|---|
| 375 | return 1; |
|---|
| 376 | } |
|---|
| 377 | |
|---|
| 378 | osg::Group* rootnode = new osg::Group; |
|---|
| 379 | |
|---|
| 380 | rootnode->addChild(createSkyBox()); |
|---|
| 381 | |
|---|
| 382 | |
|---|
| 383 | osg::Node* model = osgDB::readNodeFiles(arguments); |
|---|
| 384 | if (!model) |
|---|
| 385 | { |
|---|
| 386 | const float radius = 1.0f; |
|---|
| 387 | osg::Geode* geode = new osg::Geode; |
|---|
| 388 | geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f),radius))); |
|---|
| 389 | model = geode; |
|---|
| 390 | } |
|---|
| 391 | |
|---|
| 392 | |
|---|
| 393 | osgUtil::Optimizer optimzer; |
|---|
| 394 | optimzer.optimize(model); |
|---|
| 395 | |
|---|
| 396 | |
|---|
| 397 | osgUtil::SmoothingVisitor smoother; |
|---|
| 398 | model->accept(smoother); |
|---|
| 399 | |
|---|
| 400 | rootnode->addChild( addRefractStateSet(model) ); |
|---|
| 401 | |
|---|
| 402 | |
|---|
| 403 | viewer.setSceneData(rootnode); |
|---|
| 404 | |
|---|
| 405 | |
|---|
| 406 | viewer.realize(); |
|---|
| 407 | |
|---|
| 408 | |
|---|
| 409 | for(unsigned int contextID = 0; |
|---|
| 410 | contextID<viewer.getDisplaySettings()->getMaxNumberOfGraphicsContexts(); |
|---|
| 411 | ++contextID) |
|---|
| 412 | { |
|---|
| 413 | osg::VertexProgram::Extensions* vpExt = osg::VertexProgram::getExtensions(contextID,false); |
|---|
| 414 | if (vpExt) |
|---|
| 415 | { |
|---|
| 416 | if (!vpExt->isVertexProgramSupported()) |
|---|
| 417 | { |
|---|
| 418 | std::cout<<"Warning: ARB_vertex_program not supported by OpenGL drivers, unable to run application."<<std::endl; |
|---|
| 419 | return 1; |
|---|
| 420 | } |
|---|
| 421 | } |
|---|
| 422 | } |
|---|
| 423 | |
|---|
| 424 | while( !viewer.done() ) |
|---|
| 425 | { |
|---|
| 426 | |
|---|
| 427 | viewer.sync(); |
|---|
| 428 | |
|---|
| 429 | |
|---|
| 430 | |
|---|
| 431 | viewer.update(); |
|---|
| 432 | |
|---|
| 433 | |
|---|
| 434 | viewer.frame(); |
|---|
| 435 | |
|---|
| 436 | } |
|---|
| 437 | |
|---|
| 438 | |
|---|
| 439 | viewer.sync(); |
|---|
| 440 | |
|---|
| 441 | return 0; |
|---|
| 442 | } |
|---|