opengl 实现三角形逆时针旋转

要实现旋转的操作就会用到旋转公式,这里先贴出2d平面内的旋转公式:

x' = x*cos(a) - y*sin(a);
y' = x*sin(a) + y*cos(a)

这里只需要将a动态的传递给shader程序就行了

顶点着色器为:shader.vs

#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aColor;
out vec3 outputColor;
float tempx;
float tempy;
uniform float degree;
void main()
{
    tempx = aPos.x*cos(radians(degree)) - aPos.y * sin(radians(degree));
	tempy = aPos.x*sin(radians(degree)) + aPos.y * cos(radians(degree));
	gl_Position = vec4(tempx,tempy,aPos.z,1.0f);
    outputColor = aColor;
}

片段着色器:shader.fs

#version 330 core
in vec3 outputColor;
out vec4 fragColor;
uniform vec4 outcolor;
void main(){
	fragColor = vec4(outputColor,1.0f);
}

其中degree这个变量就是程序传递到shader中的变量

main.cpp:

#include "shader.h"
#include <glad/glad.h>
#include <gl/GL.h>
#include <GLFW/glfw3.h>
#include <string>
#include <iostream>
typedef unsigned int uint;
using namespace std;
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow *window);
GLFWwindow* showWindowSomething();
// template<class T, int N>
void renderTriangle(int shaderProgram, unsigned int VAO, unsigned int VBO, unsigned int EBO,uint verticesSizeof,uint indicesSizeof,float* elementVertices,uint* indices);
void drawSomgthing();
// settings
void renderTwoTriangle(unsigned int VAO, unsigned int VBO, float* vertices, uint verticesSizeof);
// 渲染带颜色值的顶点数组
void renderObjByMoreP(unsigned int VAO, unsigned int VBO, float* vertices, uint verticesSizeof);
int dealError(GLFWwindow* window);
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
uint VAO, VBO;

float vertices[] = {
	1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,
	-1.0f,0.0f,0.0f,0.0f,1.0f,0.0f,
	0.0f,1.0f,0.0f,0.0f,0.0f,1.0f
};
int main()
{
	//gladLoadGLLoader();
	// 设置线框模式
	// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	GLFWwindow* window = showWindowSomething();
	// 初始化glload
	dealError(window);
	Shader shaderItem = Shader("shader.vs","shader.fs");
	shaderItem.use();
	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);
	renderObjByMoreP(VAO,VBO,vertices,sizeof(vertices));
	// render loop
	// -----------
	while (!glfwWindowShouldClose(window))
	{
		// input
		// -----
		processInput(window);
		double curTime = glfwGetTime();

		shaderItem.setFloat("degree",curTime);
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);
		// draw
		drawSomgthing();
		// -------------------------------------------------------------------------------
		glfwSwapBuffers(window);
		glfwPollEvents();
	}
	glDeleteProgram(shaderItem.ID);
	glDeleteBuffers(1,&VBO);
	glDeleteVertexArrays(1,&VAO);
	// glfw: terminate, clearing all previously allocated GLFW resources.
	// 回收占用的内存
	// ------------------------------------------------------------------
	glfwTerminate();
	return 0;
}
void drawSomgthing() {
	glBindVertexArray(VAO);
	glDrawArrays(GL_TRIANGLES,0,3);
}
int dealError(GLFWwindow* window) {
	if (window == NULL)
	{
		std::cout << "Failed to create GLFW window" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);
	glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

	// glad: load all OpenGL function pointers
	// ---------------------------------------
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
	{
		std::cout << "Failed to initialize GLAD" << std::endl;
		return -1;
	}
}
// 渲染具体的物体对象方法
/**
   绘制三角形对象
*/
void renderTriangle(int shaderProgram, unsigned int VAO, unsigned int VBO, unsigned int EBO, uint verticesSizeof, uint indicesSizeof, float* elementVertices, uint* indices)
{
	cout << "顶点数组的sizeof is " << verticesSizeof << endl;
	// 定义顶点缓冲对象 GL_ARRAY_BUFFER
	glBindVertexArray(VAO);
	// 绑定缓冲对象 修改opengl状态机从此以后任何的缓冲调用都会来配置当前绑定的缓冲
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, verticesSizeof, elementVertices, GL_STATIC_DRAW);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesSizeof, indices, GL_STATIC_DRAW);

	// 配置顶点属性指针
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);
	glEnableVertexAttribArray(0);
	// 链接都对象后删除着色器对象我们不在需要了
	
	// 数据已经送往了GPU内存中了可以解绑了
	glBindBuffer(GL_ARRAY_BUFFER, 0);

	glBindVertexArray(0);
}
//渲染两个相连的三角形
void renderTwoTriangle(unsigned int VAO,unsigned int VBO,float* vertices,uint verticesSizeof) {
	
	glBindVertexArray(VAO);
	glBindBuffer(GL_ARRAY_BUFFER,VBO);
	glBufferData(GL_ARRAY_BUFFER,verticesSizeof,vertices,GL_STATIC_DRAW);
	// 配置顶点属性指针
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);
	glEnableVertexAttribArray(0);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindVertexArray(0);

}
/**

	测试在顶点数组中加入更多的属性比如颜色值信息

*/
void renderObjByMoreP(unsigned int VAO,unsigned int VBO,float* vertices,uint verticesSizeof) {
	glBindVertexArray(VAO);
	glBindBuffer(GL_ARRAY_BUFFER,VBO);
	glBufferData(GL_ARRAY_BUFFER, verticesSizeof, vertices, GL_STATIC_DRAW);
	// 配置顶点属性指针 位置属性
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0);
	glEnableVertexAttribArray(0);
	// 颜色属性
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)(3 * sizeof(float)));
	glEnableVertexAttribArray(1);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindVertexArray(0);
}
GLFWwindow* showWindowSomething() {
	// glfw: initialize and configure
	// ------------------------------
	glfwInit();
	// 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

	// glfw window creation
	// --------------------
	GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "OpenGL_GAME", NULL, NULL);
	
	return window;
}
// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow *window)
{
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
		glfwSetWindowShouldClose(window, true);
}
// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
	// make sure the viewport matches the new window dimensions; note that width and 
	// height will be significantly larger than specified on retina displays.
	cout << "width is " << width << "height is " << height << endl;
	glViewport(0, 0, width, height);
}

