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
相关产品推荐
相关产品推荐

