Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/5: Рейтинг темы: голосов - 5, средняя оценка - 5.00
Devilox
3 / 3 / 2
Регистрация: 19.02.2014
Сообщений: 142
1

Максимально частое обновление экрана

14.04.2016, 03:50. Просмотров 892. Ответов 4
Метки нет (Все метки)

Вечер добрый!
Появилась необходимость использовать SDL2 и OpenGL под Виндой. Я настроил MinGW - всё нормально работает. Взял первый попавшийся исходник: прога запускается, но почему-то очень быстро обновляется экран. На Ubuntu по умолчанию 50 FPS, а тут максимум - ноут аж шуметь начинает. Как это можно исправить?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <SDL2/SDL.h> 
#include <GL/gl.h>
#include <GL/glu.h> 
#include <iostream>
 
SDL_Window *window;
 
const int width = 640;
const int height = 480;
 
void drawCube(float xrf, float yrf, float zrf);
void set_vsync(bool enabled);
 
 
int init() {
    if ( SDL_Init(SDL_INIT_VIDEO) < 0 ){ 
        std :: cout << "Unable to init SDL, error: " << SDL_GetError() << std :: endl;
        return 1;
    } 
     
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
 
    window = SDL_CreateWindow("Cube", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
     
    SDL_GLContext glcontext = SDL_GL_CreateContext(window);
     
    if(window == NULL) {
        return 1;
    }
 
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClearDepth(1.0);
    glDepthFunc(GL_LESS);
    glEnable(GL_DEPTH_TEST);
    glShadeModel(GL_SMOOTH);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0f, (float) width / (float) height, 0.1f, 100.0f);
    glMatrixMode(GL_MODELVIEW);
    
    return 0;
}
 
void drawCube(float xrf, float yrf, float zrf){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     
    glLoadIdentity();
    glTranslatef(0.0f, 0.0f, -7.0f);
     
    glRotatef(xrf, 1.0f, 0.0f, 0.0f);
    glRotatef(yrf, 0.0f, 1.0f, 0.0f);
    glRotatef(zrf, 0.0f, 0.0f, 1.0f);
     
    glBegin(GL_QUADS);
 
    glColor3f(0.0f, 1.0f, 0.0f);
    glVertex3f( 1.0f, 1.0f, -1.0f);
    glVertex3f(-1.0f, 1.0f, -1.0f);
    glVertex3f(-1.0f, 1.0f,  1.0f);
    glVertex3f( 1.0f, 1.0f,  1.0f);
     
    glColor3f(1.0f, 0.5f, 0.0f);      
    glVertex3f( 1.0f, -1.0f,  1.0f);  
    glVertex3f(-1.0f, -1.0f,  1.0f); 
    glVertex3f(-1.0f, -1.0f, -1.0f);  
    glVertex3f( 1.0f, -1.0f, -1.0f);  
     
    glColor3f(1.0f, 0.0f, 0.0f);      
    glVertex3f( 1.0f,  1.0f, 1.0f);  
    glVertex3f(-1.0f,  1.0f, 1.0f);  
    glVertex3f(-1.0f, -1.0f, 1.0f); 
    glVertex3f( 1.0f, -1.0f, 1.0f);   
 
    glColor3f(1.0f,1.0f,0.0f);      
    glVertex3f( 1.0f, -1.0f, -1.0f);  
    glVertex3f(-1.0f, -1.0f, -1.0f); 
    glVertex3f(-1.0f,  1.0f, -1.0f);  
    glVertex3f( 1.0f,  1.0f, -1.0f); 
 
    glColor3f(0.0f,0.0f,1.0f);       
    glVertex3f(-1.0f,  1.0f,  1.0f);
    glVertex3f(-1.0f,  1.0f, -1.0f); 
    glVertex3f(-1.0f, -1.0f, -1.0f); 
    glVertex3f(-1.0f, -1.0f,  1.0f);  
     
    glColor3f(1.0f,0.0f,1.0f);      
    glVertex3f( 1.0f,  1.0f, -1.0f);
    glVertex3f( 1.0f,  1.0f,  1.0f);
    glVertex3f( 1.0f, -1.0f,  1.0f);
    glVertex3f( 1.0f, -1.0f, -1.0f);
 
    glEnd(); 
 
}
 
int main(int argc, char *argv[]){
 
    init();
 
    bool running = true;
 
    float xrf = 0, yrf = 0, zrf = 0;
 
    while(running){ 
       
        SDL_Event event;
       
        while ( SDL_PollEvent(&event) ) {
            switch(event.type) {
                case SDL_QUIT:
                    running = false;
                break;
 
                case SDL_KEYDOWN:
                    switch(event.key.keysym.sym){
                        case SDLK_ESCAPE:
                            running = false;
                        break;
                    }
                break;
            } 
        }
 
        xrf -= 0.1; 
        yrf -= 0.1;
        zrf -= 0.1;
 
        drawCube(xrf, yrf, zrf);
 
        glFlush();
        SDL_GL_SwapWindow(window);
    }
 
    SDL_Quit();
    return 0;
}
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.04.2016, 03:50
Ответы с готовыми решениями:

