【OpenGL】第一个窗口
包含头文件:
#include <GL/glew.h>
// GLFW
#include <GLFW/glfw3.h>
初始化与配置GLFW:
glfwInit(); //初始化glfw
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
glfwWindowHint的第一个参数代表要配置的选项,这里我们可以从一个枚举中选择可用的选项,这些选项带有GLFW_前缀。第二个参数是一个整数,它代表为选项所设置的值。
创建窗口对象:
GLFWwindow * window = glfwCreateWindow(800, 600, "LearnOpenGL",nullptr, nullptr);
glfwMakeContextCurrent(window);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
函数glfwCreateWindow需要窗口的宽度和高度作为它头两个参数。第三个参数允许我们给窗口创建一个名字;现在我们把它命名为“LearnOpenGL”但是你也可以取个自己喜欢的名字。我们可以忽略最后两个参数。这个函数返回一个GLFWwindow对象,在后面的其他GLFW操作会需要它。之后,我们告诉GLFW去创建我们窗口的环境(glfwMakeContextCurrent),这个环境是当前线程的主环境。
GLEW初始化:
glewExperimental = GL_TRUE;
if(glewInit() != GLEW_OK)
{
std::cout << "Failed to initialize GLEW" << std::endl;
return -1;
}
注意,在初始化GLEW前我们把glewExperimental变量设置为GL_TRUE。设置glewExperimental为true可以保证GLEW使用更多的现代技术来管理OpenGL机能。如果不这么设置,它就会使用默认的GL_FALSE,这样当使用core profile的时有可能发生问题。
Viewport(视口):
glViewport(0, 0, 800, 600);
前两个参数设置了窗口的左下角的位置。第三个和第四个参数是这个渲染窗口的宽度和高度,它和GLFW窗口是一样大的。我们可以把这个值设置得比GLFW窗口尺寸小;这样OpenGL的渲染都会在一个更小的窗口(区域)进行显示,我们可以在OpenGL的viewport之外显示其他的元素。
OpenGL幕后是使用特定的数据的,通过glViewport把这种2D坐标加工为屏幕上的坐标。比如,一个被加工的点的位置是(-0.5, 0.5)会(作为它最后的变换)被映射到屏幕坐标(200, 450)上。注意,OpenGL中处理的坐标是在-1和1之间,所以我们事实上是把(-1到1)的范围映射到(0, 800)和(0, 600)上了。
循环:
while (!glfwWindowShouldClose(window))
{
// Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions
glfwPollEvents();
// Render
// Clear the colorbuffer
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Swap the screen buffers
glfwSwapBuffers(window);
}
我们用一种自己选择的颜色来清空屏幕,测试一下是否能够正常工作。每个渲染迭代的开始,我们都要清理屏幕,否则只能一直看到前一个迭代的结果(这可能就是你想要的效果,但通常你不会这么想)。我们可以使用glClear函数清理屏幕的颜色缓冲,在这个函数中我们以缓冲位(BUFFER_BIT)指定我们希望清理哪个缓冲。可用的位可以是GL_COLOR_BUFFER_BIT、GL_DEPTH_BUFFER_BIT和GL_STENCIL_BUFFER_BIT①。现在,我们关心的只是颜色值,所以我们只清空颜色缓冲。
glfwWindowShouldClose函数从开始便检验每一次循环迭代中GLFW是否已经得到关闭指示,如果得到这样的指示,函数就会返回true,并且循环停止运行,之后我们就可以关闭应用了。
glfwPollEvents函数检验是否有任何事件被处触发(比如键盘输入或是鼠标移动的事件),接着调用相应函数(我们可以通过回调方法设置它们)。我们经常在循环迭代前调用事件处理函数。
glfwSwapBuffers函数会交换颜色缓冲(颜色缓冲是一个GLFW窗口为每一个像素储存颜色数值的大缓冲),它是在这次迭代中绘制的,也作为输出显示在屏幕上。
事件:
可以通过glfw回调函数实现:
glfwSetKeyCallback(window, key_callback);
按键输入函数的接收一个GLFWwindow参数,一个代表按下按键的整型数字,一个特定动作,按钮是被按下、还是释放,一个代表某个标识的整数告诉你shift、control、alt或super是否被同时按下。每当一个用户按下一个按钮,GLFW都会调用这个函数,为你的这个函数填充合适的参数。
void key_callback(GLFWwindow * window, int key, int scancode, int action, int mode)
{
// 当用户按下ESC, 我们就把WindowShouldClose设置为true, 关闭应用
if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
在我们(新创建)的key_callback函数中,我们检查被按下的按键是否等于ESC健,如果是这个按键被按下(不是释放)的话,我们就用glfwSetWindowShouldClose设置它的WindowShouldClose属性为true来关闭GLFW。下一个主while循环条件检验会失败,应用就关闭了。
我们要在创建窗口之后在循环初始化之前注册回调函数。
完整代码:
#include<iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
// Function prototypes
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
// Window dimensions
const GLuint WIDTH = 800, HEIGHT = 600;
// The MAIN function, from here we start the application and run the game loop
int main()
{
std::cout << "Starting GLFW context, OpenGL 3.3" << std::endl;
// Init GLFW
glfwInit();
// Set all the required options for GLFW
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
// Create a GLFWwindow object that we can use for GLFW's functions
GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr);
if (window == nullptr)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// Set the required callback functions
glfwSetKeyCallback(window, key_callback);
// Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions
glewExperimental = GL_TRUE;
// Initialize GLEW to setup the OpenGL Function pointers
if (glewInit() != GLEW_OK)
{
std::cout << "Failed to initialize GLEW" << std::endl;
return -1;
}
// Define the viewport dimensions
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
// Game loop
while (!glfwWindowShouldClose(window))
{
// Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions
glfwPollEvents();
// Render
// Clear the colorbuffer
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Swap the screen buffers
glfwSwapBuffers(window);
}
// Terminate GLFW, clearing any resources allocated by GLFW.
glfwTerminate();
return 0;
}
// Is called whenever a key is pressed/released via GLFW
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
std::cout << key << std::endl;
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
内容来自:http://bullteacher.com/4-hello-window.html
【OpenGL】第一个窗口的更多相关文章
- Axiom3D写游戏:第一个窗口
Axiom主要的代码大致翻看了下,就想到了自己来模拟一下游戏开发. 这章主要包括创建窗口及3D渲染的一些基本元素,并添加一个第三人称的骨骼动画作主角,加上前文中修改过后的地形组件,能用鼠标和键盘进行漫 ...
- delphi程序向另一个可执行程序发消息(使用GetForegroundWindow; 找出当前操作系统中活动的第一个窗口)
function FindWindowThroughWindowText(WindowText: string): THandle;var hCurrentWindow: THandle; cnt ...
- OpenGL教程(2)——第一个窗口
OpenGL环境终于配置好了,现在我们可以开始学习OpenGL了. 首先,创建一个.cpp文件,然后打上几行#include指令: #include <iostream> using st ...
- OpenGL学习(2)—— 创建第一个窗口
创建 GLFW GLFW是一个专门针对OpenGL的C语言库,它提供了一些渲染物体所需的最低限度的接口.它允许用户创建OpenGL上下文,定义窗口参数以及处理用户输入,这正是我们需要的. #inclu ...
- pygame_第一个窗口程序
####可以使用python自带的IDLE交互式开发,也可以借助其他的编辑器,我这里采用的pycharm编辑器 1.导入我们所需要的模块 import pygame,sys --导入我们需要的模块 ...
- (1)pygame_第一个窗口程序
####可以使用python自带的IDLE交互式开发,也可以借助其他的编辑器,我这里采用的pycharm编辑器 1.导入我们所需要的模块 import pygame,sys --导入我们需要的模块 ...
- 学习opengl第一步
有两个地址一个是学习opengl基础知识的网站, 一个是博客园大牛分享的特别好的文章. 记录一下希望向坚持做俯卧撑一样坚持下去. 学习网站:http://learnopengl-cn.readthed ...
- vscode源码分析【二】程序的启动逻辑,第一个窗口是如何创建的
上一篇文章:https://www.cnblogs.com/liulun/ (小广告:我做的开源免费的,个人知识管理及自媒体营销工具“想学吗”:https://github.com/xland/xia ...
- opengl第一个工程
#include <iostream> #include <glad/glad.h> #include <GLFW/glfw3.h> void framebuffe ...
随机推荐
- tkinter widget
tkinter messagebox
- 5.分析mitmproxy的优势及工具mitmdump的使用(参照书籍)
mitmproxy优势:功能和charles.fiddler相似,强大之处在于它的工具 mitmdump 可以直接对接python 对请求做处理. mitmdump使用 : 1.mitmdump是mi ...
- 转载:明明白白VC LIB和DLL的使用
转载来自:http://dpinglee.blog.163.com/blog/static/1440977532016316813889/ 1.加载lib/头文件 分两种方法: (1)适用于当前项目 ...
- django之ReverseOneToOneDescriptor
class ReverseOneToOneDescriptor(object): """ Accessor to the related object on the re ...
- idea 未实现接口红线提示,重复代码波浪线提示,自动换行,控制台输出内容自动换行
01,Could not autowire. No beans of 'UserMapper' type found 01.1,问题描述,通过反射动态实现的接口在调用时会出现以上提示,常见的如 ORM ...
- STM32之USB电路(摘要笔记)
- fb发布打包外部资源
将资源放在src文件夹下面即可 然后在打包那就会看到资源,勾上即可
- fb 4.7英文版 显示行数
窗口(window)à首选项(Preference)—>常规(General)—>编辑器(Editors)—>文本编辑器(Text Editors)—>“显示行号”(Show ...
- elasticSearch-header
elasticSearch既有chrome的插件 sense,但是因为chrome作为恶意插件不让植入,因此sense目前还停留在5版本. elasticSearch自带head plugin,用于监 ...
- wed开发基础--练习题
一.HTML部分 本小节重点: 熟练使用div+span布局,知道div和span的语义化的意思 熟悉对div.ul.li.span.a.img.table.form.input标签有深刻的认知, 初 ...