shader.h:

#ifndef SHADER_H
#define SHADER_H
#include <string>
using namespace std;
class Shader
{
public:
	unsigned int ID;
	// constructor generates the shader on the fly
	// ------------------------------------------------------------------------
	Shader(const char* vertexPath, const char* fragmentPath);
	// activate the shader
	// ------------------------------------------------------------------------
	void use();
	// utility uniform functions
	// -----------------------------------------------------
	void setBool(const string &name, bool value) const;
	void setInt(const string &name, int value) const;
	void setFloat(const string &name, float value) const;

private:
	// utility function for checking shader compilation/linking errors.
	// ------------------------------------------------------------------------
	void checkCompileErrors(unsigned int shader, string type);
};
#endif

shader.cpp:

#include "shader.h"
#include <glad/glad.h>
#include <gl/GL.h>
#include <GLFW/glfw3.h>
#include <climits>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
using namespace std;
Shader::Shader(const char* vertexPath,const char* fragmentPath) {
	// 1. retrieve the vertex/fragment source code from filePath
	std::string vertexCode;
	std::string fragmentCode;
	std::ifstream vShaderFile;
	std::ifstream fShaderFile;
	// ensure ifstream objects can throw exceptions:
	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_SUCCESFULLY_READ" << std::endl;
	}
	const char* vShaderCode = vertexCode.c_str();
	const char * fShaderCode = fragmentCode.c_str();
	// 2. compile shaders
	unsigned int vertex, fragment;
	cout << UINT64_MAX << endl;
	cout << glUseProgram << endl;
	cout << glCreateShader << endl;
	// vertex shader
	vertex = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vertex, 1, &vShaderCode, NULL);
	glCompileShader(vertex);
	checkCompileErrors(vertex, "VERTEX");
	// fragment Shader
	fragment = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragment, 1, &fShaderCode, NULL);
	glCompileShader(fragment);
	checkCompileErrors(fragment, "FRAGMENT");
	// shader Program
	ID = glCreateProgram();
	glAttachShader(ID, vertex);
	glAttachShader(ID, fragment);
	glLinkProgram(ID);
	checkCompileErrors(ID, "PROGRAM");
	// delete the shaders as they're linked into our program now and no longer necessary
	glDeleteShader(vertex);
	glDeleteShader(fragment);
}
void Shader::use() {
	glUseProgram(ID);
}
void Shader::setBool(const string &name, bool value) const
{
	//glUniform
	glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
}
void Shader::setInt(const string &name, int value) const
{
	glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
}
void Shader::setFloat(const string &name, float value) const
{
	glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
}
void Shader::checkCompileErrors(unsigned int shader,string type)
{
	int success;
	char infoLog[1024];
	if (type != "PROGRAM")
	{
		glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
		if (!success)
		{
			glGetShaderInfoLog(shader, 1024, NULL, infoLog);
			std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
		}
	}
	else
	{
		glGetProgramiv(shader, GL_LINK_STATUS, &success);
		if (!success)
		{
			glGetProgramInfoLog(shader, 1024, NULL, infoLog);
			std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
		}
	}
}

猜你喜欢

转载自blog.csdn.net/lck8989/article/details/101221099