X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fscene%2Fsky%2Fcloud.cxx;h=5ff1b0891ebdbbe671e60a6ee6f31e766783deba;hb=813b518b6f0c3e772fbd521d75106a650e69a084;hp=b97d39b08b267d699939e6f09a59a9d9d786421f;hpb=d3bacd0b738416da978c49149f50dbf909c5e41d;p=simgear.git diff --git a/simgear/scene/sky/cloud.cxx b/simgear/scene/sky/cloud.cxx index b97d39b0..5ff1b089 100644 --- a/simgear/scene/sky/cloud.cxx +++ b/simgear/scene/sky/cloud.cxx @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -75,7 +76,8 @@ bool SGCloudLayer::enable_bump_mapping = false; // make an StateSet for a cloud layer given the named texture static osg::StateSet* -SGMakeState(const SGPath &path, const char* colorTexture, const char* normalTexture) +SGMakeState(const SGPath &path, const char* colorTexture, + const char* normalTexture) { osg::StateSet *stateSet = new osg::StateSet; @@ -157,6 +159,11 @@ SGCloudLayer::SGCloudLayer( const string &tex_path ) : { layer_root->addChild(group_bottom.get()); layer_root->addChild(group_top.get()); + // Force the cloud layers into recursive bins of bin 4. + osg::StateSet *rootSet = layer_root->getOrCreateStateSet(); + rootSet->setRenderBinDetails(4, "RenderBin"); + rootSet->setTextureAttribute(0, new osg::TexMat()); + base = osg::Vec2(sg_random(), sg_random()); group_top->addChild(layer_transform.get()); group_bottom->addChild(layer_transform.get()); @@ -244,6 +251,17 @@ SGCloudLayer::setCoverage (Coverage coverage) } } +void +SGCloudLayer::setTextureOffset(const osg::Vec2& offset) +{ + osg::StateAttribute* attr = layer_root->getStateSet() + ->getTextureAttribute(0, osg::StateAttribute::TEXMAT); + osg::TexMat* texMat = dynamic_cast(attr); + if (!texMat) + return; + texMat->setMatrix(osg::Matrix::translate(offset[0], offset[1], 0.0)); +} + // build the cloud object void SGCloudLayer::rebuild() @@ -418,9 +436,8 @@ SGCloudLayer::rebuild() scale = 4000.0; last_lon = last_lat = -999.0f; - - base = osg::Vec2(sg_random(), sg_random()); - + + setTextureOffset(base); // build the cloud layer const float layer_scale = layer_span / scale; const float mpi = SG_PI/4; @@ -447,7 +464,7 @@ SGCloudLayer::rebuild() osg::Vec3 vertex(layer_span*(i-2)/2, -layer_span, alt_diff * (sin(i*mpi) - 2)); - osg::Vec2 tc(base[0] + layer_scale * i/4, base[1]); + osg::Vec2 tc(layer_scale * i/4, 0.0f); osg::Vec4 color(1.0f, 1.0f, 1.0f, (i == 0) ? 0.0f : 0.15f); cl[i]->push_back(color); @@ -457,8 +474,7 @@ SGCloudLayer::rebuild() for (int j = 0; j < 4; j++) { vertex = osg::Vec3(layer_span*(i-1)/2, layer_span*(j-2)/2, alt_diff * (sin((i+1)*mpi) + sin(j*mpi) - 2)); - tc = osg::Vec2(base[0] + layer_scale * (i+1)/4, - base[1] + layer_scale * j/4); + tc = osg::Vec2(layer_scale * (i+1)/4, layer_scale * j/4); color = osg::Vec4(1.0f, 1.0f, 1.0f, ( (j == 0) || (i == 3)) ? ( (j == 0) && (i == 3)) ? 0.0f : 0.15f : 1.0f ); @@ -469,8 +485,7 @@ SGCloudLayer::rebuild() vertex = osg::Vec3(layer_span*(i-2)/2, layer_span*(j-1)/2, alt_diff * (sin(i*mpi) + sin((j+1)*mpi) - 2) ); - tc = osg::Vec2(base[0] + layer_scale * i/4, - base[1] + layer_scale * (j+1)/4 ); + tc = osg::Vec2(layer_scale * i/4, layer_scale * (j+1)/4 ); color = osg::Vec4(1.0f, 1.0f, 1.0f, ((j == 3) || (i == 0)) ? ((j == 3) && (i == 0)) ? 0.0f : 0.15f : 1.0f ); @@ -482,8 +497,7 @@ SGCloudLayer::rebuild() vertex = osg::Vec3(layer_span*(i-1)/2, layer_span, alt_diff * (sin((i+1)*mpi) - 2)); - tc = osg::Vec2(base[0] + layer_scale * (i+1)/4, - base[1] + layer_scale); + tc = osg::Vec2(layer_scale * (i+1)/4, layer_scale); color = osg::Vec4(1.0f, 1.0f, 1.0f, (i == 3) ? 0.0f : 0.15f ); @@ -513,13 +527,12 @@ SGCloudLayer::rebuild() if ( layer_states[layer_coverage].valid() ) { osg::CopyOp copyOp(osg::CopyOp::DEEP_COPY_ALL & ~osg::CopyOp::DEEP_COPY_TEXTURES); - + // render bin will be set in reposition osg::StateSet* stateSet = static_cast(layer_states2[layer_coverage]->clone(copyOp)); - // OSGFIXME - stateSet->setRenderBinDetails(4, "RenderBin"); + stateSet->setDataVariance(osg::Object::DYNAMIC); group_top->setStateSet(stateSet); stateSet = static_cast(layer_states2[layer_coverage]->clone(copyOp)); - stateSet->setRenderBinDetails(4, "RenderBin"); + stateSet->setDataVariance(osg::Object::DYNAMIC); group_bottom->setStateSet(stateSet); } } @@ -847,12 +860,24 @@ bool SGCloudLayer::reposition( const SGVec3f& p, const SGVec3f& up, double lon, LAT.makeRotate(90.0 * SGD_DEGREES_TO_RADIANS - lat, osg::Vec3(0, 1, 0)); layer_transform->setMatrix( LAT*LON*T ); - + // The layers need to be drawn in order because they are + // translucent, but OSG transparency sorting doesn't work because + // the cloud polys are huge. However, the ordering is simple: the + // bottom polys should be drawn from high altitude to low, and the + // top polygons from low to high. The altitude can be used + // directly to order the polygons! + layer_root->getChild(0)->getStateSet()->setRenderBinDetails(-(int)layer_asl, + "RenderBin"); + layer_root->getChild(1)->getStateSet()->setRenderBinDetails((int)layer_asl, + "RenderBin"); if ( alt <= layer_asl ) { layer_root->setSingleChildOn(0); - } else { + } else if ( alt >= layer_asl + layer_thickness ) { layer_root->setSingleChildOn(1); + } else { + layer_root->setAllChildrenOff(); } + // now calculate update texture coordinates if ( last_lon < -900 ) { @@ -932,15 +957,7 @@ bool SGCloudLayer::reposition( const SGVec3f& p, const SGVec3f& up, double lon, // cout << "base = " << base[0] << "," << base[1] << endl; - for (int i = 0; i < 4; i++) { - (*tl[i])[0] = base + osg::Vec2(i, 0)*layer_scale/4; - for (int j = 0; j < 4; j++) { - (*tl[i])[j*2+1] = base + osg::Vec2(i+1, j)*layer_scale/4; - (*tl[i])[j*2+2] = base + osg::Vec2(i, j+1)*layer_scale/4; - } - (*tl[i])[9] = base + osg::Vec2(i+1, 4)*layer_scale/4; - } - + setTextureOffset(base); last_lon = lon; last_lat = lat; }