程序基本框架
#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>
/* 基本函数事件 */
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 init( void )
{
/*
* Clear background.
*/
glClearColor( 0.55f, 0.55f, 0.55f, 0.f );
glShadeModel( GL_FLAT );
}
/*****************************************************************************
* 显示窗体内容
*****************************************************************************/
void display(void)
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );//缓冲区清除
glPushMatrix();//把当前状态做一个副本放入堆栈之中
// TODO.
......
glPopMatrix();//返回执行glPushMatrix()时的状态
//glPushMatrix()和glPopMatrix()的配对使用能够消除上一次的变换对本次变换的影响,使本次变换是以世界坐标系的原点为參考点进行
glFlush();//清空缓冲区
}
/*****************************************************************************
* 窗口大小改变时候触发
*****************************************************************************/
void reshape( GLFWwindow* window, int w, int h )
{
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, w, h);
}
/*======================================================================*
* 键盘事件触发
*======================================================================*/
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);
}
}
}
}
/*======================================================================*
* 鼠标按键事件触发
*======================================================================*/
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 = (GLfloat)(x - width / 2) / width * 2;
cursor_y = (GLfloat)(height / 2 - y) / height * 2;
}
/*======================================================================*
* 主函数
*======================================================================*/
int main( void )
{
GLFWwindow* window;
//初始化 GLFW
if( !glfwInit() )
exit( EXIT_FAILURE );//如果GLFW未成功初始化,则退出程序
window = glfwCreateWindow( 400, 400, "Boing (classic Amiga demo)", NULL, NULL );
if (!window)
{
glfwTerminate();
exit( EXIT_FAILURE );
}//创建一个400*400,标题为"Boing (classic Amiga demo)"的GLFW窗口
glfwSetWindowAspectRatio(window, 1, 1);
glfwSetFramebufferSizeCallback(window, reshape);//设置一个新的窗口帧缓存大小回调函数cbfun给指定窗口window。当窗口帧缓存大小发生变化时,这个回调函数将会被触发。
glfwSetKeyCallback(window, key_callback);//设置一个新的键盘消息回调函数cbfun给指定的窗口window。如果按下或者放开键盘按键,系统会调用这个函数。
glfwSetMouseButtonCallback(window, mouse_button_callback);//设置一个新的鼠标按键回调函数cbfun给指定窗口window。当用户按下或者松开鼠标按键时,这个回调函数将会被触发。
glfwSetCursorPosCallback(window, cursor_position_callback);//设置一个新的鼠标光标位置回调函数cbfun给指定窗口window。每当鼠标光标位置发生变化的时候,这个回调函数就会被触发。
glfwMakeContextCurrent(window);//设置参数window中的窗口所关联的OpenGL环境为当前环境。这个环境在当前线程中会一直保持为当前环境,直到另一个环境被设置为当前环境,或者窗口被删除为止。
gladLoadGL(glfwGetProcAddress);
glfwSwapInterval( 1 );//设置监视器的最低刷新数
glfwGetFramebufferSize(window, &width, &height);//获取窗口帧缓存尺寸大小。
//window表示操作的窗口句柄。
//width和height表示保存窗口帧缓存宽高大小的地址。
reshape(window, width, height);
glfwSetTime( 0.0 );
init();
//主循环
for (;;)
{
//定时
t = glfwGetTime();
dt = t - t_old;
t_old = t;
//渲染图像
display();
//交换缓冲区
glfwSwapBuffers(window);
glfwPollEvents();
//检查程序是否仍在运行
if (glfwWindowShouldClose(window))
break;
}
glfwTerminate();
exit( EXIT_SUCCESS );
}