将Coin3D SoOffscreenRenderer转换为QImage并使用OpenGL进行渲染 [英] Convert Coin3D SoOffscreenRenderer to QImage and render with OpenGL
问题描述
我试图通过使用 SoOffscreenRenderer
QGLWidget 中显示带有QT的Coin3D / Open Inventor场景>我需要帮助将其转换为 QImage
I'm trying to display a Coin3D/Open Inventor scene with QT in a QGLWidget
, by using the SoOffscreenRenderer
and I need help converting it to a QImage
到目前为止,我试图将场景渲染为 SoOffscreenRenderer
并获得如下的缓冲区:
What I tried so far, is render the scene into SoOffscreenRenderer
and get the buffer like this:
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
从缓冲区数据:
and then create a QImage
from the buffer data:
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;
}
这是正确的做法吗?
如有关绘制QImage的问题中所述,我
e:为了确保我的缓冲区实际上包含一个场景,我将缓冲区内容写入两个文件。例如,您可以使用IrfanView及其插件查看.rgb和.ps文件。
e: To make sure that my buffer actually contains a scene, I write the buffer content to two files. You can view .rgb and .ps files for example with IrfanView plus its plugins.
e2:刚才知道,我必须使用 img .rgbSwapped()
。现在它显示黑色和白色的场景,没有闪电。我会进一步调查。
e2: Just figured out, that I have to use img.rgbSwapped()
. Now it's showing the scene black&white and without lightning. I will investigate further.
e3:使用这样的代码,你需要调整OpenGL调用以这种方式呈现彩色
e3: With the code like this, you need to adapt the OpenGL call in this way to render in color
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex.width(),
tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, tex.bits());
第一种格式是GL_RGB,第二个GL_RGBA。
First format is GL_RGB, second GL_RGBA. The cube is still completely black though.
e4:这是我的场景中的一个错误,你必须添加一个光,然后再添加其余的,尤其是在添加
e4: It was an error in my scene, you have to add a light before you add the rest and especially before you add the camera.
我想出了如何使用OpenGL绘制QImage, a href =http://stackoverflow.com/questions/20245865/render-qimage-with-opengl>此主题。所以似乎有一个缓冲区或其转换的问题。
I figured out how to draw a QImage with OpenGL, see this thread. So there seems to be a problem with the buffer or the conversion of it.
推荐答案
这里是生成的代码, 。
Here's the resulting code which renders the scene correctly.
首先创建一个有效的场景
First create a valid scene
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);
}
然后将场景渲染到屏幕缓冲区并将其转换为 QImage
:
Then render the scene into the Offscreen Buffer and convert it to a 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();
}
如果你现在想渲染 QImage
使用OpenGL,使用我的解决方案从我的使用OpenGL渲染QImage 问题和更改
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;
}
这篇关于将Coin3D SoOffscreenRenderer转换为QImage并使用OpenGL进行渲染的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!