2017-04-19 59 views
1

我有模型游戏,当我渲染它们时,我的CPU使用率变高(每个模型约为10%)。我使用glutMainLoop每秒调用DisplayFunc 60次。我打电话有绘图功能在哪里如何在OpenGL游戏中正确渲染模型(使用纹理网格)而CPU使用率不高?

  • glPushMatrix
  • 的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并切换到顶点缓冲区和着色器。 [见这个问题。(http://stackoverflow.com/questions/14300569/opengl-glbegin-glend) – VTT

+0

我还算是一个OpenGL小白的,但你在做脸剔除正常吗? https://learnopengl.com/#!Advanced-OpenGL/Face-culling –

+0

@VTT你可以评论我添加了什么? – ground0

回答

1

VTT的评论re:glBegin/glEnd是正确的答案。为了扩展它,使用旧的,不赞成使用的API,你会遇到一个确定的问题和一个潜在的问题。

确切的问题是,OpenGL无法利用现代GPU中的许多硬件加速功能,因为它不会在GPU内存中存储所有三角形(即顶点)和材质(例如纹理),而可能需要每次渲染东西时,至少将其中一些内存从主内存复制到GPU内存。这是一个不重要的开销,您可以通过使用顶点缓冲区以及顶点着色器和片段着色器来轻松避免。

如果您搜索它们,可能需要一些时间来重构您的代码,但是知道该怎么做应该不是问题。

潜在的问题是固定功能流水线已经被弃用了一段时间(并且非正式地被阻止的时间更长),因此许多驱动程序可能更多地包含该功能,以便与旧游戏和应用程序兼容,而不是作为优化的活动目标。换句话说,开发人员的时间花在优化现代API上,而不是20世纪90年代后期的API上。

你最终以你的方式编写代码很可能不是你的错。不幸的是,旧版书籍的网页和免费提供的副本提供了很多基于旧的固定功能流水线而不是现代可编程流水线的例子。结合(最初)固定功能管线通常更容易理解和使用的事实,会导致像您所处的情况。但是,学习现代API非常值得。它可以让您的图形在“低端”系统上闪耀,可以为您带来丰富的机会。

+0

你能评论我添加了什么吗? – ground0

0

所以,现在你正在以新的方式做事,但你没有充分利用你所能做的一切。每次渲染时都会上传几何图形。由于它不会改变(您使用的是GL_STATIC_DRAW),请勿多次上传。一旦它在视频内存中存在,它将一直存在,直到你删除它。与着色器的制服一样。您需要的唯一调用是清除颜色,绑定各种数组和属性,绘制数组,然后解除各种数组和属性的绑定。可能是冲水。glBufferData()电话可能是这么长时间。我不得不说,10%的CPU使用率是没有的。我不确定为什么你会担心。实际上,各种新的渲染器(Metal,Vulkan,DX12)基本上可用于减少渲染的CPU组件。如果只有10%,他们几乎不需要!