J'apprends OpenGL avec X11 sous Linux, et j'ai un problème que je ne réalise pas ce qui ne va pas.Mises à jour lentes OpenGL lorsque les objets sont petits dans l'espace écran
Lorsque je dessine un objet qui couvre un grand espace sur l'écran, il rend rapidement et met à jour X11 avec un taux de framerate élevé. Mais quand je déplace la caméra loin de l'objet, ou dessine un petit objet, de manière à ce qu'il couvre un petit espace sur l'écran (disons, en pixels), les mises à jour sont vraiment lentes. Comme il dessine petit, plus lent il met à jour le cadre.
Lorsque je suis à 100 unités loin d'un plan 1x1, il atteint environ 1 image par seconde.
Voici le code:
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();
et la fonction SetupViewMatrix:
void WindowDrawer::SetupViewMatrix(){
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(65, (float)Width/Height, 0.1, 1000);
};
et la fonction ClearScreen:
void WindowDrawer::ClearScreen(){
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
EDIT: J'ajoute un peu plus de code aider. Celui-ci est la fonction Init j'utilise pour créer une fenêtre:
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);
}
Et celui-ci j'utilise pour créer une boucle d'événement:
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);
}
};
Eh bien, comme je peux voir, Ce problème n'est pas un problème de performance, mais une mise à jour de la file d'attente (ou quelque chose comme). Parce que lorsque l'objet est proche de la caméra, disons, il utilise un grand écran, il dessine plus rapidement comme il le devrait, mais quand il devient plus petit dans l'espace écran, il ralentit linéairement les mises à jour de l'écran. J'imprime les événements pour exposer, keypress et keyrelease, tous ces événements s'exécutent rapidement, comme il se doit, seules les mises à jour de la zone d'écran ne suivent pas la vitesse du système.
Quelle version d'OpenGL ciblez-vous? Pour OpenGL moderne, 'glEnableClientState' a été supprimé dans OpenGL 4.5., Et le rendu sans shader n'est pas non plus supporté. –
Je suis sûr que ce n'est pas le problème dans la question. –
Comment mesurez-vous la fréquence d'images?(J'espère que non seulement en le regardant, les petits objets ne changent souvent pas) Comment générez-vous l'événement X Expose pour forcer un redessin, XClear après chaque image, un minuteur? Avez-vous activé la compression d'événement? –