You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 17:05:33