Glew的配置与使用

参考网址:https://learnopengl-cn.github.io/legacy/

编译和链接GLEW

  • OpenGL定义的这些GL基元类型的内存布局是与平台无关的,使用GL基元类型可以保证你的程序在不同的平台上工作一致。
  • GLEW是OpenGL Extension Wrangler Library的缩写,因为GLEW也是一个库,我们同样需要构建并将其链接进工程。
  • Glew的下载地址为:http://glew.sourceforge.net/index.html
  • 对于Glew的选择,如果不确定的话,选择32位的二进制版本。
  • 使用GLEW的静态版本glew32s.lib(注意这里的“s”),将库文件添加到你的库目录,将include内容添加到你的include目录。接下来,在VS的链接器选项里加上glew32s.lib

GLEW的初始化

  • GLEW是用来管理OpenGL的函数指针的,所以在调用任何OpenGL的函数之前我们需要初始化GLEW。
  • 我们在初始化GLEW之前设置glewExperimental变量的值为GL_TRUE,这样做能让GLEW在管理OpenGL的函数指针时更多地使用现代化的技术。

视口

  • 我们必须告诉OpenGL渲染窗口的尺寸大小,这样OpenGL才只能知道怎样相对于窗口大小显示数据和坐标。
  • 我们可以通过调用glViewport函数来设置窗口的维度。
  • glViewport函数前两个参数控制窗口左下角的位置。第三个和第四个参数控制渲染窗口的宽度和高度(像素)。
  • 实际上也可以将视口的维度设置为比GLFW的维度小,这样子之后所有的OpenGL渲染将会在一个更小的窗口中显示。
  • OpenGL幕后使用glViewport中定义的位置和宽高进行2D坐标的转换,将OpenGL中的位置坐标转换为你的屏幕坐标。处理过的OpenGL坐标范围只为-1到1。
  • 具体的应用示例:

输入

  • 按键回调是众多回调函数中的一种。当我们设置了按键回调之后,GLFW会在用户有键盘交互时调用它。
  • 按键回调函数接受一个GLFWwindow指针作为它的第一个参数;第二个整形参数用来表示按下的按键;action参数表示这个按键是被按下还是释放;最后一个整形参数表示是否有Ctrl、Shift、Alt、Super等按钮的操作。
  • 具体的示例:
  • 上述实例说明:在我们(新创建的)key_callback函数中,我们检测了键盘是否按下了Escape键。如果键的确按下了(不释放),我们使用glfwSetwindowShouldClose函数设定WindowShouldClose属性为true从而关闭GLFW。main函数的while循环下一次的检测将为失败,程序就关闭了。
  • 最后就是通过GLFW注册我们的函数至合适的回调:

SOIL

  • SOIL是简易OpenGL图像库(Simple OpenGL Image Library)的缩写,它支持大多数流行的图像格式。
  • SOIL的下载网址:http://www.lonesock.net/soil.html
  • 要想使用SOIL必须自己生成.lib。可以使用/projects文件夹内的任意一个解决方案(Solution)文件。还要添加src文件夹里面的文件到includes文件夹;将SOIL.lib添加到链接器选项,并在代码文件的开头加上#include <SOIL.h>
  • 使用SOIL加载图片的示例:
  • 函数首先需要输入图片文件的路径。然后需要两个int指针作为第二个和第三个参数,SOIL会分别返回图片的宽度高度到其中。后面我们在生成纹理的时候会用图像的宽度和高度。第四个参数指定图片的通道(Channel)数量,但是这里我们只需留为0。最后一个参数告诉SOIL如何来加载图片:我们只关注图片的RGB值。结果会储存为一个很大的char/byte数组。

