首页 > 其他分享 >深圳大学-计算机图形学-实验一OpenGL基本绘制

深圳大学-计算机图形学-实验一OpenGL基本绘制

时间:2025-01-14 22:00:14浏览次数:3  
标签:glm OpenGL 图形学 colors NUM vec2 深圳大学 GL POINTS

实验目的与要求

  1. 掌握Visual Studio Community 2019集成开发环境的安装;掌握CMake跨平台构建工具的安装;掌握Git版本控制工具的安装;掌握vcpkg库管理工具的安装;掌握系统环境变量的设置;了解和掌握OpenGL的环境配置;掌握OpenGL工程项目的建立和基本设置。
  2. 理解OpenGL的原理;了解和熟悉OpenGL着色语言;掌握基于OpenGL的C++程序结构;掌握OpenGL中若干基本二维图形的绘制;了解顶点着色器的使用;了解片元着色器的使用。
  3. 使用现代OpenGL中的着色器,绘制多个简单的二维图形,形状内容不限,自己发挥。

实验过程及内容

一.配置环境

1.安装VS(实验前已安装)
2.安装cmake
3.安装git(实验前已安装)
4.使用git从github上安装vcpkg
a) 运行目录下的bootstrap引导脚本,执行 .\bootstrap-vcpkg.bat,构建vcpkg。
b) 执行.\vcpkg integrate install命令,将vcpkg聚合到visual stuido
c) 测试vcpkg是否安装成功,打开cmd,键入vcpkg,出现以下提示,说明vcpkg已配置成功
在这里插入图片描述
5.设置系统环境变量
在这里插入图片描述
在这里插入图片描述
6.安装OpenGL库: GLFW,GLAD,GLM
在命令行中输入命令 vcpkg install glfw3 glad glm,等待安装完成即可
7. 以上环境配置安装完成之后,打开实验1.1_参考代码
a) 点击”main”项目,将其设置为启动项。
在这里插入图片描述
在这里插入图片描述
b) 点击“本地Windows调试器”编译运行程序
在这里插入图片描述
c) 屏幕上成功出现一个红色三角形,说明环境配置成功。
在这里插入图片描述

二.OpenGL与着色器编程

1.执行实验1.2留空代码之后,得到下图结果
在这里插入图片描述
2. 修改给定代码中生成三角形的函数,实现三角形的效果
原代码:
在这里插入图片描述
修改后:
在这里插入图片描述
运行代码:
在这里插入图片描述
3. 修改给定代码中生成正方形的函数,实现正方形的效果
a) 观察要实现的效果发现需要绘制6个正方形,且黑白相间
在这里插入图片描述
故思路为: 利用for循环,生成几个嵌套的正方形,每次绘制完正方形后,正方形的大小变小,然后更改绘制颜色。
b) 修改代码,运行代码
原代码:
在这里插入图片描述
修改后的代码:
在这里插入图片描述
运行代码:
在这里插入图片描述
运行结果与预期结果一致,完成本部分实验。

三.绘制圆和椭圆

1.观察以下代码
在这里插入图片描述
发现当参数verticalScale的值为1时,图形将填充为渐变的红色。即当verticalScale不为1时为红色椭圆。
2. 修改VAO数目,增加椭圆和圆,故数目由3改为5
在这里插入图片描述
3. 定义椭圆和圆形上的点和颜色
在这里插入图片描述
4. 生成椭圆和圆形上的点和颜色
在这里插入图片描述
5. 初始化椭圆的数据
在这里插入图片描述
6. 初始化圆的数据
在这里插入图片描述
7. 绘制椭圆和圆
在这里插入图片描述
8. 运行代码,效果如下,与实验要求一致,顺利完成实验。
在这里插入图片描述

四.设计自己的几何图形

1.图形构思
构思图形这块想了很久都没想到要绘制什么图案,最后拿出平板,打开笔记软件,绘制出了一个还算像样的图案。构思图案如下:
在这里插入图片描述
最终图案与构思版有所区别,但大致形状基本一致,我把作品取名为《几何之脸》,因为图案由简单的图形组成,且有脸型,故以之命名。
2. 绘制思路
图案由正方形,圆形,椭圆形,三角形组成,定义之后按照一定顺序绘制即可了,然后再考虑颜色问题,中间在绘制的过程中踩雷了,因为一些先绘制的图案把原来的图案遮住了,所以绘制顺序很重要。
3. 绘制脸庞
在这里插入图片描述
4. 绘制耳朵,嘴巴
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
三角形不同颜色的特判操作:
在这里插入图片描述
5. 绘制眼睛,眼珠
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
眼睛和眼珠的大小不同:
在这里插入图片描述
眼睛和眼珠的颜色不同:
在这里插入图片描述
6. 绘制鼻子,头发
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
头发为红色过渡到白色,鼻子为变化色(根据角度生成颜色)
在这里插入图片描述
在这里插入图片描述
7. 绘制顺序如下
在这里插入图片描述
8. 最终作品
在这里插入图片描述

实验结论

  1. a) 在实验1.1中,我完成了OpenGL环境的配置,成功编译并运行了程序,在屏幕上成功地运行出一个红色的三角形
    b) 在实验1.2中, 我补全了代码,调整了三角形的角度,生成了多个嵌套,颜色黑白相间的正方形。
    c) 在本次实验中,我补充了绘制椭圆和圆的代码,同时还设计了一个自定义的几何形状图片。
  2. 本次实验踩了几个坑,一是配置环境时,vcpkg版本的问题,最后通过直接在github上下载解决;二是在绘制不同图形时,需要确保正确的绘制顺序,否则一些图形会被其他图形遮住。
  3. 通过这次实验,我了解了OpenGL的基本概念和工作原理,包括顶点着色器和片段着色器的使用,学会了OpenGL中绘制简单图形的方法和技巧。

实验代码

实验1.2

#include "Angel.h"
#include <string>

