-
Notifications
You must be signed in to change notification settings - Fork 0
/
lesson2.c
330 lines (257 loc) · 7.35 KB
/
lesson2.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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <directfb.h>
#include <directfbgl.h>
#include <GLES/gl.h>
// the super interface
IDirectFB *dfb;
// the primary surface (surface of primary layer)
IDirectFBSurface *primary;
// the GL context
IDirectFBGL *primary_gl;
// our font
IDirectFBFont *font;
// event buffer
IDirectFBEventBuffer *events;
// macro for a safe call to DirectFB functions
#define DFBCHECK(x...) \
{ \
err = x; \
if (err != DFB_OK) { \
fprintf(stderr, "%s <%d>:\n\t", __FILE__, __LINE__); \
DirectFBErrorFatal(#x, err); \
} \
}
static int screen_width, screen_height;
static unsigned long T0 = 0;
static GLint Frames = 0;
static GLfloat fps = 0;
static inline unsigned long get_millis()
{
struct timeval tv;
gettimeofday (&tv, NULL);
return (tv.tv_sec * 1000 + tv.tv_usec / 1000);
}
static GLfloat view_x = 0.0, view_y = 0.0, view_z = 0.0;
static GLfloat inc_x = 0.0, inc_y = 0.0, inc_z = 0.0;
static void draw(void)
{
GLfloat vertices[4][3];
// Clear The Screen And The Depth Buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Enable VERTEX array
glEnableClientState(GL_VERTEX_ARRAY);
// Setup pointer to VERTEX array
glVertexPointer(3, GL_FLOAT, 0, vertices);
// Move Left 1.5 Units And Into The Screen 6.0
glLoadIdentity();
glTranslatef((view_x - 1.5f), (view_y + 0.0f), (view_z - 1.0f));
// Top Of Triangle
vertices[0][0] = 0.0f; vertices[0][1] = 1.0f; vertices[0][2] = 0.0f;
// Left Of Triangle
vertices[1][0] = -1.0f; vertices[1][1] = -1.0f; vertices[1][2] = 0.0f;
// Right Of Triangle
vertices[2][0] = 1.0f; vertices[2][1] = -1.0f; vertices[2][2] = 0.0f;
// Drawing Using Triangles, draw triangles using 3 vertices
glDrawArrays(GL_TRIANGLES, 0, 3);
// Move Right 3 Units
glLoadIdentity();
glTranslatef((view_x + 1.5f), (view_y + 0.0f), (view_z - 1.0f));
// Top Right Of The Quad
vertices[0][0] = 1.0f; vertices[0][1] = 1.0f; vertices[0][2] = 0.0f;
// Top Left Of The Quad
vertices[1][0] = -1.0f; vertices[1][1] = 1.0f; vertices[1][2] = 0.0f;
// Bottom Left Of The Quad
vertices[2][0] = 1.0f; vertices[2][1] = -1.0f; vertices[2][2] = 0.0f;
// Bottom Right Of The Quad
vertices[3][0] = -1.0f; vertices[3][1] = -1.0f; vertices[3][2] = 0.0f;
// Drawing using triangle strips, draw triangles using 4 vertices
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// Disable vertex array
glDisableClientState(GL_VERTEX_ARRAY);
// Flush all drawings
glFinish();
}
static void reshape(int width, int height)
{
// Height / width ration
GLfloat ratio;
// Protect against a divide by zero
if (width == 0)
width = 1;
ratio = (GLfloat)height / (GLfloat)width;
// Setup our viewport.
glViewport(0, 0, (GLsizei)width, (GLsizei)height);
// change to the projection matrix and set our viewing volume.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Set our perspective
glFrustumf(-1.0, 1.0, -ratio, ratio, 0.1, 100.0);
// Make sure we're chaning the model view and not the projection
glMatrixMode(GL_MODELVIEW);
// Reset The View
glLoadIdentity();
}
static void init(int argc, char *argv[])
{
// Enable smooth shading
glShadeModel(GL_SMOOTH);
// Set the background black
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
// Depth buffer setup
glClearDepthf(1.0f);
// Enables Depth Testing
glEnable(GL_DEPTH_TEST);
// The Type Of Depth Test To Do
glDepthFunc(GL_LEQUAL);
// Really Nice Perspective Calculations
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}
int main(int argc, char *argv[])
{
int quit = 0;
DFBResult err;
DFBSurfaceDescription dsc;
DFBCHECK(DirectFBInit(&argc, &argv));
// create the super interface
DFBCHECK(DirectFBCreate(&dfb));
// create an event buffer for all devices with these caps
DFBCHECK(dfb->CreateInputEventBuffer(dfb, DICAPS_KEYS | DICAPS_AXES, DFB_FALSE, &events));
// set our cooperative level to DFSCL_FULLSCREEN for exclusive access to the primary layer
dfb->SetCooperativeLevel(dfb, DFSCL_FULLSCREEN);
// get the primary surface, i.e. the surface of the primary layer we have exclusive access to
dsc.flags = DSDESC_CAPS;
dsc.caps = DSCAPS_PRIMARY | DSCAPS_DOUBLE | DSCAPS_OPENGL_HINT;
DFBCHECK(dfb->CreateSurface(dfb, &dsc, &primary));
// get the size of the surface and fill it
DFBCHECK(primary->GetSize(primary, &screen_width, &screen_height));
DFBCHECK(primary->FillRectangle(primary, 0, 0, screen_width, screen_height));
primary->Flip(primary, NULL, 0);
// create the default font and set it
DFBCHECK(dfb->CreateFont(dfb, NULL, NULL, &font));
DFBCHECK(primary->SetFont(primary, font));
// get the GL context
DFBCHECK(primary->GetGL(primary, &primary_gl));
DFBCHECK(primary_gl->Lock(primary_gl));
init(argc, argv);
reshape(screen_width, screen_height);
DFBCHECK(primary_gl->Unlock(primary_gl));
T0 = get_millis();
while (!quit)
{
DFBInputEvent evt;
unsigned long t;
DFBCHECK(primary_gl->Lock(primary_gl));
draw();
DFBCHECK(primary_gl->Unlock(primary_gl));
if (fps)
{
char buf[64];
snprintf(buf, 64, "%4.1f FPS\n", fps);
primary->SetColor(primary, 0xff, 0, 0, 0xff);
primary->DrawString(primary, buf, -1, screen_width - 5, 5, DSTF_TOPRIGHT);
}
primary->Flip(primary, NULL, 0);
Frames++;
t = get_millis();
if (t - T0 >= 2000)
{
GLfloat seconds = (t - T0) / 1000.0;
fps = Frames / seconds;
T0 = t;
Frames = 0;
}
while (events->GetEvent(events, DFB_EVENT(&evt)) == DFB_OK)
{
switch (evt.type)
{
case DIET_KEYPRESS:
switch (evt.key_symbol)
{
case DIKS_ESCAPE:
quit = 1;
break;
case DIKS_CURSOR_UP:
inc_y = 0.1;
break;
case DIKS_CURSOR_DOWN:
inc_y = -0.1;
break;
case DIKS_CURSOR_LEFT:
inc_x = -0.1;
break;
case DIKS_CURSOR_RIGHT:
inc_x = 0.1;
break;
case DIKS_PAGE_UP:
inc_z = 0.01;
break;
case DIKS_PAGE_DOWN:
inc_z = -0.01;
break;
default:
;
}
break;
case DIET_KEYRELEASE:
switch (evt.key_symbol)
{
case DIKS_CURSOR_UP:
inc_y = 0;
break;
case DIKS_CURSOR_DOWN:
inc_y = 0;
break;
case DIKS_CURSOR_LEFT:
inc_x = 0;
break;
case DIKS_CURSOR_RIGHT:
inc_x = 0;
break;
case DIKS_PAGE_UP:
inc_z = 0;
break;
case DIKS_PAGE_DOWN:
inc_z = 0;
break;
default:
;
}
break;
case DIET_AXISMOTION:
if (evt.flags & DIEF_AXISREL)
{
switch (evt.axis)
{
case DIAI_X:
view_x += evt.axisrel / 2.0;
break;
case DIAI_Y:
view_y -= evt.axisrel / 2.0;
break;
case DIAI_Z:
view_z += evt.axisrel / 2.0;
break;
default:
;
}
}
break;
default:
;
}
}
view_x += inc_x;
view_y += inc_y;
view_z += inc_z;
}
// release our interfaces to shutdown DirectFB
primary_gl->Release(primary_gl);
primary->Release(primary);
font->Release(font);
events->Release(events);
dfb->Release(dfb);
return 0;
}