-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmainwindow.c
189 lines (169 loc) · 3.89 KB
/
mainwindow.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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/*
* mainwindow.c
*
* Created on: Mar 8, 2013
* Author: mathijs
*/
#include <curses.h>
#include <math.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include "helper.h"
#include "mainwindow.h"
#include "particle.h"
#include "threading.h"
const int WIN_WIDTH_I = 1024;
const int WIN_HEIGHT_I = 768;
const float WIN_WIDTH_F = 1024.0f;
const float WIN_HEIGHT_F = 768.0f;
static int init(int argc, char **argv);
static void init_callbacks(void);
static void render_scene_cb(void);
static void keyboard(unsigned char key, int x, int y);
static struct Particle *particles;
static int win_num = -1;
enum STATES state = PAUSED;
#if TRACE
enum TRACES traces = TRACES_ON;
#endif
enum INFO info = INFO_ON;
#if DEBUG_TIMING
enum DEBUG debug = DEBUG_ON;
#endif
void mainwindow(int argc, char **argv)
{
int init_result = init(argc, argv);
if (init_result != 0)
{
fprintf(stderr, "Init was unsuccessful. Quitting '\n");
}
glutMainLoop();
stop_thread_pool();
}
static int init(int argc, char **argv)
{
GLenum res;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(WIN_WIDTH_I, WIN_HEIGHT_I);
glutInitWindowPosition(100, 100);
win_num = glutCreateWindow("Tutorial 01");
init_callbacks();
// Must be done after glut is initialized!
res = glewInit();
if (res != GLEW_OK)
{
fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res));
return -1;
}
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, WIN_WIDTH_F, WIN_HEIGHT_F, 0.0f, 0.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glDisable(GL_DEPTH_TEST);
particles = particle();
start_thread_pool();
return 0;
}
static void animate()
{
#if MUTEX_COND
pthread_mutex_lock(&(paint_mutex));
pthread_cond_signal(&(render_cond));
pthread_cond_wait(&(paint_cond), &(paint_mutex));
#endif
glutPostRedisplay();
#if MUTEX_COND
pthread_mutex_unlock(&(paint_mutex));
#endif
}
static void init_callbacks()
{
glutDisplayFunc(render_scene_cb);
glutKeyboardFunc(keyboard);
glutIdleFunc(animate);
}
static void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case '\e': /* ESC */
{
state = STOPPED;
glutIdleFunc(NULL);
glutDestroyWindow(win_num);
}
break;
case ' ':
{
if (state == RUNNING)
{
state = PAUSED;
}
else
{
state = RUNNING;
}
}
break;
#if TRACE
case 't':
{
traces = (traces == TRACES_OFF ? TRACES_ON : TRACES_OFF);
}
break;
#endif
case 'i':
{
info = (info == INFO_OFF ? INFO_ON : INFO_OFF);
}
break;
#if DEBUG_TIMING
case 'd':
{
debug = (debug == DEBUG_OFF ? DEBUG_ON : DEBUG_OFF);
}
break;
#endif
default:
{
}
break;
}
}
static void render_scene_cb()
{
#if DEBUG_TIMING
double secs_set = 0.0f;
struct timespec in, out;
int64_t duration = 0;
clock_gettime(CLOCK_MONOTONIC, &in);
#endif
glClear(GL_COLOR_BUFFER_BIT);
for (int i = 0; i < NUM_PARTICLES; i++)
{
particle_draw(&(particles[i]));
#if TRACE
if (traces == TRACES_ON)
{
particle_draw_trace(&(particles[i]));
}
#endif
}
glutSwapBuffers();
#if DEBUG_TIMING
clock_gettime(CLOCK_MONOTONIC, &out);
duration = timespec_diff_ns(&in, &out);
secs_set = (double) duration / 1000.0f / 1000.0f / 1000.0f;
if (debug == DEBUG_ON)
{
printf("render_scene_cb in %f secs (%f Hz) \n", secs_set, 1.0f / secs_set);
}
#endif
}