在osg开发的时候,想要绘制一些图形,但是在osg中也没有找到合适的方法(估计是我太菜了),然后就想到用OpenGL的方法进行绘制,尝试了一些,记录一下可以行的通的。
绘制一条动态变化的直线
class CreateRay : public osg::Geometry
{
public:
CreateRay(osg::ref_ptr<osg::GraphicsContext> gc);
~CreateRay() {};
private:
osg::ref_ptr<osg::Vec4Array> _varr; //vertex buffer
osg::ref_ptr<osg::Uniform> MVPMatrix;
osg::ref_ptr<osg::GraphicsContext> _gc;
private:
virtual void drawImplementation(osg::RenderInfo & renderInfo) const;
private:
GLuint m_glControllerVertBuffer;
GLuint m_unControllerVAO;
};
CreateRay::CreateRay(osg::ref_ptr<osg::GraphicsContext> gc):_gc(gc)
{
setUseVertexBufferObjects(true);
_varr = new osg::Vec4Array;
osg::Vec4 strat = osg::Vec4(0, 0, 0, 1);
osg::Vec4 end = osg::Vec4(10, 0, 0, 1);
_varr->push_back(strat);
_varr->push_back(end);
_varr->setBufferObject(new osg::VertexBufferObject);
osg::ref_ptr<osg::Program> vertexProg = new osg::Program;
osg::ref_ptr<osg::Shader> verShader = new osg::Shader(osg::Shader::VERTEX);
osg::ref_ptr<osg::Shader> fragment = new osg::Shader(osg::Shader::FRAGMENT);
verShader->loadShaderSourceFromFile("rayvertex.vs");
fragment->loadShaderSourceFromFile("rayfrag.fg");
vertexProg->addShader(verShader);
vertexProg->addShader(fragment);
this->getOrCreateStateSet()->setAttributeAndModes(vertexProg.get(), osg::StateAttribute::ON);
this->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
this->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
this->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
this->getOrCreateStateSet()->setRenderBinDetails(50, "RenderBin");
std::vector<float> vertdataarray;
{
osg::Vec4 start = osg::Vec4(0, 0, 0, 1);
osg::Vec4 end = osg::Vec4(10, 0, 0, 1);
vertdataarray.push_back(start.x()); vertdataarray.push_back(start.y()); vertdataarray.push_back(start.z()); vertdataarray.push_back(start.w());
vertdataarray.push_back(end.x()); vertdataarray.push_back(end.y()); vertdataarray.push_back(end.z()); vertdataarray.push_back(end.w());
osg::GLExtensions* ext = _gc->getState()->get<osg::GLExtensions>();
ext->glGenVertexArrays(1, &m_unControllerVAO);
ext->glBindVertexArray(m_unControllerVAO);
ext->glGenBuffers(1, &m_glControllerVertBuffer);
ext->glBindBuffer(GL_ARRAY_BUFFER_ARB, m_glControllerVertBuffer);
ext->glBufferData(GL_ARRAY_BUFFER_ARB, sizeof(float) * vertdataarray.size(), &vertdataarray[0], GL_STREAM_DRAW);
GLuint stride = 4 * sizeof(float);
ext->glEnableVertexAttribArray(0);
ext->glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, stride, (GLvoid *)0);
ext->glBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
ext->glBindVertexArray(0);
//ext->glBindBuffer(GL_ARRAY_BUFFER_ARB, m_glControllerVertBuffer);
//ext->glBufferData(GL_ARRAY_BUFFER_ARB, sizeof(float) * vertdataarray.size(), &vertdataarray[0], GL_STREAM_DRAW);
}
}
int main()
{
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
osg::ref_ptr<osg::Group> gp = new osg::Group;
osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
if (!wsi)
return 0;
osg::GraphicsContext::ScreenIdentifier si;
si.readDISPLAY();
if (si.displayNum < 0)
si.displayNum = 0;
if (si.screenNum < 0)
si.screenNum = 0;
unsigned int width, height;
wsi->getScreenResolution(si, width, height);
osg::GraphicsContext::Traits* traits = new osg::GraphicsContext::Traits;
traits->hostName = "";// si.hostName;
traits->screenNum = 0;
traits->displayNum = 0;
traits->windowDecoration = true;
traits->x = 200;
traits->y = 200;
traits->width = width - traits->x;
traits->height = height - traits->y;
traits->doubleBuffer = true;
traits->sharedContext = nullptr;
osg::ref_ptr<osg::GraphicsContext> gc;
gc = osg::GraphicsContext::createGraphicsContext(traits);
if (gc.valid())
{
gc->setClearColor(osg::Vec4(0, 0, 0, 1.0));
gc->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
viewer->getCamera()->setGraphicsContext(gc);
viewer->getCamera()->setViewport(0, 0, traits->width, traits->height);
viewer->realize();
viewer->getCamera()->getGraphicsContext()->makeCurrent();//osg不在绘制阶段时需要建立一个有效的gc供OpenGL函数使用
viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);//需要单线程
gc->getState()->setUseModelViewAndProjectionUniforms(true);
osg::ref_ptr<CreateRay> ray = new CreateRay(gc);
gp->addChild(ray);
gp->addChild(osgDB::readNodeFile("cow.osg"));
viewer->setSceneData(gp);
viewer->getCamera()->setClearColor(osg::Vec4(0, 0, 0, 1.0));
viewer->addEventHandler(new osgViewer::StatsHandler);
viewer->addEventHandler(new osgViewer::WindowSizeHandler);
return viewer->run();
}