gpt4 book ai didi

c++ - 将 Coin3D SoOffscreenRenderer 转换为 QImage 并使用 OpenGL 进行渲染

转载 作者:太空狗 更新时间:2023-10-29 23:17:07 25 4
gpt4 key购买 nike

我正在尝试使用 SoOffscreenRendererQGLWidget 中使用 QT 显示 Coin3D/Open Inventor 场景,我需要帮助将其转换为 QImage

到目前为止,我尝试将场景渲染到 SoOffscreenRenderer 中并像这样获取缓冲区:

unsigned char * getCoinCubeImgBuffer(){
// [...] create the scene, add lightning and camera

SoOffscreenRenderer offscreenRenderer(vpRegion);
offscreenRenderer.setComponents(
SoOffscreenRenderer::Components::RGB_TRANSPARENCY
);
SbBool ok = offscreenRenderer.render(root);

// to be sure that something is actually rendered
// save the buffer content to a file
SbBool ok = offscreenRenderer.render(root);
qDebug() << "SbBool ok?" << ok;
qDebug() << "wasFileWrittenRGB" <<
offscreenRenderer.writeToRGB("C:/test-gl.rgb");
qDebug() << "wasFileWrittenPS" <<
offscreenRenderer.writeToPostScript("C:/test-gl.ps");


unsigned char * imgbuffer = offscreenRenderer.getBuffer();
return imgbuffer;
}

然后从缓冲区数据创建一个QImage:

QImage convertImgBuffer(){
unsigned char *const imgBuffer = getCoinCubeImgBuffer();
QImage img(imgBuffer, windowWidth, windowHeight, QImage::Format_ARGB32);

// Important!
img = img.rgbSwapped();

QImage imgGL = convertToGLFormat(img);
return imgGL;
}

这是正确的做法吗?

this question about drawing a QImage 中所述,如果来源是图片,我就能画出来。

e:为了确保我的缓冲区确实包含一个场景,我将缓冲区内容写入两个文件。例如,您可以使用 IrfanView 及其插件查看 .rgb 和 .ps 文件。

e2:刚刚发现,我必须使用 img.rgbSwapped()。现在它显示的场景是黑白的,没有闪电。我会进一步调查。

e3:对于这样的代码,您需要以这种方式调整 OpenGL 调用以进行彩色渲染

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex.width(), 
tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, tex.bits());

第一种格式是 GL_RGB,第二种是 GL_RGBA。立方体仍然是完全黑色的。

e4:这是我场景中的一个错误,你必须在添加其余部分之前添加灯光,尤其是在添加相机之前。


<删除>所以现在我可以使用 `QGLWidget` 的函数,如 `bindTexture()` 或使用直接的 OpenGL 调用,但我不确定具体如何。如果有人能把我推向正确的方向,那就太好了。我不能像这样使用 OpenGL 吗? glEnable(GL_TEXTURE_2D); glGenTextures(1, &offscreenBufferTexture); glBindTexture(GL_TEXTURE_2D, offscreenBufferTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imgGL.width(), imgGL.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, imgGL.bits());或者也许是 `glDrawPixels()`? glDrawPixels(imgGL.width(), imgGL.height(), GL_RGBA, GL_UNSIGNED_BYTE, imgGL.bits());


我想出了如何使用 OpenGL 绘制 QImage,请参阅 this thread .所以缓冲区或它的转换似乎有问题。

最佳答案

这是正确渲染场景的结果代码。

首先创建一个有效的场景

void loadCoinScene(){
// Init Coin
SoDB::init();
// The root node
root = new SoSeparator;
root->ref();

// Add the light _before_ you add the camera
SoDirectionalLight * light = new SoDirectionalLight;
root->addChild(light);

vpRegion.setViewportPixels(0, 0, coinSceneWidth, coinSceneHeight);

SoPerspectiveCamera *perscam = new SoPerspectiveCamera();
root->addChild(perscam);

SbRotation cameraRotation = SbRotation::identity();
cameraRotation *= SbRotation(SbVec3f(0, 1, 0), 0.4f);
perscam->orientation = cameraRotation;

SoCube * cube = new SoCube;
root->addChild(cube);
// make sure that the cube is visible
perscam->viewAll(root, vpRegion);
}

然后将场景渲染到 Offscreen Buffer 中并将其转换为 QImage:

QImage getCoinCubeImgBuffer(){
SoOffscreenRenderer offscreenRenderer(vpRegion);
offscreenRenderer.setComponents(
SoOffscreenRenderer::Components::RGB_TRANSPARENCY
);
offscreenRenderer.render(root);

QImage img(offscreenRenderer.getBuffer(), coinSceneWidth,
coinSceneHeight, QImage::Format_ARGB32);

// Important!
return img.rgbSwapped();
}

如果您现在想使用 OpenGL 渲染 QImage,请使用我的 Render QImage with OpenGL 中的解决方案质疑并将 loadTexture2() 方法更改为:

QImage loadTexture2(GLuint &textureID){
glEnable(GL_TEXTURE_2D); // Enable texturing

glGenTextures(1, &textureID); // Obtain an id for the texture
glBindTexture(GL_TEXTURE_2D, textureID); // Set as the current texture

QImage im = getCoinCubeImgBuffer();
// Convert to OpenGLs unnamed format
// The resulting GL format is GL_RGBA
QImage tex = QGLWidget::convertToGLFormat(im);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex.width(), tex.height(), 0,
GL_RGBA, GL_UNSIGNED_BYTE, tex.bits());

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

glDisable(GL_TEXTURE_2D);

return tex;
}

关于c++ - 将 Coin3D SoOffscreenRenderer 转换为 QImage 并使用 OpenGL 进行渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20126354/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com