(七)glDrawArry绘制

news2024/11/17 6:28:45

几何数据:vao和vbo
材质程序:vs和fs(顶点着色器和片元着色器)
接下来只需要告诉GPU,使用几何数据和材质程序来进行绘制。

#include <glad/glad.h>//glad必须在glfw头文件之前包含
#include <GLFW/glfw3.h>
#include <iostream>

void frameBufferSizeCallbakc(GLFWwindow* window, int width, int height)
{
	glViewport(0, 0, width, height);
}
void glfwKeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
}

GLuint program = 0;
GLuint vao = 0;
void prepareInterleavedBuffer() {
	//1 准备好Interleaved数据(位置+颜色)
	float vertices[] = {
		   -0.5f, -0.5f, 0.0f,  1.0f, 0.0f, 0.0f,
			0.5f, -0.5f, 0.0f,  0.0f, 1.0f, 0.0f,
			0.0f,  0.5f, 0.0f,  0.0f,  0.0f, 1.0f
	};


	//2 创建唯一的vbo
	GLuint vbo = 0;
	glGenBuffers(1, &vbo);
	glBindBuffer(GL_ARRAY_BUFFER, vbo);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

	//3 创建并绑定vao
	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);


	glBindBuffer(GL_ARRAY_BUFFER, vbo);
	//4 为vao加入位置和颜色的描述信息
	//4.1 位置描述信息
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);

	//4.2 颜色描述信息
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));

	//5 扫尾工作:解绑当前vao
	glBindVertexArray(0);
}
void prepareVAOForGLTriangles() {
	//1 准备positions
	float positions[] = {
		-0.5f, -0.5f, 0.0f,
		0.5f, -0.5f, 0.0f,
		0.0f,  0.5f, 0.0f,
		0.5f,  0.5f, 0.0f,
		0.8f,  0.8f, 0.0f,
		0.8f,  0.0f, 0.0f
	};
	//2  posVbo
	GLuint posVbo;
	glGenBuffers(1, &posVbo);

	glBindBuffer(GL_ARRAY_BUFFER, posVbo);
	glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);

	//3 生成vao并且绑定
	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);

	//4 描述位置属性
	glBindBuffer(GL_ARRAY_BUFFER, posVbo);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);

	glBindVertexArray(0);
}
void prepareShader() {
	//1 完成vs与fs的源代码,并且装入字符串
	const char* vertexShaderSource =
		"#version 330 core\n"
		"layout (location = 0) in vec3 aPos;\n"
		"void main()\n"
		"{\n"
		"   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
		"}\0";
	const char* fragmentShaderSource =
		"#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";


	//2 创建Shader程序(vs、fs)
	GLuint vertex, fragment;
	vertex = glCreateShader(GL_VERTEX_SHADER);
	fragment = glCreateShader(GL_FRAGMENT_SHADER);


	//3 为shader程序输入shader代码
	glShaderSource(vertex, 1, &vertexShaderSource, NULL);
	glShaderSource(fragment, 1, &fragmentShaderSource, NULL);

	int success = 0;
	char infoLog[1024];
	//4 执行shader代码编译 
	glCompileShader(vertex);
	//检查vertex编译结果
	glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
	if (!success) {
		glGetShaderInfoLog(vertex, 1024, NULL, infoLog);
		std::cout << "Error: SHADER COMPILE ERROR --VERTEX" << "\n" << infoLog << std::endl;
	}

	glCompileShader(fragment);
	//检查fragment编译结果
	glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
	if (!success) {
		glGetShaderInfoLog(fragment, 1024, NULL, infoLog);
		std::cout << "Error: SHADER COMPILE ERROR --FRAGMENT" << "\n" << infoLog << std::endl;
	}

	//5 创建一个Program壳子
	program = glCreateProgram();

	//6 将vs与fs编译好的结果放到program这个壳子里
	glAttachShader(program, vertex);
	glAttachShader(program, fragment);

	//7 执行program的链接操作,形成最终可执行shader程序
	glLinkProgram(program);

	//检查链接错误
	glGetProgramiv(program, GL_LINK_STATUS, &success);
	if (!success) {
		glGetProgramInfoLog(program, 1024, NULL, infoLog);
		std::cout << "Error: SHADER LINK ERROR " << "\n" << infoLog << std::endl;
	}

	//清理
	glDeleteShader(vertex);
	glDeleteShader(fragment);
}

void render()
{
	//执行opengl画布清理操作
	glClear(GL_COLOR_BUFFER_BIT);

	//1.绑定当前的program
	glUseProgram(program);
	//2 绑定当前的vao
	glBindVertexArray(vao);
	//3 发出绘制指令
	glDrawArrays(GL_TRIANGLES, 0, 3);

}


