如何从OpenGL上下文ID正确加载纹理到OpenSceneGraph上下文?
我第一次撰写此类技术内容,若存在错误、重复或格式问题,敬请谅解。
我使用JOGL在OpenGL上下文中创建并加载了一张纹理,随后将上下文ID(context id)和纹理ID(texture id)传入OpenSceneGraph(OSG),编写的代码如下:
osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D(); osg::ref_ptr<osg::Texture::TextureObject> textureObject = new osg::Texture::TextureObject(texture.get(), (GLuint)handle, GL_TEXTURE_2D); textureObject->setAllocated(true); texture->setTextureObject(ID, textureObject.get());
原本以为可以通过OpenGL上下文句柄和纹理ID获取纹理,但打印发现纹理大小为0(Java端已知该纹理的实际大小),说明当前流程有误。请问正确的从OpenGL上下文ID获取纹理并加载到OSG的流程是什么?
你的核心问题是直接构造TextureObject并标记为已分配,但OSG并没有从OpenGL上下文中主动查询纹理的实际参数(比如尺寸、格式等),所以OSG内部的纹理元数据是缺失的,导致显示大小为0。正确的流程需要让OSG绑定到目标OpenGL上下文,主动查询纹理的属性并同步到OSG的Texture2D对象中,步骤如下:
确保OSG使用目标OpenGL上下文
在操作纹理前,需要让OSG的GraphicsContext切换到你通过JOGL创建的那个OpenGL上下文。可以通过osg::GraphicsContext::setCurrent()方法绑定上下文,确保后续的OpenGL调用都在目标上下文执行:// 假设你已经通过JOGL获取到上下文的osg::GraphicsContext实例 osg::GraphicsContext* gc = ...; // 对应你的JOGL上下文 if (gc) gc->setCurrent();查询OpenGL纹理的实际参数
绑定目标纹理ID,然后通过OpenGL API查询纹理的宽度、高度、内部格式等关键参数:GLuint textureId = (GLuint)handle; // 你的JOGL纹理ID glBindTexture(GL_TEXTURE_2D, textureId); GLint width, height, internalFormat; glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &internalFormat);初始化OSG的Texture2D对象并同步参数
创建OSG的Texture2D对象,设置从OpenGL查询到的参数,再关联TextureObject:osg::ref_ptr<osg::Texture2D> osgTexture = new osg::Texture2D(); osgTexture->setTextureSize(width, height); osgTexture->setInternalFormat(internalFormat); // 根据实际情况设置其他参数,比如过滤方式、环绕模式等 // 创建并关联TextureObject osg::ref_ptr<osg::Texture::TextureObject> texObj = new osg::Texture::TextureObject(osgTexture.get(), textureId, GL_TEXTURE_2D); texObj->setAllocated(true); osgTexture->setTextureObject(gc->getState()->getContextID(), texObj.get());验证并清理
操作完成后,可以取消上下文绑定(可选),然后检查OSG纹理的尺寸是否正确:if (gc) gc->releaseContext(); // 打印验证 std::cout << "OSG Texture Size: " << osgTexture->getTextureWidth() << "x" << osgTexture->getTextureHeight() << std::endl;
关键注意点:
- 必须在目标OpenGL上下文激活的状态下执行
glGetTexLevelParameteriv查询,否则会获取到错误的参数(比如当前上下文的默认纹理参数)。 - OSG的
Texture2D需要明确设置尺寸、格式等元数据,仅关联TextureObject不足以让OSG自动填充这些信息。 - 如果你的JOGL上下文和OSG的上下文是跨线程的,需要确保上下文切换的线程安全性,避免资源竞争。
内容的提问来源于stack exchange,提问作者Marc Romano

