OpenGL材质系统和贴图纹理

上一篇文章当中笔者为大家介绍了风氏光照模型,相信大家也发现了光照着色器当中有设置有很多控制光照强度的参数,而所谓的材质系统就是我们可以人为的去调节这些参数,让一个物体的反光效果能够更加接近我们现实生活当中的一些物体。

材质系统

当描述一个表面时,我们可以分别为三个光照分量定义一个材质颜色(Material Color ):环境光照(Ambient Lighting )、漫反射光照(Diffuse Lighting )和镜面光照(Specular Lighting )。通过为每个分量指定一个颜色,我们就能够对表面的颜色输出有细粒度的控制了。现在,我们再添加一个反光度(Shininess)分量,结合上述的三个颜色,我们就有了全部所需的材质属性了

cpp 复制代码
#version 450 core
struct Material {
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
    float shininess;
}; 

uniform Material material;

如你所见,我们为风氏光照模型的每个分量都定义一个颜色向量。ambient 材质向量定义了在环境光照下这个表面反射的是什么颜色,通常与表面的颜色相同。diffuse 材质向量定义了在漫反射光照下表面的颜色。漫反射颜色(和环境光照一样)也被设置为我们期望的物体颜色。specular 材质向量设置的是表面上镜面高光的颜色(或者甚至可能反映一个特定表面的颜色)。最后,shininess影响镜面高光的散射/半径。

使用材质

我们在片段着色器中创建了一个材质结构体的uniform ,所以下面我们希望修改一下光照的计算来遵从新的材质属性。由于所有材质变量都储存在一个结构体中,我们可以从uniform 变量material中访问它们:

cpp 复制代码
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;
    FragColor = vec4(result, 1.0);
}

我们可以看到,和之前光照模型几乎没有什么不同的,我们只是通过结构体的方式来访问这些向量,这样做的好处是我们可以人为的控制这些材质的向量了。

cpp 复制代码
lightingShader.setVec3("material.ambient",  1.0f, 0.5f, 0.31f);
lightingShader.setVec3("material.diffuse",  1.0f, 0.5f, 0.31f);
lightingShader.setVec3("material.specular", 0.5f, 0.5f, 0.5f);
lightingShader.setFloat("material.shininess", 32.0f);

不过到现在还是有一个问题,那就是整个光照模型看上去会特别的亮,这是因为我们还没有设置照射光的属性,我们需要调整光的亮度。

cpp 复制代码
struct Light {
    vec3 position;

    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};

uniform Light light;

片段着色器修改成如下的代码