int main()
{
	//初始化glfw环境
	glfwInit();
	//设置opengl主版本号
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	//设置opengl次版本号
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	//设置opengl启用核心模式
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

	//创建窗体对象
	GLFWwindow* window = glfwCreateWindow(800, 600, "lenarnOpenGL", nullptr, nullptr);
	//设置当前窗体对象为opengl的绘制舞台
	glfwMakeContextCurrent(window);
	//窗体大小回调
	glfwSetFramebufferSizeCallback(window, frameBufferSizeCallbakc);
	//键盘相应回调
	glfwSetKeyCallback(window, glfwKeyCallback);

	//使用glad加载所有当前版本opengl的函数
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
	{
		std::cout << "初始化glad失败" << std::endl;
		return -1;
	}
	;
	//设置opengl视口大小和清理颜色
	glViewport(0, 0, 800, 600);
	glClearColor(0.2f, 0.3f, 0.3f, 1.0f);

	//着色器
	prepareShader();
	//vao
	prepareInterleavedBuffer();

	//执行窗体循环
	while (!glfwWindowShouldClose(window))
	{
		//接受并分发窗体消息
		//检查消息队列是否有需要处理的鼠标、键盘等消息
		//如果有的话就将消息批量处理,清空队列
		glfwPollEvents();
		//渲染操作
		render();
		//切换双缓存
		glfwSwapBuffers(window);
	}

	//推出程序前做相关清理
	glfwTerminate();
	return 0;
}

glUseProgram:设置使用的shader程序
glBindVertexArray:绑定使用的VAO几何信息

glDrawArrays(GLenum mode, GLint first, GLsizei count);

mode:绘制模式
first:从第几个顶点数据开始绘制
count:绘制到第几个顶点数据
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1884644.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

英伟达经济学:云服务商在GPU上每花1美元 就能赚7美元

NVIDIA超大规模和 HPC 业务副总裁兼总经理 Ian Buck 近日在美国银行证券 2024 年全球技术大会上表示&#xff0c;客户正在投资数十亿美元购买新的NVIDIA硬件&#xff0c;以跟上更新的 AI 大模型的需求&#xff0c;从而提高收入和生产力。 Buck表示&#xff0c;竞相建设大型数据…

flask中解决图片不显示的问题(很细微的点)

我在编写flask项目的时候&#xff0c;在编写html的时候&#xff0c;发现不管我的图片路径如何变化&#xff0c;其就是显示不出来。如下图我框中的地方。 我尝试过使用浏览器打开&#xff0c;是可以的。 一旦运行这个flask项目&#xff0c;就无法显示了。 我查阅资料后。发现…

Kafka-时间轮和延迟操作-源码流程

TimingWheel 字段&#xff1a; buckets&#xff1a;Array.tabulate[TimerTaskList]类型&#xff0c;其每一个项都对应时间轮中的一个时间格&#xff0c;用于保存 TimerTaskList的数组。在TimingWheel中&#xff0c;同一个TimerTaskList中的不同定时任务的到期时间可能 不同&a…

【Dison夏令营 Day 06】用 Python 和 Rich 制作 Wordle克隆(中篇)

在大流行期间&#xff0c;Wordle 在 Twitter 上还算比较流行的一款基于网络的益智游戏&#xff0c;要求玩家每天在六次或更短时间内猜出一个新的五个字母的单词&#xff0c;每个人得到的单词都是一样的。 在本教程中&#xff0c;你将在终端上创建自己的 Wordle 克隆。自 2021 …

【Qt】认识Qt界面Hello world小程序

一.认识Qt界面 1.左边栏 在编辑模式下&#xff0c;左边竖排的两个窗⼝叫做 "边栏" 。 ① 是项⽬⽂件管理窗⼝ ② 是打开⽂件列表窗⼝。 边栏⾥的窗⼝数⽬可以增加&#xff0c;边栏⼦窗⼝标题栏有⼀排⼩按钮&#xff0c;最右边的是关闭按钮&#xff0c;倒数第⼆个是 …

分布式限流:Spring Cloud Gateway 限流

分布式限流&#xff1a;Spring Cloud Gateway 限流 在现代微服务架构中&#xff0c;流量控制是一个至关重要的部分。分布式限流作为一种有效的流量控制手段&#xff0c;能够帮助我们保护系统不被突发的流量冲垮。Spring Cloud Gateway支持多种限流方式。 什么是分布式限流 分…

电影交流平台小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;电影类型管理&#xff0c;留言反馈管理&#xff0c;电影中心管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;电影中心&#xff0c;留言反馈 开发系统&#xff1a;Window…

适用于高海拔地区的工业路由器产品

