Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

OpenGL, Поток с таймером для анимации.

64K
15 февраля 2011 года
napalm256
13 / / 15.02.2011
Знаю делфи и си , захотелось игру сварганить - змейку:) , начал учить OpenGL, ну и тут как полагается траблы. Пишу в Висуал Студио 2008 експрес.

В чём проблема:
Надо сделать ежесекундное обновление картинки, функция Draw() работает 100% - ставил cuot внутрь для проверки, но картинка не обновляется.
Картинка обновляется если Draw запихнуть в keyPress() событие или же когда я изменяю размер окна (срабатывает glutDisplayFunc) .

Помогите советом я зашел в тупик =(
Код:
DWORD dwThreadId=1;

DWORD WINAPI Timer(LPVOID lpCOM) //  Thread Timer
{
    while(tim)
    {
        Sleep(1000);
        Draw();      // функция отрисовки
    }
    return 0;
}

int main()
{
    printf("Press SPACE to start\n");
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(400, 400);
    glutInitWindowPosition(200, 200);
    glutCreateWindow("Snake");
    glutKeyboardFunc(keyPress);
    Initialize();
    glutDisplayFunc(Draw);
    glutMainLoop();

    return 0;
}
7
15 февраля 2011 года
@pixo $oft
3.4K / / 20.09.2006
Что за функция Draw()?Может статься,что надо вызвать функцию перерисовки.Либо самого OpenGL,либоWindows(для окна)
278
15 февраля 2011 года
Alexander92
1.1K / / 04.08.2008
Присоединяюсь к @pixo $oft плюс еще одно замечание: если хотите сделать таймер, это лучше делать не через CreateThread(), а через SetTimer(). А функцию Draw() напишите все-таки.
64K
16 февраля 2011 года
napalm256
13 / / 15.02.2011
сделал через glutIdeFunc анимация есть, пришлось усыплять Draw() Sleep()'ом чтобы не хавал много
но всё же хочу по людски
Треды я использовал потому что у меня консольное преложение и мне так легче будет его перенести на линукс
а Drow() отрисовует сцену, рисует змейку и ни в чём не виноват :)
Код:
void Draw()
{
glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(0.6, 0.6, 0.9);
    glBegin(GL_LINES);
    for(unsigned char i=1;i<=20;i++)
    {
        glVertex3f(0.05*i, 1.0, 0.0);
        glVertex3f(0.05*i, 0.0, 0.0);
        glVertex3f(0.0, 0.05*i, 0.0);
        glVertex3f(1.0, 0.05*i, 0.0);
    };
    glEnd();
...
 тоже самое только со змейкой
...
}

как заставить glut или окно(лучше глут) перерисовывать сцену через таймер, а не через события
277
16 февраля 2011 года
arrjj
1.7K / / 26.01.2011
Раз хочеш перенести потом и на линукс то почемубы не использовать Qt? В нём это просто делается: по QTimer'у вызывается updateGL и всё. Есть в Qt и готовые примеры по опенгл.
64K
16 февраля 2011 года
napalm256
13 / / 15.02.2011
Qt по дефолту использует qtшные либы, и все вмести они занимают 4мб, а для змейки это жирно. Нас когда учили то всегда делали акцент на производительности, если её не соблюдать то войдёт в привычку писать как попало. Qt использую на крайняк: если надо сделать форму, но так и толком не розобрался в нём... сигналы и слоты и т п..
Придерживаюсь теории: сперва чтобы начинать что то учить новое - надо хорошо знать старое...
Спасибо всем за помощь - разобрался сам. Игру написал работает на ура)) использовал только С++ и опенГЛ... скомпилировал в VS .NET вес ехе 46кб + glut dll 86кб.
360
16 февраля 2011 года
P*t*
474 / / 15.02.2007
Если уж используешь glut, то вместо вот этого:
 
Код:
while(tim)
{
Sleep(1000);
Draw(); // функция отрисовки
}


Надо бы писать так:
 
Код:
while(tim)
{
Sleep(1000);
glutPostRedisplay(); /* glut скажет операционной системе, что окно хочет
перерисоваться, затем ОС дождется удобного момента
 и вызовет Draw (т.к Draw указывалось в параметре glutDisplayFunc() ). */
}


А еще лучше так:
Код:
void timerF() { // сработал таймер glut
   glutTimerFunc(30, timerF, 0); // переустановить таймер
   glutPostRedisplay(); // перерисовать
}

int main() {
...
   glutDisplayFunc(Draw);
   glutTimerFunc(30, timerF, 0); // включить таймер на 30мс
   glutMainLoop();
}
64K
16 февраля 2011 года
napalm256
13 / / 15.02.2011
хм..,P*t* , спасибо, а вот это уже интересно.
У меня возник новый вопрос :
змейку сделал динамическим списком и просто переставляю с конца на перёд.
но вот с фруктом проблема: иногда может подвисать когда rand_apple() кинет фрукт на змею, просто идет многочленный перебор змеи как бы это исправить
Код:
typedef struct lst //динам змейка
{
 char x;
 char y;
 lst *next;
} snake;

bool check_apple() //проверка
{
    snake *temp = p1;
    while(temp!=NULL)
        {
            if((temp->x==apple_x) && (temp->y==apple_y)) return 0;
            temp = temp->next;
        };
    return 1;
}

void rand_apple()
{
    do {
        srand(time(0));
        apple_x = rand() % 19;
        apple_y = rand() % 19;
    } while(!check_apple()); //проверка, не на змее яблоко ...
}
297
16 февраля 2011 года
koodeer
1.2K / / 02.05.2009
Уберите srand(time(0)); из цикла. Достаточно делать инициализацию ГСЧ один раз, в начале программы.
Когда это делается в цикле, то при попадании яблока на змею новое значение выдастся лишь по истечении секунды - вот и зависание.
360
16 февраля 2011 года
P*t*
474 / / 15.02.2007
Вариант 1: Хранить двумерный массив, где для каждой клетки поля записано, есть там змейка или нет. При перемещении змейки из конца в начало нужно будет поменять два элемента этого массива.
Минус здесь только в том, что если на поле останется последняя свободная от змейки клетка, то случайный перебор может работать долго. ;)

Вариант 2 (извращенный): помимо змейки таким же способом хранить свободные клетки и, если свободных осталось мало, случайным образом определять не координаты, а номер в последовательности свободных.

P.S srand нужно писать только один раз в начале программы. Иначе, если rand_apple() вызвать дважды в секунду, time() выдаст одно и то же время, srand задаст одну и ту же последовательность случайных чисел и "случайные" координаты в обоих случаях будут одинаковы. ( ну вот, koodeer меня опередил :( )
64K
16 февраля 2011 года
napalm256
13 / / 15.02.2011
Оуу... блин точно :)
P*t* (2) Идея хорошая спс...
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог