我试图根据OpenTK官方教程(here)实现一个简单的测试程序,但没有取得任何结果.

特别是,建议的代码允许您在不绑定纹理的情况下生成纹理和指定属性,而我发现一些答案表明,在指定任何属性之前都应该进行绑定(例如here).

因此,我try 了GL函数调用的任何组合,但我仍然没有可用的代码,但有一些见解(下面是我的最新代码):

  • 如果我之前通过激活纹理单元加载纹理,无论纹理对象的创建顺序如何,它都会始终指定纹理,但是似乎只有TextureUnit.Texture0个纹理到达片段着色器,并被指定给任何声明的sampler2D
  • 调用GL.GetUniformLocation和随后的GL.Uniform1()来分配统一索引不会在行为中产生任何可见的变化
  • 改变我叫GL.UseProgram(shader.Handle)的位置;没什么区别
  • 如上所述,片段着色器函数texture(tex0, texCoord)显示第一个纹理,因此texture(tex1, texCoord)或任何其他声明的采样器
  • mix(texture(tex0, TexCoord), texture(tex1, TexCoord), 0.2);片段着色器函数始终显示白色像素,即使在混合相同的纹理调用mix(texture(tex0, TexCoord), texture(tex0, TexCoord), 0.2);时也是如此(请注意,这样的纹理在我调用texture(tex0, texCoord)时会显示)

我没有 idea ,也找不到任何资源.

Fragment Shader Source:

#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);
}

Vertex Shader Source:

#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 Class Source:

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 Class Source (only relevant methods):

[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);
}

Loading method of the game class:

    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();
    }

Frame drawing method of the game class:

    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);
    }

推荐答案

GL.Uniform1()设置当前程序对象的标准统一块中统一变量的值.因此,您必须先安装GL.UseProgram程序,然后才能设置统一:

shader.Use();
shader.SetInt("tex0", 0);
shader.SetInt("tex1", 1);

Csharp相关问答推荐

如何禁用ASP.NET MVP按钮,以便无法使用开发人员控制台重新启用它

使用变量子根名称在C#中重新初始化SON文件

向类注入一个工厂来创建一些资源是一个好的实践吗?

不仅仅是一个简单的自定义按钮

实体框架核心上是否支持使用NPGSQL的字符串聚合?

更新产品但丢失产品ASP.NET Core的形象

Nuget包Serilog.Sinks.AwsCloudwatch引发TypeLoadExceptions,因为父类型是密封的

如何在C#中实现非抛出`MinBy`?

异步实体框架核心查询引发InvalidOperation异常

如何将字符串变量传递给JObject C#-无法加载文件或程序集';System.Text.Json

在IAsyncEnumerable上先调用,然后跳过(1)可以吗?

如何将DotNet Watch与发布配置和传递给应用程序的参数一起使用?

未在Windows上运行的Maui项目

如何使用.NET Aspire从Blazor应用程序与GRPC API通信?

如何在单击按钮后多次异步更新标签

通过mini kube中的远程调试Pod与从emoteProcessPickerScript中解析错误输出的代码错误进行比较

在C#中删除多个不同名称的会话

我是否以错误的方式使用了异步延迟初始化?

ASP.NET文件上传不接受超过10MB的文件

Firefox中的MudBlazor DataGrid单元格溢出