const glm::vec3 WHITE(1.0, 1.0, 1.0);
const glm::vec3 BLACK(0.0, 0.0, 0.0);
const glm::vec3 RED(1.0, 0.0, 0.0);
const glm::vec3 GREEN(0.0, 1.0, 0.0);
const glm::vec3 BLUE(0.0, 0.0, 1.0);

const int TRIANGLE_NUM_POINTS = 3;
const int SQUARE_NUM = 6;
const int SQUARE_NUM_POINTS = 4 * SQUARE_NUM; // 获得三角形的每个角度

double getTriangleAngle(int point) {
	return 2 * M_PI / 3 * point;
}

// 获得正方形的每个角度
double getSquareAngle(int point) {
	return M_PI / 4 + (M_PI / 2 * point);
}

// 生成三角形上的每个点
void generateTrianglePoints(glm::vec2 vertices[], glm::vec3 colors[], int startVertexIndex)
{
	// 三角形尺寸
	glm::vec2 scale(0.25, 0.25);
	// 三角形中心位置
	glm::vec2 center(0.0, 0.70);

	for (int i = 0; i < 3; i++) {
		// 当前顶点对应的角度
		double currentAngle = getTriangleAngle(i) + M_PI / 2;
		// 根据角度及三角形中心计算顶点坐标
		vertices[startVertexIndex + i] = glm::vec2(cos(currentAngle), sin(currentAngle)) * scale + center;
	}

	// 确定三个顶点的颜色
	colors[startVertexIndex] = RED;
	colors[startVertexIndex + 1] = BLUE;
	colors[startVertexIndex + 2] = GREEN;
}

// 生成正方形上的每个点
void generateSquarePoints(glm::vec2 vertices[], glm::vec3 colors[], int squareNum, int startVertexIndex)
{
	// 最大正方形尺寸
	glm::vec2 scale(0.90, 0.90);
	// 正方形中心位置
	glm::vec2 center(0.0, -0.25);

	glm::vec3 currentColor = WHITE;
	int vertexIndex = startVertexIndex;

	// 根据正方形及顶点对应角度,计算当前正方形四个顶点坐标
	for(int i = 0; i < SQUARE_NUM; i++){
		for (int j = 0; j < 4; j++){
			double currentAngle = getSquareAngle(j);
			vertices[vertexIndex] = glm::vec2(cos(currentAngle), sin(currentAngle)) * scale + center;
			colors[vertexIndex] = currentColor;
			vertexIndex++;
		}
		scale -= (0.15, 0.15);
		if(i % 2){
			currentColor = WHITE;
		}else{
			currentColor = BLACK;
		}
	}

}

// 全局变量,两个vao,一个绘制三角形,一个绘制正方形
GLuint vao[2], program;
void init()
{

	// 定义三角形的三个点
	glm::vec2 triangle_vertices[TRIANGLE_NUM_POINTS];
	glm::vec3 triangle_colors[TRIANGLE_NUM_POINTS];
	// 定义矩形的点
	glm::vec2 square_vertices[SQUARE_NUM_POINTS];
	glm::vec3 square_colors[SQUARE_NUM_POINTS];

	// 调用生成形状顶点位置的函数
	generateTrianglePoints(triangle_vertices, triangle_colors, 0);
	generateSquarePoints(square_vertices, square_colors, SQUARE_NUM, 0);


	// 读取着色器并使用
	std::string vshader, fshader;
	vshader = "shaders/vshader.glsl";
	fshader = "shaders/fshader.glsl";
	program = InitShader(vshader.c_str(), fshader.c_str());
	glUseProgram(program);

	/*
	* 初始化三角形的数据
	*/
	// 创建顶点数组对象
	glGenVertexArrays(1, &vao[0]);		// 分配1个顶点数组对象
	glBindVertexArray(vao[0]);			// 绑定顶点数组对象

// 创建顶点缓存对象,vbo[2]是因为我们将要使用两个缓存对象,
// 一个是顶点坐标,一个是顶点颜色
	GLuint vbo[2];

	// 分配1个顶点缓存对象
	glGenBuffers(1, &vbo[0]);
	// 绑定顶点缓存对象
	glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
	// 分配数据所需的存储空间,将数据拷贝到OpenGL服务端内存
	glBufferData(GL_ARRAY_BUFFER, sizeof(triangle_vertices), triangle_vertices, GL_STATIC_DRAW);
	// 从顶点着色器中初始化顶点的位置
	GLuint location = glGetAttribLocation(program, "vPosition");
	// 启用顶点属性数组
	glEnableVertexAttribArray(location);
	// 关联到顶点属性数组 (index, size, type, normalized, stride, *pointer)
	glVertexAttribPointer(
		location,
		2,
		GL_FLOAT,
		GL_FALSE,
		sizeof(glm::vec2),
		BUFFER_OFFSET(0));

	// 给颜色
	glGenBuffers(1, &vbo[1]);
	glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(triangle_colors), triangle_colors, GL_STATIC_DRAW);
	GLuint cLocation = glGetAttribLocation(program, "vColor");
	glEnableVertexAttribArray(cLocation);
	glVertexAttribPointer(
		cLocation,
		3,
		GL_FLOAT,
		GL_FALSE,
		sizeof(glm::vec3),
		BUFFER_OFFSET(0));

	/*
	* 初始化正方形的数据
	*/
	// 创建顶点数组对象
	glGenVertexArrays(1, &vao[1]);      // 分配1个顶点数组对象
	glBindVertexArray(vao[1]);          // 绑定顶点数组对象
 // 创建顶点缓存对象,我们可以重复使用我们声明的vbo变量
