本篇文章是基于清清博客
代码整合
总代码
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);
}