- // Set up some shared structures.
- // FIXME: Currently we only take the texture, height and width of the first tree in the forest. In the future
- // we should be able to handle multiple textures etc.
- TreeBin::Tree firstTree = forest.getTree(0);
-
- osg::Geometry* shared_geometry = createOrthQuads(firstTree.width,
- firstTree.height,
- transform);
- osg::Group* group = new osg::Group;
-
- osg::Texture2D *tex = new osg::Texture2D;
- tex->setWrap( osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP );
- tex->setWrap( osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP );
- tex->setImage(osgDB::readImageFile(firstTree.texture));
-
- osg::AlphaFunc* alphaFunc = new osg::AlphaFunc;
- alphaFunc->setFunction(osg::AlphaFunc::GEQUAL,0.05f);
-
- osg::StateSet *dstate = new osg::StateSet;
- dstate->setTextureAttributeAndModes(0, tex, osg::StateAttribute::ON );
- dstate->setTextureAttribute(0, new osg::TexEnv );
- dstate->setAttributeAndModes( new osg::BlendFunc, osg::StateAttribute::ON );
- dstate->setAttributeAndModes( alphaFunc, osg::StateAttribute::ON );
- dstate->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
- dstate->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
-
- osg::StateSet* stateset = new osg::StateSet;
- stateset->setTextureAttributeAndModes(0, tex, osg::StateAttribute::ON );
- stateset->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
-
- osg::Program* program = new osg::Program;
- stateset->setAttribute(program);
- osg::Uniform* baseTextureSampler = new osg::Uniform("baseTexture",0);
- stateset->addUniform(baseTextureSampler);
-
- /*
- * FIXME: Currently, calculating the diffuse term results in a bad
- * "flickering" and a tendency of the diffuse term be either
- * 0.0 of 1.0. Hence, it has been commented out in the shader below.
- * I (Stuart) suspect it may be because the light is so distant that
- * we're seeing floating point representation issues.
- */
- char vertexShaderSource[] =
-// "varying vec3 N;\n"\r
-// "varying vec3 v;\n"
- "varying vec2 texcoord;\n"
- "varying float fogFactor;\n"
- "\n"
- "void main(void)\n"
- "{\n"
-// " v = vec3(gl_ModelViewMatrix * gl_Vertex);\n"\r
-// " N = normalize(gl_NormalMatrix * gl_Normal);\n"\r
- " texcoord = gl_MultiTexCoord0.st;\n"
- " vec3 position = gl_Vertex.xyz * gl_Color.w + gl_Color.xyz;\n"
- " gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);\n"
- " const float LOG2 = 1.442695;\n"\r
- " gl_FogFragCoord = gl_Position.z;\n"\r
- " fogFactor = exp2( -gl_Fog.density * gl_Fog.density * gl_FogFragCoord * gl_FogFragCoord * LOG2 );\n"\r
- " fogFactor = clamp(fogFactor, 0.0, 1.0);\n"
- "}\n";
-
- char fragmentShaderSource[] =
- "uniform sampler2D baseTexture; \n"
-// "varying vec3 N;\n"\r
-// "varying vec3 v;\n"
- "varying vec2 texcoord;\n"
- "varying float fogFactor;\n"
- "\n"
- "void main(void) \n"
- "{ \n"
- " vec4 base = texture2D( baseTexture, texcoord);\n"
-// " vec3 L = normalize(gl_LightSource[0].position.xyz);\n"
-// " vec4 vDiffuse = gl_FrontLightProduct[0].diffuse * max(dot(N,L), 0.0);\n"
-// " vDiffuse = sqrt(clamp(vDiffuse, 0.0, 1.0));\n"
-// " vec4 vAmbient = gl_FrontLightProduct[0].ambient;\n"
-// " vec4 finalColor = base * (vAmbient + vDiffuse);\n"
- " vec4 finalColor = base * gl_FrontLightProduct[0].diffuse;\n"
- " gl_FragColor = mix(gl_Fog.color, finalColor, fogFactor );\n"
- "}\n";
-
- osg::Shader* vertex_shader = new osg::Shader(osg::Shader::VERTEX, vertexShaderSource);
- program->addShader(vertex_shader);
-
- osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource);
- program->addShader(fragment_shader);
-
- // Now, create a quadtree for the forest.
- osg::ref_ptr<osg::Group> _root;
- ShaderGeometry* leaves[SG_TREE_QUAD_TREE_SIZE][SG_TREE_QUAD_TREE_SIZE];
-
- // Determine the extents of the tree, and a list of the required textures for later.
- osg::BoundingBox extents;
- for (unsigned int i = 0; i < forest.getNumTrees(); i++)
- {
- const osg::Vec3f center = forest.getTree(i).position.osg() * transform;
- extents.expandBy(center);