openGL系列文章目录

文章目录

  • openGL系列文章目录
  • 前言
  • 一、代码
    • 1.主程序
  • 二、着色器程序
    • 1.顶点着色器
    • 2.片元着色器
  • 运行效果
  • 总结
  • 源码下载

前言

在照明和材质章节中,我们考虑了物体的“光泽”。然而,我们从未对非常闪亮的物体
进行建模,例如镜子或铬制品。这些物体在有小范围镜面高光的同时,还能够反射出周围
物体的镜像。当我们看向这些物品时,我们会看到房间里的其他东西,有时甚至会看到我
们自己的倒影。ADS 照明模型并没有提供模拟这种效果的方法。
不过,纹理立方体贴图提供了一种相对简单的方法来模拟(至少部分模拟)反射表面。
其诀窍是使用立方体贴图来构造反射对象本身。①如果想要做得看起来真实,则需要找我们
从物体上看到的周围环境所对应的纹理坐标。
图1 展示了使用视图向量和法向量组合计算反射向量的策略,之后,该反射向量会用
来从立方体贴图中查找纹素。因此,反射向量可用来直接访问纹理立方体贴图。当立方体
贴图用于上述功能时,称其为环境贴图。
我们在之前研究Blinn-Phong 照明时计算过反射向量。除了我们现在使用反射向量从纹
理贴图中查找值,这里的反射向量概念和之前类似。这种技术称为环境贴图或反射贴图。
如果使用我们描述的第二种方法(在9.3.2 小节中,使用OpenGL GL_TEXTURE_CUBE_MAP)
实现立方体贴图,那么OpenGL 可以使用与之前为立方体添加纹理相同的方法来进行环境
贴图查找。我们使用视图向量和曲面法向量计算视图向量对应的离开对象表面的反射向量。
然后可以使用反射向量直接对纹理立方体贴图图像进行采样。查找过程由OpenGL
samplerCube 辅助实现;回忆上一节中,samplerCube 使用视图方向向量索引。因此,反射
向量非常适用于查找所需的纹素。

                                                    图1

实现环境贴图需要添加相对少量的代码。程序9.3 展示了display()函数和init()函数以及
相关着色器中的更改,以使用环境贴图渲染“反射”环面。所有更改都已经高亮显示。值
得注意的是,如果使用了Blinn-Phong 照明,那么很多需要添加的代码可能已经存在了。真
正新的代码部分在片段着色器中[在main()函数中]。
乍一看程序中突出显示的代码好像并不是新代码。实际上,在我们研究照明的时候,
已经看到过几乎相同的代码。然而,在当前情况下,法向量和反射向量用于完全不同的目
的。在之前的代码中,它们用于实现ADS 照明模型。而在这里,它们用于计算环境贴图的
纹理坐标。因此,我们将部分代码高亮,以便读者可以更轻松地追踪法向量和反射向量计
算的使用,以实现这一新目的。
渲染的结果会显示使用了环境贴图的“铬制”环面,如图2 所示。

图2

一、代码

1.主程序

