OpenGL 3:​​glBindVertexArray 使 GL_ELEMENT_ARRAY_BUFFER 无效

2024-03-13

我确信如果你通过绑定缓冲区glBindBuffer(),您可以放心地假设它保持绑定状态,直到目标通过另一个调用反弹glBindBuffer()。因此,当我发现调用时,我感到非常惊讶glBindVertexArray()将绑定到 GL_ELEMENT_ARRAY 目标的缓冲区设置为 0。

这是最小的 C++ 示例代码:

GLuint buff;
glGenBuffers(1, &buff);
std::cout << "Buffer is " << buff << "\n";
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buff);
GLuint vao;
glGenVertexArrays(1, &vao);

GLint bound_buff;
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &bound_buff);
std::cout << "Bound before glBindVertexArray: " << bound_buff << "\n";

glBindVertexArray(vao);    
  // ^- an implicit glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); ?

glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &bound_buff);
std::cout << "Bound after glBindVertexArray: " << bound_buff << "\n";

我在初始化 OpenGL 3.2 设备上下文后立即运行此代码并获得以下输出:

 Buffer is 1
 Bound before glBindVertexArray: 1
 Bound after glBindVertexArray: 0

另一方面,GL_ARRAY_BUFFER 是not因通话而改变。我检查了 OpenGL 3.2 规范 (2.10)glBindVertexArray并没有发现任何提及这种意想不到的副作用。

  1. 这种行为符合规范吗?
  2. 如果是这样,调用以下命令还会产生哪些其他副作用glBindVertexArray?
  3. 这背后的理由是什么?

我在带有 296.10 WHQL 驱动程序的 Win XPx64 机器上的 nvidia 卡上进行了测试。 使用 nvidia GT330M 在 OS X Lion 上进行的快速测试得出了相同的结果。


顶点数组对象 http://www.opengl.org/wiki/Vertex_Array_Object封装渲染顶点数据所需的所有状态*。因此,它们必须封装与属性关联的缓冲区(通过glVertexAttribPointer), GL_ELEMENT_ARRAY_BUFFER (需要glDrawElement*调用)等。

然而,我仍然感到有点困惑,因为我在文档中找不到任何关于这种副作用的提及。

规范清楚地解释了这一点,尽管需要了解规范的工作原理才能了解其工作原理。

OpenGL 是状态的集合,这意味着所有 OpenGL 函数(除了那些实际渲染某些内容的函数)都会修改 OpenGL 状态。你打电话时glVertexAttribPointer,这个函数从概念上修改了一些内部 OpenGL 状态。

OpenGL对象 http://www.opengl.org/wiki/OpenGL_Object由它们封装的 OpenGL 状态片段定义。因此,如果函数修改对象封装的状态,那么该函数也会修改对象本身。绑定对象意味着用该对象的当前状态替换它们封装的当前状态。

The ARB_顶点_数组_对象 http://www.opengl.org/registry/specs/ARB/vertex_array_object.txt规范根据 VAO 封装的状态来定义它们。它基本上指向一个 OpenGL 状态表并说:“VAO 就是所有这些。”此功能的核心 3.x 版本实际上修改了状态表以使其更加清晰(相同的行为,其解释略有不同):

OpenGL 3.3 规范,第 2.10 节:

生成的顶点数组对象是一个新的状态向量,包含表 6.4 和 6.5 中列出的所有状态值。

我不打算重印表 6.4 和 6.5;你可以自己查一下。但它们显然包括GL_ELEMENT_ARRAY_BUFFER_BINDING以及各种GL_VERTEX_ATTRIB_ARRAY_BUFFER_BIDNING(它们是缓冲区对象)。

* 注意:VAO 不包含由glVertexAttrib http://www.opengl.org/wiki/GLAPI/glVertexAttrib功能。如果未启用属性数组,这些可能会影响渲染。

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

