You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenTK多纹理绑定异常求助:仅Texture0生效且mix函数失效

多纹理渲染异常问题求助

按照OpenTK官方教程实现多纹理测试程序,始终无法得到预期结果,仅显示白色方块。移除片元着色器的mix()函数后发现,只有最后加载的纹理能传入片元着色器。注意到教程生成纹理时未绑定纹理,但部分资料显示绑定操作应在属性设置前完成,尝试多种GL函数调用组合后仍未解决,目前观察到以下现象:

  • 提前激活TextureUnit加载纹理时,仅TextureUnit.Texture0能被片元着色器的所有sampler2D采样
  • 调用GL.GetUniformLocation和GL.Uniform1设置uniform索引无可见效果
  • 调整GL.UseProgram(shader.Handle)的调用位置无变化
  • 片元着色器中texture(tex0, texCoord)能显示对应纹理,但texture(tex1, texCoord)等也显示tex0的纹理
  • 使用mix(texture(tex0, TexCoord), texture(tex1, TexCoord), 0.2)始终输出白色像素,即使混合同一个纹理也是如此

片元着色器代码

#version 330 core

in vec2 texCoord;
out vec4 outputColor;

uniform sampler2D tex0;
uniform sampler2D tex1;
uniform sampler2D tex2;

void main() {
    //outputColor = mix(texture(tex0, TexCoord), texture(tex1, TexCoord), 0.2);
    outputColor = texture(tex0, texCoord);
    //outputColor = vec4(1.0, 0.0, 0.0, 1.0);
}

顶点着色器代码

#version 330 core

layout(location = 0) in vec3 aPosition;
layout(location = 1) in vec2 aTexCoord;

out vec2 texCoord;

void main(void)
{
    texCoord = aTexCoord;
    gl_Position = vec4(aPosition, 1.0);
}

Texture类代码

internal class Texture {

public int Handle { get; private set; }

public Texture(string sourceFile, TextureUnit unit = TextureUnit.Texture0)
{

    Image<Rgba32> image = Image.Load<Rgba32>(sourceFile);
    image.Mutate(x => x.Flip(FlipMode.Vertical));
    var pixels = new byte[4 * image.Width * image.Height];
    image.CopyPixelDataTo(pixels);

    GL.ActiveTexture(unit);

    this.Handle = GL.GenTexture();
    GL.BindTexture(TextureTarget.Texture2D, this.Handle);

    GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
    GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
    GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
    GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);

    GL.TexImage2D(
            TextureTarget.Texture2D,     // Texture type
            0,                           // Level of detail
            PixelInternalFormat.Rgba,    // GPU storing format
            image.Width, image.Height,   // Width, Height
            0,                           // Border of the image, legacy param
            PixelFormat.Rgba,            // Format: ImgSharp use this
            PixelType.UnsignedByte,      // Pixel type
            pixels);                     // Actual pixels
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Use()
{
    GL.BindTexture(TextureTarget.Texture2D, this.Handle);
}

//[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Use(TextureUnit unit)
{
    // GL.ActiveTexture(unit);
    // GL.BindTexture(TextureTarget.Texture2D, this.Handle);
}

} // Texture Class

Shader类相关代码

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Use()
{
    GL.UseProgram(program);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetInt(string name, int value)
{
    int location = GL.GetUniformLocation(program, name);
    GL.Uniform1(location, value);
}

游戏类加载方法

protected override void OnLoad()
{
    GL.ClearColor(0.2f, 0.2f, 0.2f, 1.0f);

    VertexArrayObject = GL.GenVertexArray();
    VertexBufferObject = GL.GenBuffer();
    ElementBufferObject = GL.GenBuffer();

    // 1. bind Vertex Array Object
    GL.BindVertexArray(VertexArrayObject);

    // 2. copy our vertices array in a buffer for OpenGL to use
    GL.BindBuffer(BufferTarget.ArrayBuffer, VertexBufferObject);
    GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * sizeof(float), vertices, BufferUsageHint.StaticDraw);

    // 3. then set our vertex attributes pointers
    GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 5 * sizeof(float), 0);
    GL.EnableVertexAttribArray(0);
    GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 5 * sizeof(float), 3 * sizeof(float));
    GL.EnableVertexAttribArray(1);

    // Indices to ElementBufferObject
    GL.BindBuffer(BufferTarget.ElementArrayBuffer, ElementBufferObject);
    GL.BufferData(BufferTarget.ElementArrayBuffer, indices.Length * sizeof(uint), indices, BufferUsageHint.StaticDraw);

    shader = new Shader("./ShadersSrc/vshader6_textures2.glsl", "./ShadersSrc/fshader6_textures2.glsl");

    texture0 = new Texture("./Textures/src/container.jpg", TextureUnit.Texture0);
    shader.SetInt("tex0", 0);

    texture1 = new Texture("./Textures/src/awesomeface.png", TextureUnit.Texture1);
    shader.SetInt("tex1", 1);
    
    texture2 = new Texture("./Textures/src/wall.jpg", TextureUnit.Texture2);
    shader.SetInt("tex1", 2);

    base.OnLoad();
}

游戏类帧渲染方法

protected override void OnRenderFrame(FrameEventArgs e)
{
    GL.Clear(ClearBufferMask.ColorBufferBit);

    GL.BindVertexArray(VertexArrayObject);

    shader.Use();
    //texture0.Use(TextureUnit.Texture0);
    //texture1.Use(TextureUnit.Texture1);

    GL.DrawElements(PrimitiveType.Triangles, indices.Length, DrawElementsType.UnsignedInt, 0);

    Context.SwapBuffers();

    base.OnRenderFrame(e);
}

恳请各位提供解决思路。

内容的提问来源于stack exchange,提问作者MaxC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 20:18:20