2017-06-10 7 views
1

LinuxでX11でOpenGLを学習していて、何が間違っているのか分からないという問題がありました。オブジェクトが画面の空き領域で小さいときにOpenGLが遅く更新される

私は、画面上の大きなスペースをカバーするオブジェクトを描画すると、速くレンダリングし、高いフレームレートでX11に更新します。しかし、カメラからオブジェクトを遠くに移動したり、小さなオブジェクトを描画したりすると、画面上の小さな領域(ピクセル領域など)を覆うように、実際には遅く更新されます。それが小さいほど、フレームを更新する速度が遅くなります。

私は1x1飛行機から100ユニット離れていますが、1フレームあたり約1フレームに達します。ここで

はコードです:

XGetWindowAttributes(dpy, win, &gwa); 
glViewport(0, 0, Width, Height); 
SetupViewMatrix(); 

Camera * cam = mainCamera.GetComponent<Camera>(); 
if(cam != NULL){ 
    CamPose(cam->eyePose, cam->pivotPoint, cam->upDirection); 
} else { 
    CamPose(Vector3::back(), Vector3::forward(), Vector3::up()); 
} 
//glViewport(0, 0, gwa.width, gwa.height); 

ClearScreen(); 

GLfloat cube[] = { 
     -0.05f, -0.05f, -0.05f, 
     -0.05f, 0.05f, -0.05f, 
     0.05f, 0.05f, -0.05f, 
     -0.05f, -0.05f, -0.05f, 
     0.05f, 0.05f, -0.05f, 
     0.05f, -0.05f, -0.05f, 
};//*/ 
GLfloat colors[] = { 
     0.5f, 0.5f, 0.5f, 1.0f, 
     0.5f, 0.5f, 0.5f, 1.0f, 
     0.5f, 0.5f, 0.5f, 1.0f, 

     0.5f, 0.5f, 0.5f, 1.0f, 
     0.5f, 0.5f, 0.5f, 1.0f, 
     0.5f, 0.5f, 0.5f, 1.0f, 
};//*/ 

glVertexPointer(3, GL_FLOAT, 0, cube); 
glColorPointer(4, GL_FLOAT, 0, colors); 

glEnableClientState(GL_VERTEX_ARRAY); 
glEnableClientState(GL_COLOR_ARRAY); 
glDrawArrays(GL_TRIANGLES, 0, 6); 
glDisableClientState(GL_COLOR_ARRAY); 
glDisableClientState(GL_VERTEX_ARRAY); 

glXSwapBuffers(dpy, win); 
glFlush(); 

とSetupViewMatrix機能:

void WindowDrawer::SetupViewMatrix(){ 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    gluPerspective(65, (float)Width/Height, 0.1, 1000); 
}; 

とCLEARSCREEN機能:

void WindowDrawer::ClearScreen(){ 
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
} 

EDIT: 私はいくつかのより多くのコードを追加しています助けるために。私が見ることができるように、

void WindowObject::DealWithEvents(){ 
    if(XEventsQueued(windowDrawer.dpy, QueuedAlready)){ 
     XNextEvent(windowDrawer.dpy, &xev); 
     eventHandler.RouteXEvents(&xev, windowDrawer.dpy); 
    } else { 
     memset(&redrawEvent, 0, sizeof(redrawEvent)); 
     redrawEvent.type = Expose; 
     redrawEvent.xexpose.window = windowDrawer.win; 
     XSendEvent(windowDrawer.dpy, windowDrawer.win, False, ExposureMask, &redrawEvent); 
     XFlush(windowDrawer.dpy); 
     eventHandler.RouteXEvents((XEvent *)&redrawEvent, windowDrawer.dpy); 
    } 
}; 

まあ:

