glDrawArrays,glDrawElements用法

2023-11-02

 glDrawArrays 和 glDrawElements 的作用都是从一个数据数组中提取数据渲染基本图元。( render primitives from array data )

 
 
注!如果要 glDrawArrays 和 glDrawElements 正确进行绘制的话,必须在之前 调用带有相应参数的 glEnableClientState 方法。 比如:

/* Enable vertex arrays. */
glEnableClientState( GL_VERTEX_ARRAY );
/* Enable texture arrays. */
glEnableClientState( GL_TEXTURE_COORD_ARRAY );


 
这两个方法的第一个形参都是代表 绘制模式(GLenum mode)。绘图模式有如下几种:
GL_POINTS
GL_LINES
GL_LINE_LOOP
GL_LINE_STRIP
GL_TRIANGLES
GL_TRIANGLE_STRIP
GL_TRIANGLE_FAN
 
我们还没有讨论点或线,所以我只介绍最后的三个 。
在我开始之前,我要提醒你,顶点数组可能包含不止一个三角形,以便当您只看到一个物体顶点数组,你要知道,不仅限于这一点。
 
假设我们有如下的顶点数据:

const GLfloat squareVertices[] = {
    -1.0,  1.0, -6.0, 
// Top left
    -1.0, -1.0, -6.0, 
// Bottom left
    1.0,  -1.0, -6.0, 
// Bottom right
    1.0,   1.0, -6.0  
// Top right
};

 
GL_POINTS - 单独的将顶点画出来。
 
GL_LINES - 单独地将直线画出来。行为和 GL_TRIANGLES 类似。

GL_LINE_STRIP - 连贯地将直线画出来。行为和 GL_TRIANGLE_STRIP 类似。
 
GL_LINE_LOOP - 连贯地将直线画出来。行为和 GL_LINE_STRIP 类似,但是会自动将最后一个顶点和第一个顶点通过直线连接起来。
 
GL_TRIANGLES - 这个参数意味着OpenGL使用三个顶点来组成图形。所以,在开始的三个顶点,将用顶点1,顶点2,顶点3来组成一个三角形。完成后,在用下一组的三个顶点(顶点4,5,6)来组成三角形,直到数组结束。

 
GL_TRIANGLE_STRIP - OpenGL的使用将最开始的两个顶点出发,然后遍历每个顶点,这些顶点将使用前2个顶点一起组成一个三角形。
所以 squareVertices[6~8]{1.0, -1.0, 6.0} 将与 squareVerticies[0~2]{-1.0, 1.0, -6.0} 和 squareVerticies[3~5]{-1.0, -1.0, -6.0} 生成一个三角形。
squareVertices[9~11]{1.0, 1,0, -6.0} 将与  squareVertices[3~5]{-1.0, -1.0, -6.0} 和squareVertices[6~8]{1.0, -1.0, 6.0} 生成三角形。
 
也就是说,P0,P1,P2这三个点组成一个三角形,P1,P2,P3这三个点也组成一个三角形。
 
注意的是, squareVerticies[0~2]表示的意思是:
squareVerticies[0] x坐标
squareVerticies[1] y坐标
squareVerticies[2] z坐标
 
 
GL_TRIANGLE_FAN - 在跳过开始的2个顶点,然后遍历每个顶点,让OpenGL将这些顶点于它们前一个,以及数组的第一个顶点一起组成一个三角形。 squareVertices[6~8]{1.0, -1.0, 6.0} 将与 squareVerticies[3~5]{-1.0, -1.0, -6.0} (前一个)和 squareVerticies[0~2]{-1.0, 1.0, -6.0}(第一个).生成一个三角形。
 
也就是说,同样是P0,P1,P2,P3 这4个顶点。
1) 在 GL_TRIANGLE_STRIP 状态下是: P2、P1、P0 ; P3、P2、P1 这2个三角形。
2) 在 GL_TRIANGLE_FAN   状态下是: P2、P1、P0 ; P3、P2、P0 这2个三角形。
 
 
 
1.1 glDrawArrays 方法介绍
 
Description

glDrawArrays specifies multiple geometric primitives with very few subroutine calls. You can prespecify separate arrays of vertices, normals, colors, and texture coordinates and use them to construct a sequence of primitives with a single call to glDrawArrays.
 