1、西藏背景 西藏&#xff0c;这个位于中国西南部的神秘之地&#xff0c;以其雄伟壮观、神奇瑰丽的自然风光和深厚的文化底蕴&#xff0c;被无数人视为心中的圣地。这里属于高原性气候&#xff0c;具有气温低、气压低&#xff0c;降水少&#xff0c;生态环境十分恶劣。西藏被誉…

Spring Boot集成DeepLearning4j实现图片数字识别

1.什么是DeepLearning4j&#xff1f; DeepLearning4J&#xff08;DL4J&#xff09;是一套基于Java语言的神经网络工具包&#xff0c;可以构建、定型和部署神经网络。DL4J与Hadoop和Spark集成&#xff0c;支持分布式CPU和GPU&#xff0c;为商业环境&#xff08;而非研究工具目的…

《Windows API每日一练》7.4 状态报告上使用计时器

这一节我们使用计时器&#xff0c;每隔一秒获取当前鼠标坐标位置的像素值&#xff0c;并显示在窗口&#xff0c;这就相当于是一个简单的取色器了。 本节必须掌握的知识点&#xff1a; 第47练&#xff1a;取色器 7.4.1 第47练&#xff1a;取色器 /*----------------------------…

商家团购app微信小程序模板

手机微信商家团购小程序页面&#xff0c;商家订餐外卖小程序前端模板下载。包含&#xff1a;团购主页、购物车订餐页面、我的订单、个人主页等。 商家团购app微信小程序模板

昇思25天学习打卡营第13天|ResNet50图像分类

1. 学习内容复盘 图像分类是最基础的计算机视觉应用&#xff0c;属于有监督学习类别&#xff0c;如给定一张图像(猫、狗、飞机、汽车等等)&#xff0c;判断图像所属的类别。本章将介绍使用ResNet50网络对CIFAR-10数据集进行分类。 ResNet网络介绍 ResNet50网络是2015年由微软…

使用Git从Github上克隆仓库,修改并提交修改

前言 本次任务主要是进行github提交修改的操作练习实践&#xff0c;本文章是对实践过程以及遇到的问题进行的一个记录。 在此之前&#xff0c;我已经简单使用过github&#xff0c;Git之前已经下好了&#xff0c;所以就省略一些步骤。 步骤记录 注册github账号&#xff0c;gi…

PS系统教程31

调色之色阶 调色与通道最基本的关系通道是记录颜色最基本的信息有些图片可以用通道去改变颜色信息的说明这些图像是比较高级的PS是一款图像合成软件&#xff0c;在合成过程中需要处理大量素材&#xff0c;比如要用这些素材进行抠背景&#xff0c;就要用到图层蒙版以及Alpha通道…

Go语言--格式化输出输入、类型转换

格式说明 %T操作变量所属类型自动匹配格式的不一定很正确&#xff0c;尤其是字符类型&#xff0c;本应该是整型&#xff0c;实际上他会输出数字 输入 阻塞等待用户的输入 fmt.Scanf("%d", &a)fmt.Scan(&b)不需要写格式&#xff0c;自动匹配 类型转换 类…

深入学习 Kafka(1)- 核心组件

组件概述 1. Producer&#xff08;消息生产者&#xff09; 核心作用&#xff1a;生成数据源&#xff0c;将消息发送至指定Topic。关键特性&#xff1a;支持批量发送、分区策略选择&#xff0c;以及可配置的重试逻辑&#xff0c;提高了数据传输效率和可靠性。 2. Topic&#x…

iptable精讲

SNAT策略 SNAT策略的典型应用环境 局域网主机共享单个公网IP地址接入Internet SNAT策略的原理 源地址转换&#xff0c;Source Network Address Translantion 修改数据包的源地址 部署SNAT策略 1.准备二台最小化虚拟机修改主机名 主机名&#xff1a;gw 主机名&#xff1…

SpringBoot 项目整合 MyBatisPlus 框架,附带测试示例

文章目录 一、创建 SpringBoot 项目二、添加 MyBatisPlus 依赖三、项目结构和数据库表结构四、项目代码1、application.yml2、TestController3、TbUser4、TbUserMapper5、TestServiceImpl6、TestService7、TestApplication8、TbUserMapper.xml9、MyBatisPlusTest 五、浏览器测试…

云服务出现故障这样处理

无法连接云服务器 服务器远程无法连接时&#xff0c;可通过7ECloud控制台进行连接。 常见故障现象 1、ping不通 2、ping丢包 3、部分端口telnet不通 4、全部端口telnet不通 5、广告、弹窗植入 6、域名无法访问IP访问正常 常见故障原因 1、云服务器过期、关机或者EIP被…

【技巧】ArcgisPro 字段计算器内置函数方法的调用

在arcgisPro中&#xff0c;内置了常用的几种函数方法&#xff0c;如顺序编号&#xff0c;重分类等&#xff1b;调用方法如下&#xff1a;