我在Linux上用X11学习OpenGL,遇到了一个我没有意识到出错的问题。
当我绘制一个覆盖屏幕上大空间的对象时,它会快速渲染并以高帧速率更新到X11。但是当我将相机远离物体移动或绘制一个小物体时,它会覆盖屏幕上的小空间(比如像素区域),它的更新速度非常慢。它绘制的越小,它就会更慢地更新帧。
当我距离1x1飞机100个单位时,它达到每秒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);
}
编辑: 我正在添加一些代码来帮助。 这个是我用来创建窗口的Init函数:
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);
}
这个我用来创建一个事件循环:
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);
}
};
好吧,正如我所看到的,这看起来不是性能问题,而是更新队列(或类似的东西)问题。当对象靠近相机时,例如,它使用大屏幕空间,它绘制得更快,但是当它在屏幕空间中变小时,它线性地减慢了屏幕更新。我正在打印曝光,按键和键盘释放的事件,所有这些事件都快速运行,就像它应该的那样,只有屏幕区域更新不符合系统的速度。
答案 0 :(得分:0)
哦,我发现了错误,我为此提出了自己的问题。我很惭愧地说这个,因为它真的像图形中的新手一样愚蠢:/
问题是我在低ppi显示器上使用小屏幕。此外,屏幕上的形状是一个完美的正方形(它不会在像素上绘制对角线边缘),因此当对象很小时,重绘边框像素需要很长时间。计算机图形使用一些抗锯齿效果来平滑这种效果,并且原始的opengl不会,因此它会产生与我以前看到的完全不同的效果。我花了很长时间才意识到这只是一个像素细节问题...
谢谢大家的帮助。
答案 1 :(得分:-2)
这里的一些东西看起来并不像它的“优化”正确。例如,您使用gluPerspective。这个已被弃用了10年!!我们不希望这样!为什么不在相机类中制作自己的viewmatrix? :)
另外,我不确定这是不是问题。但似乎你在RENDER循环中调用了glClearColor。这当然不好。把它放在你的init函数中。这可能是它的问题。