C++/OpenGL 入门(4):三角形移动动画

  1. 来源:《Computer Graphics Programming in OpenGL Using C++ 》by V Scott Gordon John L Clevenger
  2. 内容:程序2.6 Program 2.6: Simple Animation Example,书P29页,PDF48/403
  3. 生成三角形移动动画,如图
    请添加图片描述
    请添加图片描述
    请添加图片描述
  4. 文件1: 2.6 fragShader.glsl (可用记事本写,更改后缀名)
#version 430 
out vec4 color; 
void main(void) { 
	if (gl_FragCoord.x < 500)  // 这个是整个窗口的值,在对应cpp文件中设置窗口1000x400
								// 所以500 是窗口的正中间位置
		color = vec4(1.0, 0.0, 0.0, 1.0);
	else 
		color = vec4(0.0, 0.0, 1.0, 1.0);
		}
  1. 文件2: 2.6 verShader.glsl
#version 430 
uniform float offset; // 注意,offset 的值,是由 cpp文件中 x 来赋值的
void main(void) 
{ 
     if (gl_VertexID == 0) gl_Position = vec4( 0.25 + offset, -0.25, 0.0, 1.0);
	 else if (gl_VertexID == 1) gl_Position = vec4(-0.25 + offset, -0.25, 0.0, 1.0);
	 else gl_Position = vec4( 0.25 + offset, 0.25, 0.0, 1.0);
}
  1. 文件3: 220202 2.6 animation.cpp
#include "include/GL/glew.h"
#include "include/GLFW/glfw3.h"

#include <iostream>
#include <string>
#include <iostream>
#include <fstream>
using namespace std;



#define numVAOs 1
GLuint renderingProgram;
GLuint vao[numVAOs];

float x = 0.0f;		// x轴上三角形的位置
float inc = 0.01f;	// 三角形运动的偏移量

void printShaderLog(GLuint shader) {
	int len = 0;
	int chWrittn = 0;
	char *log;
	glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
	if (len > 0) {
		log = (char *)malloc(len);
		glGetShaderInfoLog(shader, len, &chWrittn, log);
		cout << "Shader Info Log: " << log << endl;
		free(log);
	}
}
void printProgramLog(int prog) {
	int len = 0;
	int chWrittn = 0;
	char *log;
	glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len);
	if (len > 0) {
		log = (char *)malloc(len);
		glGetProgramInfoLog(prog, len, &chWrittn, log);
		cout << "Program Info Log: " << log << endl;
		free(log);
	}
}
bool checkOpenGLError() {
	bool foundError = false;
	int glErr = glGetError();
	while (glErr != GL_NO_ERROR) {
		cout << "glError: " << glErr << endl;
		foundError = true;
		glErr = glGetError();
	}
	return foundError;
}

string readShaderSource(const char *filePath) {
	string content;
	ifstream fileStream(filePath, ios::in);
	string line = "";
	while (!fileStream.eof()) {
		getline(fileStream, line);
		content.append(line + "\n");
	}
	fileStream.close();
	return content;
}
GLuint createShaderProgram() {
	GLint vertCompiled;
	GLint fragCompiled;
	GLint linked;
	string vertShaderStr = readShaderSource("add/2.6 vertShader.glsl"); // 文件在add文件夹中
	string fragShaderStr = readShaderSource("add/2.6 fragShader.glsl");
	const char *vertShaderSrc = vertShaderStr.c_str();
	const char *fragShaderSrc = fragShaderStr.c_str();
	GLuint vShader = glCreateShader(GL_VERTEX_SHADER);
	GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(vShader, 1, &vertShaderSrc, NULL);
	glShaderSource(fShader, 1, &fragShaderSrc, NULL);
	// 在编译着色器时,捕捉错误
	glCompileShader(vShader);
	checkOpenGLError();
	glGetShaderiv(vShader, GL_COMPILE_STATUS, &vertCompiled);
	if (vertCompiled != 1) {
		cout << "vertex compilation failed" << endl;
		printShaderLog(vShader);
	}
	glCompileShader(fShader);
	checkOpenGLError();
	glGetShaderiv(fShader, GL_COMPILE_STATUS, &fragCompiled);
	if (fragCompiled != 1) {
		cout << "fragment compilation failed" << endl;
		printShaderLog(fShader);
	}
	GLuint vfProgram = glCreateProgram();
	glAttachShader(vfProgram, vShader);
	glAttachShader(vfProgram, fShader);
	glLinkProgram(vfProgram);
	checkOpenGLError();
	glGetProgramiv(vfProgram, GL_LINK_STATUS, &linked);
	if (linked != 1) {
		cout << "linking failed" << endl;
		printProgramLog(vfProgram);
	}

	return vfProgram;
}
void init(GLFWwindow* window) {
	renderingProgram = createShaderProgram();
	glGenVertexArrays(numVAOs, vao);
	glBindVertexArray(vao[0]);
}
void display(GLFWwindow* window, double currentTime) {
	glClear(GL_DEPTH_BUFFER_BIT);
	glClearColor(0.0, 0.0, 0.0, 1.0);
	glClear(GL_COLOR_BUFFER_BIT); // 每一次都将背景清理(clear)为黑色
	glUseProgram(renderingProgram);
	x += inc; // 在x轴上移动三角形
	if (x > 0.6f) inc = -0.01f; // 三角形改变移动方向,改变为向左移动
	if (x < -0.6f) inc = 0.01f; // 三角形改变为向右移动方向
	GLuint offsetLoc = glGetUniformLocation(renderingProgram, "offset"); // 设置一个指针ptr指向 offset
	glProgramUniform1f(renderingProgram, offsetLoc, x); // 将x的值赋值给offset
	glDrawArrays(GL_TRIANGLES, 0, 3);
}

int main(void) {
	if (!glfwInit()) { exit(EXIT_FAILURE); }
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	GLFWwindow* window = glfwCreateWindow(1000, 400, "Chapter2-program2", NULL, NULL);
	glfwMakeContextCurrent(window);
	if (glewInit() != GLEW_OK) { exit(EXIT_FAILURE); }
	glfwSwapInterval(1);
	init(window);
	while (!glfwWindowShouldClose(window)) {
		display(window, glfwGetTime());
		glfwSwapBuffers(window);
		glfwPollEvents();
	}
	glfwDestroyWindow(window);
	glfwTerminate();
	exit(EXIT_SUCCESS);
}


  1. 补充
    main() : 函数需要重构来支持动画 animation,调用一次 init(), 然后重复调用 display()
     frame 帧:场景每一次渲染,就叫做帧
     frame rate 帧率: 调用 display() 的频率
     x :
     在 display 函数中,采用 x 来表示 X 坐标的偏移量,
     每次调用 display 函数,x 的值就会不一样,当x = 1.0或者-1.0,就会反向移动。
     X 的 值,赋值给 点着色器 (vertex shader)的 offset 变量
     X 的值赋值给 offset 变量,称为 uniform variable 统一变量
    glGetUniformLocation(): 给 offset 变量一个指针
    glProgramUniform1f() : 然后再调用该函数复制x的值到 offset
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值