2017-04-19 7 views
1

私はモデルを使ってゲームをしています。レンダリングすると、CPU使用率が高くなります(1つのモデルにつき約10%)。私はを使用して、DisplayFuncを1秒間に60回呼び出します。 glPushMatrixCPU使用率の高いOpenGLゲームでモデル(テクスチャ付きメッシュ)を正しくレンダリングするにはどうすればよいですか?

  • です
  • glTranslatef、glRotatef、glScalef
  • glMaterialfvテクスチャのための材料は、私は私のテクスチャ三角形その後、顔のためのループで
  • ため
  • glBeginをバインドするようglNormal3f私はそこの機能を描画呼び出し、glTexCoord2f、glVertex3f、三角形用
  • glEnd
  • およびglPopMatrix

私は何が間違っているのかわからないし、足場もないので、私はここで尋ねています。

わかりましたので、私は簡単な修正を行いました。

#include <GL/glut.h> 
    #include <gl/glext.h> 

    void Display(); 
    void Reshape(int width, int height); 

    const int windowWidth = 480; 
    const int windowHeight = 270; 

    GLuint vertexbuffer; 
    static const GLfloat g_vertex_buffer_data[] = 
    { 
     -1.0f, -1.0f, 0.0f, 
     1.0f, -1.0f, 0.0f, 
     0.0f, 1.0f, 0.0f, 
    }; 

    int main(int argc, char* argv[]) 
    { 
     glutInit(&argc, argv); 
     glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); 
     glutInitWindowPosition(100, 100); 
     glutInitWindowSize(windowWidth, windowHeight); 
     glutCreateWindow("Modern OpenGL"); 

     glutDisplayFunc(Display); 
     glutReshapeFunc(Reshape); 
     glutIdleFunc(Display); 

     GLfloat reset_ambient[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; 
     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, reset_ambient); 
     glEnable(GL_LIGHTING); 
     glShadeModel(GL_SMOOTH); 
     glEnable(GL_LIGHT0); 

     glGenBuffers(1, &vertexbuffer); 

     glutMainLoop(); 

     return 0; 
    } 

    void Display() 
    { 
     glClearColor(1.0, 1.0, 1.0, 1.0); 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
     glLoadIdentity(); 

     gluLookAt(0,0,10,0,0,0,0,1,0); 

     GLfloat light0amb[4] = { 1.0, 1.0, 1.0, 1.0 }; 
     glLightfv(GL_LIGHT0, GL_AMBIENT, light0amb); 
     GLfloat light0dif[4] = { 1.0, 1.0, 1.0, 1.0 }; 
     glLightfv(GL_LIGHT0, GL_DIFFUSE, light0dif); 
     GLfloat light0spe[4] = { 1.0, 1.0, 1.0, 1.0 }; 
     glLightfv(GL_LIGHT0, GL_SPECULAR, light0spe); 
     GLfloat light0pos[4] = { 0.0, 0.0, 0.0, 1.0 }; 
     glLightfv(GL_LIGHT0, GL_POSITION, light0pos); 

     glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); 
     glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW); 
     glEnableVertexAttribArray(0); 
     glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); 
     glVertexAttribPointer(
      0, 
      3, 
      GL_FLOAT, 
      GL_FALSE, 
      0, 
      (void*)0 
     ); 
     glDrawArrays(GL_TRIANGLES, 0, 3); 
     glDisableVertexAttribArray(0); 

     glFlush(); 
     glutSwapBuffers(); 
    } 

    void Reshape(int width, int height) 
    { 
     glutReshapeWindow(windowWidth, windowHeight); 
     glMatrixMode(GL_PROJECTION); 
     glLoadIdentity(); 
     glViewport(0, 0, width, height); 
     gluPerspective(45.0f, width/(double)height, 0.1f, 1000.0f); 
     glMatrixMode(GL_MODELVIEW); 
    } 
+3

廃止予定の 'glBegin' /' glEnd' APIと固定パイプラインAPIの使用を止め、頂点バッファとシェーダに切り替えるべきです。 [この質問を参照してください。](http://stackoverflow.com/questions/14300569/opengl-glbegin-glend) – VTT

+0

私はある種のopenglのnoobですが、正しくカリングをしていますか? https://learnopengl.com/#!Advanced-OpenGL/Face-culling –

+0

@VTTあなたが追加したものについてコメントすることができますか? – ground0

答えて

1

VTTのコメント:glBegin/glEndが正しい答えです。それを少し拡張するために、古くなった非難されたAPIを使用することで、1つの明確な問題と1つの潜在的な問題が発生しています。

GPUメモリに保存されている三角形(つまり頂点)やマテリアル(テクスチャなど)をすべて取るのではなく、OpenGLでハードウェアアクセラレーション機能を利用できないという問題があります。物事をレンダリングするたびに、それらのうちの少なくともいくつかをメインメモリからGPUメモリにコピーします。これは、頂点シェーダとフラグメントシェーダと一緒に頂点バッファを使用することで簡単に避けることができます。

多くの例がありますので、コードをリファクタリングするのに時間がかかることがありますが、その方法を知っていては問題ではないはずです。

潜在的な問題は、固定機能パイプラインが、しばらくの間非難されており(多くのドライバーが、その機能を、より古いゲームやアプリケーションとの互換性のためにアクティブなターゲットとしてではなく) 。つまり、開発者の時間は、1990年代後半のAPIではなく、現代のAPIの最適化に費やされています。

あなたのコードをあなたのやり方で書くことになったのはあなたのせいではないでしょう。残念ながら、古い書籍のウェブと自由に利用できるコピーは、現代のプログラマブルなパイプラインではなく古い固定機能のパイプラインに基づく多くの例を提供しています。 (最初は)固定機能パイプラインがしばしば理解して使いやすくなるという事実と組み合わさって、あなたがいるような状況に繋がります。しかし、現代のAPIを学ぶ時間は十分です。 「ローエンド」システムでもグラフィックスを輝かせる効果の点で、豊富な機会を提供します。

+0

私が追加したものをコメントできますか? – ground0

0

これで、あなたは新しいやり方をしていますが、可能な限りすべてを活用しているわけではありません。レンダリングするたびにジオメトリをアップロードしています。変更していないので(GL_STATIC_DRAWを使用しています)、複数回アップロードしないでください。あなたがそれを削除するまで、それがビデオメモリにそこにあると、そこにとどまるでしょう。あなたのシェイダーのユニフォームと同じです。必要な呼び出しは、色を消去し、さまざまな配列と属性をバインドし、配列を描画してから、さまざまな配列と属性のバインドを解除することだけです。そしておそらくフラッシュ。glBufferData()コールは、おそらく長い時間がかかります。

また、10%のCPU使用率は何もないと言わなければなりません。それがなぜあなたに関係するのか分かりません。実際、様々な新しいレンダラー(Metal、Vulkan、DX12)はレンダリングのCPUコンポーネントを減らすために基本的に便利です。それがわずか10%だったら、彼らはほとんど必要ありませんでした!

関連する問題