当前位置: 首页 > news >正文

哈密网站建设贺州市城乡住房建设厅网站

哈密网站建设,贺州市城乡住房建设厅网站,关键字排名软件官网,机械行业网站建设系列文章目录 LearnOpenGL 笔记 - 入门 01 OpenGLLearnOpenGL 笔记 - 入门 02 创建窗口LearnOpenGL 笔记 - 入门 03 你好#xff0c;窗口 文章目录系列文章目录前言你好#xff0c;三角形顶点输入顶点着色器#xff08;Vertex Shader#xff09;编译着色器片段着色器…系列文章目录 LearnOpenGL 笔记 - 入门 01 OpenGLLearnOpenGL 笔记 - 入门 02 创建窗口LearnOpenGL 笔记 - 入门 03 你好窗口 文章目录系列文章目录前言你好三角形顶点输入顶点着色器Vertex Shader编译着色器片段着色器Fragment Shader着色器程序链接顶点属性顶点数组对象VAO三角形元素缓冲对象前言 原文链接你好三角形本文代码2_1_hello_triangle.cpp 本文难度较大学习曲线突然陡峭了起来。但没有关系我将以一个初学者的视角来讲述自己的理解帮助你学习 VAO、VBO、EBO、Shader 等概念。首先仍然先以知识点列表的形式总结全文。 你好三角形 先记住三个单词 顶点数组对象Vertex Array ObjectVAO顶点缓冲对象Vertex Buffer ObjectVBO元素缓冲对象Element Buffer ObjectEBO 或 索引缓冲对象 Index Buffer ObjectIBO OpenGL 中所有事物都在 3D 空间而屏幕是 2D。3D坐标转为2D坐标的处理过程是由OpenGL的图形渲染管线图形渲染管线分为两个主要部分 3D坐标转换为2D坐标2D坐标转变为实际的有颜色的像素 图形渲染管线可分为几个阶段每个阶段将会把前一个阶段的输出作为输入。这些阶段容易并行执行。显卡中的核心运行着每个阶段的小程序这些小程序被叫做着色器Shader有些阶段的 Shader 可以有开发者来编写。OpenGL 着色器是用 OpenGL 着色器语言(OpenGL Shading Language, GLSL)写成的下图为渲染管线的每个阶段的抽象展示。蓝色部分可以输入自定义的 shader 管线的第一部分是顶点着色器(Vertex Shader)它输入一个顶点。作用是把 3D 坐标转为另一种 3D 坐标后面会解释同时顶点着色器允许我们对顶点属性进行一些基本处理。图元装配(Primitive Assembly)阶段将顶点着色器输出的所有顶点作为输入如果是GL_POINTS那么就是一个顶点并所有的点装配成指定图元的形状本节例子中是一个三角形。图元装配阶段的输出会传递给几何着色器(Geometry Shader)。几何着色器把图元形式的一系列顶点的集合作为输入它可以通过产生新顶点构造出新的或是其它的图元来生成其他形状。例子中它生成了另一个三角形。几何着色器的输出会被传入光栅化阶段(Rasterization Stage)这里它会把图元映射为最终屏幕上相应的像素生成供片段着色器(Fragment Shader)使用的片段(Fragment)。在片段着色器运行之前会执行裁切(Clipping)。裁切会丢弃超出你的视图以外的所有像素用来提升执行效率。片段着色器的主要目的是计算一个像素的最终颜色这也是所有OpenGL高级效果产生的地方。通常片段着色器包含3D场景的数据比如光照、阴影、光的颜色等等这些数据可以被用来计算最终像素的颜色。最终的对象将会被传到最后一个阶段我们叫做Alpha测试和混合(Blending)阶段。这个阶段检测片段的对应的深度和模板(Stencil)值后面会讲用它们来判断这个像素是其它物体的前面还是后面决定是否应该丢弃。这个阶段也会检查alpha值alpha值定义了一个物体的透明度并对物体进行混合(Blend)。所以即使在片段着色器中计算出来了一个像素输出的颜色在渲染多个三角形的时候最后的像素颜色也可能完全不同。在现代OpenGL中我们必须定义至少一个顶点着色器和一个片段着色器。 顶点输入 绘制图形需要顶点OpenGL 中顶点采用 3D 坐标即 xy 和 z范围在 [-1, 1] 之间我们称这个范围叫 标准化设备坐标(Normalized Device Coordinates)。在范围外的点不会显示。 float vertices[] {-0.5f, -0.5f, 0.0f,0.5f, -0.5f, 0.0f,0.0f, 0.5f, 0.0f };标准化设备坐标通过 glViewport 函数进行视口变化转换为屏幕空间坐标。vertices 中的点现在存放在内存中你的代码内存中我们需要将它们送至顶点着色器。顶点着色器会在显存中开辟一块空间来存放这些点。同时你要告诉 OpenGL 如何解释这些数据。顶点缓冲对象(Vertex Buffer Objects, VBO)负责管理这个显存。 unsigned int VBO; glGenBuffers(1, VBO);使用 glGenBuffers 创建 VBOglBindBuffer(GL_ARRAY_BUFFER, VBO); 将这个 VBO 绑定到 OpenGL Context 中的顶点缓冲对象。glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 将内存中数据复制到显存中 GL_STATIC_DRAW 数据不会或几乎不会改变。GL_DYNAMIC_DRAW数据会被改变很多。GL_STREAM_DRAW 数据每次绘制时都会改变。 顶点着色器Vertex Shader 现代OpenGL需要我们至少设置一个顶点和一个片段着色器。使用 GLSL(OpenGL Shading Language)编写顶点着色器。 #version 330 core layout (location 0) in vec3 aPos;void main() {gl_Position vec4(aPos.x, aPos.y, aPos.z, 1.0); }#version 330 core 声明版本和核心模式。OpenGL 3.3以及和更高版本中GLSL版本号和OpenGL的版本是匹配的。in 声明输入顶点属性Input Vertex Attributevec3 向量类型vec.x、vec.y、vec.z 获取不同分量gl_Position 是 Vertex Shader 的输出。我们必须把位置数据赋值给它。它是一个 vec4 类型 编译着色器 const char *vertexShaderSource R(#version 330layout (location 0) in vec3 aPos;layout (location 1) in vec3 bPos;void main(){gl_Position vec4(aPos.x, aPos.y, aPos.z, 1.0);} );auto vertexShader glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, vertexShaderSource, NULL); glCompileShader(vertexShader); glGetShaderiv(vertexShader, GL_COMPILE_STATUS, success); if (!success) {glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);std::cout ERROR::SHADER::VERTEX::COMPILATION_FAILED\n infoLog std::endl;return -1; }glCreateShader(GL_VERTEX_SHADER) 创建一个顶点着色器类型是 GL_VERTEX_SHADER 表明其类型。glShaderSource(vertexShader, 1,vertexShaderSource, NULL); 设置着色器对象的源码。glCompileShader(vertexShader); 编译该着色器。glGetShaderiv 检查是否编译成功 片段着色器Fragment Shader 片段着色器所做的是计算像素最后的颜色输出 #version 330 core out vec4 FragColor;void main() {FragColor vec4(1.0f, 0.5f, 0.2f, 1.0f); } 片段着色器只需要输出一个变量。使用 out 关键字定义该变量。编译片段着色器与编译顶点着色器类似 unsigned int fragmentShader; fragmentShader glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, fragmentShaderSource, NULL); glCompileShader(fragmentShader);着色器程序 着色器程序对象(Shader Program Object)是多个着色器合并之后并最终链接完成的版本。我们必须将多个编译好的着色器链接Link为一个着色器程序对象在渲染时激活它。 unsigned int shaderProgram; shaderProgram glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); glGetProgramiv(shaderProgram, GL_LINK_STATUS, success); if (!success) {glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog)std::cout ERROR::SHADER::PROGRAM::LINKING_FAILED\n infoLog std::endl;return -1; } glDeleteShader(vertexShader); glDeleteShader(fragmentShader);glUseProgram(shaderProgram);glCreateProgram 创建着色器程序对象glAttachShader 将顶点着色器和片段着色器附加到程序对象上程序对象属性的修改glLinkProgram(shaderProgram); 链接它们。glUseProgram(shaderProgram); 将该程序对象绑定至 OpenGL Context激活它。glDeleteShaderLink 以后记得删除着色器对象我们不再需要它们了。 链接顶点属性 之前我们通过 VBO 将一堆数据送给了顶点着色器。允许我们指定任何以顶点属性为形式的输入。这具有很强的灵活性还意味着我们必须手动指定输入数据的哪一个部分对应顶点着色器的哪一个顶点属性。 glVertexAttribPointer 告诉 OpenGL 如何解释 VBO 中的数据glEnableVertexAttribArray 启用顶点属性顶点属性默认是禁用的。 顶点数组对象VAO OpenGL的核心模式要求我们使用VAO所以它知道该如何处理我们的顶点输入。如果我们绑定VAO失败OpenGL会拒绝绘制任何东西。一个顶点数组对象会储存以下这些内容 glEnableVertexAttribArray和glDisableVertexAttribArray的调用。通过glVertexAttribPointer设置的顶点属性配置。通过glVertexAttribPointer调用与顶点属性关联的顶点缓冲对象。 glGenVertexArrays 创建 VAO使用 VAO 和 VBO 绘制图形流程如下 // ..:: 初始化代码只运行一次 (除非你的物体频繁改变) :: .. // 1. 绑定VAO glBindVertexArray(VAO); // 2. 把顶点数组复制到缓冲中供OpenGL使用 glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // 3. 设置顶点属性指针 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); glEnableVertexAttribArray(0);[...]// ..:: 绘制代码渲染循环中 :: .. // 4. 绘制物体 glUseProgram(shaderProgram); glBindVertexArray(VAO); someOpenGLFunctionThatDrawsOurTriangle();三角形 glUseProgram(shaderProgram); glBindVertexArray(VAO); glDrawArrays(GL_TRIANGLES, 0, 3);glDrawArrays函数它使用当前激活的着色器之前定义的顶点属性配置和VBO的顶点数据通过VAO间接绑定来绘制图元 元素缓冲对象 绘制一个矩形需要 4 个顶点但 glDrawArrays 只能绘制点、线、和三角形。并不能绘制矩形。幸运的是你可以绘制两个三角形来达成这个目的。顶点如下 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 // 左上角 };指定右下角和左上角两次一个矩形只有4个而不是6个顶点这样就产生50%的额外开销。更好的解决方案是只储存不同的顶点并设定绘制这些顶点的顺序。这样子我们只要储存4个顶点就能绘制矩形了。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 // 左上角 };unsigned int indices[] {// 注意索引从0开始! // 此例的索引(0,1,2,3)就是顶点数组vertices的下标// 这样可以由下标代表顶点组合成矩形0, 1, 3, // 第一个三角形1, 2, 3 // 第二个三角形 }; unsigned int EBO; glGenBuffers(1, EBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);使用 glDrawElements 使用当前绑定的索引缓冲对象中的索引进行绘制。
http://www.tj-hxxt.cn/news/228682.html