void WindowDrawer::InitX11OpenGL(){ 
    dpy = XOpenDisplay(NULL); 
    if(dpy == NULL){ 
     printf("\n\tCannot Connect to X server\n\n"); 
     exit(0); 
    } 
    root = DefaultRootWindow(dpy); 

    vi = glXChooseVisual(dpy, 0, att); 
    if(vi == NULL){ 
     printf("\n\tno appropriate visual found\n\n"); 
     exit(0); 
    } else { 
     printf("\nvisual %p selected\n", (void *)vi->visualid); 
    } 
    cmap = XCreateColormap(dpy, root, vi->visual, AllocNone); 
    swa.colormap = cmap; 
    swa.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask; 

    win = XCreateWindow(dpy, root, 0, 0, 720, 480, 0, vi->depth, InputOutput, vi->visual, CWColormap | CWEventMask, &swa); 
    XMapWindow(dpy, win); 
    glc = glXCreateContext(dpy, vi, NULL, GL_TRUE); 
    glXMakeCurrent(dpy, win, glc); 
    glEnable(GL_DEPTH_TEST); 
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f); 
} 

と私はイベントループを作成するために使用しています。この1: この1つは、私は、ウィンドウを作成するために使用していInit関数でありますこれはパフォーマンス上の問題ではなく、更新キュー(またはそれに似たもの)の問題です。オブジェクトがカメラに近づくと、大きなスクリーンスペースが使用されるため、より速く描画されますが、スクリーンスペースが小さくなると、スクリーンの更新が直線的に遅くなります。公開、キー押し、キーリリースのイベントを印刷しています。これらのイベントはすべて速く実行されます。画面領域の更新のみがシステムの速度に追従しません。

+0

どのOpenGLのバージョンをターゲットにしていますか?最新のOpenGLでは、 'glEnableClientState'がOpenGL 4.5で削除されました。シェーダのないレンダリングもサポートされていません。 –

+0

私はそれが問題の問題ではないと確信しています。 –

+1

どのようにフレームレートを測定していますか?(私はそれを見るだけではなく、小さなオブジェクトはしばしば変化しないことを望む)X Exposeイベントを生成して、各フレームの後にXClearを強制的にタイマーする方法はありますか?イベント圧縮を有効にしていますか? –

答えて

-2

ここでは、「最適化された」ようには見えません。たとえば、gluPerspectiveを使用します。それは10年後に廃止されました!私たちはそれを望んでいません!なぜあなたのカメラクラスにあなた自身のビューマトリックスを作ってみませんか? :)

また、これが問題なのかどうかはわかりません。しかし、あなたはRENDERループ内でglClearColorを呼び出すようです。それはもちろん、良くありません。これをあなたのinit関数に入れてください。それは可能な問題です。

+0

返信ありがとうございます。私はちょうどチュートリアルに従っている、これは私が古い関数を使用している理由です:)。 glClearColorをinit関数に移動しようとしましたが、これで問題は解決されませんでした。 –

+0

また、後でもっと良い方法を実装しようとしていますが、今のところ私はちょうど学んでいます:) –

+0

問題のない友人、あなたのエラーを見つける上で幸運! :) – Verideth

0

ああ、私はエラーを見つけました、そして、私はこれについて私自身の質問に甘んじています。私はこれを言うのは恥ずかしいので、それは本当にグラフィックスの初心者から期待どおりに馬鹿だったため、/

問題は、私は低ppiモニターで、小さな画面で作業しているということです。さらに、画面上の形状は完全な四角形(ピクセル上に斜めの辺をペイントしません)なので、オブジェクトが小さい場合、境界ピクセルを塗り直すまでに長い時間がかかります。コンピュータグラフィックスは、この効果を滑らかにするためにいくつかのアンチエイリアシング効果を使用し、生のOpenGLはそうではありません。私はそれが単なるピクセル詳細問題であることを理解するまで、長い時間をかけました...

ありがとうございました。

+0

これは不合理な1fpsについては説明しません。 – Ripi2

+0

さて、1fpsはありませんでしたが、ちょうどピクセルが補間されると、1秒で描画されるピクセルが変更されるなど、小さな形状が描かれているため、ピクセルが再描画されるのに約1秒かかりました... –

関連する問題