Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/test/browser/perspective.c
7085 views
1
/*
2
* SDL OpenGL Tutorial.
3
* (c) Michael Vance, 2000
4
* [email protected]
5
*
6
* Distributed under terms of the LGPL.
7
*/
8
9
#include <SDL/SDL.h>
10
11
#ifdef __EMSCRIPTEN__
12
#include <GL/gl.h>
13
#include <GL/glu.h>
14
#include "emscripten.h"
15
#else
16
#include <GL/gl.h>
17
#include <GL/glu.h>
18
#endif
19
#include <stdio.h>
20
#include <stdlib.h>
21
22
#ifdef __EMSCRIPTEN__
23
#define emColor4ubv(x)
24
#else
25
#define emColor4ubv(x) glColor4ubv(x)
26
#endif
27
28
static GLboolean should_rotate = GL_TRUE;
29
30
static void quit_tutorial( int code )
31
{
32
/*
33
* Quit SDL so we can release the fullscreen
34
* mode and restore the previous video settings,
35
* etc.
36
*/
37
SDL_Quit( );
38
39
/* Exit program. */
40
exit( code );
41
}
42
43
static void handle_key_down( SDL_keysym* keysym )
44
{
45
46
/*
47
* We're only interested if 'Esc' has
48
* been presssed.
49
*
50
* EXERCISE:
51
* Handle the arrow keys and have that change the
52
* viewing position/angle.
53
*/
54
switch( keysym->sym ) {
55
case SDLK_ESCAPE:
56
quit_tutorial( 0 );
57
break;
58
case SDLK_SPACE:
59
should_rotate = !should_rotate;
60
break;
61
default:
62
break;
63
}
64
65
}
66
67
static void process_events( void )
68
{
69
/* Our SDL event placeholder. */
70
SDL_Event event;
71
72
/* Grab all the events off the queue. */
73
while( SDL_PollEvent( &event ) ) {
74
75
switch( event.type ) {
76
case SDL_KEYDOWN:
77
/* Handle key presses. */
78
handle_key_down( &event.key.keysym );
79
break;
80
case SDL_QUIT:
81
/* Handle quit requests (like Ctrl-c). */
82
quit_tutorial( 0 );
83
break;
84
}
85
86
}
87
88
}
89
90
static void draw_screen( void )
91
{
92
/* Our angle of rotation. */
93
static float angle = 0.0f;
94
95
/*
96
* EXERCISE:
97
* Replace this awful mess with vertex
98
* arrays and a call to glDrawElements.
99
*
100
* EXERCISE:
101
* After completing the above, change
102
* it to use compiled vertex arrays.
103
*
104
* EXERCISE:
105
* Verify my windings are correct here ;).
106
*/
107
static GLfloat v0[] = { -1.0f, -1.0f, 1.0f };
108
static GLfloat v1[] = { 1.0f, -1.0f, 1.0f };
109
static GLfloat v2[] = { 1.0f, 1.0f, 1.0f };
110
static GLfloat v3[] = { -1.0f, 1.0f, 1.0f };
111
static GLfloat v4[] = { -1.0f, -1.0f, -1.0f };
112
static GLfloat v5[] = { 1.0f, -1.0f, -1.0f };
113
static GLfloat v6[] = { 1.0f, 1.0f, -1.0f };
114
static GLfloat v7[] = { -1.0f, 1.0f, -1.0f };
115
static GLubyte red[] = { 255, 0, 0, 255 };
116
static GLubyte green[] = { 0, 255, 0, 255 };
117
static GLubyte blue[] = { 0, 0, 255, 255 };
118
static GLubyte white[] = { 255, 255, 255, 255 };
119
static GLubyte yellow[] = { 0, 255, 255, 255 };
120
static GLubyte black[] = { 0, 0, 0, 255 };
121
static GLubyte orange[] = { 255, 255, 0, 255 };
122
static GLubyte purple[] = { 255, 0, 255, 0 };
123
124
/* Clear the color and depth buffers. */
125
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
126
127
/* We don't want to modify the projection matrix. */
128
glMatrixMode( GL_MODELVIEW );
129
glLoadIdentity( );
130
131
/* Move down the z-axis. */
132
glTranslatef( 0.0, 0.0, -5.0 );
133
134
/* Rotate. */
135
glRotatef( angle, 0.0, 1.0, 0.0 );
136
137
if( should_rotate ) {
138
139
if( ++angle > 360.0f ) {
140
angle = 0.0f;
141
}
142
143
}
144
145
/* Send our triangle data to the pipeline. */
146
glBegin( GL_TRIANGLES );
147
148
emColor4ubv( red );
149
glVertex3fv( v0 );
150
emColor4ubv( green );
151
glVertex3fv( v1 );
152
emColor4ubv( blue );
153
glVertex3fv( v2 );
154
155
emColor4ubv( red );
156
glVertex3fv( v0 );
157
emColor4ubv( blue );
158
glVertex3fv( v2 );
159
emColor4ubv( white );
160
glVertex3fv( v3 );
161
162
emColor4ubv( green );
163
glVertex3fv( v1 );
164
emColor4ubv( black );
165
glVertex3fv( v5 );
166
emColor4ubv( orange );
167
glVertex3fv( v6 );
168
169
emColor4ubv( green );
170
glVertex3fv( v1 );
171
emColor4ubv( orange );
172
glVertex3fv( v6 );
173
emColor4ubv( blue );
174
glVertex3fv( v2 );
175
176
emColor4ubv( black );
177
glVertex3fv( v5 );
178
emColor4ubv( yellow );
179
glVertex3fv( v4 );
180
emColor4ubv( purple );
181
glVertex3fv( v7 );
182
183
emColor4ubv( black );
184
glVertex3fv( v5 );
185
emColor4ubv( purple );
186
glVertex3fv( v7 );
187
emColor4ubv( orange );
188
glVertex3fv( v6 );
189
190
emColor4ubv( yellow );
191
glVertex3fv( v4 );
192
emColor4ubv( red );
193
glVertex3fv( v0 );
194
emColor4ubv( white );
195
glVertex3fv( v3 );
196
197
emColor4ubv( yellow );
198
glVertex3fv( v4 );
199
emColor4ubv( white );
200
glVertex3fv( v3 );
201
emColor4ubv( purple );
202
glVertex3fv( v7 );
203
204
emColor4ubv( white );
205
glVertex3fv( v3 );
206
emColor4ubv( blue );
207
glVertex3fv( v2 );
208
emColor4ubv( orange );
209
glVertex3fv( v6 );
210
211
emColor4ubv( white );
212
glVertex3fv( v3 );
213
emColor4ubv( orange );
214
glVertex3fv( v6 );
215
emColor4ubv( purple );
216
glVertex3fv( v7 );
217
218
emColor4ubv( green );
219
glVertex3fv( v1 );
220
emColor4ubv( red );
221
glVertex3fv( v0 );
222
emColor4ubv( yellow );
223
glVertex3fv( v4 );
224
225
emColor4ubv( green );
226
glVertex3fv( v1 );
227
emColor4ubv( yellow );
228
glVertex3fv( v4 );
229
emColor4ubv( black );
230
glVertex3fv( v5 );
231
232
glEnd( );
233
234
/*
235
* EXERCISE:
236
* Draw text telling the user that 'Spc'
237
* pauses the rotation and 'Esc' quits.
238
* Do it using vetors and textured quads.
239
*/
240
241
/*
242
* Swap the buffers. This this tells the driver to
243
* render the next frame from the contents of the
244
* back-buffer, and to set all rendering operations
245
* to occur on what was the front-buffer.
246
*
247
* Double buffering prevents nasty visual tearing
248
* from the application drawing on areas of the
249
* screen that are being updated at the same time.
250
*/
251
SDL_GL_SwapBuffers( );
252
}
253
254
static void setup_opengl( int width, int height )
255
{
256
float ratio = (float) width / (float) height;
257
258
/* Our shading model--Gouraud (smooth). */
259
glShadeModel( GL_SMOOTH );
260
261
/* Culling. */
262
glCullFace( GL_BACK );
263
glFrontFace( GL_CCW );
264
glEnable( GL_CULL_FACE );
265
266
/* Set the clear color. */
267
glClearColor( 0, 0, 0, 0 );
268
269
/* Setup our viewport. */
270
glViewport( 0, 0, width, height );
271
272
/*
273
* Change to the projection matrix and set
274
* our viewing volume.
275
*/
276
glMatrixMode( GL_PROJECTION );
277
glLoadIdentity( );
278
/*
279
* EXERCISE:
280
* Replace this with a call to glFrustum.
281
*/
282
gluPerspective( 60.0, ratio, 1.0, 1024.0 );
283
}
284
285
void one_iter();
286
void one_iter() {
287
process_events( );
288
/* Draw the screen. */
289
draw_screen( );
290
}
291
292
int main( int argc, char* argv[] )
293
{
294
/* Information about the current video settings. */
295
const SDL_VideoInfo* info = NULL;
296
/* Dimensions of our window. */
297
int width = 0;
298
int height = 0;
299
/* Color depth in bits of our window. */
300
int bpp = 0;
301
/* Flags we will pass into SDL_SetVideoMode. */
302
int flags = 0;
303
304
/* First, initialize SDL's video subsystem. */
305
if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
306
/* Failed, exit. */
307
fprintf( stderr, "Video initialization failed: %s\n",
308
SDL_GetError( ) );
309
quit_tutorial( 1 );
310
}
311
312
/* Let's get some video information. */
313
info = SDL_GetVideoInfo( );
314
315
if( !info ) {
316
/* This should probably never happen. */
317
fprintf( stderr, "Video query failed: %s\n",
318
SDL_GetError( ) );
319
quit_tutorial( 1 );
320
}
321
322
/*
323
* Set our width/height to 640/480 (you would
324
* of course let the user decide this in a normal
325
* app). We get the bpp we will request from
326
* the display. On X11, VidMode can't change
327
* resolution, so this is probably being overly
328
* safe. Under Win32, ChangeDisplaySettings
329
* can change the bpp.
330
*/
331
width = 640;
332
height = 480;
333
bpp = info->vfmt->BitsPerPixel;
334
335
/*
336
* Now, we want to setup our requested
337
* window attributes for our OpenGL window.
338
* We want *at least* 5 bits of red, green
339
* and blue. We also want at least a 16-bit
340
* depth buffer.
341
*
342
* The last thing we do is request a double
343
* buffered window. '1' turns on double
344
* buffering, '0' turns it off.
345
*
346
* Note that we do not use SDL_DOUBLEBUF in
347
* the flags to SDL_SetVideoMode. That does
348
* not affect the GL attribute state, only
349
* the standard 2D blitting setup.
350
*/
351
// SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
352
// SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
353
// SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
354
// SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
355
// SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
356
357
/*
358
* We want to request that SDL provide us
359
* with an OpenGL window, in a fullscreen
360
* video mode.
361
*
362
* EXERCISE:
363
* Make starting windowed an option, and
364
* handle the resize events properly with
365
* glViewport.
366
*/
367
flags = SDL_OPENGL;// | SDL_FULLSCREEN;
368
369
/*
370
* Set the video mode
371
*/
372
if( SDL_SetVideoMode( width, height, bpp, flags ) == 0 ) {
373
/*
374
* This could happen for a variety of reasons,
375
* including DISPLAY not being set, the specified
376
* resolution not being available, etc.
377
*/
378
fprintf( stderr, "Video mode set failed: %s\n",
379
SDL_GetError( ) );
380
quit_tutorial( 1 );
381
}
382
383
/*
384
* At this point, we should have a properly setup
385
* double-buffered window for use with OpenGL.
386
*/
387
setup_opengl( width, height );
388
389
/*
390
* Now we want to begin our normal app process--
391
* an event loop with a lot of redrawing.
392
*/
393
one_iter(); // just one for testing purposes
394
395
#ifndef __EMSCRIPTEN__
396
SDL_Delay(2000);
397
#endif
398
399
/*
400
* EXERCISE:
401
* Record timings using SDL_GetTicks() and
402
* and print out frames per second at program
403
* end.
404
*/
405
406
/* Never reached. */
407
return 0;
408
}
409
410