|
因为项目需要,我现在要实时将qwidget的界面动态显示在osg场景中,根据osgtexture2d的例子我做了一个测试程序,实现了动态更换纹理的功能,但刷新速度却非常的慢,不足以实际应用,希望有经验的老师,同学能指点以下。主要代码如下:
class JaTextureUpdateCallback : public osg::NodeCallback
{
private:
typedef void(*JaGetDisplayDataFunc)(int *w, int *h, unsigned char *data);
osg::Texture2D* myTexture;
JaGetDisplayDataFunc getDisplayData;
osg::Image * myImage;
tttttt t;
public:
JaTextureUpdateCallback(const char *libName, osg::Texture2D*image): myTexture(image)
{
//getDisplayData = (JaGetDisplayDataFunc)QLibrary::resolve(libName, "getDisplayData");
myImage = new osg::Image;
myImage->allocateImage(t.width(), t.height(), 1, GL_RGBA, GL_UNSIGNED_BYTE);
//myImage->setDataVariance(osg::Object:YNAMIC);
myTexture->setImage(0,myImage);
t.show();
}
void __getDisplayDataFunc(int *w, int *h, unsigned char **data)
{
QPixmap pixmap(t.size());
t.render(&pixmap);
QImage image = QGLWidget::convertToGLFormat(pixmap.toImage());
*w = image.width();
*h = image.height();
int __size = image.numBytes() * sizeof(unsigned char);
unsigned char *__data = image.bits();
free(*data);
*data = (unsigned char *)malloc(__size);
memcpy(*data, __data, __size);
}
virtual void operator ()(osg::Node* node, osg::NodeVisitor* nv)
{
/*if(!getDisplayData)
return;*/
unsigned char *data = myImage->data();
int w, h;
__getDisplayDataFunc(&w, &h, &data);
myImage->dirty();
// getDisplayData(&w, &h, data);
//osg::ref_ptr<osg::Image > __image = new osg::Image;
/*myImage->setImage(w, h, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, data,
osg::Image::AllocationMode::USE_MALLOC_FREE);*/
//myTexture->setImage(0,0);
//myTexture->setImage(0,myImage);
traverse(node, nv);
}
};
/***********************************************************************************************/
JaDynamicTextureNode::JaDynamicTextureNode(double width, double height,
const char *libName)
{
addChild(createDisplayGraph(width, height, libName));
}
JaDynamicTextureNode::~JaDynamicTextureNode(void)
{
}
//创建预渲染场景
osg::Node* JaDynamicTextureNode::createDisplayGraph(double width, double height,
const char *libName)
{
osg::Group* group = new osg::Group;
//创建定点数组
osg::Vec3 top_left(0,-width / 2.0f, height / 2.0f);
osg::Vec3 bottom_left(0,-width / 2.0f, -height / 2.0f);
osg::Vec3 bottom_right(0,width / 2.0f, -height / 2.0f);
osg::Vec3 top_right(0,width / 2.0f, height / 2.0f);
// create the geometry for the wall.
osg::Geometry* geom = new osg::Geometry;
osg::Vec3Array* vertices = new osg::Vec3Array(4);
(*vertices)[0] = top_left;
(*vertices)[1] = bottom_left;
(*vertices)[2] = bottom_right;
(*vertices)[3] = top_right;
geom->setVertexArray(vertices);
osg::Vec2Array* texcoords = new osg::Vec2Array(4);
(*texcoords)[0].set(0.0f,1.0f);
(*texcoords)[1].set(0.0f,0.0f);
(*texcoords)[2].set(1.0f,0.0f);
(*texcoords)[3].set(1.0f,1.0f);
geom->setTexCoordArray(0,texcoords);
osg::Vec3Array* normals = new osg::Vec3Array(1);
(*normals)[0].set(0.0f,-1.0f,0.0f);
geom->setNormalArray(normals);
geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
osg::Vec4Array* colors = new osg::Vec4Array(1);
(*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
geom->setColorArray(colors);
geom->setColorBinding(osg::Geometry::BIND_OVERALL);
geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,4));
osg::Geode* geom_geode = new osg::Geode;
geom_geode->addDrawable(geom);
group->addChild(geom_geode);
// set up the texture state.
osg::Texture2D* texture = new osg::Texture2D;
texture->setDataVariance(osg::Object::DYNAMIC); // protect from being optimized away as static state.
texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D:INEAR);
texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
osg::StateSet* stateset = geom->getOrCreateStateSet();
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
/*stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);*/
//osg::Image * __image = new osg::Image;
//texture->setImage(0, __image);
// set the update callback to cycle through the various min and mag filter modes.
group->setUpdateCallback(new JaTextureUpdateCallback(libName, texture));
return group;
}
不论是采用osg::Image::setImage()或是采用如上代码自己调整image的内存数据,都会使刷新速度下降,若将上述代码中的myImage->dirty();屏蔽掉而不强制texture重新加载image则刷新很快。
请大家给予帮助,谢谢。 |
|