2012-09-27 34 views
11

問題は

私はちょうどGLUTを使用してOpenGLで作業を始めました。以下のコードは、2つのワイヤフレームの立方体と球をコンパイルして表示します。問題は、ウィンドウをドラッグまたはサイズ変更しようとすると、マウスをたどる前に目に見える遅延が発生することです。OpenGL GLUTウィンドウが非常に遅いのはなぜですか?

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

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

コード

// 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(); 
} 
+1

あなたの 'draw'関数で' Sleep(1) 'を追加しようとしたかもしれません。 –

+1

実際にはうまくいきました!あなたはこの仕事の技術的理由を知っていますか、私の仲間の生徒は必要としないのですか? – aPerfectMisterMan

答えて

10

ソリューション:

レンダリング機能でSleep(1)を使用して簡単な解決策が働いたようです。あなたはまた理由を尋ねました - 私はこれを正しく解決することができないか分かりませんが、ここで私の推測は最高です:

なぜそれは機能しますか?

仲間の生徒は、ドライバでデフォルトでVSyncを有効にすることができます。これにより、画面がリフレッシュできるだけの速さで、おそらく60 fpsの速度でコードが実行されます。これはフレームをレンダリングするのに約16ミリ秒を与え、コードが効率的であれば(レンダリングに2msかかるなど)、CPUがウィンドウを動かすなどの他のOS関連の処理を行うのに多くの時間がかかります。

ここで、垂直同期を無効にすると、プログラムはできるだけ多くのフレームをレンダリングしようとし、他のすべてのプロセスを効果的に詰まらせます。私はこの1つの特定の問題を明らかにするので、あなたは睡眠を使用するように提案しました。 1〜3ミリ秒かどうかは関係ありませんが、実際には「ちょっと、CPU、今は特に何もしていないので、他のことをやっているかもしれません。

私のプログラムは遅くなっていませんか?

スリープの使用は一般的な手法です。それが1フレームごとに失われてしまうことが懸念されている場合は、全く同じように動作するので、Sleep(0)を入れてみてください。空き時間をCPUに与えてください。垂直同期を有効にして、実際に私の推測が正しいかどうかを検証することもできます。

また、スリープの有無にかかわらず、CPU使用率グラフを見ることもできます。プログラムの要件やCPUの速度によっては、100%(またはデュアルコアCPUの場合は50%)(できるだけ速く実行する)、さらにはそれよりも低くする必要があります。睡眠について

補足説明(0)

スリープ間隔が経過した後、スレッドを実行する準備ができています。 0ミリ秒を指定すると、スレッドはタイムスライスの残りの部分を放棄しますが、準備ができたままになります。準備スレッドはすぐに実行されることは保証されません。したがって、スレッドは、スリープインターバルが経過してからしばらくするまで実行されないことがあります。 - それはhereからです。

Linuxシステムでは、動作が多少異なる場合があります。私はLinuxの専門家ではありません。おそらく通行人が明らかにすることができます。

+1

+1良い説明。スリープ(0)_yields_スレッドの実行は、部分的に協調的なスレッドスケジューリング(a.o.t.preemptive_スレッドスケジューリング)を行います。 – sehe

+2

LinuxについてPOSIXでCPU時間を解放する関数は 'sched_yield'です。パラメータはなく、Windowsで 'Sleep(0)'を呼び出すのとほぼ同じ効果があります。 – datenwolf

関連する問題