OpenGL 3:​​glBindVertexArray 使 GL_ELEMENT_ARRAY_BUFFER 无效 的相关文章

  • C++ 令人头疼的命名空间

    好吧 这个问题已经发生了一些变化 我想尝试从我正在追求的基本目标开始 重新 创建在 C 资源获取和初始化中包装遗留 C 语言实体的库代码 并提供基本或更好的异常保证 使此代码的客户端能够以非常自然的 C 方式使用它 而不会为现有代码创建大量
  • 实现 `memcpy()`:需要 `unsigned char *`,还是只需要 `char *`?

    我正在实施一个版本memcpy 能够与它一起使用volatile 使用安全吗char 或者我需要unsigned char volatile void memcpy v volatile void dest const volatile v
  • Lambda、封闭变量、显示类、可序列化性和流行层

    我已经为 Compact Framework 实现了一个流行层 包括BinaryFormatter 类似序列化器 我希望能够在适当的情况下序列化编译器生成的类 这些类是由 lambda 和迭代器等产生的 这样如果 例如 lambda 及其封
  • 是否已经有一些基于 std::vector 的 set/map 实现?

    对于小型集合或地图 通常使用排序向量而不是基于树的向量要快得多set map 特别是对于 5 10 个元素的情况 LLVM 有一些类本着这种精神 http llvm org docs ProgrammersManual html ds se
  • 将 MyGeneration 与 Fluent NHibernate 结合使用

    我在这里找到了一个使用 MyGeneration 生成 NHibernate 代码的绝佳模板 http vucetica blogspot com 2009 01 nhibernate template for my Generation
  • 以 ASCII 字符串形式获取 MemoryStream 内容的快速方法

    我在 MemoryStream 中有一个 JSON 字符串 我使用以下代码将其作为 ASCII 字符串获取 MemoryStream memstream new MemoryStream Write a JSON string to mem
  • 如何设置属性选择器的值 Expression>

    我需要使用模式工厂的想法将 Person 类实体中的实体属性 Address 与 FactoryEntities 类中的表达式 linq 相关联 看看这就是我所拥有的并且我想要做的 Address address new Address a
  • 在 C++ 中重用异常处理代码

    我有这两个函数 具有重复的异常处理 其唯一目的是显示错误消息 void func1 noexcept try do task do another task catch const std out of range e show msg O
  • boost::unordered_map 是...有序的吗?

    我有一个 boost unordered map 但它看起来是有序的 给我一种压倒性的 你做错了 的感觉 为什么输出是这样的 我希望底层的哈希算法能够随机化这个顺序 include
  • 如何存储生成的格式化 C 字符串

    这是一个新手问题 为了创建格式化的 C 字符串 我使用printf like int n 10 printf My number is i 10 但是 怎么样 int n 10 char msg My number is i 10 prin
  • 使用 .NET Core Razor Pages 将文件下载到浏览器

    使用 ASP NET Razor Pages 我尝试将文件下载到浏览器 在页面 html 中 使用这样的链接效果很好 href DownloadableFiles testB csv download newname gt Download
  • 委托:方法名称预期错误

    我正在尝试让以下简单的委托示例正常工作 根据我从中取出的一本书 应该没问题 但我得到了Method name expected error namespace TestConsoleApp class Program private del
  • 更改子进程中的 iostream

    现在 我正在开发一个项目 其中我需要启动一个子进程来使用 C 在 Linux 中执行一个新程序 并且我需要重定向标准输入和输出 就像在 C 中一样 它们是cin and cout 到一个文件 这意味着在子进程中 标准输入和输出都是文件 子进
  • 拦截C# HttpClient GetAsync

    我有一个 Web 项目 C MVC5 但没有 WebAPI 和一个简单的 HTTP REST 客户端 该客户端调用外部 REST 服务并获取 accessToken 等 我想检查所有 Get PostAsync 调用对 statusCode
  • 如何避免函数的多重定义(Linux、GCC/G++、Code::Blocks)

    我有一个代码块项目 它使用许多不同的文件 通常是由其他程序员编写的 目前我遇到的情况是 我有两个不同的子项目 其中包含以相同方式命名的函数 比方说 F int x 因此 F int x 是在两个不同位置的两个源文件中定义的 并且它们有两个不
  • 使用全局 Web API 过滤器属性进行 Unity 依赖注入

    参考这个CodePlex 统一文章 http unity codeplex com discussions 446780我能够使用 WebAPI 控制器获取过滤器属性 如下所示 MyFilterAttribute public class
  • 如何将 typedef 结构传递给函数?

    此刻我正在努力 void avg everything 但这给了我错误 error subscripted value is neither array nor pointer 当我今天早些时候收到此错误时 这是 因为我没有正确地将 2D
  • 在.Net中使用ObjectCache缓存对象并设置过期时间

    我陷入了一个场景 我的代码如下 更新 它不是关于如何使用数据缓存 我已经在使用它及其工作 它是关于扩展它 以便该方法在到期时间和从外部源获取新数据之间不会进行调用 object string this GetDataFromCache ca
  • 我该怎么做才能完全关闭与mcu的tcpClient连接?

    我现在正在研究与 ESP32 中运行的 tcp 服务器的 tcp 套接字连接 通信工作正常 但我无法关闭连接 在搜索关闭 重置 tcpClient 上的解决方案后 似乎关闭 tcpClient 的正确方法应该是 tcpClient GetS
  • 如何为单个函数设置 ICC 属性“fp-model precision”,以防止关联优化?

    我正在实施卡汉求和 http en wikipedia org wiki Kahan summation algorithm 在支持 gcc47 gcc48 clang33 icc13 和 icc14 编译的项目中 作为该算法的一部分 我想

