Squashed 'deps/nostalgia/' content from commit 9cb6bd4a
git-subtree-dir: deps/nostalgia git-subtree-split: 9cb6bd4a32e9f39a858f72443ff5c6d40489fe22
This commit is contained in:
93
deps/glfw/examples/CMakeLists.txt
vendored
Normal file
93
deps/glfw/examples/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
|
||||
link_libraries(glfw)
|
||||
|
||||
include_directories("${GLFW_SOURCE_DIR}/deps")
|
||||
|
||||
if (MATH_LIBRARY)
|
||||
link_libraries("${MATH_LIBRARY}")
|
||||
endif()
|
||||
|
||||
# Workaround for the MS CRT deprecating parts of the standard library
|
||||
if (MSVC OR CMAKE_C_SIMULATE_ID STREQUAL "MSVC")
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
set(ICON glfw.rc)
|
||||
elseif (APPLE)
|
||||
set(ICON glfw.icns)
|
||||
endif()
|
||||
|
||||
if (${CMAKE_VERSION} VERSION_EQUAL "3.1.0" OR
|
||||
${CMAKE_VERSION} VERSION_GREATER "3.1.0")
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
else()
|
||||
# Remove this fallback when removing support for CMake version less than 3.1
|
||||
add_compile_options("$<$<C_COMPILER_ID:AppleClang>:-std=c99>"
|
||||
"$<$<C_COMPILER_ID:Clang>:-std=c99>"
|
||||
"$<$<C_COMPILER_ID:GNU>:-std=c99>")
|
||||
|
||||
endif()
|
||||
|
||||
set(GLAD_GL "${GLFW_SOURCE_DIR}/deps/glad/gl.h"
|
||||
"${GLFW_SOURCE_DIR}/deps/glad_gl.c")
|
||||
set(GETOPT "${GLFW_SOURCE_DIR}/deps/getopt.h"
|
||||
"${GLFW_SOURCE_DIR}/deps/getopt.c")
|
||||
set(TINYCTHREAD "${GLFW_SOURCE_DIR}/deps/tinycthread.h"
|
||||
"${GLFW_SOURCE_DIR}/deps/tinycthread.c")
|
||||
|
||||
add_executable(boing WIN32 MACOSX_BUNDLE boing.c ${ICON} ${GLAD_GL})
|
||||
add_executable(gears WIN32 MACOSX_BUNDLE gears.c ${ICON} ${GLAD_GL})
|
||||
add_executable(heightmap WIN32 MACOSX_BUNDLE heightmap.c ${ICON} ${GLAD_GL})
|
||||
add_executable(offscreen offscreen.c ${ICON} ${GLAD_GL})
|
||||
add_executable(particles WIN32 MACOSX_BUNDLE particles.c ${ICON} ${TINYCTHREAD} ${GETOPT} ${GLAD_GL})
|
||||
add_executable(sharing WIN32 MACOSX_BUNDLE sharing.c ${ICON} ${GLAD_GL})
|
||||
add_executable(simple WIN32 MACOSX_BUNDLE simple.c ${ICON} ${GLAD_GL})
|
||||
add_executable(splitview WIN32 MACOSX_BUNDLE splitview.c ${ICON} ${GLAD_GL})
|
||||
add_executable(wave WIN32 MACOSX_BUNDLE wave.c ${ICON} ${GLAD_GL})
|
||||
|
||||
target_link_libraries(particles "${CMAKE_THREAD_LIBS_INIT}")
|
||||
if (RT_LIBRARY)
|
||||
target_link_libraries(particles "${RT_LIBRARY}")
|
||||
endif()
|
||||
|
||||
set(GUI_ONLY_BINARIES boing gears heightmap particles sharing simple splitview
|
||||
wave)
|
||||
set(CONSOLE_BINARIES offscreen)
|
||||
|
||||
set_target_properties(${GUI_ONLY_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
|
||||
FOLDER "GLFW3/Examples")
|
||||
|
||||
if (GLFW_USE_OSMESA)
|
||||
target_compile_definitions(offscreen PRIVATE USE_NATIVE_OSMESA)
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
# Tell MSVC to use main instead of WinMain
|
||||
set_target_properties(${GUI_ONLY_BINARIES} PROPERTIES
|
||||
LINK_FLAGS "/ENTRY:mainCRTStartup")
|
||||
elseif (CMAKE_C_SIMULATE_ID STREQUAL "MSVC")
|
||||
# Tell Clang using MS CRT to use main instead of WinMain
|
||||
set_target_properties(${GUI_ONLY_BINARIES} PROPERTIES
|
||||
LINK_FLAGS "-Wl,/entry:mainCRTStartup")
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
set_target_properties(boing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Boing")
|
||||
set_target_properties(gears PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Gears")
|
||||
set_target_properties(heightmap PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Heightmap")
|
||||
set_target_properties(particles PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Particles")
|
||||
set_target_properties(sharing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Sharing")
|
||||
set_target_properties(simple PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Simple")
|
||||
set_target_properties(splitview PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "SplitView")
|
||||
set_target_properties(wave PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Wave")
|
||||
|
||||
set_source_files_properties(glfw.icns PROPERTIES
|
||||
MACOSX_PACKAGE_LOCATION "Resources")
|
||||
set_target_properties(${GUI_ONLY_BINARIES} PROPERTIES
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION}
|
||||
MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION}
|
||||
MACOSX_BUNDLE_ICON_FILE glfw.icns
|
||||
MACOSX_BUNDLE_INFO_PLIST "${GLFW_SOURCE_DIR}/CMake/MacOSXBundleInfo.plist.in")
|
||||
endif()
|
||||
|
679
deps/glfw/examples/boing.c
vendored
Normal file
679
deps/glfw/examples/boing.c
vendored
Normal file
@ -0,0 +1,679 @@
|
||||
/*****************************************************************************
|
||||
* Title: GLBoing
|
||||
* Desc: Tribute to Amiga Boing.
|
||||
* Author: Jim Brooks <gfx@jimbrooks.org>
|
||||
* Original Amiga authors were R.J. Mical and Dale Luck.
|
||||
* GLFW conversion by Marcus Geelnard
|
||||
* Notes: - 360' = 2*PI [radian]
|
||||
*
|
||||
* - Distances between objects are created by doing a relative
|
||||
* Z translations.
|
||||
*
|
||||
* - Although OpenGL enticingly supports alpha-blending,
|
||||
* the shadow of the original Boing didn't affect the color
|
||||
* of the grid.
|
||||
*
|
||||
* - [Marcus] Changed timing scheme from interval driven to frame-
|
||||
* time based animation steps (which results in much smoother
|
||||
* movement)
|
||||
*
|
||||
* History of Amiga Boing:
|
||||
*
|
||||
* Boing was demonstrated on the prototype Amiga (codenamed "Lorraine") in
|
||||
* 1985. According to legend, it was written ad-hoc in one night by
|
||||
* R. J. Mical and Dale Luck. Because the bouncing ball animation was so fast
|
||||
* and smooth, attendees did not believe the Amiga prototype was really doing
|
||||
* the rendering. Suspecting a trick, they began looking around the booth for
|
||||
* a hidden computer or VCR.
|
||||
*****************************************************************************/
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// Make MS math.h define M_PI
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <glad/gl.h>
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <linmath.h>
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Various declarations and macros
|
||||
*****************************************************************************/
|
||||
|
||||
/* Prototypes */
|
||||
void init( void );
|
||||
void display( void );
|
||||
void reshape( GLFWwindow* window, int w, int h );
|
||||
void key_callback( GLFWwindow* window, int key, int scancode, int action, int mods );
|
||||
void mouse_button_callback( GLFWwindow* window, int button, int action, int mods );
|
||||
void cursor_position_callback( GLFWwindow* window, double x, double y );
|
||||
void DrawBoingBall( void );
|
||||
void BounceBall( double dt );
|
||||
void DrawBoingBallBand( GLfloat long_lo, GLfloat long_hi );
|
||||
void DrawGrid( void );
|
||||
|
||||
#define RADIUS 70.f
|
||||
#define STEP_LONGITUDE 22.5f /* 22.5 makes 8 bands like original Boing */
|
||||
#define STEP_LATITUDE 22.5f
|
||||
|
||||
#define DIST_BALL (RADIUS * 2.f + RADIUS * 0.1f)
|
||||
|
||||
#define VIEW_SCENE_DIST (DIST_BALL * 3.f + 200.f)/* distance from viewer to middle of boing area */
|
||||
#define GRID_SIZE (RADIUS * 4.5f) /* length (width) of grid */
|
||||
#define BOUNCE_HEIGHT (RADIUS * 2.1f)
|
||||
#define BOUNCE_WIDTH (RADIUS * 2.1f)
|
||||
|
||||
#define SHADOW_OFFSET_X -20.f
|
||||
#define SHADOW_OFFSET_Y 10.f
|
||||
#define SHADOW_OFFSET_Z 0.f
|
||||
|
||||
#define WALL_L_OFFSET 0.f
|
||||
#define WALL_R_OFFSET 5.f
|
||||
|
||||
/* Animation speed (50.0 mimics the original GLUT demo speed) */
|
||||
#define ANIMATION_SPEED 50.f
|
||||
|
||||
/* Maximum allowed delta time per physics iteration */
|
||||
#define MAX_DELTA_T 0.02f
|
||||
|
||||
/* Draw ball, or its shadow */
|
||||
typedef enum { DRAW_BALL, DRAW_BALL_SHADOW } DRAW_BALL_ENUM;
|
||||
|
||||
/* Vertex type */
|
||||
typedef struct {float x; float y; float z;} vertex_t;
|
||||
|
||||
/* Global vars */
|
||||
int windowed_xpos, windowed_ypos, windowed_width, windowed_height;
|
||||
int width, height;
|
||||
GLfloat deg_rot_y = 0.f;
|
||||
GLfloat deg_rot_y_inc = 2.f;
|
||||
int override_pos = GLFW_FALSE;
|
||||
GLfloat cursor_x = 0.f;
|
||||
GLfloat cursor_y = 0.f;
|
||||
GLfloat ball_x = -RADIUS;
|
||||
GLfloat ball_y = -RADIUS;
|
||||
GLfloat ball_x_inc = 1.f;
|
||||
GLfloat ball_y_inc = 2.f;
|
||||
DRAW_BALL_ENUM drawBallHow;
|
||||
double t;
|
||||
double t_old = 0.f;
|
||||
double dt;
|
||||
|
||||
/* Random number generator */
|
||||
#ifndef RAND_MAX
|
||||
#define RAND_MAX 4095
|
||||
#endif
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Truncate a degree.
|
||||
*****************************************************************************/
|
||||
GLfloat TruncateDeg( GLfloat deg )
|
||||
{
|
||||
if ( deg >= 360.f )
|
||||
return (deg - 360.f);
|
||||
else
|
||||
return deg;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Convert a degree (360-based) into a radian.
|
||||
* 360' = 2 * PI
|
||||
*****************************************************************************/
|
||||
double deg2rad( double deg )
|
||||
{
|
||||
return deg / 360 * (2 * M_PI);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* 360' sin().
|
||||
*****************************************************************************/
|
||||
double sin_deg( double deg )
|
||||
{
|
||||
return sin( deg2rad( deg ) );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* 360' cos().
|
||||
*****************************************************************************/
|
||||
double cos_deg( double deg )
|
||||
{
|
||||
return cos( deg2rad( deg ) );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Compute a cross product (for a normal vector).
|
||||
*
|
||||
* c = a x b
|
||||
*****************************************************************************/
|
||||
void CrossProduct( vertex_t a, vertex_t b, vertex_t c, vertex_t *n )
|
||||
{
|
||||
GLfloat u1, u2, u3;
|
||||
GLfloat v1, v2, v3;
|
||||
|
||||
u1 = b.x - a.x;
|
||||
u2 = b.y - a.y;
|
||||
u3 = b.y - a.z;
|
||||
|
||||
v1 = c.x - a.x;
|
||||
v2 = c.y - a.y;
|
||||
v3 = c.z - a.z;
|
||||
|
||||
n->x = u2 * v3 - v2 * u3;
|
||||
n->y = u3 * v1 - v3 * u1;
|
||||
n->z = u1 * v2 - v1 * u2;
|
||||
}
|
||||
|
||||
|
||||
#define BOING_DEBUG 0
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* init()
|
||||
*****************************************************************************/
|
||||
void init( void )
|
||||
{
|
||||
/*
|
||||
* Clear background.
|
||||
*/
|
||||
glClearColor( 0.55f, 0.55f, 0.55f, 0.f );
|
||||
|
||||
glShadeModel( GL_FLAT );
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* display()
|
||||
*****************************************************************************/
|
||||
void display(void)
|
||||
{
|
||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||
glPushMatrix();
|
||||
|
||||
drawBallHow = DRAW_BALL_SHADOW;
|
||||
DrawBoingBall();
|
||||
|
||||
DrawGrid();
|
||||
|
||||
drawBallHow = DRAW_BALL;
|
||||
DrawBoingBall();
|
||||
|
||||
glPopMatrix();
|
||||
glFlush();
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* reshape()
|
||||
*****************************************************************************/
|
||||
void reshape( GLFWwindow* window, int w, int h )
|
||||
{
|
||||
mat4x4 projection, view;
|
||||
|
||||
glViewport( 0, 0, (GLsizei)w, (GLsizei)h );
|
||||
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
mat4x4_perspective( projection,
|
||||
2.f * (float) atan2( RADIUS, 200.f ),
|
||||
(float)w / (float)h,
|
||||
1.f, VIEW_SCENE_DIST );
|
||||
glLoadMatrixf((const GLfloat*) projection);
|
||||
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
{
|
||||
vec3 eye = { 0.f, 0.f, VIEW_SCENE_DIST };
|
||||
vec3 center = { 0.f, 0.f, 0.f };
|
||||
vec3 up = { 0.f, -1.f, 0.f };
|
||||
mat4x4_look_at( view, eye, center, up );
|
||||
}
|
||||
glLoadMatrixf((const GLfloat*) view);
|
||||
}
|
||||
|
||||
void key_callback( GLFWwindow* window, int key, int scancode, int action, int mods )
|
||||
{
|
||||
if (action != GLFW_PRESS)
|
||||
return;
|
||||
|
||||
if (key == GLFW_KEY_ESCAPE && mods == 0)
|
||||
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
||||
if ((key == GLFW_KEY_ENTER && mods == GLFW_MOD_ALT) ||
|
||||
(key == GLFW_KEY_F11 && mods == GLFW_MOD_ALT))
|
||||
{
|
||||
if (glfwGetWindowMonitor(window))
|
||||
{
|
||||
glfwSetWindowMonitor(window, NULL,
|
||||
windowed_xpos, windowed_ypos,
|
||||
windowed_width, windowed_height, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
||||
if (monitor)
|
||||
{
|
||||
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
|
||||
glfwGetWindowPos(window, &windowed_xpos, &windowed_ypos);
|
||||
glfwGetWindowSize(window, &windowed_width, &windowed_height);
|
||||
glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void set_ball_pos ( GLfloat x, GLfloat y )
|
||||
{
|
||||
ball_x = (width / 2) - x;
|
||||
ball_y = y - (height / 2);
|
||||
}
|
||||
|
||||
void mouse_button_callback( GLFWwindow* window, int button, int action, int mods )
|
||||
{
|
||||
if (button != GLFW_MOUSE_BUTTON_LEFT)
|
||||
return;
|
||||
|
||||
if (action == GLFW_PRESS)
|
||||
{
|
||||
override_pos = GLFW_TRUE;
|
||||
set_ball_pos(cursor_x, cursor_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
override_pos = GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void cursor_position_callback( GLFWwindow* window, double x, double y )
|
||||
{
|
||||
cursor_x = (float) x;
|
||||
cursor_y = (float) y;
|
||||
|
||||
if ( override_pos )
|
||||
set_ball_pos(cursor_x, cursor_y);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Draw the Boing ball.
|
||||
*
|
||||
* The Boing ball is sphere in which each facet is a rectangle.
|
||||
* Facet colors alternate between red and white.
|
||||
* The ball is built by stacking latitudinal circles. Each circle is composed
|
||||
* of a widely-separated set of points, so that each facet is noticeably large.
|
||||
*****************************************************************************/
|
||||
void DrawBoingBall( void )
|
||||
{
|
||||
GLfloat lon_deg; /* degree of longitude */
|
||||
double dt_total, dt2;
|
||||
|
||||
glPushMatrix();
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
|
||||
/*
|
||||
* Another relative Z translation to separate objects.
|
||||
*/
|
||||
glTranslatef( 0.0, 0.0, DIST_BALL );
|
||||
|
||||
/* Update ball position and rotation (iterate if necessary) */
|
||||
dt_total = dt;
|
||||
while( dt_total > 0.0 )
|
||||
{
|
||||
dt2 = dt_total > MAX_DELTA_T ? MAX_DELTA_T : dt_total;
|
||||
dt_total -= dt2;
|
||||
BounceBall( dt2 );
|
||||
deg_rot_y = TruncateDeg( deg_rot_y + deg_rot_y_inc*((float)dt2*ANIMATION_SPEED) );
|
||||
}
|
||||
|
||||
/* Set ball position */
|
||||
glTranslatef( ball_x, ball_y, 0.0 );
|
||||
|
||||
/*
|
||||
* Offset the shadow.
|
||||
*/
|
||||
if ( drawBallHow == DRAW_BALL_SHADOW )
|
||||
{
|
||||
glTranslatef( SHADOW_OFFSET_X,
|
||||
SHADOW_OFFSET_Y,
|
||||
SHADOW_OFFSET_Z );
|
||||
}
|
||||
|
||||
/*
|
||||
* Tilt the ball.
|
||||
*/
|
||||
glRotatef( -20.0, 0.0, 0.0, 1.0 );
|
||||
|
||||
/*
|
||||
* Continually rotate ball around Y axis.
|
||||
*/
|
||||
glRotatef( deg_rot_y, 0.0, 1.0, 0.0 );
|
||||
|
||||
/*
|
||||
* Set OpenGL state for Boing ball.
|
||||
*/
|
||||
glCullFace( GL_FRONT );
|
||||
glEnable( GL_CULL_FACE );
|
||||
glEnable( GL_NORMALIZE );
|
||||
|
||||
/*
|
||||
* Build a faceted latitude slice of the Boing ball,
|
||||
* stepping same-sized vertical bands of the sphere.
|
||||
*/
|
||||
for ( lon_deg = 0;
|
||||
lon_deg < 180;
|
||||
lon_deg += STEP_LONGITUDE )
|
||||
{
|
||||
/*
|
||||
* Draw a latitude circle at this longitude.
|
||||
*/
|
||||
DrawBoingBallBand( lon_deg,
|
||||
lon_deg + STEP_LONGITUDE );
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Bounce the ball.
|
||||
*****************************************************************************/
|
||||
void BounceBall( double delta_t )
|
||||
{
|
||||
GLfloat sign;
|
||||
GLfloat deg;
|
||||
|
||||
if ( override_pos )
|
||||
return;
|
||||
|
||||
/* Bounce on walls */
|
||||
if ( ball_x > (BOUNCE_WIDTH/2 + WALL_R_OFFSET ) )
|
||||
{
|
||||
ball_x_inc = -0.5f - 0.75f * (GLfloat)rand() / (GLfloat)RAND_MAX;
|
||||
deg_rot_y_inc = -deg_rot_y_inc;
|
||||
}
|
||||
if ( ball_x < -(BOUNCE_HEIGHT/2 + WALL_L_OFFSET) )
|
||||
{
|
||||
ball_x_inc = 0.5f + 0.75f * (GLfloat)rand() / (GLfloat)RAND_MAX;
|
||||
deg_rot_y_inc = -deg_rot_y_inc;
|
||||
}
|
||||
|
||||
/* Bounce on floor / roof */
|
||||
if ( ball_y > BOUNCE_HEIGHT/2 )
|
||||
{
|
||||
ball_y_inc = -0.75f - 1.f * (GLfloat)rand() / (GLfloat)RAND_MAX;
|
||||
}
|
||||
if ( ball_y < -BOUNCE_HEIGHT/2*0.85 )
|
||||
{
|
||||
ball_y_inc = 0.75f + 1.f * (GLfloat)rand() / (GLfloat)RAND_MAX;
|
||||
}
|
||||
|
||||
/* Update ball position */
|
||||
ball_x += ball_x_inc * ((float)delta_t*ANIMATION_SPEED);
|
||||
ball_y += ball_y_inc * ((float)delta_t*ANIMATION_SPEED);
|
||||
|
||||
/*
|
||||
* Simulate the effects of gravity on Y movement.
|
||||
*/
|
||||
if ( ball_y_inc < 0 ) sign = -1.0; else sign = 1.0;
|
||||
|
||||
deg = (ball_y + BOUNCE_HEIGHT/2) * 90 / BOUNCE_HEIGHT;
|
||||
if ( deg > 80 ) deg = 80;
|
||||
if ( deg < 10 ) deg = 10;
|
||||
|
||||
ball_y_inc = sign * 4.f * (float) sin_deg( deg );
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Draw a faceted latitude band of the Boing ball.
|
||||
*
|
||||
* Parms: long_lo, long_hi
|
||||
* Low and high longitudes of slice, resp.
|
||||
*****************************************************************************/
|
||||
void DrawBoingBallBand( GLfloat long_lo,
|
||||
GLfloat long_hi )
|
||||
{
|
||||
vertex_t vert_ne; /* "ne" means south-east, so on */
|
||||
vertex_t vert_nw;
|
||||
vertex_t vert_sw;
|
||||
vertex_t vert_se;
|
||||
vertex_t vert_norm;
|
||||
GLfloat lat_deg;
|
||||
static int colorToggle = 0;
|
||||
|
||||
/*
|
||||
* Iterate through the points of a latitude circle.
|
||||
* A latitude circle is a 2D set of X,Z points.
|
||||
*/
|
||||
for ( lat_deg = 0;
|
||||
lat_deg <= (360 - STEP_LATITUDE);
|
||||
lat_deg += STEP_LATITUDE )
|
||||
{
|
||||
/*
|
||||
* Color this polygon with red or white.
|
||||
*/
|
||||
if ( colorToggle )
|
||||
glColor3f( 0.8f, 0.1f, 0.1f );
|
||||
else
|
||||
glColor3f( 0.95f, 0.95f, 0.95f );
|
||||
#if 0
|
||||
if ( lat_deg >= 180 )
|
||||
if ( colorToggle )
|
||||
glColor3f( 0.1f, 0.8f, 0.1f );
|
||||
else
|
||||
glColor3f( 0.5f, 0.5f, 0.95f );
|
||||
#endif
|
||||
colorToggle = ! colorToggle;
|
||||
|
||||
/*
|
||||
* Change color if drawing shadow.
|
||||
*/
|
||||
if ( drawBallHow == DRAW_BALL_SHADOW )
|
||||
glColor3f( 0.35f, 0.35f, 0.35f );
|
||||
|
||||
/*
|
||||
* Assign each Y.
|
||||
*/
|
||||
vert_ne.y = vert_nw.y = (float) cos_deg(long_hi) * RADIUS;
|
||||
vert_sw.y = vert_se.y = (float) cos_deg(long_lo) * RADIUS;
|
||||
|
||||
/*
|
||||
* Assign each X,Z with sin,cos values scaled by latitude radius indexed by longitude.
|
||||
* Eg, long=0 and long=180 are at the poles, so zero scale is sin(longitude),
|
||||
* while long=90 (sin(90)=1) is at equator.
|
||||
*/
|
||||
vert_ne.x = (float) cos_deg( lat_deg ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE ));
|
||||
vert_se.x = (float) cos_deg( lat_deg ) * (RADIUS * (float) sin_deg( long_lo ));
|
||||
vert_nw.x = (float) cos_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE ));
|
||||
vert_sw.x = (float) cos_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo ));
|
||||
|
||||
vert_ne.z = (float) sin_deg( lat_deg ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE ));
|
||||
vert_se.z = (float) sin_deg( lat_deg ) * (RADIUS * (float) sin_deg( long_lo ));
|
||||
vert_nw.z = (float) sin_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE ));
|
||||
vert_sw.z = (float) sin_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo ));
|
||||
|
||||
/*
|
||||
* Draw the facet.
|
||||
*/
|
||||
glBegin( GL_POLYGON );
|
||||
|
||||
CrossProduct( vert_ne, vert_nw, vert_sw, &vert_norm );
|
||||
glNormal3f( vert_norm.x, vert_norm.y, vert_norm.z );
|
||||
|
||||
glVertex3f( vert_ne.x, vert_ne.y, vert_ne.z );
|
||||
glVertex3f( vert_nw.x, vert_nw.y, vert_nw.z );
|
||||
glVertex3f( vert_sw.x, vert_sw.y, vert_sw.z );
|
||||
glVertex3f( vert_se.x, vert_se.y, vert_se.z );
|
||||
|
||||
glEnd();
|
||||
|
||||
#if BOING_DEBUG
|
||||
printf( "----------------------------------------------------------- \n" );
|
||||
printf( "lat = %f long_lo = %f long_hi = %f \n", lat_deg, long_lo, long_hi );
|
||||
printf( "vert_ne x = %.8f y = %.8f z = %.8f \n", vert_ne.x, vert_ne.y, vert_ne.z );
|
||||
printf( "vert_nw x = %.8f y = %.8f z = %.8f \n", vert_nw.x, vert_nw.y, vert_nw.z );
|
||||
printf( "vert_se x = %.8f y = %.8f z = %.8f \n", vert_se.x, vert_se.y, vert_se.z );
|
||||
printf( "vert_sw x = %.8f y = %.8f z = %.8f \n", vert_sw.x, vert_sw.y, vert_sw.z );
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Toggle color so that next band will opposite red/white colors than this one.
|
||||
*/
|
||||
colorToggle = ! colorToggle;
|
||||
|
||||
/*
|
||||
* This circular band is done.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Draw the purple grid of lines, behind the Boing ball.
|
||||
* When the Workbench is dropped to the bottom, Boing shows 12 rows.
|
||||
*****************************************************************************/
|
||||
void DrawGrid( void )
|
||||
{
|
||||
int row, col;
|
||||
const int rowTotal = 12; /* must be divisible by 2 */
|
||||
const int colTotal = rowTotal; /* must be same as rowTotal */
|
||||
const GLfloat widthLine = 2.0; /* should be divisible by 2 */
|
||||
const GLfloat sizeCell = GRID_SIZE / rowTotal;
|
||||
const GLfloat z_offset = -40.0;
|
||||
GLfloat xl, xr;
|
||||
GLfloat yt, yb;
|
||||
|
||||
glPushMatrix();
|
||||
glDisable( GL_CULL_FACE );
|
||||
|
||||
/*
|
||||
* Another relative Z translation to separate objects.
|
||||
*/
|
||||
glTranslatef( 0.0, 0.0, DIST_BALL );
|
||||
|
||||
/*
|
||||
* Draw vertical lines (as skinny 3D rectangles).
|
||||
*/
|
||||
for ( col = 0; col <= colTotal; col++ )
|
||||
{
|
||||
/*
|
||||
* Compute co-ords of line.
|
||||
*/
|
||||
xl = -GRID_SIZE / 2 + col * sizeCell;
|
||||
xr = xl + widthLine;
|
||||
|
||||
yt = GRID_SIZE / 2;
|
||||
yb = -GRID_SIZE / 2 - widthLine;
|
||||
|
||||
glBegin( GL_POLYGON );
|
||||
|
||||
glColor3f( 0.6f, 0.1f, 0.6f ); /* purple */
|
||||
|
||||
glVertex3f( xr, yt, z_offset ); /* NE */
|
||||
glVertex3f( xl, yt, z_offset ); /* NW */
|
||||
glVertex3f( xl, yb, z_offset ); /* SW */
|
||||
glVertex3f( xr, yb, z_offset ); /* SE */
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw horizontal lines (as skinny 3D rectangles).
|
||||
*/
|
||||
for ( row = 0; row <= rowTotal; row++ )
|
||||
{
|
||||
/*
|
||||
* Compute co-ords of line.
|
||||
*/
|
||||
yt = GRID_SIZE / 2 - row * sizeCell;
|
||||
yb = yt - widthLine;
|
||||
|
||||
xl = -GRID_SIZE / 2;
|
||||
xr = GRID_SIZE / 2 + widthLine;
|
||||
|
||||
glBegin( GL_POLYGON );
|
||||
|
||||
glColor3f( 0.6f, 0.1f, 0.6f ); /* purple */
|
||||
|
||||
glVertex3f( xr, yt, z_offset ); /* NE */
|
||||
glVertex3f( xl, yt, z_offset ); /* NW */
|
||||
glVertex3f( xl, yb, z_offset ); /* SW */
|
||||
glVertex3f( xr, yb, z_offset ); /* SE */
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*======================================================================*
|
||||
* main()
|
||||
*======================================================================*/
|
||||
|
||||
int main( void )
|
||||
{
|
||||
GLFWwindow* window;
|
||||
|
||||
/* Init GLFW */
|
||||
if( !glfwInit() )
|
||||
exit( EXIT_FAILURE );
|
||||
|
||||
window = glfwCreateWindow( 400, 400, "Boing (classic Amiga demo)", NULL, NULL );
|
||||
if (!window)
|
||||
{
|
||||
glfwTerminate();
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
glfwSetWindowAspectRatio(window, 1, 1);
|
||||
|
||||
glfwSetFramebufferSizeCallback(window, reshape);
|
||||
glfwSetKeyCallback(window, key_callback);
|
||||
glfwSetMouseButtonCallback(window, mouse_button_callback);
|
||||
glfwSetCursorPosCallback(window, cursor_position_callback);
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
gladLoadGL(glfwGetProcAddress);
|
||||
glfwSwapInterval( 1 );
|
||||
|
||||
glfwGetFramebufferSize(window, &width, &height);
|
||||
reshape(window, width, height);
|
||||
|
||||
glfwSetTime( 0.0 );
|
||||
|
||||
init();
|
||||
|
||||
/* Main loop */
|
||||
for (;;)
|
||||
{
|
||||
/* Timing */
|
||||
t = glfwGetTime();
|
||||
dt = t - t_old;
|
||||
t_old = t;
|
||||
|
||||
/* Draw one frame */
|
||||
display();
|
||||
|
||||
/* Swap buffers */
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
|
||||
/* Check if we are still running */
|
||||
if (glfwWindowShouldClose(window))
|
||||
break;
|
||||
}
|
||||
|
||||
glfwTerminate();
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
360
deps/glfw/examples/gears.c
vendored
Normal file
360
deps/glfw/examples/gears.c
vendored
Normal file
@ -0,0 +1,360 @@
|
||||
/*
|
||||
* 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 Löwy:
|
||||
* - Removed FPS counter (this is not a benchmark)
|
||||
* - Added a few comments
|
||||
* - Enabled vsync
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// Make MS math.h define M_PI
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glad/gl.h>
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
/**
|
||||
|
||||
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)
|
||||
{
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
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( GLFWwindow* window, int k, int s, int action, int mods )
|
||||
{
|
||||
if( action != GLFW_PRESS ) return;
|
||||
|
||||
switch (k) {
|
||||
case GLFW_KEY_Z:
|
||||
if( mods & GLFW_MOD_SHIFT )
|
||||
view_rotz -= 5.0;
|
||||
else
|
||||
view_rotz += 5.0;
|
||||
break;
|
||||
case GLFW_KEY_ESCAPE:
|
||||
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
||||
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( GLFWwindow* window, 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(void)
|
||||
{
|
||||
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};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/* program entry */
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
GLFWwindow* window;
|
||||
int width, height;
|
||||
|
||||
if( !glfwInit() )
|
||||
{
|
||||
fprintf( stderr, "Failed to initialize GLFW\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
glfwWindowHint(GLFW_DEPTH_BITS, 16);
|
||||
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE);
|
||||
|
||||
window = glfwCreateWindow( 300, 300, "Gears", NULL, NULL );
|
||||
if (!window)
|
||||
{
|
||||
fprintf( stderr, "Failed to open GLFW window\n" );
|
||||
glfwTerminate();
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
// Set callback functions
|
||||
glfwSetFramebufferSizeCallback(window, reshape);
|
||||
glfwSetKeyCallback(window, key);
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
gladLoadGL(glfwGetProcAddress);
|
||||
glfwSwapInterval( 1 );
|
||||
|
||||
glfwGetFramebufferSize(window, &width, &height);
|
||||
reshape(window, width, height);
|
||||
|
||||
// Parse command-line options
|
||||
init();
|
||||
|
||||
// Main loop
|
||||
while( !glfwWindowShouldClose(window) )
|
||||
{
|
||||
// Draw gears
|
||||
draw();
|
||||
|
||||
// Update animation
|
||||
animate();
|
||||
|
||||
// Swap buffers
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
// Terminate GLFW
|
||||
glfwTerminate();
|
||||
|
||||
// Exit program
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
BIN
deps/glfw/examples/glfw.icns
vendored
Normal file
BIN
deps/glfw/examples/glfw.icns
vendored
Normal file
Binary file not shown.
BIN
deps/glfw/examples/glfw.ico
vendored
Normal file
BIN
deps/glfw/examples/glfw.ico
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
3
deps/glfw/examples/glfw.rc
vendored
Normal file
3
deps/glfw/examples/glfw.rc
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
GLFW_ICON ICON "glfw.ico"
|
||||
|
512
deps/glfw/examples/heightmap.c
vendored
Normal file
512
deps/glfw/examples/heightmap.c
vendored
Normal file
@ -0,0 +1,512 @@
|
||||
//========================================================================
|
||||
// Heightmap example program using OpenGL 3 core profile
|
||||
// Copyright (c) 2010 Olivier Delannoy
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <glad/gl.h>
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
/* Map height updates */
|
||||
#define MAX_CIRCLE_SIZE (5.0f)
|
||||
#define MAX_DISPLACEMENT (1.0f)
|
||||
#define DISPLACEMENT_SIGN_LIMIT (0.3f)
|
||||
#define MAX_ITER (200)
|
||||
#define NUM_ITER_AT_A_TIME (1)
|
||||
|
||||
/* Map general information */
|
||||
#define MAP_SIZE (10.0f)
|
||||
#define MAP_NUM_VERTICES (80)
|
||||
#define MAP_NUM_TOTAL_VERTICES (MAP_NUM_VERTICES*MAP_NUM_VERTICES)
|
||||
#define MAP_NUM_LINES (3* (MAP_NUM_VERTICES - 1) * (MAP_NUM_VERTICES - 1) + \
|
||||
2 * (MAP_NUM_VERTICES - 1))
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Default shader programs
|
||||
*********************************************************************/
|
||||
|
||||
static const char* vertex_shader_text =
|
||||
"#version 150\n"
|
||||
"uniform mat4 project;\n"
|
||||
"uniform mat4 modelview;\n"
|
||||
"in float x;\n"
|
||||
"in float y;\n"
|
||||
"in float z;\n"
|
||||
"\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = project * modelview * vec4(x, y, z, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* fragment_shader_text =
|
||||
"#version 150\n"
|
||||
"out vec4 color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" color = vec4(0.2, 1.0, 0.2, 1.0); \n"
|
||||
"}\n";
|
||||
|
||||
/**********************************************************************
|
||||
* Values for shader uniforms
|
||||
*********************************************************************/
|
||||
|
||||
/* Frustum configuration */
|
||||
static GLfloat view_angle = 45.0f;
|
||||
static GLfloat aspect_ratio = 4.0f/3.0f;
|
||||
static GLfloat z_near = 1.0f;
|
||||
static GLfloat z_far = 100.f;
|
||||
|
||||
/* Projection matrix */
|
||||
static GLfloat projection_matrix[16] = {
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
/* Model view matrix */
|
||||
static GLfloat modelview_matrix[16] = {
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
/**********************************************************************
|
||||
* Heightmap vertex and index data
|
||||
*********************************************************************/
|
||||
|
||||
static GLfloat map_vertices[3][MAP_NUM_TOTAL_VERTICES];
|
||||
static GLuint map_line_indices[2*MAP_NUM_LINES];
|
||||
|
||||
/* Store uniform location for the shaders
|
||||
* Those values are setup as part of the process of creating
|
||||
* the shader program. They should not be used before creating
|
||||
* the program.
|
||||
*/
|
||||
static GLuint mesh;
|
||||
static GLuint mesh_vbo[4];
|
||||
|
||||
/**********************************************************************
|
||||
* OpenGL helper functions
|
||||
*********************************************************************/
|
||||
|
||||
/* Creates a shader object of the specified type using the specified text
|
||||
*/
|
||||
static GLuint make_shader(GLenum type, const char* text)
|
||||
{
|
||||
GLuint shader;
|
||||
GLint shader_ok;
|
||||
GLsizei log_length;
|
||||
char info_log[8192];
|
||||
|
||||
shader = glCreateShader(type);
|
||||
if (shader != 0)
|
||||
{
|
||||
glShaderSource(shader, 1, (const GLchar**)&text, NULL);
|
||||
glCompileShader(shader);
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_ok);
|
||||
if (shader_ok != GL_TRUE)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to compile %s shader\n", (type == GL_FRAGMENT_SHADER) ? "fragment" : "vertex" );
|
||||
glGetShaderInfoLog(shader, 8192, &log_length,info_log);
|
||||
fprintf(stderr, "ERROR: \n%s\n\n", info_log);
|
||||
glDeleteShader(shader);
|
||||
shader = 0;
|
||||
}
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
||||
/* Creates a program object using the specified vertex and fragment text
|
||||
*/
|
||||
static GLuint make_shader_program(const char* vs_text, const char* fs_text)
|
||||
{
|
||||
GLuint program = 0u;
|
||||
GLint program_ok;
|
||||
GLuint vertex_shader = 0u;
|
||||
GLuint fragment_shader = 0u;
|
||||
GLsizei log_length;
|
||||
char info_log[8192];
|
||||
|
||||
vertex_shader = make_shader(GL_VERTEX_SHADER, vs_text);
|
||||
if (vertex_shader != 0u)
|
||||
{
|
||||
fragment_shader = make_shader(GL_FRAGMENT_SHADER, fs_text);
|
||||
if (fragment_shader != 0u)
|
||||
{
|
||||
/* make the program that connect the two shader and link it */
|
||||
program = glCreateProgram();
|
||||
if (program != 0u)
|
||||
{
|
||||
/* attach both shader and link */
|
||||
glAttachShader(program, vertex_shader);
|
||||
glAttachShader(program, fragment_shader);
|
||||
glLinkProgram(program);
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &program_ok);
|
||||
|
||||
if (program_ok != GL_TRUE)
|
||||
{
|
||||
fprintf(stderr, "ERROR, failed to link shader program\n");
|
||||
glGetProgramInfoLog(program, 8192, &log_length, info_log);
|
||||
fprintf(stderr, "ERROR: \n%s\n\n", info_log);
|
||||
glDeleteProgram(program);
|
||||
glDeleteShader(fragment_shader);
|
||||
glDeleteShader(vertex_shader);
|
||||
program = 0u;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "ERROR: Unable to load fragment shader\n");
|
||||
glDeleteShader(vertex_shader);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "ERROR: Unable to load vertex shader\n");
|
||||
}
|
||||
return program;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* Geometry creation functions
|
||||
*********************************************************************/
|
||||
|
||||
/* Generate vertices and indices for the heightmap
|
||||
*/
|
||||
static void init_map(void)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
int k;
|
||||
GLfloat step = MAP_SIZE / (MAP_NUM_VERTICES - 1);
|
||||
GLfloat x = 0.0f;
|
||||
GLfloat z = 0.0f;
|
||||
/* Create a flat grid */
|
||||
k = 0;
|
||||
for (i = 0 ; i < MAP_NUM_VERTICES ; ++i)
|
||||
{
|
||||
for (j = 0 ; j < MAP_NUM_VERTICES ; ++j)
|
||||
{
|
||||
map_vertices[0][k] = x;
|
||||
map_vertices[1][k] = 0.0f;
|
||||
map_vertices[2][k] = z;
|
||||
z += step;
|
||||
++k;
|
||||
}
|
||||
x += step;
|
||||
z = 0.0f;
|
||||
}
|
||||
#if DEBUG_ENABLED
|
||||
for (i = 0 ; i < MAP_NUM_TOTAL_VERTICES ; ++i)
|
||||
{
|
||||
printf ("Vertice %d (%f, %f, %f)\n",
|
||||
i, map_vertices[0][i], map_vertices[1][i], map_vertices[2][i]);
|
||||
|
||||
}
|
||||
#endif
|
||||
/* create indices */
|
||||
/* line fan based on i
|
||||
* i+1
|
||||
* | / i + n + 1
|
||||
* | /
|
||||
* |/
|
||||
* i --- i + n
|
||||
*/
|
||||
|
||||
/* close the top of the square */
|
||||
k = 0;
|
||||
for (i = 0 ; i < MAP_NUM_VERTICES -1 ; ++i)
|
||||
{
|
||||
map_line_indices[k++] = (i + 1) * MAP_NUM_VERTICES -1;
|
||||
map_line_indices[k++] = (i + 2) * MAP_NUM_VERTICES -1;
|
||||
}
|
||||
/* close the right of the square */
|
||||
for (i = 0 ; i < MAP_NUM_VERTICES -1 ; ++i)
|
||||
{
|
||||
map_line_indices[k++] = (MAP_NUM_VERTICES - 1) * MAP_NUM_VERTICES + i;
|
||||
map_line_indices[k++] = (MAP_NUM_VERTICES - 1) * MAP_NUM_VERTICES + i + 1;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < (MAP_NUM_VERTICES - 1) ; ++i)
|
||||
{
|
||||
for (j = 0 ; j < (MAP_NUM_VERTICES - 1) ; ++j)
|
||||
{
|
||||
int ref = i * (MAP_NUM_VERTICES) + j;
|
||||
map_line_indices[k++] = ref;
|
||||
map_line_indices[k++] = ref + 1;
|
||||
|
||||
map_line_indices[k++] = ref;
|
||||
map_line_indices[k++] = ref + MAP_NUM_VERTICES;
|
||||
|
||||
map_line_indices[k++] = ref;
|
||||
map_line_indices[k++] = ref + MAP_NUM_VERTICES + 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
for (k = 0 ; k < 2 * MAP_NUM_LINES ; k += 2)
|
||||
{
|
||||
int beg, end;
|
||||
beg = map_line_indices[k];
|
||||
end = map_line_indices[k+1];
|
||||
printf ("Line %d: %d -> %d (%f, %f, %f) -> (%f, %f, %f)\n",
|
||||
k / 2, beg, end,
|
||||
map_vertices[0][beg], map_vertices[1][beg], map_vertices[2][beg],
|
||||
map_vertices[0][end], map_vertices[1][end], map_vertices[2][end]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void generate_heightmap__circle(float* center_x, float* center_y,
|
||||
float* size, float* displacement)
|
||||
{
|
||||
float sign;
|
||||
/* random value for element in between [0-1.0] */
|
||||
*center_x = (MAP_SIZE * rand()) / (float) RAND_MAX;
|
||||
*center_y = (MAP_SIZE * rand()) / (float) RAND_MAX;
|
||||
*size = (MAX_CIRCLE_SIZE * rand()) / (float) RAND_MAX;
|
||||
sign = (1.0f * rand()) / (float) RAND_MAX;
|
||||
sign = (sign < DISPLACEMENT_SIGN_LIMIT) ? -1.0f : 1.0f;
|
||||
*displacement = (sign * (MAX_DISPLACEMENT * rand())) / (float) RAND_MAX;
|
||||
}
|
||||
|
||||
/* Run the specified number of iterations of the generation process for the
|
||||
* heightmap
|
||||
*/
|
||||
static void update_map(int num_iter)
|
||||
{
|
||||
assert(num_iter > 0);
|
||||
while(num_iter)
|
||||
{
|
||||
/* center of the circle */
|
||||
float center_x;
|
||||
float center_z;
|
||||
float circle_size;
|
||||
float disp;
|
||||
size_t ii;
|
||||
generate_heightmap__circle(¢er_x, ¢er_z, &circle_size, &disp);
|
||||
disp = disp / 2.0f;
|
||||
for (ii = 0u ; ii < MAP_NUM_TOTAL_VERTICES ; ++ii)
|
||||
{
|
||||
GLfloat dx = center_x - map_vertices[0][ii];
|
||||
GLfloat dz = center_z - map_vertices[2][ii];
|
||||
GLfloat pd = (2.0f * (float) sqrt((dx * dx) + (dz * dz))) / circle_size;
|
||||
if (fabs(pd) <= 1.0f)
|
||||
{
|
||||
/* tx,tz is within the circle */
|
||||
GLfloat new_height = disp + (float) (cos(pd*3.14f)*disp);
|
||||
map_vertices[1][ii] += new_height;
|
||||
}
|
||||
}
|
||||
--num_iter;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* OpenGL helper functions
|
||||
*********************************************************************/
|
||||
|
||||
/* Create VBO, IBO and VAO objects for the heightmap geometry and bind them to
|
||||
* the specified program object
|
||||
*/
|
||||
static void make_mesh(GLuint program)
|
||||
{
|
||||
GLuint attrloc;
|
||||
|
||||
glGenVertexArrays(1, &mesh);
|
||||
glGenBuffers(4, mesh_vbo);
|
||||
glBindVertexArray(mesh);
|
||||
/* Prepare the data for drawing through a buffer inidices */
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh_vbo[3]);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)* MAP_NUM_LINES * 2, map_line_indices, GL_STATIC_DRAW);
|
||||
|
||||
/* Prepare the attributes for rendering */
|
||||
attrloc = glGetAttribLocation(program, "x");
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mesh_vbo[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[0][0], GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(attrloc);
|
||||
glVertexAttribPointer(attrloc, 1, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
|
||||
attrloc = glGetAttribLocation(program, "z");
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mesh_vbo[2]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[2][0], GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(attrloc);
|
||||
glVertexAttribPointer(attrloc, 1, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
|
||||
attrloc = glGetAttribLocation(program, "y");
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mesh_vbo[1]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[1][0], GL_DYNAMIC_DRAW);
|
||||
glEnableVertexAttribArray(attrloc);
|
||||
glVertexAttribPointer(attrloc, 1, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
}
|
||||
|
||||
/* Update VBO vertices from source data
|
||||
*/
|
||||
static void update_mesh(void)
|
||||
{
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[1][0]);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* GLFW callback functions
|
||||
*********************************************************************/
|
||||
|
||||
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||
{
|
||||
switch(key)
|
||||
{
|
||||
case GLFW_KEY_ESCAPE:
|
||||
/* Exit program on Escape */
|
||||
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void error_callback(int error, const char* description)
|
||||
{
|
||||
fprintf(stderr, "Error: %s\n", description);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
GLFWwindow* window;
|
||||
int iter;
|
||||
double dt;
|
||||
double last_update_time;
|
||||
int frame;
|
||||
float f;
|
||||
GLint uloc_modelview;
|
||||
GLint uloc_project;
|
||||
int width, height;
|
||||
|
||||
GLuint shader_program;
|
||||
|
||||
glfwSetErrorCallback(error_callback);
|
||||
|
||||
if (!glfwInit())
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
|
||||
|
||||
window = glfwCreateWindow(800, 600, "GLFW OpenGL3 Heightmap demo", NULL, NULL);
|
||||
if (! window )
|
||||
{
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Register events callback */
|
||||
glfwSetKeyCallback(window, key_callback);
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
gladLoadGL(glfwGetProcAddress);
|
||||
|
||||
/* Prepare opengl resources for rendering */
|
||||
shader_program = make_shader_program(vertex_shader_text, fragment_shader_text);
|
||||
|
||||
if (shader_program == 0u)
|
||||
{
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
glUseProgram(shader_program);
|
||||
uloc_project = glGetUniformLocation(shader_program, "project");
|
||||
uloc_modelview = glGetUniformLocation(shader_program, "modelview");
|
||||
|
||||
/* Compute the projection matrix */
|
||||
f = 1.0f / tanf(view_angle / 2.0f);
|
||||
projection_matrix[0] = f / aspect_ratio;
|
||||
projection_matrix[5] = f;
|
||||
projection_matrix[10] = (z_far + z_near)/ (z_near - z_far);
|
||||
projection_matrix[11] = -1.0f;
|
||||
projection_matrix[14] = 2.0f * (z_far * z_near) / (z_near - z_far);
|
||||
glUniformMatrix4fv(uloc_project, 1, GL_FALSE, projection_matrix);
|
||||
|
||||
/* Set the camera position */
|
||||
modelview_matrix[12] = -5.0f;
|
||||
modelview_matrix[13] = -5.0f;
|
||||
modelview_matrix[14] = -20.0f;
|
||||
glUniformMatrix4fv(uloc_modelview, 1, GL_FALSE, modelview_matrix);
|
||||
|
||||
/* Create mesh data */
|
||||
init_map();
|
||||
make_mesh(shader_program);
|
||||
|
||||
/* Create vao + vbo to store the mesh */
|
||||
/* Create the vbo to store all the information for the grid and the height */
|
||||
|
||||
/* setup the scene ready for rendering */
|
||||
glfwGetFramebufferSize(window, &width, &height);
|
||||
glViewport(0, 0, width, height);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
/* main loop */
|
||||
frame = 0;
|
||||
iter = 0;
|
||||
last_update_time = glfwGetTime();
|
||||
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
++frame;
|
||||
/* render the next frame */
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glDrawElements(GL_LINES, 2* MAP_NUM_LINES , GL_UNSIGNED_INT, 0);
|
||||
|
||||
/* display and process events through callbacks */
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
/* Check the frame rate and update the heightmap if needed */
|
||||
dt = glfwGetTime();
|
||||
if ((dt - last_update_time) > 0.2)
|
||||
{
|
||||
/* generate the next iteration of the heightmap */
|
||||
if (iter < MAX_ITER)
|
||||
{
|
||||
update_map(NUM_ITER_AT_A_TIME);
|
||||
update_mesh();
|
||||
iter += NUM_ITER_AT_A_TIME;
|
||||
}
|
||||
last_update_time = dt;
|
||||
frame = 0;
|
||||
}
|
||||
}
|
||||
|
||||
glfwTerminate();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
177
deps/glfw/examples/offscreen.c
vendored
Normal file
177
deps/glfw/examples/offscreen.c
vendored
Normal file
@ -0,0 +1,177 @@
|
||||
//========================================================================
|
||||
// Offscreen rendering example
|
||||
// Copyright (c) Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include <glad/gl.h>
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#if USE_NATIVE_OSMESA
|
||||
#define GLFW_EXPOSE_NATIVE_OSMESA
|
||||
#include <GLFW/glfw3native.h>
|
||||
#endif
|
||||
|
||||
#include "linmath.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include <stb_image_write.h>
|
||||
|
||||
static const struct
|
||||
{
|
||||
float x, y;
|
||||
float r, g, b;
|
||||
} vertices[3] =
|
||||
{
|
||||
{ -0.6f, -0.4f, 1.f, 0.f, 0.f },
|
||||
{ 0.6f, -0.4f, 0.f, 1.f, 0.f },
|
||||
{ 0.f, 0.6f, 0.f, 0.f, 1.f }
|
||||
};
|
||||
|
||||
static const char* vertex_shader_text =
|
||||
"#version 110\n"
|
||||
"uniform mat4 MVP;\n"
|
||||
"attribute vec3 vCol;\n"
|
||||
"attribute vec2 vPos;\n"
|
||||
"varying vec3 color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = MVP * vec4(vPos, 0.0, 1.0);\n"
|
||||
" color = vCol;\n"
|
||||
"}\n";
|
||||
|
||||
static const char* fragment_shader_text =
|
||||
"#version 110\n"
|
||||
"varying vec3 color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_FragColor = vec4(color, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static void error_callback(int error, const char* description)
|
||||
{
|
||||
fprintf(stderr, "Error: %s\n", description);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
GLFWwindow* window;
|
||||
GLuint vertex_buffer, vertex_shader, fragment_shader, program;
|
||||
GLint mvp_location, vpos_location, vcol_location;
|
||||
float ratio;
|
||||
int width, height;
|
||||
mat4x4 mvp;
|
||||
char* buffer;
|
||||
|
||||
glfwSetErrorCallback(error_callback);
|
||||
|
||||
glfwInitHint(GLFW_COCOA_MENUBAR, GLFW_FALSE);
|
||||
|
||||
if (!glfwInit())
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
||||
|
||||
window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);
|
||||
if (!window)
|
||||
{
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
gladLoadGL(glfwGetProcAddress);
|
||||
|
||||
// NOTE: OpenGL error checks have been omitted for brevity
|
||||
|
||||
glGenBuffers(1, &vertex_buffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
|
||||
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL);
|
||||
glCompileShader(vertex_shader);
|
||||
|
||||
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL);
|
||||
glCompileShader(fragment_shader);
|
||||
|
||||
program = glCreateProgram();
|
||||
glAttachShader(program, vertex_shader);
|
||||
glAttachShader(program, fragment_shader);
|
||||
glLinkProgram(program);
|
||||
|
||||
mvp_location = glGetUniformLocation(program, "MVP");
|
||||
vpos_location = glGetAttribLocation(program, "vPos");
|
||||
vcol_location = glGetAttribLocation(program, "vCol");
|
||||
|
||||
glEnableVertexAttribArray(vpos_location);
|
||||
glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE,
|
||||
sizeof(vertices[0]), (void*) 0);
|
||||
glEnableVertexAttribArray(vcol_location);
|
||||
glVertexAttribPointer(vcol_location, 3, GL_FLOAT, GL_FALSE,
|
||||
sizeof(vertices[0]), (void*) (sizeof(float) * 2));
|
||||
|
||||
glfwGetFramebufferSize(window, &width, &height);
|
||||
ratio = width / (float) height;
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
mat4x4_ortho(mvp, -ratio, ratio, -1.f, 1.f, 1.f, -1.f);
|
||||
|
||||
glUseProgram(program);
|
||||
glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) mvp);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
glFinish();
|
||||
|
||||
#if USE_NATIVE_OSMESA
|
||||
glfwGetOSMesaColorBuffer(window, &width, &height, NULL, (void**) &buffer);
|
||||
#else
|
||||
buffer = calloc(4, width * height);
|
||||
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
|
||||
#endif
|
||||
|
||||
// Write image Y-flipped because OpenGL
|
||||
stbi_write_png("offscreen.png",
|
||||
width, height, 4,
|
||||
buffer + (width * 4 * (height - 1)),
|
||||
-width * 4);
|
||||
|
||||
#if USE_NATIVE_OSMESA
|
||||
// Here is where there's nothing
|
||||
#else
|
||||
free(buffer);
|
||||
#endif
|
||||
|
||||
glfwDestroyWindow(window);
|
||||
|
||||
glfwTerminate();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
1073
deps/glfw/examples/particles.c
vendored
Normal file
1073
deps/glfw/examples/particles.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
234
deps/glfw/examples/sharing.c
vendored
Normal file
234
deps/glfw/examples/sharing.c
vendored
Normal file
@ -0,0 +1,234 @@
|
||||
//========================================================================
|
||||
// Context sharing example
|
||||
// Copyright (c) Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include <glad/gl.h>
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "getopt.h"
|
||||
#include "linmath.h"
|
||||
|
||||
static const char* vertex_shader_text =
|
||||
"#version 110\n"
|
||||
"uniform mat4 MVP;\n"
|
||||
"attribute vec2 vPos;\n"
|
||||
"varying vec2 texcoord;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = MVP * vec4(vPos, 0.0, 1.0);\n"
|
||||
" texcoord = vPos;\n"
|
||||
"}\n";
|
||||
|
||||
static const char* fragment_shader_text =
|
||||
"#version 110\n"
|
||||
"uniform sampler2D texture;\n"
|
||||
"uniform vec3 color;\n"
|
||||
"varying vec2 texcoord;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_FragColor = vec4(color * texture2D(texture, texcoord).rgb, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const vec2 vertices[4] =
|
||||
{
|
||||
{ 0.f, 0.f },
|
||||
{ 1.f, 0.f },
|
||||
{ 1.f, 1.f },
|
||||
{ 0.f, 1.f }
|
||||
};
|
||||
|
||||
static void error_callback(int error, const char* description)
|
||||
{
|
||||
fprintf(stderr, "Error: %s\n", description);
|
||||
}
|
||||
|
||||
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||
{
|
||||
if (action == GLFW_PRESS && key == GLFW_KEY_ESCAPE)
|
||||
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
GLFWwindow* windows[2];
|
||||
GLuint texture, program, vertex_buffer;
|
||||
GLint mvp_location, vpos_location, color_location, texture_location;
|
||||
|
||||
glfwSetErrorCallback(error_callback);
|
||||
|
||||
if (!glfwInit())
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||
|
||||
windows[0] = glfwCreateWindow(400, 400, "First", NULL, NULL);
|
||||
if (!windows[0])
|
||||
{
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
glfwSetKeyCallback(windows[0], key_callback);
|
||||
|
||||
glfwMakeContextCurrent(windows[0]);
|
||||
|
||||
// Only enable vsync for the first of the windows to be swapped to
|
||||
// avoid waiting out the interval for each window
|
||||
glfwSwapInterval(1);
|
||||
|
||||
// The contexts are created with the same APIs so the function
|
||||
// pointers should be re-usable between them
|
||||
gladLoadGL(glfwGetProcAddress);
|
||||
|
||||
// Create the OpenGL objects inside the first context, created above
|
||||
// All objects will be shared with the second context, created below
|
||||
{
|
||||
int x, y;
|
||||
char pixels[16 * 16];
|
||||
GLuint vertex_shader, fragment_shader;
|
||||
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
srand((unsigned int) glfwGetTimerValue());
|
||||
|
||||
for (y = 0; y < 16; y++)
|
||||
{
|
||||
for (x = 0; x < 16; x++)
|
||||
pixels[y * 16 + x] = rand() % 256;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 16, 16, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL);
|
||||
glCompileShader(vertex_shader);
|
||||
|
||||
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL);
|
||||
glCompileShader(fragment_shader);
|
||||
|
||||
program = glCreateProgram();
|
||||
glAttachShader(program, vertex_shader);
|
||||
glAttachShader(program, fragment_shader);
|
||||
glLinkProgram(program);
|
||||
|
||||
mvp_location = glGetUniformLocation(program, "MVP");
|
||||
color_location = glGetUniformLocation(program, "color");
|
||||
texture_location = glGetUniformLocation(program, "texture");
|
||||
vpos_location = glGetAttribLocation(program, "vPos");
|
||||
|
||||
glGenBuffers(1, &vertex_buffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
glUseProgram(program);
|
||||
glUniform1i(texture_location, 0);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
|
||||
glEnableVertexAttribArray(vpos_location);
|
||||
glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE,
|
||||
sizeof(vertices[0]), (void*) 0);
|
||||
|
||||
windows[1] = glfwCreateWindow(400, 400, "Second", NULL, windows[0]);
|
||||
if (!windows[1])
|
||||
{
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Place the second window to the right of the first
|
||||
{
|
||||
int xpos, ypos, left, right, width;
|
||||
|
||||
glfwGetWindowSize(windows[0], &width, NULL);
|
||||
glfwGetWindowFrameSize(windows[0], &left, NULL, &right, NULL);
|
||||
glfwGetWindowPos(windows[0], &xpos, &ypos);
|
||||
|
||||
glfwSetWindowPos(windows[1], xpos + width + left + right, ypos);
|
||||
}
|
||||
|
||||
glfwSetKeyCallback(windows[1], key_callback);
|
||||
|
||||
glfwMakeContextCurrent(windows[1]);
|
||||
|
||||
// While objects are shared, the global context state is not and will
|
||||
// need to be set up for each context
|
||||
|
||||
glUseProgram(program);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
|
||||
glEnableVertexAttribArray(vpos_location);
|
||||
glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE,
|
||||
sizeof(vertices[0]), (void*) 0);
|
||||
|
||||
while (!glfwWindowShouldClose(windows[0]) &&
|
||||
!glfwWindowShouldClose(windows[1]))
|
||||
{
|
||||
int i;
|
||||
const vec3 colors[2] =
|
||||
{
|
||||
{ 0.8f, 0.4f, 1.f },
|
||||
{ 0.3f, 0.4f, 1.f }
|
||||
};
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
int width, height;
|
||||
mat4x4 mvp;
|
||||
|
||||
glfwGetFramebufferSize(windows[i], &width, &height);
|
||||
glfwMakeContextCurrent(windows[i]);
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
mat4x4_ortho(mvp, 0.f, 1.f, 0.f, 1.f, 0.f, 1.f);
|
||||
glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) mvp);
|
||||
glUniform3fv(color_location, 1, colors[i]);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
glfwSwapBuffers(windows[i]);
|
||||
}
|
||||
|
||||
glfwWaitEvents();
|
||||
}
|
||||
|
||||
glfwTerminate();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
166
deps/glfw/examples/simple.c
vendored
Normal file
166
deps/glfw/examples/simple.c
vendored
Normal file
@ -0,0 +1,166 @@
|
||||
//========================================================================
|
||||
// Simple GLFW example
|
||||
// Copyright (c) Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
//! [code]
|
||||
|
||||
#include <glad/gl.h>
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "linmath.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static const struct
|
||||
{
|
||||
float x, y;
|
||||
float r, g, b;
|
||||
} vertices[3] =
|
||||
{
|
||||
{ -0.6f, -0.4f, 1.f, 0.f, 0.f },
|
||||
{ 0.6f, -0.4f, 0.f, 1.f, 0.f },
|
||||
{ 0.f, 0.6f, 0.f, 0.f, 1.f }
|
||||
};
|
||||
|
||||
static const char* vertex_shader_text =
|
||||
"#version 110\n"
|
||||
"uniform mat4 MVP;\n"
|
||||
"attribute vec3 vCol;\n"
|
||||
"attribute vec2 vPos;\n"
|
||||
"varying vec3 color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = MVP * vec4(vPos, 0.0, 1.0);\n"
|
||||
" color = vCol;\n"
|
||||
"}\n";
|
||||
|
||||
static const char* fragment_shader_text =
|
||||
"#version 110\n"
|
||||
"varying vec3 color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_FragColor = vec4(color, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static void error_callback(int error, const char* description)
|
||||
{
|
||||
fprintf(stderr, "Error: %s\n", description);
|
||||
}
|
||||
|
||||
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||
{
|
||||
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
|
||||
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
GLFWwindow* window;
|
||||
GLuint vertex_buffer, vertex_shader, fragment_shader, program;
|
||||
GLint mvp_location, vpos_location, vcol_location;
|
||||
|
||||
glfwSetErrorCallback(error_callback);
|
||||
|
||||
if (!glfwInit())
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||
|
||||
window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);
|
||||
if (!window)
|
||||
{
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
glfwSetKeyCallback(window, key_callback);
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
gladLoadGL(glfwGetProcAddress);
|
||||
glfwSwapInterval(1);
|
||||
|
||||
// NOTE: OpenGL error checks have been omitted for brevity
|
||||
|
||||
glGenBuffers(1, &vertex_buffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
|
||||
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL);
|
||||
glCompileShader(vertex_shader);
|
||||
|
||||
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL);
|
||||
glCompileShader(fragment_shader);
|
||||
|
||||
program = glCreateProgram();
|
||||
glAttachShader(program, vertex_shader);
|
||||
glAttachShader(program, fragment_shader);
|
||||
glLinkProgram(program);
|
||||
|
||||
mvp_location = glGetUniformLocation(program, "MVP");
|
||||
vpos_location = glGetAttribLocation(program, "vPos");
|
||||
vcol_location = glGetAttribLocation(program, "vCol");
|
||||
|
||||
glEnableVertexAttribArray(vpos_location);
|
||||
glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE,
|
||||
sizeof(vertices[0]), (void*) 0);
|
||||
glEnableVertexAttribArray(vcol_location);
|
||||
glVertexAttribPointer(vcol_location, 3, GL_FLOAT, GL_FALSE,
|
||||
sizeof(vertices[0]), (void*) (sizeof(float) * 2));
|
||||
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
float ratio;
|
||||
int width, height;
|
||||
mat4x4 m, p, mvp;
|
||||
|
||||
glfwGetFramebufferSize(window, &width, &height);
|
||||
ratio = width / (float) height;
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
mat4x4_identity(m);
|
||||
mat4x4_rotate_Z(m, m, (float) glfwGetTime());
|
||||
mat4x4_ortho(p, -ratio, ratio, -1.f, 1.f, 1.f, -1.f);
|
||||
mat4x4_mul(mvp, p, m);
|
||||
|
||||
glUseProgram(program);
|
||||
glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) mvp);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
glfwDestroyWindow(window);
|
||||
|
||||
glfwTerminate();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
//! [code]
|
546
deps/glfw/examples/splitview.c
vendored
Normal file
546
deps/glfw/examples/splitview.c
vendored
Normal file
@ -0,0 +1,546 @@
|
||||
//========================================================================
|
||||
// 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. useful for 3D modelling software). This
|
||||
// demo uses scissors to separate 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 <glad/gl.h>
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// Make MS math.h define M_PI
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <linmath.h>
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Global variables
|
||||
//========================================================================
|
||||
|
||||
// Mouse position
|
||||
static double 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;
|
||||
mat4x4 view;
|
||||
|
||||
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)
|
||||
{
|
||||
vec3 eye = { 0.f, 0.f, 1.f };
|
||||
vec3 center = { 0.f, 0.f, 0.f };
|
||||
vec3 up = { 0.f, 1.f, 0.f };
|
||||
mat4x4_look_at(view, eye, center, up);
|
||||
}
|
||||
glLoadMatrixf((const GLfloat*) view);
|
||||
|
||||
// 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};
|
||||
float aspect;
|
||||
mat4x4 view, projection;
|
||||
|
||||
// Calculate aspect of window
|
||||
if (height > 0)
|
||||
aspect = (float) width / (float) height;
|
||||
else
|
||||
aspect = 1.f;
|
||||
|
||||
// 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);
|
||||
{
|
||||
vec3 eye = { 0.f, 10.f, 1e-3f };
|
||||
vec3 center = { 0.f, 0.f, 0.f };
|
||||
vec3 up = { 0.f, 1.f, 0.f };
|
||||
mat4x4_look_at( view, eye, center, up );
|
||||
}
|
||||
glLoadMatrixf((const GLfloat*) view);
|
||||
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);
|
||||
{
|
||||
vec3 eye = { 0.f, 0.f, 10.f };
|
||||
vec3 center = { 0.f, 0.f, 0.f };
|
||||
vec3 up = { 0.f, 1.f, 0.f };
|
||||
mat4x4_look_at( view, eye, center, up );
|
||||
}
|
||||
glLoadMatrixf((const GLfloat*) view);
|
||||
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);
|
||||
{
|
||||
vec3 eye = { 10.f, 0.f, 0.f };
|
||||
vec3 center = { 0.f, 0.f, 0.f };
|
||||
vec3 up = { 0.f, 1.f, 0.f };
|
||||
mat4x4_look_at( view, eye, center, up );
|
||||
}
|
||||
glLoadMatrixf((const GLfloat*) view);
|
||||
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);
|
||||
mat4x4_perspective(projection,
|
||||
65.f * (float) M_PI / 180.f,
|
||||
aspect,
|
||||
1.f, 50.f);
|
||||
glLoadMatrixf((const GLfloat*) projection);
|
||||
|
||||
// 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);
|
||||
{
|
||||
vec3 eye = { 3.f, 1.5f, 3.f };
|
||||
vec3 center = { 0.f, 0.f, 0.f };
|
||||
vec3 up = { 0.f, 1.f, 0.f };
|
||||
mat4x4_look_at( view, eye, center, up );
|
||||
}
|
||||
glLoadMatrixf((const GLfloat*) view);
|
||||
|
||||
// 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();
|
||||
glTranslatef((GLfloat) ((active_view - 1) & 1), (GLfloat) (1 - (active_view - 1) / 2), 0.0f);
|
||||
|
||||
glColor3f(1.0f, 1.0f, 0.6f);
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2i(1, 0);
|
||||
glVertex2i(1, 1);
|
||||
glVertex2i(0, 1);
|
||||
glVertex2i(0, 0);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Framebuffer size callback function
|
||||
//========================================================================
|
||||
|
||||
static void framebufferSizeFun(GLFWwindow* window, int w, int h)
|
||||
{
|
||||
width = w;
|
||||
height = h > 0 ? h : 1;
|
||||
do_redraw = 1;
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Window refresh callback function
|
||||
//========================================================================
|
||||
|
||||
static void windowRefreshFun(GLFWwindow* window)
|
||||
{
|
||||
drawAllViews();
|
||||
glfwSwapBuffers(window);
|
||||
do_redraw = 0;
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Mouse position callback function
|
||||
//========================================================================
|
||||
|
||||
static void cursorPosFun(GLFWwindow* window, double x, double y)
|
||||
{
|
||||
int wnd_width, wnd_height, fb_width, fb_height;
|
||||
double scale;
|
||||
|
||||
glfwGetWindowSize(window, &wnd_width, &wnd_height);
|
||||
glfwGetFramebufferSize(window, &fb_width, &fb_height);
|
||||
|
||||
scale = (double) fb_width / (double) wnd_width;
|
||||
|
||||
x *= scale;
|
||||
y *= scale;
|
||||
|
||||
// Depending on which view was selected, rotate around different axes
|
||||
switch (active_view)
|
||||
{
|
||||
case 1:
|
||||
rot_x += (int) (y - ypos);
|
||||
rot_z += (int) (x - xpos);
|
||||
do_redraw = 1;
|
||||
break;
|
||||
case 3:
|
||||
rot_x += (int) (y - ypos);
|
||||
rot_y += (int) (x - xpos);
|
||||
do_redraw = 1;
|
||||
break;
|
||||
case 4:
|
||||
rot_y += (int) (x - xpos);
|
||||
rot_z += (int) (y - ypos);
|
||||
do_redraw = 1;
|
||||
break;
|
||||
default:
|
||||
// Do nothing for perspective view, or if no view is selected
|
||||
break;
|
||||
}
|
||||
|
||||
// Remember cursor position
|
||||
xpos = x;
|
||||
ypos = y;
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Mouse button callback function
|
||||
//========================================================================
|
||||
|
||||
static void mouseButtonFun(GLFWwindow* window, int button, int action, int mods)
|
||||
{
|
||||
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;
|
||||
}
|
||||
else if (button == GLFW_MOUSE_BUTTON_LEFT)
|
||||
{
|
||||
// Deselect any previously selected view
|
||||
active_view = 0;
|
||||
}
|
||||
|
||||
do_redraw = 1;
|
||||
}
|
||||
|
||||
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||
{
|
||||
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
|
||||
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// main
|
||||
//========================================================================
|
||||
|
||||
int main(void)
|
||||
{
|
||||
GLFWwindow* window;
|
||||
|
||||
// Initialise GLFW
|
||||
if (!glfwInit())
|
||||
{
|
||||
fprintf(stderr, "Failed to initialize GLFW\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
glfwWindowHint(GLFW_SAMPLES, 4);
|
||||
|
||||
// Open OpenGL window
|
||||
window = glfwCreateWindow(500, 500, "Split view demo", NULL, NULL);
|
||||
if (!window)
|
||||
{
|
||||
fprintf(stderr, "Failed to open GLFW window\n");
|
||||
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Set callback functions
|
||||
glfwSetFramebufferSizeCallback(window, framebufferSizeFun);
|
||||
glfwSetWindowRefreshCallback(window, windowRefreshFun);
|
||||
glfwSetCursorPosCallback(window, cursorPosFun);
|
||||
glfwSetMouseButtonCallback(window, mouseButtonFun);
|
||||
glfwSetKeyCallback(window, key_callback);
|
||||
|
||||
// Enable vsync
|
||||
glfwMakeContextCurrent(window);
|
||||
gladLoadGL(glfwGetProcAddress);
|
||||
glfwSwapInterval(1);
|
||||
|
||||
if (GLAD_GL_ARB_multisample || GLAD_GL_VERSION_1_3)
|
||||
glEnable(GL_MULTISAMPLE_ARB);
|
||||
|
||||
glfwGetFramebufferSize(window, &width, &height);
|
||||
framebufferSizeFun(window, width, height);
|
||||
|
||||
// Main loop
|
||||
for (;;)
|
||||
{
|
||||
// Only redraw if we need to
|
||||
if (do_redraw)
|
||||
windowRefreshFun(window);
|
||||
|
||||
// Wait for new events
|
||||
glfwWaitEvents();
|
||||
|
||||
// Check if the window should be closed
|
||||
if (glfwWindowShouldClose(window))
|
||||
break;
|
||||
}
|
||||
|
||||
// Close OpenGL window and terminate GLFW
|
||||
glfwTerminate();
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
462
deps/glfw/examples/wave.c
vendored
Normal file
462
deps/glfw/examples/wave.c
vendored
Normal file
@ -0,0 +1,462 @@
|
||||
/*****************************************************************************
|
||||
* 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
|
||||
* 2010-10-24: Formatting and cleanup - Camilla Löwy
|
||||
*****************************************************************************/
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// Make MS math.h define M_PI
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <glad/gl.h>
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <linmath.h>
|
||||
|
||||
// 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.f, beta = -70.f;
|
||||
GLfloat zoom = 2.f;
|
||||
|
||||
double cursorX;
|
||||
double cursorY;
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
//========================================================================
|
||||
// Initialize grid geometry
|
||||
//========================================================================
|
||||
|
||||
void init_vertices(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 = (GLfloat) (x - GRIDW / 2) / (GLfloat) (GRIDW / 2);
|
||||
vertex[p].y = (GLfloat) (y - GRIDH / 2) / (GLfloat) (GRIDH / 2);
|
||||
vertex[p].z = 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);
|
||||
|
||||
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];
|
||||
|
||||
//========================================================================
|
||||
// Initialize grid
|
||||
//========================================================================
|
||||
|
||||
void init_grid(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 scene
|
||||
//========================================================================
|
||||
|
||||
void draw_scene(GLFWwindow* window)
|
||||
{
|
||||
// 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);
|
||||
|
||||
glDrawElements(GL_QUADS, 4 * QUADNUM, GL_UNSIGNED_INT, quad);
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Initialize Miscellaneous OpenGL state
|
||||
//========================================================================
|
||||
|
||||
void init_opengl(void)
|
||||
{
|
||||
// Use Gouraud (smooth) shading
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
// Switch on the z-buffer
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, sizeof(struct Vertex), vertex);
|
||||
glColorPointer(3, 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 adjust_grid(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_grid(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Print errors
|
||||
//========================================================================
|
||||
|
||||
static void error_callback(int error, const char* description)
|
||||
{
|
||||
fprintf(stderr, "Error: %s\n", description);
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Handle key strokes
|
||||
//========================================================================
|
||||
|
||||
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||
{
|
||||
if (action != GLFW_PRESS)
|
||||
return;
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_ESCAPE:
|
||||
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
||||
break;
|
||||
case GLFW_KEY_SPACE:
|
||||
init_grid();
|
||||
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_PAGE_UP:
|
||||
zoom -= 0.25f;
|
||||
if (zoom < 0.f)
|
||||
zoom = 0.f;
|
||||
break;
|
||||
case GLFW_KEY_PAGE_DOWN:
|
||||
zoom += 0.25f;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Callback function for mouse button events
|
||||
//========================================================================
|
||||
|
||||
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
|
||||
{
|
||||
if (button != GLFW_MOUSE_BUTTON_LEFT)
|
||||
return;
|
||||
|
||||
if (action == GLFW_PRESS)
|
||||
{
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
glfwGetCursorPos(window, &cursorX, &cursorY);
|
||||
}
|
||||
else
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Callback function for cursor motion events
|
||||
//========================================================================
|
||||
|
||||
void cursor_position_callback(GLFWwindow* window, double x, double y)
|
||||
{
|
||||
if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
alpha += (GLfloat) (x - cursorX) / 10.f;
|
||||
beta += (GLfloat) (y - cursorY) / 10.f;
|
||||
|
||||
cursorX = x;
|
||||
cursorY = y;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Callback function for scroll events
|
||||
//========================================================================
|
||||
|
||||
void scroll_callback(GLFWwindow* window, double x, double y)
|
||||
{
|
||||
zoom += (float) y / 4.f;
|
||||
if (zoom < 0)
|
||||
zoom = 0;
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Callback function for framebuffer resize events
|
||||
//========================================================================
|
||||
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
float ratio = 1.f;
|
||||
mat4x4 projection;
|
||||
|
||||
if (height > 0)
|
||||
ratio = (float) width / (float) height;
|
||||
|
||||
// Setup viewport
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
// Change to the projection matrix and set our viewing volume
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
mat4x4_perspective(projection,
|
||||
60.f * (float) M_PI / 180.f,
|
||||
ratio,
|
||||
1.f, 1024.f);
|
||||
glLoadMatrixf((const GLfloat*) projection);
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// main
|
||||
//========================================================================
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
GLFWwindow* window;
|
||||
double t, dt_total, t_old;
|
||||
int width, height;
|
||||
|
||||
glfwSetErrorCallback(error_callback);
|
||||
|
||||
if (!glfwInit())
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
window = glfwCreateWindow(640, 480, "Wave Simulation", NULL, NULL);
|
||||
if (!window)
|
||||
{
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
glfwSetKeyCallback(window, key_callback);
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
glfwSetMouseButtonCallback(window, mouse_button_callback);
|
||||
glfwSetCursorPosCallback(window, cursor_position_callback);
|
||||
glfwSetScrollCallback(window, scroll_callback);
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
gladLoadGL(glfwGetProcAddress);
|
||||
glfwSwapInterval(1);
|
||||
|
||||
glfwGetFramebufferSize(window, &width, &height);
|
||||
framebuffer_size_callback(window, width, height);
|
||||
|
||||
// Initialize OpenGL
|
||||
init_opengl();
|
||||
|
||||
// Initialize simulation
|
||||
init_vertices();
|
||||
init_grid();
|
||||
adjust_grid();
|
||||
|
||||
// Initialize timer
|
||||
t_old = glfwGetTime() - 0.01;
|
||||
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
t = glfwGetTime();
|
||||
dt_total = t - t_old;
|
||||
t_old = t;
|
||||
|
||||
// Safety - iterate if dt_total is too large
|
||||
while (dt_total > 0.f)
|
||||
{
|
||||
// Select iteration time step
|
||||
dt = dt_total > MAX_DELTA_T ? MAX_DELTA_T : dt_total;
|
||||
dt_total -= dt;
|
||||
|
||||
// Calculate wave propagation
|
||||
calc_grid();
|
||||
}
|
||||
|
||||
// Compute height of each vertex
|
||||
adjust_grid();
|
||||
|
||||
// Draw wave grid to OpenGL display
|
||||
draw_scene(window);
|
||||
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
glfwTerminate();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
Reference in New Issue
Block a user