(Hello OpenGL!)创建窗口

Posted on 2017-08-24 15:10  涯止  阅读(40)  评论(0)    收藏  举报

  今天开始学习OpenGL了,记录一下学习过程与知识总结。开始吧!

  这个教程使用的是GLFW与GLAD,教程地址是https://learnopengl-cn.github.io/。关于openGL环境的配置在这里就不多说了,直接开始代码的内容吧。

 

  首先,因为使用的是GLFW,刚开始自然是对GLFW进行一个初始化。

1 glfwInit();
2 glfwWindowHint(GLFW_VERSION_MAJOR, 3);
3 glfwWindowHint(GLFW_VERSION_MINOR, 3);
4 glfwWindowHint(GLFW_OPENGL_ANY_PROFILE, GLFW_OPENGL_CORE_PROFILE);

  其中第一行对于GLFW进行了初始化,随后三行对于GLFW做了相关的配置。2、3行指明版本,第4行则是告诉GLFW,我们要使用openGL的“核心模式”(Core-profile)。

  接下来我们创建一个窗体实例,并把窗口设置为当前线程的上下文(context):

  

GLFWwindow *window = glfwCreateWindow(800, 600, "Texture", NULL, NULL);
 if (!window)
 {
  std::cout << "Failed to init window" << std::endl;
  return -1;
 }
 glfwMakeContextCurrent(window);

  这样我们就可以在这个窗口上进行一些绘制。

  然而,在正式调用openGL的函数之前,我们还需要做一些工作。

  因为openGL是由显卡厂商提供的,我们需要加载系统相关的OpenGL函数指针地址,这时就要用到glad了。

  

if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
        std::cout << "failed to init glad" << std::endl;
    return -1;
}    

  glfwGetProcAddress会根据我们编译的系统定义正确的函数。

  至此,准备工作就做完了。

  

  接下来,让我们设置一下视口(vireport),用于显示东西。

  可以简单的用glViewport函数完成

  

void frameSize(GLFWwindow* window, int width, int height)
{
    glViewport(0, 0, width, height);
}

  因为要根据窗口的大小来改变视口的大小,因此将它写成一个函数。之后通过

glfwSetFramebufferSizeCallback(window, frameSize);

  设置为回调函数,这样,在改变窗口大小的时候,frameSize函数会自动被系统调用,自动调整视口的大小。

  接下来,我们创建一个render loop

  

 while (!glfwWindowShouldClose(window))
  {
      processInput(window);
      glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
      glClear(GL_COLOR_BUFFER_BIT);
    
    // 交换颜色缓冲 glfwSwapBuffers(window);
    // 检查有没有触发什么事件(比如键盘输入、鼠标移动等)、更新窗口状态,并调用对应的回调函数(可以通过回调方法手动设置)
glfwPollEvents(); }

  这就创建好了一个窗口:

  

  完整代码如下(这里就直接贴教程那边的教程啦2333):

  

#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include <iostream>

void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow *window);

// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;

int main()
{
    // glfw: initialize and configure
    // ------------------------------
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

#ifdef __APPLE__
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X
#endif

    // glfw window creation
    // --------------------
    GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
    if (window == NULL)
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

    // glad: load all OpenGL function pointers
    // ---------------------------------------
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }    

    // render loop
    // -----------
    while (!glfwWindowShouldClose(window))
    {
        // input
        // -----
        processInput(window);

        // render
        // ------
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
        // -------------------------------------------------------------------------------
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    // glfw: terminate, clearing all previously allocated GLFW resources.
    // ------------------------------------------------------------------
    glfwTerminate();
    return 0;
}

// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow *window)
{
    if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);
}

// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
    // make sure the viewport matches the new window dimensions; note that width and 
    // height will be significantly larger than specified on retina displays.
    glViewport(0, 0, width, height);
}