OpenGL implements triangle rotation

Recently, I was looking at graphics programming. It is a bit simple. The exercise is to realize a two-dimensional triangle rotation.

//main.cpp
//
#include<GL/glew.h>
#include<GLFW/glfw3.h>
#include<iostream>
#include<string>
#include"Utils.h"
#include<glm/gtx/string_cast.hpp>
#include<vector>
using namespace std;
using namespace glm;
#define numVAOs 1
GLuint renderingProgram;
GLuint vao[numVAOs];
float x = 0.0f;
float inc = 0.01f;
float scaleRatio = 1.0f;
float scaleRate = 0.05f;
vector<glm::vec4> vecTrianglesVertex;
GLfloat* vecrawTrianglesVertex;

GLuint createShaderProgram() {
    
    
	GLuint vShader = LoadShaderSource(GL_VERTEX_SHADER, "./shader/vshader.shader", 1);
	GLuint fShader = LoadShaderSource(GL_FRAGMENT_SHADER, "./shader/fshader.shader", 1);
	GLuint vfProgram = glCreateProgram();
	glAttachShader(vfProgram, vShader);
	glAttachShader(vfProgram, fShader);
	glLinkProgram(vfProgram);
	ProgramErrorCheck(vfProgram);
	return vfProgram;
}

void init(GLFWwindow* window) {
    
    
	renderingProgram = createShaderProgram();
	glGenVertexArrays(numVAOs, vao);
	glBindVertexArray(vao[0]);
}
void InitVertexData() {
    
    
	vecTrianglesVertex.emplace_back(vec4(0.0, 0.25, 0.0, 1.0));
	vecTrianglesVertex.emplace_back(vec4(0.25, 0.0, 0.0, 1.0));
	vecTrianglesVertex.emplace_back(vec4(-0.25, 0.0, 0.0, 1.0));
	vecrawTrianglesVertex = new GLfloat[3 * 4];
	for (int i = 0, vecIndex = 0; i < 12; ++i) {
    
    
		*(vecrawTrianglesVertex + i) = vecTrianglesVertex[i / 4][i % 4];
	}
}
void display(GLFWwindow* window, double currentTime) {
    
    
	using namespace glm;
	auto rotate = [](vector<glm::vec4>& vecTrianglesVertex, float rad) {
    
    
		for (auto v = vecTrianglesVertex.begin(); v != vecTrianglesVertex.end(); ++v) {
    
    
			*v = buildRotateMat(rad, RotateAxis::Z) * (*v);
		}
	};
	auto scale = [](vector<glm::vec4>& vecTrianglesVertex, float scaleX, float scaleY, float scaleZ) {
    
    
		for (auto v = vecTrianglesVertex.begin(); v != vecTrianglesVertex.end(); ++v) {
    
    
			*v = buildScaleMat(scaleX, scaleY, scaleZ) * (*v);
		}
	};
	glClear(GL_DEPTH_BUFFER_BIT);
	glClearColor(0.0, 0.0, 0.0, 1);
	glClear(GL_COLOR_BUFFER_BIT);
	glUseProgram(renderingProgram);
	
	
	//旋转
	rotate(vecTrianglesVertex, 0.1);
	
	for (int i = 0, vecIndex = 0; i < 12; ++i) {
    
    
		*(vecrawTrianglesVertex + i) = vecTrianglesVertex[i / 4][i%4];
	}
	GLuint vertexsLoc = glGetUniformLocation(renderingProgram, "vertexs");
	glProgramUniform4fv(renderingProgram,vertexsLoc,3, vecrawTrianglesVertex);
	glDrawArrays(GL_TRIANGLES, 0, 3);
}
int main() {
    
    
	
	if (!glfwInit())	exit(EXIT_FAILURE);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	GLFWwindow* windows = glfwCreateWindow(400, 400, "Chapter2", NULL, NULL);
	glfwMakeContextCurrent(windows);
	if (glewInit() != GLEW_OK)
		exit(EXIT_FAILURE);
	glfwSwapInterval(1);
	init(windows);
	InitVertexData();
	while (!glfwWindowShouldClose(windows)) {
    
    
		display(windows, glfwGetTime());
		glfwSwapBuffers(windows);
		glfwPollEvents();
	}
	glfwDestroyWindow(windows);
	glfwTerminate();
}

shader file

