当顶点属性数组零被禁用时,为什么 OpenGL 绘制会失败?

2024-01-18

我在让我的顶点着色器在 ATI 驱动程序上的 OpenGL 3.3 核心下运行时遇到了极大的困难:

#version 150

uniform mat4 graph_matrix, view_matrix, proj_matrix;
uniform bool align_origin;

attribute vec2 graph_position;
attribute vec2 screen_position;
attribute vec2 texcoord0;
attribute vec4 color;
varying vec2 texcoord0_px;
varying vec4 color_px;

void main() {
    // Pick the position or the annotation position
    vec2 pos = graph_position;

    // Transform the coordinates
    pos = vec2(graph_matrix * vec4(pos, 0.0, 1.0));

    if( align_origin )
        pos = floor(pos + vec2(0.5, 0.5)) + vec2(0.5, 0.5);

    gl_Position = proj_matrix * view_matrix * vec4(pos + screen_position, 0.0, 1.0);
    texcoord0_px = texcoord0;
    color_px = color;
}

我使用 glVertexAttrib4f 指定颜色属性,并关闭属性数组。根据 3.3 核心规范第 33 页,这应该有效:

如果未启用与顶点着色器所需的通用属性相对应的数组,则从当前通用属性状态中获取相应的元素(参见第 2.7 节)。

但是(大多数时候,取决于配置文件和驱动程序)如果我访问禁用的颜色属性,着色器要么根本不运行,要么使用黑色。用常量替换它就可以运行了。

大量搜索结果本页有关 WebGL 的提示 https://developer.mozilla.org/en-US/docs/WebGL/WebGL_best_practices,其中有以下内容:

始终启用顶点属性 0 数组。如果您在禁用顶点属性 0 数组的情况下进行绘制,则在桌面 OpenGL(例如在 Mac OSX 上)上运行时,您将强制浏览器进行复杂的模拟。这是因为在桌面 OpenGL 中,如果顶点属性 0 未启用数组,则不会绘制任何内容。您可以使用bindAttribLocation()强制顶点属性使用位置0,并使用enableVertexAttribArray()使其启用数组。

果然,不仅颜色属性被分配给索引零,而且如果我将另一个启用数组的属性强制绑定为零,代码就会运行并产生正确的颜色。

我在任何地方都找不到任何其他提及此规则的内容,当然在 ATI 硬件上也找不到。有谁知道这个规则从何而来?或者这是 Mozilla 人员注意到并警告过的实现中的错误?


tl;dr:这是一个驱动程序错误。核心 OpenGL 3.3 应该允许您不使用属性 0,但兼容性配置文件不允许,并且某些驱动程序无法正确实现该开关。只需确保使用属性 0 即可避免出现任何问题。

实际内容:

让我们上一堂历史课,了解 OpenGL 规范是如何诞生的。

在 OpenGL 最古老的时代,只有一种渲染方式:立即模式(即:glBegin/glVertex/glColor/glEtc/glEnd)。显示列表是存在的,但它们始终被定义为简单地再次发送捕获的命令。因此,虽然实现实际上并未进行所有这些函数调用,但实现的行为仍然就像它们进行了一样。

在 OpenGL 1.1 中,客户端顶点数组被添加到规范中。现在记住:规范是指定的文档behavior,而不是实施。因此,ARB 简单地定义客户端数组的工作方式与进行立即模式调用完全相同,使用对当前数组指针的适当访问。显然,实现实际上不会这样做,但它们的行为却好像这样做了。

基于缓冲区对象的顶点数组以相同的方式定义,但由于从服务器存储而不是客户端存储中提取,语言稍微复杂一些。

然后发生了一些事情:ARB_vertex_program(不是ARB_vertex_shader。我说的是汇编程序)。

看,一旦有了着色器,您就希望能够开始定义自己的属性,而不是使用内置属性。这一切都是有道理的。然而,有一个问题。

立即模式的工作原理如下:

glBegin(...);
glTexCoord(...);
glColor(...);
glVertex(...);
glTexCoord(...);
glColor(...);
glVertex(...);
glTexCoord(...);
glColor(...);
glVertex(...);
glEnd();

每次你打电话glVertex,这会导致所有当前属性状态都用于单个顶点。所有其他立即模式函数只是将值设置到上下文中;这个功能实际上sendsOpenGL 中要处理的顶点。这在即时模式下非常重要。由于每个顶点都必须在固定功能区域中拥有一个位置,因此使用此函数来决定何时应处理顶点是有意义的。

