3

QGLWidgetを使用して、QT を使用して Coin3D/Open Inventor シーンを表示しようとしていますSoOffscreenRendererQImage

私がこれまでに試したことは、シーンをレンダリングして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;
}

これは正しい方法でしょうか?

QImage の描画に関するこの質問で説明されているように、ソースが画像の場合は描画できます。

e: バッファーに実際にシーンが含まれていることを確認するために、バッファーの内容を 2 つのファイルに書き込みます。たとえば、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、2 番目の形式は GL_RGBA です。ただし、立方体はまだ完全に黒です。

e4: 私のシーンではエラーでした。残りを追加する前に、特にカメラを追加する前にライトを追加する必要があります。


これで、`bindTexture()` のような `QGLWidget` の関数を使用するか、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 を描画する方法を見つけました。このスレッドを参照してください。そのため、バッファまたはその変換に問題があるようです。

4

3 に答える 3

0

QImage を介してテクスチャをフィードする必要はないと思います。以下は実際の例です。

#include <QApplication>
#include <QGLWidget>
#include <Inventor/SoInput.h>
#include <Inventor/SoOffscreenRenderer.h>
#include <Inventor/nodes/SoSeparator.h>

static GLuint textureID(0);

class GLWidget : public QGLWidget
{
public:
    explicit GLWidget() : QGLWidget() {}
    ~GLWidget() {}
protected:
    void initializeGL() {
        glShadeModel(GL_FLAT);
        glEnable(GL_LIGHTING);
        glEnable(GL_LIGHT0);
        static GLfloat lightAmbient[4] = { 1.0, 1.0, 1.0, 1.0 };
        glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient);
    }
    void paintGL() {
        if (!textureID)
            return;
        glClearColor(0.4f, 0.1f, 0.1f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, textureID);

        glBegin(GL_QUADS);
            glTexCoord2f(0,0); glVertex3f(-1, -1, -1);
            glTexCoord2f(1,0); glVertex3f( 1, -1, -1);
            glTexCoord2f(1,1); glVertex3f( 1,  1, -1);
            glTexCoord2f(0,1); glVertex3f(-1,  1, -1);
        glEnd();

        glDisable(GL_TEXTURE_2D);
    }
    void resizeGL(int width, int height) {
        int side = qMin(width, height);
        glViewport((width - side) / 2, (height - side) / 2, side, side);

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-1.0, 1.0, -1.0, 1.0, 0.0, 1000.0);
        glMatrixMode(GL_MODELVIEW);
    }
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    GLWidget glWidget;
    glWidget.show();

    static const char * inlineSceneGraph[] = {
        "#Inventor V2.1 ascii\n",
        "\n",
        "Separator {\n",
        "  PerspectiveCamera { position 0 0 5 }\n",
        "  DirectionalLight {}\n",
        "  Rotation { rotation 1 0 0  0.3 }\n",
        "  Cone { }\n",
        "  BaseColor { rgb 1 0 0 }\n",
        "  Scale { scaleFactor .7 .7 .7 }\n",
        "  Cube { }\n",
        "\n",
        "  DrawStyle { style LINES }\n",
        "  ShapeHints { vertexOrdering COUNTERCLOCKWISE }\n",
        "  Coordinate3 {\n",
        "    point [\n",
        "       -2 -2 1.1,  -2 -1 1.1,  -2  1 1.1,  -2  2 1.1,\n",
        "       -1 -2 1.1,  -1 -1 1.1,  -1  1 1.1,  -1  2 1.1\n",
        "        1 -2 1.1,   1 -1 1.1,   1  1 1.1,   1  2 1.1\n",
        "        2 -2 1.1,   2 -1 1.1,   2  1 1.1,   2  2 1.1\n",
        "      ]\n",
        "  }\n",
        "\n",
        "  Complexity { value 0.7 }\n",
        "  NurbsSurface {\n",
        "     numUControlPoints 4\n",
        "     numVControlPoints 4\n",
        "     uKnotVector [ 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0 ]\n",
        "     vKnotVector [ 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0 ]\n",
        "  }\n",
        "}\n",
        NULL
    };

    SoInput in;
    in.setStringArray(inlineSceneGraph);

    glWidget.resize(600, 600);
    SoOffscreenRenderer renderer(SbViewportRegion(glWidget.width(),
                                                  glWidget.height()));
    renderer.setComponents(SoOffscreenRenderer::RGB_TRANSPARENCY);
    renderer.setBackgroundColor(SbColor(.0f, .0f, .8f));
    SoSeparator *rootScene = SoDB::readAll(&in);
    rootScene->ref();
    renderer.render(rootScene);
    rootScene->unref();

    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

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
                 renderer.getViewportRegion().getViewportSizePixels()[0],
                 renderer.getViewportRegion().getViewportSizePixels()[1],
                 0, GL_BGRA, GL_UNSIGNED_BYTE, renderer.getBuffer());

    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 app.exec();
}
于 2014-04-22T21:00:21.820 に答える