OpenGL--材质
目录(?)[+]
一、 材质
通过为每个元素指定一个颜色,我们已经对物体的颜色输出有了精密的控制。现在把一个镜面高光元素添加到这三个颜色里,这是我们需要的所有材质属性:
#version 330 core
struct Material
{vec3 ambient;vec3 diffuse;vec3 specular;float shininess;
};
uniform Material material;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
1. 设置材质
由于所有材质元素都储存在结构体中,我们可以从uniform变量material取得它们:
void main()
{// 环境光vec3 ambient = lightColor * material.ambient;// 漫反射光vec3 norm = normalize(Normal);vec3 lightDir = normalize(lightPos - FragPos);float diff = max(dot(norm, lightDir), 0.0);vec3 diffuse = lightColor * (diff * material.diffuse);// 镜面高光vec3 viewDir = normalize(viewPos - FragPos);vec3 reflectDir = reflect(-lightDir, norm);float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);vec3 specular = lightColor * (spec * material.specular);vec3 result = ambient + diffuse + specular;color = vec4(result, 1.0f);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
一个结构体值扮演uniform变量的封装体,所以如果我们希望填充这个结构体,我们就仍然必须设置结构体中的各个元素的uniform值,但是这次带有结构体名字作为前缀:
GLint matAmbientLoc = glGetUniformLocation(lightingShader.Program, "material.ambient");
GLint matDiffuseLoc = glGetUniformLocation(lightingShader.Program, "material.diffuse");
GLint matSpecularLoc = glGetUniformLocation(lightingShader.Program, "material.specular");
GLint matShineLoc = glGetUniformLocation(lightingShader.Program, "material.shininess");glUniform3f(matAmbientLoc, 1.0f, 0.5f, 0.31f);
glUniform3f(matDiffuseLoc, 1.0f, 0.5f, 0.31f);
glUniform3f(matSpecularLoc, 0.5f, 0.5f, 0.5f);
glUniform1f(matShineLoc, 32.0f);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
2. 光的属性
前面的教程,我们通过使用一个强度值改变环境和镜面强度的方式解决了这个问题。我们想做一个相同的系统,但是这次为每个光照元素指定了强度向量。如果我们想象lightColor是vec3(1.0),代码看起来像是这样:
vec3 ambient = vec3(1.0f) * material.ambient;
vec3 diffuse = vec3(1.0f) * (diff * material.diffuse);
vec3 specular = vec3(1.0f) * (spec * material.specular);
- 1
- 2
- 3
所以物体的每个材质属性返回了每个光照元素的全强度。这些vec3(1.0)值可以各自独立的影响各个光源,这通常就是我们想要的。现在物体的ambient元素完全地展示了立方体的颜色,可是环境元素不应该对最终颜色有这么大的影响,所以我们要设置光的ambient亮度为一个小一点的值,从而限制环境色:
vec3 result = vec3(0.1f) * material.ambient;
- 1
我们可以用同样的方式影响光源diffuse和specular的强度。这和我们前面教程所做的极为相似;你可以说我们已经创建了一些光的属性来各自独立地影响每个光照元素。我们希望为光的属性创建一些与材质结构体相似的东西:
struct Light
{vec3 position;vec3 ambient;vec3 diffuse;vec3 specular;
};
uniform Light light;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
一个光源的ambient、diffuse和specular光都有不同的亮度。环境光通常设置为一个比较低的亮度,因为我们不希望环境色太过显眼。光源的diffuse元素通常设置为我们希望光所具有的颜色;经常是一个明亮的白色。specular元素通常被设置为vec3(1.0f)类型的全强度发光。要记住的是我们同样把光的位置添加到结构体中。
就像材质uniform一样,需要更新片段着色器:
vec3 ambient = light.ambient * material.ambient;
vec3 diffuse = light.diffuse * (diff * material.diffuse);
vec3 specular = light.specular * (spec * material.specular);
- 1
- 2
- 3
然后我们要在应用里设置光的亮度:
GLint lightAmbientLoc = glGetUniformLocation(lightingShader.Program, "light.ambient");
GLint lightDiffuseLoc = glGetUniformLocation(lightingShader.Program, "light.diffuse");
GLint lightSpecularLoc = glGetUniformLocation(lightingShader.Program, "light.specular");glUniform3f(lightAmbientLoc, 0.2f, 0.2f, 0.2f);
glUniform3f(lightDiffuseLoc, 0.5f, 0.5f, 0.5f);// 让我们把这个光调暗一点,这样会看起来更自然
glUniform3f(lightSpecularLoc, 1.0f, 1.0f, 1.0f);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
3. 不同光源颜色
利用sin和glfwGetTime改变光的环境和漫反射颜色,我们可以随着时间流逝简单的改变光源颜色:
glm::vec3 lightColor; lightColor.x = sin(glfwGetTime() * 2.0f);
lightColor.y = sin(glfwGetTime() * 0.7f);
lightColor.z = sin(glfwGetTime() * 1.3f);glm::vec3 diffuseColor = lightColor * glm::vec3(0.5f);
glm::vec3 ambientColor = diffuseColor * glm::vec3(0.2f);glUniform3f(lightAmbientLoc, ambientColor.x, ambientColor.y, ambientColor.z);
glUniform3f(lightDiffuseLoc, diffuseColor.x, diffuseColor.y, diffuseColor.z);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
二、 光照贴图
前面的材质系统对于除了最简单的模型以外都是不够的,所以我们需要扩展前面的系统,我们要介绍diffuse和specular贴图。它们允许你对一个物体的diffuse(而对于简洁的ambient成分来说,它们几乎总是是一样的)和specular成分能够有更精确的影响。
1. 漫反射贴图
在光照场景中,通过纹理来呈现一个物体的diffuse颜色,这个做法被称做漫反射贴图(Diffuse texture)。为了演示漫反射贴图,我们将会使用下面的图片,它是一个有一圈钢边的木箱:
在着色器中使用漫反射贴图和纹理教程介绍的一样。这次我们把纹理以sampler2D类型储存在Material结构体中。我们使用diffuse贴图替代早期定义的vec3类型的diffuse颜色。
struct Material
{sampler2D diffuse;vec3 specular;float shininess;
};
...
in vec2 TexCoords;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
注意,在片段着色器中我们将会再次需要纹理坐标,所以我们声明一个额外输入变量。然后我们简单地从纹理采样,来获得原始像素的diffuse颜色值:
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
- 1
同样,不要忘记把ambient材质的颜色设置为diffuse材质的颜色:
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
- 1
为了让它工作,我们需要用到纹理坐标更新顶点数据,把它们作为顶点属性传递到片段着色器,把纹理加载并绑定到合适的纹理单元。
要保证更新的顶点属性指针,不仅是VAO匹配新的顶点数据,也要把箱子图片加载为纹理。在绘制箱子之前,我们希望首选纹理单元被赋为material.diffuse这个uniform采样器,并绑定箱子的纹理到这个纹理单元:
glUniform1i(glGetUniformLocation(lightingShader.Program, "material.diffuse"), 0);
...
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, diffuseMap);
- 1
- 2
- 3
- 4
2. 镜面贴图
我们同样用一个纹理贴图,来获得镜面高光。这意味着我们需要生成一个黑白(或者你喜欢的颜色)纹理来定义specular亮度,把它应用到物体的每个部分。下面是一个镜面贴图(Specular Map)的例子:
一个specular高光的亮度可以通过图片中每个纹理的亮度来获得。specular贴图的每个像素可以显示为一个颜色向量,比如:在那里黑色代表颜色向量vec3(0.0f),灰色是vec3(0.5f)。在片段着色器中,我们采样相应的颜色值,把它乘以光的specular亮度。像素越“白”,乘积的结果越大,物体的specualr部分越亮。
镜面贴图采样
由于我们在同样的片段着色器中使用另一个纹理采样器,我们必须为specular贴图使用一个不同的纹理单元(参见纹理),所以在渲染前让我们把它绑定到合适的纹理单元
glUniform1i(glGetUniformLocation(lightingShader.Program, "material.specular"), 1);
...
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, specularMap);
- 1
- 2
- 3
- 4
然后更新片段着色器材质属性,接受一个sampler2D作为这个specular部分的类型,而不是vec3:
struct Material
{sampler2D diffuse;sampler2D specular;float shininess;
};
- 1
- 2
- 3
- 4
- 5
- 6
最后我们希望采样这个specular贴图,来获取原始像素相应的specular亮度:
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
color = vec4(ambient + diffuse + specular, 1.0f);
- 1
- 2
- 3
- 4
转载请注明出处:http://blog.csdn.net/ylbs110/article/details/52566131
三、 示例
代码:
#include <iostream>
using namespace std;
// GLEW
#define GLEW_STATIC
#include <GL/glew.h>
// GLFW
#include <GLFW/glfw3.h>
// SOIL
#include <SOIL\SOIL.h>#include <glm\glm.hpp>
#include <glm\gtc\matrix_transform.hpp>
#include <glm\gtc\type_ptr.hpp>#include "Shader.h"
#include "Camera.h"const GLuint WIDTH = 800, HEIGHT = 600;void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
GLuint loadTexture(string fileName, GLint REPEAT, GLint FILTER);
void do_movement();
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
// Shaders
const GLchar* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 position;\n"//顶点数据传入的坐标
"layout (location = 1) in vec3 normal;\n"//顶点数据传入的颜色
"layout (location = 2) in vec2 texCoord;\n"//顶点数据传入的纹理坐标
"uniform vec4 offset;\n"
"uniform float mixPar;\n"
"uniform mat4 model;\n"
"uniform mat4 view;\n"
"uniform mat4 projection;\n"
"out vec3 FragPos;\n"
"out vec3 Normal;\n"
"out vec2 TexCoord;\n"
"out float MixPar;\n"
"void main()\n"
"{\n"
"gl_Position =projection * view * model* vec4(position.x, position.y, position.z, 1.0)+offset;\n"
"FragPos = vec3(model * vec4(position, 1.0f));\n"
"Normal=normal;\n"
"TexCoord=texCoord;\n"
"MixPar=mixPar;\n"
"}\0";const GLchar* fragmentShaderSource = "#version 330 core\n"
"out vec4 color;\n"
"in vec3 FragPos;\n"
"in vec3 Normal;\n"
"in vec2 TexCoord;\n"
"in float MixPar;\n"
"uniform sampler2D ourTexture1;\n"
"uniform sampler2D ourTexture2;\n"
"uniform vec3 objectColor;\n"
"uniform vec3 lightPos;\n"
"uniform vec3 viewPos;\n""struct Material{\n"
"sampler2D diffuse;\n"
"sampler2D specular;\n"
"float shininess;\n"
"};\n"
"uniform Material material;\n""struct Light{\n"
"vec3 position;\n"
"vec3 ambient;\n"
"vec3 diffuse;\n"
"vec3 specular;\n"
"};\n"
"uniform Light light;\n""void main()\n"
"{\n"
"vec3 diffTex = vec3(texture(material.diffuse, TexCoord));\n"
"vec3 specTex = vec3(texture(material.specular, TexCoord));\n""vec3 ambient =light.ambient * diffTex;\n""vec3 norm = normalize(Normal);\n"
"vec3 lightDir = normalize(lightPos - FragPos);\n"
"float diff = max(dot(norm, lightDir), 0.0);\n"
"vec3 diffuse =light.diffuse * diff * diffTex;\n""vec3 viewDir = normalize(viewPos - FragPos);\n"
"vec3 reflectDir = reflect(-lightDir, norm);\n"
"float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);\n"
"vec3 specular =light.specular * spec * specTex;\n""vec3 result = (ambient + diffuse+specular) * objectColor;\n"
"color = vec4(result, 1.0f);\n"
//"color =result*mix(texture(ourTexture1, TexCoord),texture(ourTexture2, vec2(TexCoord.x,1-TexCoord.y)),MixPar)+vec4(lightColor * objectColor, 1.0f);\n"
"}\n\0";
const GLchar* fragmentShaderSourceLight = "#version 330 core\n"
"out vec4 color;\n"
"uniform vec3 lightColor;\n"
"void main()\n"
"{\n"
"color = vec4(lightColor,1.0f);\n"
"}\n\0";
Camera mainCamera;
Shader shader, lightintShader;//shader
GLuint texContainer, texAwesomeface, diffuseContainer,specularContainer;//纹理idfloat key_UD = 0.5f;//混合比例
GLuint VBO, lightVAO, VAO;GLfloat deltaTime = 0.0f; // 当前帧遇上一帧的时间差
GLfloat lastFrame = 0.0f; // 上一帧的时间bool keys[1024];GLfloat lastX = 400, lastY = 300;
GLfloat scrollSpeed = 0.05f;
bool firstMouse = true;glm::vec3 lightPos(1.2f, 1.0f, 2.0f);
glm::mat4 model;
glm::mat4 view;
glm::mat4 projection;
GLint modelLoc;
GLint viewLoc;
GLint projectionLoc;void shaderInit() {shader = Shader(vertexShaderSource, fragmentShaderSource);lightintShader = Shader(vertexShaderSource, fragmentShaderSourceLight);
}
void textureInit() {texContainer = loadTexture("container.jpg", GL_CLAMP_TO_EDGE, GL_LINEAR);texAwesomeface = loadTexture("awesomeface.png", GL_MIRRORED_REPEAT, GL_NEAREST);diffuseContainer = loadTexture("container_diffuse.png", GL_MIRRORED_REPEAT, GL_NEAREST);specularContainer = loadTexture("container_specular.png", GL_MIRRORED_REPEAT, GL_NEAREST);
}
GLuint loadTexture(string fileName, GLint REPEAT, GLint FILTER) {//创建纹理GLuint texture;glGenTextures(1, &texture);//绑定纹理glBindTexture(GL_TEXTURE_2D, texture);// 为当前绑定的纹理对象设置环绕、过滤方式glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, FILTER);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, FILTER);//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// 加载纹理int width, height;unsigned char* image = SOIL_load_image(fileName.c_str(), &width, &height, 0, SOIL_LOAD_RGB);// 生成纹理glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);glGenerateMipmap(GL_TEXTURE_2D);//释放图像的内存并解绑纹理对象SOIL_free_image_data(image);glBindTexture(GL_TEXTURE_2D, 0);return texture;
}void vertexObjectInit() {//不使用索引缓冲对象用两个三角形绘制一个梯形// 设置顶点缓存和属性指针GLfloat vertices[] = {-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,1.0f, 0.0f,0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,1.0f, 1.0f,0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,1.0f, 1.0f,-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,1.0f, 0.0f,0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,1.0f, 1.0f,0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,0.0f, 1.0f,0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,0.0f, 1.0f,0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,0.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,1.0f, 0.0f,-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,1.0f, 1.0f,0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,1.0f, 0.0f,0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,1.0f, 0.0f,-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,1.0f, 1.0f,0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,1.0f, 0.0f,0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,1.0f, 0.0f,-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f};//创建索引缓冲对象glGenBuffers(1, &VBO);// 把顶点数组复制到缓冲中供OpenGL使用glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);glGenVertexArrays(1, &VAO);glBindVertexArray(VAO);// 位置属性glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);glEnableVertexAttribArray(0);// 颜色属性glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));glEnableVertexAttribArray(1);glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));glEnableVertexAttribArray(2);//glBindBuffer(GL_ARRAY_BUFFER, 0);// 这个方法将顶点属性指针注册到VBO作为当前绑定顶点对象,然后我们就可以安全的解绑glBindVertexArray(0);// 解绑 VAO (这通常是一个很好的用来解绑任何缓存/数组并防止奇怪错误的方法)glGenVertexArrays(1, &lightVAO);glBindVertexArray(lightVAO);// 只需要绑定VBO不用再次设置VBO的数据,因为容器(物体)的VBO数据中已经包含了正确的立方体顶点数据glBindBuffer(GL_ARRAY_BUFFER, VBO);// 设置灯立方体的顶点属性指针(仅设置灯的顶点数据)glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);glEnableVertexAttribArray(0);// 颜色属性glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));glEnableVertexAttribArray(1);glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));glEnableVertexAttribArray(2);glBindVertexArray(0);
}int main()
{//初始化GLFWglfwInit();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);//创建窗口对象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);//注册键盘回调glfwSetKeyCallback(window, key_callback);//注册鼠标回调glfwSetCursorPosCallback(window, mouse_callback);//注册鼠标滚轮回到glfwSetScrollCallback(window, scroll_callback);//设置光标隐藏并捕获//glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);//初始化GLEWglewExperimental = GL_TRUE;if (glewInit() != GLEW_OK){std::cout << "Failed to initialize GLEW" << std::endl;return -1;}//告诉OpenGL渲染窗口尺寸大小int width, height;glfwGetFramebufferSize(window, &width, &height);glViewport(0, 0, width, height);glEnable(GL_DEPTH_TEST);//初始化并绑定shadersshaderInit();//初始化texturestextureInit();//初始化顶点对象数据vertexObjectInit();mainCamera = Camera();//让窗口接受输入并保持运行while (!glfwWindowShouldClose(window)){GLfloat currentFrame = glfwGetTime();deltaTime = currentFrame - lastFrame;lastFrame = currentFrame;//检查事件glfwPollEvents();do_movement();//渲染指令glClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//GLfloat timeValue = glfwGetTime();//lightPos.x = lightPos.x+ sin(timeValue);//lightPos.y = lightPos.y + cos(timeValue);glm::vec3 lightColor; lightColor.x = sin(glfwGetTime() * 2.0f);lightColor.y = sin(glfwGetTime() * 0.7f);lightColor.z = sin(glfwGetTime() * 1.3f);//绘制光源model = glm::mat4();model = glm::translate(model, lightPos);model = glm::scale(model, glm::vec3(0.2f));lightintShader.Use();//GLint vertexColorLocation = glGetUniformLocation(lightintShader.Program, "offset");//glUniform4f(vertexColorLocation, offsetx, offsety, 0.0f, 1.0f);// 设置模型、视图和投影矩阵uniformmodelLoc = glGetUniformLocation(lightintShader.Program, "model");glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));viewLoc = glGetUniformLocation(lightintShader.Program, "view");glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));projectionLoc = glGetUniformLocation(lightintShader.Program, "projection");glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));GLint lightColorLoc = glGetUniformLocation(lightintShader.Program, "lightColor");glUniform3f(lightColorLoc, lightColor.x, lightColor.y, lightColor.z); // 依旧把光源设置为白色// 绘制灯立方体对象glBindVertexArray(lightVAO);glDrawArrays(GL_TRIANGLES, 0, 36);glBindVertexArray(0);//绘制箱子 shader.Use();//绑定两张贴图//glActiveTexture(GL_TEXTURE0);//glBindTexture(GL_TEXTURE_2D, texContainer);//glUniform1i(glGetUniformLocation(shader.Program, "ourTexture1"), 0);//glActiveTexture(GL_TEXTURE1);//glBindTexture(GL_TEXTURE_2D, texAwesomeface);//glUniform1i(glGetUniformLocation(shader.Program, "ourTexture2"), 1); glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, diffuseContainer);glUniform1i(glGetUniformLocation(shader.Program, "material.diffuse"), 0);glActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D, specularContainer);glUniform1i(glGetUniformLocation(shader.Program, "material.specular"), 1);// 更新uniform值//设置混合比例GLint mixPar = glGetUniformLocation(shader.Program, "mixPar");glUniform1f(mixPar, key_UD);model = glm::rotate(model, (GLfloat)glfwGetTime() * 5.0f, glm::vec3(0.5f, 1.0f, 0.0f));view = mainCamera.GetViewMatrix();projection = glm::perspective(mainCamera.Zoom*scrollSpeed, (float)(WIDTH / HEIGHT), 0.1f, 100.0f);modelLoc = glGetUniformLocation(shader.Program, "model");glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));viewLoc = glGetUniformLocation(shader.Program, "view");glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));projectionLoc = glGetUniformLocation(shader.Program, "projection");glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));// 在此之前不要忘记首先'使用'对应的着色器程序(来设定uniform)GLint objectColorLoc = glGetUniformLocation(shader.Program, "objectColor");glUniform3f(objectColorLoc, 1.0f, 1.0f, 1.0f);// 我们所熟悉的珊瑚红GLint lightPosLoc = glGetUniformLocation(shader.Program, "lightPos");glUniform3f(lightPosLoc, lightPos.x, lightPos.y, lightPos.z);GLint viewPosLoc = glGetUniformLocation(shader.Program, "viewPos");glUniform3f(viewPosLoc, mainCamera.Position.x, mainCamera.Position.y, mainCamera.Position.z);//设置材质参数GLint matShineLoc = glGetUniformLocation(shader.Program, "material.shininess");glUniform1f(matShineLoc, 32.0f);//设置光照参数GLint lightAmbientLoc = glGetUniformLocation(shader.Program, "light.ambient");GLint lightDiffuseLoc = glGetUniformLocation(shader.Program, "light.diffuse");GLint lightSpecularLoc = glGetUniformLocation(shader.Program, "light.specular");glm::vec3 diffuseColor = lightColor * glm::vec3(0.5f);glm::vec3 ambientColor = diffuseColor * glm::vec3(0.2f);glUniform3f(lightAmbientLoc, ambientColor.x, ambientColor.y, ambientColor.z);glUniform3f(lightDiffuseLoc, diffuseColor.x, diffuseColor.y, diffuseColor.z);//glUniform3f(lightAmbientLoc, 0.2f, 0.2f, 0.2f);//glUniform3f(lightDiffuseLoc, 0.5f, 0.5f, 0.5f);glUniform3f(lightSpecularLoc, 1.0f, 1.0f, 1.0f);glm::vec3 cubePositions[] = {glm::vec3(0.0f, 0.0f, 0.0f),glm::vec3(2.0f, 5.0f, -15.0f),glm::vec3(-1.5f, -2.2f, -2.5f),glm::vec3(-3.8f, -2.0f, -12.3f),glm::vec3(2.4f, -0.4f, -3.5f),glm::vec3(-1.7f, 3.0f, -7.5f),glm::vec3(1.3f, -2.0f, -2.5f),glm::vec3(1.5f, 2.0f, -2.5f),glm::vec3(1.5f, 0.2f, -1.5f),glm::vec3(-1.3f, 1.0f, -1.5f)};glBindVertexArray(VAO);for (GLuint i = 0; i < 10; i++){glm::mat4 model;model = glm::translate(model, cubePositions[i]);if (i < 4) {GLfloat angle = (GLfloat)glfwGetTime()*5.0f * i;model = glm::rotate(model, angle, glm::vec3(1.0f, 0.3f, 0.5f));glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));}else{glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));}glDrawArrays(GL_TRIANGLES, 0, 36);}glBindVertexArray(0);//交换缓冲glfwSwapBuffers(window);}glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);//释放资源glfwTerminate();return 0;
}
void do_movement()
{// 摄像机控制GLfloat cameraSpeed = 5.0f* deltaTime;if (keys[GLFW_KEY_W])mainCamera.ProcessKeyboard(FORWARD, deltaTime);if (keys[GLFW_KEY_S])mainCamera.ProcessKeyboard(BACKWARD, deltaTime);if (keys[GLFW_KEY_A])mainCamera.ProcessKeyboard(LEFT, deltaTime);if (keys[GLFW_KEY_D])mainCamera.ProcessKeyboard(RIGHT, deltaTime);
}
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{// 当用户按下ESC键,我们设置window窗口的WindowShouldClose属性为true// 关闭应用程序if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)glfwSetWindowShouldClose(window, GL_TRUE);if (key == GLFW_KEY_UP&& action == GLFW_PRESS)//按下UP键增加混合比例key_UD = key_UD + 0.1f;if (key == GLFW_KEY_DOWN&& action == GLFW_PRESS)//按下DOWN减小混合比例key_UD = key_UD - 0.1f;if (action == GLFW_PRESS)keys[key] = true;else if (action == GLFW_RELEASE)keys[key] = false;
}
void mouse_callback(GLFWwindow* window, double xpos, double ypos)
{if (firstMouse){lastX = xpos;lastY = ypos;firstMouse = false;}GLfloat xoffset = xpos - lastX;GLfloat yoffset = lastY - ypos; // Reversed since y-coordinates go from bottom to left lastX = xpos;lastY = ypos;mainCamera.ProcessMouseMovement(xoffset, yoffset);
}void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{cout << yoffset << endl;mainCamera.ProcessMouseScroll(yoffset);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
结果:
可以看到金属边框产生了高光但是木质材质没有高光。
OpenGL--材质相关推荐
- OpenGL材质Materials
OpenGL材质Materials 材质Materials简介 设置材质 光的属性 不同的光源颜色 材质Materials简介 在现实世界里,每个物体会对光产生不同的反应.比如说,钢看起来通常会比陶瓷 ...
- OpenGL材质和光照(转)part1
真实感图形绘制是计算机图形学的一个重要组成部分,它综合利用数学.物理学.计算机科学和其它科学知识在计算机图形设备上生成象彩色照片那样的具有真实感的图形.一般说来,用计算机在图形设备上生成真实感图形必须 ...
- OpenGL材质和光照(转)part2
10.4.3 材质RGB值和光源RGB值的关系 材质的颜色与光源的颜色有些不同.对于光源,R.G.B值等于R.G.B对其最大强度的百分比.若光源颜色的R.G.B值都是1.0,则是最强的白光:若值变为0 ...
- 从零开始学习OpenGL ES之五 – 材质
从零开始学习OpenGL ES之五 – 材质 作者: iPhoneGeek 爱疯极客 09-Jan-10 iPhone Development 浏览次数: 411 | 评论 ↓ Tweet Shar ...
- NeHe OpenGL第三十二课:拾取游戏
NeHe OpenGL第三十二课:拾取游戏 拾取, Alpha混合, Alpha测试, 排序: 这又是一个小游戏,交给的东西会很多,慢慢体会吧 欢迎来到32课. 这课大概是在我所写作已来最大的一课 ...
- OpenGL完整教程专栏完整目录
OpenGL完整教程专栏完整目录 专栏说明如下 专栏目录 专栏说明如下 内容:OpenGL完整教程 数量:314篇博文(2023年2月15日截止) 更新时间至:2023年2月15日(后续加上去的博文, ...
- metaball公式_Houdini 节点解释
一 模型部分 掌握快捷键 1物体 2 点 3线 4面 a.编辑模型 主要使用edit工具 直接移动旋转缩放 在属性条添加软修改半径进行软修改 按m键 切换成笔刷修改类似zb b.简单练习4个常用命令 ...
- Houdini 节点
-Houdini 节点 由于刚学Houdini,对于缺少的我会在后续持续补充........... 所有节点均按字母先后顺序排列. 表达式 $PT 点序号 $NPT点总序号数 fit 重映射区间 ra ...
- 小白的python与houdini之旅(houdini_转载houdini节点解析)
Houdini 节点解释 OP 解释 Add Generators|polygon 创建点或Polygon线/面,为输入添加点或polys Align Filters|NURBS 互相对齐一组面或和辅 ...
- Android4.2.2 Gallery2源码分析(4)——GLCanvas.java
首先申明,找到这个类是在GLRootView.java中发现的线索.这是一个接口,源码中对该接口作了详细的说明: // // GLCanvas gives a convenient interface ...
最新文章
- android-sdk-windows版本号下载
- FTP服务(vsftpd)配置
- java面试题oracle,2021年度javasqloracle面试题汇总.doc
- 网页静态服务器-1-显示固定的页面
- JAVA设计模式 - 抽象工厂模式
- 对接物联网设备tcp协议_什么是物联网?常见IoT协议最全讲解
- 失业几个月找不到工作是一种怎样的体验?
- 第十四天-企业应用架构模式-Web表现模式
- Bailian2716 全局变量【字符流】
- 13.vim 全局替换路径
- python里isalpha_Python 2.7中isalpha 不支持 unicode
- 万兆网、10G ethernet subsystem IP核
- instead和instead of
- 全微分里dxy是怎么化成xdy+ydx
- Facebook登录的时候验证邮箱
- 锁机制初探(五)Moniter的实现原理
- 利用Python导入股票列表
- 【JVM】类加载系统
- 软件测试项目流程报告,周口软件测试报告流程,科技项目申报
- DO447管理任务执行--控制任务执行
热门文章
- VS新建项目时出现 异常来自 HRESULT:0x80041FE2
- c语言编写程序“输入任意一个年份和月份,打印当月日历。”
- Valheim英灵神殿黑森林地标建筑详解
- 浅谈运用计算机铺助教学体会,浅谈计算机辅助教学的优点与运用.doc
- 一键cia文件转cci_几十年来,CIA秘密经营着全球最大的加密公司之一
- python 递归 写平方_Python递归函数如何写?正确的Python递归函数用法
- 中国民生信托荣膺《经济观察报》“年度卓越财富管理信托公司”称号
- html页面设定为连接的方法,html代码运用
- Android Apk 瘦身大法
- @JsonFormat、@JSONField、@DateTimeFormat的使用以及其区别 ||||返回json的时候的时间转化