Opengl顶点着色器为每个顶点设置布尔值(glVertexAttribPointer)
Posted
技术标签:
【中文标题】Opengl顶点着色器为每个顶点设置布尔值(glVertexAttribPointer)【英文标题】:Opengl Vertex Shader set boolean per vertex (glVertexAttribPointer) 【发布时间】:2016-04-19 11:21:54 【问题描述】:问题: 我有一个 VBO,其中包含一个结构数组 (MyStruct),其中包含一个布尔属性。我想将此布尔值传递给我的顶点着色器,但根据glVertexAttribPointer(...);
的文档,GL_BOOL
是不允许的。
指定数组中每个组件的数据类型。象征性的 常量 GL_BYTE、GL_UNSIGNED_BYTE、GL_SHORT、GL_UNSIGNED_SHORT、 GL_INT 和 GL_UNSIGNED_INT 被 glVertexAttribPointer 接受,并且 glVertexAttribIPointer。另外 GL_HALF_FLOAT、GL_FLOAT、 GL_DOUBLE、GL_FIXED、GL_INT_2_10_10_10_REV、 GL_UNSIGNED_INT_2_10_10_10_REV 和 GL_UNSIGNED_INT_10F_11F_11F_REV 是 被 glVertexAttribPointer 接受。 GL_DOUBLE 也被 glVertexAttribLPointer 并且是该类型接受的唯一标记 该函数的参数。初始值为 GL_FLOAT。 来源:https://www.opengl.org/sdk/docs/man/html/glVertexAttribPointer.xhtml
我做了什么: 如模型所示,我尝试使用in int myBoolean;
,但结构的布尔值(已正确设置,我已检查)不是正确映射到顶点着色器中的整数(这可能是我的目的?)。
问题的模拟代码:
我的结构
struct MyStruct
...
bool myBoolean;
...
顶点着色器
#version 400 compatibility // Can be set higher if needed
in vec3 position;
//in bool myBoolean;
//in int myBoolean; -> doesn't work either
out vec4 color;
void main( void )
//if (myBoolean) // (myBool == 1) for the int
// color = vec4(1,0,0,1);
// else
color = vec4(position, 1);
//
...
;
我如何设置缓冲区:
// Build OpenGL VBO
glGenBuffers( 1, &m_glVBO );
glBindBuffer( GL_ARRAY_BUFFER, m_glVBO );
glBufferData( GL_ARRAY_BUFFER, numOfMyStructs*sizeof(MyStruct), myStructs, GL_DYNAMIC_DRAW );
// Build OpenGL VAO
glGenVertexArrays( 1, &m_glVAO );
glBindVertexArray( m_glVAO );
// Position attribute
glEnableVertexAttribArray( 0 );
glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, sizeof(myStruct), (GLvoid*)offsetof(MyStruct, position) );
// Does not work, all booleans in the vertex buffer are false
// and GL_BOOL is not allowed.
//glEnableVertexAttribArray( 1 );
//glVertexAttribPointer( 1, 1, GL_INT, GL_FALSE, sizeof(MyStruct), (GLvoid*)offsetof(MyStruct, myBoolean) );
glBindVertexArray( 0 );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
绑定着色器:
myShader = new QGLShaderProgram( QGLContext::currentContext() );
...
myShader->bindAttributeLocation( "position", 0 );
//myShader->bindAttributeLocation( "myBoolean", 1);
glBindFragDataLocation( myShader->programId(), 0, "color" );
...
渲染:(我以后想用实例渲染(一个球体)不过没关系)
...
glEnable( GL_POINT_SMOOTH );
glHint( GL_POINT_SMOOTH_HINT, GL_NICEST );
glBindVertexArray( m_glVAO );
glDrawArrays( GL_POINTS, 0, numMyStructs );
glBindVertexArray( 0 );
...
其他信息:我使用 QtCreator (3.6.1)、C++11、OpenGL (4.5)、GLM (0.9.7.4)、GLEW(1.13)、Nvidia 卡(364.16 驱动程序+ CUDA 7.5),Linux 64 位。 我是 OpenGL 新手。如果可能的话,我宁愿不使用额外的库。 没有 myBoolean 就可以正常工作(因此使用 moc-up 代码中设置的注释部分)。 moc-up 代码是为 *** 快速键入的,我对可能的语法错误表示歉意,请随时指出它们(真实世界的代码在没有 myBoolean 的情况下确实可以工作)。如果需要,我可以提供更多信息。
提前致谢。
【问题讨论】:
【参考方案1】:您可能想要glVertexAttribIPointer
(注意其中的字母“I”)-这是用于传递整数值。由于结构中的所有内容至少是字节对齐的,因此单个布尔值不能小于 GL_UNSIGNED_BYTE
https://www.opengl.org/sdk/docs/man/html/glVertexAttribPointer.xhtml
【讨论】:
"glVertexAttribPointer 和 glVertexAttribIPointer 接受符号常量 GL_BYTE、GL_UNSIGNED_BYTE、GL_SHORT、GL_UNSIGNED_SHORT、GL_INT 和 GL_UNSIGNED_INT。"让我感到困惑,我认为 glVertexAttribPointer (没有我)也可以处理整数。但是您的建议是正确的,现在可以使用,谢谢!我生命中的 10 个小时我不会回来。 没有 i,它会将它们转换为浮点数.. 我想。这就是非 I 版本中的 NORMALIZED 标志控制的内容。所以,他们被接受了,但他们的行为不同。另外,大约一周前我遇到了这种确切的情况,真是太幸运了。以上是关于Opengl顶点着色器为每个顶点设置布尔值(glVertexAttribPointer)的主要内容,如果未能解决你的问题,请参考以下文章