// 正方形顶点坐标
	glGenBuffers(1, &vbo[0]);
	glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(square_vertices), square_vertices, GL_STATIC_DRAW);
	// 从顶点着色器中初始化顶点的位置
	location = glGetAttribLocation(program, "vPosition");
	glEnableVertexAttribArray(location);
	glVertexAttribPointer(
		location,
		2,
		GL_FLOAT,
		GL_FALSE,
		sizeof(glm::vec2),
		BUFFER_OFFSET(0));
	// 正方形颜色
	glGenBuffers(1, &vbo[1]);
	glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(square_colors), square_colors, GL_STATIC_DRAW);
	cLocation = glGetAttribLocation(program, "vColor");
	glEnableVertexAttribArray(cLocation);
	glVertexAttribPointer(
		cLocation,
		3,
		GL_FLOAT,
		GL_FALSE,
		sizeof(glm::vec3),
		BUFFER_OFFSET(0));


	// 黑色背景
	glClearColor(0.0, 0.0, 0.0, 1.0);
}

void display(void)
{
	// 清理窗口
	glClear(GL_COLOR_BUFFER_BIT);

	// 激活着色器
	glUseProgram(program);
	// 绑定三角形的顶点数组对象
	glBindVertexArray(vao[0]);
	glDrawArrays(GL_TRIANGLES, 0, TRIANGLE_NUM_POINTS);
	// 绑定正方形的顶点数组对象
	glBindVertexArray(vao[1]);

	// 注意这里使用的绘制模式为GL_TRIANGLE_FAN
	// 它会以顶点数据的一个点为中心顶点,绘制三角形

	// 绘制多个正方形
	for (int i = 0; i < SQUARE_NUM; ++i) {
		glDrawArrays(GL_TRIANGLE_FAN, (i * 4), 4);
	}
	// 强制所有进行中的OpenGL命令完成
	glFlush();
}

void framebuffer_size_callback(GLFWwindow* window, int width, int height);

int main(int argc, char** argv)
{
	// 初始化GLFW库,必须是应用程序调用的第一个GLFW函数
	glfwInit();

	// 配置GLFW
	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);
#endif

	// 配置窗口属性
	GLFWwindow* window = glfwCreateWindow(512, 512, "Red Triangle", NULL, NULL);
	if (window == NULL)
	{
		std::cout << "Failed to create GLFW window" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);
	glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

	// 调用任何OpenGL的函数之前初始化GLAD
	// ---------------------------------------
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
	{
		std::cout << "Failed to initialize GLAD" << std::endl;
		return -1;
	}

	init();
	// 指定当前窗口进行重绘时要调用的函数
	while (!glfwWindowShouldClose(window))
	{
		display();

		// 交换颜色缓冲 以及 检查有没有触发什么事件(比如键盘输入、鼠标移动等)
		// -------------------------------------------------------------------------------
		glfwSwapBuffers(window);
		glfwPollEvents();
	}
	return 0;
}

// 每当窗口改变大小,GLFW会调用这个函数并填充相应的参数供你处理。
// ---------------------------------------------------------------------------------------------
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.
	glViewport(0, 0, width, height);
}

补充圆和椭圆

#include "Angel.h"
#include <string>

const glm::vec3 WHITE(1.0, 1.0, 1.0);
const glm::vec3 BLACK(0.0, 0.0, 0.0);
const glm::vec3 RED(1.0, 0.0, 0.0);
const glm::vec3 GREEN(0.0, 1.0, 0.0);
const glm::vec3 BLUE(0.0, 0.0, 1.0); 
const int CIRCLE_NUM_POINTS = 100;
const int ELLIPSE_NUM_POINTS = 100;
const int TRIANGLE_NUM_POINTS  = 3;
const int SQUARE_NUM  = 6;
const int SQUARE_NUM_POINTS  = 4 * SQUARE_NUM;
const int LINE_NUM_POINTS = 2;

// 每当窗口改变大小,GLFW会调用这个函数并填充相应的参数
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
	glViewport(0, 0, width, height);
}

// 根据角度生成颜色
float generateAngleColor(double angle)
{
	return 1.0 / (2 * M_PI) * angle;
}

// 获得三角形的每个角度
double getTriangleAngle(int point)
{
	return 2 * M_PI / 3 * point;
}

// 获得正方形的每个角度
double getSquareAngle(int point)
{
	return M_PI / 4 + (M_PI / 2 * point);
}

// 计算椭圆/圆上的点
glm::vec2 getEllipseVertex(glm::vec2 center, double scale, double verticalScale, double angle)
{
	glm::vec2 vertex(sin(angle), cos(angle));
	vertex *= scale;
	vertex.y *= verticalScale;
	vertex += center;
	return vertex;
}

// 获得三角形的每个顶点
void generateTrianglePoints(glm::vec2 vertices[], glm::vec3 colors[], int startVertexIndex)
{
	glm::vec2 scale(0.25, 0.25);
	glm::vec2 center(0.0, 0.70);

	for (int i = 0; i < 3; ++i) {
		double currentAngle = getTriangleAngle(i);
		vertices[startVertexIndex + i] = glm::vec2(sin(currentAngle), cos(currentAngle)) * scale + center;
	}

	colors[startVertexIndex] = RED;
	colors[startVertexIndex + 1] = GREEN;
	colors[startVertexIndex + 2] = BLUE;
}

// 获得正方形的每个顶点
void generateSquarePoints(glm::vec2 vertices[], glm::vec3 colors[], int squareNumber, int startVertexIndex)
{
	glm::vec2 scale(0.90, 0.90);
	double scaleDecrease = 0.15;
	glm::vec2 center(0.0, -0.25);
	int vertexIndex = startVertexIndex;

	for (int i = 0; i < squareNumber; ++i) {
		glm::vec3 currentColor;
		currentColor = (i % 2) ? BLACK : WHITE;
		for (int j = 0; j < 4; ++j) {
			double currentAngle = getSquareAngle(j);
			vertices[vertexIndex] = glm::vec2(sin(currentAngle), cos(currentAngle)) * scale + center;
			colors[vertexIndex] = currentColor;
			vertexIndex++;
		}
		scale -= scaleDecrease;
	}
}

// 获得线的顶点
void generateLinePoints(glm::vec2 vertices[], glm::vec3 colors[], int startVertexIndex)
{
	vertices[startVertexIndex] = glm::vec2(-1.0, -1.0);
	vertices[startVertexIndex + 1] = glm::vec2(1.0, 1.0);


	colors[startVertexIndex] = WHITE;
	colors[startVertexIndex + 1] = BLUE;
}

