WS30 Uniform arrays and photoscenery search path
This commit is contained in:
parent
2ec9df7597
commit
0470375889
@ -354,30 +354,12 @@ SGMaterialCache::Atlas SGMaterialLib::getMaterialTextureAtlas(SGVec2f center, co
|
|||||||
|
|
||||||
atlas.image = new osg::Texture2DArray();
|
atlas.image = new osg::Texture2DArray();
|
||||||
|
|
||||||
osg::ref_ptr<osg::Image> dimensionImage = new osg::Image();
|
if (landclasslib.size() > 128) SG_LOG(SG_TERRAIN, SG_ALERT, "Too many landclass entries for uniform arrays");
|
||||||
dimensionImage->allocateImage(512, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE);
|
|
||||||
atlas.dimensions = new osg::Texture1D(dimensionImage.get());
|
atlas.dimensions = new osg::Uniform(osg::Uniform::Type::FLOAT_VEC4, "dimensionsArray", 128);
|
||||||
atlas.dimensions->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
|
atlas.ambient = new osg::Uniform(osg::Uniform::Type::FLOAT_VEC4, "ambientArray", 128);
|
||||||
atlas.dimensions->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
|
atlas.diffuse = new osg::Uniform(osg::Uniform::Type::FLOAT_VEC4, "diffuseArray", 128);
|
||||||
atlas.dimensions->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP);
|
atlas.specular = new osg::Uniform(osg::Uniform::Type::FLOAT_VEC4, "specularArray", 128);
|
||||||
atlas.dimensions->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP);
|
|
||||||
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::Image> diffuseImage = new osg::Image();
|
|
||||||
diffuseImage->allocateImage(512, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE);
|
|
||||||
atlas.diffuse = new osg::Texture1D(diffuseImage.get());
|
|
||||||
atlas.diffuse->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
|
|
||||||
atlas.diffuse->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
|
|
||||||
atlas.diffuse->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP);
|
|
||||||
atlas.diffuse->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP);
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::Image> specularImage = new osg::Image();
|
|
||||||
specularImage->allocateImage(512, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE);
|
|
||||||
atlas.specular = new osg::Texture1D(specularImage.get());
|
|
||||||
atlas.specular->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
|
|
||||||
atlas.specular->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
|
|
||||||
atlas.specular->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP);
|
|
||||||
atlas.specular->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP);
|
|
||||||
|
|
||||||
atlas.image->setMaxAnisotropy(SGSceneFeatures::instance()->getTextureFilter());
|
atlas.image->setMaxAnisotropy(SGSceneFeatures::instance()->getTextureFilter());
|
||||||
atlas.image->setResizeNonPowerOfTwoHint(false);
|
atlas.image->setResizeNonPowerOfTwoHint(false);
|
||||||
@ -385,57 +367,53 @@ SGMaterialCache::Atlas SGMaterialLib::getMaterialTextureAtlas(SGVec2f center, co
|
|||||||
atlas.image->setWrap(osg::Texture::WRAP_S,osg::Texture::REPEAT);
|
atlas.image->setWrap(osg::Texture::WRAP_S,osg::Texture::REPEAT);
|
||||||
atlas.image->setWrap(osg::Texture::WRAP_T,osg::Texture::REPEAT);
|
atlas.image->setWrap(osg::Texture::WRAP_T,osg::Texture::REPEAT);
|
||||||
|
|
||||||
int index = -1;
|
unsigned int index = 0;
|
||||||
lc_iter = landclasslib.begin();
|
lc_iter = landclasslib.begin();
|
||||||
for (; lc_iter != landclasslib.end(); ++lc_iter) {
|
for (; lc_iter != landclasslib.end(); ++lc_iter) {
|
||||||
// index is incremented at the start of the loop so that we have a valid
|
|
||||||
// mapping based on the lanclassList, even if we fail to process the texture.
|
|
||||||
++index;
|
|
||||||
int i = lc_iter->first;
|
int i = lc_iter->first;
|
||||||
SGMaterial* mat = find(lc_iter->second.first, center);
|
SGMaterial* mat = find(lc_iter->second.first, center);
|
||||||
atlas.index[i] = index;
|
atlas.index[i] = index;
|
||||||
atlas.waterAtlas[i] = lc_iter->second.second;
|
atlas.waterAtlas[i] = lc_iter->second.second;
|
||||||
|
|
||||||
if (mat == NULL) continue;
|
if (mat != NULL) {
|
||||||
|
|
||||||
// Just get the first texture in the first texture-set for the moment.
|
// Just get the first texture in the first texture-set for the moment.
|
||||||
// Should add some variability in texture-set in the future.
|
// Should add some variability in texture-set in the future.
|
||||||
const std::string texture = mat->get_one_texture(0,0);
|
const std::string texture = mat->get_one_texture(0,0);
|
||||||
if (texture.empty()) continue;
|
if (! texture.empty()) {
|
||||||
|
if (texture.empty()) continue;
|
||||||
|
|
||||||
SGPath texturePath = SGPath("Textures");
|
SGPath texturePath = SGPath("Textures");
|
||||||
//texturePath.append(texture);
|
//texturePath.append(texture);
|
||||||
std::string fullPath = SGModelLib::findDataFile(texture, options, texturePath);
|
std::string fullPath = SGModelLib::findDataFile(texture, options, texturePath);
|
||||||
|
|
||||||
if (fullPath.empty()) {
|
if (fullPath.empty()) {
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "Cannot find texture \""
|
SG_LOG(SG_GENERAL, SG_ALERT, "Cannot find texture \""
|
||||||
<< texture << "\" in Textures folders when creating texture atlas");
|
<< texture << "\" in Textures folders when creating texture atlas");
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Copy the texture into the atlas in the appropriate place
|
|
||||||
osg::ref_ptr<osg::Image> subtexture = osgDB::readRefImageFile(fullPath, options);
|
|
||||||
|
|
||||||
if (subtexture && subtexture->valid()) {
|
|
||||||
|
|
||||||
if ((subtexture->s() != 2048) || (subtexture->t() != 2048)) {
|
|
||||||
subtexture->scaleImage(2048,2048,1);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Copy the texture into the atlas in the appropriate place
|
||||||
|
osg::ref_ptr<osg::Image> subtexture = osgDB::readRefImageFile(fullPath, options);
|
||||||
|
|
||||||
// Add other useful information, such as the texture size in m.
|
if (subtexture && subtexture->valid()) {
|
||||||
// As we pack the texture size into a texture, we need to scale to [0..1.0]
|
|
||||||
float x_size = (0 < mat->get_xsize()) ? mat->get_xsize()/10000.0 : 0.1f;
|
|
||||||
float y_size = (0 < mat->get_ysize()) ? mat->get_ysize()/10000.0 : 0.1f;
|
|
||||||
|
|
||||||
SG_LOG(SG_TERRAIN, SG_DEBUG, "Adding image " << fullPath << " to texture atlas " << x_size << " " << y_size);
|
if ((subtexture->s() != 2048) || (subtexture->t() != 2048)) {
|
||||||
atlas.image->setImage(index,subtexture);
|
subtexture->scaleImage(2048,2048,1);
|
||||||
|
}
|
||||||
|
|
||||||
atlas.dimensions->getImage()->setColor(osg::Vec4(x_size, y_size, mat->get_shininess(), 1.0f), index);
|
atlas.image->setImage(index,subtexture);
|
||||||
atlas.diffuse->getImage()->setColor(mat->get_diffuse(), index);
|
atlas.dimensions->setElement(index, osg::Vec4f(mat->get_xsize(), mat->get_ysize(), mat->get_shininess(), 1.0f));
|
||||||
atlas.specular->getImage()->setColor(mat->get_specular(), index);
|
atlas.ambient->setElement(index, mat->get_ambient());
|
||||||
|
atlas.diffuse->setElement(index, mat->get_diffuse());
|
||||||
|
atlas.specular->setElement(index, mat->get_specular());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
++index;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache for future lookups
|
// Cache for future lookups
|
||||||
|
@ -59,9 +59,10 @@ public:
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
AtlasIndex index;
|
AtlasIndex index;
|
||||||
AtlasImage image;
|
AtlasImage image;
|
||||||
osg::ref_ptr<osg::Texture1D> dimensions;
|
osg::ref_ptr<osg::Uniform> dimensions;
|
||||||
osg::ref_ptr<osg::Texture1D> diffuse;
|
osg::ref_ptr<osg::Uniform> ambient;
|
||||||
osg::ref_ptr<osg::Texture1D> specular;
|
osg::ref_ptr<osg::Uniform> diffuse;
|
||||||
|
osg::ref_ptr<osg::Uniform> specular;
|
||||||
WaterAtlas waterAtlas;
|
WaterAtlas waterAtlas;
|
||||||
} Atlas;
|
} Atlas;
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ VPBTechnique::VPBTechnique():
|
|||||||
_randomObjectsConstraintGroup = new osg::Group();
|
_randomObjectsConstraintGroup = new osg::Group();
|
||||||
}
|
}
|
||||||
|
|
||||||
VPBTechnique::VPBTechnique(const SGReaderWriterOptions* options, const string& fileName):
|
VPBTechnique::VPBTechnique(const SGReaderWriterOptions* options, const string fileName):
|
||||||
_fileName(fileName)
|
_fileName(fileName)
|
||||||
{
|
{
|
||||||
setFilterBias(0);
|
setFilterBias(0);
|
||||||
@ -1296,20 +1296,29 @@ void VPBTechnique::applyColorLayers(BufferData& buffer, Locator* masterLocator)
|
|||||||
// Firstly, we need to work out the texture file we want to load. Fortunately this follows the same
|
// Firstly, we need to work out the texture file we want to load. Fortunately this follows the same
|
||||||
// naming convention as the VPB scenery itself.
|
// naming convention as the VPB scenery itself.
|
||||||
auto tileID = _terrainTile->getTileID();
|
auto tileID = _terrainTile->getTileID();
|
||||||
SG_LOG(SG_TERRAIN, SG_DEBUG, "Using Photoscenery for " << tileID.level << " X" << tileID.x << " Y" << tileID.y);
|
SG_LOG(SG_TERRAIN, SG_DEBUG, "Using Photoscenery for " << _fileName << " " << tileID.level << " X" << tileID.x << " Y" << tileID.y);
|
||||||
|
|
||||||
const osg::Vec3d world = buffer._transform->getMatrix().getTrans();
|
const osg::Vec3d world = buffer._transform->getMatrix().getTrans();
|
||||||
const SGGeod loc = SGGeod::fromCart(toSG(world));
|
const SGGeod loc = SGGeod::fromCart(toSG(world));
|
||||||
const SGBucket bucket = SGBucket(loc);
|
const SGBucket bucket = SGBucket(loc);
|
||||||
|
SGPath orthotexture;
|
||||||
|
|
||||||
// Bit of a hack - we assume the Orthophotos are in the same FG_SCENERY top level as the .osgb tiles.
|
osgDB::FilePathList& pathList = _options->getDatabasePathList();
|
||||||
string base = _fileName.substr(0, _fileName.find("vpb"));
|
bool found = false;
|
||||||
SGPath orthotexture = SGPath(base);
|
|
||||||
orthotexture.append("Orthophotos");
|
|
||||||
orthotexture.append(bucket.gen_vpb_subtile(tileID.level, tileID.x, tileID.y) + ".dds");
|
|
||||||
SG_LOG(SG_TERRAIN, SG_DEBUG, "Using phototexture " << orthotexture);
|
|
||||||
|
|
||||||
if (orthotexture.exists()) {
|
for (auto iter = pathList.begin(); !found && iter != pathList.end(); ++iter) {
|
||||||
|
orthotexture = SGPath(*iter);
|
||||||
|
orthotexture.append("Orthophotos");
|
||||||
|
orthotexture.append(bucket.gen_vpb_subtile(tileID.level, tileID.x, tileID.y) + ".dds");
|
||||||
|
SG_LOG(SG_TERRAIN, SG_DEBUG, "Looking for phototexture " << orthotexture);
|
||||||
|
|
||||||
|
if (orthotexture.exists()) {
|
||||||
|
found = true;
|
||||||
|
SG_LOG(SG_TERRAIN, SG_DEBUG, "Found phototexture " << orthotexture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
// Set up the texture with wrapping of UV to reduce black edges at tile boundaries.
|
// Set up the texture with wrapping of UV to reduce black edges at tile boundaries.
|
||||||
osg::Texture2D* texture = SGLoadTexture2D(SGPath(orthotexture), _options, true, true);
|
osg::Texture2D* texture = SGLoadTexture2D(SGPath(orthotexture), _options, true, true);
|
||||||
osg::StateSet* stateset = buffer._landGeode->getOrCreateStateSet();
|
osg::StateSet* stateset = buffer._landGeode->getOrCreateStateSet();
|
||||||
@ -1369,10 +1378,11 @@ void VPBTechnique::applyColorLayers(BufferData& buffer, Locator* masterLocator)
|
|||||||
osg::StateSet* stateset = buffer._landGeode->getOrCreateStateSet();
|
osg::StateSet* stateset = buffer._landGeode->getOrCreateStateSet();
|
||||||
stateset->setTextureAttributeAndModes(0, texture2D, osg::StateAttribute::ON);
|
stateset->setTextureAttributeAndModes(0, texture2D, osg::StateAttribute::ON);
|
||||||
stateset->setTextureAttributeAndModes(1, atlas.image, osg::StateAttribute::ON);
|
stateset->setTextureAttributeAndModes(1, atlas.image, osg::StateAttribute::ON);
|
||||||
stateset->setTextureAttributeAndModes(2, atlas.dimensions, osg::StateAttribute::ON);
|
|
||||||
stateset->setTextureAttributeAndModes(3, atlas.diffuse, osg::StateAttribute::ON);
|
|
||||||
stateset->setTextureAttributeAndModes(4, atlas.specular, osg::StateAttribute::ON);
|
|
||||||
stateset->addUniform(new osg::Uniform("photoScenery", false));
|
stateset->addUniform(new osg::Uniform("photoScenery", false));
|
||||||
|
stateset->addUniform(atlas.dimensions);
|
||||||
|
stateset->addUniform(atlas.ambient);
|
||||||
|
stateset->addUniform(atlas.diffuse);
|
||||||
|
stateset->addUniform(atlas.specular);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ class VPBTechnique : public TerrainTechnique
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
VPBTechnique();
|
VPBTechnique();
|
||||||
VPBTechnique(const SGReaderWriterOptions* options, const string& fileName);
|
VPBTechnique(const SGReaderWriterOptions* options, const string fileName);
|
||||||
|
|
||||||
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
|
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
|
||||||
VPBTechnique(const VPBTechnique&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
|
VPBTechnique(const VPBTechnique&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
|
||||||
|
Loading…
Reference in New Issue
Block a user