#include "OsgIconAuto.h"
#include "Common.h"
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Billboard>
#include <osg/Texture2D>
#include <osgDB/ReadFile>
OsgIconAuto::OsgIconAuto(const osg::Vec3 &bottomcenter, std::string &imgurl,float imgWidth):
osg::AutoTransform(),
_imgWidth(imgWidth)
{
osg::ref_ptr<osg::Image> img = osgDB::readImageFile(imgurl);
if(img.valid())
{
double scale = 2.0/ img->s();//固定宽度2米
double s = scale * img->s();
double t = scale * img->t();
//osg::Geode * geode = new osg::Geode();
osg::Billboard * geode = new osg::Billboard();
geode->setMode(osg::Billboard::POINT_ROT_EYE);
geode->addDrawable( createSquare(osg::Vec3(0,0,0),(float)s,(float)t));
geode->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
geode->getOrCreateStateSet()->setRenderingHint(
osg::StateSet::TRANSPARENT_BIN);
const char vertexShader[] = "#version " GLSL_VERSION_STR "\n"
GLSL_DEFAULT_PRECISION_FLOAT "\n"
"varying vec2 TexCoord0; \n"
"void main() { \n"
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; \n"
" TexCoord0 = gl_MultiTexCoord0.xy; \n"
"} \n";
const char fragmentShader[] = "#version " GLSL_VERSION_STR "\n"
GLSL_DEFAULT_PRECISION_FLOAT "\n"
"varying vec2 TexCoord0; \n"
"uniform sampler2D mytexture; \n"
"void main() { \n"
" gl_FragColor = texture2D(mytexture,TexCoord0); \n"
"} \n";
osg::ref_ptr<osg::Shader> tvshader = new osg::Shader(osg::Shader::VERTEX,
vertexShader);
osg::ref_ptr<osg::Shader> tfshader = new osg::Shader(osg::Shader::FRAGMENT,
fragmentShader);
osg::ref_ptr<osg::Program> tprog = new osg::Program;
tprog->addShader(tvshader);
tprog->addShader(tfshader);
//set Texture
osg::Texture2D* tex = new osg::Texture2D(img);
tex->setDataVariance(osg::Object::DYNAMIC);
geode->getOrCreateStateSet()->setTextureAttributeAndModes(0, tex);
osg::ref_ptr<osg::Uniform> tmyTexture = new osg::Uniform("mytexture", 0);
geode->getOrCreateStateSet()->addUniform(tmyTexture);
geode->getOrCreateStateSet()->setAttributeAndModes(tprog,
osg::StateAttribute::ON | osg::StateAttribute::PROTECTED);
geode->getOrCreateStateSet()->setAttribute(tprog);
//
this->addChild(geode);
this->setAutoScaleToScreen(true);
//当相机位置与at距离介于minScale和maxScale之间时,at会自动的进行缩放,以维持固定的大小,但是如果相机和at之间距离超出该范围,该放大放大,该缩小缩小
this->setMinimumScale(0.0000001);
this->setMaximumScale(10000);
this->setPosition(bottomcenter);
}
}
osg::Drawable *OsgIconAuto::createSquare(const osg::Vec3 &bottomcenter, float width, float height)
{
// set up the Geometry.
osg::Geometry* geom = new osg::Geometry;
float widthhalf = width*0.5;
osg::Vec3Array* coords = new osg::Vec3Array(4);
(*coords)[0] = bottomcenter+osg::Vec3(-widthhalf,0.0f,height);
(*coords)[1] = bottomcenter+osg::Vec3(widthhalf,0.0f,height);
(*coords)[2] = bottomcenter+osg::Vec3(widthhalf,0.0f,0.0f);
(*coords)[3] = bottomcenter+osg::Vec3(-widthhalf,0.0f,0.0f);
geom->setVertexArray(coords);
osg::Vec3Array* norms = new osg::Vec3Array(1);
(*norms)[0] = osg::Vec3(0.0f,-1.0f,0.0f);
//(*norms)[0].normalize();
geom->setNormalArray(norms, osg::Array::BIND_OVERALL);
osg::Vec2Array* tcoords = new osg::Vec2Array(4);
(*tcoords)[0].set(0.0f,1.0f);
(*tcoords)[1].set(1.0f,1.0f);
(*tcoords)[2].set(1.0f,0.0f);
(*tcoords)[3].set(0.0f,0.0f);
geom->setTexCoordArray(0,tcoords);
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
return geom;
}