计算机图形学 | 实验三:绘制一个四边形

用BufferGeometry自定义顶点来创建图形 上一节用到了自带函数PlaneBufferGeometry创建四边形,PlaneBufferGeometry的基类也是BufferGeomtry。但是在你做项目或者产品的时候是需要自定义顶点数组的,特别是大规模顶点数据时,我们要用到BufferGeometry。使用 BufferGeometry 可以有效少向 GPU 传输上述数据所需的开销。BufferGeometry包括了几何体所有的信息,都放入buffer中一次性传输给gpu,包括顶点位置,面片索引、法相量、颜色值、UV 坐标和自定义缓存属性值。因为 阅读详情

华中科技大学《计算机图形学》课程

MOOC地址:计算机图形学(HUST)

计算机图形学 | 实验三:绘制一个四边形

在正式搭建环境之前,我们先来介绍一下读完下面的部分你会了解些什么。

  • 基础绘制的过程,包括初始化,顶点输入,数据处理,着色器计算以及渲染
  • 用VAO/VBO以及EBO两种方式绘制四边形

接下来,我们来介绍一下绘制四边形。绘制效果如下:

在这里插入图片描述

初始化

在代码的开始部分,我们依然对OpenGL进行一个初始化,其中就包括初始化GLFW,创建窗口,初始化GLAD,创建视口这四个部分。

	glfwInit();// 初始化GLFW
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);// OpenGL版本为3.3,主次版本号均设为3
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);// 使用核心模式(无需向后兼容性)
	glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);// 如果使用的是Mac OS X系统,需加上这行
	glfwWindowHint(GLFW_RESIZABLE, false);// 不可改变窗口大小

	// 创建窗口(宽、高、窗口名称)
	auto window = glfwCreateWindow(screen_width, screen_height, "Quad", nullptr, nullptr);
	if (window == nullptr)
	{
		// 如果窗口创建失败,输出Failed to Create OpenGL Context
		std::cout << "Failed to Create OpenGL Context" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);// 将窗口的上下文设置为当前线程的主上下文

	// 初始化GLAD,加载OpenGL函数指针地址的函数
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
	{
		std::cout << "Failed to initialize GLAD" << std::endl;
		return -1;
	}

	// 指定当前视口尺寸(前两个参数为左下角位置,后两个参数是渲染窗口宽、高)
	glViewport(0, 0, screen_width, screen_height);

顶点输入

初始化之后,我们需要给出我们四边形的顶点数据,并对数据做出一些处理,包括生成绑定VAO、VBO和属性设置,最后将其解绑。

由于我们绘制的是一个四边形,因此我们的顶点数据由两组三角形组成。这里的顶点数据是标准化的设备坐标,也就是x,y,z轴坐标均映射到[-1,1]之间。

// 四边形的顶点数据
float vertices[] = {
	// 第一个三角形
	0.5f, 0.5f, 0.0f,   // 右上
	0.5f, -0.5f, 0.0f,  // 右下
	-0.5f, -0.5f, 0.0f, // 左下
	// 第二个三角形
	-0.5f, -0.5f, 0.0f, // 左下
	0.5f, 0.5f, 0.0f,   // 右上
	-0.5f, 0.5f, 0.0f   // 左上
};

数据处理

VAO、VBO

我们有了顶点数据,接下来就是要将这些顶点数据发送到GPU中去处理,这里我们生成了一个顶点缓冲对象VBO,并且将其绑定到顶点缓冲对象上,使用这个顶点缓冲对象的好处是我们不用将顶点数据一个一个的发送到显卡,而是可以借助VBO一次性的发送一大批数据过去,然后使用glBufferData将顶点数据绑定到当前默认的缓冲上,这里的GL_STATIC_DRAW表示我们的四边形位置数据不会被改变。

这里我们还生成了一个顶点数组对象VAO,使用VAO的原因是首先我们使用的核心模式要求我们需要使用VAO,其次使用VAO的好处在于我们在渲染的时候只需要调用一次VAO就可以了,之前的数据都对应存储在了VAO中,不用再调用VBO。那么VAO的生成过程也跟VBO一样,需要先生成再绑定,等到这些操作都进行完,我们可以解绑我们的VAO,VBO。

	// 生成并绑定VAO和VBO
	GLuint vertex_array_object;// VAO
	glGenVertexArrays(1, &vertex_array_object);
	glBindVertexArray(vertex_array_object);

	GLuint vertex_buffer_object;// VBO
	glGenBuffers(1, &vertex_buffer_object);
	glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_object);

	// 将顶点数据绑定至当前默认的缓冲中
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

顶点属性

	// 设置顶点属性指针
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);
	glEnableVertexAttribArray(0);

这个函数第一个参数是我们后面会用到的顶点着色器的位置值,3表示的是顶点属性是一个三分量的向量,第三个参数表示的是我们顶点的类型,第四个是我们是否希望数据被标准化,就是映射到0-1之间,第五个参数叫做步长,它表示连续顶点属性之间的间隔,因为我们这里只有顶点的位置,所以我们将步长设置为这个,表示下组数据在3个float之后。最后一个是数据的偏移量,这里我们的位置属性是在数组的开头,因此这里是0,并且由于参数类型的限制,我们需要将其进行强制类型转换。

而下面Enable的函数则是表明我们开启了0的这个通道,默认状态下是关闭的,因此我们在这里要开启一下。

等到设置属性指针完成之后,我们这里需要解绑VAO和VBO。那么,我们可以思考一下,为什么我们在这里要解绑VAO和VBO呢?

一个原因是因为在防止之后再继续绑定VAO的时候会影响当前的VAO,另一个原因是为了使代码更加灵活规范,在渲染需要的时候我们会再绑定VAO。

我们已经通过VAO、VBO将顶点数据储存在显卡的GPU上了,接下来我们会创建顶点和片段着色器真正处理这些数据。这里我们会给出着色器的源码,然后生成并编译着色器,最后将顶点和片段着色器链接到一个着色器程序,在之后的渲染流程中我们会使用这个着色器程序,最后将之前的着色器删除。

顶点着色器和片段着色器

这里我们给出的这两段分别是顶点着色器的源码和片段着色器的源码,这个是用GLSL语言来编写的,而且这个GLSL语言看起来与C语言的风格类似,很容易懂。我们先看顶点着色器,第一行表示我们使用的是OpenGL3.3的核心模式,第二行就是我们之前说到的位置值。Main函数中的部分就是将我们之前的顶点数据直接输出到GLSL已经定义好的一个内建变量gl_Position中,这个就是我们顶点着色器的输出,也就是说我们在顶点着色器这里什么都没做,就只是将顶点位置作为顶点着色器的输出。

	// 顶点着色器源码
	const char *vertex_shader_source =
		"#version 330 core\n"
		"layout (location = 0) in vec3 aPos;\n"// 位置变量的属性位置值为0
		"void main()\n"
		"{\n"
		"    gl_Position = vec4(aPos, 1.0);\n"
		"}\n\0";

接下来是片段着色器,前面两行类似,这里的out表示输出变量,就像之前的in表示输入变量。然后我们这里的四分量向量就是我们之前看到的四边形是红色的来源,是一个四分量的RGBA,那么我们也可以将其更改一下,我们输出的四边形颜色就会发生变化。

	// 片段着色器源码
	const char *fragment_shader_source =
		"#version 330 core\n"
		"out vec4 FragColor;\n" // 输出的颜色向量
		"void main()\n"
		"{\n"
		"    FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
		"}\n\0";

有了顶点和片段着色器的源码,我们还需要生成和编译着色器,那么这里我们先生成了顶点着色器,并且附加上了之前的源码,将其进行编译,然后我们这里对其进行检测,是否成功编译,如果编译不成功就打印错误信息。

同样的片段着色器也是一样的。

