我在openTK
中使用统一块时遇到一些问题。我从“OpenGL着色语言手册”(source code)中举了一个例子。
档案:scenebasic_uniformblock.cpp
成功编译并成功连接着色器。
Fragment Shader:
#version 400
// in-Parameter
in vec3 TexCoord;
// out-Parameter
layout (location = 0) out vec4 FragColor;
uniform BlobSettings
{
vec4 InnerColor;
vec4 OuterColor;
float RadiusInner;
float RadiusOuter;
} Blob;
void main()
{
float dx = TexCoord.x - 0.5;
float dy = TexCoord.y - 0.5;
float dist = sqrt(dx * dx + dy * dy);
FragColor = mix(Blob.InnerColor, Blob.OuterColor, smoothstep(Blob.RadiusInner, Blob.RadiusOuter, dist));
}
顶点着色器:
#version 400
// in-Parameter
layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexTexCoord;
// out-Parameter
out vec3 TexCoord;
void main()
{
TexCoord = VertexTexCoord;
gl_Position = vec4(VertexPosition, 1.0);
}
现在我有以下代码:
// Get the index of the uniform block
var blockIndex = GL.GetUniformBlockIndex(program.Handle, "BlobSettings");
// Allocate space for the buffer
int blockSize;
GL.GetActiveUniformBlock(program.Handle, blockIndex,
ActiveUniformBlockParameter.UniformBlockDataSize, out blockSize);
//var blockBuffer = new IntPtr[blockSize];
var blockBuffer = new IntPtr();
// Query for the offsets of each block variable
var names = new [] { "BlobSettings.InnerColor", "BlobSettings.OuterColor",
"BlobSettings.RadiusInner", "BlobSettings.RadiusOuter" };
var indices = new int[4];
GL.GetUniformIndices(program.Handle, 4, names, indices);
var offset = new int[4];
GL.GetActiveUniforms(program.Handle, 4, indices,
ActiveUniformParameter.UniformOffset, offset);
// Store data within the buffer at the appropriate offsets
var outerColor = new[] {0.0f, 0.0f, 0.0f, 0.0f};
var innerColor = new[] {1.0f, 1.0f, 0.75f, 1.0f};
var innerRadius = 0.25f;
var outerRadius = 0.45f;
// Here is the problem...
Marshal.Copy(innerColor, offset[0], blockBuffer, 4*sizeof(float));
// Create the buffer object and copy the data
int uboHandle;
GL.GenBuffers(1, out uboHandle);
GL.BindBuffer(BufferTarget.UniformBuffer, uboHandle);
GL.BufferData(BufferTarget.UniformBuffer,
(IntPtr)blockSize, (IntPtr)blockBuffer, BufferUsageHint.DynamicDraw);
GL.BindBufferBase(BufferRangeTarget.UniformBuffer, 1, uboHandle);
在//这是问题所在。我不知道进一步。我如何填充缓冲区? 在c ++中,我有函数memcpy,但是如何在C#中执行此操作?
感谢。
答案 0 :(得分:0)
GL.BufferData
有一个泛型重载,需要struct
引用或数组。
struct BlobSettings
{
public Vector4 OuterColor;
public Vector4 InnerColor;
public float InnerRadius;
public float OuterRadius;
public static readonly int Size =
BlittableValueType<BlobSettings>.Stride;
}
// ...
// Store data within the buffer at the appropriate offsets
var blockBuffer = new BlobSettings
{
OuterColor = new Vector4(0.0f, 0.0f, 0.0f, 0.0f),
InnerColor = new Vector4(1.0f, 1.0f, 0.75f, 1.0f),
InnerRadius = 0.25f,
OuterRadius = 0.45f
};
// ...
GL.BufferData(BufferTarget.UniformBuffer,
(IntPtr)BlockSettings.Size,
ref blockBuffer,
BufferUsageHint.DynamicDraw);
编辑:这假设您使用的是std140布局。如果没有,您可能必须使用[StructLayout(LayoutKind.Explicit)]
声明C#结构,以确保字段偏移与统一块布局匹配。