//fshader.shader
#version 430
out vec4 color;
void main(void){
    
    
	//if (gl_FragCoord.x < 200)
	//	color = vec4(1.0, 0.0, 0.0, 1.0);
	//else
		color = vec4(0.0, 0.0, 1.0, 1.0);
}
//vshader.shader
#version 430
//uniform float offset;
//uniform float scaleOffset;
uniform vec4 vertexs[3];
void main(void){
    
    
	if (gl_VertexID == 0)
		gl_Position = vertexs[0];
	else if(gl_VertexID == 1)
		gl_Position = vertexs[1];
	else if (gl_VertexID == 2)
		gl_Position = vertexs[2];
	}

Self-encapsulated tools

//Utils.h
//简单封装一些工具
#pragma once
#ifndef __TESTOPENGL__
#define __TESTOPENGL__
#include<GL/glew.h>
#include<GLFW/glfw3.h>
#include<string>
#include<iostream>
#include<fstream>
#include<assert.h>
#include<type_traits>
#include<glm/glm.hpp>
enum class RotateAxis {
    
    
	X = 0,
	Y = 1,
	Z = 2,
};

std::string ReadGLSL(std::string filePath);

void ProgramErrorCheck(GLint program);

GLuint LoadShaderSource(GLuint flag, std::string shaderSourcePath, GLsizei count);	//加载shader文件

glm::mat4 buildTranslateMat(float x, float y, float z);

glm::mat4 buildRotateMat(float rad, RotateAxis axis);

glm::mat4 buildScaleMat(float x, float y, float z);


#endif // !__AUXFUN__

//Utils.cpp

#include"Utils.h"

std::string ReadGLSL(std::string filePath) {
    
    
	std::ifstream fileStream(filePath.c_str());
	assert(fileStream);
	return std::string(std::istreambuf_iterator<char>(fileStream), std::istreambuf_iterator<char>());
}

void ProgramErrorCheck(GLint program) {
    
    
	GLint logLength = 0;
	glGetShaderiv(program, GL_INFO_LOG_LENGTH, &logLength);
	if (logLength <= 0)	return;
	std::string errorlog(logLength, '\0');
	glGetProgramInfoLog(program, logLength, nullptr, errorlog.data());
	std::cerr << errorlog << std::endl;
}

GLuint LoadShaderSource(GLuint flag, std::string shaderSourcePath, GLsizei count) {
    
    
	auto PrintErrorLog = [](GLuint shader, std::string fileName = "") {
    
    
		GLint logLength = 0;
		glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
		if (logLength <= 0)	return;
		std::string errorlog(logLength, '\0');
		glGetShaderInfoLog(shader, logLength, nullptr, errorlog.data());
		std::cerr << fileName << ": " << errorlog << std::endl;
	};
	std::string shaderSource = ReadGLSL(shaderSourcePath);
	const char* c_strShaderSource = shaderSource.c_str();
	GLuint shader = glCreateShader(flag);
	glShaderSource(shader, count, &c_strShaderSource, NULL);
	glCompileShader(shader);
	PrintErrorLog(shader, shaderSourcePath);
	return shader;
}

glm::mat4 buildTranslateMat(float x, float y, float z) {
    
    
	using namespace glm;
	return mat4(1.0, 0.0, 0.0, 0.0,
		0.0, 1.0, 0.0, 0.0,
		0.0, 0.0, 1.0, 0.0,
		x,   y,   z,   1.0
		);
}

glm::mat4 buildRotateMat(float rad, RotateAxis axis) {
    
    
	using namespace glm;
	constexpr auto f0 = 0.0;
	constexpr auto f1 = 1.0;
	if (axis == RotateAxis::X) {
    
    
		return mat4(f1, f0, f0, f0,
			f0, cos(rad), -sin(rad), f0,
			f0, sin(rad), cos(rad), f0,
			f0, f0, f0, f1
		);
	}
	else if (axis == RotateAxis::Y) {
    
    
		return mat4(cos(rad), f0,sin(rad), f0,
			f0, f1, f0, f0,
			-sin(rad), f0, cos(rad), f0,
			f0, f0, f0, f1
		);
	}
	else if (axis == RotateAxis::Z) {
    
    
		return mat4(
			cos(rad), -sin(rad), f0, f0,
			sin(rad), cos(rad), f0, f0,
			f0, f0, f1, f0,
			f0, f0, f0, f1
		);
	}
	else {
    
    
		assert(-1 && "undefine RotateAxis");
	}
}

glm::mat4 buildScaleMat(float x, float y, float z) {
    
    
	using namespace glm;
	constexpr auto f0 = 0.0;
	constexpr auto f1 = 1.0;
	return mat4(x, f0, f0, f0,
		f0, y, f0, f0,
		f0, f0, z, f0,
		f0, f0, f0, f1
	);
}


Guess you like

Origin blog.csdn.net/ninesnow_c/article/details/122945925