有人能告诉我在glVertexAttribPointer()中我们如何使用GL_INT_2_10_10_10_REV作为类型参数? 我试图使用此类型传递颜色值。此类型中“REV”后缀的含义是什么?是否需要在着色器中进行任何特殊处理?
我的代码如下:
GLuint red=1023,green=1023,blue=1023,alpha=3;
GLuint val = 0;
val = val | (alpha << 30);
val = val | (blue << 20);
val = val | (green << 10);
val = val | (red << 0);
GLuint test_data[]={val,val,val,val};
loadshaders();
glBindAttribLocation(ps,0,"tk_position");
glBindAttribLocation(ps,1,"color");
LinkShader();
glUseProgram(ps);
glEnableVertexAttribArray (0);
glVertexAttribPointer(0, 4, GL_FLOAT, 0, 0, vertices);
glEnableVertexAttribArray (1);
glVertexAttribPointer(1,GL_BGRA,GL_UNSIGNED_INT_2_10_10_10_REV,GL_TRUE,0,test_data);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
着色器是: 顶点着色器 -
#version 150
in vec4 tk_position;
in vec4 color;
out vec4 v_color;
void main()
{
v_color = color;
gl_Position = tk_position;
}
片段着色器 -
#version 150
in vec4 v_color;
out vec4 fragColor;
void main()
{
fragColor = v_color;
}
程序对象也经过验证。没问题。这段代码在AMD卡上工作正常,但在NVidia上失败了。失败意味着我在glDrawArrays()调用时获得NULL指针访问。
Access violation
Exception Flag: 0x00000000
Exception Addr: 0x055f32ce
答案 0 :(得分:16)
如果你传递颜色,那么你很可能想要 UNSIGNED _ INT_2_10_10_10_REV。所以我会假装这就是你所要求的。
整个字段打包成一个无符号整数。 OpenGL将无符号整数定义为大小为32位,因此您应该使用OpenGL提供的GLuint
typedef来获取它。
但是,这种格式是打包,因此您不能只将数组推入其中。它是一种压缩形式,因此当您认真考虑使顶点属性数据变小时,通常会使用它。
首先,将10/10/10/2用于颜色的唯一原因是,如果您的原始源颜色具有比例如常规的每通道8位颜色更高的颜色深度颜色。毕竟,RGB组件每个都有10位;如果你的源颜色只有8位,你实际上并没有获得任何新信息。
因此,假设您有一些具有浮点精度的浮点颜色值。您必须将每个组件标准化为[0,1]范围。然后将每个值乘以2 10 - 1,从而扩展到[0,1023]范围。然后将每个组件转换为整数。
问题在于将其打包到实际领域。名称中的“REV
”表示组件的顺序受到尊重。通常在OpenGL中,如果你看到像GL_UNSIGNED_SHORT_5_6_5
这样的格式,那么这意味着每个无符号短路被分解成5位的模式,接着是6位,接着是5位。最左边的5位字段是红色,6位字段是绿色,最右边的5位字段是蓝色。
“REV
”意味着反过来。所以2_10_10_10_REV
意味着两个最重要的位转到 alpha 。接下来的10位转到蓝色。然后是格林。然后是红色。
所以你必须在[0,1023]范围内捆绑整数,然后将它们推到GLuint值的正确位置。你可以为数组中的每个这样的组件做到这一点。
GLuint val = 0;
val = val | (alpha << 30);
val = val | (blue << 20);
val = val | (green << 10);
val = val | (red << 0);
此代码假定alpha
只有2个非零位,blue
,green
和red
每个只有10个非零位。
答案 1 :(得分:4)
因此,让我们将其分解为可理解的部分:
INT
表示格式将被读取为整数。
2_10_10_10
意味着第一个int的比特分为2比特,下一个比特为10比特。请注意,这些值加起来为32,即4字节整数中的比特数。
REV
表示组件的顺序相反。
修改强>
另外,我发现this cool page的表格可以准确地显示哪些位代表哪些值。该网站主要使用日语,但表格均为英文。
编辑2
上述页面的链接已失效,here是另一个页面,其中包含如何布置值的表格。