包含头文件:

#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】第一个窗口的更多相关文章

  1. Axiom3D写游戏:第一个窗口

    Axiom主要的代码大致翻看了下,就想到了自己来模拟一下游戏开发. 这章主要包括创建窗口及3D渲染的一些基本元素,并添加一个第三人称的骨骼动画作主角,加上前文中修改过后的地形组件,能用鼠标和键盘进行漫 ...

  2. delphi程序向另一个可执行程序发消息(使用GetForegroundWindow; 找出当前操作系统中活动的第一个窗口)

    function FindWindowThroughWindowText(WindowText: string): THandle;var  hCurrentWindow: THandle;  cnt ...

  3. OpenGL教程(2)——第一个窗口

    OpenGL环境终于配置好了,现在我们可以开始学习OpenGL了. 首先,创建一个.cpp文件,然后打上几行#include指令: #include <iostream> using st ...

  4. OpenGL学习(2)—— 创建第一个窗口

    创建 GLFW GLFW是一个专门针对OpenGL的C语言库,它提供了一些渲染物体所需的最低限度的接口.它允许用户创建OpenGL上下文,定义窗口参数以及处理用户输入,这正是我们需要的. #inclu ...

  5. pygame_第一个窗口程序

    ####可以使用python自带的IDLE交互式开发,也可以借助其他的编辑器,我这里采用的pycharm编辑器 1.导入我们所需要的模块 import pygame,sys   --导入我们需要的模块 ...

  6. (1)pygame_第一个窗口程序

    ####可以使用python自带的IDLE交互式开发,也可以借助其他的编辑器,我这里采用的pycharm编辑器 1.导入我们所需要的模块 import pygame,sys   --导入我们需要的模块 ...

  7. 学习opengl第一步

    有两个地址一个是学习opengl基础知识的网站, 一个是博客园大牛分享的特别好的文章. 记录一下希望向坚持做俯卧撑一样坚持下去. 学习网站:http://learnopengl-cn.readthed ...

  8. vscode源码分析【二】程序的启动逻辑,第一个窗口是如何创建的

    上一篇文章:https://www.cnblogs.com/liulun/ (小广告:我做的开源免费的,个人知识管理及自媒体营销工具“想学吗”:https://github.com/xland/xia ...

  9. opengl第一个工程

    #include <iostream> #include <glad/glad.h> #include <GLFW/glfw3.h> void framebuffe ...

随机推荐

  1. java-代码生成器

    package ormRex; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import ...

  2. python tkinter chk

    视频过程中的练习, 可以在python2.7下运行. 001: hello,world: 1 2 3 4 5 6 from Tkinter import Label, Tk root = Tk() t ...

  3. 【Social Listening实战】当数据分析遭遇心理动力学:用户深层次的情感需求浮出水面

    本文转自知乎 作者:苏格兰折耳喵 ----------------------------------------------------- 本文篇幅较长,分为五部分,在中间部分有关于心理分析工具的介 ...

  4. RMI non-JRMP server at remote endpoint

    又是一个jmx问题 jmx明明端口占用了, 而且相关java进程也起来了, 为什么会不能通过jconsole访问jmx呢?总是:RMI non-JRMP server at remote endpoi ...

  5. http://www.cnblogs.com/hanshuhe/archive/2012/08/30/vss.html

    http://www.cnblogs.com/hanshuhe/archive/2012/08/30/vss.html

  6. AES-128-CBC C语言代码

    /** * Copyright (c) 2007, Cameron Rich * * All rights reserved. * * Redistribution and use in source ...

  7. addEventListener 的事件冒泡

    语法 target.addEventListener(type, listener, useCapture); target 文档节点.document.window 或 XMLHttpRequest ...

  8. static,final的用法

    static的用法:修鉓符,修鉓属性,方法,代码块a1.修鉓属性:该属性是一个静态的属性,叫类的成员(没有static修鉓的属性叫实例的成员,调用时用:对象名.属性),调用:类名.属性.a2.修鉓方法 ...

  9. OS位数,基本概念,结合iOS

    CPU位数,一般指CPU支持的指令集位数,32位CPU对应32位的指令集,64位的CPU对应64位的指令集,不过为了向下兼容,64位CPU也支持32位的指令集. 操作系统位数,一般指操作系统对应的指令 ...

  10. SignalR快速入门

    本篇是SignalR系列教程的第一篇,本篇内容介绍了如何创建SignalR应用,如何利用SignalR搭建简易的聊天室等,本篇内容参考自:http://www.asp.net/signalr/over ...