// 获得椭圆/圆的每个顶点
void generateEllipsePoints(glm::vec2 vertices[], glm::vec3 colors[], int startVertexIndex, int numPoints,
	glm::vec2 center, double scale, double verticalScale)
{
	double angleIncrement = (2 * M_PI) / numPoints;
	double currentAngle = M_PI / 2;

	for (int i = startVertexIndex; i < startVertexIndex + numPoints; ++i) {
		vertices[i] = getEllipseVertex(center, scale, verticalScale, currentAngle);
		if (verticalScale == 1.0) {
			colors[i] = glm::vec3(generateAngleColor(currentAngle), 0.0, 0.0);
		}
		else {
			colors[i] = RED;
		}
		currentAngle += angleIncrement;
	}
}
// 将3改为5,因为多了椭圆和圆
// GLuint vao[3], program;
GLuint vao[5], program;

void init()
{

	// 定义三角形的点
	glm::vec2 triangle_vertices[TRIANGLE_NUM_POINTS];
	glm::vec3 triangle_colors[TRIANGLE_NUM_POINTS];
	// 定义矩形的点
	glm::vec2 square_vertices[SQUARE_NUM_POINTS];
	glm::vec3 square_colors[SQUARE_NUM_POINTS];
	// 定义线的点
	glm::vec2 line_vertices[LINE_NUM_POINTS];
	glm::vec3 line_colors[LINE_NUM_POINTS];
	
	// 定义椭圆的点
	glm::vec2 ellipse_vertices[ELLIPSE_NUM_POINTS];
	glm::vec3 ellipse_colors[ELLIPSE_NUM_POINTS];
	// 定义圆的点
	glm::vec2 circle_vertices[CIRCLE_NUM_POINTS];
	glm::vec3 circle_colors[CIRCLE_NUM_POINTS];

	// @TODO: 生成圆形和椭圆上的点和颜色
	// 调用生成形状顶点位置的函数
	generateTrianglePoints(triangle_vertices, triangle_colors, 0);
	generateSquarePoints(square_vertices, square_colors, SQUARE_NUM, 0);
	generateLinePoints(line_vertices, line_colors, 0);
	generateEllipsePoints(ellipse_vertices, ellipse_colors, 0, ELLIPSE_NUM_POINTS,glm::vec2(-0.6, 0.7), 0.25, 0.5);
	generateEllipsePoints(circle_vertices, circle_colors, 0, CIRCLE_NUM_POINTS, glm::vec2(0.6, 0.7), 0.2, 1);

	// 读取着色器并使用
	std::string vshader, fshader;
	vshader = "shaders/vshader.glsl";
	fshader = "shaders/fshader.glsl";
	program = InitShader(vshader.c_str(), fshader.c_str());
	glUseProgram(program);

	// 创建顶点缓存对象,vbo[2]是因为我们将要使用两个缓存对象
	GLuint vbo[2];


	/*
	* 初始化三角形的数据
	*/

	glGenVertexArrays(1, &vao[0]);		
	glBindVertexArray(vao[0]);			

	glGenBuffers(1, &vbo[0]);
	glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(triangle_vertices), triangle_vertices, GL_STATIC_DRAW);
	GLuint location  = glGetAttribLocation(program, "vPosition");
	glEnableVertexAttribArray(location);
	glVertexAttribPointer(
		location,
		2,
		GL_FLOAT,
		GL_FALSE,
		sizeof(glm::vec2),
		BUFFER_OFFSET(0));

	glGenBuffers(1, &vbo[1]);
	glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(triangle_colors), triangle_colors, GL_STATIC_DRAW);
	GLuint cLocation  = glGetAttribLocation(program, "vColor");
	glEnableVertexAttribArray(cLocation);
	glVertexAttribPointer(
		cLocation,
		3,
		GL_FLOAT,
		GL_FALSE,
		sizeof(glm::vec3),
		BUFFER_OFFSET(0));

	/*
	* 初始化正方形的数据
	*/  

	glGenVertexArrays(1, &vao[1]);      
	glBindVertexArray(vao[1]);         

	glGenBuffers(1, &vbo[0]);
	glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(square_vertices), square_vertices, GL_STATIC_DRAW);
	location  = glGetAttribLocation(program, "vPosition");
	glEnableVertexAttribArray(location);
	glVertexAttribPointer(
		location,
		2,
		GL_FLOAT,
		GL_FALSE,
		sizeof(glm::vec2),
		BUFFER_OFFSET(0));

	glGenBuffers(1, &vbo[1]);
	glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(square_colors), square_colors, GL_STATIC_DRAW);
	cLocation  = glGetAttribLocation(program, "vColor");
	glEnableVertexAttribArray(cLocation);
	glVertexAttribPointer(
		cLocation,
		3,
		GL_FLOAT,
		GL_FALSE,
		sizeof(glm::vec3),
		BUFFER_OFFSET(0));

	/*
	* 初始化线的数据
	*/

	glGenVertexArrays(1, &vao[2]);
	glBindVertexArray(vao[2]);

	glGenBuffers(1, &vbo[0]);
	glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(line_vertices), line_vertices, GL_STATIC_DRAW);
	location = glGetAttribLocation(program, "vPosition");
	glEnableVertexAttribArray(location);
	glVertexAttribPointer(
		location,
		2,
		GL_FLOAT,
		GL_FALSE,
		sizeof(glm::vec2),
		BUFFER_OFFSET(0));

	glGenBuffers(1, &vbo[1]);
	glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(line_colors), line_colors, GL_STATIC_DRAW);
	cLocation = glGetAttribLocation(program, "vColor");
	glEnableVertexAttribArray(cLocation);
	glVertexAttribPointer(
		cLocation,
		3,
		GL_FLOAT,
		GL_FALSE,
		sizeof(glm::vec3),
		BUFFER_OFFSET(0));


	// 初始化椭圆
	glGenVertexArrays(1, &vao[3]);
	glBindVertexArray(vao[3]);

	glGenBuffers(1, &vbo[0]);
	glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(ellipse_vertices), ellipse_vertices, GL_STATIC_DRAW);
	location = glGetAttribLocation(program, "vPosition");
	glEnableVertexAttribArray(location);
	glVertexAttribPointer(
		location,
		2,
		GL_FLOAT,
		GL_FALSE,
		sizeof(glm::vec2),
		BUFFER_OFFSET(0));

	glGenBuffers(1, &vbo[1]);
	glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(ellipse_colors), ellipse_colors, GL_STATIC_DRAW);
	cLocation = glGetAttribLocation(program, "vColor");
	glEnableVertexAttribArray(cLocation);
	glVertexAttribPointer(
		cLocation,
		3,
		GL_FLOAT,
		GL_FALSE,
		sizeof(glm::vec3),
		BUFFER_OFFSET(0));

	//初始化圆
	glGenVertexArrays(1, &vao[4]);
	glBindVertexArray(vao[4]);

	glGenBuffers(1, &vbo[0]);
	glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(circle_vertices), circle_vertices, GL_STATIC_DRAW);
	location = glGetAttribLocation(program, "vPosition");
	glEnableVertexAttribArray(location);
	glVertexAttribPointer(
		location,
		2,
		GL_FLOAT,
		GL_FALSE,
		sizeof(glm::vec2),
		BUFFER_OFFSET(0));

	glGenBuffers(1, &vbo[1]);
	glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(circle_colors), circle_colors, GL_STATIC_DRAW);
	cLocation = glGetAttribLocation(program, "vColor");
	glEnableVertexAttribArray(cLocation);
	glVertexAttribPointer(
		cLocation,
		3,
		GL_FLOAT,
		GL_FALSE,
		sizeof(glm::vec3),
		BUFFER_OFFSET(0));


	glClearColor(0.0, 0.0, 0.0, 1.0);
}

