当对象在屏幕空间中很小时,OpenGL会缓慢更新

时间:2017-06-10 22:08:06

标签: c++ opengl game-engine x11 slowdown

我在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);
    }
};

好吧,正如我所看到的,这看起来不是性能问题,而是更新队列(或类似的东西)问题。当对象靠近相机时,例如,它使用大屏幕空间,它绘制得更快,但是当它在屏幕空间中变小时,它线性地减慢了屏幕更新。我正在打印曝光,按键和键盘释放的事件,所有这些事件都快速运行,就像它应该的那样,只有屏幕区域更新不符合系统的速度。

2 个答案:

答案 0 :(得分:0)

哦,我发现了错误,我为此提出了自己的问题。我很惭愧地说这个,因为它真的像图形中的新手一样愚蠢:/

问题是我在低ppi显示器上使用小屏幕。此外,屏幕上的形状是一个完美的正方形(它不会在像素上绘制对角线边缘),因此当对象很小时,重绘边框像素需要很长时间。计算机图形使用一些抗锯齿效果来平滑这种效果,并且原始的opengl不会,因此它会产生与我以前看到的完全不同的效果。我花了很长时间才意识到这只是一个像素细节问题...

谢谢大家的帮助。

答案 1 :(得分:-2)

这里的一些东西看起来并不像它的“优化”正确。例如,您使用gluPerspective。这个已被弃用了10年!!我们不希望这样!为什么不在相机类中制作自己的viewmatrix? :)

另外,我不确定这是不是问题。但似乎你在RENDER循环中调用了glClearColor。这当然不好。把它放在你的init函数中。这可能是它的问题。