You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
680 lines
19 KiB
680 lines
19 KiB
/***************************************************************************** |
|
* Title: GLBoing |
|
* Desc: Tribute to Amiga Boing. |
|
* Author: Jim Brooks <gfx@jimbrooks.org> |
|
* Original Amiga authors were R.J. Mical and Dale Luck. |
|
* GLFW conversion by Marcus Geelnard |
|
* Notes: - 360' = 2*PI [radian] |
|
* |
|
* - Distances between objects are created by doing a relative |
|
* Z translations. |
|
* |
|
* - Although OpenGL enticingly supports alpha-blending, |
|
* the shadow of the original Boing didn't affect the color |
|
* of the grid. |
|
* |
|
* - [Marcus] Changed timing scheme from interval driven to frame- |
|
* time based animation steps (which results in much smoother |
|
* movement) |
|
* |
|
* History of Amiga Boing: |
|
* |
|
* Boing was demonstrated on the prototype Amiga (codenamed "Lorraine") in |
|
* 1985. According to legend, it was written ad-hoc in one night by |
|
* R. J. Mical and Dale Luck. Because the bouncing ball animation was so fast |
|
* and smooth, attendees did not believe the Amiga prototype was really doing |
|
* the rendering. Suspecting a trick, they began looking around the booth for |
|
* a hidden computer or VCR. |
|
*****************************************************************************/ |
|
|
|
#if defined(_MSC_VER) |
|
// Make MS math.h define M_PI |
|
#define _USE_MATH_DEFINES |
|
#endif |
|
|
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <math.h> |
|
|
|
#define GLAD_GL_IMPLEMENTATION |
|
#include <glad/gl.h> |
|
#define GLFW_INCLUDE_NONE |
|
#include <GLFW/glfw3.h> |
|
|
|
#include <linmath.h> |
|
|
|
|
|
/***************************************************************************** |
|
* Various declarations and macros |
|
*****************************************************************************/ |
|
|
|
/* Prototypes */ |
|
void init( void ); |
|
void display( void ); |
|
void reshape( GLFWwindow* window, int w, int h ); |
|
void key_callback( GLFWwindow* window, int key, int scancode, int action, int mods ); |
|
void mouse_button_callback( GLFWwindow* window, int button, int action, int mods ); |
|
void cursor_position_callback( GLFWwindow* window, double x, double y ); |
|
void DrawBoingBall( void ); |
|
void BounceBall( double dt ); |
|
void DrawBoingBallBand( GLfloat long_lo, GLfloat long_hi ); |
|
void DrawGrid( void ); |
|
|
|
#define RADIUS 70.f |
|
#define STEP_LONGITUDE 22.5f /* 22.5 makes 8 bands like original Boing */ |
|
#define STEP_LATITUDE 22.5f |
|
|
|
#define DIST_BALL (RADIUS * 2.f + RADIUS * 0.1f) |
|
|
|
#define VIEW_SCENE_DIST (DIST_BALL * 3.f + 200.f)/* distance from viewer to middle of boing area */ |
|
#define GRID_SIZE (RADIUS * 4.5f) /* length (width) of grid */ |
|
#define BOUNCE_HEIGHT (RADIUS * 2.1f) |
|
#define BOUNCE_WIDTH (RADIUS * 2.1f) |
|
|
|
#define SHADOW_OFFSET_X -20.f |
|
#define SHADOW_OFFSET_Y 10.f |
|
#define SHADOW_OFFSET_Z 0.f |
|
|
|
#define WALL_L_OFFSET 0.f |
|
#define WALL_R_OFFSET 5.f |
|
|
|
/* Animation speed (50.0 mimics the original GLUT demo speed) */ |
|
#define ANIMATION_SPEED 50.f |
|
|
|
/* Maximum allowed delta time per physics iteration */ |
|
#define MAX_DELTA_T 0.02f |
|
|
|
/* Draw ball, or its shadow */ |
|
typedef enum { DRAW_BALL, DRAW_BALL_SHADOW } DRAW_BALL_ENUM; |
|
|
|
/* Vertex type */ |
|
typedef struct {float x; float y; float z;} vertex_t; |
|
|
|
/* Global vars */ |
|
int windowed_xpos, windowed_ypos, windowed_width, windowed_height; |
|
int width, height; |
|
GLfloat deg_rot_y = 0.f; |
|
GLfloat deg_rot_y_inc = 2.f; |
|
int override_pos = GLFW_FALSE; |
|
GLfloat cursor_x = 0.f; |
|
GLfloat cursor_y = 0.f; |
|
GLfloat ball_x = -RADIUS; |
|
GLfloat ball_y = -RADIUS; |
|
GLfloat ball_x_inc = 1.f; |
|
GLfloat ball_y_inc = 2.f; |
|
DRAW_BALL_ENUM drawBallHow; |
|
double t; |
|
double t_old = 0.f; |
|
double dt; |
|
|
|
/* Random number generator */ |
|
#ifndef RAND_MAX |
|
#define RAND_MAX 4095 |
|
#endif |
|
|
|
|
|
/***************************************************************************** |
|
* Truncate a degree. |
|
*****************************************************************************/ |
|
GLfloat TruncateDeg( GLfloat deg ) |
|
{ |
|
if ( deg >= 360.f ) |
|
return (deg - 360.f); |
|
else |
|
return deg; |
|
} |
|
|
|
/***************************************************************************** |
|
* Convert a degree (360-based) into a radian. |
|
* 360' = 2 * PI |
|
*****************************************************************************/ |
|
double deg2rad( double deg ) |
|
{ |
|
return deg / 360 * (2 * M_PI); |
|
} |
|
|
|
/***************************************************************************** |
|
* 360' sin(). |
|
*****************************************************************************/ |
|
double sin_deg( double deg ) |
|
{ |
|
return sin( deg2rad( deg ) ); |
|
} |
|
|
|
/***************************************************************************** |
|
* 360' cos(). |
|
*****************************************************************************/ |
|
double cos_deg( double deg ) |
|
{ |
|
return cos( deg2rad( deg ) ); |
|
} |
|
|
|
/***************************************************************************** |
|
* Compute a cross product (for a normal vector). |
|
* |
|
* c = a x b |
|
*****************************************************************************/ |
|
void CrossProduct( vertex_t a, vertex_t b, vertex_t c, vertex_t *n ) |
|
{ |
|
GLfloat u1, u2, u3; |
|
GLfloat v1, v2, v3; |
|
|
|
u1 = b.x - a.x; |
|
u2 = b.y - a.y; |
|
u3 = b.y - a.z; |
|
|
|
v1 = c.x - a.x; |
|
v2 = c.y - a.y; |
|
v3 = c.z - a.z; |
|
|
|
n->x = u2 * v3 - v2 * u3; |
|
n->y = u3 * v1 - v3 * u1; |
|
n->z = u1 * v2 - v1 * u2; |
|
} |
|
|
|
|
|
#define BOING_DEBUG 0 |
|
|
|
|
|
/***************************************************************************** |
|
* init() |
|
*****************************************************************************/ |
|
void init( void ) |
|
{ |
|
/* |
|
* Clear background. |
|
*/ |
|
glClearColor( 0.55f, 0.55f, 0.55f, 0.f ); |
|
|
|
glShadeModel( GL_FLAT ); |
|
} |
|
|
|
|
|
/***************************************************************************** |
|
* display() |
|
*****************************************************************************/ |
|
void display(void) |
|
{ |
|
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); |
|
glPushMatrix(); |
|
|
|
drawBallHow = DRAW_BALL_SHADOW; |
|
DrawBoingBall(); |
|
|
|
DrawGrid(); |
|
|
|
drawBallHow = DRAW_BALL; |
|
DrawBoingBall(); |
|
|
|
glPopMatrix(); |
|
glFlush(); |
|
} |
|
|
|
|
|
/***************************************************************************** |
|
* reshape() |
|
*****************************************************************************/ |
|
void reshape( GLFWwindow* window, int w, int h ) |
|
{ |
|
mat4x4 projection, view; |
|
|
|
glViewport( 0, 0, (GLsizei)w, (GLsizei)h ); |
|
|
|
glMatrixMode( GL_PROJECTION ); |
|
mat4x4_perspective( projection, |
|
2.f * (float) atan2( RADIUS, 200.f ), |
|
(float)w / (float)h, |
|
1.f, VIEW_SCENE_DIST ); |
|
glLoadMatrixf((const GLfloat*) projection); |
|
|
|
glMatrixMode( GL_MODELVIEW ); |
|
{ |
|
vec3 eye = { 0.f, 0.f, VIEW_SCENE_DIST }; |
|
vec3 center = { 0.f, 0.f, 0.f }; |
|
vec3 up = { 0.f, -1.f, 0.f }; |
|
mat4x4_look_at( view, eye, center, up ); |
|
} |
|
glLoadMatrixf((const GLfloat*) view); |
|
} |
|
|
|
void key_callback( GLFWwindow* window, int key, int scancode, int action, int mods ) |
|
{ |
|
if (action != GLFW_PRESS) |
|
return; |
|
|
|
if (key == GLFW_KEY_ESCAPE && mods == 0) |
|
glfwSetWindowShouldClose(window, GLFW_TRUE); |
|
if ((key == GLFW_KEY_ENTER && mods == GLFW_MOD_ALT) || |
|
(key == GLFW_KEY_F11 && mods == GLFW_MOD_ALT)) |
|
{ |
|
if (glfwGetWindowMonitor(window)) |
|
{ |
|
glfwSetWindowMonitor(window, NULL, |
|
windowed_xpos, windowed_ypos, |
|
windowed_width, windowed_height, 0); |
|
} |
|
else |
|
{ |
|
GLFWmonitor* monitor = glfwGetPrimaryMonitor(); |
|
if (monitor) |
|
{ |
|
const GLFWvidmode* mode = glfwGetVideoMode(monitor); |
|
glfwGetWindowPos(window, &windowed_xpos, &windowed_ypos); |
|
glfwGetWindowSize(window, &windowed_width, &windowed_height); |
|
glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate); |
|
} |
|
} |
|
} |
|
} |
|
|
|
static void set_ball_pos ( GLfloat x, GLfloat y ) |
|
{ |
|
ball_x = (width / 2) - x; |
|
ball_y = y - (height / 2); |
|
} |
|
|
|
void mouse_button_callback( GLFWwindow* window, int button, int action, int mods ) |
|
{ |
|
if (button != GLFW_MOUSE_BUTTON_LEFT) |
|
return; |
|
|
|
if (action == GLFW_PRESS) |
|
{ |
|
override_pos = GLFW_TRUE; |
|
set_ball_pos(cursor_x, cursor_y); |
|
} |
|
else |
|
{ |
|
override_pos = GLFW_FALSE; |
|
} |
|
} |
|
|
|
void cursor_position_callback( GLFWwindow* window, double x, double y ) |
|
{ |
|
cursor_x = (float) x; |
|
cursor_y = (float) y; |
|
|
|
if ( override_pos ) |
|
set_ball_pos(cursor_x, cursor_y); |
|
} |
|
|
|
/***************************************************************************** |
|
* Draw the Boing ball. |
|
* |
|
* The Boing ball is sphere in which each facet is a rectangle. |
|
* Facet colors alternate between red and white. |
|
* The ball is built by stacking latitudinal circles. Each circle is composed |
|
* of a widely-separated set of points, so that each facet is noticeably large. |
|
*****************************************************************************/ |
|
void DrawBoingBall( void ) |
|
{ |
|
GLfloat lon_deg; /* degree of longitude */ |
|
double dt_total, dt2; |
|
|
|
glPushMatrix(); |
|
glMatrixMode( GL_MODELVIEW ); |
|
|
|
/* |
|
* Another relative Z translation to separate objects. |
|
*/ |
|
glTranslatef( 0.0, 0.0, DIST_BALL ); |
|
|
|
/* Update ball position and rotation (iterate if necessary) */ |
|
dt_total = dt; |
|
while( dt_total > 0.0 ) |
|
{ |
|
dt2 = dt_total > MAX_DELTA_T ? MAX_DELTA_T : dt_total; |
|
dt_total -= dt2; |
|
BounceBall( dt2 ); |
|
deg_rot_y = TruncateDeg( deg_rot_y + deg_rot_y_inc*((float)dt2*ANIMATION_SPEED) ); |
|
} |
|
|
|
/* Set ball position */ |
|
glTranslatef( ball_x, ball_y, 0.0 ); |
|
|
|
/* |
|
* Offset the shadow. |
|
*/ |
|
if ( drawBallHow == DRAW_BALL_SHADOW ) |
|
{ |
|
glTranslatef( SHADOW_OFFSET_X, |
|
SHADOW_OFFSET_Y, |
|
SHADOW_OFFSET_Z ); |
|
} |
|
|
|
/* |
|
* Tilt the ball. |
|
*/ |
|
glRotatef( -20.0, 0.0, 0.0, 1.0 ); |
|
|
|
/* |
|
* Continually rotate ball around Y axis. |
|
*/ |
|
glRotatef( deg_rot_y, 0.0, 1.0, 0.0 ); |
|
|
|
/* |
|
* Set OpenGL state for Boing ball. |
|
*/ |
|
glCullFace( GL_FRONT ); |
|
glEnable( GL_CULL_FACE ); |
|
glEnable( GL_NORMALIZE ); |
|
|
|
/* |
|
* Build a faceted latitude slice of the Boing ball, |
|
* stepping same-sized vertical bands of the sphere. |
|
*/ |
|
for ( lon_deg = 0; |
|
lon_deg < 180; |
|
lon_deg += STEP_LONGITUDE ) |
|
{ |
|
/* |
|
* Draw a latitude circle at this longitude. |
|
*/ |
|
DrawBoingBallBand( lon_deg, |
|
lon_deg + STEP_LONGITUDE ); |
|
} |
|
|
|
glPopMatrix(); |
|
|
|
return; |
|
} |
|
|
|
|
|
/***************************************************************************** |
|
* Bounce the ball. |
|
*****************************************************************************/ |
|
void BounceBall( double delta_t ) |
|
{ |
|
GLfloat sign; |
|
GLfloat deg; |
|
|
|
if ( override_pos ) |
|
return; |
|
|
|
/* Bounce on walls */ |
|
if ( ball_x > (BOUNCE_WIDTH/2 + WALL_R_OFFSET ) ) |
|
{ |
|
ball_x_inc = -0.5f - 0.75f * (GLfloat)rand() / (GLfloat)RAND_MAX; |
|
deg_rot_y_inc = -deg_rot_y_inc; |
|
} |
|
if ( ball_x < -(BOUNCE_HEIGHT/2 + WALL_L_OFFSET) ) |
|
{ |
|
ball_x_inc = 0.5f + 0.75f * (GLfloat)rand() / (GLfloat)RAND_MAX; |
|
deg_rot_y_inc = -deg_rot_y_inc; |
|
} |
|
|
|
/* Bounce on floor / roof */ |
|
if ( ball_y > BOUNCE_HEIGHT/2 ) |
|
{ |
|
ball_y_inc = -0.75f - 1.f * (GLfloat)rand() / (GLfloat)RAND_MAX; |
|
} |
|
if ( ball_y < -BOUNCE_HEIGHT/2*0.85 ) |
|
{ |
|
ball_y_inc = 0.75f + 1.f * (GLfloat)rand() / (GLfloat)RAND_MAX; |
|
} |
|
|
|
/* Update ball position */ |
|
ball_x += ball_x_inc * ((float)delta_t*ANIMATION_SPEED); |
|
ball_y += ball_y_inc * ((float)delta_t*ANIMATION_SPEED); |
|
|
|
/* |
|
* Simulate the effects of gravity on Y movement. |
|
*/ |
|
if ( ball_y_inc < 0 ) sign = -1.0; else sign = 1.0; |
|
|
|
deg = (ball_y + BOUNCE_HEIGHT/2) * 90 / BOUNCE_HEIGHT; |
|
if ( deg > 80 ) deg = 80; |
|
if ( deg < 10 ) deg = 10; |
|
|
|
ball_y_inc = sign * 4.f * (float) sin_deg( deg ); |
|
} |
|
|
|
|
|
/***************************************************************************** |
|
* Draw a faceted latitude band of the Boing ball. |
|
* |
|
* Parms: long_lo, long_hi |
|
* Low and high longitudes of slice, resp. |
|
*****************************************************************************/ |
|
void DrawBoingBallBand( GLfloat long_lo, |
|
GLfloat long_hi ) |
|
{ |
|
vertex_t vert_ne; /* "ne" means south-east, so on */ |
|
vertex_t vert_nw; |
|
vertex_t vert_sw; |
|
vertex_t vert_se; |
|
vertex_t vert_norm; |
|
GLfloat lat_deg; |
|
static int colorToggle = 0; |
|
|
|
/* |
|
* Iterate through the points of a latitude circle. |
|
* A latitude circle is a 2D set of X,Z points. |
|
*/ |
|
for ( lat_deg = 0; |
|
lat_deg <= (360 - STEP_LATITUDE); |
|
lat_deg += STEP_LATITUDE ) |
|
{ |
|
/* |
|
* Color this polygon with red or white. |
|
*/ |
|
if ( colorToggle ) |
|
glColor3f( 0.8f, 0.1f, 0.1f ); |
|
else |
|
glColor3f( 0.95f, 0.95f, 0.95f ); |
|
#if 0 |
|
if ( lat_deg >= 180 ) |
|
if ( colorToggle ) |
|
glColor3f( 0.1f, 0.8f, 0.1f ); |
|
else |
|
glColor3f( 0.5f, 0.5f, 0.95f ); |
|
#endif |
|
colorToggle = ! colorToggle; |
|
|
|
/* |
|
* Change color if drawing shadow. |
|
*/ |
|
if ( drawBallHow == DRAW_BALL_SHADOW ) |
|
glColor3f( 0.35f, 0.35f, 0.35f ); |
|
|
|
/* |
|
* Assign each Y. |
|
*/ |
|
vert_ne.y = vert_nw.y = (float) cos_deg(long_hi) * RADIUS; |
|
vert_sw.y = vert_se.y = (float) cos_deg(long_lo) * RADIUS; |
|
|
|
/* |
|
* Assign each X,Z with sin,cos values scaled by latitude radius indexed by longitude. |
|
* Eg, long=0 and long=180 are at the poles, so zero scale is sin(longitude), |
|
* while long=90 (sin(90)=1) is at equator. |
|
*/ |
|
vert_ne.x = (float) cos_deg( lat_deg ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE )); |
|
vert_se.x = (float) cos_deg( lat_deg ) * (RADIUS * (float) sin_deg( long_lo )); |
|
vert_nw.x = (float) cos_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE )); |
|
vert_sw.x = (float) cos_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo )); |
|
|
|
vert_ne.z = (float) sin_deg( lat_deg ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE )); |
|
vert_se.z = (float) sin_deg( lat_deg ) * (RADIUS * (float) sin_deg( long_lo )); |
|
vert_nw.z = (float) sin_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE )); |
|
vert_sw.z = (float) sin_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo )); |
|
|
|
/* |
|
* Draw the facet. |
|
*/ |
|
glBegin( GL_POLYGON ); |
|
|
|
CrossProduct( vert_ne, vert_nw, vert_sw, &vert_norm ); |
|
glNormal3f( vert_norm.x, vert_norm.y, vert_norm.z ); |
|
|
|
glVertex3f( vert_ne.x, vert_ne.y, vert_ne.z ); |
|
glVertex3f( vert_nw.x, vert_nw.y, vert_nw.z ); |
|
glVertex3f( vert_sw.x, vert_sw.y, vert_sw.z ); |
|
glVertex3f( vert_se.x, vert_se.y, vert_se.z ); |
|
|
|
glEnd(); |
|
|
|
#if BOING_DEBUG |
|
printf( "----------------------------------------------------------- \n" ); |
|
printf( "lat = %f long_lo = %f long_hi = %f \n", lat_deg, long_lo, long_hi ); |
|
printf( "vert_ne x = %.8f y = %.8f z = %.8f \n", vert_ne.x, vert_ne.y, vert_ne.z ); |
|
printf( "vert_nw x = %.8f y = %.8f z = %.8f \n", vert_nw.x, vert_nw.y, vert_nw.z ); |
|
printf( "vert_se x = %.8f y = %.8f z = %.8f \n", vert_se.x, vert_se.y, vert_se.z ); |
|
printf( "vert_sw x = %.8f y = %.8f z = %.8f \n", vert_sw.x, vert_sw.y, vert_sw.z ); |
|
#endif |
|
|
|
} |
|
|
|
/* |
|
* Toggle color so that next band will opposite red/white colors than this one. |
|
*/ |
|
colorToggle = ! colorToggle; |
|
|
|
/* |
|
* This circular band is done. |
|
*/ |
|
return; |
|
} |
|
|
|
|
|
/***************************************************************************** |
|
* Draw the purple grid of lines, behind the Boing ball. |
|
* When the Workbench is dropped to the bottom, Boing shows 12 rows. |
|
*****************************************************************************/ |
|
void DrawGrid( void ) |
|
{ |
|
int row, col; |
|
const int rowTotal = 12; /* must be divisible by 2 */ |
|
const int colTotal = rowTotal; /* must be same as rowTotal */ |
|
const GLfloat widthLine = 2.0; /* should be divisible by 2 */ |
|
const GLfloat sizeCell = GRID_SIZE / rowTotal; |
|
const GLfloat z_offset = -40.0; |
|
GLfloat xl, xr; |
|
GLfloat yt, yb; |
|
|
|
glPushMatrix(); |
|
glDisable( GL_CULL_FACE ); |
|
|
|
/* |
|
* Another relative Z translation to separate objects. |
|
*/ |
|
glTranslatef( 0.0, 0.0, DIST_BALL ); |
|
|
|
/* |
|
* Draw vertical lines (as skinny 3D rectangles). |
|
*/ |
|
for ( col = 0; col <= colTotal; col++ ) |
|
{ |
|
/* |
|
* Compute co-ords of line. |
|
*/ |
|
xl = -GRID_SIZE / 2 + col * sizeCell; |
|
xr = xl + widthLine; |
|
|
|
yt = GRID_SIZE / 2; |
|
yb = -GRID_SIZE / 2 - widthLine; |
|
|
|
glBegin( GL_POLYGON ); |
|
|
|
glColor3f( 0.6f, 0.1f, 0.6f ); /* purple */ |
|
|
|
glVertex3f( xr, yt, z_offset ); /* NE */ |
|
glVertex3f( xl, yt, z_offset ); /* NW */ |
|
glVertex3f( xl, yb, z_offset ); /* SW */ |
|
glVertex3f( xr, yb, z_offset ); /* SE */ |
|
|
|
glEnd(); |
|
} |
|
|
|
/* |
|
* Draw horizontal lines (as skinny 3D rectangles). |
|
*/ |
|
for ( row = 0; row <= rowTotal; row++ ) |
|
{ |
|
/* |
|
* Compute co-ords of line. |
|
*/ |
|
yt = GRID_SIZE / 2 - row * sizeCell; |
|
yb = yt - widthLine; |
|
|
|
xl = -GRID_SIZE / 2; |
|
xr = GRID_SIZE / 2 + widthLine; |
|
|
|
glBegin( GL_POLYGON ); |
|
|
|
glColor3f( 0.6f, 0.1f, 0.6f ); /* purple */ |
|
|
|
glVertex3f( xr, yt, z_offset ); /* NE */ |
|
glVertex3f( xl, yt, z_offset ); /* NW */ |
|
glVertex3f( xl, yb, z_offset ); /* SW */ |
|
glVertex3f( xr, yb, z_offset ); /* SE */ |
|
|
|
glEnd(); |
|
} |
|
|
|
glPopMatrix(); |
|
|
|
return; |
|
} |
|
|
|
|
|
/*======================================================================* |
|
* main() |
|
*======================================================================*/ |
|
|
|
int main( void ) |
|
{ |
|
GLFWwindow* window; |
|
|
|
/* Init GLFW */ |
|
if( !glfwInit() ) |
|
exit( EXIT_FAILURE ); |
|
|
|
window = glfwCreateWindow( 400, 400, "Boing (classic Amiga demo)", NULL, NULL ); |
|
if (!window) |
|
{ |
|
glfwTerminate(); |
|
exit( EXIT_FAILURE ); |
|
} |
|
|
|
glfwSetWindowAspectRatio(window, 1, 1); |
|
|
|
glfwSetFramebufferSizeCallback(window, reshape); |
|
glfwSetKeyCallback(window, key_callback); |
|
glfwSetMouseButtonCallback(window, mouse_button_callback); |
|
glfwSetCursorPosCallback(window, cursor_position_callback); |
|
|
|
glfwMakeContextCurrent(window); |
|
gladLoadGL(glfwGetProcAddress); |
|
glfwSwapInterval( 1 ); |
|
|
|
glfwGetFramebufferSize(window, &width, &height); |
|
reshape(window, width, height); |
|
|
|
glfwSetTime( 0.0 ); |
|
|
|
init(); |
|
|
|
/* Main loop */ |
|
for (;;) |
|
{ |
|
/* Timing */ |
|
t = glfwGetTime(); |
|
dt = t - t_old; |
|
t_old = t; |
|
|
|
/* Draw one frame */ |
|
display(); |
|
|
|
/* Swap buffers */ |
|
glfwSwapBuffers(window); |
|
glfwPollEvents(); |
|
|
|
/* Check if we are still running */ |
|
if (glfwWindowShouldClose(window)) |
|
break; |
|
} |
|
|
|
glfwTerminate(); |
|
exit( EXIT_SUCCESS ); |
|
} |
|
|
|
|