projection 里的角度,角度越大,物体离摄像机越远;角度越小,物体离摄像机越近,这个角度表示视野(fov),视野越大,看到的物体就越小
头文件
#ifndef SHADER_H_INCLUDE
#define SHADER_H_INCLUDE #include <iostream>
#include <string>
#include <sstream>
#include <fstream> #include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <typeinfo>
class Shader {
public:
unsigned int ID; Shader(const GLchar* vertexPath, const GLchar* fragmentPath)
{
std::string vertexCode;
std::string fragmentCode;
std::ifstream vShaderFile;
std::ifstream fShaderFile; vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit); try {
//open files
vShaderFile.open(vertexPath);
fShaderFile.open(fragmentPath); std::stringstream vShaderStream, fShaderStream; //read file's buffer contents into streams
vShaderStream << vShaderFile.rdbuf();
fShaderStream << fShaderFile.rdbuf(); //close file handlers
vShaderFile.close();
fShaderFile.close(); //convert stream into string
vertexCode = vShaderStream.str();
fragmentCode = fShaderStream.str();
}
catch (std::ifstream::failure e)
{
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ" << std::endl;
}
const char* vShaderCode = vertexCode.c_str();
const char* fShaderCode = fragmentCode.c_str(); //2.compile shaders
unsigned int vertex, fragment;
int success;
char infoLog[]; //vertex shader
vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, , &vShaderCode, NULL);
glCompileShader(vertex);
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertex, , NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED!" << std::endl;
} fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, , &fShaderCode, NULL);
glCompileShader(fragment);
glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragment, , NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED!" << std::endl;
} ID = glCreateProgram();
glAttachShader(ID, vertex);
glAttachShader(ID, fragment);
glLinkProgram(ID);
glGetProgramiv(ID, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(ID, , NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKTING_FAILED!" << std::endl;
} //delete the shaders sa they are linked into our program now and no long necessary
glDeleteShader(vertex);
glDeleteShader(fragment);
} //activate the shader
void use()
{
glUseProgram(ID);
} //utility uniform functions
void setBool(const std::string &name, bool value) const
{
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
} void setInt(const std::string &name, int value) const
{
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
} void setFloat(const std::string &name, float value) const
{
glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
} void setMat4(const std::string &name, glm::mat4 &trans) const
{ glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), , GL_FALSE, &trans[][]);
} /*void setMat4(const std::string &name, glm::mat4 trans) const
{ //'trans': formal parameter with requested alignment of 16 won't be aligned,请求对齐的16的形式参数不会对齐
glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, glm::value_ptr(trans));
}*/ }; #endif
.cpp源文件
//projection 里的角度,角度越大,物体离摄像机越远;角度越小,物体离摄像机越近,这个角度表示视野(fov)
//视野越大,看到的物体就越小
#include <iostream>
using namespace std;
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include "Shader.h"
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp> void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void mouse_callback(GLFWwindow* window, GLdouble xpos, GLdouble ypos);
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
//void scroll_callback(GLFWwindow* window, GLdouble xoffset, GLdouble yoffset);
void processInput(GLFWwindow *window); glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f);
glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f); float deltaTime = 0.0f;
float lastFrame = 0.0f;
float mixValue = 0.3f;
float SCR_WIDTH = ;
float SCR_HEIGHT = ;
float Left = 0.0f;
float Up = 0.0f;
float lastX = , lastY = ;
float yaw = -90.0f, pitch = 0.0f;//yaw是偏航角,pitch是俯仰角
GLboolean firstMouse = true;
float fov = 45.0f; int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, );
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, );
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(, , "LearnOpenGL", NULL, NULL);
if (!window)
{
cout << "Failed to create window!\n" << endl;
glfwTerminate();
return -;
}
glfwMakeContextCurrent(window); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); //隐藏并捕捉光标
glfwSetCursorPosCallback(window, mouse_callback); //回调鼠标事件
glfwSetScrollCallback(window, scroll_callback); //滚轮回调事件 glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
{
cout << "Failed to initialize GLEW!" << endl;
return -;
} //glfwSetCursorPosCallback(window, mouse_callback);
//glfwSetScrollCallback(window, scroll_callback); //tell GLFW to capture our mouse
//glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); //configure global opengl state, z buffer
glEnable(GL_DEPTH_TEST);//Z缓冲,深度缓冲 //build and compile our shader program
Shader ourShader("E:\\C++\\3.txt", "E:\\C++\\4.txt"); float vertices[] = {
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 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)
}; unsigned int indeices[] = {
, , ,
, ,
};
unsigned int VBO, VAO, EBO;
glGenVertexArrays(, &VAO);
glGenBuffers(, &VBO);
glGenBuffers(, &EBO); glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indeices), indeices, GL_STATIC_DRAW); glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, * sizeof(float), (void*));
glEnableVertexAttribArray(); glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, * sizeof(float), (void*)( * sizeof(float)));
glEnableVertexAttribArray(); //glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
//glEnableVertexAttribArray(2); unsigned int texture1, texture2;
glGenTextures(, &texture1);
glBindTexture(GL_TEXTURE_2D, texture1); 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_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); int width, height, nrChannels;//Channels通道
stbi_set_flip_vertically_on_load(true); //tell stb_image.h to flip load texture's on the y-axis //flip翻转
unsigned char *data = stbi_load("wall.jpg", &width, &height, &nrChannels, ); //加载图像
if (data)
{
glTexImage2D(GL_TEXTURE_2D, , GL_RGB, width, height, , GL_RGB, GL_UNSIGNED_BYTE, data); //创建一个纹理
glGenerateMipmap(GL_TEXTURE_2D); //承担创建一个纹理后接下来的全部工作,为当前绑定的纹理自动生成所有需要的多级渐远纹理
}
else
{
cout << "Failed to load texture1!" << endl;
}
stbi_image_free(data); //为绑定的纹理生辰多级渐远纹理之后释放图像的内存 //texture2
glGenTextures(, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); data = stbi_load("timg.jpg", &width, &height, &nrChannels, );
if (data)
{
glTexImage2D(GL_TEXTURE_2D, , GL_RGB, width, height, , GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
cout << "Failed to load texture2!" << endl;
}
stbi_image_free(data); ourShader.use();
glUniform1i(glGetUniformLocation(ourShader.ID, "texture1"), );
glUniform1i(glGetUniformLocation(ourShader.ID, "texture2"), ); //trans = glm::rotate(trans, glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f));
//trans = glm::scale(trans, glm::vec3(0.5f, -0.5f, 1.0f));
//第二个参数是传递的矩阵的数量,第三个是是否希望矩阵被置换(行与列交换),第四个是要传递的矩阵 float axis; //render loop
while (!glfwWindowShouldClose(window))
{
//per-frame time logic 每帧的时间增量
GLfloat currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame; processInput(window); glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2); ourShader.setFloat("mixValue", mixValue); glm::mat4 trans; //trans = glm::translate(trans, glm::vec3(0.5f, -0.5f, 0.0f));
//trans = glm::rotate(trans, glm::radians(15.0f), glm::vec3(1.0f, 0.0f, 0.0f));
//trans = glm::rotate(trans, (float)glfwGetTime(), glm::vec3(0.0f, 0.0f, 1.0f));
glUniformMatrix4fv(glGetUniformLocation(ourShader.ID, "transform"), , GL_FALSE, glm::value_ptr(trans)); glUseProgram(ourShader.ID);
glm::mat4 transform;
transform = glm::translate(trans, glm::vec3(Left, Up, 0.0f));
ourShader.setMat4("transform", transform); //glm::mat4 model;
glm::mat4 view;
glm::mat4 projection;
//model = glm::rotate(model, glm::radians(45.0f), glm::vec3(0.0f, 1.0f, 0.0f));
//model = glm::rotate(model, (float)glfwGetTime() * glm::radians(50.0f), glm::vec3(0.5f, 1.0f, 0.0f));
//view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp); //摄像机的lookAt矩阵就是观察矩阵
//glm::mat4 view;
float radius = 10.0f;
float camX = sin(glfwGetTime()) * radius;
float camZ = cos(glfwGetTime()) * radius;
//view = glm::lookAt(glm::vec3(camX, 0.0f, camZ), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f)); //projection = glm::ortho(0.0f, 800.0f, 0.0f, 600.0f, 0.1f, 100.0f);
projection = glm::perspective(glm::radians(fov), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f); //
//glUniformMatrix4fv(glGetUniformLocation(ourShader.ID, "model"), 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(glGetUniformLocation(ourShader.ID, "view"), , GL_FALSE, glm::value_ptr(view));
ourShader.setMat4("projection", projection); glBindVertexArray(VAO); for (unsigned int i = ; i < ; i++)
{
glm::mat4 model;
model = glm::translate(model, cubePositions[i]);
float angle = 20.0f * i; angle = glfwGetTime() * 25.0f; //axis = sin(glfwGetTime());
model = glm::rotate(model, glm::radians(angle), glm::vec3(0.2f * i, 0.1* i, 0.3));
ourShader.setMat4("model", model);
glDrawArrays(GL_TRIANGLES, , );
} //glDrawArrays(GL_TRIANGLES, 0, 36);
//glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); //trans = glm::mat4(); //trans必须是与上面的trans是同一个,一个uniform在同一个程序中只能被绑定一次
//trans = glm::translate(trans, glm::vec3(-0.5f, 0.5f, 0.0f));
//trans = glm::scale(trans, glm::vec3(sin(glfwGetTime()), sin(glfwGetTime()), sin(glfwGetTime())));
//glUniformMatrix4fv(glGetUniformLocation(ourShader.ID, "transform"), 1, GL_FALSE,glm::value_ptr(trans));
////glBindVertexArray(VAO);
//glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glfwSwapBuffers(window);
glfwPollEvents();
} glDeleteVertexArrays(, &VAO);
glDeleteBuffers(, &VBO); glfwTerminate();
return ; return ;
} void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(, , width, height);
} void processInput(GLFWwindow* window)
{
if (glfwGetKey(window, GLFW_KEY_ENTER) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS)
{
mixValue += 0.001f;
if (mixValue >= 1.0f)
mixValue = 1.0f;
}
if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS)
{
mixValue -= 0.001f;
if (mixValue <= 0.0f)
mixValue = 0.0f;
} if (glfwGetKey(window, GLFW_KEY_4) == GLFW_PRESS)
{
Left -= 0.001;
} if (glfwGetKey(window, GLFW_KEY_6) == GLFW_PRESS)
{
Left += 0.001f;
}
if (glfwGetKey(window, GLFW_KEY_8) == GLFW_PRESS)
{
Up += 0.001f;
} if (glfwGetKey(window, GLFW_KEY_2) == GLFW_PRESS)
{
Up -= 0.001f;
} float cameraSpeed = 2.5 * deltaTime;
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
cameraPos += cameraSpeed * cameraFront;
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
cameraPos -= cameraSpeed * cameraFront;
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
cameraPos -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
cameraPos += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
} void mouse_callback(GLFWwindow* window, double xpos, double ypos)
{
if (firstMouse)
{
lastX = xpos;
lastY = ypos;
firstMouse = false;
} float xoffset = xpos - lastX;
float yoffset = lastY - ypos; lastX = xpos;
lastY = ypos;
float sensitivity = 0.0005f;
xoffset *= sensitivity;
yoffset *= sensitivity;
yaw += xoffset;
pitch += yoffset; if (pitch > 89.0f)
pitch = 89.0f;
if (pitch < -89.0f)
pitch = -89.0f; glm::vec3 front;
front.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
front.y = sin(glm::radians(pitch));
front.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
cameraFront = glm::normalize(front); } 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;
}
timg.jpg文件
wall.jpg文件