首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用ImageSharp加载的纹理显示为白色(opentk)

使用ImageSharp加载的纹理显示为白色(opentk)
EN

Stack Overflow用户
提问于 2018-04-11 23:21:45
回答 1查看 822关注 0票数 2

在ImageSharp的帮助下加载图像,然后将其加载到vram中,它只渲染了一个白色四边形。我基本上不知道我可能做错了什么,这是第一次使用opentk跨平台,而不是使用BitmapData

纹理类:

public struct Texture2D
{
    public readonly int Handle;
    public readonly int Width;
    public readonly int Height;

    public Texture2D(int[] data, int width, int height)
    {
        Width = width;
        Height = height;

        GL.Enable(EnableCap.Texture2D);
        GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest);
        Handle = GL.GenTexture();
        GL.BindTexture(TextureTarget.Texture2D, Handle);

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

        unsafe
        {
            fixed (int* dataptr = data)
                GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, Width, Height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, (IntPtr)dataptr);
            GL.BindTexture(TextureTarget.Texture2D, 0);
        }

        GL.Disable(EnableCap.Texture2D);
    }

    public static implicit operator int(Texture2D texture) => texture.Handle;

    public static Texture2D FromFile(string file) => FromImage(Image.Load(Path.Combine("resources", file)));

    public static Texture2D FromImage(Image<Rgba32> image)
    {
        var xL = image.Width;
        var yL = image.Height;
        var data = new int[image.Width * image.Height];
        for (var x = 0; x < xL; x++)
            for (var y = 0; y < yL; y++)
                data[y * xL + x] = image[x, y].R << 24 | image[x, y].G << 16 | image[x, y].B << 8 | image[x, y].A;
        return new Texture2D(data, image.Width, image.Height);
    }
}

渲染:

GL.Clear(ClearBufferMask.ColorBufferBit);
GL.PushMatrix();
GL.Begin(PrimitiveType.Quads);
{
    GL.BindTexture(TextureTarget.ProxyTexture2D, loadingTex.Handle);

    var x = app.Width - loadingTex.Width;
    var x2 = app.Width;
    var y = 0;
    var y2 = loadingTex.Height;

    GL.TexCoord2(0, 0);
    GL.Vertex2(x, 0);

    GL.TexCoord2(0, 1);
    GL.Vertex2(x2, 0);

    GL.TexCoord2(1, 1);
    GL.Vertex2(x2, y2);

    GL.TexCoord2(1, 0);
    GL.Vertex2(x, loadingTex.Height);
}
GL.End();
GL.PopMatrix();
GL.Flush();
SwapBuffers();

loadingTex是引用纹理的静态变量

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-10 06:38:57

这只是.net核心,它适用于.net框架,但有更好的解决方案。

经过大量的研究,我找到了我的答案。

简而言之:GL.TexImage2D接受图像中所有颜色的数组。

长长的答案是:

  1. 从图像中获取这样的数组。

嗯,实际上这很容易。但是这需要您使用SixLabors中的ImageSharp库,但是如果您找到一个类似的库,您可以随意使用它。

第一步是,将图像作为Image<Rgba32>加载到。然后,您需要将图像数据放入一维(int)数组中。每个int的结构应该是这样的ABGR。

示例:

var xL = image.Width;
var yL = image.Height;
var data = new int[image.Width * image.Height];
for (var x = 0; x < xL; x++)
    for (var y = 0; y < yL; y++)
    {
        var color = image[x, y];
        data[y * xL + x] = (color.A << 24) | (color.B << 16) | (color.G << 8) | (color.R << 0);
    }

这段代码遍历图像的每个像素,并将其写入int数组。

  1. 将其加载到内存中(使用不安全代码)(这只涉及到GL.TexImage2D)

现在,我们需要使用fixed语句获取指向该数组的指针

fixed (int* dataptr = data)

此语句需要一个正文!

GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, Width, Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, (IntPtr) dataptr);

然后这个把它加载到VRam中。让我们跳过前两个参数,我不需要为这个问题解释它们。第三个参数PixelInternalFormat.Rgba告诉gpu如何将每个像素存储到V-Ram中。接下来的两个是告诉gpu图像的尺寸。目前,参数6并不重要。下一个参数PixelFormat.Rgba告诉gpu您正在以什么格式传递像素。现在我们有了PixelType.UnsignedByte,它告诉图形处理器像素的一部分有多大(红、蓝、绿和阿尔法都是像素的一部分),而不是像素本身的大小。最后,将数据本身作为IntPtr传递,这基本上是一个通用指针,可以传递给本地库。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49778884

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档