osg中使用OpenGL绘制

在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();
}

猜你喜欢

转载自blog.csdn.net/HelloEarth_/article/details/88804916