void display(void)
{

	glClear(GL_COLOR_BUFFER_BIT);

	glUseProgram(program);

	glBindVertexArray(vao[0]);
	glDrawArrays(GL_TRIANGLES, 0, TRIANGLE_NUM_POINTS);
	
	glBindVertexArray(vao[1]);
	for (int i = 0; i  < SQUARE_NUM; ++i) {
		glDrawArrays(GL_TRIANGLE_FAN, (i  * 4), 4);
	}

	glBindVertexArray(vao[2]);
	glDrawArrays(GL_LINES, 0, LINE_NUM_POINTS);

	// @TODO: 绘制圆
	glBindVertexArray(vao[4]);
	glDrawArrays(GL_TRIANGLE_FAN, 0, CIRCLE_NUM_POINTS);
	// @TODO: 绘制椭圆
	glBindVertexArray(vao[3]);
	glDrawArrays(GL_TRIANGLE_FAN, 0, ELLIPSE_NUM_POINTS);

	glFlush();
}

int main(int argc, char **argv)
{
	// 初始化GLFW库
	glfwInit();

	// 配置GLFW
	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);
	#endif

	// 配置窗口属性
	GLFWwindow* window = glfwCreateWindow(512, 512, "学号_姓名_实验一", NULL, NULL);
	if (window == NULL)
	{
		std::cout << "Failed to create GLFW window" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);
	glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

	// 调用任何OpenGL的函数之前初始化GLAD
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
	{
		std::cout << "Failed to initialize GLAD" << std::endl;
		return -1;
	}

	init();

	std::cout << "OpenGL Vendor: " << glGetString(GL_VENDOR) << std::endl;
	std::cout << "OpenGL Renderer: " << glGetString(GL_RENDERER) << std::endl;
	std::cout << "OpenGL Version: " << glGetString(GL_VERSION) << std::endl;
	std::cout << "Supported GLSL version is: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;
	
	
	while (!glfwWindowShouldClose(window))
	{	
		display();
		// 交换颜色缓冲 以及 检查有没有触发什么事件(比如键盘输入、鼠标移动等)
		glfwSwapBuffers(window);
		glfwPollEvents();
	}
	return 0;
}

设计图形

#include <string>
#include "Angel.h"

const glm::vec3 WHITE(1.0, 1.0, 1.0);
const glm::vec3 BLACK(0.0, 0.0, 0.0);
const glm::vec3 RED(1.0, 0.0, 0.0);
const glm::vec3 GREEN(0.0, 1.0, 0.0);
const glm::vec3 BLUE(0.0, 0.0, 1.0);
const glm::vec3 OTHER_BLUE(0.0, 0.749, 1.0);
const int CIRCLE_NUM_POINTS = 100;
const int ELLIPSE_NUM_POINTS = 100;
const int TRIANGLE_NUM_POINTS = 3;
const int SQUARE_NUM = 6;
const int SQUARE_NUM_POINTS = 4 * SQUARE_NUM;

// 颜色插值函数
glm::vec3 interpolateColors(glm::vec3 color1, glm::vec3 color2, double t) {
    return glm::mix(color1, color2, t);
}
// 每当窗口改变大小,GLFW会调用这个函数并填充相应的参数
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
    glViewport(0, 0, width, height);
}

// 根据角度生成颜色
float generateAngleColor(double angle) {
    return 1.0 / (2 * M_PI) * angle;
}

// 获得三角形的每个角度
double getTriangleAngle(int point) {
    return 2 * M_PI / 3 * point;
}

// 获得正方形的每个角度
double getSquareAngle(int point) {
    return M_PI / 4 + (M_PI / 2 * point);
}

// 计算椭圆/圆上的点
glm::vec2 getEllipseVertex(glm::vec2 center, double scale, double verticalScale, double angle) {
    glm::vec2 vertex(sin(angle), cos(angle));
    vertex *= scale;
    vertex.y *= verticalScale;
    vertex += center;
    return vertex;
}

