OPENGL添加摄像机功能练习

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

#include <glad\glad.h>
#include <GLFW\glfw3.h>
#include <iostream>


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


const unsigned int SRC_WIDTH = 800;
const unsigned int SRC_HEIGHT = 600;

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);

bool firstMouse = true;
float yaw = -90.0f;
float pitch = 0.0f;
float lastX = 800.0f / 2.0f;
float lastY = 600.0f / 2.0f;



void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
void processInput(GLFWwindow *window);


const char* vertexShaderSource = "#version 330 core\n"
"layout(location = 0) in vec3 aPos;\n"
"layout(location = 1) in vec2 aVtexCord;\n"
"out vec2 VtexCord;\n"
"uniform mat4 model;\n"
"uniform mat4 view;\n"
"uniform mat4 projection;\n"
"void main(){\n"
"gl_Position = projection * view * model * vec4(aPos,1.0);\n"
"VtexCord = vec2(aVtexCord.x , aVtexCord.y);\n"
"}\n"
;


const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"in vec2 VtexCord;\n"
"uniform sampler2D texture1;\n"
"uniform sampler2D texture2;\n"
"void main(){\n"
"FragColor = mix( texture( texture1,VtexCord ), texture( texture2,VtexCord ), 0.5);\n"
"}\n";