Найти сумму максимально отрицательного и максимально положительного элемента массива
Ребята, помогите, плиз)) найти суму максимально отрицательного и максимально...

Наиболее частое число в массиве
Задан Массив m из Чисел. Найти число,наиболее часто встречающееся в этом...

Частое использование dynamic_cast в конкретных целях. Правильно ли?
Привет, форум. Гуманно ли использовать dynamic_cast вот в таких случаях?...

Частое от деления любого из первых 10 чисел Фибоначчи на предшествующее стремится к золотому сечению
Посчитать первые 10 чисел Фибоначчи и показать что частое от деления любого...

Написать игру. В верхней части экрана летят 3 «звездочки»(***). В нижнем правом углу экрана находиться буква «О»
Написать игру. В верхней части экрана летят 3 «звездочки»(***). В нижнем правом...

4
Renji
2124 / 1562 / 476
Регистрация: 05.06.2014
Сообщений: 4,544
14.04.2016, 06:05 2
Цитата Сообщение от Devilox Посмотреть сообщение
На Ubuntu по умолчанию 50 FPS, а тут максимум - ноут аж шуметь начинает. Как это можно исправить?
Он будет шуметь даже если вы вообще ничего рисовать не будете. SDL_PollEvent, судя по документации, немедленно возвращает управление, даже если никаких событий в очереди нет. Соответственно, цикл while ( SDL_PollEvent(&event) ) у вас будет крутиться без передышки, нагружая процессор на 100%. От этого он разогреется как печка и куллер врубится на полную мощность.

Не вникал в работу SDL, но уверен что поможет поменять SDL_PollEvent на SDL_WaitEvent и повесить перерисовку на таймер.
0
Devilox
3 / 3 / 2
Регистрация: 19.02.2014
Сообщений: 142
14.04.2016, 23:34  [ТС] 3
Renji, SDL_WaitEvent скорость обновления даёт нормальную, но только если присутствует какое-либо событие, мне же нужно постоянное обновление (SDL_PushEvent всё возвращает к исходной проблеме). Таймер тоже не помогает (всё становится дёрганым, и притом нет разницы, какой, например, я поставлю угол вращения объекта - скорость одна и та же)
0
Renji
2124 / 1562 / 476
Регистрация: 05.06.2014
Сообщений: 4,544
15.04.2016, 01:14 4
Лучший ответ Сообщение было отмечено Devilox как решение

Решение

Цитата Сообщение от Devilox Посмотреть сообщение
Renji, SDL_WaitEvent скорость обновления даёт нормальную, но только если присутствует какое-либо событие, мне же нужно постоянное обновление (SDL_PushEvent всё возвращает к исходной проблеме).
Так в таймере событие и генерировать. N раз в секунду и ни событием больше. А в промежутках процессор будет отдыхать, чтоб не слишком нагружать куллер.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
Uint32 my_callbackfunc(Uint32 interval, void *param)
{
    SDL_Event event;
    SDL_UserEvent userevent;
 
    /* In this example, our callback pushes an SDL_USEREVENT event
    into the queue, and causes our callback to be called again at the
    same interval: */
 
    userevent.type = SDL_USEREVENT;
    userevent.code = 0;
    userevent.data1 = NULL;
    userevent.data2 = NULL;
 
    event.type = SDL_USEREVENT;
    event.user = userevent;
 
    SDL_PushEvent(&event);
    return(interval);
}
 
//...
 
int main(int argc, char *argv[]){
 
    init();
    SDL_AddTimer(100, my_callbackfunc, 0);
    bool running = true;
 
 
    SDL_Event event;
    float xrf = 0, yrf = 0, zrf = 0;
 
    while ( SDL_WaitEvent(&event) && running)
    {
        switch(event.type) {
        case SDL_USEREVENT:
        {
            xrf -= 0.1;
            yrf -= 0.1;
            zrf -= 0.1;
 
            drawCube(xrf, yrf, zrf);
 
            glFlush();
            SDL_GL_SwapWindow(window);
        }
            break;
        case SDL_QUIT:
            running = false;
            break;
 
        case SDL_KEYDOWN:
            switch(event.key.keysym.sym){
                case SDLK_ESCAPE:
                    running = false;
                break;
            }
            break;
        }
    }
 
    SDL_Quit();
    return 0;
}
1
Devilox
3 / 3 / 2
Регистрация: 19.02.2014
Сообщений: 142
15.04.2016, 14:10  [ТС] 5
Спасибо, работает!
0
15.04.2016, 14:10
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.04.2016, 14:10

WinForms: частое обновление картинки
Немного глуповатый вопрос, но все же сам видимо не решу, или решу нескоро. ...

слишком частое обновление холста
было необходимо нарисовать некоторые детали на холсте канвы с помощью ...

максимально использовать площадь экрана
Добрая ночь, прошу Вас помочь , намекнуть, объяснить фразу. Что означает...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru