LearnOpenGL学习笔记—光照04:Lighting Maps

本篇文章是基于清清博客
代码整合
在这里插入图片描述

总代码

Camera.h

#pragma once

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

class Camera
{
    
    
public:
	~Camera();
	//position 相机所在位置  target 相机指向的位置  worldup 世界向上的向量
	Camera(glm::vec3 position, glm::vec3 target, glm::vec3 worldup);
	//pitch俯仰角和yaw偏航角
	Camera(glm::vec3 position, float pitch, float yaw, glm::vec3 worldup);


	//摄影机位置
	glm::vec3 Position;
	//Forward 摄影机的“方向”(一个和朝向相反的向量)
	glm::vec3 Forward;
	glm::vec3 Right;
	//摄影机的上方向
	glm::vec3 Up;
	//世界的上方向
	glm::vec3 WorldUp;
	float Pitch;
	float Yaw;
	float cameraPosSpeed;


	glm::mat4 GetViewMatrix();
	void ProcessMouseMovement(float deltaX, float deltaY);
	void PosUpdateForward();
	void PosUpdateBackward();
	void PosUpdateLeft();
	void PosUpdateRight();
	void PosUpdateUp();
	void PosUpdateDown();
private:
	void UpdateCameraVectors();
};

fragmentSouce.frag

#version 330 core			
//in vec4 vertexColor;
in vec2 TexCoord;
//着色点和法向
in vec3 FragPos;
in vec3 Normal;

struct Material {
    
    
    vec3 ambient;
    sampler2D diffuse;
    vec3 specular;
    float shininess;
}; 

uniform Material material;

out vec4 FragColor;			

uniform sampler2D ourTexture;
uniform sampler2D ourFace;

uniform vec3 lightPos;
uniform vec3 lightColor;
uniform vec3 ambientColor;
uniform vec3 cameraPos;


void main(){
    
    				
	vec3 r=lightPos-FragPos;
	//光线方向
	vec3 lightDir = normalize(r);
	//距离系数
	float coefficient=50/(pow(r.x,2)+pow(r.y,2)+pow(r.z,2));
	//法向
	vec3 normal = normalize(Normal);
	//漫反射
	float diff = max(dot(normal, lightDir), 0.0);
	vec3 diffuse = texture(material.diffuse,TexCoord).rgb;
	//vec3 diffuse = material.diffuse * coefficient * diff * lightColor;
	//材质
	//vec4 objColor= mix(texture(ourTexture,TexCoord),texture(ourFace,TexCoord),texture(ourFace,TexCoord).a*0.2);
	vec4 objColor= vec4(1.0f, 0.5f, 0.31f,1.0f);
	//观察方向
	vec3 cameraVec= normalize(cameraPos - FragPos);

	//Blinn-Phong光照模型镜面反射
	vec3 halfwarDir = normalize(lightDir + cameraVec);
	float specularAmount = pow(max(dot(normal, halfwarDir), 0.0),material.shininess);
	vec3 specular = material.specular * coefficient * specularAmount * lightColor;

	//环境光
	vec3 ambient= material.ambient * ambientColor;

	FragColor=vec4(specular+diffuse+ambient,1.0f)*objColor;

}

Material.h

#pragma once
#include "Shader.h"
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

class Material
{
    
    
public:
	Shader * shader;
	unsigned int diffuse;
	glm::vec3 specular;
	glm::vec3 ambient;
	float shininess;

	Material(Shader* _shader, unsigned int _diffuse, glm::vec3 _specular, glm::vec3 _ambient, float _shininess);
	~Material();

};

Shader.h

#pragma once
#include <string>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

class Shader
{
    
    
public:
	Shader(const char* vertexPath, const char* fragmentPath);
	std::string vertexString;
	std::string fragmentString;
	const char* vertexSource;
	const char* fragmentSource;
	unsigned int ID;  //Shader Program ID
	void use();
	void SetUniform3f(const char* paraNameString, glm::vec3 param);
	void SetUniform1f(const char* paraNameString, float param);
	void SetUniform1i(const char* paraNameString, int slot);

	//~Shader();
private:
	void checkCompileErrors(unsigned int ID, std::string type);
};

vertexSource.vert

#version 330 core									  
layout(location = 0) in vec3 aPos;   // 位置变量的属性位置值为 0
//layout(location = 1) in vec3 aColor; // 颜色变量的属性位置值为 1
layout(location = 3) in vec2 aTexCoord; // uv变量的属性位置值为 2
layout(location = 2) in vec3 aNormal; // 法向量的属性位置值为 3

//out vec4 vertexColor;
out vec2 TexCoord;

//着色点和法向
out vec3 FragPos;
out vec3 Normal;

//uniform mat4 transform;
uniform mat4 modelMat;
uniform mat4 viewMat;
uniform mat4 projMat;


void main(){
    
    										   
   gl_Position =  projMat * viewMat * modelMat * vec4(aPos.xyz,1.0);   
   Normal =mat3(transpose(inverse(modelMat)))*aNormal;
   FragPos=(modelMat * vec4(aPos.xyz,1.0)).xyz;
   //vertexColor = vec4(aColor,1.0);	
   TexCoord = aTexCoord;
}

Camera.cpp

#include "Camera.h"

Camera::Camera(glm::vec3 position, glm::vec3 target, glm::vec3 worldup)
{
    
    
	Position = position;
	WorldUp = worldup;
	//normalize 归一化变成单位向量
	//Forward 摄影机的“方向”(一个和朝向相反的向量)
	Forward = glm::normalize(position - target);
	//Right 它代表Camera的右方,用世界的上方向与摄影机朝向叉乘
	Right = glm::normalize(glm::cross(WorldUp, Forward));
	//UP  摄像机的上方向
	Up = glm::cross(Forward, Right);
}

glm::mat4 Camera::GetViewMatrix()
{
    
    
	//glm::LookAt函数需要一个摄像机位置、一个目标位置和表示世界空间中的上向量的向量。
	//它会创建一个观察矩阵。
	return glm::lookAt(Position, Position - Forward, WorldUp);
}

Camera::Camera(glm::vec3 position, float pitch, float yaw, glm::vec3 worldup)
{
    
    
	Position = position;
	WorldUp = worldup;
	Pitch = pitch;
	Yaw = yaw;
	Forward.x = cos(glm::radians(Pitch)) * sin(glm::radians(Yaw));
	Forward.y = sin(glm::radians(Pitch));
	Forward.z = cos(glm::radians(Pitch)) * cos(glm::radians(Yaw));
	Forward = glm::normalize(Forward);
	//Right 它代表摄像机空间的x轴的正方向
	Right = glm::normalize(glm::cross(WorldUp, Forward));
	//UP 一个指向摄像机的正y轴向量
	Up = glm::cross(Forward, Right);
}

void Camera::ProcessMouseMovement(float deltaX, float deltaY)
{
    
    
	Pitch += deltaY;
	Yaw -= deltaX;

	UpdateCameraVectors();
	if (Pitch > 89.0f)
		Pitch = 89.0f;
	if (Pitch < -89.0f)
		Pitch = -89.0f;
}

//-Forward是当前相机的朝向
//朝前
void Camera::PosUpdateForward()
{
    
    
	Position += cameraPosSpeed * -Forward;
}
//朝后
void Camera::PosUpdateBackward()
{
    
    
	Position -= cameraPosSpeed * -Forward;
}
//朝上
void Camera::PosUpdateUp()
{
    
    
	Position += cameraPosSpeed * WorldUp;
}
//朝下
void Camera::PosUpdateDown()
{
    
    
	Position -= cameraPosSpeed * WorldUp;
	//左边
}
void Camera::PosUpdateLeft()
	{
    
    
		Position -= glm::normalize(glm::cross(-Forward, Up)) * cameraPosSpeed;
	}
	//右边
void Camera::PosUpdateRight()
	{
    
    
		Position += glm::normalize(glm::cross(-Forward, Up)) * cameraPosSpeed;
	}


void Camera::UpdateCameraVectors()
	{
    
    
		Forward.x = cos(glm::radians(Pitch)) * sin(glm::radians(Yaw));
		Forward.y = sin(glm::radians(Pitch));
		Forward.z = cos(glm::radians(Pitch)) * cos(glm::radians(Yaw));
		Forward = glm::normalize(Forward);
		//Right 它代表摄像机空间的x轴的正方向
		Right = glm::normalize(glm::cross(WorldUp, Forward));
		//UP 一个指向摄像机的正y轴向量
		Up = glm::cross(Forward, Right);
	}


Camera::~Camera()
{
    
    
}

main.cpp

#include <iostream>

#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>

#include "Shader.h"
#include "Camera.h"
#include "Material.h"

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

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

#pragma region Model Data

float vertices[] = {
    
    
	//position             //normal             //TexCoord 
	-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,

	-15.0f, -4.0f, -15.0f,  0.0f,  1.0f,  0.0f,  0.0f, 1.0f,
	 15.0f, -4.0f, -15.0f,  0.0f,  1.0f,  0.0f,  1.0f, 1.0f,
	 15.0f, -4.0f,  15.0f,  0.0f,  1.0f,  0.0f,  1.0f, 0.0f,
	 15.0f, -4.0f,  15.0f,  0.0f,  1.0f,  0.0f,  1.0f, 0.0f,
	-15.0f, -4.0f,  15.0f,  0.0f,  1.0f,  0.0f,  0.0f, 0.0f,
	-15.0f, -4.0f, -15.0f,  0.0f,  1.0f,  0.0f,  0.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)
};
#pragma endregion

#pragma region Camera Declare
//建立camera
glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f);
glm::vec3 cameraTarget = glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
Camera camera(cameraPos, cameraTarget, cameraUp);
#pragma endregion

#pragma region Input Declare
//移动用
float deltaTime = 0.0f; // 当前帧与上一帧的时间差
float lastFrame = 0.0f; // 上一帧的时间

void processInput(GLFWwindow* window) {
    
    
	//看是不是按下esc键 然后退出
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
    
    
		glfwSetWindowShouldClose(window, true);
	}
	//更流畅点的摄像机系统
	if (deltaTime != 0) {
    
    
		camera.cameraPosSpeed = 5 * deltaTime;
	}
	//camera前后左右根据镜头方向移动
	if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
		camera.PosUpdateForward();
	if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
		camera.PosUpdateBackward();
	if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
		camera.PosUpdateLeft();
	if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
		camera.PosUpdateRight();
	if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS)
		camera.PosUpdateUp();
	if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS)
		camera.PosUpdateDown();


}
float lastX;
float lastY;
bool firstMouse = true;

//鼠标控制镜头方向
void mouse_callback(GLFWwindow* window, double xpos, double ypos) {
    
    
	if (firstMouse == true)
	{
    
    
		lastX = xpos;
		lastY = ypos;
		firstMouse = false;
	}
	float deltaX, deltaY;
	float sensitivity = 0.05f;

	deltaX = (xpos - lastX)*sensitivity;
	deltaY = (ypos - lastY)*sensitivity;

	lastX = xpos;
	lastY = ypos;

	camera.ProcessMouseMovement(deltaX, deltaY);

};
//缩放
float fov = 45.0f;

void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
    
    
	if (fov >= 1.0f && fov <= 45.0f)
		fov -= yoffset;
	if (fov <= 1.0f)
		fov = 1.0f;
	if (fov >= 45.0f)
		fov = 45.0f;
}

#pragma endregion 

unsigned int LoadImageToGPU(const char* filename, GLint internalFormat, GLenum format, int textureSlot) {
    
    
	unsigned int TexBuffer;
	glGenTextures(1, &TexBuffer);
	glActiveTexture(GL_TEXTURE0 + textureSlot);
	glBindTexture(GL_TEXTURE_2D, TexBuffer);

	// 为当前绑定的纹理对象设置环绕、过滤方式
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

	// 加载并生成纹理
	int width, height, nrChannel;
	unsigned char *data = stbi_load(filename, &width, &height, &nrChannel, 0);
	if (data) {
    
    
		glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, data);
		glGenerateMipmap(GL_TEXTURE_2D);
	}
	else
	{
    
    
		printf("Failed to load texture");
	}
	stbi_image_free(data);
	return TexBuffer;
}