When glDrawArrays is called, it uses count sequential elements from each enabled array to construct a sequence of geometric primitives, beginning with element first. mode specifies what kind of primitives are constructed, and how the array elements construct those primitives. If GL_VERTEX_ARRAY is not enabled, no geometric primitives are generated.
 
Vertex attributes that are modified by glDrawArrays have an unspecified value after glDrawArrays returns. For example, if GL_COLOR_ARRAY is enabled, the value of the current color is undefined after glDrawArrays executes. Attributes that aren't modified remain well defined.



示例代码:

glEnableClientState(GL_VERTEX_ARRAY);
    
const GLfixed vers[] = {
        F2X(0.25), F2X(0.25), F2X(0.0), 
        F2X(0.75), F2X(0.25), F2X(0.0), 
        F2X(0.25), F2X(0.75), F2X(0.0), 
        F2X(0.75), F2X(0.75), F2X(0.0), 
}
;

glVertexPointer(3, GL_FIXED, 0, vers);
    
glDrawArrays(GL_LINE_STRIP, 0, 4);
    
eglSwapBuffers(iGlDisp, iGlSurface);



结果:
 

 
  
1.2 glDrawElements 是一个OPENGL的图元绘制函数,从数组中获得数据并渲染图元。
函数原型为:
void glDrawElements( 
        GLenum mode, 
        GLsizei count,
        GLenum type, 
        const GLvoid *indices
        );
其中:
    mode 指定绘制图元的类型,但是如果GL_VERTEX_ARRAY 没有被激活的话,不能生成任何图元。它应该是下列值之一:
        GL_POINTS, GL_LINE_STRIP, 
        GL_LINE_LOOP, GL_LINES, 
        GL_TRIANGLE_STRIP, 
        GL_TRIANGLE_FAN, 
        GL_TRIANGLES, 
        GL_QUAD_STRIP, 
        GL_QUADS, 
        GL_POLYGON

         
    count 为绘制图元的数量。
    type 为索引数组(indices)中元素的类型,只能是下列值之一: 
        GL_UNSIGNED_BYTE, 
        GL_UNSIGNED_SHORT, 
        GL_UNSIGNED_INT

        
    indices:指向索引数组的指针。

glDrawElements函数能够通过较少的函数调用绘制多个几何图元,而不是通过OPENGL函数调用来传递每一个顶点,法线,颜色信息。
 
你可以事先准备一系列分离的顶点、法线、颜色数组,并且调用一次glDrawElements把这些数组定义成一个图元序列。
 
当调用glDrawElements函数的时候,它将通过索引使用count个成序列的元素来创建一系列的几何图元。
 
glDrawElements修改的顶点属性在glDrawElements调用返回后的值具有不确定性。

例如,在 GL_COLOR_ARRAY 被激活后,当glDrawElements执行完成时,当前的颜色值是没有指定的。没有被修改的属性值保持不变。
 
可以在显示列表中包含 glDrawElements,当glDrawElements被包含进显示列表时,相应的顶点、法线、颜色数组数据也得进入显示列表的,因为那些数组指针是ClientSideState的变量,在显示列表创建的时候而不是在显示列表执行的时候,这些数组指针的值影响显示列表。
 
glDrawElements 只能用在 OPENGL1.1 或者更高的版本。

示例代码如下:

// The vertex array is enabled for writing and used during rendering.
glEnableClientState(GL_VERTEX_ARRAY); 

// 顶点坐标数组
const GLfixed vers[] = {
        F2X(0.25), F2X(0.25), F2X(0.0), 
// 第1个顶点坐标
        F2X(0.75), F2X(0.25), F2X(0.0), 
// 第2个顶点坐标
        F2X(0.25), F2X(0.75), F2X(0.0), 
// 第3个顶点坐标
        F2X(0.75), F2X(0.75), F2X(0.0)  
// 第4个顶点坐标
};


glVertexPointer(
        3,        
// 表示每一个顶点由3维坐标构成
        GL_FIXED, 
// 顶点坐标数组中的元素是 GL_FIXED 类型
        0,        
// 从顶点坐标数组的第0个元素开始读取数据
        vers      
// 指向顶点坐标数组的指针
        );

// 等效替换 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4) ++

/* 索引数组. 此索引数组表示依次是
第0个顶点{F2X(0.25), F2X(0.25), F2X(0.0)},
第1个顶点{F2X(0.75), F2X(0.25), F2X(0.0)},
第2个顶点{F2X(0.25), F2X(0.75), F2X(0.0)},
第3个顶点{F2X(0.75), F2X(0.75), F2X(0.0)} */