// 获得椭圆/圆的每个顶点
void generateEllipsePoints(glm::vec2 vertices[], glm::vec3 colors[], int startVertexIndex, int numPoints, glm::vec2 center, double scale, double verticalScale) {
    double angleIncrement = (2 * M_PI) / numPoints;
    double currentAngle = M_PI / 2;

    for (int i = startVertexIndex; i < startVertexIndex + numPoints; ++i) {
        vertices[i] = getEllipseVertex(center, scale, verticalScale, currentAngle);
        if (verticalScale == 1.0) {
            if (startVertexIndex == 2 * CIRCLE_NUM_POINTS || startVertexIndex == 3 * CIRCLE_NUM_POINTS) {
                // 眼珠为黑色
                colors[i] = BLACK;
            }
            else {
                // 眼睛采用了渐变色
                double t = static_cast<double>(i - startVertexIndex) / numPoints;
                colors[i] = interpolateColors(WHITE, OTHER_BLUE, t);
            }
        }
        else {
            if (startVertexIndex == 0) {
                // 鼻子,变化色
                colors[i] = glm::vec3(generateAngleColor(currentAngle), generateAngleColor(currentAngle), 1.0);
            }
            else {
                // 头发,红色逐渐过渡到白色
                double t = static_cast<double>(i - startVertexIndex) / numPoints;
                colors[i] = interpolateColors(RED, WHITE, t);
            }
        }
        currentAngle += angleIncrement;
    }
}

// 获得三角形的每个顶点
void generateTrianglePoints(glm::vec2 scale,
    glm::vec2 center,
    glm::vec2 vertices[],
    glm::vec3 colors[],
    int startVertexIndex,
    double change_angle) {
    for (int i = 0; i < 3; ++i) {
        double currentAngle = getTriangleAngle(i) + change_angle;
        vertices[startVertexIndex + i] = glm::vec2(sin(currentAngle), cos(currentAngle)) * scale + center;
    }
    if (startVertexIndex == 3 * TRIANGLE_NUM_POINTS) {
        // 嘴巴里面的
        colors[startVertexIndex] = WHITE;
        colors[startVertexIndex + 1] = WHITE;
        colors[startVertexIndex + 2] = WHITE;
    }
    else {
        // 其他均为红色
        colors[startVertexIndex] = RED; 
        colors[startVertexIndex + 1] = RED;
        colors[startVertexIndex + 2] = RED;
    }

}

// 获得正方形的每个顶点
void generateSquarePoints(glm::vec2 vertices[], glm::vec3 colors[], int squareNumber, int startVertexIndex) {
    glm::vec2 scale(0.6, 0.6);
    glm::vec2 center(0.0, 0.0);
    int vertexIndex = startVertexIndex;

    for (int i = 0; i < squareNumber; ++i) {
        glm::vec3 currentColor;
        for (int j = 0; j < 4; ++j) {
            double currentAngle = getSquareAngle(j);
            currentColor = WHITE;  
            vertices[vertexIndex] =
                glm::vec2(sin(currentAngle), cos(currentAngle)) * scale +
                center;
            colors[vertexIndex] = currentColor;
            vertexIndex++;
        }
    }
}