最后我们将顶点和片段着色器链接到一个着色器程序中,这样我们在渲染时只需要调用一个着色器程序就可以了,同样这里我们检测了一下链接是否成功。

	// 生成并编译着色器
	// 顶点着色器
	int vertex_shader = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL);
	glCompileShader(vertex_shader);
	int success;
	char info_log[512];
	// 检查着色器是否成功编译,如果编译失败,打印错误信息
	glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
	if (!success)
	{
		glGetShaderInfoLog(vertex_shader, 512, NULL, info_log);
		std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n"
			<< info_log << std::endl;
	}
	// 片段着色器
	int fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL);
	glCompileShader(fragment_shader);
	// 检查着色器是否成功编译,如果编译失败,打印错误信息
	glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);
	if (!success)
	{
		glGetShaderInfoLog(fragment_shader, 512, NULL, info_log);
		std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n"
			<< info_log << std::endl;
	}
	// 链接顶点和片段着色器至一个着色器程序
	int shader_program = glCreateProgram();
	glAttachShader(shader_program, vertex_shader);
	glAttachShader(shader_program, fragment_shader);
	glLinkProgram(shader_program);
	// 检查着色器是否成功链接,如果链接失败,打印错误信息
	glGetProgramiv(shader_program, GL_LINK_STATUS, &success);
	if (!success)
	{
		glGetProgramInfoLog(shader_program, 512, NULL, info_log);
		std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n"
			<< info_log << std::endl;
	}

最后删除掉顶点和片段着色器。因为在后面渲染的时候我们只需要用那个我们之前链接好的着色器程序就可以了,不需要再使用顶点和片段着色器了。

	// 删除着色器
	glDeleteShader(vertex_shader);
	glDeleteShader(fragment_shader);

渲染

接下来我们进入我们的渲染阶段,当窗口没有关闭的时候我们就一直进行渲染。首先我们先清空颜色缓冲,我们这里用的是黑色的背景色来清空屏幕颜色缓冲,当然这里我们可以更换颜色。接下来我们使用我们之前已经链接好的着色器程序,和VAO,来绘制四边形,绘制四边形其实只要一句话,就是这个glDrawArrays,当然还有其他的绘制方式,我们这里用的是这种方式。这里的第一个参数表示我们是要绘制四边形,第二个参数表示我们顶点数组的起始索引值,第三个参数表示我们要绘制的顶点数量,这里绘制四边形我们要绘制三个顶点。绘制结束后解除绑定。最后我们会交换一下缓冲,这里我们使用的是一个双缓冲的做法,前缓冲保存着输出的图像,而渲染指令都在后缓冲中进行,当指令执行完毕后我们交换前后缓冲,最后我们还会检测是否有触发一些回调函数。

		// 使用着色器程序
		glUseProgram(shader_program);

		// 绘制四边形
		glBindVertexArray(vertex_array_object);// 绑定VAO						
		glDrawArrays(GL_TRIANGLES, 0, 6);// 绘制四边形

当我们的窗口关闭之后,我们还会进行一些善后工作,这里包括删除我们之前所创建的VAO、VBO,以及调用GLFW的函数来清理所有的资源并退出程序。

	// 删除VAO/VBO/EBO
	glDeleteVertexArrays(1, &vertex_array_object);
	glDeleteBuffers(1, &vertex_buffer_object);
	glDeleteBuffers(1, &element_buffer_object);

	// 清理所有的资源并正确退出程序
	glfwTerminate();

整个绘制四边形的程序就到此为止。

我们回头再来梳理一遍绘制四边形流程,刚开始我们先初始化OpenGL,接下来对我们的数据进行处理,通过VAO、VBO将其发送至GPU中,并设置属性指针告诉GPU我们会如何解释这些数据,然后在着色器中通过顶点和片段着色器对数据进行处理,最后进行渲染,渲染之后做好我们的善后工作,一个四边形就绘制成功了。

效果如下:

在这里插入图片描述

EBO

细心的人可能已经看出了些问题,左下和右上角的顶点我们使用了两次,一个矩形只有四个顶点,如果是大量的复杂模型计算就会产生很多浪费。如何解决这个问题呢?其实我们只要存储矩形的四个顶点,然后指定绘制顺序就好了,EBO帮助我们实现了这个功能。

我们采用了一种索引绘制的方式,首先要定义不重复的顶点:

// 四边形的顶点数据
float vertices[] = {
	// 第一个三角形
	0.5f, 0.5f, 0.0f,   // 右上
	0.5f, -0.5f, 0.0f,  // 右下
	-0.5f, -0.5f, 0.0f, // 左下
	// 第二个三角形
	-0.5f, -0.5f, 0.0f, // 左下
	0.5f, 0.5f, 0.0f,   // 右上
	-0.5f, 0.5f, 0.0f   // 左上
};

// 索引数据(注意这里是从0开始的)
unsigned int indices[] = {
	0, 1, 5, // 第一个三角形
	1, 2, 5  // 第二个三角形
};

