我可以将着色器作为4个浮点数发送给着色器 - 没问题。但是我想将它作为整数(或无符号整数,无关紧要,重要的是32位)发送,并在着色器上的vec4中进行分解。
我正在使用OpenTK作为OpenGL的C#包装器(虽然它应该只是一个直接的包装器)。
让我们考虑一个最简单的着色器,顶点包含位置(xyz)和颜色(rgba)。
顶点着色器:
#version 150 core
in vec3 in_position;
in vec4 in_color;
out vec4 pass_color;
uniform mat4 u_WorldViewProj;
void main()
{
gl_Position = vec4(in_position, 1.0f) * u_WorldViewProj;
pass_color = in_color;
}
片段着色器:
#version 150 core
in vec4 pass_color;
out vec4 out_color;
void main()
{
out_color = pass_color;
}
让我们创建顶点缓冲区:
public static int CreateVertexBufferColor(int attributeIndex, int[] rawData)
{
var bufferIndex = GL.GenBuffer();
GL.BindBuffer(BufferTarget.ArrayBuffer, bufferIndex);
GL.BufferData(BufferTarget.ArrayBuffer, sizeof(int) * rawData.Length, rawData, BufferUsageHint.StaticDraw);
GL.VertexAttribIPointer(attributeIndex, 4, VertexAttribIntegerType.UnsignedByte, 0, rawData);
GL.EnableVertexAttribArray(attributeIndex);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
return bufferIndex;
}
而且我在顶点着色器中为vec4'in_color'得到全零。不确定是什么问题。
同样在VertexAttribIPointer中我传递0作为一个步幅,因为我确实有VertexBufferArray并保持数据分开。因此每个顶点的颜色紧紧包装32位(每种颜色)。
当着色器中的输入为浮点数(vec4)时,必须使用VertexAttribPointer而不是VertexAttribIPointer。
将规范化参数设置为GL_TRUE。
规格说:
glVertexAttribPointer,如果规范化设置为GL_TRUE,则表示以整数格式存储的值将映射到范围[-1,1](对于有符号值)或[0,1](对于无符号值)访问并转换为浮点。否则,值将直接转换为浮点数而不进行标准化。
Aight,所以这对我有用了:
管理数据为int[]
,其中紧密排列的颜色阵列(其中int
格式为:RGBA
意为0xAABBGGRR
),然后将顶点属性定义为:GL.VertexAttribPointer(index, 4, VertexAttribPointerType.UnsignedByte, true, sizeof(int), IntPtr.Zero)
并在着色器中使用它:in vec4 in_color;
。