openGL 三:矩阵和向量

1.使用glm数学库进行矩阵和向量的计算
2.位置坐标可以看做一个向量
3.向量的移动,缩放,旋转,都是可以通过和矩阵的计算得出
4.向量的缩放=乘一个44的矩阵
5.注意事项(有些版本的glm::mat4 不是默认构建一个单位4
4的矩阵),这个时候需要手动赋值,glm::mat4 matval = glm::mat4(1.0f);

#include "GL/glew.h"
#include "glfw3.h"
#include "SOIL2.h"
//glfw :graphics library framework 图形库框架
// 作用:1.用于创建和管理跨平台的窗口; 2. 处理输入,鼠标键盘等 ; 3.用于创建和管理opengl上下文

//glew:opengl extension Wrangler 用于管理opengl 扩展的开源库
// 作用: 1.用于加载扩展函数,2.查询扩展支持
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"

#include 
#include 

//顶点着色器源码 glsl
const GLchar* vertexSource = "#version 330 core \n \
							 layout(location=0) in vec3 position;\
							 layout(location=1) in vec3 color;\
							 layout(location=2) in vec2 texcoodr;\
							 out vec4 outcolor;\
							 out vec2 outtexcoodr;\
							 uniform mat4 transformkk;\
void main()\
{\
gl_Position=transformkk*vec4(position, 1.0f); outcolor=vec4(color,1.0f); outtexcoodr=texcoodr;\
}";

//GLSL 语言: mix, texture, sampler2D 采样器变量
const GLchar* fragmentSource = "#version 330 core \n \
							   in vec4 outcolor;\
							   in vec2 outtexcoodr;\
							   out vec4 color;\
							   uniform sampler2D ourtexture;\
							   uniform sampler2D ourtexture2;\
							   uniform float mixval;\
								void main(){\
									vec2 coord = vec2(outtexcoodr.x , 1.0f - outtexcoodr.y);\
									color = mix(texture(ourtexture,outtexcoodr),texture(ourtexture2,coord),mixval);\
									}";

