繁体   English   中英

在openTK中创建统一的着色器块

[英]Create uniform shader blocks in openTK

我在openTK中使用统一块时openTK一些问题。 我从“ OpenGL Shading Language Cookbook”( 源代码 )中举了一个例子。

文件: scenebasic_uniformblock.cpp

成功编译并链接着色器后。

片段着色器:

#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#中做到这一点?

谢谢。

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#结构,以确保字段偏移量与统一块布局匹配。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM