如果我们有glBindBuffer,“ glGenBuffers”真的重要吗?

时间:2019-04-06 19:56:33

标签: opengl

好吧,我从OpenGl开始,通过阅读有关glBindBuffer的文档,我有些困惑。

  

“ glBindBuffer将缓冲区对象绑定到指定的缓冲区绑定点。在 target 设置为可接受的符号常量和 buffer之一的情况下调用glBindBuffer设置为缓冲对象名称的 会将缓冲对象名称绑定到目标。如果不存在名称为 buffer 的缓冲对象,则为使用该名称创建。当缓冲区对象绑定到目标时,该目标的先前绑定将自动中断。”   来源:http://docs.gl/gl4/glBindBuffer

这是否意味着如果我不创建名称为“ foo”的缓冲区对象,而是调用glBindBuffer,它将为我创建一个名称为“ foo”的缓冲区对象?

如果是这样,下面的代码应该可以正常工作:

with final_cal as (WITH
  index_cal AS (
  SELECT
    values-01,
    kind,
    EXTRACT (QUARTER  FROM  date) as QUARTER,
    date,
  FROM
    `project.dataset.table`,
  geom AS (
  SELECT
    identifier
  FROM
    `project.dataset.table2` )
SELECT
   AVG(values-01) AS averages,
    QUARTER AS quarter,
    geom. identifier as identifier
  FROM
    index_cal as g
INNER JOIN
  geom
ON
  INTERSECTS(g.kind,
    geom. identifier)
GROUP BY
  identifier
  quarter)
SELECT identifier, ARRAY_AGG(STRUCT(averages, quarter)) from final_cal GROUP BY identifier

->创建缓冲区对象,将其与条(70)“连接”并将其绑定到GL_ARRAY_BUFFER。

2 个答案:

答案 0 :(得分:5)

否,此代码仅在兼容性配置文件上下文(或OpenGL ES)中工作。

请参见OpenGL 4.6 API Core Profile Specification - 2.6.1 Object Management- page 28

  

[...] GenBuffers命令返回一个或多个以前未使用的缓冲区对象名称。
  GL将生成的名称标记为已使用,仅用于生成名称的目的。以这种方式标记的对象名称将不会通过其他调用返回,以生成相同类型的名称,直到通过删除名称再次将它们标记为未使用时。[...]

这意味着glGenBuffers does nothing else than reserving names (values). Further calls to glGenBuffers will not return the same values. If glGenBuffers`始终用于获取缓冲区对象的名称值,然后可以确保该值尚未用于其他缓冲区对象。 / p>

但是在桌面OpenGL核心配置文件规范中,不允许使用glBindBuffer的名称,glGenBuffers并未保留(返回)该名称。

请参见OpenGL 4.6 API Core Profile Specification - 6.1 Creating and Binding Buffer Objects - page 62

  

如果缓冲区不为零或名称,则生成INVALID_OPERATION错误   从先前对GenBuffers的调用返回,或者此名称是否为   用DeleteBuffers删除。

OpenGL 4.6 API Compatibility Profile Specification - 6.1 Creating and Binding Buffer Objects - page 62

中缺少规范的这一部分

这有点令人困惑,但这就是规范。

此行为可通过您的问题代码验证。以下代码使用兼容性配置文件上下文不返回错误,但是使用核心配置文件上下文返回GL_INVALID_OPERATION

GLuint bar = 70;
glBindBuffer(GL_ARRAY_BUFFER, bar); 
GLenum error = glGetError();

答案 1 :(得分:2)

第6.1节中的OpenGL 4.6 Spec状态指出,当缓冲区未指向using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace StudentLinq { public class Student { public int Id { get; set; } } public class Admin { public string Name { get; set; } } public class Generic { public void Print<T>(List<T> list) { foreach(var itemList in list) { if (list is List<Student>) { Console.WriteLine(itemList); } //How can I print the properties from the product class and student } } } class Program { static void Main(string[] args) { var studentsList = new List<Student>(); studentsList.Add(new Student { Id = 2 }); var productList = new List<Product>(); productList.Add(new Product { Price = 40 }); var generic = new Generic(); generic.Print<Student>(studentsList); generic.Print<Product>(productList); Console.ReadLine(); } } } 先前保留的名称时,glBindBuffer必须抛出GL_INVALID_OPERATION异常:

  

如果缓冲区不为零或名称,则生成INVALID_OPERATION错误   从先前对GenBuffers的调用返回,或者如果此名称自   用DeleteBuffers删除。

official docs中说明了相同的信息。

我不确定docs.GL为什么不声明该信息。可能是因为我们以错误的方式解释了该句子,因为它指出已创建缓冲区。从技术上讲,通过调用glGenBuffers仅创建缓冲区名称,但是在第一次绑定该名称时创建缓冲区对象。