int main() {
    
    

#pragma region Open a Window
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

	//Open GLFW Window
	GLFWwindow* window = glfwCreateWindow(800, 600, "My OpenGL Game", NULL, NULL);
	if (window == NULL)
	{
    
    
		printf("Open window failed.");
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);
	//关闭鼠标显示
	glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
	//回调函数监听鼠标
	glfwSetCursorPosCallback(window, mouse_callback);
	//回调函数监听滚轮
	glfwSetScrollCallback(window, scroll_callback);

	//Init GLEW
	glewExperimental = true;
	if (glewInit() != GLEW_OK)
	{
    
    
		printf("Init GLEW failed.");
		glfwTerminate();
		return -1;
	}


	glViewport(0, 0, 800, 600);
	glEnable(GL_DEPTH_TEST);

#pragma endregion

#pragma region Init Shader Program
	Shader* myShader = new Shader("vertexSource.vert", "fragmentSource.frag");
#pragma endregion

#pragma region Init Material
	Material* myMaterial = new Material(myShader,
		LoadImageToGPU("container.jpg", GL_RGB, GL_RGB, 0),
		glm::vec3(0.5f, 0.5f, 0.5f),
		glm::vec3(1.0f, 0.5f, 0.31f),
		150.0f);
#pragma endregion


#pragma region Init and Load Models to VAO,VBO
	unsigned int VAO;
	glGenVertexArrays(1, &VAO);
	glBindVertexArray(VAO);

	unsigned int VBO;
	glGenBuffers(1, &VBO);
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

	// 位置属性
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
	glEnableVertexAttribArray(0);
	// 颜色属性
	//glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
	//glEnableVertexAttribArray(1);
	// 法向量属性
	glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
	glEnableVertexAttribArray(2);
	// 贴图uv属性
	glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
	glEnableVertexAttribArray(3);
#pragma endregion

#pragma region Init and Load Textures
	//坐标翻转
	stbi_set_flip_vertically_on_load(true);
	//材质
	//unsigned int TexBufferA;
	//TexBufferA = LoadImageToGPU("container.jpg",GL_RGB,GL_RGB,0);

	//unsigned int TexBufferB;
	//TexBufferB = LoadImageToGPU("awesomeface.png", GL_RGBA, GL_RGBA, 1);
#pragma endregion

#pragma region Prepare MVP matrices
	//model
	glm::mat4 modelMat;
	//view
	glm::mat4 viewMat;
	//projection
	glm::mat4 projMat;
#pragma endregion


	while (!glfwWindowShouldClose(window))
	{
    
    
		//Process Input
		processInput(window);

		//Clear Screen
		glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		for (unsigned int i = 0; i < 10; i++)
		{
    
    
			//Set Model matrix
			modelMat = glm::translate(glm::mat4(1.0f), cubePositions[i]);
			float angle = 20.0f * i;
			modelMat = glm::rotate(modelMat, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));

			//Set view matrix
			viewMat = camera.GetViewMatrix();

			//Set projection matrix
			projMat = glm::perspective(glm::radians(fov), 800.0f / 600.0f, 0.1f, 100.0f);


			//Set Material -> Shader Program
			myShader->use();

			//Set Material -> Textures
			glActiveTexture(GL_TEXTURE0 + 0);
			glBindTexture(GL_TEXTURE_2D, myMaterial->diffuse);
			//glActiveTexture(GL_TEXTURE0 + Shader::SPECULAR);
			//glBindTexture(GL_TEXTURE_2D, myMaterial->specular);
			//glActiveTexture(GL_TEXTURE0 + Shader::EMISSSION);
			//glBindTexture(GL_TEXTURE_2D, myMaterial->emission);

			//Set Material -> Uniforms
			//glUniform1i(glGetUniformLocation(myShader->ID, "ourTexture"), 0);
			//glUniform1i(glGetUniformLocation(myShader->ID, "ourFace"), 1);

			glUniformMatrix4fv(glGetUniformLocation(myShader->ID, "modelMat"), 1, GL_FALSE, glm::value_ptr(modelMat));
			glUniformMatrix4fv(glGetUniformLocation(myShader->ID, "viewMat"), 1, GL_FALSE, glm::value_ptr(viewMat));
			glUniformMatrix4fv(glGetUniformLocation(myShader->ID, "projMat"), 1, GL_FALSE, glm::value_ptr(projMat));

			glUniform3f(glGetUniformLocation(myShader->ID, "objColor"), 1.0f, 1.0f, 1.0f);
			glUniform3f(glGetUniformLocation(myShader->ID, "ambientColor"), 0.2f, 0.2f, 0.2f);
			glUniform3f(glGetUniformLocation(myShader->ID, "lightPos"), 0.0f, 3.0f, 3.0f);
			glUniform3f(glGetUniformLocation(myShader->ID, "lightColor"), 1.0f, 1.0f, 1.0f);
			glUniform3f(glGetUniformLocation(myShader->ID, "cameraPos"), camera.Position.x, camera.Position.y, camera.Position.z);

			glUniform1f(glGetUniformLocation(myShader->ID, "time"), glfwGetTime());

			myMaterial->shader->SetUniform3f("material.ambient", myMaterial->ambient);
			myMaterial->shader->SetUniform1i("material.diffuse", 0);
			//myMaterial->shader->SetUniform1i("material.specular", Shader::SPECULAR);
			//myMaterial->shader->SetUniform1i("material.emission", Shader::EMISSSION);
			//myMaterial->shader->SetUniform1f("material.shininess", myMaterial->shininess);

			//Set Model
			glBindVertexArray(VAO);

			//DrawCall
			glDrawArrays(GL_TRIANGLES, 0, 36);
			if (i == 0) {
    
    
				glDrawArrays(GL_TRIANGLES, 36, 6);
			}

		}


		//Clean up prepare for next render loop
		glfwSwapBuffers(window);
		glfwPollEvents();

		//Recording the time
		float currentFrame = glfwGetTime();
		deltaTime = currentFrame - lastFrame;
		lastFrame = currentFrame;
	}
	//Exit program
	glfwTerminate();
	return 0;

}