接下来我们要创建索引缓冲对象,这里同VBO类似。

	GLuint element_buffer_object;// EBO
	glGenBuffers(1, &element_buffer_object);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_buffer_object);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

我们先绑定EBO然后用glBufferData把索引复制到缓冲里。这次我们把缓冲的类型定义为GL_ELEMENT_ARRAY_BUFFER。

运行程序则会显示如下的结果。

在这里插入图片描述

开启线框模式如下:

// 线框模式 
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

其中第一个参数表示我们应用到所有三角形的正面和背面,第二个参数则是我们选择用线来绘制还是使用填充模式(GL_FILL)来设置回默认模式。

效果如下:

在这里插入图片描述

完整代码

/***
* 例程  绘制四边形 (MAKE后运行时可删除ALL_BUILD,也可以将Task-quad设为默认启动工程)
* 步骤:
* 1-初始化:   GLFW窗口,GLAD。
* 2-数据处理: 给定顶点数据,生成并绑定VAO&VBO(准备在GPU中进行处理),设置顶点属性指针(本质上就是告诉OpenGL如何处理数据)。
* 3-着色器:   给出顶点和片段着色器,然后链接为着色器程序,渲染时使用着色器程序。
* 4-渲染:     清空缓冲,使用着色器程序,绘制四边形,交换缓冲区检查触发事件后释放资源
*/

#include <iostream>
#include "glad/glad.h"
#include "GLFW/glfw3.h"

// 四边形的顶点数据
float vertices[] = {
	// 第一个三角形
	0.5f, 0.5f, 0.0f,   // 右上
	0.5f, -0.5f, 0.0f,  // 右下
	-0.5f, -0.5f, 0.0f, // 左下
	// 第二个三角形
	-0.5f, -0.5f, 0.0f, // 左下
	0.5f, 0.5f, 0.0f,   // 右上
	-0.5f, 0.5f, 0.0f   // 左上
};

// 索引数据(注意这里是从0开始的)
unsigned int indices[] = {
	0, 1, 5, // 第一个三角形
	1, 2, 5  // 第二个三角形
};

// 屏幕宽,高
int screen_width = 1280;
int screen_height = 720;