一旦不再使用 OpenGL 的固定功能顶点语义,立即模式就会出现问题。也就是说,你如何决定何时真正send顶点?

按照惯例,他们将其粘贴到属性 0 上。因此,所有立即模式渲染必须使用属性 0 或 glVertex 来发送顶点。

然而,因为所有其他渲染基于立即模式渲染的语言,所有其他渲染都有相同的局限性立即模式渲染。立即模式需要属性 0 或 glVertex,因此客户端数组等也是如此。尽管这对他们来说没有意义,但他们需要它,因为规范如何定义他们的行为。

然后 OpenGL 3.0 出现了。他们不赞成立即模式。弃用并不意味着removed;规范中仍然包含这些函数,并且所有顶点数组渲染仍然被定义in terms其中。

OpenGL 3.1 实际上删除了旧的东西。这带来了一些语言问题。毕竟,每个数组绘制命令总是根据立即模式定义的。但是一旦即时模式不再存在......你如何定义它?

因此他们必须为核心 OpenGL 3.1+ 开发新的语言。在这样做的同时,他们删除了需要使用属性 0 的毫无意义的限制。

但兼容性配置文件did not.

因此,OpenGL 3.2+的规则是这样的。如果您有核心 OpenGL 配置文件,则不必使用属性 0。如果您有兼容性 OpenGL 配置文件,则必须使用属性 0(或glVertex)。规范就是这么说的。

但这不是实现所实现的。

一般来说,NVIDIA 从来不太关心“必须使用属性 0”规则,只是按照您的预期行事,即使在兼容性配置文件中也是如此。从而违反了规范的规定。 AMD 通常更有可能遵守该规范。然而,他们忘记了实施core行为正确。所以NVIDIA对兼容性太宽容,而AMD对核心太限制。

要解决这些驱动程序错误,只需始终使用属性 0。

顺便说一句,如果您想知道的话,NVIDIA 赢了。在 OpenGL 4.3 中,兼容性配置文件对其数组渲染命令使用与核心相同的措辞。因此,您可以在核心和兼容性上不使用属性 0。

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