int main()
{

	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
	glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X
#endif

	GLFWwindow* window = glfwCreateWindow(SRC_WIDTH, SRC_HEIGHT, "Zhongqi", NULL, NULL);
	if (window == NULL)
	{
		std::cout << "Cannot Create Window\n" << std::endl;
		glfwTerminate();
		return -1;
	}

	glfwMakeContextCurrent(window);
	glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
	glfwSetCursorPosCallback(window, mouse_callback);
	// tell GLFW to capture our mouse
    //glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);


	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
	{
		return -1;
	}

	//创建顶点着色器
	int vertexShader = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vertexShader, 1,&vertexShaderSource,NULL);
	glCompileShader(vertexShader);
	int success;
	char infoLog[512];
	glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
	if (!success)
	{
		glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
		std::cout << infoLog << std::endl;
	}

    //创建片段着色器
	int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
	glCompileShader(fragmentShader);
	glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
	if (!success)
	{
		glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
		std::cout << infoLog << std::endl;
	}

	//创建连接器程序
	int shaderPrograme = glCreateProgram();
	glAttachShader(shaderPrograme, vertexShader);
	glAttachShader(shaderPrograme, fragmentShader);
	glLinkProgram(shaderPrograme);
	glGetProgramiv(shaderPrograme, GL_LINK_STATUS, &success);
	if (!success)
	{
		glGetProgramInfoLog(shaderPrograme, 512, NULL, infoLog);
		std::cout << infoLog << std::endl;
	}

	glDeleteShader(vertexShader);
	glDeleteShader(fragmentShader);

	//创建顶点
	float firstTrangles[] = {

		-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 VAO, VBO;
	 glGenVertexArrays(1, &VAO);
	 glGenBuffers(1, &VBO);

	 glBindVertexArray(VAO);
	 glBindBuffer(GL_ARRAY_BUFFER, VBO);
	 glBufferData(GL_ARRAY_BUFFER, sizeof(firstTrangles), firstTrangles, GL_STATIC_DRAW);
	 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(0));
	 glEnableVertexAttribArray(0);
	 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
	 glEnableVertexAttribArray(1);
	 

	 //绘制纹理
	 unsigned int texture1, texture2;
	 glGenTextures(1, &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_MAG_FILTER, GL_LINEAR);
	 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	 //加载图片
	 int pic_width, pic_height, pic_channels;
	 stbi_set_flip_vertically_on_load(true);
	 unsigned char* data = stbi_load("container.jpg", &pic_width, &pic_height, &pic_channels, 0);
	 if (data)
	 {
		 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, pic_width, pic_height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
		 glGenerateMipmap(GL_TEXTURE_2D);
	 }
	 else {
		 std::cout << "load image failed\n" << std::endl;
	 }
	 stbi_image_free(data);

	 glGenTextures(1, &texture2);
	 glBindTexture(GL_TEXTURE_2D, texture2);
	 //设置环绕模式
	 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_MAG_FILTER, GL_LINEAR);
	 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	 //加载图片
	 data = stbi_load("awesomeface.png", &pic_width, &pic_height, &pic_channels, 0);
	 if (data)
	 {
		 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, pic_width, pic_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
		 glGenerateMipmap(GL_TEXTURE_2D);
	 }
	 else {
		 std::cout << "load image failed\n" << std::endl;
	 }
	 stbi_image_free(data);

	 //绑定纹理单元
	 glUseProgram(shaderPrograme);
	 GLint firstTexPos = glGetUniformLocation(shaderPrograme, "texture1");
	 GLint secondTexPos = glGetUniformLocation(shaderPrograme, "texture2");
	 glUniform1i(firstTexPos, 0);
	 glUniform1i(secondTexPos,1);

	 //深度测试
	 glEnable(GL_DEPTH_TEST);

	 //渲染
	 while (!glfwWindowShouldClose(window))
	 {

		 processInput(window);
		 glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // also clear the depth buffer now!

															 //激活纹理单元
		 glActiveTexture(GL_TEXTURE0);
		 glBindTexture(GL_TEXTURE_2D, texture1);
		 glActiveTexture(GL_TEXTURE1);
		 glBindTexture(GL_TEXTURE_2D, texture2);

		 //创建模型矩阵--》世界坐标
		 glm::mat4 model;
		 //视野矩阵--》观察坐标
		 glm::mat4 view;
		 //透视投影矩阵
		 glm::mat4 projection;

		 //透视投影
		 projection = glm::perspective(glm::radians(45.0f), (float)SRC_WIDTH / (float)SRC_HEIGHT, 0.1f, 200.0f);

		 view = glm::lookAt(cameraPos, cameraFront + cameraPos, cameraUp);

		 glUseProgram(shaderPrograme);

		 GLint viewPosition = glGetUniformLocation(shaderPrograme, "view");
		 GLint projectionPosition = glGetUniformLocation(shaderPrograme, "projection");
		 glUniformMatrix4fv(viewPosition, 1, GL_FALSE, glm::value_ptr(view));
		 glUniformMatrix4fv(projectionPosition, 1, GL_FALSE, glm::value_ptr(projection));


		 for (int i = 0; i < 10; i++)
		 {
			 model = glm::translate(model, cubePositions[i]);
			 float angle = 20.0f * i;
			 model = glm::rotate(model, glm::radians(angle), glm::vec3(0.5f, 1.0f, 0.0f));
			 GLint modelPosition = glGetUniformLocation(shaderPrograme, "model");
			 glUniformMatrix4fv(modelPosition, 1, GL_FALSE, glm::value_ptr(model));
			 glBindVertexArray(VAO);
			 //使用EBO的时候用glDrawElements
			 //glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
			 glDrawArrays(GL_TRIANGLES, 0, 36);

		 }

		 glfwSwapBuffers(window);
		 glfwPollEvents();

	 }
	 glDeleteVertexArrays(1,&VAO);
	 glDeleteBuffers(1, &VBO);

	 glfwTerminate();
	 return 0;

}

//鼠标滑动的时候X轴模仿yaw Y轴模仿pitch 获得front向量的三个方向
void mouse_callback(GLFWwindow* window, double xpos, double ypos)
{
	if (firstMouse)
	{
		lastX = (float)xpos;
		lastY = (float)ypos;
		firstMouse = false;
	}

	float xoff = (float)xpos - lastX;
	float yoff = (float)ypos - lastY;
	lastX = (float)xpos;
	lastY = (float)ypos;

	float sensitive = 0.1f;
	xoff *= sensitive;
	yoff *= sensitive;

	yaw += xoff;
	pitch += yoff;
	if (pitch > 89.0f)
	{
		pitch = 89.0f;
	}
	else 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 processInput(GLFWwindow *window)
{
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
				glfwSetWindowShouldClose(window, true);
}

void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
	glViewport(0, 0, width, height);
}


效果图



谢谢https://learnopengl-cn.github.io/02%20Lighting/01%20Colors/网站提供的资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值