int main()
{
	glfwInit();// 初始化GLFW
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);// OpenGL版本为3.3,主次版本号均设为3
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);// 使用核心模式(无需向后兼容性)
	glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);// 如果使用的是Mac OS X系统,需加上这行
	glfwWindowHint(GLFW_RESIZABLE, false);// 不可改变窗口大小

	// 创建窗口(宽、高、窗口名称)
	auto window = glfwCreateWindow(screen_width, screen_height, "Quadrangle", nullptr, nullptr);
	if (window == nullptr)
	{
		// 如果窗口创建失败,输出Failed to Create OpenGL Context
		std::cout << "Failed to Create OpenGL Context" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);// 将窗口的上下文设置为当前线程的主上下文

	// 初始化GLAD,加载OpenGL函数指针地址的函数
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
	{
		std::cout << "Failed to initialize GLAD" << std::endl;
		return -1;
	}

	// 指定当前视口尺寸(前两个参数为左下角位置,后两个参数是渲染窗口宽、高)
	glViewport(0, 0, screen_width, screen_height);

	// 生成并绑定VAO和VBO
	GLuint vertex_array_object;// VAO
	glGenVertexArrays(1, &vertex_array_object);
	glBindVertexArray(vertex_array_object);

	GLuint vertex_buffer_object;// VBO
	glGenBuffers(1, &vertex_buffer_object);
	glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_object);

	// 将顶点数据绑定至当前默认的缓冲中
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

	GLuint element_buffer_object;// EBO
	glGenBuffers(1, &element_buffer_object);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_buffer_object);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

	// 设置顶点属性指针
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);
	glEnableVertexAttribArray(0);

	// 解绑VAO和VBO
	glBindVertexArray(0);
	glBindBuffer(GL_ARRAY_BUFFER, 0);

	// 顶点着色器源码
	const char *vertex_shader_source =
		"#version 330 core\n"
		"layout (location = 0) in vec3 aPos;\n"// 位置变量的属性位置值为0
		"void main()\n"
		"{\n"
		"    gl_Position = vec4(aPos, 1.0);\n"
		"}\n\0";
	// 片段着色器源码
	const char *fragment_shader_source =
		"#version 330 core\n"
		"out vec4 FragColor;\n" // 输出的颜色向量
		"void main()\n"
		"{\n"
		"    FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
		"}\n\0";

	// 生成并编译着色器
	// 顶点着色器
	int vertex_shader = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL);
	glCompileShader(vertex_shader);
	int success;
	char info_log[512];
	// 检查着色器是否成功编译,如果编译失败,打印错误信息
	glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
	if (!success)
	{
		glGetShaderInfoLog(vertex_shader, 512, NULL, info_log);
		std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n"
			<< info_log << std::endl;
	}
	// 片段着色器
	int fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL);
	glCompileShader(fragment_shader);
	// 检查着色器是否成功编译,如果编译失败,打印错误信息
	glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);
	if (!success)
	{
		glGetShaderInfoLog(fragment_shader, 512, NULL, info_log);
		std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n"
			<< info_log << std::endl;
	}
	// 链接顶点和片段着色器至一个着色器程序
	int shader_program = glCreateProgram();
	glAttachShader(shader_program, vertex_shader);
	glAttachShader(shader_program, fragment_shader);
	glLinkProgram(shader_program);
	// 检查着色器是否成功链接,如果链接失败,打印错误信息
	glGetProgramiv(shader_program, GL_LINK_STATUS, &success);
	if (!success)
	{
		glGetProgramInfoLog(shader_program, 512, NULL, info_log);
		std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n"
			<< info_log << std::endl;
	}
	// 删除着色器
	glDeleteShader(vertex_shader);
	glDeleteShader(fragment_shader);

	// 线框模式
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	// 填充模式
	// glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

	// 渲染循环
	while (!glfwWindowShouldClose(window))
	{

		// 清空颜色缓冲
		glClearColor(0.0f, 0.34f, 0.57f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);

		// 使用着色器程序
		glUseProgram(shader_program);

		// 绘制四边形
		glBindVertexArray(vertex_array_object);// 绑定VAO						
		glDrawArrays(GL_TRIANGLES, 0, 6);// 绘制四边形
		// 用EBO绘制四边形
		// glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
		glBindVertexArray(0);// 解除绑定

		// 交换缓冲并且检查是否有触发事件(比如键盘输入、鼠标移动等)
		glfwSwapBuffers(window);
		glfwPollEvents();
	}

	// 删除VAO/VBO/EBO
	glDeleteVertexArrays(1, &vertex_array_object);
	glDeleteBuffers(1, &vertex_buffer_object);
	glDeleteBuffers(1, &element_buffer_object);

	// 清理所有的资源并正确退出程序
	glfwTerminate();

	return 0;
}

计算机图形学实验 文章目录实验介绍实验内容实验一实验二实验三实验四实验五实验源码 实验介绍 大二学期的计算机图形学课程,内容包含扫描转换算法,裁剪算法,图形变换,三维图形投影和消隐,曲线和曲面;从完成情况来看虽算不上十分出色,但也花了很多时间和精力,代码必然存在一些冗余、不足和待改进之处,故公开和大家交流和参考 实验内容 实验一 (●’◡’●) 效果展示 实验题1-1:绘制任意斜率的直线 实验题1-3:用中点画圆法画圆 实验题1-4:中点画圆法画椭圆 实验题1-5:中点画圆法画圆弧 实 阅读详情

相关推荐

计算机图形学——简单图形绘制

图元的绘制 1.在屏幕上绘制几何图元(如下图所示),自定义坐标和颜色。 2.采用中点圆算法在屏幕上画一个圆。 二、实验环境 dev-c IDE MinGW32编译器 opengl若干拓展包 三、实验一 在屏幕上绘制几何图元,自定义坐标和颜色。 较为熟练的使用函数库。 实验结果 四、实验二 采用中点圆算法在屏幕中画一个圆。 算法: MidPointCircl算法画出1/8个圆 利用圆的八...

m0_46601288的博客 7033

OpenGL(四)——创建一个四边形

//不显示控制台窗口 #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")

ifeng12358的博客 1872

孔令德的计算机图形学课程实验

