Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在OpenGL中,如何声明和使用作为基本元素数组的顶点属性_C++_Opengl_Glsl - Fatal编程技术网

C++ 在OpenGL中,如何声明和使用作为基本元素数组的顶点属性

C++ 在OpenGL中,如何声明和使用作为基本元素数组的顶点属性,c++,opengl,glsl,C++,Opengl,Glsl,在着色器中,我希望将一组基本体作为顶点属性传递给它 在着色器中,我声明 in float FloatItems[8] in int IntItems[8] 在C++代码中使用: void glGetActiveAttrib( GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); r

在着色器中,我希望将一组基本体作为顶点属性传递给它

在着色器中,我声明

in float FloatItems[8]
in int IntItems[8]
<>在C++代码中使用:

void glGetActiveAttrib(     GLuint program,
    GLuint index,
    GLsizei bufSize,
    GLsizei *length,
    GLint *size,
    GLenum *type,
    GLchar *name);

returns 
    name == "FloatItems[0]"
    size == 1
    type == 0x1406 (GL_FLOAT) - GL_INT for the int one.
当我尝试使用要绑定到它的位置的glVertexAttribPointer时,它失败,返回0x0501“无效值”

显然,gls正在创建一个名为“FloatItem[0]”的单个属性,而不是一个大小为8个元素的数组FloatItem

有没有一种“正确”的方法来做到这一点

表示着色器具有八个单独的属性,着色器可以作为值数组访问这些属性。这是8个具有8个不同属性位置的属性。这些属性的位置将从
FloatItems[0]
的位置开始连续分配

显然,为8个浮动使用8个属性位置是对位置和其他顶点输入资源的巨大浪费。因此,处理此问题的最佳方法是在属性本身的限制范围内工作

属性位置的长度最多为4个元素(这就是为什么会得到
GL\u INVALID\u值
大小只能是1-4)。这表示向量类型中组件的数量:2-4,1表示标量版本

因此,如果您想要一个“8个浮点数组”,那么您需要的是两个
vec4
s的数组:

layout(location = X) in vec4 FloatItems[2];
要访问数组元素,请使用多重索引。要从数组中获取索引Y,请使用
FloatItems[Y/4][Y%4]
。使用4是因为您使用的是
vec4


当然,这里涉及两个属性位置。第一个位于位置X(前4个元素),下一个位于位置X+1。因此,您需要两个
glVertexAttribFormat
glVertexAttribPointer
调用来为其设置VAO。

根据需要,您可以使用制服来传递数组(只需谷歌一下),但将它们作为顶点属性传递可能更好(更快)。在这种情况下,根据数据的“逻辑”外观,通常会有单个值或vec2/3/4s(通常不会将8个任意浮点值传递给着色器,但会有pos(vec2/3)、tex-coords(vec2)等,在这种情况下,命名和分离它们会使使用它更容易)。我认为不可能将数组作为属性传递,但我可能弄错了。@KamiKaze是的,我知道有人使用多元素基本类型。但是想知道是否有一种方法可以声明和使用一组基本体,就像着色器中的基本体一样,作为顶点属性。这是专门针对逐顶点数据的,缓冲区中所有顶点的大小都是固定的。这可能是因为您引用了该数组的第一个元素。基本上是@Nicol Bolas所说的。在这里我也回答了:除此之外,你仍然有制服,就像我在第一篇评论中所说的,或者使用基本体(例如2 vec4s)的“通常”方式,或者使用纹理来传递数据。唉,情况似乎就是这样。GLSL中的一个缺陷-我可以理解将位置舍入为4个浮点以提高效率,但这可以很容易地克服,因为语言支持mat4(16个元素)和mat3(9个元素)-缺少数组声明-即使有对齐和填充的警告-也会让很多人感到困惑,当然,未策划的Howto和博客的众包疯狂让寻找答案变得困难-我不得不使用两个vec4和两个ivec4来获得您所描述的所需内容。@peterk:“GLSL中的缺陷”到底是什么缺陷?正如我所展示的,您可以拥有输入数组。没有“缺少数组声明”;只是缺少将它们自动打包到尽可能少的位置。每个数组元素都有自己的位置、周期。这不是“缺陷”;这就是它的行为。@peterk:“未经策划的Howto和博客的众包疯狂使得寻找答案变得困难”是的,如果有一整页专门解释顶点着色器的工作原理,这不是更有意义吗,但这只是众包;它不在Khronos的OpenGL网站上,我确实读过Khronos的文档——语言是程序员可以理解的工具,用于定义他们想要的代码。许多人不理解GLSL数组声明的细微差别,允许声明一个包含8字节以下(vec2)实体的数组,并让编译器很好地生成代码,为其保留空间,将其四舍五入到16字节,并使用索引在源代码中寻址,这是完全合理的。并由编译器计算所有偏移量。即使是简单的汇编程序也能做到这一点。@peterk:“我确实读过Khronos文档”,所以。。。什么是“让寻找答案变得困难”?如果您阅读了文档,那么您就了解了输入的数组声明是如何工作的。你可能不喜欢答案,但你不应该表现得好像答案对你隐瞒了。“让编译器很好地生成代码,为其保留空间,将其四舍五入到16字节,并使用索引在源代码中寻址”,这可能是有意义的。。。直到您记住GLSL中没有定义这些内容的字节大小。这是VAO的一部分。
layout(location = X) in vec4 FloatItems[2];