|
据我知道有两种方法:
1. 使用一个点作为方块的中心,将其装换为屏幕坐标,然后根据屏幕坐标算出一这个点为中心的方块的四个点,再转换成OSG的world坐标,这样就实现了,但是有个问题是重载了osg::Geomtry后纹理无法加载了
2. 计算出方块在摄像机拉近或者远离时的缩放比例,动态的缩放方块,但是OSG中我不会计算缩放比例
这两种方式在OpenGL中我都实现了。
第一种实现的源码,那位帮我分析一下,纹理为什么无法加载(Geode设置纹理和Geometry设置均无效):
#include <osg/MatrixTransform>
#include <osg/ClipNode>
#include <osg/Billboard>
#include <osg/Geode>
#include <osg/Group>
#include <osg/Notify>
#include <osg/Material>
#include <osg/PolygonOffset>
#include <osg/PolygonMode>
#include <osg/LineStipple>
#include <osg/AnimationPath>
#include <osgGA/TrackballManipulator>
#include <osgDB/Registry>
#include <osgDB/ReadFile>
#include <osg/BlendFunc>
#include <osg/PointSprite>
#include <osgSim/DOFTransform>
#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osg/Vec3d>
#include <osgViewer/Viewer>
#include <osg/ComputeBoundsVisitor>
#include <osg/Texture2D>
#include <osg/Point>
#if 1
class goSymbolPoint :
public osg::Geometry
{
public:
goSymbolPoint::goSymbolPoint(void);
goSymbolPoint::goSymbolPoint( int iSize, const osg::Vec3& pos, osg::Image* pImage );
goSymbolPoint::~goSymbolPoint(void);
virtual void drawImplementation( osg::RenderInfo& renderInfo ) const;
inline void SetPosition(osg::Vec3 pos){m_v3Position = pos;}
inline void SetSize(int iS){m_iSize = iS;}
inline void SetTexture(osg::Image* pI);
private:
void ScreenToWorld(osg::Camera* pCamera, const osg::Vec3& v3In, osg::Vec3& v3Out) const;
void WorldToScreen(osg::Camera* pCamera, const osg::Vec3& v3In, osg::Vec3& v3Out) const;
void ComputeWorld(osg::Camera* pCamera, const osg::Vec3& v3In, osg::Vec3& v3Out) const;
void ComputeNotVPWorld(osg::Camera* pCamera, const osg::Vec3& v3In, osg::Vec3& v3Out) const;
osg::Vec3 m_v3Position, m_v3WorldPosition;
int m_iSize;
osg::ref_ptr<osg::Vec3Array> m_pVertexes;
osg::ref_ptr<osg::Vec4Array> m_pColors;
osg::ref_ptr<osg::Vec2Array> m_pTexCoord;
osg::ref_ptr<osg::StateSet> m_pStateSet;
};
goSymbolPoint::goSymbolPoint(void)
{
m_pStateSet = new osg::StateSet;
m_pVertexes = new osg::Vec3Array;
m_pColors = new osg::Vec4Array;
m_pTexCoord = new osg::Vec2Array;
};
goSymbolPoint::goSymbolPoint( int iSize, const osg::Vec3& pos, osg::Image* pImage )
{
m_iSize = iSize;
m_v3Position = pos;
m_pVertexes = new osg::Vec3Array;
m_pColors = new osg::Vec4Array;
m_pTexCoord = new osg::Vec2Array;
m_pVertexes->push_back(osg::Vec3(0, 0, 0));
m_pVertexes->push_back(osg::Vec3(10, 0, 0));
m_pVertexes->push_back(osg::Vec3(10, 0, 10));
m_pVertexes->push_back(osg::Vec3(0, 0, 10));
m_pTexCoord->push_back(osg::Vec2(0, 0));
m_pTexCoord->push_back(osg::Vec2(0, 1));
m_pTexCoord->push_back(osg::Vec2(1, 1));
m_pTexCoord->push_back(osg::Vec2(1, 0));
osg::Geometry::setTexCoordArray(0, m_pTexCoord);
osg::Geometry::setVertexArray(m_pVertexes);
osg::Geometry::addPrimitiveSet(new osg:rawArrays(osg::DrawArrays:UADS, 0, 4));
m_pColors->push_back(osg::Vec4(1, 0, 0, 1));
osg::Geometry::setColorArray(m_pColors);
osg::Geometry::setColorBinding(Geometry::BIND_OVERALL);
this->setUseDisplayList(false);
};
goSymbolPoint::~goSymbolPoint(void)
{
}
void goSymbolPoint::drawImplementation( osg::RenderInfo& renderInfo ) const
{
((osg::Geometry*)this)->setUseDisplayList(false);
osg::Camera* pCamera = renderInfo.getCurrentCamera();
if(!pCamera)
{
((osg::Geometry*)this)->dirtyDisplayList();
((osg::Geometry*)this)->dirtyBound();
return;
}
int halfSize = m_iSize/2;
osg::Vec3 v3ScreenPos, p1, p2, p3, p4, pw1, pw2, pw3, pw4, pwi1, pwi2, pwi3, pwi4, v3ComputPos;
//ComputeWorld(pCamera, m_v3Position, v3ComputPos);
WorldToScreen(pCamera, m_v3Position, v3ScreenPos);
p1.set(v3ScreenPos.x() - halfSize, v3ScreenPos.y() + halfSize, 0);
p2.set(v3ScreenPos.x() - halfSize, v3ScreenPos.y() - halfSize, 0);
p3.set(v3ScreenPos.x() + halfSize, v3ScreenPos.y() - halfSize, 0);
p4.set(v3ScreenPos.x() + halfSize, v3ScreenPos.y() + halfSize, 0);
ScreenToWorld(pCamera, p1, pw1);
ScreenToWorld(pCamera, p2, pw2);
ScreenToWorld(pCamera, p3, pw3);
ScreenToWorld(pCamera, p4, pw4);
m_pVertexes->at(0).set(pw1);
m_pVertexes->at(1).set(pw2);
m_pVertexes->at(2).set(pw3);
m_pVertexes->at(3).set(pw4);
m_pTexCoord->at(0).set(0, 0);
m_pTexCoord->at(1).set(0, 1);
m_pTexCoord->at(2).set(1, 1);
m_pTexCoord->at(3).set(1, 0);
osg::Geometry::drawImplementation(renderInfo);
/*((osg::Geometry*)this)->dirtyDisplayList();
((osg::Geometry*)this)->dirtyBound();*/
}
void goSymbolPoint::SetTexture( osg::Image* pI )
{
osg::Texture2D* pTex2D = new osg::Texture2D(pI);
m_pStateSet->setAttribute(pTex2D);
osg::Geometry::setStateSet(m_pStateSet);
}
void goSymbolPoint::ScreenToWorld( osg::Camera* pCamera, const osg::Vec3& v3In, osg::Vec3& v3Out ) const
{
osg::Matrix VPW = pCamera->getViewMatrix() *
pCamera->getProjectionMatrix() *
pCamera->getViewport()->computeWindowMatrix();
osg::Matrix inverseVPW;
inverseVPW.invert(VPW);
v3Out = v3In * inverseVPW;
v3Out.set(v3Out.x(), 0, v3Out.z());
}
void goSymbolPoint::WorldToScreen( osg::Camera* pCamera, const osg::Vec3& v3In, osg::Vec3& v3Out ) const
{
osg::Matrix VPW = pCamera->getViewMatrix() *
pCamera->getProjectionMatrix() *
pCamera->getViewport()->computeWindowMatrix();
v3Out = v3In * VPW;
v3Out.set(v3Out.x(), v3Out.y(), 0);
}
void goSymbolPoint::ComputeWorld( osg::Camera* pCamera, const osg::Vec3& v3In, osg::Vec3& v3Out ) const
{
osg::Matrix VP = pCamera->getViewMatrix() *
pCamera->getProjectionMatrix();
v3Out = v3In * VP;
}
void goSymbolPoint::ComputeNotVPWorld( osg::Camera* pCamera, const osg::Vec3& v3In, osg::Vec3& v3Out ) const
{
osg::Matrix VP = pCamera->getViewMatrix() *
pCamera->getProjectionMatrix();
osg::Matrix InVP = osg::Matrix::inverse(VP);
v3Out = v3In * VP;
}
#endif
osg::Geometry* GetTestPoint(osg::Vec3& pos)
{
osg::Geometry* pGeom = new osg::Geometry;
osg::Vec3Array* pV3Vertexes = new osg::Vec3Array;
pV3Vertexes->push_back(pos);
osg::Vec4Array* pV4Colors = new osg::Vec4Array;
pV4Colors->push_back(osg::Vec4(0,0,0,1));
pGeom->setVertexArray(pV3Vertexes);
pGeom->addPrimitiveSet(new osg::DrawArrays(osg::DrawArrays:OINTS, 0, 1));
pGeom->setColorArray(pV4Colors);
pGeom->setColorBinding(osg::Geometry::BIND_OVERALL);
osg::StateSet* pStateSet = pGeom->getOrCreateStateSet();
osg::Point* pPA = new osg::Point;
pPA->setSize(5);
pStateSet->setAttributeAndModes(pPA, osg::StateAttribute::ON);
return pGeom;
}
int main( int argc, char **argv )
{
osgViewer::Viewer viewer;
osg::ref_ptr<osg::Group> rootnode = new osg::Group;
osg::ref_ptr<osg::Geode> pGeode = new osg::Geode;
osg::Vec3 pos(0, 0, 0);
rootnode->addChild(pGeode);
osg::Image* pImage = osgDB::readImageFile("Images/maincall.png");
goSymbolPoint* pSymbolPoint = new goSymbolPoint(100, pos, pImage);
osg::ref_ptr<osg::StateSet> m_pStateSet = new osg::StateSet;
osg::Texture2D* pTex2D = new osg::Texture2D;
pTex2D->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D:INEAR);
pTex2D->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR);
pTex2D->setDataVariance(osg::Object::DYNAMIC);
pTex2D->setImage(pImage);
m_pStateSet->setAssociatedTextureModes(0, pTex2D, osg::StateAttribute::ON);
pGeode->setStateSet(m_pStateSet);
pGeode->addDrawable(pSymbolPoint);
osg::Geometry* pPointTest = GetTestPoint(pos);
pGeode->addDrawable(pPointTest);
viewer.setSceneData(rootnode);
viewer.setCameraManipulator(new osgGA::TrackballManipulator);
viewer.setUpViewInWindow(20, 100, 800, 600);
viewer.setLightingMode(osg::View::NO_LIGHT);
return viewer.run();
} |
|