授课总学时64,实验项目学时12  实验一  绘制任意斜率的直线(2学时)        验证性 实验内容:利用中点Bresenham算法,编程实现绘制任意斜率的直线。 基本要求: 1. 掌握中点Bresenham算法的原理和算法; 2. 使用鼠标在屏幕上绘制任意斜率的直线; 实验拓展:彩色直线与反走样直线。   实验二  交互式绘制多边形(2学时)  

klingde的专栏 1万+

【OpenGL 学习笔记】第 4 篇:绘制四边形

(0)选择x64平台 (1)添加链接打开项目属性打开项目目录添加文件路径:包含目录添加:D:\OpenGL_Link\Includes;库目录添加:D:\OpenGL_Link\Libs; 打开链接器/输入添加: 在项目源文件夹下添加glad.c文件 新建main.cpp文件,测试代码,没问题即可。 输出结果 包括:初始化GLFW、创建窗口、初始化GLAD、创建视口 2、顶点输入 3、数据处理 (1)VBO 我们有了顶点数据,接下来就是将这些顶点数据发送到GPU中去处理,这里我们

有朋自远方来,不亦乐乎。 1962

计算机图形学实验四球体 Gouraud 光照模型

实验目的 (1)掌握双线性光强插值模型。 二、实验步骤 (1)建立三维坐标系 Oxyz,原点位于屏幕客户区中心,x 轴水平向右为正, y 轴铅直向上为正,z 轴垂直于屏幕指向观察者。 (2)绘制体心和坐标系中心重合的球体表面,使用 ZBuffer 消隐算法进行消 隐。使用 Z‐Buffer 算法对球面进行深度消隐,然后使用有效边表算法进行填充。 为了减少渲染的面片数,先使用凸多面体消隐...

NuvoleSiene的博客 8343

TIT 计算机图形学 期末课设-青花瓷坛的实体模型

文章目录TIT 计算机图形学 期末课设-青花瓷坛的实体模型前言一、项目描述二、项目设计1.原理2.相关算法3.模型三、部分代码1.导入位图,格式为bmp2.Texture类3.在贝塞尔曲线类中绑定纹理对象4.ZBuffer四、整体设计步骤五、总结 TIT 计算机图形学 期末课设-青花瓷坛的实体模型 前言 实验中用到了很多知识点,这里只讲解其中的一部分,仅供参考.详细讲解可以看孔老师的视频课,具体学习程序中的类 参考视频计算机图形学全套算法讲解和C++编码实现(共23讲配套源码),计算机图形学案例视频讲解以

张时贰的博客 5515

python绘制平行四边形

cv2.polylines是OpenCV库中的一个函数,用于在图像上绘制多边形。它可以绘制闭合或非闭合的多边形,并且可以选择不同的线宽和颜色。

重剑无锋博客 1340

计算机图形学实验二 多边形的填充算法

接着,将该像素点的四周像素点依次加入一个队列中,然后逐个取出队列中的像素点,并将其颜色替换为所需填充的颜色。该算法的时间复杂度与填充的像素数量有关,通常为 O(m),其中 m 是填充的像素数量。本次实验理解多边形的表示方法,理解四连接和八连接的概念,学会了多边形的种子填充算法,多边形填充有扫描线算法、边界填充算法、色彩种子填充算法四种填充算法。答:四连接种子填充算法是指从种子像素的上、下、左、右四个方向进行填充,而八连接种子填充算法则是在四个基本方向的基础上,增加四个斜向(45度)方向的填充。

XIYOUMIN110的博客 1643

OSG学习:几何对象的绘制(一)——四边形

以下内容来自:  1、《OpenSceneGraph三维渲染引擎编程指南》肖鹏 刘更代 徐明亮 清华大学出版社  2、《OpenSceneGraph三维渲染引擎设计与实践》王锐 钱学雷 清华大学出版社 3、自己的总结   OSG中类的继承关系等见OSG学习:OSG组成(二)——场景树。 下载完整工程OSG_3_GeometryQuads 创建C++项目后,首先需要配置OSG环境...

韶光 4637

计算机图形学实验指导:从理论到实践