#include <GL\glew.h>
#include <GLFW\glfw3.h>
#include <SOIL2\soil2.h>
#include <string>
#include <iostream>
#include <fstream>
#include <glm\gtc\type_ptr.hpp> // glm::value_ptr
#include <glm\gtc\matrix_transform.hpp> // glm::translate, glm::rotate, glm::scale, glm::perspective
#include "Torus.h"
#include "Utils.h"
using namespace std;float toRadians(float degrees) { return (degrees * 2.0f * 3.14159f) / 360.0f; }#define numVAOs 1
#define numVBOs 4Utils util = Utils();
float cameraX, cameraY, cameraZ;
float torLocX, torLocY, torLocZ;
GLuint renderingProgram, renderingProgramCubeMap;
GLuint vao[numVAOs];
GLuint vbo[numVBOs];
GLuint skyboxTexture;
float rotAmt = 0.0f;// variable allocation for display
GLuint vLoc, mvLoc, projLoc, nLoc;
int width, height;
float aspect;
glm::mat4 pMat, vMat, mMat, mvMat, invTrMat;Torus myTorus(0.8f, 0.4f, 48);
int numTorusVertices, numTorusIndices;void setupVertices(void) {float cubeVertexPositions[108] ={  -1.0f,  1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f,1.0f, -1.0f, -1.0f, 1.0f,  1.0f, -1.0f, -1.0f,  1.0f, -1.0f,1.0f, -1.0f, -1.0f, 1.0f, -1.0f,  1.0f, 1.0f,  1.0f, -1.0f,1.0f, -1.0f,  1.0f, 1.0f,  1.0f,  1.0f, 1.0f,  1.0f, -1.0f,1.0f, -1.0f,  1.0f, -1.0f, -1.0f,  1.0f, 1.0f,  1.0f,  1.0f,-1.0f, -1.0f,  1.0f, -1.0f,  1.0f,  1.0f, 1.0f,  1.0f,  1.0f,-1.0f, -1.0f,  1.0f, -1.0f, -1.0f, -1.0f, -1.0f,  1.0f,  1.0f,-1.0f, -1.0f, -1.0f, -1.0f,  1.0f, -1.0f, -1.0f,  1.0f,  1.0f,-1.0f, -1.0f,  1.0f,  1.0f, -1.0f,  1.0f,  1.0f, -1.0f, -1.0f,1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f,  1.0f,-1.0f,  1.0f, -1.0f, 1.0f,  1.0f, -1.0f, 1.0f,  1.0f,  1.0f,1.0f,  1.0f,  1.0f, -1.0f,  1.0f,  1.0f, -1.0f,  1.0f, -1.0f};numTorusVertices = myTorus.getNumVertices();numTorusIndices = myTorus.getNumIndices();std::vector<int> ind = myTorus.getIndices();std::vector<glm::vec3> vert = myTorus.getVertices();std::vector<glm::vec2> tex = myTorus.getTexCoords();std::vector<glm::vec3> norm = myTorus.getNormals();std::vector<float> pvalues;std::vector<float> tvalues;std::vector<float> nvalues;for (int i = 0; i < numTorusVertices; i++) {pvalues.push_back(vert[i].x);pvalues.push_back(vert[i].y);pvalues.push_back(vert[i].z);tvalues.push_back(tex[i].s);tvalues.push_back(tex[i].t);nvalues.push_back(norm[i].x);nvalues.push_back(norm[i].y);nvalues.push_back(norm[i].z);}glGenVertexArrays(1, vao);glBindVertexArray(vao[0]);glGenBuffers(numVBOs, vbo);glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertexPositions), cubeVertexPositions, GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);glBufferData(GL_ARRAY_BUFFER, pvalues.size() * 4, &pvalues[0], GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);glBufferData(GL_ARRAY_BUFFER, nvalues.size() * 4, &nvalues[0], GL_STATIC_DRAW);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[3]);glBufferData(GL_ELEMENT_ARRAY_BUFFER, ind.size() * 4, &ind[0], GL_STATIC_DRAW);
}void init(GLFWwindow* window) {renderingProgram = Utils::createShaderProgram("vertShader.glsl", "fragShader.glsl");renderingProgramCubeMap = Utils::createShaderProgram("vertCShader.glsl", "fragCShader.glsl");glfwGetFramebufferSize(window, &width, &height);aspect = (float)width / (float)height;pMat = glm::perspective(1.0472f, aspect, 0.1f, 1000.0f);setupVertices();skyboxTexture = Utils::loadCubeMap("cubeMap"); // expects a folder nameglEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);torLocX = 0.0f; torLocY = 0.0f; torLocZ = 0.0f;cameraX = 0.0f; cameraY = 0.0f; cameraZ = 5.0f;
}void display(GLFWwindow* window, double currentTime) {glClear(GL_DEPTH_BUFFER_BIT);glClear(GL_COLOR_BUFFER_BIT);vMat = glm::translate(glm::mat4(1.0f), glm::vec3(-cameraX, -cameraY, -cameraZ));// draw cube mapglUseProgram(renderingProgramCubeMap);vLoc = glGetUniformLocation(renderingProgramCubeMap, "v_matrix");glUniformMatrix4fv(vLoc, 1, GL_FALSE, glm::value_ptr(vMat));projLoc = glGetUniformLocation(renderingProgramCubeMap, "p_matrix");glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(pMat));glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);glEnableVertexAttribArray(0);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_CUBE_MAP, skyboxTexture);glEnable(GL_CULL_FACE);glFrontFace(GL_CCW);   // cube is CW, but we are viewing the insideglDisable(GL_DEPTH_TEST);glDrawArrays(GL_TRIANGLES, 0, 36);glEnable(GL_DEPTH_TEST);// draw scene (in this case it is just a torus)glUseProgram(renderingProgram);mvLoc = glGetUniformLocation(renderingProgram, "mv_matrix");projLoc = glGetUniformLocation(renderingProgram, "proj_matrix");nLoc = glGetUniformLocation(renderingProgram, "normalMat");rotAmt += 0.01f;mMat = glm::translate(glm::mat4(1.0f), glm::vec3(torLocX, torLocY, torLocZ));mMat = glm::rotate(mMat, rotAmt, glm::vec3(1.0f, 0.0f, 0.0f));mvMat = vMat * mMat;invTrMat = glm::transpose(glm::inverse(mvMat));glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvMat));glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(pMat));glUniformMatrix4fv(nLoc, 1, GL_FALSE, glm::value_ptr(invTrMat));glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);glEnableVertexAttribArray(0);glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);glEnableVertexAttribArray(1);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_CUBE_MAP, skyboxTexture);glClear(GL_DEPTH_BUFFER_BIT);glEnable(GL_CULL_FACE);glFrontFace(GL_CCW);glDepthFunc(GL_LEQUAL);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[3]);glDrawElements(GL_TRIANGLES, numTorusIndices, GL_UNSIGNED_INT, 0);
}void window_size_callback(GLFWwindow* win, int newWidth, int newHeight) {aspect = (float)newWidth / (float)newHeight;glViewport(0, 0, newWidth, newHeight);pMat = glm::perspective(1.0472f, aspect, 0.1f, 1000.0f);
}int main(void) {if (!glfwInit()) { exit(EXIT_FAILURE); }glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);GLFWwindow* window = glfwCreateWindow(800, 800, "Chapter9 - program2", NULL, NULL);glfwMakeContextCurrent(window);if (glewInit() != GLEW_OK) { exit(EXIT_FAILURE); }glfwSwapInterval(1);glfwSetWindowSizeCallback(window, window_size_callback);init(window);while (!glfwWindowShouldClose(window)) {display(window, glfwGetTime());glfwSwapBuffers(window);glfwPollEvents();}glfwDestroyWindow(window);glfwTerminate();exit(EXIT_SUCCESS);
}

