mav*_*888 1 opengl glsl vertex-attributes
谁能告诉我在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);
Run Code Online (Sandbox Code Playgroud)
着色器是:顶点着色器 -
#version 150
in vec4 tk_position;
in vec4 color;
out vec4 v_color;
void main()
{
v_color = color;
gl_Position = tk_position;
}
Run Code Online (Sandbox Code Playgroud)
片段着色器 -
#version 150
in vec4 v_color;
out vec4 fragColor;
void main()
{
fragColor = v_color;
}
Run Code Online (Sandbox Code Playgroud)
程序对象也经过验证.没问题.这段代码在AMD卡上工作正常,但在NVidia上失败了.失败意味着我在glDrawArrays()调用时得到NULL指针访问.
Access violation
Exception Flag: 0x00000000
Exception Addr: 0x055f32ce
Run Code Online (Sandbox Code Playgroud)
Nic*_*las 16
如果你传递颜色,那么你很可能想要UNSIGNED_ INT_2_10_10_10_REV.所以我会假装这就是你所要求的.
整个字段打包成一个无符号整数.OpenGL将无符号整数定义为32位大小,因此您应该使用GLuintOpenGL提供的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);
Run Code Online (Sandbox Code Playgroud)
此代码假定alpha仅有2个非零位,和blue,green和red每个都具有唯一的10个非零比特.