片元着色器之牛顿分形
![](http://images0.cnblogs.com/blog/403684/201312/13192719-089da0a3911843359dd15c96750adfa7.png)
#include <osgViewer/Viewer> #include <osgDB/ReadFile> #ifdef _DEBUG #pragma comment(lib, "osgParticled.lib") #pragma comment(lib, "osgQtd.lib") #pragma comment(lib, "osgAnimationd.lib") #pragma comment(lib, "osgManipulatord.lib") #pragma comment(lib, "osgPresentationd.lib") #pragma comment(lib, "OpenThreadsd.lib") #pragma comment(lib, "osgWidgetd.lib") #pragma comment(lib, "osgVolumed.lib") #pragma comment(lib, "osgd.lib") #pragma comment(lib, "osgSimd.lib") #pragma comment(lib, "osgDBd.lib") #pragma comment(lib, "osgFXd.lib") #pragma comment(lib, "osgGAd.lib") #pragma comment(lib, "osgUtild.lib") #pragma comment(lib, "osgViewerd.lib") #pragma comment(lib, "osgShadowd.lib") #pragma comment(lib, "osgTextd.lib") #pragma comment(lib, "osgTerraind.lib") #pragma comment(lib, "osgEarthd.lib") #pragma comment(lib, "osgEarthQtd.lib") #pragma comment(lib, "osgEarthFeaturesd.lib") #pragma comment(lib, "osgEarthSymbologyd.lib") #pragma comment(lib, "osgEarthUtild.lib") #pragma comment(lib, "osgEarthAnnotationd.lib") #pragma comment(lib, "osgdb_osgearth_gdald.lib") #pragma comment(lib, "osgdb_osgearth_feature_wfsd.lib") #pragma comment(lib, "osgdb_osgearth_feature_tfsd.lib") #pragma comment(lib, "osgdb_osgearth_feature_ogrd.lib") #pragma comment(lib, "OpenGL32.lib") #else #pragma comment(lib, "osgParticle.lib") #pragma comment(lib, "osgQt.lib") #pragma comment(lib, "osgAnimation.lib") #pragma comment(lib, "osgManipulator.lib") #pragma comment(lib, "osgPresentation.lib") #pragma comment(lib, "OpenThreads.lib") #pragma comment(lib, "osgWidget.lib") #pragma comment(lib, "osgVolume.lib") #pragma comment(lib, "osg.lib") #pragma comment(lib, "osgSim.lib") #pragma comment(lib, "osgDB.lib") #pragma comment(lib, "osgFX.lib") #pragma comment(lib, "osgGA.lib") #pragma comment(lib, "osgUtil.lib") #pragma comment(lib, "osgViewer.lib") #pragma comment(lib, "osgShadow.lib") #pragma comment(lib, "osgText.lib") #pragma comment(lib, "osgTerrain.lib") #pragma comment(lib, "osgEarth.lib") #pragma comment(lib, "osgEarthQt.lib") #pragma comment(lib, "osgEarthFeatures.lib") #pragma comment(lib, "osgEarthSymbology.lib") #pragma comment(lib, "osgEarthUtil.lib") #pragma comment(lib, "osgEarthAnnotation.lib") #pragma comment(lib, "osgdb_osgearth_gdal.lib") #pragma comment(lib, "osgdb_osgearth_feature_wfs.lib") #pragma comment(lib, "osgdb_osgearth_feature_tfs.lib") #pragma comment(lib, "osgdb_osgearth_feature_ogr.lib") #endif const std::string vs = " \ #version 330\n \ in vec2 Position; \ out vec2 vertCoord; \ void main(void) \ { \ vertCoord = Position; \ gl_Position = vec4(Position, 0.0, 1.0); \ } \ "; const std::string fs = " \ #version 330\n \ in vec2 vertCoord; \ uniform vec3 Color1, Color2; \ out vec4 fragColor; \ \ vec2 f(vec2 n) \ { \ return vec2( \ n.x * n.x * n.x * n.x + n.y * n.y * n.y * n.y - 2 * n.x * n.x * n.y * n.y - 1, \ 4 * n.x * n.x * n.x * n.y - 4 * n.y * n.y * n.y * n.x \ ); \ } \ \ vec2 df(vec2 n) \ { \ return 4 * vec2( \ n.x*n.x*n.x - 3.0*n.x*n.y*n.y, \ -n.y*n.y*n.y + 3.0*n.x*n.x*n.y \ ); \ } \ \ vec2 cdiv(vec2 a, vec2 b) \ { \ float d = dot(b, b); \ if(d == 0.0) return a; \ else return vec2( \ (a.x*b.x + a.y*b.y) / d, \ (a.y*b.x - a.x*b.y) / d \ ); \ } \ void main(void) \ { \ vec2 z = vertCoord; \ int i, max = 128; \ for(i = 0; i != max; ++i) \ { \ vec2 zn = z - cdiv(f(z), df(z)); \ if(distance(zn, z) < 0.00001) break; \ z = zn; \ } \ fragColor = vec4( \ mix( \ Color1.rgb, \ Color2.rgb, \ float(i) / float(max) \ ), \ 1.0 \ ); \ } \ "; osg::ref_ptr<osg::StateSet> CreateStateSet() { osg::ref_ptr<osg::StateSet> stateSet = new osg::StateSet; osg::ref_ptr<osg::Shader> vShader = new osg::Shader(osg::Shader::VERTEX, vs); osg::ref_ptr<osg::Shader> fShader = new osg::Shader(osg::Shader::FRAGMENT, fs); osg::ref_ptr<osg::Program> program = new osg::Program; program->addShader(vShader.get()); program->addShader(fShader.get()); program->addBindAttribLocation("Position", 0); osg::ref_ptr<osg::Uniform> uColor1 = new osg::Uniform("Color1", osg::Vec3(0.2f, 0.02f, 0.05f)); osg::ref_ptr<osg::Uniform> uColor2 = new osg::Uniform("Color2", osg::Vec3(1.0f, 0.95f, 0.98f)); stateSet->addUniform(uColor1.get()); stateSet->addUniform(uColor2.get()); stateSet->setAttributeAndModes(program.get(), osg::StateAttribute::ON); return stateSet.get(); } osg::ref_ptr<osg::Geode> CreateGeode() { osg::ref_ptr<osg::Geode> geode = new osg::Geode; osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry; osg::ref_ptr<osg::Vec3Array> vArray = new osg::Vec3Array; osg::ref_ptr<osg::Vec2Array> aArray = new osg::Vec2Array; const GLfloat rectangle_verts[12] = { -1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f }; vArray->push_back(osg::Vec3(-1.0f, -1.0f, 0.0f)); vArray->push_back(osg::Vec3(-1.0f, 1.0f, 0.0f)); vArray->push_back(osg::Vec3(1.0f, 1.0f, 0.0f)); vArray->push_back(osg::Vec3(1.0f, -1.0f, 0.0f)); aArray->push_back(osg::Vec2(0.0, 0.0)); geometry->setVertexArray(vArray.get()); geometry->setVertexAttribArray(0, aArray.get()); geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, vArray->size())); geode->addDrawable(geometry.get()); return geode.get(); } int main() { osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer; osg::ref_ptr<osg::Geode> geode = CreateGeode(); geode->setStateSet(CreateStateSet()); viewer->setSceneData(geode.get()); viewer->setUpViewInWindow(35, 35, 1024, 800); return viewer->run(); }