Material.cpp

#include "Material.h"

Material::Material(Shader * _shader, unsigned int _diffuse, glm::vec3 _specular, glm::vec3 _ambient, float _shininess) :
	shader(_shader),
	diffuse(_diffuse),
	specular(_specular),
	ambient(_ambient),
	shininess(_shininess)
{
    
    

}

Material::~Material()
{
    
    
}

Shader.cpp

#include "Shader.h"
#include <iostream>
#include <fstream>
#include <SStream>

#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>

using namespace std;

Shader::Shader(const char* vertexPath, const char* fragmentPath)
{
    
    
	//从文件路径中获取顶点/片段着色器
	ifstream vertexFile;
	ifstream fragmentFile;
	stringstream vertexSStream;
	stringstream fragmentSStream;
	//打开文件
	vertexFile.open(vertexPath);
	fragmentFile.open(fragmentPath);
	//保证ifstream对象可以抛出异常:
	vertexFile.exceptions(ifstream::failbit || ifstream::badbit);
	fragmentFile.exceptions(ifstream::failbit || ifstream::badbit);

	try
	{
    
    
		if (!vertexFile.is_open() || !fragmentFile.is_open())
		{
    
    
			throw exception("open file error");
		}

		//读取文件缓冲内容到数据流
		vertexSStream << vertexFile.rdbuf();
		fragmentSStream << fragmentFile.rdbuf();

		//转换数据流到string
		vertexString = vertexSStream.str();
		fragmentString = fragmentSStream.str();

		vertexSource = vertexString.c_str();
		fragmentSource = fragmentString.c_str();

		// 编译着色器
		unsigned int vertex, fragment;
		// 顶点着色器
		vertex = glCreateShader(GL_VERTEX_SHADER);
		glShaderSource(vertex, 1, &vertexSource, NULL);
		glCompileShader(vertex);
		checkCompileErrors(vertex, "VERTEX");

		// 片段着色器
		fragment = glCreateShader(GL_FRAGMENT_SHADER);
		glShaderSource(fragment, 1, &fragmentSource, NULL);
		glCompileShader(fragment);
		checkCompileErrors(fragment, "FRAGMENT");

		// 着色器程序
		ID = glCreateProgram();
		glAttachShader(ID, vertex);
		glAttachShader(ID, fragment);
		glLinkProgram(ID);
		checkCompileErrors(ID, "PROGRAM");

		// 删除着色器,它们已经链接到我们的程序中了,已经不再需要了
		glDeleteShader(vertex);
		glDeleteShader(fragment);

	}
	catch (const std::exception& ex)
	{
    
    
		printf(ex.what());
	}
}

void Shader::use()
{
    
    
	glUseProgram(ID);
}

void Shader::SetUniform3f(const char * paraNameString, glm::vec3 param)
{
    
    
	glUniform3f(glGetUniformLocation(ID, paraNameString), param.x, param.y, param.z);
}

void Shader::SetUniform1f(const char * paraNameString, float param)
{
    
    
	glUniform1f(glGetUniformLocation(ID, paraNameString), param);
}

void Shader::checkCompileErrors(unsigned int ID, std::string type) {
    
    
	int sucess;
	char infolog[512];

	if (type != "PROGRAM")
	{
    
    
		glGetShaderiv(ID, GL_COMPILE_STATUS, &sucess);
		if (!sucess)
		{
    
    
			glGetShaderInfoLog(ID, 512, NULL, infolog);
			cout << "shader compile error:" << infolog << endl;
		}
	}
	else
	{
    
    
		glGetProgramiv(ID, GL_LINK_STATUS, &sucess);
		if (!sucess)
		{
    
    
			glGetProgramInfoLog(ID, 512, NULL, infolog);
			cout << "program linking error:" << infolog << endl;
		}
	}
}
void Shader::SetUniform1i(const char * paraNameString, int slot)
{
    
    
	glUniform1i(glGetUniformLocation(ID, paraNameString), slot);
}

猜你喜欢

转载自blog.csdn.net/esjiang/article/details/114222068