4

Visual Studio 2010 を使用して Windows XP (Qt 4.7.2) でいくつかのコードを作成してテストし、Windows 7 がインストールされた別のマシンで試しました。

プログラムは QDialog を開き、ウェブカメラの画像を表示する QGLWidget を作成します (いくつかの処理を行います)。Windows XP では画像が正しく表示されますが、Windows 7 マシンでプログラムをテストすると、QGLWidget が黒くなり、画像が表示されません。ただ不思議なことに、ウィンドウの周りを移動して画面の枠からはみ出すと、画像が一瞬表示され、再び移動を停止すると真っ暗になり、画像が正しく受信されているように思えます。 /processed (場合によっては)、QTimer に問題がある可能性があります。

関連するコードは次のとおりです。

初期化:

void GLVideo::initializeGL()
{   
    glEnable(GL_TEXTURE_2D);
    glShadeModel(GL_SMOOTH);

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClearDepth(1.0f);

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);

    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

    // Some OpenCV processing

    // Here I declare the timer, might it be the problem?
    m_timer = new QTimer(this);
    connect( m_timer, SIGNAL(timeout()), this, SLOT(timeOutSlot()) );
    m_timer->start( 33 );

}

タイムアウトごとに呼び出されるスロット:

void GLVideo::timeOutSlot() 
{
    ReceiveInfo();
    LoadTextures();
}

void GLVideo::LoadTextures() 
{   
    // Get the image from the webcam
    ProcessCamera();

    glBindTexture(GL_TEXTURE_2D, texture);  
    glTexImage2D( GL_TEXTURE_2D, 0, 3, qImage->width(), 
        qImage->height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, qImage->bits());
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

    updateGL();
}

void GLVideo::resizeGL( int width, int height )
{
    height = height?height:1;
    glViewport( 0, 0, (GLint)width, (GLint)height );
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

最後に、ウィジェットのペイント機能:

void GLVideo::paintGL()
{   
    glPushAttrib(GL_ALL_ATTRIB_BITS) ;
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    glPopAttrib() ;

    glEnable(GL_TEXTURE_2D);
    glShadeModel(GL_SMOOTH);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    glBindTexture(GL_TEXTURE_2D, texture);

    glColor4f(1.0f,1.0f,1.0f, 1.0f);
    glBegin(GL_QUADS);
        glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.65f, 1.24f, -3.0f);
        glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.65f, 1.24f, -3.0f);
        glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.65f,-1.24f, -3.0f);
        glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.65f,-1.24f, -3.0f);
    glEnd();    

    glDisable(GL_TEXTURE_2D);
    glDisable(GL_DEPTH_TEST);

    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();

    // Some 2D drawing:
}

私が間違っていることについて何か考えはありますか?SLOT timeOutSlot を呼び出していないのは QTimer ではないでしょうか?

4

3 に答える 3

5

paintGL()resizeGL()、または以外で OpenGL API を使用していますinitializeGL()

スロットが呼び出されたら、状態を変更して新しいフレームを描画できるようにしますが、OpenGL API はまだ呼び出さないでください。代わりに、 を呼び出しQWidget::updateGL()て、 の再実装で OpenGL 呼び出しを実行しますpaintGL()

あなたが経験している問題は、これら 3 つの関数の外では、GL コンテキストが現在のものではないということです。古い OS では問題にならないかもしれませんが、合成ウィンドウ マネージャを備えた OS では問題が発生します。たとえば、あなたの場合、あなたのプログラムは XP で唯一の OpenGL ユーザーだった可能性があるため、あなたのプログラムは常に現在のコンテキストでした。しかし、Windows 7 では、デスクトップ自体が OpenGL ではなくても Direct3D を使用します。同じハードウェア。

これら 3 つの関数の外部で OpenGL 関数を絶対に呼び出さなければならないQGLWidget::makeCurrent()場合は、最初に呼び出す必要がありますが、これは慣用的な使い方ではないことに注意してください。

QTimerでの作成に関してinitializeGL(): クラスのコンストラクターでそのタイマーを作成する方が確かに慣用的ですが、でも問題ないはずinitializeGL()です。

于 2011-05-05T17:43:57.603 に答える
3

プログラムが Windows XP では動作するが、Windows 7 では動作しない場合は、新しいバージョンのディスプレイ ドライバーがあるかどうかを確認することをお勧めします。

于 2011-05-05T19:00:29.067 に答える
3

こんにちは、新しい NVIDIA ドライバー (280.something) + Win7 で同様の問題 (画像が断続的に正しく描画された黒い画面) がありました。paintGL の最後とコンストラクター設定 setAutoBufferSwap( true) - これがお役に立てば幸いです。

于 2011-08-29T23:35:00.773 に答える