随机推荐

  • 确定新日期是否是默认的 new DateTime()

    这是我的问题 DateTime previousDate new DateTime DateTime currentDate new DateTime foreach ApproverVo approver in approvers if
  • 出错时再次循环

    我试图阅读所有内容 但我有点陷入了一个问题 通过使用 bigrquery 我创建了对 Google BigQuery 的查询来获取数据 不幸的是 有时我的查询由于超时而无法工作 Q 是一个 SQL 查询 BQ 应该存储从 BigQuery
  • 如何从 iOS 应用程序上的自定义键盘检索击键?

    我需要为我的 iPhone 应用程序构建一个自定义键盘 之前的问题和答案 https stackoverflow com questions 4643167 iphone objc how to create a custom keyboa
  • mvn:找不到命令

    我正在尝试使用 jenkinsfile 在我无权管理路径的特定对象上运行管道 但我遇到了这个错误 有人知道如何解决这个问题吗 您需要在执行作业的构建代理上安装 Maven Jenkins 的另一种选择是它可以为您安装 Maven 这可以在全
  • C# 中未知长度的数组

    我刚刚开始学习 C 在数组简介中 他们展示了如何将变量建立为数组 但似乎必须在赋值时指定数组的长度 那么如果我不知道数组的长度怎么办 大批 数组必须指定长度 要允许任意数量的元素 请使用List http msdn microsoft co
  • 如何使用 gspread 缓存 Google Sheets 的授权?

    我正在尝试创建一个简单的函数 将一些数据发布到 Google Sheets 电子表格中 我在 AWS Lambda 中托管此函数 无论如何 代码看起来有点像这样 import gspread from oauth2client servic
  • 添加到数据库后保持在同一页面而不刷新

    我有 PHP 网页 需要在其中插入一些信息到我的数据库中 插入完成后 它会刷新同一页面 但我被告知这个过程不切实际 因为你正在加载所有HTML CSS and JS每次都会显示您的页面 我应该你AJAX要做到这一点 我搜索它 并尝试了这段代
  • find_in_set 与 laravel 中的 join

    如何使用 Laravel 查询获取所需的输出 尝试过这种方式没有成功请指导提前非常感谢 如果可能的话 我们有什么方法可以在模型中设置它 请指导 User id name b id 1 Alax 1 3 2 Rex 2 4 3 Lex 2 3
  • jQuery droppable out 事件无法触发?

    LWdrop droppable accept LW drop function event ui ui draggable addClass LWactive this droppable option accept this css b
  • 如何避免重复出现消息“更新被拒绝,因为远程包含您所做的工作...”?

    我正在与另外三个合作者一起参与一个项目 我的情况是 每次我尝试添加新提交并且远程中存在一些更改 即使它是我未在本地工作过的文件 时 我都会收到以下消息 迫使我使用以下默认消息创建合并 error failed to push some re
  • 从表单生成表格

    我有一个表单组 public transactionOrRefundRequestForm FormGroup new FormGroup SaleRequest new FormGroup Header new FormGroup Typ
  • Perl 中有 zip 和 Fold 等函数吗?

    我想使用一些功能 例如 zip http zvon org other haskell Outputprelude zip f html fold http www haskell org haskellwiki Fold and map
  • Java:使用 double 不准确[重复]

    这个问题在这里已经有答案了 可能的重复 在java中使用双精度数保持精度 https stackoverflow com questions 322749 retain precision with doubles in java Java
  • 混淆 ASP.Net dll 破坏 Web 应用程序

    我通常不会费心去混淆 Web 应用程序 DLL 但现在我必须与可能有利益冲突的人共享一些服务器空间 并且可能会试图窃取交易并反编译它 我知道这不是一个理想的解决方案 但是嘿 因此 我使用 VS 2005 一个 Web 部署项目 编译为单个
  • Getpass输入Python 3

    我正在尝试创建密码输入 我知道getpass getpass但是当我将其置于闲置状态时 它会出现错误 提示 密码可能会被回显 My code import getpass p getpass getpass print You entere
  • gremlin 语法计算 Jaccard 相似度度量

    我有兴趣计算图中未直接连接的所有顶点对的杰卡德相似度度量 Jaccard度量定义为两个顶点的邻居交集的范数除以相同集合的并集的范数 where 到目前为止 我已经能够获得所有未直接连接的节点对 仅对这种情况下的链接预测感兴趣 如果直接链接已
  • 其可能的 Google 表单脚本每天上午 00:01 至中午 12:00 自动打开和关闭

    我想每天 00 01 打开 google 表单并在 12 00 关闭 这是我的代码 function createDailyTrigger ScriptApp newTrigger openCloseFormTrigger timeBase
  • 由于 Integer.parseInt 导致崩溃

    我正在尝试从另一个文本文件中生成的文本导入文本Activity 生成的文本文件由String ArrayList其中仅包含数字和 Android 生成的其他随机文本 当我从文件导入文本时 我使用的是BufferedReader and re
  • 如何在Python中检查神经网络的层数以及何时应该增加层数?

    请对您的想法添加最少的评论 以便我可以改进我的查询 谢谢 我正在研究MNIST数据集并写一些CNN代码 然而 我对其中的一些观点感到困惑CNN代码 如何知道神经网络的层数 根据我目前的理解 我认为它有 6 层和 4 个隐藏层 是对的吗 如果
  • OpenGL 3:​​glBindVertexArray 使 GL_ELEMENT_ARRAY_BUFFER 无效

    我确信如果你通过绑定缓冲区glBindBuffer 您可以放心地假设它保持绑定状态 直到目标通过另一个调用反弹glBindBuffer 因此 当我发现调用时 我感到非常惊讶glBindVertexArray 将绑定到 GL ELEMENT