【问题标题】:Why can't I set Texture Wrap parameters using OpenGL in C#? (SharpGL dll)为什么我不能在 C# 中使用 OpenGL 设置 Texture Wrap 参数? (SharpGL DLL)
【发布时间】:2017-12-13 05:39:31
【问题描述】:

我一直在构建一种方法,使用 SharpGL 在 WPF 应用程序中为数字地形模型的顶点着色(我是澳大利亚人)。我面临的问题是,我似乎无法使用附加到活动 OpenGL 实例的 TexParameter 方法将 GL_TEXTURE_WRAP_T 和 S 参数更改为 GL_REPEAT 以外的任何参数。

如果我无法将纹理环绕设置为 GL_CLAMP_TO_EDGE,那么在访问最低颜色时我会得到最高颜色的出血,除非我将纹理坐标偏移半个像素(这很笨重,但我知道它会起作用)。

窗口当前呈现如下:

Current wrong result

当它的中间三分之一应该是彩虹,上三分之一是纯红色,下三分之一是蓝色。

我知道我正确使用了 TexParameter 方法,因为我可以成功操作同一纹理的 GL_TEXTURE_MIN_FILTER 和 GL_TEXTURE_MAG_FILTER 参数。我唯一能想到的是,需要在 OpenGL 实例中启用某些功能才能更改纹理包装参数。

我附上了整个 C# 测试代码和 WPF xaml 代码,以便能够重现问题。第 52 和 53 行是调用该方法的位置。我将不胜感激。

using SharpGL;
using System.Windows;
using System.Drawing;
using SharpGL.SceneGraph.Assets;

namespace WpfApplication3
{
    public partial class MainWindow : Window
    {
        Bitmap bitmap;
        Texture texture;

        public MainWindow()
        {
            InitializeComponent();

            //Create a 5-pixel wide bitmap to be used as the texture
            bitmap = new Bitmap(5, 1);
            bitmap.SetPixel(0, 0, Color.Red);
            bitmap.SetPixel(1, 0, Color.Yellow);
            bitmap.SetPixel(2, 0, Color.Green);
            bitmap.SetPixel(3, 0, Color.Cyan);
            bitmap.SetPixel(4, 0, Color.Blue);
        }

        private void GLDraw(object sender, SharpGL.SceneGraph.OpenGLEventArgs args)
        {
            OpenGL gl = args.OpenGL;

            //  Clear the color and depth buffers.
            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);

            //Set an ortho projection to be able to see the entire square
            gl.MatrixMode(OpenGL.GL_PROJECTION);
            gl.LoadIdentity();
            gl.Ortho(-2, 2, -2, 2, -2, 2);

            gl.MatrixMode(OpenGL.GL_MODELVIEW);

            //  Reset the modelview.
            gl.LoadIdentity();

            texture.Bind(gl);

            gl.Enable(OpenGL.GL_TEXTURE_2D);

            gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_T, OpenGL.GL_CLAMP_TO_EDGE);
            gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_S, OpenGL.GL_CLAMP_TO_EDGE);
            //gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MIN_FILTER, OpenGL.GL_NEAREST);
            //gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MAG_FILTER, OpenGL.GL_NEAREST);

            //Draw the square
            gl.Begin(OpenGL.GL_QUADS);

            gl.Color(1.0f, 1.0f, 1.0f, 1.0f);

            //Texture coordinate outside of 0-1 range to test wrapping method
            gl.TexCoord(-1, 0.5);
            gl.Vertex(1.0f, 1.0f, 1.0f);
            gl.Vertex(-1.0f, 1.0f, 1.0f);
            //Texture coordinate outside of 0-1 range to test wrapping method
            gl.TexCoord(2, 0.5);
            gl.Vertex(-1.0f, -1.0f, 1.0f);
            gl.Vertex(1.0f, -1.0f, 1.0f);

            gl.End();

            gl.Disable(OpenGL.GL_TEXTURE_2D);

            //  Flush OpenGL.
            gl.Flush();
        }

        private void GLInitialize(object sender, SharpGL.SceneGraph.OpenGLEventArgs args)
        {
            OpenGL gl = args.OpenGL;
            gl.Enable(OpenGL.GL_DEPTH_TEST);
            gl.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);

            texture = new Texture();
            texture.Create(gl, bitmap);
        }
    }
}

这是 xaml 代码:

<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication3"
        xmlns:sharpGL="clr-namespace:SharpGL.WPF;assembly=SharpGL.WPF"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <sharpGL:OpenGLControl OpenGLVersion="OpenGL3_2" OpenGLDraw="GLDraw" OpenGLInitialized="GLInitialize" Cursor="Cross"
                               Background="Transparent"/>
    </Grid>
</Window>

【问题讨论】:

    标签: c# wpf opengl textures sharpgl


    【解决方案1】:

    我找到了答案。我使用的 OpenGL 版本不支持“GL_CLAMP_TO_EDGE”进行纹理包装,并且代码在将其更改为简单的“GL_CLAMP”(较旧的等效项)后工作。

    编辑:我找到了一个答案,但不完整。

    【讨论】:

    • 不等价;这就是为什么它有不同的名称。 GL_CLAMP 夹在边界纹素上。 GL_CLAMP_TO_EDGE 夹在纹理的边缘。
    • 使用 GL_CLAMP_TO_EDGE 并没有做任何事情,GL_CLAMP_TO_BORDER 也没有。我认为夹紧到边界将外部 0-1 范围纹理坐标设置为预设颜色?
    • 我说的是“夹到边界 texels”。早在 GL 1.1 时代,纹理就有“边界纹素”的概念。您可以在纹理边缘周围提供额外的像素,只有在您使用GL_CLAMP 时才会从中采样。也就是说,不是单一的边框颜色(GL_CLAMP_TO_BORDER 所做的)或钳制到纹理边缘(GL_CLAMP_TO_EDGE 所做的),而是钳制到最接近采样点的边框纹素。所以它们是不等价的。
    • 啊,我明白了。那么知道为什么 GL_CLAMP_TO_EDGE 没有为我做任何事情吗?我上面的问题?我使用的是 OpenGL 3.1 版,所以应该支持它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-16
    • 1970-01-01
    • 2010-10-05
    • 1970-01-01
    • 2012-02-23
    相关资源
    最近更新 更多