Stuart Buchanan :
- Replaces simple shader attributes with vectors (this was missed out of the last patch by mistake) - Includes Yon's Fog update code (Thanks!) - Fixes a bug since 1.0 where --enable-real-weather-fetch stopped the other weather scenarios from working.
This commit is contained in:
@@ -59,7 +59,7 @@ void CloudShaderGeometry::drawImplementation(RenderInfo& renderInfo) const
|
|||||||
float p = view_dir*_cloudsprites[0]->position.osg();
|
float p = view_dir*_cloudsprites[0]->position.osg();
|
||||||
// Do a single iteration of a bubble sort, sorting
|
// Do a single iteration of a bubble sort, sorting
|
||||||
// back to front.
|
// back to front.
|
||||||
for(int i = 0; i < _cloudsprites.size() - 1; i++)
|
for(unsigned int i = 0; i < _cloudsprites.size() - 1; i++)
|
||||||
{
|
{
|
||||||
float q = view_dir*_cloudsprites[i+1]->position.osg();
|
float q = view_dir*_cloudsprites[i+1]->position.osg();
|
||||||
if (p > q) {
|
if (p > q) {
|
||||||
@@ -103,12 +103,10 @@ void CloudShaderGeometry::drawImplementation(RenderInfo& renderInfo) const
|
|||||||
|
|
||||||
for(CloudSpriteList::const_iterator t = _cloudsprites.begin(); t != _cloudsprites.end(); ++t)
|
for(CloudSpriteList::const_iterator t = _cloudsprites.begin(); t != _cloudsprites.end(); ++t)
|
||||||
{
|
{
|
||||||
extensions->glVertexAttrib1f(TEXTURE_INDEX_X, (GLfloat) (*t)->texture_index_x/varieties_x);
|
GLfloat ua1[3] = { (GLfloat) (*t)->texture_index_x/varieties_x, (GLfloat) (*t)->texture_index_y/varieties_y, (*t)->width };
|
||||||
extensions->glVertexAttrib1f(TEXTURE_INDEX_Y, (GLfloat) (*t)->texture_index_y/varieties_y);
|
GLfloat ua2[3] = { (GLfloat) (*t)->height, (*t)->shade, (GLfloat) (*t)->cloud_height };
|
||||||
extensions->glVertexAttrib1f(WIDTH, (GLfloat) (*t)->width);
|
extensions->glVertexAttrib3fv(USR_ATTR_1, ua1 );
|
||||||
extensions->glVertexAttrib1f(HEIGHT, (GLfloat) (*t)->height);
|
extensions->glVertexAttrib3fv(USR_ATTR_2, ua2 );
|
||||||
extensions->glVertexAttrib1f(SHADE, (GLfloat) (*t)->shade);
|
|
||||||
extensions->glVertexAttrib1f(CLOUD_HEIGHT, (GLfloat) (*t)->cloud_height);
|
|
||||||
glColor4f((*t)->position.x(), (*t)->position.y(), (*t)->position.z(), 1.0);
|
glColor4f((*t)->position.x(), (*t)->position.y(), (*t)->position.z(), 1.0);
|
||||||
_geometry->draw(renderInfo);
|
_geometry->draw(renderInfo);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,12 +43,8 @@ class CloudShaderGeometry : public osg::Drawable
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
const static unsigned int CLOUD_HEIGHT = 10;
|
const static unsigned int USR_ATTR_1 = 10;
|
||||||
const static unsigned int TEXTURE_INDEX_X = 11;
|
const static unsigned int USR_ATTR_2 = 11;
|
||||||
const static unsigned int TEXTURE_INDEX_Y = 12;
|
|
||||||
const static unsigned int WIDTH = 13;
|
|
||||||
const static unsigned int HEIGHT = 14;
|
|
||||||
const static unsigned int SHADE = 15;
|
|
||||||
|
|
||||||
CloudShaderGeometry()
|
CloudShaderGeometry()
|
||||||
{
|
{
|
||||||
@@ -148,7 +144,7 @@ class CloudShaderGeometry : public osg::Drawable
|
|||||||
|
|
||||||
virtual ~CloudShaderGeometry() {
|
virtual ~CloudShaderGeometry() {
|
||||||
delete skip_info;
|
delete skip_info;
|
||||||
for (int i = 0; i < _cloudsprites.size(); i++)
|
for (unsigned int i = 0; i < _cloudsprites.size(); i++)
|
||||||
{
|
{
|
||||||
delete _cloudsprites[i];
|
delete _cloudsprites[i];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ using std::vector;
|
|||||||
|
|
||||||
#include <simgear/environment/visual_enviro.hxx>
|
#include <simgear/environment/visual_enviro.hxx>
|
||||||
#include <simgear/scene/util/RenderConstants.hxx>
|
#include <simgear/scene/util/RenderConstants.hxx>
|
||||||
|
#include <simgear/scene/util/SGUpdateVisitor.hxx>
|
||||||
#include "sky.hxx"
|
#include "sky.hxx"
|
||||||
#include "newcloud.hxx"
|
#include "newcloud.hxx"
|
||||||
#include "cloudfield.hxx"
|
#include "cloudfield.hxx"
|
||||||
@@ -69,7 +70,7 @@ float SGCloudField::coverage = 1.0f;
|
|||||||
double SGCloudField::timer_dt = 0.0;
|
double SGCloudField::timer_dt = 0.0;
|
||||||
float SGCloudField::view_distance = 20000.0f;
|
float SGCloudField::view_distance = 20000.0f;
|
||||||
sgVec3 SGCloudField::view_vec, SGCloudField::view_X, SGCloudField::view_Y;
|
sgVec3 SGCloudField::view_vec, SGCloudField::view_X, SGCloudField::view_Y;
|
||||||
|
SGCloudField::StateSetMap SGCloudField::cloudTextureMap;
|
||||||
|
|
||||||
// reposition the cloud layer at the specified origin and orientation
|
// reposition the cloud layer at the specified origin and orientation
|
||||||
bool SGCloudField::reposition( const SGVec3f& p, const SGVec3f& up, double lon, double lat,
|
bool SGCloudField::reposition( const SGVec3f& p, const SGVec3f& up, double lon, double lat,
|
||||||
@@ -136,6 +137,29 @@ bool SGCloudField::reposition( const SGVec3f& p, const SGVec3f& up, double lon,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct threeDCloudsFogUpdater : public osg::NodeCallback {
|
||||||
|
threeDCloudsFogUpdater() {};
|
||||||
|
|
||||||
|
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) {
|
||||||
|
SGUpdateVisitor* updateVisitor = static_cast<SGUpdateVisitor*>(nv);
|
||||||
|
//running at 5 times frame
|
||||||
|
SGCloudField::StateSetMap::iterator iter;
|
||||||
|
osg::Fog * fog;
|
||||||
|
for( iter = SGCloudField::cloudTextureMap.begin(); iter != SGCloudField::cloudTextureMap.end(); ++iter) {
|
||||||
|
fog = static_cast<osg::Fog*>(iter->second->getAttribute( osg::StateAttribute::FOG, 0 ));
|
||||||
|
fog->setMode(osg::Fog::EXP);
|
||||||
|
osg::Vec4f fogC = updateVisitor->getFogColor().osg();
|
||||||
|
fogC[3] = 0.0;
|
||||||
|
fog->setColor(fogC);
|
||||||
|
fog->setDensity(updateVisitor->getFogExpDensity());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->getNumChildrenRequiringUpdateTraversal()>0)
|
||||||
|
traverse(node,nv);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
SGCloudField::SGCloudField() :
|
SGCloudField::SGCloudField() :
|
||||||
field_root(new osg::Group),
|
field_root(new osg::Group),
|
||||||
field_transform(new osg::MatrixTransform),
|
field_transform(new osg::MatrixTransform),
|
||||||
@@ -147,6 +171,7 @@ SGCloudField::SGCloudField() :
|
|||||||
reposition_count(0)
|
reposition_count(0)
|
||||||
{
|
{
|
||||||
cld_pos = SGGeoc();
|
cld_pos = SGGeoc();
|
||||||
|
field_root->setUpdateCallback( new threeDCloudsFogUpdater() );
|
||||||
field_root->addChild(field_transform.get());
|
field_root->addChild(field_transform.get());
|
||||||
field_root->setName("3D Cloud field root");
|
field_root->setName("3D Cloud field root");
|
||||||
osg::StateSet *rootSet = field_root->getOrCreateStateSet();
|
osg::StateSet *rootSet = field_root->getOrCreateStateSet();
|
||||||
|
|||||||
@@ -123,6 +123,9 @@ public:
|
|||||||
|
|
||||||
void applyCoverage(void);
|
void applyCoverage(void);
|
||||||
void applyVisRange(void);
|
void applyVisRange(void);
|
||||||
|
|
||||||
|
typedef std::map<std::string, osg::ref_ptr<osg::StateSet> > StateSetMap;
|
||||||
|
static StateSetMap cloudTextureMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _CLOUDFIELD_HXX
|
#endif // _CLOUDFIELD_HXX
|
||||||
|
|||||||
@@ -61,21 +61,23 @@ typedef std::map<std::string, osg::ref_ptr<osg::StateSet> > StateSetMap;
|
|||||||
typedef std::vector< osg::ref_ptr<osg::Geode> > GeodeList;
|
typedef std::vector< osg::ref_ptr<osg::Geode> > GeodeList;
|
||||||
typedef std::map<std::string, GeodeList*> CloudMap;
|
typedef std::map<std::string, GeodeList*> CloudMap;
|
||||||
|
|
||||||
static StateSetMap cloudTextureMap;
|
StateSetMap cloudTextureMap;
|
||||||
static CloudMap cloudMap;
|
static CloudMap cloudMap;
|
||||||
double SGNewCloud::sprite_density = 1.0;
|
double SGNewCloud::sprite_density = 1.0;
|
||||||
int SGNewCloud::num_flavours = 10;
|
unsigned int SGNewCloud::num_flavours = 10;
|
||||||
|
|
||||||
static char vertexShaderSource[] =
|
static char vertexShaderSource[] =
|
||||||
"#version 120\n"
|
"#version 120\n"
|
||||||
"\n"
|
"\n"
|
||||||
"varying float fogFactor;\n"
|
"varying float fogFactor;\n"
|
||||||
"attribute float textureIndexX;\n"
|
"attribute vec3 usrAttr1;\n"
|
||||||
"attribute float textureIndexY;\n"
|
"attribute vec3 usrAttr2;\n"
|
||||||
"attribute float wScale;\n"
|
"float textureIndexX = usrAttr1.r;\n"
|
||||||
"attribute float hScale;\n"
|
"float textureIndexY = usrAttr1.g;\n"
|
||||||
"attribute float shade;\n"
|
"float wScale = usrAttr1.b;\n"
|
||||||
"attribute float cloud_height;\n"
|
"float hScale = usrAttr2.r;\n"
|
||||||
|
"float shade = usrAttr2.g;\n"
|
||||||
|
"float cloud_height = usrAttr2.b;\n"
|
||||||
"void main(void)\n"
|
"void main(void)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" gl_TexCoord[0] = gl_MultiTexCoord0 + vec4(textureIndexX, textureIndexY, 0.0, 0.0);\n"
|
" gl_TexCoord[0] = gl_MultiTexCoord0 + vec4(textureIndexX, textureIndexY, 0.0, 0.0);\n"
|
||||||
@@ -171,9 +173,9 @@ SGNewCloud::SGNewCloud(string type,
|
|||||||
name(type)
|
name(type)
|
||||||
{
|
{
|
||||||
// Create a new StateSet for the texture, if required.
|
// Create a new StateSet for the texture, if required.
|
||||||
StateSetMap::iterator iter = cloudTextureMap.find(texture);
|
StateSetMap::iterator iter = SGCloudField::cloudTextureMap.find(texture);
|
||||||
|
|
||||||
if (iter == cloudTextureMap.end()) {
|
if (iter == SGCloudField::cloudTextureMap.end()) {
|
||||||
stateSet = new osg::StateSet;
|
stateSet = new osg::StateSet;
|
||||||
|
|
||||||
osg::ref_ptr<osgDB::ReaderWriter::Options> options = makeOptionsFromPath(tex_path);
|
osg::ref_ptr<osgDB::ReaderWriter::Options> options = makeOptionsFromPath(tex_path);
|
||||||
@@ -213,13 +215,8 @@ SGNewCloud::SGNewCloud(string type,
|
|||||||
baseTextureSampler = new osg::Uniform("baseTexture", 0);
|
baseTextureSampler = new osg::Uniform("baseTexture", 0);
|
||||||
Shader* vertex_shader = new Shader(Shader::VERTEX, vertexShaderSource);
|
Shader* vertex_shader = new Shader(Shader::VERTEX, vertexShaderSource);
|
||||||
program->addShader(vertex_shader);
|
program->addShader(vertex_shader);
|
||||||
program->addBindAttribLocation("textureIndexX", CloudShaderGeometry::TEXTURE_INDEX_X);
|
program->addBindAttribLocation("usrAttr1", CloudShaderGeometry::USR_ATTR_1);
|
||||||
program->addBindAttribLocation("textureIndexY", CloudShaderGeometry::TEXTURE_INDEX_Y);
|
program->addBindAttribLocation("usrAttr2", CloudShaderGeometry::USR_ATTR_2);
|
||||||
program->addBindAttribLocation("wScale", CloudShaderGeometry::WIDTH);
|
|
||||||
program->addBindAttribLocation("hScale", CloudShaderGeometry::HEIGHT);
|
|
||||||
program->addBindAttribLocation("shade", CloudShaderGeometry::SHADE);
|
|
||||||
program->addBindAttribLocation("cloud_height", CloudShaderGeometry::CLOUD_HEIGHT);
|
|
||||||
|
|
||||||
Shader* fragment_shader = new Shader(Shader::FRAGMENT, fragmentShaderSource);
|
Shader* fragment_shader = new Shader(Shader::FRAGMENT, fragmentShaderSource);
|
||||||
program->addShader(fragment_shader);
|
program->addShader(fragment_shader);
|
||||||
material = new Material;
|
material = new Material;
|
||||||
@@ -240,7 +237,7 @@ SGNewCloud::SGNewCloud(string type,
|
|||||||
stateSet->setAttribute(material.get());
|
stateSet->setAttribute(material.get());
|
||||||
|
|
||||||
// Add the newly created texture to the map for use later.
|
// Add the newly created texture to the map for use later.
|
||||||
cloudTextureMap.insert(StateSetMap::value_type(texture, stateSet));
|
SGCloudField::cloudTextureMap.insert(StateSetMap::value_type(texture, stateSet));
|
||||||
} else {
|
} else {
|
||||||
stateSet = iter->second.get();
|
stateSet = iter->second.get();
|
||||||
}
|
}
|
||||||
@@ -310,10 +307,9 @@ osg::ref_ptr<Geode> SGNewCloud::genCloud() {
|
|||||||
// allows us to strike a balance between performance and
|
// allows us to strike a balance between performance and
|
||||||
// visual complexity.
|
// visual complexity.
|
||||||
|
|
||||||
GeodeList* g = (*iter).second;
|
if (iter == cloudMap.end() || (*iter).second->size() < num_flavours)
|
||||||
|
|
||||||
if (iter == cloudMap.end() || g->size() < num_flavours)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
geode = new Geode;
|
geode = new Geode;
|
||||||
|
|
||||||
CloudShaderGeometry* sg = new CloudShaderGeometry(num_textures_x, num_textures_y, max_width, max_height);
|
CloudShaderGeometry* sg = new CloudShaderGeometry(num_textures_x, num_textures_y, max_width, max_height);
|
||||||
@@ -405,7 +401,7 @@ osg::ref_ptr<Geode> SGNewCloud::genCloud() {
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Add the new cloud to the list of geodes
|
// Add the new cloud to the list of geodes
|
||||||
(*iter).second->push_back(geode.get());
|
(*iter).second->push_back(geode);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ private:
|
|||||||
osg::Geometry* quad;
|
osg::Geometry* quad;
|
||||||
osg::ref_ptr<osg::StateSet> stateSet;
|
osg::ref_ptr<osg::StateSet> stateSet;
|
||||||
static double sprite_density;
|
static double sprite_density;
|
||||||
static int num_flavours;
|
static unsigned int num_flavours;
|
||||||
|
|
||||||
osg::Geometry* createOrthQuad(float w, float h, int varieties_x, int varieties_y);
|
osg::Geometry* createOrthQuad(float w, float h, int varieties_x, int varieties_y);
|
||||||
|
|
||||||
@@ -113,5 +113,4 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _NEWCLOUD_HXX
|
#endif // _NEWCLOUD_HXX
|
||||||
|
|||||||
Reference in New Issue
Block a user