建立一个py文件,然后导出GLFW和GL的库:
import glfw
from OpenGL.GL import *
若使用GLFW,则首先需要初始化GLFW:
if not glfw.init():
raise Exception("glfw can not be initialized!")
glfw.init()
函数用于初始化GLFW,在调用大部分其它GLFW函数前,都需要初始化GLFW。glfw.init()
如果成功,将会返回GLFW_TRUE,否则返回GLFW_FALSE,其中GLFW_TRUE和GLFW_FALSE是GLFW定义的常量,被定义为于1和0。
若初始化失败,则会输出:glfw can not be initialized!
使用glfw.window_hint()
函数设置hint
,这里hint
可以理解为一些关于窗口的选项。glfw.window_hint()
接受两个参数,第一个是我们要设置的hint
的名字,使用GLFW常量
(以 glfw.
开头)指定;第二个是我们要把该hint
设置成的值,该值随要设置的hint
而异。
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) # OpenGL主版本号
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) # OpenGL副版本号
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) # OpenGL模式,此处设置为OpenGL核心模式
glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, True)
# 4 MSAA is a good default with wide support
glfw.window_hint(glfw.SAMPLES, 4)
如上面所示,OpenGL版本号设置为3.3
,OpenGL模式是核心模式。这样的设置是有原因的具体后面再讲。
glfw.create_window()
函数接受5个参数。第一个、第二个是窗口的宽和高,以像素为单位,这里分别是800和600(可根据显示器设置);第三个是窗口标题,这里是"My OpenGL window";第四个和第五个参数可以忽略,直接传入None
。
创建完成之后要检查一下是否创建完成。若创建失败则输出glfw window can not be created!
# creating the window
window = glfw.create_window(800, 600, "My OpenGL window", None, None)
# check if window was created
if not window:
glfw.terminate()
raise Exception("glfw window can not be created!")
然后查询实际的framebuffer
大小,这样我们可以稍后设置正确的viewport
# Query the actual framebuffer size so we can set the right viewport later
# -> glViewport(0, 0, framebuffer_size[0], framebuffer_size[1])
framebuffer_size = glfw.get_framebuffer_size(window)
最后设置窗口的位置(这里是260,50),并且把创建的窗口设置成在当前线程上可使用的窗口,即接下来的画图都会画在刚刚创建的窗口上。
# set window's position
glfw.set_window_pos(window, 260, 50)
# make the context current
# 让当前窗口的环境在当前线程上成为当前环境(接下来的画图都会画在我们刚刚创建的窗口上)
glfw.make_context_current(window)
和控制台程序不同,我们希望这个程序可以一直运行,直到用户关闭窗口(或有点击键盘等)。这样我们就需要创建一个循环,叫做游戏循环(game loop)。
glfw.window_should_close()
检查窗口是否需要关闭。如果是,游戏循环就结束了,接下来我们将会清理资源,结束程序。
while not glfw.window_should_close(window):
glfw.poll_events()
glfw.swap_buffers(window)
glfw.swap_buffers( )
用来交换窗口的两个颜色缓冲(color buffer)。这个概念叫做双缓冲(double buffer)。如果不使用双缓冲,就可能会出现闪屏现象,因为绘制一般不是一下子就绘制完毕的,而是从左到右、从上到下地绘制。为了避免这个问题,一般会使用双缓冲,前缓冲(front buffer)是最终的图像,而程序会在后缓冲(back buffer)上绘制。后缓冲绘制完毕后,就交换两个缓冲,这样就不会有闪屏的问题了。
glfw.poll_events()
用来检查是否有事件被触发,例如点击关闭按钮、点击鼠标、按下键盘,等等。如果有,GLFW将会对这些事件进行处理。当某个事件触发时,GLFW不会自动更新状态,必须调用glfw.poll_events()
才能更新。调用glfw.poll_events()
时会检查状态是否有变化,如果有就会更新该状态。如果设置了回调函数(这个将在以后讲),还会调用相应的回调函数。如果不调用这个函数,不仅无法检测输入(后文会需要这样),我们在点击窗口右上角的X
时,GLFW也不会知道需要关闭窗口。所以必须在每一轮游戏循环中调用这个函数。
最后,当循环执行完毕后,需要释放前面所申请的资源
# terminate glfw, free up allocated resources
glfw.terminate()
glfw.terminate()
将会释放所有GLFW资源,关闭当前窗口。然后程序就成功退出了。
import glfw
from OpenGL.GL import *
# initializing glfw library
if not glfw.init():
raise Exception("glfw can not be initialized!")
# Configure the OpenGL context.
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) # OpenGL主版本号
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) # OpenGL副版本号
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) # OpenGL模式,此处设置为OpenGL核心模式
glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, True)
# 4 MSAA is a good default with wide support
glfw.window_hint(glfw.SAMPLES, 4)
# creating the window
window = glfw.create_window(800, 600, "My OpenGL window", None, None)
# check if window was created
if not window:
glfw.terminate()
raise Exception("glfw window can not be created!")
# Query the actual framebuffer size so we can set the right viewport later
# -> glViewport(0, 0, framebuffer_size[0], framebuffer_size[1])
framebuffer_size = glfw.get_framebuffer_size(window)
# set window's position
glfw.set_window_pos(window, 260, 50)
# make the context current
glfw.make_context_current(window)
# the main application loop
while not glfw.window_should_close(window):
glfw.poll_events()
glfw.swap_buffers(window)
# terminate glfw, free up allocated resources
glfw.terminate()
我们还可以设置背景色,比如设置成绿色。还可以改变退出控制方式,比如按下键盘q
就可以退出当前窗口。这个的代码实现后面会补上。
150讲轻松搞定Python网络爬虫