C++ 如何在OpenGL游戏中正确地渲染模型(带有纹理的网格),而不需要高CPU使用率?
我有一个模型游戏,当我渲染它们时,我的CPU使用率很高(每个模型大约10%)。我使用C++ 如何在OpenGL游戏中正确地渲染模型(带有纹理的网格),而不需要高CPU使用率?,c++,opengl,cpu,C++,Opengl,Cpu,我有一个模型游戏,当我渲染它们时,我的CPU使用率很高(每个模型大约10%)。我使用glutMainLoop,它每秒调用DisplayFunc60次。我在那里调用绘图函数 glPushMatrix glTranslatef,glRotatef,glScalef GLMATERALEV所以材质对于纹理,我绑定我的纹理 三角形的glBegin 然后在循环中为面glNormal3f、glTexCoord2f、glVertex3f为三角形 格伦德 和GLPOP矩阵 我不知道我做错了什么,我没有任何立
glutMainLoop
,它每秒调用DisplayFunc
60次。我在那里调用绘图函数
- glPushMatrix
- glTranslatef,glRotatef,glScalef
- GLMATERALEV所以材质对于纹理,我绑定我的纹理
- 三角形的glBegin
- 然后在循环中为面glNormal3f、glTexCoord2f、glVertex3f为三角形
- 格伦德
- 和GLPOP矩阵
#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);
}
#包括
#包括
void Display();
空洞重塑(内部宽度、内部高度);
常数int windowWidth=480;
const int windowHeight=270;
GLuint顶点缓冲区;
静态常量GLfloat g_顶点_缓冲区_数据[]=
{
-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);
位置(100100);
glutInitWindowSize(窗口宽度、窗口高度);
glutCreateWindow(“现代OpenGL”);
glutDisplayFunc(显示器);
GLUTREFORUNC(重塑);
glutIdleFunc(显示);
GLfloat reset_环境[4]={0.0f,0.0f,0.0f,1.0f};
GLLIGHTModelf(GL_灯光_模型_环境、重置_环境);
glEnable(德国劳埃德大学照明);
glShadeModel(GL_平滑);
glEnable(GL_LIGHT0);
glGenBuffers(1和vertexbuffer);
glutMainLoop();
返回0;
}
无效显示()
{
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
glLoadIdentity();
gluLookAt(0,0,10,0,0,0,0,1,0);
GLfloat light0amb[4]={1.0,1.0,1.0,1.0};
glLightfv(GLU LIGHT0、GLU环境光、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_镜面反射,light0spe);
GLfloat light0pos[4]={0.0,0.0,0.0,1.0};
glLightfv(GLU LIGHT0、GLU位置、light0pos);
glBindBuffer(GL_数组_BUFFER,vertexbuffer);
glBufferData(GLU数组缓冲区、sizeof(g顶点缓冲区数据)、g顶点缓冲区数据、GLU静态绘图);
GlenableVertexAttributeArray(0);
glBindBuffer(GL_数组_BUFFER,vertexbuffer);
glvertexattributepointer(
0,
3.
浮球,
GL_FALSE,
0,
(无效*)0
);
gldrawArray(GL_三角形,0,3);
glDisableVertexAttributeArray(0);
glFlush();
glutSwapBuffers();
}
空洞重塑(整型宽度、整型高度)
{
窗口宽度(窗口宽度、窗口高度);
glMatrixMode(GL_投影);
glLoadIdentity();
glViewport(0,0,宽度,高度);
透视图(45.0f,宽/(双)高,0.1f,1000.0f);
glMatrixMode(GLU模型视图);
}
VTT关于glBegin/glEnd的评论是正确的答案。进一步说,使用旧的、不推荐使用的API,您将遇到一个确定的问题和一个潜在的问题
明确的问题是OpenGL无法利用现代GPU中的许多硬件加速功能,因为不是将所有三角形(即顶点)和材质(例如纹理)存储在GPU内存中,每次渲染时,它可能至少需要将其中的一部分从主内存复制到GPU内存。通过使用顶点缓冲区以及顶点着色器和片段着色器,您可以轻松避免这一不小的开销
如果您搜索它们,那么会有很多示例,因此虽然重构代码可能需要一些时间,但知道如何进行并不成问题
潜在的问题是,固定功能管道已经被弃用了一段时间(并且非正式地被劝阻了更长时间),因此许多驱动程序可能包含该功能更多是为了与旧游戏和应用程序兼容,而不是作为优化的活动目标。换句话说,开发人员的时间花在优化现代API上,而不是20世纪90年代末的API上
以这样的方式编写代码可能不是你的错。不幸的是,网络和免费提供的旧书副本提供了许多基于旧的固定功能管道而非现代可编程管道的示例。结合(最初)固定功能管道通常更容易理解和使用的事实,它会导致类似您所处的情况。但是花时间学习现代API是值得的。它为您提供了大量的机会,使您的图形即使在“低端”系统上也能大放异彩。因此,现在您正在以新的方式做事,但您并没有充分利用您所能利用的一切。每次渲染时都会上载几何体。因为它没有变化(您使用的是
GL\u STATIC\u DRAW
),所以不要多次上传它。一旦它出现在视频内存中,它就会一直存在,直到你删除它。你的着色器的制服也一样。您只需要清除颜色、绑定各种数组和属性、绘制数组,然后解除绑定各种数组和属性。可能是同花顺。glBufferData()
调用可能花费了这么长时间
另外,我不得不说,10%的CPU使用率不算什么。我不知道你为什么会担心。事实上,各种新的渲染器(Metal、Vulkan、DX12)对于减少渲染的CPU组件基本上是有用的。如果只有1