二、着色器程序

1.顶点着色器

#version 430layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
out vec3 vNormal;
out vec3 vVertPos;uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
uniform mat4 normalMat;
layout (binding = 0) uniform samplerCube t;void main(void)
{vVertPos = (mv_matrix * vec4(position,1.0)).xyz;vNormal = (normalMat * vec4(normal,1.0)).xyz;gl_Position = proj_matrix * mv_matrix * vec4(position,1.0);
}
#version 430layout (location = 0) in vec3 position;
out vec3 tc;uniform mat4 v_matrix;
uniform mat4 p_matrix;
layout (binding = 0) uniform samplerCube samp;void main(void)
{tc = position;mat4 v3_matrix = mat4(mat3(v_matrix));gl_Position = p_matrix * v3_matrix * vec4(position,1.0);
}

2.片元着色器

#version 430in vec3 vNormal;
in vec3 vVertPos;
out vec4 fragColor;uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
uniform mat4 normalMat;
layout (binding = 0) uniform samplerCube t;void main(void)
{vec3 r = -reflect(normalize(-vVertPos), normalize(vNormal));fragColor = texture(t,r);
}
#version 430in vec3 tc;
out vec4 fragColor;uniform mat4 v_matrix;
uniform mat4 p_matrix;
layout (binding = 0) uniform samplerCube samp;void main(void)
{fragColor = texture(samp,tc);
}

运行效果

总结

虽然该场景需要两组着色器—— 一组用于立方体贴图,另一组用于环面——但是程序9.3
中仅展示了用于绘制环面的着色器。这是因为用于渲染立方体贴图的着色器与程序9.2 中的
相同。通过对程序 的修改得到程序 的过程,总结如下。
在init()函数中:

