|
楼主 |
发表于 2012-8-11 12:26:21
|
显示全部楼层
sky11811 发表于 2012-8-11 00:52
上传你的代码,我帮你改好,很简单。
1. 这个函数做一些初始化相机的工作
void cOSG::InitCameraConfig(void)
{
// Local Variable to hold window size data
RECT rect;
// Create the viewer for this window
mViewer = new osgViewer::Viewer();
//Get the width and height of screen
int nFullWidth=GetSystemMetrics(SM_CXSCREEN);
int nFullHeight=GetSystemMetrics(SM_CYSCREEN);
if(mViewer)
{
mViewer->setUpViewAcrossAllScreens();
// Add a Stats Handler to the viewer
//mViewer->addEventHandler(new osgViewer::StatsHandler);
// Get the current window size
::GetWindowRect(m_hWnd, &rect);
// Init the GraphicsContext Traits
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
// Init the Windata Variable that holds the handle for the Window to display OSG in.
osg::ref_ptr<osg::Referenced> windata = new osgViewer::GraphicsWindowWin32::WindowData(m_hWnd);
// Setup the traits parameters
traits->x = 0;
traits->y = 0;
traits->width = rect.right - rect.left;
traits->height = rect.bottom - rect.top;
traits->windowDecoration = false;
traits->doubleBuffer = true;
traits->sharedContext = 0;
traits->setInheritedWindowPixelFormat = true;
traits->inheritedWindowData = windata;
// Create the Graphics Context
osg::GraphicsContext* gc = osg::GraphicsContext::createGraphicsContext(traits.get());
// Init a new Camera (Master for this View)
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
// Assign Graphics Context to the Camera
camera->setGraphicsContext(gc);
// Set the viewport for the Camera
camera->setViewport(new osg::Viewport(traits->x, traits->y, traits->width, traits->height));
// Set projection matrix and camera attribtues
camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
//camera->setClearColor(osg::Vec4f(0.2f, 0.2f, 0.4f, 1.0f));
camera->setClearColor(osg::Vec4f(0.0f, 0.0f, 0.0f, 1.0f));
camera->setProjectionMatrixAsPerspective(
30.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 1.0, 1000.0);
std:stringstream viewStr;
osg::ref_ptr<osg::Geode>geodeText= new osg::Geode();
std::string timesFont("fonts/arial.ttf");
// turn lighting off for the text and disable depth test to ensure its always ontop.
osg::StateSet* stateset = geodeText->getOrCreateStateSet();
stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
// Disable depth test, and make sure that the hud is drawn after everything
// else so that it always appears ontop.
stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
stateset->setRenderBinDetails(11,"RenderBin");
osg::ref_ptr<osgText::Text>StatisText = new osgText::Text();
geodeText->addDrawable(StatisText);
osg::Geometry* geom = new osg::Geometry;
geodeText->addDrawable(geom);
// create the hud.
osg::MatrixTransform* modelview_abs = new osg::MatrixTransform;
modelview_abs->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
modelview_abs->setMatrix(osg::Matrix::identity());
modelview_abs->addChild(geodeText);
osg::ref_ptr<osg:rojection> projectText= new osg::Projection();
projectText->setMatrix(osg::Matrix::ortho2D(0,nFullWidth,0,nFullHeight));
//projectText->setMatrix(osg::Matrix::ortho2D(0,traits->width,0,traits->height));
projectText->addChild(modelview_abs);
mRoot->addChild(projectText);
// Add the Camera to the Viewer
mViewer->setCamera(camera.get());
// Add the Camera Manipulator to the Viewer
mViewer->setCameraManipulator(keyswitchManipulator.get());
// Set the Scene Data
mViewer->setSceneData(mRoot.get());
if(nFullWidth != rect.right - rect.left || nFullHeight != rect.bottom - rect.top)
{
mViewer->setKeyEventSetsDone(0);
}
mViewer->realize();
messageLog->GetSystemTime();
messageLog->o_file << "Initialize Camera Config" << endl;
}
}
2. 这个函数负责根据输出texture信息画HUD区域,然后画我需要的那条直线
bool cOSG:isplayText(const char* pModelName,const char* pText)
{
string szModelName = pModelName;
string szText = pText;
geodeText->removeDrawables(0,geodeText->getNumDrawables());
std::string timesFont("fonts/arial.ttf");
osg::Vec4 staticTextColor(199,77,15,1);
osg::Vec3 position(0.0f, GetSystemMetrics(SM_CYSCREEN)-GetSystemMetrics(SM_CYSCREEN)/50,0.0f);
//osg::Vec3 position(0.0f, 860,0.0f);
osg::ref_ptr<osgText::Text>StatisText = new osgText::Text();
geodeText->addDrawable(StatisText );
std::ostringstream viewStr;
viewStr.clear();
viewStr.setf(std::ios::left, std::ios::adjustfield);
viewStr.width(14);
szText = "Testing text";
viewStr << szText;
viewStr << "Description" << std::endl;
viewStr << "" << std::endl;
viewStr << "Lights" << std::endl;
viewStr << "Bins" << std::endl;
viewStr << "Depth" << std::endl;
StatisText->setFont(timesFont);
StatisText->setColor(staticTextColor);
StatisText->setCharacterSize(20.0f);
StatisText->setPosition(position);
viewStr.setf(std::ios::right,std::ios::adjustfield);
StatisText->setText(viewStr.str());
osg::BoundingBox bb;
int aa = geodeText->getNumDrawables();
for(unsigned int i=0;i<geodeText->getNumDrawables();++i)
{
bb.expandBy(geodeText->getDrawable(i)->getBound());
}
osg::Geometry* geom = new osg::Geometry;
osg::Vec3Array* vertices = new osg::Vec3Array;
float depth = bb.zMin()-0.1;
vertices->push_back(osg::Vec3(bb.xMin(),bb.yMax(),depth));
vertices->push_back(osg::Vec3(bb.xMin(),bb.yMin(),depth));
vertices->push_back(osg::Vec3(bb.xMax(),bb.yMin(),depth));
vertices->push_back(osg::Vec3(bb.xMax(),bb.yMax(),depth));
geom->setVertexArray(vertices);
osg::Vec3Array* normals = new osg::Vec3Array;
normals->push_back(osg::Vec3(0.0f,0.0f,1.0f));
geom->setNormalArray(normals);
geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back(osg::Vec4(1.0f,1.0,0.8f,0.2f));
geom->setColorArray(colors);
geom->setColorBinding(osg::Geometry::BIND_OVERALL);
geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,4));
osg::StateSet* stateset1 = geom->getOrCreateStateSet();
stateset1->setMode(GL_BLEND,osg::StateAttribute::ON);
stateset1->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
geodeText->addDrawable(geom);
//Convert from World coordinate screen coordinate
MatrixList matrixList;
map<string, osg::ref_ptr<osg::MatrixTransform> >::iterator itor;
for(itor = mapAllModels.begin();itor != mapAllModels.end();itor++)
{
string strModelName = itor->first;
osg::ref_ptr<osg::MatrixTransform>tran = itor->second;
if(tran)
{
if(0 == strcmp(szModelName.c_str(),strModelName.c_str()))
{
matrixList = tran->getWorldMatrices(tran.get());
break;
}
}
}
osg::Vec3 worldpoint = matrixList[0].getTrans();
int viewPort[4];
osg::Viewport* myviewPort = mViewer->getCamera()->getViewport();
viewPort[0] = myviewPort->x();
viewPort[1] = myviewPort->y();
viewPort[2] = myviewPort->width();
viewPort[3] = myviewPort->height();
osg::Vec3 winPos = worldpoint*(mViewer->getCamera()->getViewMatrix())* (mViewer->getCamera()->getProjectionMatrix())* (mViewer->getCamera()->getViewport()->computeWindowMatrix());
//Draw line
osg::Geometry* geom2 = new osg::Geometry;
osg::Vec3Array* vertices2 = new osg::Vec3Array;
vertices2->push_back(osg::Vec3(bb.xMax()/2,bb.yMin(),depth));
vertices2->push_back(osg::Vec3(winPos._v[0]*((double)GetSystemMetrics(SM_CXSCREEN)/(double)viewPort[2]),winPos._v[1]*((double)GetSystemMetrics(SM_CYSCREEN)/(double)viewPort[3]),depth));
geom2->setVertexArray(vertices2);
osg::Vec4Array* colors2 = new osg::Vec4Array;
colors2->push_back(osg::Vec4(1.0f,1.0,0.8f,0.2f));
geom2->setColorArray(colors2);
geom2->addPrimitiveSet(new osg::DrawArrays(GL_LINES,0,2));
geodeText->addDrawable(geom2);
return true;
}
geodeText与第一个函数里geodeText是同一个,第一个函数先执行,第二个函数是做一些操作之后会执行,获取到的winPos 屏幕坐标不正确,我屏幕大小是,宽1680,高1050, 显示3D的这个窗口区域大小是840,668。请帮忙看一下怎么修改,非常感谢。这个问题已经困扰我两三天了 |
|