生成纹理

  • 纹理是使用ID引用的。glGenTextures函数首先需要输入生成纹理的数量,然后把它们储存在第二个参数的GLuint数组中。
  • 我们需要绑定它,让之后任何的纹理指令都可以配置当前绑定的纹理。
  • 我们可以使用前面载入的图片数据生成一个纹理了。纹理可以通过glTexImage2D来生成:
  • 当调用glTexImage2D时,当前绑定的纹理对象就会被附加上纹理图像。然而,目前只有基本级别(Base-level)的纹理图像被加载了,如果要使用多级渐远纹理,我们必须手动设置所有不同的图像(不断递增第二个参数)。或者,直接在生成纹理之后调用glGenerateMipmap。这会为当前绑定的纹理自动生成所有需要的多级渐远纹理。
  • 释放图像的内存并解绑纹理对象操作。
  • 生成一个纹理的完整过程

纹理单元

  • 一个纹理的位置值通常称为一个纹理单元,一个纹理的默认纹理单元是0,它是默认的激活纹理单元。
  • 使用glUniform1i,我们可以给纹理采样器分配一个位置值,这样的话我们能够在一个片段着色器中设置多个纹理。
  • 纹理单元的主要目的是让我们在着色器中可以使用多于一个的纹理。通过把纹理单元赋值给采样器,我们可以一次绑定多个纹理。
  • 我们可以使用glActiveTexture激活纹理单元,传入我们需要使用的纹理单元:
  • 激活纹理单元之后,接下来的glBindTexture函数调用会绑定这个纹理到当前激活的纹理单元。纹理单元GL_TEXTURE0默认总是被激。
  • 我们需要编辑片段着色器来接收另一个采样器,具体的演示示例如下:
  • 最终输出颜色现在是两个纹理的结合。GLSL内建的mix函数需要接受两个值作为参数,并对它们根据第三个参数进行线性插值。如果第三个值是0.0,它会返回第一个输入;如果是1.0,会返回第二个输入值。0.2会返回80%的第一个输入颜色和20%的第二个输入颜色,即返回两个纹理的混合色。
  • 先绑定两个纹理到对应的纹理单元,然后定义哪个uniform采样器对应哪个纹理单元:
  • 我们使用glUniform1i设置uniform采样器的位置值,或者说纹理单元。通过glUniform1i的设置,我们保证每个uniform采样器对应着正确的纹理单元。
  • 根据上图可以发现:纹理上下颠倒了。这是因为OpenGL要求y轴0.0坐标是在图片的底部的,但是图片的y轴0.0坐标通常在顶部。一些图片加载器比如Devil在加载的时候有选项重置y原点,但是SOIL没有。
  • SOIL却有一个叫做SOIL_load_OGL_texture函数可以使用一个叫做SOIL_FLAG_INVERT_Y的标记加载生成纹理,这可以解决我们的问题。不过这个函数用了一些在现代OpenGL中失效的特性。
  • 修复我们的小问题,有两个选择:

  • (1)我们可以改变顶点数据的纹理坐标,翻转y值(用1减去y坐标)。
  • (2)我们可以编辑顶点着色器来自动翻转y坐标,替换TexCoord的值为TexCoord = vec2(texCoord.x, 1.0f - texCoord.y);

摄像机-自由移动

  • 首先我们必须设置一个摄像机系统,所以在我们的程序前面定义一些摄像机变量很有用:
  • 我们首先将摄像机位置设置为之前定义的cameraPos。方向是当前的位置加上我们刚刚定义的方向向量。
  • 当我们按下WASD键的任意一个,摄像机的位置都会相应更新。如果我们希望向前或向后移动,我们就把位置向量加上或减去方向向量。如果我们希望向左右移动,我们使用叉乘来创建一个右向量(Right Vector),并沿着它相应移动就可以了。这样就创建了使用摄像机时熟悉的扫射(Strafe)效果。
  • 因为大多数事件输入系统一次只能处理一个键盘输入,它们的函数只有当我们激活了一个按键时才被调用。

猜你喜欢

转载自blog.csdn.net/LYKymy/article/details/83033122
今日推荐