相关文章:

  • 广告联盟没有网站怎么做汕头网页设计
  • 沈阳餐饮网站建设网站开发工具 比较好
  • linux做网站配置小程序加盟代理平台
  • 在演示文稿上网站怎么做淘宝客网站模块
  • 辽宁省网站备案系统小说网站开发思路
  • 电影网站盗链怎么做南昌模板建站定制
  • 深圳哪些设计公司做网站比较出名国内做网站的企业
  • 公司网站 建设福州网站搜索引擎优化
  • 网站创建教程自助建手机网站免费
  • 咸宁网站制作培训去香洲会变黄码吗
  • 楼盘价格哪个网站做的好嘉定网站建设电脑培训
  • 深圳网站设计师天津在哪做网站
  • 公司网站建设苏州劳伦wordpress如何双语
  • 老外做的汉语网站discuz论坛系统
  • 网站转移服务器需要重新备案吗山东省建设管理中心网站首页
  • 如何给网站做证书wordpress term id
  • 网站设计制作哪个公司的好网页小游戏代码
  • 莆田建设项目环境网站各大网站网址目录
  • 建设银行网站用户名是什么竞价托管 微竞价
  • 后台网站模板下载网页版梦幻西游五色石
  • 设计师接私活的兼职平台网络营销优化培训
  • 厦门app网站建设网站建设的er图
  • 网站建设评审标准wordpress目录浏览漏洞
  • 网站建设广告wordpress 总访问量
  • 网站推广自己可以做吗做h5小程序的网站
  • 网站基础功能google网页版入口
  • 网站生成公司品牌推广公司
  • 服务器上配置网站海南seo顾问服务
  • 关于网站建设方案怎样开公司
  • 厦门专业的网站建设中国香烟网上商城