const GLubyte indices[] = {0, 1, 2, 3};

glDrawElements(
        GL_TRIANGLE_STRIP, 
// 绘图模式
        4,                 
// 依次从索引数组中读取4个顶点来进行绘制
        GL_UNSIGNED_BYTE,  
// 索引数组中存放的元素的类型
        indices            
// 指向索引数组的指针
        );

// 等效替换 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4) --

eglSwapBuffers(iGlDisp, iGlSurface);



转自:http://hwcrazy.com/7d354b48702f11e187c2000d601c5586/


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

glDrawArrays,glDrawElements用法 的相关文章

  • 延迟阴影映射 GLSL

    我目前正在实施延迟渲染管道 但我仍坚持使用阴影贴图 我已经成功地将其实施到前向管道中 我所做的步骤是 获取灯光视图中的位置 转换为光视图剪辑空间 使用 0 5 0 5 获取阴影纹理坐标 检查深度 编辑 使用新结果图像更新代码 float c
  • GLSL聚光投影体积

    在我的开源项目中 我使用 Qt3D 设置了延迟渲染管道 到目前为止一切顺利 但现在我想通过添加聚光灯投影量来继续前进 例如场景中好像有烟雾 像这样 我正在使用的片段着色器位于问题的末尾 我读过 对于每个片段 我应该从光位置进行光线行进并找到
  • 渲染缓冲区大于窗口大小 - OpenGL

    我正在尝试绘制大于屏幕尺寸 即 320x480 的渲染缓冲区 512x512 执行 glReadPixels 后 图像看起来是正确的 除非图像的尺寸超过了屏幕尺寸 在本例中 超过了水平 320 和垂直 480 是什么原因导致这种异常现象呢
  • 如何在opengl中使用四元数绕屏幕中心旋转?

    我正在尝试实现轨迹球 轨迹球旋转 但我的中心有问题 回转 无论如何 我希望中心成为屏幕的中心 让我解释一下到目前为止我所做的事情 我创建了一个四元数 旋转轴 向量起点x向量结束 角度 向量起点 向量结束 从该四元数中 我创建了一个旋转矩阵
  • 在 libgdx 中批处理多维数据集时出现问题

    我正在尝试开发一款游戏 在屏幕上渲染多达 300 个立方体 为每个多维数据集创建新的 modelInstance 时 modelBatch 的性能非常糟糕 据我所知 没有 3d 批处理可以将所有立方体批处理到一次绘制调用 所以我拼命地尝试以
  • 如何在多采样纹理上渲染帧缓冲区对象?

    我目前有一个使用多个通道的渲染引擎 其中图像的各个部分在纹理上渲染 然后使用着色器进行组合 它有效 现在我想激活多重采样 我在这里读到 http www opengl org wiki Framebuffer Object Examples
  • 与整数纹理进行 Alpha 混合以进行对象拾取

    问题描述 你好 在我们的 WebGL 应用程序中 我们正在绘制许多 甚至数十万 形状 并且我们想要发现当前鼠标位于哪个形状 我正在寻找一种有效的方法 Details 形状定义为有符号距离函数 https en wikipedia org w
  • 计算任意网格的平面 UV 坐标

    我有从二维形状生成三角形网格的代码 因为在大多数情况下 这些形状在表面上的顶点分布不均匀 所以我在生成 UV 时遇到了问题 这样就不会导致纹理扭曲 任何人都可以推荐一些讨论平面网格上 UV 计算技术的文章 书籍 代码示例吗 谢谢 好的 让我
  • 在 R 中绘制 3D 数据

    我有一个 3D 数据集 data data frame x rep c 0 1 0 2 0 3 0 4 0 5 each 5 y rep c 1 2 3 4 5 5 data z runif 25 min data x data y 0 1
  • 使用 gl_FragColor 与 vec4 颜色?

    似乎有很多不明确的地方gl FragColor被弃用 例如 它缺失在GLSL 4 40 规范 https www khronos org registry OpenGL specs gl GLSLangSpec 4 40 pdf 但它包含在
  • OpenGL纹理渲染与原始不匹配

    我正在尝试使用 OpenGL 渲染纹理 我用作测试的纹理是白色背景上的一堆黑色矩形 如下所示 然而 在渲染时 纹理似乎被复制并叠加在其自身之上多次 我使用以下方法设置场景 std string vertexSource ShaderLoad
  • OpenGL 与 OpenCL,选择哪个以及为什么?

    哪些功能使 OpenCL 能够独特地选择 OpenGL 和 GLSL 进行计算 尽管有与图形相关的术语和不实用的数据类型 OpenGL 是否有任何真正的警告 例如 可以通过使用其他纹理将 a 渲染到纹理来完成并行函数评估 减少操作可以通过迭
  • 无法在 Linux 的 NetBeans 中编译 C++ 和 OpenGL (GLFW) 的简单源代码

    我开始学习 OpenGL glfw 我从教程中复制源代码并尝试编译它 但出现了错误 我想我已经正确安装了所有头文件 glm glfw 等 这是我的来源 我没有在头文件中使用这些字符 include iostream include stdi
  • GLSL memoryBarrierShared() 有用吗?

    我想知道 memoryBarrierShared 的用处 事实上 当我查找屏障功能的文档时 我读到 对于计算着色器中任何给定的静态屏障实例 单个工作组内的所有调用都必须进入该实例 然后才能允许任何调用继续超出该实例 这确保了在给定的屏障静态
  • OpenGL/GLSL - 纹理过滤的实现

    我想在 GLSL 着色器中自己实现纹理过滤 min 和 magfilter 因为我想使用 image load and store 而不是采样器 而且我想以特殊方式处理未定义的像素 并且我正在寻找一篇文章或者这样讨论过滤过程 我记得如何从我
  • 3D 图形批处理

    很多网站 文章都说 批量 批 批 有人可以解释一下着色器中的 批处理 代表什么吗 即 是否 改变纹理 更改任意着色器变量 意味着某些东西不能 批处理 最简单的总结方法就是尝试尽可能少地调用 API 来绘制您需要绘制的内容 使用顶点数组或 V
  • sRGB 纹理。它是否正确?

    我最近阅读了一些有关 sRGB 格式以及它们如何允许硬件自动对典型显示器执行色彩校正的文章 作为我阅读的一部分 我发现您可以使用普通纹理和返回结果上的 pow 函数来模拟此步骤 无论如何 我想问两个问题 因为我以前从未使用过此功能 首先 有
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲
  • Libgdx SpriteBatch.draw() 指定 4 个顶点

    我正在使用 libGdx 创建一个 2d 游戏 并尝试使用这个特殊的方法来绘制一个简单的 2d 纹理 分别指定 4 个顶点 draw Texture texture float spriteVertices int offset int l