GLuint vao[5], program; 
void init() {
    // 定义三角形的点
    glm::vec2 triangle_vertices[4 * TRIANGLE_NUM_POINTS];
    glm::vec3 triangle_colors[4 * TRIANGLE_NUM_POINTS]; 
    // 定义正方形的点
    glm::vec2 square_vertices[SQUARE_NUM_POINTS];
    glm::vec3 square_colors[SQUARE_NUM_POINTS];
    // 定义椭圆的点
    glm::vec2 elipse_vertices[3 * ELLIPSE_NUM_POINTS];
    glm::vec3 elipse_colors[3 * ELLIPSE_NUM_POINTS];
    // 定义圆的点
    glm::vec2 circle_vertices[4 * CIRCLE_NUM_POINTS];
    glm::vec3 circle_colors[4 * CIRCLE_NUM_POINTS];


    // 正方形(整个脸庞)
    generateSquarePoints(square_vertices, square_colors, 1, 0);

    // 椭圆(鼻子)
    glm::vec2 elipse_center1(0.0, 0.0);
    generateEllipsePoints(elipse_vertices, elipse_colors, 0, ELLIPSE_NUM_POINTS,
        elipse_center1, 0.05, 1.4);
    // 椭圆(头发),两个
    glm::vec2 elipse_center2(0.18, 0.42);
    generateEllipsePoints(elipse_vertices, elipse_colors, ELLIPSE_NUM_POINTS, ELLIPSE_NUM_POINTS,
        elipse_center2, 0.13, 0.25);  
    glm::vec2 elipse_center3(-0.18, 0.42);
    generateEllipsePoints(elipse_vertices, elipse_colors, 2 * ELLIPSE_NUM_POINTS, ELLIPSE_NUM_POINTS,
        elipse_center3, 0.13, 0.25);

    // 圆(眼睛)
    glm::vec2 circle_center1(-0.15, 0.15);
    generateEllipsePoints(circle_vertices, circle_colors, 0, CIRCLE_NUM_POINTS, circle_center1, 0.08, 1.0);
    glm::vec2 circle_center2(0.15, 0.15);
    generateEllipsePoints(circle_vertices, circle_colors, CIRCLE_NUM_POINTS, CIRCLE_NUM_POINTS, circle_center2, 0.08, 1.0);
    // 圆(眼珠)
    generateEllipsePoints(circle_vertices, circle_colors, 2 * CIRCLE_NUM_POINTS, CIRCLE_NUM_POINTS, circle_center1, 0.03, 1.0);
    generateEllipsePoints(circle_vertices, circle_colors, 3 * CIRCLE_NUM_POINTS, CIRCLE_NUM_POINTS, circle_center2, 0.03, 1.0);

    // 三角形(耳朵,嘴巴)
    glm::vec2 traTriangle_scale1(0.1, 0.1);
    glm::vec2 traTriangle_scale2(0.16, 0.16);
    glm::vec2 traTriangle_scale3(0.09, 0.09);
    glm::vec2 traTriangle_center1(-0.48, 0.0);
    glm::vec2 traTriangle_center2(0.48, 0.0);
    glm::vec2 traTriangle_center3(0.0, -0.2);
    generateTrianglePoints(traTriangle_scale1, traTriangle_center1, triangle_vertices, triangle_colors, 0, 3 * M_PI / 2);
    generateTrianglePoints(traTriangle_scale1, traTriangle_center2, triangle_vertices, triangle_colors, TRIANGLE_NUM_POINTS, M_PI / 2);
    generateTrianglePoints(traTriangle_scale2, traTriangle_center3, triangle_vertices, triangle_colors, 2 * TRIANGLE_NUM_POINTS, M_PI);
    generateTrianglePoints(traTriangle_scale3, traTriangle_center3, triangle_vertices, triangle_colors, 3 * TRIANGLE_NUM_POINTS, M_PI);
    

    // 读取着色器并使用
    std::string vshader, fshader;
    vshader = "shaders/vshader.glsl";
    fshader = "shaders/fshader.glsl";
    program = InitShader(vshader.c_str(), fshader.c_str());
    glUseProgram(program);

    // 创建顶点缓存对象,vbo[2]是因为我们将要使用两个缓存对象
    GLuint vbo[2];

    /*
     * 初始化正方形的数据
     */

    glGenVertexArrays(1, &vao[1]);
    glBindVertexArray(vao[1]);

    glGenBuffers(1, &vbo[0]);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(square_vertices), square_vertices,
        GL_STATIC_DRAW);
    GLuint location = glGetAttribLocation(program, "vPosition");
    glEnableVertexAttribArray(location);
    glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2),
        BUFFER_OFFSET(0));

    glGenBuffers(1, &vbo[1]);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(square_colors), square_colors,
        GL_STATIC_DRAW);
    GLuint cLocation = glGetAttribLocation(program, "vColor");
    glEnableVertexAttribArray(cLocation);
    glVertexAttribPointer(cLocation, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3),
        BUFFER_OFFSET(0));

    /*
     * 初始化三角形的数据
     */

    glGenVertexArrays(1, &vao[0]);
    glBindVertexArray(vao[0]);

    glGenBuffers(1, &vbo[0]);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(triangle_vertices), triangle_vertices,
        GL_STATIC_DRAW);
    location = glGetAttribLocation(program, "vPosition");
    glEnableVertexAttribArray(location);
    glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2),
        BUFFER_OFFSET(0));

    glGenBuffers(1, &vbo[1]);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(triangle_colors), triangle_colors,
        GL_STATIC_DRAW);
    cLocation = glGetAttribLocation(program, "vColor");
    glEnableVertexAttribArray(cLocation);
    glVertexAttribPointer(cLocation, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3),
        BUFFER_OFFSET(0));

    /*
     * 初始化椭圆的数据
     */

    glGenVertexArrays(1, &vao[3]);
    glBindVertexArray(vao[3]);

    glGenBuffers(1, &vbo[0]);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(elipse_vertices), elipse_vertices,
        GL_STATIC_DRAW);
    location = glGetAttribLocation(program, "vPosition");
    glEnableVertexAttribArray(location);
    glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2),
        BUFFER_OFFSET(0));

    glGenBuffers(1, &vbo[1]);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(elipse_colors), elipse_colors,
        GL_STATIC_DRAW);
    cLocation = glGetAttribLocation(program, "vColor");
    glEnableVertexAttribArray(cLocation);
    glVertexAttribPointer(cLocation, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3),
        BUFFER_OFFSET(0));
    /*
     * 初始化圆的数据
     */
    glGenVertexArrays(1, &vao[4]);
    glBindVertexArray(vao[4]);

    glGenBuffers(1, &vbo[0]);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(circle_vertices), circle_vertices,
        GL_STATIC_DRAW);
    location = glGetAttribLocation(program, "vPosition");
    glEnableVertexAttribArray(location);
    glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2),
        BUFFER_OFFSET(0));

    glGenBuffers(1, &vbo[1]);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(circle_colors), circle_colors,
        GL_STATIC_DRAW);
    cLocation = glGetAttribLocation(program, "vColor");
    glEnableVertexAttribArray(cLocation);
    glVertexAttribPointer(cLocation, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3),
        BUFFER_OFFSET(0));

    glClearColor(0.0, 0.0, 0.0, 1.0);
}

void display(void) {
    glClear(GL_COLOR_BUFFER_BIT);
    glUseProgram(program);

    // 绘制正方形
    // 得先画正方形,否则有一个三角形会被遮住
    glBindVertexArray(vao[1]);
    for (int i = 0; i < SQUARE_NUM; ++i) {
        glDrawArrays(GL_TRIANGLE_FAN, (i * 4), 4);
    }

    // 绘制三角形
    // 红色的(耳朵,嘴巴)
    glBindVertexArray(vao[0]);
    glDrawArrays(GL_TRIANGLES, 0, TRIANGLE_NUM_POINTS);
    glDrawArrays(GL_TRIANGLES, TRIANGLE_NUM_POINTS, TRIANGLE_NUM_POINTS);
    glDrawArrays(GL_TRIANGLES, 2 * TRIANGLE_NUM_POINTS, TRIANGLE_NUM_POINTS);
    // 白色的(嘴巴里面)
    glDrawArrays(GL_TRIANGLES, 3 * TRIANGLE_NUM_POINTS, TRIANGLE_NUM_POINTS);

    // 绘制圆(眼睛)
    glBindVertexArray(vao[4]);
    glDrawArrays(GL_TRIANGLE_FAN, 0, CIRCLE_NUM_POINTS);
    glBindVertexArray(vao[4]);
    glDrawArrays(GL_TRIANGLE_FAN, CIRCLE_NUM_POINTS, CIRCLE_NUM_POINTS);
    glBindVertexArray(vao[4]);
    // 绘制圆(眼珠)
    glDrawArrays(GL_TRIANGLE_FAN, 2 * CIRCLE_NUM_POINTS, CIRCLE_NUM_POINTS);
    glBindVertexArray(vao[4]);
    glDrawArrays(GL_TRIANGLE_FAN, 3 * CIRCLE_NUM_POINTS, CIRCLE_NUM_POINTS);


    //  绘制椭圆(鼻子)
    glBindVertexArray(vao[3]);
    glDrawArrays(GL_TRIANGLE_FAN, 0, ELLIPSE_NUM_POINTS);
    //  绘制椭圆(头发),两个
    glBindVertexArray(vao[3]);
    glDrawArrays(GL_TRIANGLE_FAN, ELLIPSE_NUM_POINTS, ELLIPSE_NUM_POINTS);
    glBindVertexArray(vao[3]);
    glDrawArrays(GL_TRIANGLE_FAN, 2 * ELLIPSE_NUM_POINTS, ELLIPSE_NUM_POINTS);

    glFlush();
}

