Подтвердить что ты не робот

Окно OpenGL GLUT очень медленно, почему?

Проблема

Я только что начал работать с OpenGL, используя GLUT. Приведенный ниже код компилирует и отображает два каркасных куба и сферу. Проблема заключается в том, что при попытке перетащить или изменить размер окна он вызывает заметную задержку перед тем, как следовать за моей мышью.

Эта проблема не возникает на моем компьютере коллеги, том же коде.

Я работаю с Visual Studio 2012 С++ express на компьютере под управлением Windows 7. Я не опытный программист.

Код

    // OpenGLHandin1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <GL/glut.h>

void initView(int argc, char * argv[]){
    //init here
    glutInit(&argc, argv);
    //Simple buffer
    glutInitDisplayMode( GLUT_SINGLE | GLUT_RGBA );
    glutInitWindowPosition(100,100);
    glutInitWindowSize(800,400);
    glutCreateWindow("Handin 2");
}
void draw(){

    glClearColor(0,0,0,1);
    glClear(GL_COLOR_BUFFER_BIT);
    //Background color

    glPushMatrix();
    glLoadIdentity();
    glTranslatef(0.6, 0, 0);

    glColor3f(0.8,0,0);
    glutWireCube(1.1); //Draw the cube
    glPopMatrix();

    glPushMatrix();
    glLoadIdentity();
    glTranslatef(-0.5, 0, -0.2);

    glColor3f(0,0.8,0);
    glutWireCube(1.1); //Draw the cube
    glPopMatrix();

    glPushMatrix();
    glLoadIdentity();
    glTranslatef(0, 1.2, 0);
    glRotatef(90, 1, 0, 0);

    glColor3f(1,1,1);
    glutWireSphere(0.6, 20, 20); //Draw the sphere
    glPopMatrix();

    //draw here
    //glutSwapBuffers();
    glutPostRedisplay();
    glFlush();

}
void reshape (int w, int h){
    glViewport(0,0,w ,h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45, (float)w/(float)h, 1.5, 10);
    gluLookAt(1.5, 2.5, 4, 
              0, 0.6, 0, 
              0, 1, 0); //Orient the camera
    glRotatef(5, 0, 0, 1);
    glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char * argv[])
{
    initView(argc,argv);
    glutDisplayFunc(draw);
    glutReshapeFunc(reshape);
    glutMainLoop();
}
4b9b3361

Ответ 1

Решение:

Кажется, что сработало простое решение с использованием Sleep(1) в функции рендеринга. Вы также спросили, почему - я не уверен, что смогу это решить правильно, но здесь мое лучшее предположение:

Почему это работает?

Ваши сокурсники могут включить VSync по умолчанию в своих драйверах. Это приводит к тому, что их код работает только так быстро, как может обновиться экран, скорее всего, 60 кадров в секунду. Это дает вам около 16 миллисекунд для рендеринга кадра, и если код эффективен (например, 2 мс для рендеринга), он оставляет много времени для того, чтобы процессор мог выполнять другие связанные с ОС вещи, такие как перемещение вашего окна.

Теперь, если вы отключите вертикальную синхронизацию, программа попытается отобразить как можно больше кадров, эффективно забивая все остальные процессы. Я предложил вам использовать Сон, потому что он раскрывает эту конкретную проблему. Это не имеет значения, если это 1 или 3 мс, что он действительно делает, это сказать "эй, процессор, я сейчас ничего не делаю, поэтому ты можешь делать другие вещи".

Но разве это не замедляет мою программу?

Использование сна - обычная техника. Если вы обеспокоены тем, что потеряли 1 мс каждый кадр, вы также можете попробовать поставить Sleep(0), так как он должен действовать точно так же, предоставляя свободное время CPU. Вы также можете попробовать включить вертикальную синхронизацию и проверить, действительно ли моя догадка была правильной.

В качестве дополнительной заметки вы также можете посмотреть графики использования процессора с и без сна. Он должен быть на 100% (или 50% на двухъядерном процессоре) без (работает как можно быстрее) и намного ниже, в зависимости от ваших программных требований и скорости вашего процессора.

Дополнительные замечания о Sleep (0)

После того, как интервал ожидания прошел, поток готов к запуску. Если вы укажете 0 миллисекунд, поток отменит оставшуюся часть своего временного фрагмента, но останется готовым. Обратите внимание, что готовый поток не гарантирует немедленного запуска. Следовательно, поток может не работать до некоторого времени после истечения интервала ожидания. - это от здесь.

Также обратите внимание, что поведение систем Linux может несколько отличаться; но я не специалист по Linux; возможно, прохожий может прояснить.