cpp 复制代码
void main()
{    
    // 环境光
    vec3 ambient = light.ambient * material.ambient;

    // 漫反射 
    vec3 norm = normalize(Normal);
    vec3 lightDir = normalize(lightPos - FragPos);
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = light.diffuse * (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 = light.specular * (spec * material.specular);  

    vec3 result = ambient + diffuse + specular;
    FragColor = vec4(result, 1.0);
}

设置光照的属性

cpp 复制代码
lightingShader.setVec3("light.ambient",  0.2f, 0.2f, 0.2f);
lightingShader.setVec3("light.diffuse",  0.5f, 0.5f, 0.5f); // 将光照调暗了一些以搭配场景
lightingShader.setVec3("light.specular", 1.0f, 1.0f, 1.0f); 

好的到了这里,我们材质系统就为大家介绍到这里了,不过通过上面的代码我们知道,这个材质系统影响的是整个立方体的材质状况,但我们也知道现实生活当中这种单一材质物体是很少见的,一般我们看到的物体都是好几种材质组合而来的。要想表现出这种复杂的纹理,我们组好要能控制每个像素颜色,那怎样才能做到这种事了?可能有的朋友已经想到了,那就是使用之前的纹理,就可以控制片段着色器当中的像素颜色了!

纹理贴图

我们使用下面两个纹理图片来制作一个带有贴边的木箱子。

可能有的朋友想问,为什么铁框的贴图的中间的部分是黑色的,其实这个目的就在于减小木制材料部分中间的反光程度。整个光照着色器代码如下:

cpp 复制代码
#type vertex
#version 450 core
layout(location = 0) in vec4 position;
layout(location = 1) in vec3 color;
layout(location = 2) in vec3 normal;
layout(location = 3) in vec2 texCoord;

layout(location = 0) out vec4 v_Position;
layout(location = 1) out vec3 v_Color;
layout(location = 2) out vec3 v_Normal;
layout(location = 3) out vec2 v_texCoord;

uniform mat4 u_ViewProject;

void main(){
    gl_Position = u_ViewProject * position;
    v_Position = position;
    v_Color = color;
    v_Normal = normal;
    v_texCoord = texCoord;
}


#type fragment
#version 450 core

layout(location = 0) out vec4 o_Color;

layout(location = 0) in vec4 v_Position;
layout(location = 1) in vec3 v_Color;
layout(location = 2) in vec3 v_Normal;
layout(location = 3) in vec2 v_texCoord;

struct Material {
    int diffuse;
    int specular;
    int shininess;
};

struct Light{
    vec3 position;

    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};

uniform sampler2D u_Textures[2];

uniform vec3 u_ViewPos;
uniform Material material;
uniform Light light;

void main(){
    vec3 v_position3 = vec3(v_Position.x,v_Position.y,v_Position.z);
    //环境亮度
    vec3 ambient = light.ambient * texture(u_Textures[material.diffuse],v_texCoord).rgb;
    //漫反射亮度
    vec3 vertex2light = normalize(light.position - v_position3);
    float diff = max(dot(vertex2light,normalize(v_Normal)),0.0f);
    vec3 diffuse = light.diffuse * diff * texture(u_Textures[material.diffuse],v_texCoord).rgb;

    //镜面反射
    vec3 viewDir = normalize(u_ViewPos - v_position3);
    vec3 reflectDir = reflect(-vertex2light,normalize(v_Normal));
    float spec = pow(max(dot(viewDir,reflectDir),0.0f),material.shininess);
    vec3 specular = light.specular * spec * texture(u_Textures[material.specular],v_texCoord).rgb;

    vec3 result = ambient + diffuse + specular;
    o_Color = vec4(result,1.0f);
}

这样我们就可得到一个边框反光的木箱子了,这一章总体是比较简单的,主函数代码贴在下面,如果对主函数当中的一些变量不清楚的话可以到这个网站获取此案例的所有的代码,包括纹理贴图:https://gitee.com/HonyOrange_227/opengl-light-lab

我们来看一下最后的效果

此文章到这里就结束了,希望能帮助到大家

cpp 复制代码
#include<glad/glad.h>
#include<GLFW/glfw3.h>

#include<iostream>
#include<glm/gtc/matrix_transform.hpp>

#include"Shader.h"
#include"Texture.h"
#include"Camera.h"

static Camera camera(glm::vec3(0.0f, 0.0f, 5.0f));
static bool run = true;
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
void mouse_callback(GLFWwindow* window, double xposIn, double yposIn);
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);