int main(int argc, char** argv) {
    // 初始化GLFW库
    glfwInit();

    // 配置GLFW
    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);
#endif

    // 配置窗口属性
    GLFWwindow* window = glfwCreateWindow(512, 512, "学号_姓名_实验一", NULL, NULL);
    if (window == NULL) {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

    // 调用任何OpenGL的函数之前初始化GLAD
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }

    init();

    std::cout << "OpenGL Vendor: " << glGetString(GL_VENDOR) << std::endl;
    std::cout << "OpenGL Renderer: " << glGetString(GL_RENDERER) << std::endl;
    std::cout << "OpenGL Version: " << glGetString(GL_VERSION) << std::endl;
    std::cout << "Supported GLSL version is: "
        << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;

    while (!glfwWindowShouldClose(window)) {
        display();
        // 交换颜色缓冲以及检查有没有触发什么事件(比如键盘输入、鼠标移动等)
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    return 0;
}

标签:glm,OpenGL,图形学,colors,NUM,vec2,深圳大学,GL,POINTS
From: https://blog.csdn.net/qq_73179413/article/details/145147701

相关文章

  • 深圳大学-程序设计基础-OJ
    A.100到n以内的水仙花数题目描述若3位数ABC满足ABC=A3+B3+C3,则称其为水仙花数.例如:153=13+53+3^3,所以153是水仙花数.你的任务是输出100~n中所有的水仙花数.每行输出一个。输入输入n,表示100到n之间的范围输出请输出100~n中所有的水仙花数.每行输出一个.样例输出......
  • 深圳大学-程序设计基础-OJ
    A.字母转换(顺序)题目描述输入一个大写字母,输出其对应的小写字母。例如输入E,输出e。输入一个大写字母(A~Z)输出对应的小写字母输入样例B输出样例b代码#include<iostream>#include<algorithm>#include<cmath>#include<vector>#include<set>#include......
  • 详解 opengl 语法
    以下是OpenGL语法的详解,分为核心功能、常见函数的用法以及它们在OpenGL渲染管线中的位置。OpenGL是一个状态机,许多操作都是围绕上下文状态进行的。1.OpenGL基本结构OpenGL的主要功能是通过调用一系列的API,完成三维图形的绘制。主要包括以下几个步骤:初始化Open......
  • 初识 OpenGL
    OpenGL(OpenGraphicsLibrary)是一种跨平台的图形开发接口,它用于渲染2D和3D图形。OpenGL的主要功能是向开发者提供一个可以调用硬件加速的API,以绘制复杂的图形和视觉效果。它被广泛应用于游戏开发、图形设计、科学可视化和虚拟现实等领域。在初识OpenGL时,我们可以通过一......
  • OpenGL 使用记录
    多线程渲染方案方案多线程更新纹理,主线程渲染多线程FBO渲染,主线程显示线程安全性子线程只操作共享的纹理,主线程负责渲染,信号槽机制确保线程安全。子线程直接操作自己的FBO,主线程仅访问FBO的纹理,较安全。复杂性逻辑较简单,纹理数据更新逻辑独立,主线程负责完整的......
  • 【OpenGL ES】GLSL基础语法
    1前言​本文将介绍GLSL中数据类型、数组、结构体、宏、运算符、向量运算、矩阵运算、函数、流程控制、精度限定符、变量限定符(in、out、inout)、函数参数限定符等内容,另外提供了一个include工具,方便多文件管理glsl代码,实现代码的精简、复用。​Unity中Shader介......
  • 计算机图形学——射线与三角形相交检测_Möller-Trumbore算法及推导过程(涉及标量三重
    1.标量三重积1.1标量三重积的定义标量三重积(scalartripleproduct)是一个结合点积和叉积的运算,定义为:a⋅(b......
  • 计算机图形学——Ray Tracing 反射、折射(Snell’s Law 斯涅尔定律)、 菲涅耳反射系数、
    1.反射方向的计算反射方向的计算是光线追踪中一个重要的数学过程,用于模拟光线在物体表面反射的行为。通过计算反射方向,可以生成新的光线来追踪反射光的传播路径。1.1反射方向公式:反射光的方向基于光的反射定律:入射角等于反射角,且反射光方向与表面法线关于法线对称。数......
  • 麒麟系统修改配置镜像源地址并安装openGL
    1.编辑文件/etc/apt/sources.list进入目录cd /etc/apt/编辑文件(需要root权限)sudovi sources.list将镜像地址改为你指定的镜像地址#debhttp://archive.kylinos.cn/kylin/KYLIN-ALL10.1mainrestricteduniversemultiverse#debhttp://archive.kylinos.cn/kylin/KYL......
  • Opengl-状态机
    状态机AslongasyoukeepinmindthatOpenGlisbasicllyonelargestatemchine,mostofitsfunctionalitywillmakemoresense.OPengl是一个巨大的状态机,变量(描述该如何操作)的大集合。Opengl的状态被称为上下文(context)状态设置函数(State-changingFunction)状态应......