11

問題

GLUT を使用して OpenGL を使い始めたところです。以下のコードは、2 つのワイヤフレーム キューブと 1 つの球体をコンパイルして表示します。問題は、ウィンドウをドラッグまたはサイズ変更しようとすると、マウスを追跡する前に顕著な遅延が発生することです。

この問題は、同じコードの同僚のコンピューターでは発生しません。

Windows 7 コンピューターで Visual Studio 2012 c++ Express を使用しています。私は経験豊富なプログラマーではありません。

コード

    // OpenGLHandin1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <GL/glut.h>

void initView(int argc, char * argv[]){
    //init here
    glutInit(&argc, argv);
    //Simple buffer
    glutInitDisplayMode( GLUT_SINGLE | GLUT_RGBA );
    glutInitWindowPosition(100,100);
    glutInitWindowSize(800,400);
    glutCreateWindow("Handin 2");
}
void draw(){

    glClearColor(0,0,0,1);
    glClear(GL_COLOR_BUFFER_BIT);
    //Background color

    glPushMatrix();
    glLoadIdentity();
    glTranslatef(0.6, 0, 0);

    glColor3f(0.8,0,0);
    glutWireCube(1.1); //Draw the cube
    glPopMatrix();

    glPushMatrix();
    glLoadIdentity();
    glTranslatef(-0.5, 0, -0.2);

    glColor3f(0,0.8,0);
    glutWireCube(1.1); //Draw the cube
    glPopMatrix();

    glPushMatrix();
    glLoadIdentity();
    glTranslatef(0, 1.2, 0);
    glRotatef(90, 1, 0, 0);

    glColor3f(1,1,1);
    glutWireSphere(0.6, 20, 20); //Draw the sphere
    glPopMatrix();

    //draw here
    //glutSwapBuffers();
    glutPostRedisplay();
    glFlush();

}
void reshape (int w, int h){
    glViewport(0,0,w ,h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45, (float)w/(float)h, 1.5, 10);
    gluLookAt(1.5, 2.5, 4, 
              0, 0.6, 0, 
              0, 1, 0); //Orient the camera
    glRotatef(5, 0, 0, 1);
    glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char * argv[])
{
    initView(argc,argv);
    glutDisplayFunc(draw);
    glutReshapeFunc(reshape);
    glutMainLoop();
}
4

1 に答える 1

12

解決:

Sleep(1)render 関数で使用する簡単なソリューションが機能したようです。理由も尋ねられました-これを適切に解決できるかどうかはわかりませんが、私の最善の推測は次のとおりです。

なぜそれが機能するのですか?

仲間の学生は、ドライバーでデフォルトで VSync をオンにすることができます。これにより、コードは画面がリフレッシュできる速度 (おそらく 60 fps) でのみ実行されます。フレームをレンダリングするのに約 16 ミリ秒かかります。コードが効率的である場合 (たとえば、レンダリングに 2 ミリ秒かかります)、CPU がウィンドウの移動など、他の OS 関連の作業を行うための十分な時間を残します。

現在、垂直同期を無効にすると、プログラムはできるだけ多くのフレームをレンダリングしようとし、他のすべてのプロセスを事実上詰まらせます。この 1 つの特定の問題が明らかになるため、Sleep を使用することをお勧めします。それが 1 ミリ秒であろうと 3 ミリ秒であろうと、実際には「ねえ、CPU、私は今特に何もしていないので、他のことをすることができます」と言います。

しかし、それは私のプログラムを遅くしていませんか?

スリープの使用は一般的な手法です。フレームごとに 1 ミリ秒の損失が気になる場合は、 を入れてみることもできますSleep(0)。CPU に空き時間を与えることで、まったく同じように動作するはずです。垂直同期を有効にして、私の推測が実際に正しいかどうかを確認することもできます。

ちなみに、スリープの有無にかかわらず、CPU 使用率のグラフを確認することもできます。プログラムの要件と CPU の速度に応じて、(可能な限り高速に実行する) なしで 100% (またはデュアルコア CPU では 50%) であり、ある場合ははるかに低くなります。

Sleep(0) に関するその他の注意事項

スリープ間隔が経過すると、スレッドは実行可能になります。0 ミリ秒を指定すると、スレッドは残りのタイム スライスを放棄しますが、準備が整ったままになります。準備完了スレッドがすぐに実行されるとは限らないことに注意してください。その結果、スレッドは、スリープ間隔が経過した後しばらく実行されない場合があります。-ここからです。

また、Linux システムでは動作が若干異なる場合があることに注意してください。しかし、私は Linux の専門家ではありません。おそらく通行人が明確にすることができます。

于 2012-09-27T11:35:54.947 に答える