在二维平面中,一个点的位置可以通过一对数值来定义,即该点在横坐标(x轴)和纵坐标(y轴)上的位置。而在三维空间中,我们引入了第三维的坐标值z,用来表示点在深度方向的位置。通过这些坐标值,我们可以构造出一个坐标系,它是进行图形绘制和变换的基石。向量是图形学中一种重要的数学工具,它不仅表示位置和方向,还是描述物理量和变换的基础。向量可以从几何的角度被看作有方向和长度的直线段,也可以从代数的角度被看作由一系列数值组成的数组,这些数值在数学和物理学中代表了向量的不同分量。在图形学中,二维向量通常表示为。

weixin_36012152的博客 573

计算机图形学实验报告

山东大学计算机图形学实验报告 两个实验报告 实验一1. 利用Glut库,编写一个OpenGL程序,实现以下功能:  仿照课本2.4.3的例子,绘制若干OpenGL基本体素(三角形、三角形带、四边形、四边形带)构成的球体,注意球体绘制与球体划分的区别。  可以控制改变球的数量和球的体积,来改变基本体素的数量以及顶点的数量。等等 实验二 设计一个OpenGL程序,创建一个三维迷宫,支持替身通过一定交互手段在迷宫中漫游,基本功能包括:  迷宫应当至少包含10 * 10 个Cell,不能过于简单,下图给出一种示例。  读取给定的替身模型,加载到场景中。  键盘方向键控制替身转向与漫游。  有碰撞检测,替身不应当穿墙。

计算机图形学 实验1 《实验环境配置和基本图元绘制》

