OpenGL4 无法将纹理加载到 Sampler2D

OpenGL4 fails to load Texture into Sampler2D

我无法将纹理绑定到片段着色器中的 sampler2D。理论上我的程序应该用一种颜色绘制整个场景(我的图像是一个红色的 64x64 大正方形)。当使用 textureSize 获取 sampler2D 的尺寸时,它 return 1x1.

TextureID 或 SamplerLocation 都不是 return -1

我现在在做什么:

  1. 将图像加载到gpu内存中并使用loadImage()获取Location (int TextureID)。
  2. 获取我的 sampler2D 的 UniformLocation (int SamplerLocation)
  3. 在渲染方法中:绑定纹理并相应地设置统一位置

源代码:

http://neokabuto.blogspot.de/

复制的 loadImage 方法
    int loadImage(Bitmap image)
    {
        int texID = GL.GenTexture();

        GL.BindTexture(TextureTarget.Texture2D, texID);
        BitmapData data = image.LockBits(new System.Drawing.Rectangle(0, 0, image.Width, image.Height),
            ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

        GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0,
            OpenTK.Graphics.OpenGL4.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);

        image.UnlockBits(data);

        GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);

        return texID;
    }

OnLoad 方法在启动时调用一次

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        int status_code;
        string info;

        Console.Out.WriteLine(GL.GetString(StringName.Version));

        m.loadFromOBJ("C:/Users/Anwender/Downloads/lpm_yard.obj");
        m.init();

        TextureID = loadImage("C:/Users/Anwender/Desktop/test.png");

        // Setup openGL
        GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        GL.Enable(EnableCap.DepthTest);
        GL.DepthFunc(DepthFunction.Lequal);

        // Create MVP-Matrices and Camera Data
        ProjectionMatrix = Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, Width / (float)Height, 0.5f, 10000.0f);
        WorldMatrix = new Matrix4();
        ModelviewMatrix = new Matrix4();
        CameraPosition = new Vector3(0.5f, 0.5f, 0);

        defaultPickSSB = new PickSSB();
        defaultPickSSB.DepthValue = float.MaxValue;
        defaultPickSSB.PickIndex = -1;

        string VertexSource = File.ReadAllText("C:/Users/Anwender/Source/Repos/ShaderDemo/ShaderDemo/Shader/vs.glsl");
        string FragmentSource = File.ReadAllText("C:/Users/Anwender/Source/Repos/ShaderDemo/ShaderDemo/Shader/fr.glsl");

        // Create Shaders
        int VertexID = GL.CreateShader(ShaderType.VertexShader);
        int FragmentID = GL.CreateShader(ShaderType.FragmentShader);

        // Compile vertex shader
        GL.ShaderSource(VertexID, VertexSource);
        GL.CompileShader(VertexID);
        GL.GetShaderInfoLog(VertexID, out info);
        GL.GetShader(VertexID, ShaderParameter.CompileStatus, out status_code);

        if (status_code != 1)
            throw new ApplicationException(info);

        // Compile fragment shader
        GL.ShaderSource(FragmentID, FragmentSource);
        GL.CompileShader(FragmentID);
        GL.GetShaderInfoLog(FragmentID, out info);
        GL.GetShader(FragmentID, ShaderParameter.CompileStatus, out status_code);

        if (status_code != 1)
            throw new ApplicationException(info);

        // Create and Link Program
        Program = GL.CreateProgram();
        GL.AttachShader(Program, FragmentID);
        GL.AttachShader(Program, VertexID);

        GL.BindFragDataLocation(Program, 0, "color");

        GL.LinkProgram(Program);

        GL.UseProgram(Program);

        // Get Buffer Locations
        PickColorLocation = GL.GetAttribLocation(Program, "vertex_pick_index");
        PositionLocation = GL.GetAttribLocation(Program, "vertex_position");
        NormalLocation = GL.GetAttribLocation(Program, "vertex_normal");
        ColorLocation = GL.GetAttribLocation(Program, "vertex_color");
        UniformMVPMatrixLocation = GL.GetUniformLocation(Program, "mvp_matrix");
        UniformMouseXLocation = GL.GetUniformLocation(Program, "mouse_x");
        UniformMouseYLocation = GL.GetUniformLocation(Program, "mouse_y");
        SamplerLocation = GL.GetUniformLocation(Program, "main_texture");


        GL.GenBuffers(1, out SSB);
        GL.BindBuffer(BufferTarget.ShaderStorageBuffer, SSB);
        GL.BufferData(BufferTarget.ShaderStorageBuffer, (IntPtr)(4 * sizeof(float)), ref defaultPickSSB, BufferUsageHint.DynamicCopy);
        GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 0, SSB);

        GL.UseProgram(0);
    }

OnRenderFrame 方法

    protected override void OnRenderFrame(FrameEventArgs e)
    {
        base.OnRenderFrame(e);

        GL.Viewport(0, 0, Width, Height);
        GL.ClearColor(0.0f, 0.8f, 0.8f, 1.0f);
        GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

        GL.UseProgram(Program);

        GL.BindTexture(TextureTarget.Texture2D, TextureID);
        GL.Uniform1(SamplerLocation, TextureID);

        m.draw(PositionLocation, NormalLocation, ColorLocation, PickColorLocation);

        GL.UseProgram(0);

        SwapBuffers();
    }

我的片段着色器:

#version 430
in vec4 frag_color;
in vec4 gl_FragCoord;
flat in int frag_pick_index;

out vec4 color;

layout (std430, binding = 0) buffer mouse_color { int pick_index; float depth_value; };

uniform int mouse_x;
uniform int mouse_y;
uniform sampler2D main_texture;

void main(void)
{       
    if (int(gl_FragCoord.x) == mouse_x && int(gl_FragCoord.y) == mouse_y) {
        if (gl_FragCoord.z < depth_value) 
        {
            pick_index = frag_pick_index;
            depth_value = gl_FragCoord.z;
        }
    }

    // pick_index = textureSize(main_texture, 0).y;

    if (int(gl_FragCoord.x) == mouse_x || int(gl_FragCoord.y) == mouse_y) {
        color = vec4(0.0f, 1,0,1.0f);
    } else {
        color = frag_color;
    }

    color = texture(main_texture, vec2(0.5f, 0.5f));
}

您传递给采样器的整数必须是纹理绑定到的纹理单元的索引,而不是纹理ID。除非你在某处调用 GL.ActiveTexture,否则活动纹理单元是 TextureUnit.Texture0,这意味着你必须将 0 传递给 GL.Uniform1:

GL.ActiveTexture(TextureUnit.Texture0);
GL.BindTexture(TextureTarget.Texture2D, TextureID);
GL.Uniform1(SamplerLocation, 0);