mirror of
https://github.com/glfw/glfw.git
synced 2026-09-21 00:30:57 +00:00
Initial import of 2.7 Lite.
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
# This line is used to link with static libraries
|
||||
# Note that the library list should be updated to be obtained from
|
||||
# the main CMakeLists.txt
|
||||
link_libraries(libglfwStatic ${GLFW_LIBRARIES} ${OPENGL_glu_LIBRARY})
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include ${OPENGL_INCLUDE_DIR})
|
||||
|
||||
add_executable(listmodes listmodes.c)
|
||||
|
||||
if(APPLE)
|
||||
# Set fancy names for bundles
|
||||
add_executable(Boing MACOSX_BUNDLE boing.c)
|
||||
add_executable(Gears MACOSX_BUNDLE gears.c)
|
||||
add_executable("Split View" MACOSX_BUNDLE splitview.c)
|
||||
add_executable(Triangle MACOSX_BUNDLE triangle.c)
|
||||
add_executable(Wave MACOSX_BUNDLE wave.c)
|
||||
else(APPLE)
|
||||
# Set boring names for executables
|
||||
add_executable(boing WIN32 boing.c)
|
||||
add_executable(gears WIN32 gears.c)
|
||||
add_executable(splitview WIN32 splitview.c)
|
||||
add_executable(triangle WIN32 triangle.c)
|
||||
add_executable(wave WIN32 wave.c)
|
||||
endif(APPLE)
|
||||
|
||||
if(MSVC)
|
||||
# Tell MSVC to use main instead of WinMain for Windows subsystem executables
|
||||
set_target_properties(boing gears splitview triangle wave PROPERTIES LINK_FLAGS "/ENTRY:mainCRTStartup")
|
||||
endif(MSVC)
|
||||
|
||||
if(CYGWIN)
|
||||
# Set cross-compile and subsystem compile and link flags
|
||||
set_target_properties(boing gears listmodes splitview triangle wave PROPERTIES COMPILE_FLAGS "-mno-cygwin")
|
||||
set_target_properties(boing gears splitview triangle wave PROPERTIES LINK_FLAGS "-mno-cygwin -mwindows")
|
||||
set_target_properties(listmodes PROPERTIES LINK_FLAGS "-mno-cygwin -mconsole")
|
||||
endif(CYGWIN)
|
||||
|
||||
@@ -0,0 +1,615 @@
|
||||
/*****************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <GL/glfw.h>
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Various declarations and macros
|
||||
*****************************************************************************/
|
||||
|
||||
/* Prototypes */
|
||||
void init( void );
|
||||
void display( void );
|
||||
void reshape( int w, int h );
|
||||
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 */
|
||||
GLfloat deg_rot_y = 0.f;
|
||||
GLfloat deg_rot_y_inc = 2.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
|
||||
|
||||
/* PI */
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
#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 * v3;
|
||||
n->y = u3 * v1 - v3 * u1;
|
||||
n->z = u1 * v2 - v1 * u2;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Calculate the angle to be passed to gluPerspective() so that a scene
|
||||
* is visible. This function originates from the OpenGL Red Book.
|
||||
*
|
||||
* Parms : size
|
||||
* The size of the segment when the angle is intersected at "dist"
|
||||
* (ie at the outermost edge of the angle of vision).
|
||||
*
|
||||
* dist
|
||||
* Distance from viewpoint to scene.
|
||||
*****************************************************************************/
|
||||
GLfloat PerspectiveAngle( GLfloat size,
|
||||
GLfloat dist )
|
||||
{
|
||||
GLfloat radTheta, degTheta;
|
||||
|
||||
radTheta = 2.f * (GLfloat) atan2( size / 2.f, dist );
|
||||
degTheta = (180.f * radTheta) / (GLfloat) M_PI;
|
||||
return degTheta;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#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( int w, int h )
|
||||
{
|
||||
glViewport( 0, 0, (GLsizei)w, (GLsizei)h );
|
||||
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glLoadIdentity();
|
||||
|
||||
gluPerspective( PerspectiveAngle( RADIUS * 2, 200 ),
|
||||
(GLfloat)w / (GLfloat)h,
|
||||
1.0,
|
||||
VIEW_SCENE_DIST );
|
||||
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
|
||||
gluLookAt( 0.0, 0.0, VIEW_SCENE_DIST,/* eye */
|
||||
0.0, 0.0, 0.0, /* center of vision */
|
||||
0.0, -1.0, 0.0 ); /* up vector */
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* 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 noticably 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 dt )
|
||||
{
|
||||
GLfloat sign;
|
||||
GLfloat deg;
|
||||
|
||||
/* 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)dt*ANIMATION_SPEED);
|
||||
ball_y += ball_y_inc * ((float)dt*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 thru 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 )
|
||||
{
|
||||
int running;
|
||||
|
||||
/* Init GLFW */
|
||||
if( !glfwInit() )
|
||||
{
|
||||
fprintf( stderr, "Failed to initialize GLFW\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
if( !glfwOpenWindow( 400,400, 0,0,0,0, 16,0, GLFW_WINDOW ) )
|
||||
{
|
||||
fprintf( stderr, "Failed to open GLFW window\n" );
|
||||
glfwTerminate();
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
glfwSetWindowTitle( "Boing (classic Amiga demo)" );
|
||||
glfwSetWindowSizeCallback( reshape );
|
||||
glfwEnable( GLFW_STICKY_KEYS );
|
||||
glfwSwapInterval( 1 );
|
||||
glfwSetTime( 0.0 );
|
||||
|
||||
init();
|
||||
|
||||
/* Main loop */
|
||||
do
|
||||
{
|
||||
/* Timing */
|
||||
t = glfwGetTime();
|
||||
dt = t - t_old;
|
||||
t_old = t;
|
||||
|
||||
/* Draw one frame */
|
||||
display();
|
||||
|
||||
/* Swap buffers */
|
||||
glfwSwapBuffers();
|
||||
|
||||
/* Check if we are still running */
|
||||
running = !glfwGetKey( GLFW_KEY_ESC ) &&
|
||||
glfwGetWindowParam( GLFW_OPENED );
|
||||
}
|
||||
while( running );
|
||||
|
||||
glfwTerminate();
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,373 @@
|
||||
/*
|
||||
* 3-D gear wheels. This program is in the public domain.
|
||||
*
|
||||
* Command line options:
|
||||
* -info print GL implementation information
|
||||
* -exit automatically exit after 30 seconds
|
||||
*
|
||||
*
|
||||
* Brian Paul
|
||||
*
|
||||
*
|
||||
* Marcus Geelnard:
|
||||
* - Conversion to GLFW
|
||||
* - Time based rendering (frame rate independent)
|
||||
* - Slightly modified camera that should work better for stereo viewing
|
||||
*
|
||||
*
|
||||
* Camilla Berglund:
|
||||
* - Removed FPS counter (this is not a benchmark)
|
||||
* - Added a few comments
|
||||
* - Enabled vsync
|
||||
*/
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <GL/glfw.h>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.141592654
|
||||
#endif
|
||||
|
||||
/* The program exits when this is zero.
|
||||
*/
|
||||
static int running = 1;
|
||||
|
||||
/* If non-zero, the program exits after that many seconds
|
||||
*/
|
||||
static int autoexit = 0;
|
||||
|
||||
/**
|
||||
|
||||
Draw a gear wheel. You'll probably want to call this function when
|
||||
building a display list since we do a lot of trig here.
|
||||
|
||||
Input: inner_radius - radius of hole at center
|
||||
outer_radius - radius at center of teeth
|
||||
width - width of gear teeth - number of teeth
|
||||
tooth_depth - depth of tooth
|
||||
|
||||
**/
|
||||
|
||||
static void
|
||||
gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
|
||||
GLint teeth, GLfloat tooth_depth)
|
||||
{
|
||||
GLint i;
|
||||
GLfloat r0, r1, r2;
|
||||
GLfloat angle, da;
|
||||
GLfloat u, v, len;
|
||||
|
||||
r0 = inner_radius;
|
||||
r1 = outer_radius - tooth_depth / 2.f;
|
||||
r2 = outer_radius + tooth_depth / 2.f;
|
||||
|
||||
da = 2.f * (float) M_PI / teeth / 4.f;
|
||||
|
||||
glShadeModel(GL_FLAT);
|
||||
|
||||
glNormal3f(0.f, 0.f, 1.f);
|
||||
|
||||
/* draw front face */
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (i = 0; i <= teeth; i++) {
|
||||
angle = i * 2.f * (float) M_PI / teeth;
|
||||
glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), width * 0.5f);
|
||||
glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), width * 0.5f);
|
||||
if (i < teeth) {
|
||||
glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), width * 0.5f);
|
||||
glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), width * 0.5f);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
|
||||
/* draw front sides of teeth */
|
||||
glBegin(GL_QUADS);
|
||||
da = 2.f * (float) M_PI / teeth / 4.f;
|
||||
for (i = 0; i < teeth; i++) {
|
||||
angle = i * 2.f * (float) M_PI / teeth;
|
||||
|
||||
glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), width * 0.5f);
|
||||
glVertex3f(r2 * (float) cos(angle + da), r2 * (float) sin(angle + da), width * 0.5f);
|
||||
glVertex3f(r2 * (float) cos(angle + 2 * da), r2 * (float) sin(angle + 2 * da), width * 0.5f);
|
||||
glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), width * 0.5f);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
glNormal3f(0.0, 0.0, -1.0);
|
||||
|
||||
/* draw back face */
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (i = 0; i <= teeth; i++) {
|
||||
angle = i * 2.f * (float) M_PI / teeth;
|
||||
glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), -width * 0.5f);
|
||||
glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), -width * 0.5f);
|
||||
if (i < teeth) {
|
||||
glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), -width * 0.5f);
|
||||
glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), -width * 0.5f);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
|
||||
/* draw back sides of teeth */
|
||||
glBegin(GL_QUADS);
|
||||
da = 2.f * (float) M_PI / teeth / 4.f;
|
||||
for (i = 0; i < teeth; i++) {
|
||||
angle = i * 2.f * (float) M_PI / teeth;
|
||||
|
||||
glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), -width * 0.5f);
|
||||
glVertex3f(r2 * (float) cos(angle + 2 * da), r2 * (float) sin(angle + 2 * da), -width * 0.5f);
|
||||
glVertex3f(r2 * (float) cos(angle + da), r2 * (float) sin(angle + da), -width * 0.5f);
|
||||
glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), -width * 0.5f);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
/* draw outward faces of teeth */
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (i = 0; i < teeth; i++) {
|
||||
angle = i * 2.f * (float) M_PI / teeth;
|
||||
|
||||
glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), width * 0.5f);
|
||||
glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), -width * 0.5f);
|
||||
u = r2 * (float) cos(angle + da) - r1 * (float) cos(angle);
|
||||
v = r2 * (float) sin(angle + da) - r1 * (float) sin(angle);
|
||||
len = (float) sqrt(u * u + v * v);
|
||||
u /= len;
|
||||
v /= len;
|
||||
glNormal3f(v, -u, 0.0);
|
||||
glVertex3f(r2 * (float) cos(angle + da), r2 * (float) sin(angle + da), width * 0.5f);
|
||||
glVertex3f(r2 * (float) cos(angle + da), r2 * (float) sin(angle + da), -width * 0.5f);
|
||||
glNormal3f((float) cos(angle), (float) sin(angle), 0.f);
|
||||
glVertex3f(r2 * (float) cos(angle + 2 * da), r2 * (float) sin(angle + 2 * da), width * 0.5f);
|
||||
glVertex3f(r2 * (float) cos(angle + 2 * da), r2 * (float) sin(angle + 2 * da), -width * 0.5f);
|
||||
u = r1 * (float) cos(angle + 3 * da) - r2 * (float) cos(angle + 2 * da);
|
||||
v = r1 * (float) sin(angle + 3 * da) - r2 * (float) sin(angle + 2 * da);
|
||||
glNormal3f(v, -u, 0.f);
|
||||
glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), width * 0.5f);
|
||||
glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), -width * 0.5f);
|
||||
glNormal3f((float) cos(angle), (float) sin(angle), 0.f);
|
||||
}
|
||||
|
||||
glVertex3f(r1 * (float) cos(0), r1 * (float) sin(0), width * 0.5f);
|
||||
glVertex3f(r1 * (float) cos(0), r1 * (float) sin(0), -width * 0.5f);
|
||||
|
||||
glEnd();
|
||||
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
/* draw inside radius cylinder */
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (i = 0; i <= teeth; i++) {
|
||||
angle = i * 2.f * (float) M_PI / teeth;
|
||||
glNormal3f(-(float) cos(angle), -(float) sin(angle), 0.f);
|
||||
glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), -width * 0.5f);
|
||||
glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), width * 0.5f);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
}
|
||||
|
||||
|
||||
static GLfloat view_rotx = 20.f, view_roty = 30.f, view_rotz = 0.f;
|
||||
static GLint gear1, gear2, gear3;
|
||||
static GLfloat angle = 0.f;
|
||||
|
||||
/* OpenGL draw function & timing */
|
||||
static void draw(void)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glPushMatrix();
|
||||
glRotatef(view_rotx, 1.0, 0.0, 0.0);
|
||||
glRotatef(view_roty, 0.0, 1.0, 0.0);
|
||||
glRotatef(view_rotz, 0.0, 0.0, 1.0);
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(-3.0, -2.0, 0.0);
|
||||
glRotatef(angle, 0.0, 0.0, 1.0);
|
||||
glCallList(gear1);
|
||||
glPopMatrix();
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(3.1f, -2.f, 0.f);
|
||||
glRotatef(-2.f * angle - 9.f, 0.f, 0.f, 1.f);
|
||||
glCallList(gear2);
|
||||
glPopMatrix();
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(-3.1f, 4.2f, 0.f);
|
||||
glRotatef(-2.f * angle - 25.f, 0.f, 0.f, 1.f);
|
||||
glCallList(gear3);
|
||||
glPopMatrix();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
/* update animation parameters */
|
||||
static void animate(void)
|
||||
{
|
||||
angle = 100.f * (float) glfwGetTime();
|
||||
}
|
||||
|
||||
|
||||
/* change view angle, exit upon ESC */
|
||||
void key( int k, int action )
|
||||
{
|
||||
if( action != GLFW_PRESS ) return;
|
||||
|
||||
switch (k) {
|
||||
case 'Z':
|
||||
if( glfwGetKey( GLFW_KEY_LSHIFT ) )
|
||||
view_rotz -= 5.0;
|
||||
else
|
||||
view_rotz += 5.0;
|
||||
break;
|
||||
case GLFW_KEY_ESC:
|
||||
running = 0;
|
||||
break;
|
||||
case GLFW_KEY_UP:
|
||||
view_rotx += 5.0;
|
||||
break;
|
||||
case GLFW_KEY_DOWN:
|
||||
view_rotx -= 5.0;
|
||||
break;
|
||||
case GLFW_KEY_LEFT:
|
||||
view_roty += 5.0;
|
||||
break;
|
||||
case GLFW_KEY_RIGHT:
|
||||
view_roty -= 5.0;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* new window size */
|
||||
void reshape( int width, int height )
|
||||
{
|
||||
GLfloat h = (GLfloat) height / (GLfloat) width;
|
||||
GLfloat xmax, znear, zfar;
|
||||
|
||||
znear = 5.0f;
|
||||
zfar = 30.0f;
|
||||
xmax = znear * 0.5f;
|
||||
|
||||
glViewport( 0, 0, (GLint) width, (GLint) height );
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glLoadIdentity();
|
||||
glFrustum( -xmax, xmax, -xmax*h, xmax*h, znear, zfar );
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
glTranslatef( 0.0, 0.0, -20.0 );
|
||||
}
|
||||
|
||||
|
||||
/* program & OpenGL initialization */
|
||||
static void init(int argc, char *argv[])
|
||||
{
|
||||
static GLfloat pos[4] = {5.f, 5.f, 10.f, 0.f};
|
||||
static GLfloat red[4] = {0.8f, 0.1f, 0.f, 1.f};
|
||||
static GLfloat green[4] = {0.f, 0.8f, 0.2f, 1.f};
|
||||
static GLfloat blue[4] = {0.2f, 0.2f, 1.f, 1.f};
|
||||
GLint i;
|
||||
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, pos);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_LIGHT0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
/* make the gears */
|
||||
gear1 = glGenLists(1);
|
||||
glNewList(gear1, GL_COMPILE);
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
|
||||
gear(1.f, 4.f, 1.f, 20, 0.7f);
|
||||
glEndList();
|
||||
|
||||
gear2 = glGenLists(1);
|
||||
glNewList(gear2, GL_COMPILE);
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
|
||||
gear(0.5f, 2.f, 2.f, 10, 0.7f);
|
||||
glEndList();
|
||||
|
||||
gear3 = glGenLists(1);
|
||||
glNewList(gear3, GL_COMPILE);
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
|
||||
gear(1.3f, 2.f, 0.5f, 10, 0.7f);
|
||||
glEndList();
|
||||
|
||||
glEnable(GL_NORMALIZE);
|
||||
|
||||
for ( i=1; i<argc; i++ ) {
|
||||
if (strcmp(argv[i], "-info")==0) {
|
||||
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
|
||||
printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
|
||||
printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
|
||||
printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
|
||||
}
|
||||
else if ( strcmp(argv[i], "-exit")==0) {
|
||||
autoexit = 30;
|
||||
printf("Auto Exit after %i seconds.\n", autoexit );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* program entry */
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if( !glfwInit() )
|
||||
{
|
||||
fprintf( stderr, "Failed to initialize GLFW\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
if( !glfwOpenWindow( 300,300, 0,0,0,0, 16,0, GLFW_WINDOW ) )
|
||||
{
|
||||
fprintf( stderr, "Failed to open GLFW window\n" );
|
||||
glfwTerminate();
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
glfwSetWindowTitle( "Gears" );
|
||||
glfwEnable( GLFW_KEY_REPEAT );
|
||||
glfwSwapInterval( 1 );
|
||||
|
||||
// Parse command-line options
|
||||
init(argc, argv);
|
||||
|
||||
// Set callback functions
|
||||
glfwSetWindowSizeCallback( reshape );
|
||||
glfwSetKeyCallback( key );
|
||||
|
||||
// Main loop
|
||||
while( running )
|
||||
{
|
||||
// Draw gears
|
||||
draw();
|
||||
|
||||
// Update animation
|
||||
animate();
|
||||
|
||||
// Swap buffers
|
||||
glfwSwapBuffers();
|
||||
|
||||
// Was the window closed?
|
||||
if( !glfwGetWindowParam( GLFW_OPENED ) )
|
||||
{
|
||||
running = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Terminate GLFW
|
||||
glfwTerminate();
|
||||
|
||||
// Exit program
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
//========================================================================
|
||||
// This is a small test application for GLFW.
|
||||
// The program lists all available fullscreen video modes.
|
||||
//========================================================================
|
||||
|
||||
#include <stdio.h>
|
||||
#include <GL/glfw.h>
|
||||
|
||||
// Maximum number of modes that we want to list
|
||||
#define MAX_NUM_MODES 400
|
||||
|
||||
|
||||
//========================================================================
|
||||
// main()
|
||||
//========================================================================
|
||||
|
||||
int main( void )
|
||||
{
|
||||
GLFWvidmode dtmode, modes[ MAX_NUM_MODES ];
|
||||
int modecount, i;
|
||||
|
||||
// Initialize GLFW
|
||||
if( !glfwInit() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Show desktop video mode
|
||||
glfwGetDesktopMode( &dtmode );
|
||||
printf( "Desktop mode: %d x %d x %d\n\n",
|
||||
dtmode.Width, dtmode.Height, dtmode.RedBits +
|
||||
dtmode.GreenBits + dtmode.BlueBits );
|
||||
|
||||
// List available video modes
|
||||
modecount = glfwGetVideoModes( modes, MAX_NUM_MODES );
|
||||
printf( "Available modes:\n" );
|
||||
for( i = 0; i < modecount; i ++ )
|
||||
{
|
||||
printf( "%3d: %d x %d x %d\n", i,
|
||||
modes[i].Width, modes[i].Height, modes[i].RedBits +
|
||||
modes[i].GreenBits + modes[i].BlueBits );
|
||||
}
|
||||
|
||||
// Terminate GLFW
|
||||
glfwTerminate();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
//========================================================================
|
||||
// This is an example program for the GLFW library
|
||||
//
|
||||
// It shows texture loading with mipmap generation and rendering with
|
||||
// trilienar texture filtering
|
||||
//========================================================================
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <GL/glfw.h>
|
||||
|
||||
int main( void )
|
||||
{
|
||||
int width, height, x;
|
||||
double time;
|
||||
GLboolean running;
|
||||
GLuint textureID;
|
||||
char* texturePath = "mipmaps.tga";
|
||||
|
||||
// Initialise GLFW
|
||||
if( !glfwInit() )
|
||||
{
|
||||
fprintf( stderr, "Failed to initialize GLFW\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
// Open OpenGL window
|
||||
if( !glfwOpenWindow( 640, 480, 0,0,0,0, 0,0, GLFW_WINDOW ) )
|
||||
{
|
||||
fprintf( stderr, "Failed to open GLFW window\n" );
|
||||
glfwTerminate();
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
glfwSetWindowTitle( "Trilinear interpolation" );
|
||||
|
||||
// Enable sticky keys
|
||||
glfwEnable( GLFW_STICKY_KEYS );
|
||||
|
||||
// Enable vertical sync (on cards that support it)
|
||||
glfwSwapInterval( 1 );
|
||||
|
||||
// Generate and bind our texture ID
|
||||
glGenTextures( 1, &textureID );
|
||||
glBindTexture( GL_TEXTURE_2D, textureID );
|
||||
|
||||
// Load texture from file into video memory, including mipmap levels
|
||||
if( !glfwLoadTexture2D( texturePath, GLFW_BUILD_MIPMAPS_BIT ) )
|
||||
{
|
||||
fprintf( stderr, "Failed to load texture %s\n", texturePath );
|
||||
glfwTerminate();
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
// Use trilinear interpolation (GL_LINEAR_MIPMAP_LINEAR)
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
GL_LINEAR_MIPMAP_LINEAR );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
||||
GL_LINEAR );
|
||||
|
||||
// Enable plain 2D texturing
|
||||
glEnable( GL_TEXTURE_2D );
|
||||
|
||||
running = GL_TRUE;
|
||||
while( running )
|
||||
{
|
||||
// Get time and mouse position
|
||||
time = glfwGetTime();
|
||||
glfwGetMousePos( &x, NULL );
|
||||
|
||||
// Get window size (may be different than the requested size)
|
||||
glfwGetWindowSize( &width, &height );
|
||||
height = height > 0 ? height : 1;
|
||||
|
||||
// Set viewport
|
||||
glViewport( 0, 0, width, height );
|
||||
|
||||
// Clear color buffer
|
||||
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
glClear( GL_COLOR_BUFFER_BIT );
|
||||
|
||||
// Select and setup the projection matrix
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glLoadIdentity();
|
||||
gluPerspective( 65.0f, (GLfloat)width / (GLfloat)height, 1.0f,
|
||||
50.0f );
|
||||
|
||||
// Select and setup the modelview matrix
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
gluLookAt( 0.0f, 3.0f, -20.0f, // Eye-position
|
||||
0.0f, -4.0f, -11.0f, // View-point
|
||||
0.0f, 1.0f, 0.0f ); // Up-vector
|
||||
|
||||
// Draw a textured quad
|
||||
glRotatef( 0.05f * (GLfloat)x + (GLfloat)time * 5.0f, 0.0f, 1.0f, 0.0f );
|
||||
glBegin( GL_QUADS );
|
||||
glTexCoord2f( -20.0f, 20.0f );
|
||||
glVertex3f( -50.0f, 0.0f, -50.0f );
|
||||
glTexCoord2f( 20.0f, 20.0f );
|
||||
glVertex3f( 50.0f, 0.0f, -50.0f );
|
||||
glTexCoord2f( 20.0f, -20.0f );
|
||||
glVertex3f( 50.0f, 0.0f, 50.0f );
|
||||
glTexCoord2f( -20.0f, -20.0f );
|
||||
glVertex3f( -50.0f, 0.0f, 50.0f );
|
||||
glEnd();
|
||||
|
||||
// Swap buffers
|
||||
glfwSwapBuffers();
|
||||
|
||||
// Check if the ESC key was pressed or the window was closed
|
||||
running = !glfwGetKey( GLFW_KEY_ESC ) &&
|
||||
glfwGetWindowParam( GLFW_OPENED );
|
||||
}
|
||||
|
||||
// Close OpenGL window and terminate GLFW
|
||||
glfwTerminate();
|
||||
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,854 @@
|
||||
//========================================================================
|
||||
// This is a small test application for GLFW.
|
||||
// This is an OpenGL port of the famous "PONG" game (the first computer
|
||||
// game ever?). It is very simple, and could be improved alot. It was
|
||||
// created in order to show off the gaming capabilities of GLFW.
|
||||
//========================================================================
|
||||
|
||||
#include <GL/glfw.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Constants
|
||||
//========================================================================
|
||||
|
||||
// Screen resolution
|
||||
#define WIDTH 640
|
||||
#define HEIGHT 480
|
||||
|
||||
// Player size (units)
|
||||
#define PLAYER_XSIZE 0.05f
|
||||
#define PLAYER_YSIZE 0.15f
|
||||
|
||||
// Ball size (units)
|
||||
#define BALL_SIZE 0.02f
|
||||
|
||||
// Maximum player movement speed (units / second)
|
||||
#define MAX_SPEED 1.5f
|
||||
|
||||
// Player movement acceleration (units / seconds^2)
|
||||
#define ACCELERATION 4.0f
|
||||
|
||||
// Player movement deceleration (units / seconds^2)
|
||||
#define DECELERATION 2.0f
|
||||
|
||||
// Ball movement speed (units / second)
|
||||
#define BALL_SPEED 0.4f
|
||||
|
||||
// Menu options
|
||||
#define MENU_NONE 0
|
||||
#define MENU_PLAY 1
|
||||
#define MENU_QUIT 2
|
||||
|
||||
// Game events
|
||||
#define NOBODY_WINS 0
|
||||
#define PLAYER1_WINS 1
|
||||
#define PLAYER2_WINS 2
|
||||
|
||||
// Winner ID
|
||||
#define NOBODY 0
|
||||
#define PLAYER1 1
|
||||
#define PLAYER2 2
|
||||
|
||||
// Camera positions
|
||||
#define CAMERA_CLASSIC 0
|
||||
#define CAMERA_ABOVE 1
|
||||
#define CAMERA_SPECTATOR 2
|
||||
#define CAMERA_DEFAULT CAMERA_CLASSIC
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Textures
|
||||
//========================================================================
|
||||
|
||||
#define TEX_TITLE 0
|
||||
#define TEX_MENU 1
|
||||
#define TEX_INSTR 2
|
||||
#define TEX_WINNER1 3
|
||||
#define TEX_WINNER2 4
|
||||
#define TEX_FIELD 5
|
||||
#define NUM_TEXTURES 6
|
||||
|
||||
// Texture names
|
||||
char * tex_name[ NUM_TEXTURES ] = {
|
||||
"pong3d_title.tga",
|
||||
"pong3d_menu.tga",
|
||||
"pong3d_instr.tga",
|
||||
"pong3d_winner1.tga",
|
||||
"pong3d_winner2.tga",
|
||||
"pong3d_field.tga"
|
||||
};
|
||||
|
||||
// OpenGL texture object IDs
|
||||
GLuint tex_id[ NUM_TEXTURES ];
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Global variables
|
||||
//========================================================================
|
||||
|
||||
// Display information
|
||||
int width, height;
|
||||
|
||||
// Frame information
|
||||
double thistime, oldtime, dt, starttime;
|
||||
|
||||
// Camera information
|
||||
int camerapos;
|
||||
|
||||
// Player information
|
||||
struct {
|
||||
double ypos; // -1.0 to +1.0
|
||||
double yspeed; // -MAX_SPEED to +MAX_SPEED
|
||||
} player1, player2;
|
||||
|
||||
// Ball information
|
||||
struct {
|
||||
double xpos, ypos;
|
||||
double xspeed, yspeed;
|
||||
} ball;
|
||||
|
||||
// And the winner is...
|
||||
int winner;
|
||||
|
||||
// Lighting configuration
|
||||
const GLfloat env_ambient[4] = {1.0f,1.0f,1.0f,1.0f};
|
||||
const GLfloat light1_position[4] = {-3.0f,3.0f,2.0f,1.0f};
|
||||
const GLfloat light1_diffuse[4] = {1.0f,1.0f,1.0f,0.0f};
|
||||
const GLfloat light1_ambient[4] = {0.0f,0.0f,0.0f,0.0f};
|
||||
|
||||
// Object material properties
|
||||
const GLfloat player1_diffuse[4] = {1.0f,0.3f,0.3f,1.0f};
|
||||
const GLfloat player1_ambient[4] = {0.3f,0.1f,0.0f,1.0f};
|
||||
const GLfloat player2_diffuse[4] = {0.3f,1.0f,0.3f,1.0f};
|
||||
const GLfloat player2_ambient[4] = {0.1f,0.3f,0.1f,1.0f};
|
||||
const GLfloat ball_diffuse[4] = {1.0f,1.0f,0.5f,1.0f};
|
||||
const GLfloat ball_ambient[4] = {0.3f,0.3f,0.1f,1.0f};
|
||||
const GLfloat border_diffuse[4] = {0.3f,0.3f,1.0f,1.0f};
|
||||
const GLfloat border_ambient[4] = {0.1f,0.1f,0.3f,1.0f};
|
||||
const GLfloat floor_diffuse[4] = {1.0f,1.0f,1.0f,1.0f};
|
||||
const GLfloat floor_ambient[4] = {0.3f,0.3f,0.3f,1.0f};
|
||||
|
||||
|
||||
//========================================================================
|
||||
// LoadTextures() - Load textures from disk and upload to OpenGL card
|
||||
//========================================================================
|
||||
|
||||
GLboolean LoadTextures( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
// Generate texture objects
|
||||
glGenTextures( NUM_TEXTURES, tex_id );
|
||||
|
||||
// Load textures
|
||||
for( i = 0; i < NUM_TEXTURES; i ++ )
|
||||
{
|
||||
// Select texture object
|
||||
glBindTexture( GL_TEXTURE_2D, tex_id[ i ] );
|
||||
|
||||
// Set texture parameters
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||
|
||||
// Upload texture from file to texture memory
|
||||
if( !glfwLoadTexture2D( tex_name[ i ], 0 ) )
|
||||
{
|
||||
fprintf( stderr, "Failed to load texture %s\n", tex_name[ i ] );
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// DrawImage() - Draw a 2D image as a texture
|
||||
//========================================================================
|
||||
|
||||
void DrawImage( int texnum, float x1, float x2, float y1, float y2 )
|
||||
{
|
||||
glEnable( GL_TEXTURE_2D );
|
||||
glBindTexture( GL_TEXTURE_2D, tex_id[ texnum ] );
|
||||
glBegin( GL_QUADS );
|
||||
glTexCoord2f( 0.0f, 1.0f );
|
||||
glVertex2f( x1, y1 );
|
||||
glTexCoord2f( 1.0f, 1.0f );
|
||||
glVertex2f( x2, y1 );
|
||||
glTexCoord2f( 1.0f, 0.0f );
|
||||
glVertex2f( x2, y2 );
|
||||
glTexCoord2f( 0.0f, 0.0f );
|
||||
glVertex2f( x1, y2 );
|
||||
glEnd();
|
||||
glDisable( GL_TEXTURE_2D );
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// GameMenu() - Game menu (returns menu option)
|
||||
//========================================================================
|
||||
|
||||
int GameMenu( void )
|
||||
{
|
||||
int option;
|
||||
|
||||
// Enable sticky keys
|
||||
glfwEnable( GLFW_STICKY_KEYS );
|
||||
|
||||
// Wait for a game menu key to be pressed
|
||||
do
|
||||
{
|
||||
// Get window size
|
||||
glfwGetWindowSize( &width, &height );
|
||||
|
||||
// Set viewport
|
||||
glViewport( 0, 0, width, height );
|
||||
|
||||
// Clear display
|
||||
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
|
||||
glClear( GL_COLOR_BUFFER_BIT );
|
||||
|
||||
// Setup projection matrix
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glLoadIdentity();
|
||||
glOrtho( 0.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f );
|
||||
|
||||
// Setup modelview matrix
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
|
||||
// Display title
|
||||
glColor3f( 1.0f, 1.0f, 1.0f );
|
||||
DrawImage( TEX_TITLE, 0.1f, 0.9f, 0.0f, 0.3f );
|
||||
|
||||
// Display menu
|
||||
glColor3f( 1.0f, 1.0f, 0.0f );
|
||||
DrawImage( TEX_MENU, 0.38f, 0.62f, 0.35f, 0.5f );
|
||||
|
||||
// Display instructions
|
||||
glColor3f( 0.0f, 1.0f, 1.0f );
|
||||
DrawImage( TEX_INSTR, 0.32f, 0.68f, 0.65f, 0.85f );
|
||||
|
||||
// Swap buffers
|
||||
glfwSwapBuffers();
|
||||
|
||||
// Check for keys
|
||||
if( glfwGetKey( 'Q' ) || !glfwGetWindowParam( GLFW_OPENED ) )
|
||||
{
|
||||
option = MENU_QUIT;
|
||||
}
|
||||
else if( glfwGetKey( GLFW_KEY_F1 ) )
|
||||
{
|
||||
option = MENU_PLAY;
|
||||
}
|
||||
else
|
||||
{
|
||||
option = MENU_NONE;
|
||||
}
|
||||
|
||||
// To avoid horrible busy waiting, sleep for at least 20 ms
|
||||
glfwSleep( 0.02 );
|
||||
}
|
||||
while( option == MENU_NONE );
|
||||
|
||||
// Disable sticky keys
|
||||
glfwDisable( GLFW_STICKY_KEYS );
|
||||
|
||||
return option;
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// NewGame() - Initialize a new game
|
||||
//========================================================================
|
||||
|
||||
void NewGame( void )
|
||||
{
|
||||
// Frame information
|
||||
starttime = thistime = glfwGetTime();
|
||||
|
||||
// Camera information
|
||||
camerapos = CAMERA_DEFAULT;
|
||||
|
||||
// Player 1 information
|
||||
player1.ypos = 0.0;
|
||||
player1.yspeed = 0.0;
|
||||
|
||||
// Player 2 information
|
||||
player2.ypos = 0.0;
|
||||
player2.yspeed = 0.0;
|
||||
|
||||
// Ball information
|
||||
ball.xpos = -1.0 + PLAYER_XSIZE;
|
||||
ball.ypos = player1.ypos;
|
||||
ball.xspeed = 1.0;
|
||||
ball.yspeed = 1.0;
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// PlayerControl() - Player control
|
||||
//========================================================================
|
||||
|
||||
void PlayerControl( void )
|
||||
{
|
||||
float joy1pos[ 2 ], joy2pos[ 2 ];
|
||||
|
||||
// Get joystick X & Y axis positions
|
||||
glfwGetJoystickPos( GLFW_JOYSTICK_1, joy1pos, 2 );
|
||||
glfwGetJoystickPos( GLFW_JOYSTICK_2, joy2pos, 2 );
|
||||
|
||||
// Player 1 control
|
||||
if( glfwGetKey( 'A' ) || joy1pos[ 1 ] > 0.2f )
|
||||
{
|
||||
player1.yspeed += dt * ACCELERATION;
|
||||
if( player1.yspeed > MAX_SPEED )
|
||||
{
|
||||
player1.yspeed = MAX_SPEED;
|
||||
}
|
||||
}
|
||||
else if( glfwGetKey( 'Z' ) || joy1pos[ 1 ] < -0.2f )
|
||||
{
|
||||
player1.yspeed -= dt * ACCELERATION;
|
||||
if( player1.yspeed < -MAX_SPEED )
|
||||
{
|
||||
player1.yspeed = -MAX_SPEED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player1.yspeed /= exp( DECELERATION * dt );
|
||||
}
|
||||
|
||||
// Player 2 control
|
||||
if( glfwGetKey( 'K' ) || joy2pos[ 1 ] > 0.2f )
|
||||
{
|
||||
player2.yspeed += dt * ACCELERATION;
|
||||
if( player2.yspeed > MAX_SPEED )
|
||||
{
|
||||
player2.yspeed = MAX_SPEED;
|
||||
}
|
||||
}
|
||||
else if( glfwGetKey( 'M' ) || joy2pos[ 1 ] < -0.2f )
|
||||
{
|
||||
player2.yspeed -= dt * ACCELERATION;
|
||||
if( player2.yspeed < -MAX_SPEED )
|
||||
{
|
||||
player2.yspeed = -MAX_SPEED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player2.yspeed /= exp( DECELERATION * dt );
|
||||
}
|
||||
|
||||
// Update player 1 position
|
||||
player1.ypos += dt * player1.yspeed;
|
||||
if( player1.ypos > 1.0 - PLAYER_YSIZE )
|
||||
{
|
||||
player1.ypos = 1.0 - PLAYER_YSIZE;
|
||||
player1.yspeed = 0.0;
|
||||
}
|
||||
else if( player1.ypos < -1.0 + PLAYER_YSIZE )
|
||||
{
|
||||
player1.ypos = -1.0 + PLAYER_YSIZE;
|
||||
player1.yspeed = 0.0;
|
||||
}
|
||||
|
||||
// Update player 2 position
|
||||
player2.ypos += dt * player2.yspeed;
|
||||
if( player2.ypos > 1.0 - PLAYER_YSIZE )
|
||||
{
|
||||
player2.ypos = 1.0 - PLAYER_YSIZE;
|
||||
player2.yspeed = 0.0;
|
||||
}
|
||||
else if( player2.ypos < -1.0 + PLAYER_YSIZE )
|
||||
{
|
||||
player2.ypos = -1.0 + PLAYER_YSIZE;
|
||||
player2.yspeed = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// BallControl() - Ball control
|
||||
//========================================================================
|
||||
|
||||
int BallControl( void )
|
||||
{
|
||||
int event;
|
||||
double ballspeed;
|
||||
|
||||
// Calculate new ball speed
|
||||
ballspeed = BALL_SPEED * (1.0 + 0.02*(thistime-starttime));
|
||||
ball.xspeed = ball.xspeed > 0 ? ballspeed : -ballspeed;
|
||||
ball.yspeed = ball.yspeed > 0 ? ballspeed : -ballspeed;
|
||||
ball.yspeed *= 0.74321;
|
||||
|
||||
// Update ball position
|
||||
ball.xpos += dt * ball.xspeed;
|
||||
ball.ypos += dt * ball.yspeed;
|
||||
|
||||
// Did the ball hit a top/bottom wall?
|
||||
if( ball.ypos >= 1.0 )
|
||||
{
|
||||
ball.ypos = 2.0 - ball.ypos;
|
||||
ball.yspeed = -ball.yspeed;
|
||||
}
|
||||
else if( ball.ypos <= -1.0 )
|
||||
{
|
||||
ball.ypos = -2.0 - ball.ypos;
|
||||
ball.yspeed = -ball.yspeed;
|
||||
}
|
||||
|
||||
// Did the ball hit/miss a player?
|
||||
event = NOBODY_WINS;
|
||||
|
||||
// Is the ball entering the player 1 goal?
|
||||
if( ball.xpos < -1.0 + PLAYER_XSIZE )
|
||||
{
|
||||
// Did player 1 catch the ball?
|
||||
if( ball.ypos > (player1.ypos-PLAYER_YSIZE) &&
|
||||
ball.ypos < (player1.ypos+PLAYER_YSIZE) )
|
||||
{
|
||||
ball.xpos = -2.0 + 2.0*PLAYER_XSIZE - ball.xpos;
|
||||
ball.xspeed = -ball.xspeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
event = PLAYER2_WINS;
|
||||
}
|
||||
}
|
||||
|
||||
// Is the ball entering the player 2 goal?
|
||||
if( ball.xpos > 1.0 - PLAYER_XSIZE )
|
||||
{
|
||||
// Did player 2 catch the ball?
|
||||
if( ball.ypos > (player2.ypos-PLAYER_YSIZE) &&
|
||||
ball.ypos < (player2.ypos+PLAYER_YSIZE) )
|
||||
{
|
||||
ball.xpos = 2.0 - 2.0*PLAYER_XSIZE - ball.xpos;
|
||||
ball.xspeed = -ball.xspeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
event = PLAYER1_WINS;
|
||||
}
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// DrawBox() - Draw a 3D box
|
||||
//========================================================================
|
||||
|
||||
#define TEX_SCALE 4.0f
|
||||
|
||||
|
||||
void DrawBox( float x1, float y1, float z1, float x2, float y2, float z2 )
|
||||
{
|
||||
// Draw six sides of a cube
|
||||
glBegin( GL_QUADS );
|
||||
// Side 1 (down)
|
||||
glNormal3f( 0.0f, 0.0f, -1.0f );
|
||||
glTexCoord2f( 0.0f, 0.0f );
|
||||
glVertex3f( x1,y2,z1 );
|
||||
glTexCoord2f( TEX_SCALE, 0.0f );
|
||||
glVertex3f( x2,y2,z1 );
|
||||
glTexCoord2f( TEX_SCALE, TEX_SCALE );
|
||||
glVertex3f( x2,y1,z1 );
|
||||
glTexCoord2f( 0.0f, TEX_SCALE );
|
||||
glVertex3f( x1,y1,z1 );
|
||||
// Side 2 (up)
|
||||
glNormal3f( 0.0f, 0.0f, 1.0f );
|
||||
glTexCoord2f( 0.0f, 0.0f );
|
||||
glVertex3f( x1,y1,z2 );
|
||||
glTexCoord2f( TEX_SCALE, 0.0f );
|
||||
glVertex3f( x2,y1,z2 );
|
||||
glTexCoord2f( TEX_SCALE, TEX_SCALE );
|
||||
glVertex3f( x2,y2,z2 );
|
||||
glTexCoord2f( 0.0f, TEX_SCALE );
|
||||
glVertex3f( x1,y2,z2 );
|
||||
// Side 3 (backward)
|
||||
glNormal3f( 0.0f, -1.0f, 0.0f );
|
||||
glTexCoord2f( 0.0f, 0.0f );
|
||||
glVertex3f( x1,y1,z1 );
|
||||
glTexCoord2f( TEX_SCALE, 0.0f );
|
||||
glVertex3f( x2,y1,z1 );
|
||||
glTexCoord2f( TEX_SCALE, TEX_SCALE );
|
||||
glVertex3f( x2,y1,z2 );
|
||||
glTexCoord2f( 0.0f, TEX_SCALE );
|
||||
glVertex3f( x1,y1,z2 );
|
||||
// Side 4 (forward)
|
||||
glNormal3f( 0.0f, 1.0f, 0.0f );
|
||||
glTexCoord2f( 0.0f, 0.0f );
|
||||
glVertex3f( x1,y2,z2 );
|
||||
glTexCoord2f( TEX_SCALE, 0.0f );
|
||||
glVertex3f( x2,y2,z2 );
|
||||
glTexCoord2f( TEX_SCALE, TEX_SCALE );
|
||||
glVertex3f( x2,y2,z1 );
|
||||
glTexCoord2f( 0.0f, TEX_SCALE );
|
||||
glVertex3f( x1,y2,z1 );
|
||||
// Side 5 (left)
|
||||
glNormal3f( -1.0f, 0.0f, 0.0f );
|
||||
glTexCoord2f( 0.0f, 0.0f );
|
||||
glVertex3f( x1,y1,z2 );
|
||||
glTexCoord2f( TEX_SCALE, 0.0f );
|
||||
glVertex3f( x1,y2,z2 );
|
||||
glTexCoord2f( TEX_SCALE, TEX_SCALE );
|
||||
glVertex3f( x1,y2,z1 );
|
||||
glTexCoord2f( 0.0f, TEX_SCALE );
|
||||
glVertex3f( x1,y1,z1 );
|
||||
// Side 6 (right)
|
||||
glNormal3f( 1.0f, 0.0f, 0.0f );
|
||||
glTexCoord2f( 0.0f, 0.0f );
|
||||
glVertex3f( x2,y1,z1 );
|
||||
glTexCoord2f( TEX_SCALE, 0.0f );
|
||||
glVertex3f( x2,y2,z1 );
|
||||
glTexCoord2f( TEX_SCALE, TEX_SCALE );
|
||||
glVertex3f( x2,y2,z2 );
|
||||
glTexCoord2f( 0.0f, TEX_SCALE );
|
||||
glVertex3f( x2,y1,z2 );
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// UpdateDisplay() - Draw graphics (all game related OpenGL stuff goes
|
||||
// here)
|
||||
//========================================================================
|
||||
|
||||
void UpdateDisplay( void )
|
||||
{
|
||||
// Get window size
|
||||
glfwGetWindowSize( &width, &height );
|
||||
|
||||
// Set viewport
|
||||
glViewport( 0, 0, width, height );
|
||||
|
||||
// Clear display
|
||||
glClearColor( 0.02f, 0.02f, 0.02f, 0.0f );
|
||||
glClearDepth( 1.0f );
|
||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||
|
||||
// Setup projection matrix
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glLoadIdentity();
|
||||
gluPerspective(
|
||||
55.0f, // Angle of view
|
||||
(GLfloat)width/(GLfloat)height, // Aspect
|
||||
1.0f, // Near Z
|
||||
100.0f // Far Z
|
||||
);
|
||||
|
||||
// Setup modelview matrix
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
switch( camerapos )
|
||||
{
|
||||
default:
|
||||
case CAMERA_CLASSIC:
|
||||
gluLookAt(
|
||||
0.0f, 0.0f, 2.5f,
|
||||
0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f
|
||||
);
|
||||
break;
|
||||
case CAMERA_ABOVE:
|
||||
gluLookAt(
|
||||
0.0f, 0.0f, 2.5f,
|
||||
(float)ball.xpos, (float)ball.ypos, 0.0f,
|
||||
0.0f, 1.0f, 0.0f
|
||||
);
|
||||
break;
|
||||
case CAMERA_SPECTATOR:
|
||||
gluLookAt(
|
||||
0.0f, -2.0, 1.2f,
|
||||
(float)ball.xpos, (float)ball.ypos, 0.0f,
|
||||
0.0f, 0.0f, 1.0f
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
// Enable depth testing
|
||||
glEnable( GL_DEPTH_TEST );
|
||||
glDepthFunc( GL_LEQUAL );
|
||||
|
||||
// Enable lighting
|
||||
glEnable( GL_LIGHTING );
|
||||
glLightModelfv( GL_LIGHT_MODEL_AMBIENT, env_ambient );
|
||||
glLightModeli( GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE );
|
||||
glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE );
|
||||
glLightfv( GL_LIGHT1, GL_POSITION, light1_position );
|
||||
glLightfv( GL_LIGHT1, GL_DIFFUSE, light1_diffuse );
|
||||
glLightfv( GL_LIGHT1, GL_AMBIENT, light1_ambient );
|
||||
glEnable( GL_LIGHT1 );
|
||||
|
||||
// Front face is counter-clock-wise
|
||||
glFrontFace( GL_CCW );
|
||||
|
||||
// Enable face culling (not necessary, but speeds up rendering)
|
||||
glCullFace( GL_BACK );
|
||||
glEnable( GL_CULL_FACE );
|
||||
|
||||
// Draw Player 1
|
||||
glMaterialfv( GL_FRONT, GL_DIFFUSE, player1_diffuse );
|
||||
glMaterialfv( GL_FRONT, GL_AMBIENT, player1_ambient );
|
||||
DrawBox( -1.f, (GLfloat)player1.ypos-PLAYER_YSIZE, 0.f,
|
||||
-1.f+PLAYER_XSIZE, (GLfloat)player1.ypos+PLAYER_YSIZE, 0.1f );
|
||||
|
||||
// Draw Player 2
|
||||
glMaterialfv( GL_FRONT, GL_DIFFUSE, player2_diffuse );
|
||||
glMaterialfv( GL_FRONT, GL_AMBIENT, player2_ambient );
|
||||
DrawBox( 1.f-PLAYER_XSIZE, (GLfloat)player2.ypos-PLAYER_YSIZE, 0.f,
|
||||
1.f, (GLfloat)player2.ypos+PLAYER_YSIZE, 0.1f );
|
||||
|
||||
// Draw Ball
|
||||
glMaterialfv( GL_FRONT, GL_DIFFUSE, ball_diffuse );
|
||||
glMaterialfv( GL_FRONT, GL_AMBIENT, ball_ambient );
|
||||
DrawBox( (GLfloat)ball.xpos-BALL_SIZE, (GLfloat)ball.ypos-BALL_SIZE, 0.f,
|
||||
(GLfloat)ball.xpos+BALL_SIZE, (GLfloat)ball.ypos+BALL_SIZE, BALL_SIZE*2 );
|
||||
|
||||
// Top game field border
|
||||
glMaterialfv( GL_FRONT, GL_DIFFUSE, border_diffuse );
|
||||
glMaterialfv( GL_FRONT, GL_AMBIENT, border_ambient );
|
||||
DrawBox( -1.1f, 1.0f, 0.0f, 1.1f, 1.1f, 0.1f );
|
||||
// Bottom game field border
|
||||
glColor3f( 0.0f, 0.0f, 0.7f );
|
||||
DrawBox( -1.1f, -1.1f, 0.0f, 1.1f, -1.0f, 0.1f );
|
||||
// Left game field border
|
||||
DrawBox( -1.1f, -1.0f, 0.0f, -1.0f, 1.0f, 0.1f );
|
||||
// Left game field border
|
||||
DrawBox( 1.0f, -1.0f, 0.0f, 1.1f, 1.0f, 0.1f );
|
||||
|
||||
// Enable texturing
|
||||
glEnable( GL_TEXTURE_2D );
|
||||
glBindTexture( GL_TEXTURE_2D, tex_id[ TEX_FIELD ] );
|
||||
|
||||
// Game field floor
|
||||
glMaterialfv( GL_FRONT, GL_DIFFUSE, floor_diffuse );
|
||||
glMaterialfv( GL_FRONT, GL_AMBIENT, floor_ambient );
|
||||
DrawBox( -1.01f, -1.01f, -0.01f, 1.01f, 1.01f, 0.0f );
|
||||
|
||||
// Disable texturing
|
||||
glDisable( GL_TEXTURE_2D );
|
||||
|
||||
// Disable face culling
|
||||
glDisable( GL_CULL_FACE );
|
||||
|
||||
// Disable lighting
|
||||
glDisable( GL_LIGHTING );
|
||||
|
||||
// Disable depth testing
|
||||
glDisable( GL_DEPTH_TEST );
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// GameOver()
|
||||
//========================================================================
|
||||
|
||||
void GameOver( void )
|
||||
{
|
||||
// Enable sticky keys
|
||||
glfwEnable( GLFW_STICKY_KEYS );
|
||||
|
||||
// Until the user presses ESC or SPACE
|
||||
while( !glfwGetKey( GLFW_KEY_ESC ) && !glfwGetKey( ' ' ) &&
|
||||
glfwGetWindowParam( GLFW_OPENED ) )
|
||||
{
|
||||
// Draw display
|
||||
UpdateDisplay();
|
||||
|
||||
// Setup projection matrix
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glLoadIdentity();
|
||||
glOrtho( 0.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f );
|
||||
|
||||
// Setup modelview matrix
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
|
||||
// Enable blending
|
||||
glEnable( GL_BLEND );
|
||||
|
||||
// Dim background
|
||||
glBlendFunc( GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA );
|
||||
glColor4f( 0.3f, 0.3f, 0.3f, 0.3f );
|
||||
glBegin( GL_QUADS );
|
||||
glVertex2f( 0.0f, 0.0f );
|
||||
glVertex2f( 1.0f, 0.0f );
|
||||
glVertex2f( 1.0f, 1.0f );
|
||||
glVertex2f( 0.0f, 1.0f );
|
||||
glEnd();
|
||||
|
||||
// Display winner text
|
||||
glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_COLOR );
|
||||
if( winner == PLAYER1 )
|
||||
{
|
||||
glColor4f( 1.0f, 0.5f, 0.5f, 1.0f );
|
||||
DrawImage( TEX_WINNER1, 0.35f, 0.65f, 0.46f, 0.54f );
|
||||
}
|
||||
else if( winner == PLAYER2 )
|
||||
{
|
||||
glColor4f( 0.5f, 1.0f, 0.5f, 1.0f );
|
||||
DrawImage( TEX_WINNER2, 0.35f, 0.65f, 0.46f, 0.54f );
|
||||
}
|
||||
|
||||
// Disable blending
|
||||
glDisable( GL_BLEND );
|
||||
|
||||
// Swap buffers
|
||||
glfwSwapBuffers();
|
||||
}
|
||||
|
||||
// Disable sticky keys
|
||||
glfwDisable( GLFW_STICKY_KEYS );
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// GameLoop() - Game loop
|
||||
//========================================================================
|
||||
|
||||
void GameLoop( void )
|
||||
{
|
||||
int playing, event;
|
||||
|
||||
// Initialize a new game
|
||||
NewGame();
|
||||
|
||||
// Enable sticky keys
|
||||
glfwEnable( GLFW_STICKY_KEYS );
|
||||
|
||||
// Loop until the game ends
|
||||
playing = GL_TRUE;
|
||||
while( playing && glfwGetWindowParam( GLFW_OPENED ) )
|
||||
{
|
||||
// Frame timer
|
||||
oldtime = thistime;
|
||||
thistime = glfwGetTime();
|
||||
dt = thistime - oldtime;
|
||||
|
||||
// Get user input and update player positions
|
||||
PlayerControl();
|
||||
|
||||
// Move the ball, and check if a player hits/misses the ball
|
||||
event = BallControl();
|
||||
|
||||
// Did we have a winner?
|
||||
switch( event )
|
||||
{
|
||||
case PLAYER1_WINS:
|
||||
winner = PLAYER1;
|
||||
playing = GL_FALSE;
|
||||
break;
|
||||
case PLAYER2_WINS:
|
||||
winner = PLAYER2;
|
||||
playing = GL_FALSE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Did the user press ESC?
|
||||
if( glfwGetKey( GLFW_KEY_ESC ) )
|
||||
{
|
||||
playing = GL_FALSE;
|
||||
}
|
||||
|
||||
// Did the user change camera view?
|
||||
if( glfwGetKey( '1' ) )
|
||||
{
|
||||
camerapos = CAMERA_CLASSIC;
|
||||
}
|
||||
else if( glfwGetKey( '2' ) )
|
||||
{
|
||||
camerapos = CAMERA_ABOVE;
|
||||
}
|
||||
else if( glfwGetKey( '3' ) )
|
||||
{
|
||||
camerapos = CAMERA_SPECTATOR;
|
||||
}
|
||||
|
||||
// Draw display
|
||||
UpdateDisplay();
|
||||
|
||||
// Swap buffers
|
||||
glfwSwapBuffers();
|
||||
}
|
||||
|
||||
// Disable sticky keys
|
||||
glfwDisable( GLFW_STICKY_KEYS );
|
||||
|
||||
// Show winner
|
||||
GameOver();
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// main() - Program entry point
|
||||
//========================================================================
|
||||
|
||||
int main( void )
|
||||
{
|
||||
int menuoption;
|
||||
|
||||
// Initialize GLFW
|
||||
if( !glfwInit() )
|
||||
{
|
||||
fprintf( stderr, "Failed to initialize GLFW\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
// Open OpenGL window
|
||||
if( !glfwOpenWindow( WIDTH, HEIGHT, 0,0,0,0, 16,0, GLFW_FULLSCREEN ) )
|
||||
{
|
||||
fprintf( stderr, "Failed to open GLFW window\n" );
|
||||
glfwTerminate();
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
glfwSwapInterval( 1 );
|
||||
|
||||
// Load all textures
|
||||
if( !LoadTextures() )
|
||||
{
|
||||
glfwTerminate();
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
// Main loop
|
||||
do
|
||||
{
|
||||
// Get menu option
|
||||
menuoption = GameMenu();
|
||||
|
||||
// If the user wants to play, let him...
|
||||
if( menuoption == MENU_PLAY )
|
||||
{
|
||||
GameLoop();
|
||||
}
|
||||
}
|
||||
while( menuoption != MENU_QUIT );
|
||||
|
||||
// Unload all textures
|
||||
if( glfwGetWindowParam( GLFW_OPENED ) )
|
||||
{
|
||||
glDeleteTextures( NUM_TEXTURES, tex_id );
|
||||
}
|
||||
|
||||
// Terminate GLFW
|
||||
glfwTerminate();
|
||||
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,514 @@
|
||||
//========================================================================
|
||||
// This is an example program for the GLFW library
|
||||
//
|
||||
// The program uses a "split window" view, rendering four views of the
|
||||
// same scene in one window (e.g. uesful for 3D modelling software). This
|
||||
// demo uses scissors to separete the four different rendering areas from
|
||||
// each other.
|
||||
//
|
||||
// (If the code seems a little bit strange here and there, it may be
|
||||
// because I am not a friend of orthogonal projections)
|
||||
//========================================================================
|
||||
|
||||
#include <GL/glfw.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Global variables
|
||||
//========================================================================
|
||||
|
||||
// Mouse position
|
||||
static int xpos = 0, ypos = 0;
|
||||
|
||||
// Window size
|
||||
static int width, height;
|
||||
|
||||
// Active view: 0 = none, 1 = upper left, 2 = upper right, 3 = lower left,
|
||||
// 4 = lower right
|
||||
static int active_view = 0;
|
||||
|
||||
// Rotation around each axis
|
||||
static int rot_x = 0, rot_y = 0, rot_z = 0;
|
||||
|
||||
// Do redraw?
|
||||
static int do_redraw = 1;
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Draw a solid torus (use a display list for the model)
|
||||
//========================================================================
|
||||
|
||||
#define TORUS_MAJOR 1.5
|
||||
#define TORUS_MINOR 0.5
|
||||
#define TORUS_MAJOR_RES 32
|
||||
#define TORUS_MINOR_RES 32
|
||||
|
||||
static void drawTorus( void )
|
||||
{
|
||||
static GLuint torus_list = 0;
|
||||
int i, j, k;
|
||||
double s, t, x, y, z, nx, ny, nz, scale, twopi;
|
||||
|
||||
if( !torus_list )
|
||||
{
|
||||
// Start recording displaylist
|
||||
torus_list = glGenLists( 1 );
|
||||
glNewList( torus_list, GL_COMPILE_AND_EXECUTE );
|
||||
|
||||
// Draw torus
|
||||
twopi = 2.0 * M_PI;
|
||||
for( i = 0; i < TORUS_MINOR_RES; i++ )
|
||||
{
|
||||
glBegin( GL_QUAD_STRIP );
|
||||
for( j = 0; j <= TORUS_MAJOR_RES; j++ )
|
||||
{
|
||||
for( k = 1; k >= 0; k-- )
|
||||
{
|
||||
s = (i + k) % TORUS_MINOR_RES + 0.5;
|
||||
t = j % TORUS_MAJOR_RES;
|
||||
|
||||
// Calculate point on surface
|
||||
x = (TORUS_MAJOR+TORUS_MINOR*cos(s*twopi/TORUS_MINOR_RES))*cos(t*twopi/TORUS_MAJOR_RES);
|
||||
y = TORUS_MINOR * sin(s * twopi / TORUS_MINOR_RES);
|
||||
z = (TORUS_MAJOR+TORUS_MINOR*cos(s*twopi/TORUS_MINOR_RES))*sin(t*twopi/TORUS_MAJOR_RES);
|
||||
|
||||
// Calculate surface normal
|
||||
nx = x - TORUS_MAJOR*cos(t*twopi/TORUS_MAJOR_RES);
|
||||
ny = y;
|
||||
nz = z - TORUS_MAJOR*sin(t*twopi/TORUS_MAJOR_RES);
|
||||
scale = 1.0 / sqrt( nx*nx + ny*ny + nz*nz );
|
||||
nx *= scale;
|
||||
ny *= scale;
|
||||
nz *= scale;
|
||||
|
||||
glNormal3f( (float)nx, (float)ny, (float)nz );
|
||||
glVertex3f( (float)x, (float)y, (float)z );
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
// Stop recording displaylist
|
||||
glEndList();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Playback displaylist
|
||||
glCallList( torus_list );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Draw the scene (a rotating torus)
|
||||
//========================================================================
|
||||
|
||||
static void drawScene( void )
|
||||
{
|
||||
const GLfloat model_diffuse[4] = {1.0f, 0.8f, 0.8f, 1.0f};
|
||||
const GLfloat model_specular[4] = {0.6f, 0.6f, 0.6f, 1.0f};
|
||||
const GLfloat model_shininess = 20.0f;
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
// Rotate the object
|
||||
glRotatef( (GLfloat)rot_x*0.5f, 1.0f, 0.0f, 0.0f );
|
||||
glRotatef( (GLfloat)rot_y*0.5f, 0.0f, 1.0f, 0.0f );
|
||||
glRotatef( (GLfloat)rot_z*0.5f, 0.0f, 0.0f, 1.0f );
|
||||
|
||||
// Set model color (used for orthogonal views, lighting disabled)
|
||||
glColor4fv( model_diffuse );
|
||||
|
||||
// Set model material (used for perspective view, lighting enabled)
|
||||
glMaterialfv( GL_FRONT, GL_DIFFUSE, model_diffuse );
|
||||
glMaterialfv( GL_FRONT, GL_SPECULAR, model_specular );
|
||||
glMaterialf( GL_FRONT, GL_SHININESS, model_shininess );
|
||||
|
||||
// Draw torus
|
||||
drawTorus();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Draw a 2D grid (used for orthogonal views)
|
||||
//========================================================================
|
||||
|
||||
static void drawGrid( float scale, int steps )
|
||||
{
|
||||
int i;
|
||||
float x, y;
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
// Set background to some dark bluish grey
|
||||
glClearColor( 0.05f, 0.05f, 0.2f, 0.0f);
|
||||
glClear( GL_COLOR_BUFFER_BIT );
|
||||
|
||||
// Setup modelview matrix (flat XY view)
|
||||
glLoadIdentity();
|
||||
gluLookAt( 0.0, 0.0, 1.0,
|
||||
0.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0 );
|
||||
|
||||
// We don't want to update the Z-buffer
|
||||
glDepthMask( GL_FALSE );
|
||||
|
||||
// Set grid color
|
||||
glColor3f( 0.0f, 0.5f, 0.5f );
|
||||
|
||||
glBegin( GL_LINES );
|
||||
|
||||
// Horizontal lines
|
||||
x = scale * 0.5f * (float)(steps-1);
|
||||
y = -scale * 0.5f * (float)(steps-1);
|
||||
for( i = 0; i < steps; i ++ )
|
||||
{
|
||||
glVertex3f( -x, y, 0.0f );
|
||||
glVertex3f( x, y, 0.0f );
|
||||
y += scale;
|
||||
}
|
||||
|
||||
// Vertical lines
|
||||
x = -scale * 0.5f * (float)(steps-1);
|
||||
y = scale * 0.5f * (float)(steps-1);
|
||||
for( i = 0; i < steps; i ++ )
|
||||
{
|
||||
glVertex3f( x, -y, 0.0f );
|
||||
glVertex3f( x, y, 0.0f );
|
||||
x += scale;
|
||||
}
|
||||
|
||||
glEnd();
|
||||
|
||||
// Enable Z-buffer writing again
|
||||
glDepthMask( GL_TRUE );
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Draw all views
|
||||
//========================================================================
|
||||
|
||||
static void drawAllViews( void )
|
||||
{
|
||||
const GLfloat light_position[4] = {0.0f, 8.0f, 8.0f, 1.0f};
|
||||
const GLfloat light_diffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
const GLfloat light_specular[4] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
const GLfloat light_ambient[4] = {0.2f, 0.2f, 0.3f, 1.0f};
|
||||
double aspect;
|
||||
|
||||
// Calculate aspect of window
|
||||
if( height > 0 )
|
||||
{
|
||||
aspect = (double)width / (double)height;
|
||||
}
|
||||
else
|
||||
{
|
||||
aspect = 1.0;
|
||||
}
|
||||
|
||||
// Clear screen
|
||||
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||
|
||||
// Enable scissor test
|
||||
glEnable( GL_SCISSOR_TEST );
|
||||
|
||||
// Enable depth test
|
||||
glEnable( GL_DEPTH_TEST );
|
||||
glDepthFunc( GL_LEQUAL );
|
||||
|
||||
|
||||
// ** ORTHOGONAL VIEWS **
|
||||
|
||||
// For orthogonal views, use wireframe rendering
|
||||
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
|
||||
|
||||
// Enable line anti-aliasing
|
||||
glEnable( GL_LINE_SMOOTH );
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
|
||||
// Setup orthogonal projection matrix
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glLoadIdentity();
|
||||
glOrtho( -3.0*aspect, 3.0*aspect, -3.0, 3.0, 1.0, 50.0 );
|
||||
|
||||
// Upper left view (TOP VIEW)
|
||||
glViewport( 0, height/2, width/2, height/2 );
|
||||
glScissor( 0, height/2, width/2, height/2 );
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
gluLookAt( 0.0f, 10.0f, 1e-3f, // Eye-position (above)
|
||||
0.0f, 0.0f, 0.0f, // View-point
|
||||
0.0f, 1.0f, 0.0f ); // Up-vector
|
||||
drawGrid( 0.5, 12 );
|
||||
drawScene();
|
||||
|
||||
// Lower left view (FRONT VIEW)
|
||||
glViewport( 0, 0, width/2, height/2 );
|
||||
glScissor( 0, 0, width/2, height/2 );
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
gluLookAt( 0.0f, 0.0f, 10.0f, // Eye-position (in front of)
|
||||
0.0f, 0.0f, 0.0f, // View-point
|
||||
0.0f, 1.0f, 0.0f ); // Up-vector
|
||||
drawGrid( 0.5, 12 );
|
||||
drawScene();
|
||||
|
||||
// Lower right view (SIDE VIEW)
|
||||
glViewport( width/2, 0, width/2, height/2 );
|
||||
glScissor( width/2, 0, width/2, height/2 );
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
gluLookAt( 10.0f, 0.0f, 0.0f, // Eye-position (to the right)
|
||||
0.0f, 0.0f, 0.0f, // View-point
|
||||
0.0f, 1.0f, 0.0f ); // Up-vector
|
||||
drawGrid( 0.5, 12 );
|
||||
drawScene();
|
||||
|
||||
// Disable line anti-aliasing
|
||||
glDisable( GL_LINE_SMOOTH );
|
||||
glDisable( GL_BLEND );
|
||||
|
||||
|
||||
// ** PERSPECTIVE VIEW **
|
||||
|
||||
// For perspective view, use solid rendering
|
||||
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
|
||||
|
||||
// Enable face culling (faster rendering)
|
||||
glEnable( GL_CULL_FACE );
|
||||
glCullFace( GL_BACK );
|
||||
glFrontFace( GL_CW );
|
||||
|
||||
// Setup perspective projection matrix
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glLoadIdentity();
|
||||
gluPerspective( 65.0f, aspect, 1.0f, 50.0f );
|
||||
|
||||
// Upper right view (PERSPECTIVE VIEW)
|
||||
glViewport( width/2, height/2, width/2, height/2 );
|
||||
glScissor( width/2, height/2, width/2, height/2 );
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
gluLookAt( 3.0f, 1.5f, 3.0f, // Eye-position
|
||||
0.0f, 0.0f, 0.0f, // View-point
|
||||
0.0f, 1.0f, 0.0f ); // Up-vector
|
||||
|
||||
// Configure and enable light source 1
|
||||
glLightfv( GL_LIGHT1, GL_POSITION, light_position );
|
||||
glLightfv( GL_LIGHT1, GL_AMBIENT, light_ambient );
|
||||
glLightfv( GL_LIGHT1, GL_DIFFUSE, light_diffuse );
|
||||
glLightfv( GL_LIGHT1, GL_SPECULAR, light_specular );
|
||||
glEnable( GL_LIGHT1 );
|
||||
glEnable( GL_LIGHTING );
|
||||
|
||||
// Draw scene
|
||||
drawScene();
|
||||
|
||||
// Disable lighting
|
||||
glDisable( GL_LIGHTING );
|
||||
|
||||
// Disable face culling
|
||||
glDisable( GL_CULL_FACE );
|
||||
|
||||
// Disable depth test
|
||||
glDisable( GL_DEPTH_TEST );
|
||||
|
||||
// Disable scissor test
|
||||
glDisable( GL_SCISSOR_TEST );
|
||||
|
||||
|
||||
// Draw a border around the active view
|
||||
if( active_view > 0 && active_view != 2 )
|
||||
{
|
||||
glViewport( 0, 0, width, height );
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glLoadIdentity();
|
||||
glOrtho( 0.0, 2.0, 0.0, 2.0, 0.0, 1.0 );
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
glColor3f( 1.0f, 1.0f, 0.6f );
|
||||
glTranslatef( (GLfloat) ((active_view - 1) & 1), (GLfloat) (1 - (active_view - 1) / 2), 0.0f );
|
||||
glBegin( GL_LINE_STRIP );
|
||||
glVertex2i( 0, 0 );
|
||||
glVertex2i( 1, 0 );
|
||||
glVertex2i( 1, 1 );
|
||||
glVertex2i( 0, 1 );
|
||||
glVertex2i( 0, 0 );
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Window size callback function
|
||||
//========================================================================
|
||||
|
||||
static void windowSizeFun( int w, int h )
|
||||
{
|
||||
width = w;
|
||||
height = h > 0 ? h : 1;
|
||||
do_redraw = 1;
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Window refresh callback function
|
||||
//========================================================================
|
||||
|
||||
static void windowRefreshFun( void )
|
||||
{
|
||||
do_redraw = 1;
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Mouse position callback function
|
||||
//========================================================================
|
||||
|
||||
static void mousePosFun( int x, int y )
|
||||
{
|
||||
// Depending on which view was selected, rotate around different axes
|
||||
switch( active_view )
|
||||
{
|
||||
case 1:
|
||||
rot_x += y - ypos;
|
||||
rot_z += x - xpos;
|
||||
do_redraw = 1;
|
||||
break;
|
||||
case 3:
|
||||
rot_x += y - ypos;
|
||||
rot_y += x - xpos;
|
||||
do_redraw = 1;
|
||||
break;
|
||||
case 4:
|
||||
rot_y += x - xpos;
|
||||
rot_z += y - ypos;
|
||||
do_redraw = 1;
|
||||
break;
|
||||
default:
|
||||
// Do nothing for perspective view, or if no view is selected
|
||||
break;
|
||||
}
|
||||
|
||||
// Remember mouse position
|
||||
xpos = x;
|
||||
ypos = y;
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Mouse button callback function
|
||||
//========================================================================
|
||||
|
||||
static void mouseButtonFun( int button, int action )
|
||||
{
|
||||
// Button clicked?
|
||||
if( ( button == GLFW_MOUSE_BUTTON_LEFT ) && action == GLFW_PRESS )
|
||||
{
|
||||
// Detect which of the four views was clicked
|
||||
active_view = 1;
|
||||
if( xpos >= width/2 )
|
||||
{
|
||||
active_view += 1;
|
||||
}
|
||||
if( ypos >= height/2 )
|
||||
{
|
||||
active_view += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Button released?
|
||||
else if( button == GLFW_MOUSE_BUTTON_LEFT )
|
||||
{
|
||||
// Deselect any previously selected view
|
||||
active_view = 0;
|
||||
}
|
||||
|
||||
do_redraw = 1;
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// main()
|
||||
//========================================================================
|
||||
|
||||
int main( void )
|
||||
{
|
||||
// Initialise GLFW
|
||||
if( !glfwInit() )
|
||||
{
|
||||
fprintf( stderr, "Failed to initialize GLFW\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
// Open OpenGL window
|
||||
if( !glfwOpenWindow( 500, 500, 0,0,0,0, 16,0, GLFW_WINDOW ) )
|
||||
{
|
||||
fprintf( stderr, "Failed to open GLFW window\n" );
|
||||
glfwTerminate();
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
// Enable vsync
|
||||
glfwSwapInterval( 1 );
|
||||
|
||||
// Set window title
|
||||
glfwSetWindowTitle( "Split view demo" );
|
||||
|
||||
// Enable sticky keys
|
||||
glfwEnable( GLFW_STICKY_KEYS );
|
||||
|
||||
// Enable mouse cursor (only needed for fullscreen mode)
|
||||
glfwEnable( GLFW_MOUSE_CURSOR );
|
||||
|
||||
// Disable automatic event polling
|
||||
glfwDisable( GLFW_AUTO_POLL_EVENTS );
|
||||
|
||||
// Set callback functions
|
||||
glfwSetWindowSizeCallback( windowSizeFun );
|
||||
glfwSetWindowRefreshCallback( windowRefreshFun );
|
||||
glfwSetMousePosCallback( mousePosFun );
|
||||
glfwSetMouseButtonCallback( mouseButtonFun );
|
||||
|
||||
// Main loop
|
||||
do
|
||||
{
|
||||
// Only redraw if we need to
|
||||
if( do_redraw )
|
||||
{
|
||||
// Draw all views
|
||||
drawAllViews();
|
||||
|
||||
// Swap buffers
|
||||
glfwSwapBuffers();
|
||||
|
||||
do_redraw = 0;
|
||||
}
|
||||
|
||||
// Wait for new events
|
||||
glfwWaitEvents();
|
||||
|
||||
} // Check if the ESC key was pressed or the window was closed
|
||||
while( glfwGetKey( GLFW_KEY_ESC ) != GLFW_PRESS &&
|
||||
glfwGetWindowParam( GLFW_OPENED ) );
|
||||
|
||||
// Close OpenGL window and terminate GLFW
|
||||
glfwTerminate();
|
||||
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
//========================================================================
|
||||
// This is a small test application for GLFW.
|
||||
// The program opens a window (640x480), and renders a spinning colored
|
||||
// triangle (it is controlled with both the GLFW timer and the mouse).
|
||||
//========================================================================
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <GL/glfw.h>
|
||||
|
||||
|
||||
int main( void )
|
||||
{
|
||||
int width, height, x;
|
||||
double t;
|
||||
|
||||
// Initialise GLFW
|
||||
if( !glfwInit() )
|
||||
{
|
||||
fprintf( stderr, "Failed to initialize GLFW\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
// Open a window and create its OpenGL context
|
||||
if( !glfwOpenWindow( 640, 480, 0,0,0,0, 0,0, GLFW_WINDOW ) )
|
||||
{
|
||||
fprintf( stderr, "Failed to open GLFW window\n" );
|
||||
|
||||
glfwTerminate();
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
glfwSetWindowTitle( "Spinning Triangle" );
|
||||
|
||||
// Ensure we can capture the escape key being pressed below
|
||||
glfwEnable( GLFW_STICKY_KEYS );
|
||||
|
||||
// Enable vertical sync (on cards that support it)
|
||||
glfwSwapInterval( 1 );
|
||||
|
||||
do
|
||||
{
|
||||
t = glfwGetTime();
|
||||
glfwGetMousePos( &x, NULL );
|
||||
|
||||
// Get window size (may be different than the requested size)
|
||||
glfwGetWindowSize( &width, &height );
|
||||
|
||||
// Special case: avoid division by zero below
|
||||
height = height > 0 ? height : 1;
|
||||
|
||||
glViewport( 0, 0, width, height );
|
||||
|
||||
// Clear color buffer to black
|
||||
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
|
||||
glClear( GL_COLOR_BUFFER_BIT );
|
||||
|
||||
// Select and setup the projection matrix
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glLoadIdentity();
|
||||
gluPerspective( 65.0f, (GLfloat)width/(GLfloat)height, 1.0f, 100.0f );
|
||||
|
||||
// Select and setup the modelview matrix
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
gluLookAt( 0.0f, 1.0f, 0.0f, // Eye-position
|
||||
0.0f, 20.0f, 0.0f, // View-point
|
||||
0.0f, 0.0f, 1.0f ); // Up-vector
|
||||
|
||||
// Draw a rotating colorful triangle
|
||||
glTranslatef( 0.0f, 14.0f, 0.0f );
|
||||
glRotatef( 0.3f*(GLfloat)x + (GLfloat)t*100.0f, 0.0f, 0.0f, 1.0f );
|
||||
glBegin( GL_TRIANGLES );
|
||||
glColor3f( 1.0f, 0.0f, 0.0f );
|
||||
glVertex3f( -5.0f, 0.0f, -4.0f );
|
||||
glColor3f( 0.0f, 1.0f, 0.0f );
|
||||
glVertex3f( 5.0f, 0.0f, -4.0f );
|
||||
glColor3f( 0.0f, 0.0f, 1.0f );
|
||||
glVertex3f( 0.0f, 0.0f, 6.0f );
|
||||
glEnd();
|
||||
|
||||
// Swap buffers
|
||||
glfwSwapBuffers();
|
||||
|
||||
} // Check if the ESC key was pressed or the window was closed
|
||||
while( glfwGetKey( GLFW_KEY_ESC ) != GLFW_PRESS &&
|
||||
glfwGetWindowParam( GLFW_OPENED ) );
|
||||
|
||||
// Close OpenGL window and terminate GLFW
|
||||
glfwTerminate();
|
||||
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
||||
+399
@@ -0,0 +1,399 @@
|
||||
/*****************************************************************************
|
||||
* Wave Simulation in OpenGL
|
||||
* (C) 2002 Jakob Thomsen
|
||||
* http://home.in.tum.de/~thomsen
|
||||
* Modified for GLFW by Sylvain Hellegouarch - sh@programmationworld.com
|
||||
* Modified for variable frame rate by Marcus Geelnard
|
||||
* 2003-Jan-31: Minor cleanups and speedups / MG
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <GL/glfw.h>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
#endif
|
||||
|
||||
/* Maximum delta T to allow for differential calculations */
|
||||
#define MAX_DELTA_T 0.01
|
||||
|
||||
/* Animation speed (10.0 looks good) */
|
||||
#define ANIMATION_SPEED 10.0
|
||||
|
||||
|
||||
GLfloat alpha = 210.0f, beta = -70.0f;
|
||||
GLfloat zoom = 2.0f;
|
||||
|
||||
int running = 1;
|
||||
|
||||
struct Vertex
|
||||
{
|
||||
GLfloat x,y,z;
|
||||
GLfloat r,g,b;
|
||||
};
|
||||
|
||||
#define GRIDW 50
|
||||
#define GRIDH 50
|
||||
#define VERTEXNUM (GRIDW*GRIDH)
|
||||
|
||||
#define QUADW (GRIDW-1)
|
||||
#define QUADH (GRIDH-1)
|
||||
#define QUADNUM (QUADW*QUADH)
|
||||
|
||||
GLuint quad[4*QUADNUM];
|
||||
struct Vertex vertex[VERTEXNUM];
|
||||
|
||||
/* The grid will look like this:
|
||||
*
|
||||
* 3 4 5
|
||||
* *---*---*
|
||||
* | | |
|
||||
* | 0 | 1 |
|
||||
* | | |
|
||||
* *---*---*
|
||||
* 0 1 2
|
||||
*/
|
||||
|
||||
void initVertices( void )
|
||||
{
|
||||
int x,y,p;
|
||||
|
||||
/* place the vertices in a grid */
|
||||
for(y=0;y<GRIDH;y++)
|
||||
for(x=0;x<GRIDW;x++)
|
||||
{
|
||||
p = y*GRIDW + x;
|
||||
|
||||
//vertex[p].x = (-GRIDW/2)+x+sin(2.0*M_PI*(double)y/(double)GRIDH);
|
||||
//vertex[p].y = (-GRIDH/2)+y+cos(2.0*M_PI*(double)x/(double)GRIDW);
|
||||
vertex[p].x = (GLfloat)(x-GRIDW/2)/(GLfloat)(GRIDW/2);
|
||||
vertex[p].y = (GLfloat)(y-GRIDH/2)/(GLfloat)(GRIDH/2);
|
||||
vertex[p].z = 0;//sin(d*M_PI);
|
||||
//vertex[p].r = (GLfloat)x/(GLfloat)GRIDW;
|
||||
//vertex[p].g = (GLfloat)y/(GLfloat)GRIDH;
|
||||
//vertex[p].b = 1.0-((GLfloat)x/(GLfloat)GRIDW+(GLfloat)y/(GLfloat)GRIDH)/2.0;
|
||||
if((x%4<2)^(y%4<2))
|
||||
{
|
||||
vertex[p].r = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
vertex[p].r=1.0;
|
||||
}
|
||||
|
||||
vertex[p].g = (GLfloat)y/(GLfloat)GRIDH;
|
||||
vertex[p].b = 1.f-((GLfloat)x/(GLfloat)GRIDW+(GLfloat)y/(GLfloat)GRIDH)/2.f;
|
||||
}
|
||||
|
||||
for(y=0;y<QUADH;y++)
|
||||
for(x=0;x<QUADW;x++)
|
||||
{
|
||||
p = 4*(y*QUADW + x);
|
||||
|
||||
/* first quad */
|
||||
quad[p+0] = y *GRIDW+x; /* some point */
|
||||
quad[p+1] = y *GRIDW+x+1; /* neighbor at the right side */
|
||||
quad[p+2] = (y+1)*GRIDW+x+1; /* upper right neighbor */
|
||||
quad[p+3] = (y+1)*GRIDW+x; /* upper neighbor */
|
||||
}
|
||||
}
|
||||
|
||||
double dt;
|
||||
double p[GRIDW][GRIDH];
|
||||
double vx[GRIDW][GRIDH], vy[GRIDW][GRIDH];
|
||||
double ax[GRIDW][GRIDH], ay[GRIDW][GRIDH];
|
||||
|
||||
|
||||
|
||||
void initSurface( void )
|
||||
{
|
||||
int x, y;
|
||||
double dx, dy, d;
|
||||
|
||||
for(y = 0; y<GRIDH; y++)
|
||||
{
|
||||
for(x = 0; x<GRIDW; x++)
|
||||
{
|
||||
dx = (double)(x-GRIDW/2);
|
||||
dy = (double)(y-GRIDH/2);
|
||||
d = sqrt( dx*dx + dy*dy );
|
||||
if(d < 0.1 * (double)(GRIDW/2))
|
||||
{
|
||||
d = d * 10.0;
|
||||
p[x][y] = -cos(d * (M_PI / (double)(GRIDW * 4))) * 100.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
p[x][y] = 0.0;
|
||||
}
|
||||
vx[x][y] = 0.0;
|
||||
vy[x][y] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Draw view */
|
||||
void draw_screen( void )
|
||||
{
|
||||
/* Clear the color and depth buffers. */
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
/* We don't want to modify the projection matrix. */
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
/* Move back. */
|
||||
glTranslatef(0.0, 0.0, -zoom);
|
||||
/* Rotate the view */
|
||||
glRotatef(beta, 1.0, 0.0, 0.0);
|
||||
glRotatef(alpha, 0.0, 0.0, 1.0);
|
||||
|
||||
//glDrawArrays(GL_POINTS,0,VERTEXNUM); /* Points only */
|
||||
glDrawElements(GL_QUADS, 4*QUADNUM, GL_UNSIGNED_INT, quad);
|
||||
//glDrawElements(GL_LINES, QUADNUM, GL_UNSIGNED_INT, quad);
|
||||
|
||||
glfwSwapBuffers();
|
||||
}
|
||||
|
||||
|
||||
/* Initialize OpenGL */
|
||||
void setup_opengl( void )
|
||||
{
|
||||
/* Our shading model--Gouraud (smooth). */
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
/* Culling. */
|
||||
//glCullFace(GL_BACK);
|
||||
//glFrontFace(GL_CCW);
|
||||
//glEnable(GL_CULL_FACE);
|
||||
|
||||
/* Switch on the z-buffer. */
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glVertexPointer(3/*3 components per vertex (x,y,z)*/, GL_FLOAT, sizeof(struct Vertex), vertex);
|
||||
glColorPointer(3/*3 components per vertex (r,g,b)*/, GL_FLOAT, sizeof(struct Vertex), &vertex[0].r); //Pointer to the first color
|
||||
glPointSize(2.0);
|
||||
|
||||
/* Background color is black. */
|
||||
glClearColor(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
/* Modify the height of each vertex according to the pressure. */
|
||||
void adjustGrid( void )
|
||||
{
|
||||
int pos;
|
||||
int x, y;
|
||||
|
||||
for(y = 0; y<GRIDH; y++)
|
||||
{
|
||||
for(x = 0; x<GRIDW; x++)
|
||||
{
|
||||
pos = y*GRIDW + x;
|
||||
vertex[pos].z = (float) (p[x][y]*(1.0/50.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Calculate wave propagation */
|
||||
void calc( void )
|
||||
{
|
||||
int x, y, x2, y2;
|
||||
double time_step = dt * ANIMATION_SPEED;
|
||||
|
||||
/* compute accelerations */
|
||||
for(x = 0; x < GRIDW; x++)
|
||||
{
|
||||
x2 = (x + 1) % GRIDW;
|
||||
for(y = 0; y < GRIDH; y++)
|
||||
{
|
||||
ax[x][y] = p[x][y] - p[x2][y];
|
||||
}
|
||||
}
|
||||
|
||||
for(y = 0; y < GRIDH;y++)
|
||||
{
|
||||
y2 = (y + 1) % GRIDH;
|
||||
for(x = 0; x < GRIDW; x++)
|
||||
{
|
||||
ay[x][y] = p[x][y] - p[x][y2];
|
||||
}
|
||||
}
|
||||
|
||||
/* compute speeds */
|
||||
for(x = 0; x < GRIDW; x++)
|
||||
{
|
||||
for(y = 0; y < GRIDH; y++)
|
||||
{
|
||||
vx[x][y] = vx[x][y] + ax[x][y] * time_step;
|
||||
vy[x][y] = vy[x][y] + ay[x][y] * time_step;
|
||||
}
|
||||
}
|
||||
|
||||
/* compute pressure */
|
||||
for(x = 1; x < GRIDW; x++)
|
||||
{
|
||||
x2 = x - 1;
|
||||
for(y = 1; y < GRIDH; y++)
|
||||
{
|
||||
y2 = y - 1;
|
||||
p[x][y] = p[x][y] + (vx[x2][y] - vx[x][y] + vy[x][y2] - vy[x][y]) * time_step;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Handle key strokes */
|
||||
void handle_key_down(int key, int action)
|
||||
{
|
||||
if( action != GLFW_PRESS )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch(key) {
|
||||
case GLFW_KEY_ESC:
|
||||
running = 0;
|
||||
break;
|
||||
case GLFW_KEY_SPACE:
|
||||
initSurface();
|
||||
break;
|
||||
case GLFW_KEY_LEFT:
|
||||
alpha+=5;
|
||||
break;
|
||||
case GLFW_KEY_RIGHT:
|
||||
alpha-=5;
|
||||
break;
|
||||
case GLFW_KEY_UP:
|
||||
beta-=5;
|
||||
break;
|
||||
case GLFW_KEY_DOWN:
|
||||
beta+=5;
|
||||
break;
|
||||
case GLFW_KEY_PAGEUP:
|
||||
if(zoom>1) zoom-=1;
|
||||
break;
|
||||
case GLFW_KEY_PAGEDOWN:
|
||||
zoom+=1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Callback function for window resize events */
|
||||
void handle_resize( int width, int height )
|
||||
{
|
||||
float ratio = 1.0f;
|
||||
|
||||
if( height > 0 )
|
||||
{
|
||||
ratio = (float) width / (float) height;
|
||||
}
|
||||
|
||||
/* Setup viewport (Place where the stuff will appear in the main window). */
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
/*
|
||||
* Change to the projection matrix and set
|
||||
* our viewing volume.
|
||||
*/
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(60.0, ratio, 1.0, 1024.0);
|
||||
}
|
||||
|
||||
|
||||
/* Program entry point */
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
/* Dimensions of our window. */
|
||||
int width, height;
|
||||
/* Style of our window. */
|
||||
int mode;
|
||||
/* Frame time */
|
||||
double t, t_old, dt_total;
|
||||
|
||||
/* Initialize GLFW */
|
||||
if(glfwInit() == GL_FALSE)
|
||||
{
|
||||
fprintf(stderr, "GLFW initialization failed\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* Desired window properties */
|
||||
width = 640;
|
||||
height = 480;
|
||||
mode = GLFW_WINDOW;
|
||||
|
||||
/* Open window */
|
||||
if( glfwOpenWindow(width,height,0,0,0,0,16,0,mode) == GL_FALSE )
|
||||
{
|
||||
fprintf(stderr, "Could not open window\n");
|
||||
glfwTerminate();
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* Set title */
|
||||
glfwSetWindowTitle( "Wave Simulation" );
|
||||
|
||||
glfwSwapInterval( 1 );
|
||||
|
||||
/* Keyboard handler */
|
||||
glfwSetKeyCallback( handle_key_down );
|
||||
glfwEnable( GLFW_KEY_REPEAT );
|
||||
|
||||
/* Window resize handler */
|
||||
glfwSetWindowSizeCallback( handle_resize );
|
||||
|
||||
/* Initialize OpenGL */
|
||||
setup_opengl();
|
||||
|
||||
/* Initialize simulation */
|
||||
initVertices();
|
||||
initSurface();
|
||||
adjustGrid();
|
||||
|
||||
/* Initialize timer */
|
||||
t_old = glfwGetTime() - 0.01;
|
||||
|
||||
/* Main loop */
|
||||
while(running)
|
||||
{
|
||||
/* Timing */
|
||||
t = glfwGetTime();
|
||||
dt_total = t - t_old;
|
||||
t_old = t;
|
||||
|
||||
/* Safety - iterate if dt_total is too large */
|
||||
while( dt_total > 0.0f )
|
||||
{
|
||||
/* Select iteration time step */
|
||||
dt = dt_total > MAX_DELTA_T ? MAX_DELTA_T : dt_total;
|
||||
dt_total -= dt;
|
||||
|
||||
/* Calculate wave propagation */
|
||||
calc();
|
||||
}
|
||||
|
||||
/* Compute height of each vertex */
|
||||
adjustGrid();
|
||||
|
||||
/* Draw wave grid to OpenGL display */
|
||||
draw_screen();
|
||||
|
||||
/* Still running? */
|
||||
running = running && glfwGetWindowParam( GLFW_OPENED );
|
||||
}
|
||||
|
||||
glfwTerminate();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user