int main() {
	glfwInit();

	GLFWwindow* window = glfwCreateWindow(640, 480, "Triangles", NULL, NULL);

	
	glfwMakeContextCurrent(window);
	glfwSetCursorPosCallback(window, mouse_callback);
	glfwSetScrollCallback(window, scroll_callback);

	glfwSetKeyCallback(window, key_callback);
	glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
	//需要初始化GLAD
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
		std::cout << "Failed to initialize GLAD" << std::endl;
		return -1;
	}

	float lightVertexes[] = {
		//front surface
		-0.5f,	-0.5f,	0.5f,	1.0f,	1.0f,1.0f,1.0f,	//0
		0.5f,	-0.5f,	0.5f,	1.0f,	1.0f,1.0f,1.0f,	//1
		0.5f,	0.5f,	0.5f,	1.0f,	1.0f,1.0f,1.0f,	//2
		-0.5f,	0.5f,	0.5f,	1.0f,	1.0f,1.0f,1.0f,	//3

		//back surface
		-0.5f,	-0.5f,	-0.5f,	1.0f,	1.0f,1.0f,1.0f,	//4
		0.5f,	-0.5f,	-0.5f,	1.0f,	1.0f,1.0f,1.0f,	//5
		0.5f,	0.5f,	-0.5f,	1.0f,	1.0f,1.0f,1.0f,	//6
		-0.5f,	0.5f,	-0.5f,	1.0f,	1.0f,1.0f,1.0f,	//7

		//up surface
		-0.5f,	0.5f,	0.5f,	1.0f,	1.0f,1.0f,1.0f,		//8
		0.5f,	0.5f,	0.5f,	1.0f,	1.0f,1.0f,1.0f,		//9
		0.5f,	0.5f,	-0.5f,	1.0f,	1.0f,1.0f,1.0f,		//10
		-0.5f,	0.5f,	-0.5f,	1.0f,	1.0f,1.0f,1.0f,		//11

		//down surface
		-0.5f,	-0.5f,	0.5f,	1.0f,	1.0f,1.0f,1.0f,		//12
		0.5f,	-0.5f,	0.5f,	1.0f,	1.0f,1.0f,1.0f,		//13
		0.5f,	-0.5f,	-0.5f,	1.0f,	1.0f,1.0f,1.0f,		//14
		-0.5f,	-0.5f,	-0.5f,	1.0f,	1.0f,1.0f,1.0f,		//15

		//left surface
		-0.5f,	-0.5f,	-0.5f,	1.0f,	1.0f,1.0f,1.0f,	//16
		-0.5f,	-0.5f,	0.5f,	1.0f,	1.0f,1.0f,1.0f,	//17
		-0.5f,	0.5f,	0.5f,	1.0f,	1.0f,1.0f,1.0f,	//18
		-0.5f,	0.5f,	-0.5f,	1.0f,	1.0f,1.0f,1.0f,	//19

		//right surface
		0.5f,	-0.5f,	-0.5f,	1.0f,	1.0f,1.0f,1.0f,	//20
		0.5f,	-0.5f,	0.5f,	1.0f,	1.0f,1.0f,1.0f,	//21
		0.5f,	0.5f,	0.5f,	1.0f,	1.0f,1.0f,1.0f,	//22
		0.5f,	0.5f,	-0.5f,	1.0f,	1.0f,1.0f,1.0f	//23
	};					

	float vertexes[] = {
		//front surface
		-0.5f,	-0.5f,	0.5f,	1.0f,	1.0f,0.5f,0.2f,		0.0f,0.0f,1.0f,		0.0f,0.0f,//0
		0.5f,	-0.5f,	0.5f,	1.0f,	1.0f,0.5f,0.2f,		0.0f,0.0f,1.0f,		1.0f,0.0f,//1
		0.5f,	0.5f,	0.5f,	1.0f,	1.0f,0.5f,0.2f,		0.0f,0.0f,1.0f,		1.0f,1.0f,//2
		-0.5f,	0.5f,	0.5f,	1.0f,	1.0f,0.5f,0.2f,		0.0f,0.0f,1.0f,		0.0f,1.0f,//3

		//back surface
		-0.5f,	-0.5f,	-0.5f,	1.0f,	1.0f,0.5f,0.2f,		0.0f,0.0f,-1.0f,	0.0f,0.0f,//4
		0.5f,	-0.5f,	-0.5f,	1.0f,	1.0f,0.5f,0.2f,		0.0f,0.0f,-1.0f,	1.0f,0.0f,//5
		0.5f,	0.5f,	-0.5f,	1.0f,	1.0f,0.5f,0.2f,		0.0f,0.0f,-1.0f,	1.0f,1.0f,//6
		-0.5f,	0.5f,	-0.5f,	1.0f,	1.0f,0.5f,0.2f,		0.0f,0.0f,-1.0f,	0.0f,1.0f,//7

		//up surface
		-0.5f,	0.5f,	0.5f,	1.0f,	1.0f,0.5f,0.2f,		0.0f,1.0f,0.0f,		0.0f,0.0f,//8
		0.5f,	0.5f,	0.5f,	1.0f,	1.0f,0.5f,0.2f,		0.0f,1.0f,0.0f,		1.0f,0.0f,//9
		0.5f,	0.5f,	-0.5f,	1.0f,	1.0f,0.5f,0.2f,		0.0f,1.0f,0.0f,		1.0f,1.0f,//10
		-0.5f,	0.5f,	-0.5f,	1.0f,	1.0f,0.5f,0.2f,		0.0f,1.0f,0.0f,		0.0f,1.0f,//11

		//down surface
		-0.5f,	-0.5f,	0.5f,	1.0f,	1.0f,0.5f,0.2f,		0.0f,-1.0f,0.0f,	0.0f,0.0f,//12
		0.5f,	-0.5f,	0.5f,	1.0f,	1.0f,0.5f,0.2f,		0.0f,-1.0f,0.0f,	1.0f,0.0f,//13
		0.5f,	-0.5f,	-0.5f,	1.0f,	1.0f,0.5f,0.2f,		0.0f,-1.0f,0.0f,	1.0f,1.0f,//14
		-0.5f,	-0.5f,	-0.5f,	1.0f,	1.0f,0.5f,0.2f,		0.0f,-1.0f,0.0f,	0.0f,1.0f,//15

		//left surface
		-0.5f,	-0.5f,	-0.5f,	1.0f,	1.0f,0.5f,0.2f,		-1.0f,0.0f,0.0f,	0.0f,0.0f,//16
		-0.5f,	-0.5f,	0.5f,	1.0f,	1.0f,0.5f,0.2f,		-1.0f,0.0f,0.0f,	1.0f,0.0f,//17
		-0.5f,	0.5f,	0.5f,	1.0f,	1.0f,0.5f,0.2f,		-1.0f,0.0f,0.0f,	1.0f,1.0f,//18
		-0.5f,	0.5f,	-0.5f,	1.0f,	1.0f,0.5f,0.2f,		-1.0f,0.0f,0.0f,	0.0f,1.0f,//19

		//right surface
		0.5f,	-0.5f,	-0.5f,	1.0f,	1.0f,0.5f,0.2f,		1.0f,0.0f,0.0f,		0.0f,0.0f,//20
		0.5f,	-0.5f,	0.5f,	1.0f,	1.0f,0.5f,0.2f,		1.0f,0.0f,0.0f,		1.0f,0.0f,//21
		0.5f,	0.5f,	0.5f,	1.0f,	1.0f,0.5f,0.2f,		1.0f,0.0f,0.0f,		1.0f,1.0f,//22
		0.5f,	0.5f,	-0.5f,	1.0f,	1.0f,0.5f,0.2f,		1.0f,0.0f,0.0f,		0.0f,1.0f,//23
	};

	glm::vec4 originVertexes[24] = {
		{-0.5f,	-0.5f,	0.5f,	1.0f},
		{0.5f,	-0.5f,	0.5f,	1.0f},
		{0.5f,	0.5f,	0.5f,	1.0f},
		{-0.5f,	0.5f,	0.5f,	1.0f},

		//back surface
		{-0.5f,	-0.5f,	-0.5f,	1.0f},
		{0.5f,	-0.5f,	-0.5f,	1.0f},
		{0.5f,	0.5f,	-0.5f,	1.0f},
		{-0.5f,	0.5f,	-0.5f,	1.0f},

		//up surface
		{-0.5f,	0.5f,	0.5f,	1.0f},
		{0.5f,	0.5f,	0.5f,	1.0f},
		{0.5f,	0.5f,	-0.5f,	1.0f},
		{-0.5f,	0.5f,	-0.5f,	1.0f},

		//down surface
		{-0.5f,	-0.5f,	0.5f,	1.0f},
		{0.5f,	-0.5f,	0.5f,	1.0f},
		{0.5f,	-0.5f,	-0.5f,	1.0f},
		{-0.5f,	-0.5f,	-0.5f,	1.0f},

		//left surface
		{-0.5f,	-0.5f,	-0.5f,	1.0f},
		{-0.5f,	-0.5f,	0.5f,	1.0f},
		{-0.5f,	0.5f,	0.5f,	1.0f} ,
		{-0.5f,	0.5f,	-0.5f,	1.0f},

		//right surface
		{0.5f,	-0.5f,	-0.5f,	1.0f},
		{0.5f,	-0.5f,	0.5f,	1.0f},
		{0.5f,	0.5f,	0.5f,	1.0f},
		{0.5f,	0.5f,	-0.5f,	1.0f}
	};

	unsigned int indexes[] = {
		//front surface
		0,1,2,
		2,3,0,

		//back surface
		4,5,6,
		6,7,4,

		//up surface
		8,9,10,
		10,11,8,

		//down surface
		12,13,14,
		14,15,12,

		//left surface
		16,17,18,
		18,19,16,

		//right surface
		20,21,22,
		22,23,20
	};

	glEnable(GL_DEPTH_TEST);
	unsigned int buffer = 0, lightbuffer = 0,vertexArray = 0, lightVertexArray = 0,indexBuffer = 0;

	glCreateVertexArrays(1, &vertexArray);
	glBindVertexArray(vertexArray);

	glCreateBuffers(1, &buffer);
	glBindBuffer(GL_ARRAY_BUFFER, buffer);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertexes), vertexes, GL_STATIC_DRAW);

	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 12 * sizeof(float), NULL);

	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 12 * sizeof(float), (const void*)(4 * sizeof(float)));

	glEnableVertexAttribArray(2);
	glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 12 * sizeof(float), (const void*)(7 * sizeof(float)));

	glEnableVertexAttribArray(3);
	glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 12 * sizeof(float), (const void*)(10 * sizeof(float)));

	glCreateVertexArrays(1, &lightVertexArray);
	glBindVertexArray(lightVertexArray);

	glCreateBuffers(1, &lightbuffer);
	glBindBuffer(GL_ARRAY_BUFFER, lightbuffer);
	glBufferData(GL_ARRAY_BUFFER, sizeof(lightVertexes), lightVertexes, GL_STATIC_DRAW);

	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 7 * sizeof(float), NULL);

	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (const void*)(4 * sizeof(float)));
	
	glCreateBuffers(1, &indexBuffer);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexes), indexes, GL_STATIC_DRAW);

	Shader* pShader = new Shader("assets/shaders/TextureShader.glsl");
	Shader* pLightShader = new Shader("assets/shaders/LightShader.glsl");
	Texture* pTextureWood = new Texture("assets/Textures/container2.png");
	Texture* pTextureSteel = new Texture("assets/Textures/container2_specular.png");

	glm::mat4 transform = glm::translate(glm::mat4(1.0), glm::vec3(0.3f, 1.5f, 1.5f));
	glm::vec4 orginCenter(0.0f, 0.0f, 0.0f, 1.0f);

	int textureIndexes[2] = { 0,1 };
	while (!glfwWindowShouldClose(window) && run) {
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		
		glm::mat4 project = glm::perspective(glm::radians(camera.GetCameraZoom()), 640.0f / 480.0f, 0.1f, 100.0f);
		glm::mat4 view = camera.GetViewMatrix();
		glm::mat4 ViewProject = project * view;
		
		for (int i = 0; i < 24; i++) {
			glm::vec4 originPoint = originVertexes[i];
			originPoint = transform * glm::scale(glm::mat4(1.0f), glm::vec3(0.5f, 0.5f, 0.5f)) * originPoint;
			lightVertexes[i * 7] = originPoint.x;
			lightVertexes[i * 7 + 1] = originPoint.y;
			lightVertexes[i * 7 + 2] = originPoint.z;
			lightVertexes[i * 7 + 3] = originPoint.w;
		}

		glBindBuffer(GL_ARRAY_BUFFER, lightbuffer);
		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(lightVertexes), lightVertexes);

		pShader->Bind();
		pShader->UploadUniformat4("u_ViewProject", ViewProject);

		glBindVertexArray(lightVertexArray);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);

		glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, NULL);

		glm::vec4 centerMove = transform * orginCenter;

		for (int i = 0; i < 24; i++) {
			glm::vec4 originPoint = originVertexes[i];
			originPoint = glm::scale(glm::mat4(1.0f), glm::vec3(1.5f, 1.5f, 1.5f)) * originPoint;
			vertexes[i * 12] = originPoint.x;
			vertexes[i * 12 + 1] = originPoint.y;
			vertexes[i * 12 + 2] = originPoint.z;
			vertexes[i * 12 + 3] = originPoint.w;
		}

		glBindBuffer(GL_ARRAY_BUFFER, buffer);
		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertexes), vertexes);

		pTextureWood->Bind(0);
		pTextureSteel->Bind(1);
		pLightShader->Bind();
		pLightShader->UploadUniformat4("u_ViewProject", ViewProject);
		pLightShader->UploadUnifromFloat3("u_ViewPos",camera.GetPosition());

		pLightShader->UploadUnifromFloat3("light.position", { centerMove.x, centerMove.y, centerMove.z });
		pLightShader->UploadUnifromFloat3("light.ambient", { 0.2f,0.2f,0.2f });
		pLightShader->UploadUnifromFloat3("light.diffuse", { 0.5f,0.5f,0.5f });
		pLightShader->UploadUnifromFloat3("light.specular", { 1.0f,1.0f,1.0f });

		pLightShader->UploadUniform1i("material.diffuse", 0);
		pLightShader->UploadUniform1i("material.specular", 1);
		pLightShader->UploadUniform1i("material.shininess", 64);

		pLightShader->UplaodUniform1iv("u_Textures", 2, textureIndexes);

		glBindVertexArray(vertexArray);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);

		glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, NULL);

		glfwSwapBuffers(window);

		glfwPollEvents();
	}

	delete pShader;
	delete pLightShader;

	glfwDestroyWindow(window);

	glfwTerminate();
}