当顶点属性数组零被禁用时,为什么 OpenGL 绘制会失败? 的相关文章

  • 交错顶点提交如何提高性能?

    我已经阅读并看到了其他问题 这些问题通常都指向将顶点位置和颜色等交错到一个数组中的建议 因为这可以最大限度地减少从 cpu 发送到 gpu 的数据 我不清楚的是 即使使用交错数组 您仍然必须对位置和颜色指针进行单独的 GL 调用 OpenG
  • 没有着色器的 OpenGL

    我已经阅读了一些教程来编写以下代码 唯一的区别是原始教程使用 SDL 而不是 GLEW 我不明白这段代码有什么问题 它可以编译 但我没有看到三角形 教程也没有使用着色器 include
  • 纹理openGl。 C++、qt

    我试图用草纹理覆盖我的地形 由高度图制成 但它没有按预期工作 我什至无法在简单的 GL QUAD 上获取纹理 结果是多色网络 void GLWidget initializeGL glEnable GL TEXTURE 2D 在 QGLwi
  • OpenGL 的每个组件 alpha 通道?

    是否可以使用 OpenGL 对每个组件使用一个 alpha 通道 一个用于红色 一个用于绿色 一个用于蓝色 进行混合 如果没有 有哪些可能的解决方法 这不是直接支持的东西 不过 您自己实现起来相当容易 使用 3 通道 alpha 纹理渲染三
  • 三角形未在 OSX 上的 OpenGL 2.1 中绘制

    我正在学习有关使用 OpenGL 在 Java 中创建游戏引擎的教程 我正在尝试在屏幕上渲染一个三角形 一切运行良好 我可以更改背景颜色 但三角形不会显示 我还尝试运行作为教程系列的一部分提供的代码 但它仍然不起作用 教程链接 http b
  • 法线在 openGL 中表现得很奇怪

    我一直在为 openGl 编写一个 obj 加载器 几何体加载得很好 但法线总是混乱的 我尝试在两个不同的程序中导出模型 但似乎没有任何效果 据我所知 这就是将法线放入 GL TRIANGLES 的方法 glNormal3fv norm1
  • QOpenGLFunctions 缺少重要的 OpenGL 函数

    QOpenGLFunctions 似乎缺少重要的函数 例如 glInvalidateFramebuffer 和 glMapBuffer 据我了解 QOpenGLFunctions 加载桌面 OpenGL 函数和 ES 函数的交集 如果是这样
  • OpenGL 着色器不与着色器程序链接

    我正在尝试使用 GLFW GLEW 添加着色器 我收到一个错误 指出着色器已加载 但它们没有有效的对象代码 这是我用于加载着色器的代码 class SHADER public void LoadShaders const char vert
  • WebKit 是否使用 OpenGL 来渲染 CSS 过渡?

    WebKit 是使用 OpenGL 来渲染 CSS 过渡 还是使用软件渲染 WebKit 只是一个前端 这取决于后端和硬件支持 谷歌浏览器使用skia http code google com p skia 作为后端 它可以使用软件或硬件
  • lnk1104:无法打开“LIBC.lib”链接

    使用 GLee 将着色器写入我的 OpenGL 项目并编译后 我收到了错误LNK1104 cannot open file LIBC lib 我尝试按照其他人的建议添加它并忽略它 但没有解决问题 有没有其他方法可以解决我错过的这个问题 以下
  • glBlitFramebuffer 渲染缓冲区和渲染全屏纹理哪个更快?

    哪个更快更高效 使用 OpenGL 纹理作为 CUDA 表面并在四边形上渲染 新样式 使用渲染缓冲区作为 CUDA 表面并使用 glBlitFramebuffer 进行渲染 None
  • NV_path_rendering替代方案[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我刚刚观看了 Siggraph 2012 的一个非常令人印象深刻的演示 http nvidia fullviewmedia com sig
  • glut 库中缺少 glutInitContextVersion()

    我正在练习一些 opengl 代码 但是当我想通过以下方式强制 opengl 上下文使用特定版本的 opengl 时glutInitContextVersion 它编译过程失败并给出以下消息 使用未声明的标识符 glutInitContex
  • PyQt5 的 OpenGL 模块和版本控制问题(调用不正确的 _QOpenGLFunctions_(ver))

    我一直在努力得到PyQt5 helloGL 示例代码 https github com baoboa pyqt5 blob master examples opengl hellogl py编译 当我尝试构建解决方案时 我得到 Traceb
  • GL_CULL_FACE使所有对象消失

    我正在尝试在 openGL3 3 中创建一些简单的多边形 我有两种类型的对象 具有以下属性 对象 1 10 个顶点 按顺序在下面列出 存储在GL ARRAY BUFFER并使用GL TRIANGLE FAN v x y z w v 0 0
  • OpenGL缓冲区更新[重复]

    这个问题在这里已经有答案了 目前我正在编写一个模拟水的程序 以下是我所做的步骤 创建水面 平面 创建VAO 创建顶点缓冲区对象 在其中存储法线和顶点 将指针绑定到此 VBO 创建索引缓冲区对象 然后我使用 glDrawElements 渲染
  • Opengl 像素完美 2D 绘图

    我正在研究 2d 引擎 它已经工作得很好 但我不断收到像素错误 例如 我的窗口是 960x540 像素 我从 0 0 到 959 0 画一条线 我希望扫描线 0 上的每个像素都会被设置为一种颜色 但事实并非如此 最右边的像素没有被绘制 当我
  • Visual Studio 2010 中的 SOIL 设置

    我无法得到SOIL http www lonesock net soil html正确使用 Visual Studio 2010 我远非 VS 专家 但据我所知 只需执行以下步骤即可使环境正常运行 属性 gt gt C C gt 常规 gt
  • Glew+GLFW Win32 无依赖项 Visual Studio

    是否可以在不将文件复制到 C 的情况下构建并链接 Glew 和 GLFW 我找不到任何说明如何在不将 DLL 复制到 C 上的 Visual Studio 目录的情况下使用这些库的文档 我只想包含项目目录中所需的所有 dll 和 lib 文
  • 即使手动设置显示环境变量后,WSL Ubuntu 也会显示“错误:无法打开显示”

    我在 WSL Ubuntu 上使用 g 我使用 git 克隆了 GLFW 存储库 使用了ccmake命令配置并生成二进制文件 然后使用make在 build 目录中最终创建 a文件 我安装了所有OpenGL相关的库 usr ld 我不记得我

随机推荐

  • 分组算法

    我试图帮助某人编写一个我认为很容易的程序 但当然它从来都不是 我正在尝试制定一个班级名册 通常有 10 20 名学生 并有效地将每个同学与另一个同学有效地唯一配对 以形成独特的小组 因此 一个10人的班级 可以分成9组 它也需要能够处理奇数
  • 来自 java 的 libxml2

    这个问题有点相关用于 Java 中小型 简单文档的最快 XML 解析器 https stackoverflow com questions 530064 fastest xml parser for small simple documen
  • Postgres 生成_系列

    我想要的是对表格进行统计 为此我正在使用generate series 这是我正在做的事情 SELECT x month amount FROM SELECT generate series min date trunc month dat
  • 在 docker 上运行 conda 的 jupyter

    我正在使用 docker 镜像 Continumio anaconda3 并希望通过浏览器使用 conda 启动 jupyter 笔记本服务器 docker run i t p 8888 8888 continuumio anaconda3
  • 在未使用的默认成员初始值设定项中使用仍然是 odr 使用吗?

    即使任何构造函数都没有使用默认成员初始值设定项 在默认成员初始值设定项中使用仍然是 odr 使用吗 例如 这个程序是否格式错误 因为g a 是否使用了 odr 因此其定义被隐式实例化 template a
  • 加密 SQL 数据库中的密码列

    我的数据库名称密码中有一列 我只想在发布到数据库之前对密码进行哈希或加密 我的 php 提交文件中有这样的代码
  • 在 Python 中处理字符串中的转义序列

    有时 当我从文件或用户获取输入时 我会得到一个带有转义序列的字符串 我想处理转义序列与 Python 处理字符串文字中的转义序列的方式相同 https docs python org 3 reference lexical analysis
  • 在 jQuery 中创建新的(永久)CSS 样式

    我想创建一种新样式 而不仅仅是更改元素的样式属性 下面是一些示例代码来演示该问题 Create 1st element var element1 div div text element1 addClass blue body append
  • ASP.NET c# 修复函数库内自定义ConfirmMessagebox 的 OK 事件

    我们创建了一个从 C 通过 javascript 动态显示模态弹出消息的函数 它工作正常 但我们想添加一个参数 以便我们可以传递一个函数委托 或事件处理程序 如果用户按下 确定 按钮 该函数将被调用 有什么建议么 Postdata 我们不需
  • 函数调用之外的星号

    我正在尝试 python 我有一个关于星号的问题 我知道它们用于函数调用中的参数 但我见过在函数卡之外使用它们的代码片段 例如 在 5 个等级的元组中 将它们解压到变量中 例如 first middle last grades 每当我尝试在
  • Chart.js stepSize 不适用于 min

    StepSize 不考虑 min 包括小提琴 https jsfiddle net 4p93aew7 10 https jsfiddle net 4p93aew7 10 var options type line data labels R
  • 在 CSS 中为 div 使用多个 ID

    我的网站上有 3 个 DIV 元素和这个 CSS box left box middle box right a text decoration none color 000000 它似乎只致力于 box right虽然元素 有任何想法吗
  • 将动态内容放入 mail() $message 中

    我只是想整理一封简单的 HTML 电子邮件 以确认我的数据库的订单 我的 message 看起来有点像 message etc etc 我想要在 message HTML 中执行的操作是调用我的数据库 该数据库将返回类似以下内容的行 ema
  • 使用 Facelets 标记文件时出现 FileNotFoundException

    我正在尝试运行 Core JavaServer Faces 书中的示例 ch05 http horstmann com corejsf http horstmann com corejsf 登录后我收到以下消息 sections plane
  • 实现 std::basic_streambuf 子类来操作输入

    我有一个std basic streambuf导致所有输出都以大写形式写入的子类 如下所示 class upper streambuf public std streambuf public upper streambuf std stre
  • 如何从相机拍摄的照片制作缩略图?

    在我的应用程序中 我使用外部相机应用程序来制作照片并将其保存到 SD 卡 我需要这张照片的方形缩略图 我已经设法将相机发送回的缩略图裁剪成正方形 但由于我将照片保存到磁盘 因此意图是空的 而我的旧方法使图片成为正方形Bitmap cropp
  • Spring单例bean的这种设计是线程安全的吗?

    考虑以下 Spring 服务类 spring定义的作用域是Singleton 在下面的类中自动连接为字段的两个服务 bean 具有相似的结构 它们也由以下字段之一组成 春豆本身 无状态类 不可变类 等等 该模式在应用程序设计中总体采用 Se
  • AjaxControlToolkit.CommonToolkitScripts 错误

    我在我的 ASP NET 应用程序中得到以下代码
  • 回复 Gmail 线程会向我自己发送电子邮件

    文档 https developers google com apps script reference gmail gmail message replybody options https developers google com a
  • 当顶点属性数组零被禁用时,为什么 OpenGL 绘制会失败?

    我在让我的顶点着色器在 ATI 驱动程序上的 OpenGL 3 3 核心下运行时遇到了极大的困难 version 150 uniform mat4 graph matrix view matrix proj matrix uniform b