计算机图形学 实验1 《实验环境配置和基本图元绘制》 一、实验目的 配置基本实验环境、安装软件包、建立工程和绘制基本图元,要求学会点、线、三角形、四边形的绘制方法,学会消息传递和响应机制,用一个实例完成上述要求。 二、实验内容 1、配置OpenGL绘图环境; 2、绘制点、线、三角形、四边形等基本图元。 三、实验方法 以Visual Studio 2019为开发环境,合理配置第三方glut相关文件(部署glut头文件、glut动态链接库、glut.lib类型库),并且使用OpenGL的基本绘制模式(包括GL_

Atlas 5425

RK3588嵌入式AI部署实战:从环境搭建到模型推理全链路

嵌入式AI部署涉及交叉编译、NPU驱动、模型量化与运行时环境等多个技术环节,其核心挑战在于软硬件版本矩阵的严格匹配。在边缘计算场景中,RK3588凭借6TOPS NPU算力成为热门平台,但环境搭建与模型转换的复杂性常导致部署效率低下。通过容器化工具链管理、量化参数对齐及多线程推理优化,可显著提升部署稳定性与推理性能。典型应用包括智能安防、工业质检与视频结构化分析。本文围绕RK3588的AI部署与环境搭建,系统梳理从系统烧录到板端推理的完整实践路径。

weixin_42520573的博客 284

TIT 计算机图形学 实验三 使用重心坐标算法绘制颜色渐变的正六面体

TIT 计算机图形学 实验三 使用重心坐标算法绘制颜色渐变的正六面体 前言 参考视频计算机图形学全套算法讲解和C++编码实现(共23讲配套源码),计算机图形学案例视频讲解以及主页相关算法。孔老师是我的代课老师,孔教授有十多年教学经验,视频课很不错,所有的源程序都基于他写的函数,并非小张写的。所有源程序都基于C+编译 参考教材《计算机图形学-理论与实践项目化教程》 孔令德著,大家多多支持哇 一、实验项目要求 1.设计立方体类,八个顶点的颜色定义为白、红、绿、黄、蓝、品红、青、黑 2.使用重心坐标算法,基于

张时贰的博客 1528

Red Hat Enterprise Linux 9.2

安装Red Hat Enterprise Linux 9.2

zhurobert的博客 943

星网宇达Newton-M2设备安装及配置

主要介绍了星网宇达Newton-M2设备的配置过程

weixin_49353445的博客 2679

计算机图形学

计算机图形学

ProgramNovice的博客 662

联想ThinkServer SR588 重装raid5阵列信息(装完centos7后,找不到硬盘)

这里写自定义目录标题找不到硬盘选择光盘启动 找不到硬盘 装完centos7之后,提示重启,重启之后,就一直无法启动。 进入bios 看了,确实是有设置硬盘为第一启动选项。 选择光盘启动 本地标准硬盘也是找不到。 1、 重启进入bios在系统手设置里找到存储信息, 然后找到如图选项回车进入。 选择主目录进入。 进入Configuration Management 里面 先清除原来的设置信息 选择已启用在yes 提示清除成功。 返回上一目录选择,选择 Create Virtual Drive 再选择S

熠铭心时空的博客 2万+

【OpenGL】绘制四边形

EBO、VBO和VAO的简介 思路 画一个四边形,可以有两种方法 1、通过2个三角形拼接而成,这就和前一个实验画三角形类似,利用VAO和VBO实验,我们要做的只是需要把给出的顶点增加为6个即可。 2、但是我们会发现使用上述方式,有两个顶点重复出现,这在画复杂图形时,会增加很多空间消耗,而上述介绍了通过EBO能存储顶点信息数量,从而减少顶点数组中顶点的个数。 下面介绍通过VAO+VBO+EB...

Do Better 3447

海康视觉算法平台VisionMaster 4.3.0 C# 二次开发01 加载方案并获取结果

第一次使用海康视觉算法平台VisionMaster 4.3.0,项目中要使用这个平台进行视觉处理并获取结果。

StevenChen的博客 7878

[3.4]【机器人运动学MATLAB实战分析】PUMA560机器人逆运动学MATLAB计算

PUMA560是六自由度关节型机器人,其6个关节都是转动副,属于6R型操作臂。各连杆坐标系如图1,连杆参数如表1所示。本文对PUMA560机器人逆运动学进行分析并MATLAB计算

m0_72676510的博客 1948

计算机图形学OpenGL学习笔记一:画三角形,正方形和球形

本笔记参考MOOC课程:华中科技大学 万琳老师的 《计算机图形学》 实验部分内容。 用OpenGL画一个简单三角形 教程连接: https://github.com/chenandongtime/OpenGL/blob/master/%E5%AE%9E%E9%AA%8C%EF%BC%9A%E7%BB%98%E5%88%B6%E4%B8%89%E8%A7%92%E5%BD%A2%EF%BC%88%E...

weixin_42376458的博客 4466

万字长文解密:SAP Fiori 首屏加载缓慢背后的真相

什么是一个健康理想的 Fiori 首次加载状态?FLP 首页不臃肿,用户默认看见的内容不多但足够用缓存作业按规则运行,冷启动不至于每次都从零开始应用首屏只读必要数据,UI5 资源经过 preload,视图异步加载OData 服务字段克制、分页合理、缓存分层清楚后台 CDS 与 HANA 只为当前屏幕做最必要的工作。只要这些标准同时满足,用户第一次打开 Fiori 页面的体感通常会从明显卡顿变成可接受甚至顺滑。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 559

计算机图形学实验教程,计算机图形学实验

时间:2019-05-12 06:42:24 作者:admin实验三 MFC画直线 最近自己在学习如何在VC 6.0 开发环境下的使用MFC AppWizard(exe)来绘画一条直线,虽然比较简单,通过这样的练习可以帮助你熟悉MFC的开发环境以及其中的消息传时间:2019-05-12 01:07:35 作者:admin实 验 报 告 一、 实验目的 1、掌握有序边表算法填充多边形区域; 2、理...

weixin_39862716的博客 447

TIBCO Jaspersoft Studio报表开发 使用教程-进阶版

本文学习内容容器定制二级目录三级目录 容器定制 二级目录 三级目录

吉哲的博客 7521

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

计算机图形学——实验一 VS+OpenGL绘图环境及基本图形绘制

VS+OpenGL绘图环境及基本图形绘制 1、 熟悉OpenGL的主要功能; 2、 掌握OpenGL的绘图流程和原理; 3、 掌握OpenGL核心函数的使用; 4、 熟悉OpenGL基本图形元素的绘制函数。 二. 实验内容 1、 如预备知识所述,创建一个OpenGL工程,修改第一个程序中的Display()函数,如下: 该程序是在窗口中画两条线,分别用黄色和红色绘制。如上所述,OpenGL是一个状态机,glBegin(UINT State)可以设定如下状态: GL_POINTS 画点 GL_LINES 画线

加载中....... 6021

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

上一篇: 计算机图形学 | 图形思维的起点——朴素的软光栅
下一篇: GitHub 上传大文件(>25 MB)教程
UestcXiye
博客等级 码龄8年 9032粉丝 1306原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UestcXiye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值