随机推荐

  • 【机器学习】KS值

    KS检验 风控角度 分类模型评判指标 KS曲线与KS值 从统计角度 我们知道KS是分析两组数据分布是否相同的检验指标 在金融领域中 我们的y值和预测得到的违约概率刚好是两个分布未知的两个分布 好的信用风控模型一般从准确性 稳定性和可解释性来
  • Spring创建Bean的全过程(一)

    Spring测试环境搭建 Spring模块概览 Spring中八大模块 黑色表示该模块的jar包 也就是组件 例如我们想要使用IOC容器 也就是绿色的CoreContainer 我们需要导入Beans Core Context SpEL s
  • Python+微信小程序开发实战课

    本套课程Python结合微信小程序开发实战 由前汽车之家架构师武沛齐老师主讲 共分为18天的课程 文件大小共计9G 课程除了讲解微信小程序开发的基础知识点外 更多的是示例演示 让大家知道如何灵活运用这些知识点 真正学到能够运用到具体开发工作
  • Unity3D Shader之路 写Shader前必须要知道的事情3 ShaderForge的简单使用

    版本 unity 5 4 1 语言 Unity Shader Shader Forge版本 1 32 总起 在具体介绍Shader之前准备再写一篇有关于ShaderForge的 虽然我们可能使用代码来直接编写Shader 但拥有Shader
  • python基础——列表推导式

    python基础 列表推导式 文章目录 python基础 列表推导式 一 实验目的 二 实验原理 三 实验环境 四 实验内容 五 实验步骤 一 实验目的 掌握Python数据结构 列表推导式的用法 二 实验原理 列表推导式 list com
  • 「Python 基础」常用模块

    文章目录 1 内建模块 datetime collections namedtuple deque defaultdict OrderedDict ChainMap Counter base64 struct hashlib 摘要算法 摘要
  • Tomcat的基本认识和使用

    服务器 安装了服务器软件的计算机 通常都是高配置的计算机 服务器软件 接收用户的请求 处理请求 做出响应 web服务器软件 通过浏览器来进行访问的一种服务器软件 在web服务器软件中 可以部署web项目 让用户通过浏览器来访问这些项目 常见
  • 常见泰勒展开公式及复杂泰勒展开求法

    目录 https blog csdn net weixin 45792450 article details 104404432 初等的函数泰勒展开 e x e x ex e
  • 【OpenCv】相机标定介绍及python/c++实现

    针孔相机内外参标定简单介绍 之前有一个项目需要公司标内参 之前对这方面没有接触过 网上找了很多资料 记录下相机标定的基础知识 文章是个人浅显理解 如有错误还请指正 非常感谢 参考链接 坐标系转换 相机参数标定 camera calibrat
  • keil4 编译提示 ERROR L107: ADDRESS SPACE OVERFLOW

    单片机型号STC15F2K60s2 编译环境keil4 系统win7 模式 small 错误 ERROR L107 ADDRESS SPACE OVERFLOW 这个错误意思 提示地址超出 又去看了一遍数据手册 不应该是两k吗 为啥用了13
  • 动态链接(一)

    1 为什么要动态链接 静态链接的缺点 1 内存和磁盘空间 比如有两个程序 目标文件分别为Program1 o Program2 o 并且都用到Lib o这个模块 静态链接生成可执行文件Program1 Program2时 它们都分别存有Li
  • 在虚拟机里通过U盘引导安装Win10教程

    一 前言 打算在VM虚拟机里安装一个Win10系统 按照网上的教程 通过虚拟机的光驱加载 iso镜像文件来引导 发现启动不了 虚拟机一直停留在如下界面 推测可能是该 ios镜像文件里没有合适的引导程序 因此 打算尝试U盘启动 经过验证 发现
  • GNS3 FastEthernet1/10 is up, line protocol is down / SVI 无法连接的问题

    请重启三层路由器 三层路由器在打开的情况之下 连接上的设备貌似无法工作
  • K - Robotopia Kattis - robotopia

    题目链接 题解 题目其实类似于以前的解二元一次方程组 但是如果解出方程组后 会得到一个式子 但是如果仅仅代入式子的话是错误的因为假设是这样 5X 6Y 11 5X 6Y 11 这两个方程联立的话很明显是 X 1 Y 1 所以用这种方法不对
  • C语言密勒码的软件编码,密勒码的编码规则是什么?请画出代码序列11010010的密勒码波形?...

    相关题目与解析 CMI码的编码规则是什么 请画出代码序列11010010的CMI码波形 数字双相码的编码规则是什么 请画出代码序列11010010的双相码波形 简述双相码 曼彻斯特码 的编码规则并画出二进制比特序列1011010011的双相
  • k近邻算法的原理、示例与分析

    k近邻算法的原理 示例与分析 代码参考书籍 Python机器学习基础教程 Andreas C muller Sarah Guido著 张亮 译 北京 人民邮电出版社 2018 1 2019 6重印 实现环境 System Ubuntu se
  • Ubuntu查看CPU|GPU|型号等电脑配置

    电脑配置以及CPU 一个终极命令 可以包括以下命令显示的信息 cat proc cpuinfo alay ws sudo dmidecode grep Product Name Product Name Inspiron 3558 Prod
  • matlab以空间的点画球,3D空间画空洞小球Matlab程序

    3D空间画空洞小球Matlab程序 3D空间画空洞小球Matlab程序 有时候在三维空间中 需要画出很多的空洞小球 可以使用入戏的代码 clear all clc x y z sphere 100 hold on i 1 K 3 for c
  • 【C++入门】const和mutable关键字、常函数介绍

    1 常函数介绍 1 1 什么是常函数 1 常函数的定义 类的成员函数对类中任何成员不作修改而只能作访问的函数 简单来说 就是调用类的成员函数不会对类做任何修改 2 常函数的实现 常函数是依靠const关键字实现的 具体是在类中声明成员函数和
  • glDrawArrays,glDrawElements用法

    glDrawArrays 和 glDrawElements 的作用都是从一个数据数组中提取数据渲染基本图元 render primitives from array data 注 如果要 glDrawArrays 和 glDrawEleme