openGL环境贴图相关推荐

  1. OpenGL 光照贴图Lighting maps

    OpenGL光照贴图Lighting maps 光照贴图Lighting maps简介 漫反射贴图 镜面光贴图 采样镜面光贴图 光照贴图Lighting maps简介 在上一节中,我们讨论了让每个物体 ...

  2. C++ Opengl纹理贴图源码

    C++ Opengl纹理贴图源码 项目开发环境 项目功能 项目演示 项目源码传送门 项目开发环境 开发语言:C++和IDE:VS2017,操作系统Windows版本windows SDK8.1,三方库 ...

  3. Win10系统配置Python3.6+OpenGL环境详细步骤

    1.首先登录https://www.opengl.org/resources/libraries/glut/,下载下图箭头所指的文件 2.解压缩,如下图所示: 3.粗暴一点,把这些文件全部选中,然后复 ...

  4. VS2010/VS2012/VS2015下openGL环境配置(转)

    按:按照下述博文,三个例子均成功. https://blog.csdn.net/so_geili/article/details/51685005 请仔细阅读每一个字. 为了学习<OpenGL超 ...

  5. OpenGL 立方体贴图Cubemaps

    OpenGL立方体贴图Cubemaps 立方体贴图Cubemaps简介 创建立方体贴图 天空盒 加载天空盒 显示天空盒 优化 环境映射 反射 折射 动态环境贴图 立方体贴图Cubemaps简介 我们已 ...

  6. win10python详细配置_Win10系统配置Python3.6+OpenGL环境详细步骤

    原标题:Win10系统配置Python3.6+OpenGL环境详细步骤 1.首先登录https://www.opengl.org/resources/libraries/glut/,下载下图箭头所指的 ...

  7. OpenGL环境搭建:vs2013+freeglut2.8.1+glew1.7.0+gltools

    前言:之前同事说OpenGL环境贼难搭建,搭建了好多次都没成功过.恰巧最近自己也在学习OpenGL超级宝典,开发环境这块必须得支持,否则往后学习就是光看不练假把式了.于是今天特意花了一上午时间上网搜索 ...

  8. OpenGL蓝宝书学习日记(1)—— 配置OpenGL环境与创造第一个三角形

    OpenGL蓝宝书学习日记(1)-- 配置OpenGL环境与创造第一个三角形 一.安装VS VS有众多版本,本人使用的是VS2017,在官网即可下载,有为学生专门提供的免费版,注册账号登陆后即可无限试 ...

  9. OpenGL立方体贴图

    OpenGL 立方贴图 Copyright NVIDIA Corporation, 1999. Commercial publication in written, electronic, or ot ...

最新文章

  1. HDFS【2.5.1】系列1:HDFS的核心数据结构---元数据
  2. 以游戏演绎1200多年前的古诗——《画境长恨歌》叙事设计思路分享
  3. 正在创建系统还原点_如何使Windows在启动时自动创建系统还原点
  4. 到底什么是 OAuth 2.0
  5. 鸿蒙和宙斯谁厉害,漫威宇宙宙斯vs奥丁,到底谁更强
  6. HBase数据读取流程解析
  7. 读取和设置SPFIELD的值
  8. Q96:PT(3):基于噪声的纹理(Noise-Based Textures)(0)——概述
  9. 【转】理清基本的git(github)流程
  10. java lambda有必要_深度分析:java8的新特性lambda和stream流,看完你学会了吗?
  11. React封装多个日期段组件--BatchDate组件
  12. SQL数据库笔试选择题(知识点总结)
  13. 成都中医药大学计算机基础试题,成都中医药大学2016年春季学期期末考试.计算机基础试卷-成教(答案~)分析总结.doc...
  14. abaqus .cae文件默认程序设置
  15. UVA 1001 Say Cheese(最短路)
  16. 艺赛旗(RPA)python 的 tkinter 进度条的实现
  17. 第七章、Spring Boot MyBatis升级篇
  18. 183 25用计算机算列竖式,新北师大四年级上册数学计算题
  19. linux系列之-jar包文件替换
  20. 六级考研单词之路-四十八

热门文章

  1. 用原生JS实现网页调用系统自带的分享功能
  2. 【UCIe】UCIe 数据完整性
  3. css浅紫色,一款淡紫色纯CSS实现的开关/单选和复选组件
  4. WebQQ协议分析(1)——登录
  5. 电池pack结构_详解锂电池pack基础知识,18650锂电池pack工艺技巧总结分析
  6. 各类线下营销活动如何做好推广?推荐一款仿微信公众号的链接
  7. Hadoop集群扩容新增4T硬盘(解决分区大小问题限制2T问题)
  8. BeanDefinition介绍
  9. Mysql索引分类及其使用实例
  10. 面向金融行业项目实施及开发。