void mouse_callback(GLFWwindow* window, double xposIn, double yposIn) {
	static float lastX = 320.0f, lastY = 240.0f;
	static bool firstMouse = true;

	float xpos = static_cast<float>(xposIn);
	float ypos = static_cast<float>(yposIn);

	if (firstMouse) {
		lastX = xpos;
		lastY = ypos;
		firstMouse = false;
	}

	float xoffset = xpos - lastX;
	float yoffset = lastY - ypos;

	lastX = xpos, lastY = ypos;

	camera.ProcessMouseMovement(xoffset, yoffset);
}

void scroll_callback(GLFWwindow* window, double xoffsetIn, double yoffsetIn) {
	camera.ProcessMouseScroll(static_cast<float>(yoffsetIn));
}

void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
		run = false;
}
相关推荐
weixin_399264291 小时前
QT c++ 样式 设置 标签(QLabel)的渐变色美化
开发语言·c++·qt
吾当每日三饮五升4 小时前
C++单例模式跨DLL调用问题梳理
开发语言·c++·单例模式
猫武士水星4 小时前
C++ scanf
开发语言·c++
捕鲸叉5 小时前
QT自定义工具条渐变背景颜色一例
开发语言·前端·c++·qt
Rossy Yan6 小时前
【C++面向对象——群体类和群体数据的组织】实现含排序功能的数组类(头歌实践教学平台习题)【合集】
c++·排序算法·面向对象·封装·查找
我搞slam6 小时前
全覆盖路径规划算法之BCD源码实现(The Boustrophedon Cellular Decomposition)
c++·算法·图搜索算法
Rossy Yan6 小时前
【C++数据结构——查找】二分查找(头歌实践教学平台习题)【合集】
开发语言·数据结构·c++·算法·查找·头歌实践教学平台·合集
埃菲尔铁塔_CV算法7 小时前
BOOST 在计算机视觉方面的应用及具体代码分析(二)
c++·人工智能·算法·机器学习·计算机视觉
mit6.82413 小时前
[Qt] 信号和槽(2) | 多对多 | disconnect | 结合lambda | sum
linux·前端·c++·qt·学习
gonghw40313 小时前
Linux开机LOGO更换以及附带问题
linux·c++