|
楼主 |
发表于 2011-9-17 07:30:45
|
显示全部楼层
回复 2# array
static osg::ref_ptr<osg::Group> rootNode;
static osg:rogram* BlockyProgram;
static osg::Shader* BlockyVertObj;
static osg::Shader* BlockyFragObj;
static osg::Program* ErodedProgram;
static osg::Shader* ErodedVertObj;
static osg::Shader* ErodedFragObj;
static osg::Program* MarbleProgram;
static osg::Shader* MarbleVertObj;
static osg::Shader* MarbleFragObj;
#define TEXUNIT_SINE 1
#define TEXUNIT_NOISE 2
class GeodeVisitor:public osg::NodeVisitor
{
public:
GeodeVisitor::GeodeVisitor(const std::string &searchName1,const std::string &searchName2,const std::string &searchName3,const std::string &searchName4,const std::string &searchName5,const std::string &searchName6,const std::string &searchName7,const std::string &searchName8,const std::string &searchName9,const std::string &searchName10,const std::string &searchName11,const std::string &searchName12,const std::string &searchName13,const std::string &searchName14):
osg::NodeVisitor(TRAVERSE_ALL_CHILDREN),searchForName1(searchName1),searchForName2(searchName2),searchForName3(searchName3),searchForName4(searchName4),searchForName5(searchName5),searchForName6(searchName6),searchForName7(searchName7),searchForName8(searchName8),searchForName9(searchName9),searchForName10(searchName10),searchForName11(searchName11),searchForName12(searchName12),searchForName13(searchName13),searchForName14(searchName14)
{
}
void GeodeVisitor::apply(osg::Geode &searchNode)
{
if(searchNode.getName()==searchForName1)
{
searchNode.getOrCreateStateSet()->setRenderBinDetails(3,"RenderBin");
}
if(searchNode.getName()==searchForName2)
{
searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
}
if(searchNode.getName()==searchForName3)
{
searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
}
if(searchNode.getName()==searchForName4)
{
searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
}
if(searchNode.getName()==searchForName5)
{
searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
}
if(searchNode.getName()==searchForName6)
{
searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
}
if(searchNode.getName()==searchForName7)
{
searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
}
if(searchNode.getName()==searchForName8)
{
searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
}
if(searchNode.getName()==searchForName9)
{
searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
}
if(searchNode.getName()==searchForName10)
{
searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
}
if(searchNode.getName()==searchForName11)
{
searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
}
if(searchNode.getName()==searchForName12)
{
searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
}
if(searchNode.getName()==searchForName13)
{
searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
}
if(searchNode.getName()==searchForName14)
{
searchNode.getOrCreateStateSet()->setRenderBinDetails(-1,"RenderBin");
}
NodeVisitor::apply(searchNode);
}
void GeodeVisitor::setNameToFind(const std::string &searchName1,const std::string &searchName2,const std::string &searchName3,const std::string &searchName4,const std::string &searchName5,const std::string &searchName6,const std::string &searchName7,const std::string &searchName8,const std::string &searchName9,const std::string &searchName10,const std::string &searchName11,const std::string &searchName12,const std::string &searchName13,const std::string &searchName14)
{
searchForName1=searchName1;
searchForName2=searchName2;
searchForName3=searchName3;
searchForName4=searchName4;
searchForName5=searchName5;
searchForName6=searchName6;
searchForName7=searchName7;
searchForName8=searchName8;
searchForName9=searchName9;
searchForName10=searchName10;
searchForName11=searchName11;
searchForName12=searchName12;
searchForName13=searchName13;
searchForName14=searchName14;
foundNodeList.clear();
}
osg::Node* GeodeVisitor::getFirst()
{
return *(foundNodeList.begin());
}
typedef std::vector<osg::Node*> nodeListType;
private:
std::string searchForName1;
std::string searchForName2;
std::string searchForName3;
std::string searchForName4;
std::string searchForName5;
std::string searchForName6;
std::string searchForName7;
std::string searchForName8;
std::string searchForName9;
std::string searchForName10;
std::string searchForName11;
std::string searchForName12;
std::string searchForName13;
std::string searchForName14;
nodeListType foundNodeList;
};
static osg::Image*make3DNoiseImage(int texSize)//三维噪声贴图
{
osg::Image* image = new osg::Image;
image->setImage(texSize, texSize, texSize,
4, GL_RGBA, GL_UNSIGNED_BYTE,
new unsigned char[4 * texSize * texSize * texSize],
osg::Image::USE_NEW_DELETE);
const int startFrequency = 4;
const int numOctaves = 4;
int f, i, j, k, inc;
double ni[3];
double inci, incj, inck;
int frequency = startFrequency;
GLubyte *ptr;
double amp = 0.5;
osg::notify(osg::INFO) << "creating 3D noise texture... ";
for (f = 0, inc = 0; f < numOctaves; ++f, frequency *= 2, ++inc, amp *= 0.5)
{
SetNoiseFrequency(frequency);
ptr = image->data();
ni[0] = ni[1] = ni[2] = 0;
inci = 1.0 / (texSize / frequency);
for (i = 0; i < texSize; ++i, ni[0] += inci)
{
incj = 1.0 / (texSize / frequency);
for (j = 0; j < texSize; ++j, ni[1] += incj)
{
inck = 1.0 / (texSize / frequency);
for (k = 0; k < texSize; ++k, ni[2] += inck, ptr += 4)
{
*(ptr+inc) = (GLubyte) (((noise3(ni) + 1.0) * amp) * 128.0);
}
}
}
}
osg::notify(osg::INFO) << "DONE" << std::endl;
return image;
}
static osg::Texture3D*make3DNoiseTexture(int texSize )//三维噪声纹理
{
osg::Texture3D* noiseTexture = new osg::Texture3D;
noiseTexture->setFilter(osg::Texture3D::MIN_FILTER, osg::Texture3D:INEAR);
noiseTexture->setFilter(osg::Texture3D::MAG_FILTER, osg::Texture3D::LINEAR);
noiseTexture->setWrap(osg::Texture3D::WRAP_S, osg::Texture3D::REPEAT);
noiseTexture->setWrap(osg::Texture3D::WRAP_T, osg::Texture3D::REPEAT);
noiseTexture->setWrap(osg::Texture3D::WRAP_R, osg::Texture3D::REPEAT);
noiseTexture->setImage( make3DNoiseImage(texSize) );
return noiseTexture;
}
static osg::Image*make1DSineImage( int texSize )//一维噪声贴图
{
const float PI = 3.1415927;
osg::Image* image = new osg::Image;
image->setImage(texSize, 1, 1,
4, GL_RGBA, GL_UNSIGNED_BYTE,
new unsigned char[4 * texSize],
osg::Image::USE_NEW_DELETE);
GLubyte* ptr = image->data();
float inc = 2* PI / (float)texSize;
for(int i = 0; i < texSize; i++)
{
*ptr = (GLubyte)((sinf(i * inc) * 0.5 + 0.5) * 255.);//深浅不一的红色
if (*ptr>40)
{
*ptr-=40;
}
else
*ptr=0;
ptr++;
*ptr++ = 0;
*ptr++ = 0;
*ptr++ = 1;
}
osgDB::writeImageFile(*image,"D:\\test.png");
return image;
}
static osg::Texture1D*make1DSineTexture( int texSize )//一维噪声纹理
{
osg::Texture1D* sineTexture = new osg::Texture1D;
sineTexture->setWrap(osg::Texture1D::WRAP_S, osg::Texture1D::REPEAT);
sineTexture->setFilter(osg::Texture1D::MIN_FILTER, osg::Texture1D::LINEAR);
sineTexture->setFilter(osg::Texture1D::MAG_FILTER, osg::Texture1D::LINEAR);
sineTexture->setImage( make1DSineImage(texSize) );
return sineTexture;
}
static const char *microshaderVertSource = { //顶点着色器
"// microshader - colors a fragment based on its position\n"
"varying vec4 color;\n"
"void main(void)\n"
"{\n"
" color = gl_Vertex;\n"
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
"}\n"
};
static const char *microshaderFragSource = { //片元着色器
"varying vec4 color;\n"
"void main(void)\n"
"{\n"
" gl_FragColor = clamp( color, 0.0, 1.0 );\n"
"}\n"
};
static osg::Geode*CreateModel()//建立几何体
{
osg::Geode* geode = new osg::Geode();
geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f),1.0f)));
geode->addDrawable(new osg::ShapeDrawable(new osg::Cone(osg::Vec3(2.2f,0.0f,-0.4f),0.9f,1.8f)));
geode->addDrawable(new osg::ShapeDrawable(new osg::Cylinder(osg::Vec3(4.4f,0.0f,0.0f),1.0f,1.4f)));
return geode;
}
static osg::StateSet*ModelInstance()//确定几何体位置
{
static float zvalue = 0.0f;
static osg::Node* masterModel = CreateModel();
osg::Node*glider=osgDB::readNodeFile("huo3jia4gou48.osg");
GeodeVisitor cow("Circle01-GEODE","Line12-GEODE","Line11-GEODE","Line10-GEODE","Line9-GEODE","Line8-GEODE","Line7-GEODE","Line6-GEODE","Line5-GEODE","Line4-GEODE","Line3-GEODE","Line2-GEODE","Line1-GEODE","Shape01-GEODE");
glider->accept(cow);
rootNode->addChild(glider);
return glider->getOrCreateStateSet();
}
static void LoadShaderSource( osg::Shader* shader, const std::string& fileName )
{
std::string fqFileName = osgDB::findDataFile(fileName);
if( fqFileName.length() != 0 )
{
shader->loadShaderSourceFromFile( fqFileName.c_str() );
}
else
{
osg::notify(osg::WARN) << "File \"" << fileName << "\" not found." << std::endl;
}
}
class AnimateCallback: public osg::Uniform::Callback//路径动画
{
public:
enum Operation
{
OFFSET,
};
AnimateCallback(Operation op) : _enabled(true),_operation(op) {}
virtual void operator() ( osg::Uniform* uniform, osg::NodeVisitor* nv )
{
if( _enabled )
{
float angle = 2.0 * nv->getFrameStamp()->getSimulationTime();
float sine = angle ; // -1 -> 1
float v01 = 0.5f * sine + 0.5f; // 0 -> 1
switch(_operation)
{
case OFFSET : uniform->set( osg::Vec3(-0.8f*v01, 0, 0) ); break;
}
}
}
private:
bool _enabled;
Operation _operation;
};
osg::ref_ptr<osg::Group>GL2Scene::buildScene()//贴上四个纹理
{
osg::Texture3D* noiseTexture = make3DNoiseTexture( 32 /*128*/ );
osg::Texture1D* sineTexture = make1DSineTexture( 16 /*1024*/ );
rootNode = new osg::Group;
osg::ref_ptr<osg::Node> node1 = osgDB::readNodeFile("ping2mian41.3DS");
osg::ref_ptr<osg::StateSet>frontsta=new osg::StateSet();
osg::ref_ptr<osg::Material>frontmat=new osg::Material();
osg::ref_ptr<osg::MatrixTransform> transnode1 = new osg::MatrixTransform ;
transnode1 ->setMatrix(osg::Matrix::translate(0, 0, 0.35)) ;
transnode1 ->addChild(node1.get()) ;
frontsta=node1->getOrCreateStateSet();
frontmat->setDiffuse(osg::Material::FRONT_AND_BACK,osg::Vec4(0.9,0.5,0.7,0.0));
frontmat->setSpecular(osg::Material::FRONT_AND_BACK,osg::Vec4(0.9,0.5,0.7,0.0));
frontmat->setShininess(osg::Material::FRONT,90.0f);
frontsta->setAttribute(frontmat.get());
frontsta->setRenderBinDetails(-2,"RenderBin");
frontsta->setMode(GL_BLEND,osg::StateAttribute::ON);
rootNode->addChild(transnode1);
{
osg::Uniform* OffsetUniform = new osg::Uniform( "Offset", osg::Vec3(0.0f, 0.0f, 0.0f) );
OffsetUniform->setUpdateCallback(new AnimateCallback(AnimateCallback::OFFSET));
osg::StateSet* ss = rootNode->getOrCreateStateSet();
ss->setMode(GL_LIGHTING,osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
ss->setMode(GL_BLEND,osg::StateAttribute::ON);
ss->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
ss->addUniform( OffsetUniform );
}
{
osg::StateSet* ss = ModelInstance();
ss->setTextureAttribute(TEXUNIT_NOISE, noiseTexture);
ss->setTextureAttribute(TEXUNIT_SINE, sineTexture);
MarbleProgram = new osg::Program;
MarbleProgram->setName( "marble" );
_programList.push_back( MarbleProgram );
MarbleVertObj = new osg::Shader( osg::Shader::VERTEX );
MarbleFragObj = new osg::Shader( osg::Shader::FRAGMENT );
MarbleProgram->addShader( MarbleFragObj );
MarbleProgram->addShader( MarbleVertObj );
ss->setAttributeAndModes(MarbleProgram, osg::StateAttribute::ON);
ss->addUniform( new osg::Uniform("NoiseTex", TEXUNIT_NOISE) );
ss->addUniform( new osg::Uniform("SineTex", TEXUNIT_SINE) );
}
reloadShaderSource();
return rootNode;
}
GL2Scene::GL2Scene()
{
_rootNode = buildScene();
_shadersEnabled = true;
}
GL2Scene::~GL2Scene()
{
}
void GL2Scene::reloadShaderSource()
{
osg::notify(osg::INFO) << "reloadShaderSource()" << std::endl;
LoadShaderSource( MarbleVertObj, "C:/tool/OpenSceneGraph-Data-2.8.0/OpenSceneGraph-Data-2.8.0/shaders/marble.vert" );
LoadShaderSource( MarbleFragObj, "C:/tool/OpenSceneGraph-Data-2.8.0/OpenSceneGraph-Data-2.8.0/shaders/marble.frag" );
}
void GL2Scene::toggleShaderEnable()
{
_shadersEnabled = ! _shadersEnabled;
osg::notify(osg::WARN) << "shader enable = " <<
((_shadersEnabled) ? "ON" : "OFF") << std::endl;
for( unsigned int i = 0; i < _programList.size(); i++ )
{
//_programList->enable( _shadersEnabled );
}
} |
|