GLfloat mixval = 0.2f;
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
	if (key == GLFW_KEY_UP && action == GLFW_PRESS)
	{
		mixval += 0.1f;
		if (mixval >= 1.0f)
		{
			mixval = 1.0f;
		}
	}
	else if (key == GLFW_KEY_DOWN && action == GLFW_PRESS)
	{
		mixval -= 0.1f;
		if (mixval <= 0.0f)
		{
			mixval = 0.0f;
		}
	}
}
int main()
{
	//初始化使用到的 glfw库
	glfwInit();

	//创建窗口
	GLFWwindow* window = glfwCreateWindow(600, 500, "opengl texture exercise", nullptr, nullptr);
	//指定当前上下文
	glfwMakeContextCurrent(window);

	//初始化opengl 扩展库
	glewInit();

	//创建目标着色器以及管线管理程序
	GLuint vertexShader, fragmentShader, program;
	GLint succeed;
	GLchar buff[512];

	//顶点着色器
	vertexShader = glCreateShader(GL_VERTEX_SHADER);
	//加载顶点着色器源码
	glShaderSource(vertexShader, 1, &vertexSource, (GLint*)0);//第三个参数,是指向一个整数数组,数组每个字符串的长度
	glCompileShader(vertexShader);//编译着色器源码
	glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &succeed);
	if (!succeed)
	{
		glGetShaderInfoLog(vertexShader, 512, NULL, buff);//第三个参数:返回日志的实际长度,null表示不用返回
	}

	//片段着色器
	fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragmentShader, 1, &fragmentSource, (GLint*)0);
	glCompileShader(fragmentShader);
	glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &succeed);
	if (!succeed)
	{
		glGetShaderInfoLog(fragmentShader, 512, NULL, buff);
	}
	//创建着色器程序
	program = glCreateProgram();
	glAttachShader(program, vertexShader);
	glAttachShader(program, fragmentShader);
	glLinkProgram(program);

	glDeleteShader(vertexShader);
	glDeleteShader(fragmentShader);

	//定义数据数组 ,矩形 == 两个三角形组成, 四个点,每个点对于的颜色值,和纹理坐标位置
	//GLfloat vertexArray[] = {
	//	/* 点位置				颜色				纹理坐标*/
	//	0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 1.0f, 2.0f, 2.0f,
	//	0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 2.0f, 0.0f,
	//	-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
	//	-0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 2.0f,

	//};
	GLfloat vertexArray[] = {
		// Positions          // Colors           // Texture Coords
		0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // Top Right
		0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Bottom Right
		-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Bottom Left
		-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f  // Top Left 
	};

	//GLfloat vertexArray[] = {
	//	0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 1.0f,   0.51f, 0.51f,
	//	0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.51f, 0.49f,
	//	-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.49f, 0.49f,
	//	-0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.49f, 0.51f,

	//};


	//元素数组三角形的点的数组索引
	GLuint eArray[] = {
		0, 1, 3,
		1, 2, 3
	};

	//创建顶点数组对象 VAO, 顶点缓存对象 VBO, 元素缓存对象EBO
	GLuint VAO, VBO, EBO;
	//创建顶点数组对象,用于管理和封装顶点缓存数组,以及数据解析方式。 一个顶点数组对象可以管理好几个数据缓存对象的配置信息
	//顶点属性指针,顶点缓存保存
	glGenVertexArrays(1, &VAO);
	glBindVertexArray(VAO);

	//创建vbo
	glGenBuffers(1, &VBO);
	//绑定顶点缓存对象
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	//在GPU创建缓和初始化 VBO 的数据存储,
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertexArray), vertexArray, GL_STATIC_DRAW);


	//创建EBO
	glGenBuffers(1, &EBO);
	//绑定元素缓存对象
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
	//加载数据到CPU缓存
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(eArray), eArray, GL_STATIC_DRAW);

	//配置顶点属性指针:如何解析数据输入到顶点着色器里面,类似顶点着色器输入参数的一种数据格式
	//					顶点属性数组的索引, 个数, 类型, 是否标准化, 步长stride, 偏移量
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
	//使能顶点属性数组:索引值
	glEnableVertexAttribArray(0);

	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
	glEnableVertexAttribArray(1);

	glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
	glEnableVertexAttribArray(2);

	//解绑 顶点数组对象
	glBindBuffer(GL_ARRAY_BUFFER, 0);

	//纹理============================================================================================
	//1.0 创建纹理对象
	GLuint texture1, texture2;
	glGenTextures(1, &texture1);

	//2.0 绑定纹理对象
	glBindTexture(GL_TEXTURE_2D, texture1);

	//3.0 设置纹理配置参数值
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);//超出纹理坐标的纹理如何处理:纹理环绕方式,x 轴== s 轴
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);//超出纹理坐标的纹理如何处理:纹理环绕方式,Y 轴== T 轴
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); //纹理过滤方式, 最近
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);//线性

	//4.0 根据图片生成纹理图形
	int width, height;
	unsigned  char *image = SOIL_load_image("container.jpg", &width, &height, 0, SOIL_LOAD_RGB);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);//设置2d纹理图像数据
	glGenerateMipmap(GL_TEXTURE_2D);//生成纹理的所有级别的缩放图像
	SOIL_free_image_data(image);
	glBindTexture(GL_TEXTURE_2D, 0); //相当于保存该纹理配置,不会弄乱


	/*GL_REPEAT	对纹理的默认行为。重复纹理图像。
		GL_MIRRORED_REPEAT	和GL_REPEAT一样,但每次重复图片是镜像放置的。
		GL_CLAMP_TO_EDGE	纹理坐标会被约束在0到1之间,超出的部分会重复纹理坐标的边缘,产生一种边缘被拉伸的效果。
		GL_CLAMP_TO_BORDER	超出的坐标为用户指定的边缘颜色。*/

	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_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	unsigned char* image2 = SOIL_load_image("awesomeface.png", &width, &height, 0, SOIL_LOAD_RGB);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image2);
	glGenerateMipmap(GL_TEXTURE_2D);//设置纹理缩放图像
	SOIL_free_image_data(image2);
	glBindTexture(GL_TEXTURE_2D, 0);


	//设置鼠标事件回调
	glfwSetKeyCallback(window, key_callback);


	while (!glfwWindowShouldClose(window))
	{

		glm::vec4 vect(1.0f, 1.0f, 0.0f, 1.0f);
		glm::mat4 transformkk = glm::mat4(1.0f); // ({ 1.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 1.0f });

		glfwPollEvents();

		glClearColor(0.5f, 0.5f, 0.2f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);//清除缓存区: 颜色缓存区

		
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, texture1);
		glUniform1i(glGetUniformLocation(program, "ourtexture"), 0);

		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, texture2);
		glUniform1i(glGetUniformLocation(program, "ourtexture2"), 1);

		transformkk = glm::rotate(transformkk, (GLfloat)glfwGetTime()*5.0f, glm::vec3(0.0, 0.0, 1.0));
		transformkk = glm::translate(transformkk, glm::vec3(0.5, 0.5, 0.5));
		glUniformMatrix4fv(glGetUniformLocation(program, "transformkk"), 1, GL_FALSE, glm::value_ptr(transformkk));

		glUniform1f(glGetUniformLocation(program, "mixval"), mixval);

		//使能着色器程序
		glUseProgram(program);
		glBindBuffer(GL_ARRAY_BUFFER, VAO);
		glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

		glm::mat4 transformdd = glm::mat4(1.0f);
		transformdd = glm::translate(transformdd, glm::vec3(-0.5, 0.5, 0.0));
		transformdd = glm::scale(transformdd, glm::vec3(sin((GLfloat)glfwGetTime()), sin((GLfloat)glfwGetTime()), 1.0));
		glUniformMatrix4fv(glGetUniformLocation(program, "transformkk"), 1, GL_FALSE, glm::value_ptr(transformdd));
		glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
		glBindBuffer(GL_ARRAY_BUFFER, 0);

		glfwSwapBuffers(window);

	}

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

	glfwTerminate();




	return 0;
};

你可能感兴趣的:(opengl,矩阵,线性代数)