zoukankan      html  css  js  c++  java
  • 【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

  • 相关阅读:
    juc之ConcurrentHashMap在我工作中的实践
    设计模式在我工作中的实践
    SpringBoot突报java.lang.NoSuchFieldError分析
    JQuery.UI类库AutoComplete 调用WebService进行模糊查询
    DevExpress控件库----LookUpEdit控件 和 GridLookUpEdit控件使用
    DevExpress控件库----FlyoutPanel提示控件
    Android学习笔记---Log与Activity生命周期
    DevExpress控件库---MarqueeProgressBarControl控件和ProgressBarControl控件
    DevExpress控件库---TokenEdit控件使用
    DevExpress控件库----SearchLookUpEdit控件
  • 原文地址:https://www.cnblogs.com/cknightx/p/6896099.html
Copyright © 2011-2022 走看看