c# - OpenTK 中的 Sprite Sheet 动画

标签 c# opentk

我一直在尝试制作我的第一个游戏引擎(在 OpenTK 中,但我被卡住了。我正在尝试合并动画,并且我正在尝试使用 Sprite 表,因为它们会大大减小文件大小。

我知道我需要使用 for 循环来按顺序绘制所有 Sprite ,但我不知道应该做什么才能使其与 Sprite 表一起使用。


这是我当前的绘图代码:

    //The Basis fuction for all drawing done in the application
    public static void Draw (Texture2D texture, Vector2 position, Vector2 scale, Color color, Vector2 origin, RectangleF? SourceRec = null)
    {
        Vector2[] vertices = new Vector2[4]
        {
            new Vector2(0, 0),
            new Vector2(1, 0),
            new Vector2(1, 1),
            new Vector2(0, 1),
        };

        GL.BindTexture(TextureTarget.Texture2D, texture.ID);

        //Beginning to draw on the screen
        GL.Begin(PrimitiveType.Quads);

        GL.Color3(color);
        for (int i = 0; i < 4; i++)
        {

                GL.TexCoord2((SourceRec.Value.Left + vertices[i].X * SourceRec.Value.Width) / texture.Width, (SourceRec.Value.Left + vertices[i].Y * SourceRec.Value.Height) / texture.Height);

            vertices[i].X *= texture.Width;
            vertices[i].Y *= texture.Height;
            vertices[i] -= origin;
            vertices[i] *= scale;
            vertices[i] += position;

            GL.Vertex2(vertices[i]);
        }

        GL.End();
    }

    public static void Begin(int screenWidth, int screenHeight)
    {
        GL.MatrixMode(MatrixMode.Projection);
        GL.LoadIdentity();
        GL.Ortho(-screenWidth / 2, screenWidth / 2, screenHeight / 2, -screenHeight / 2, 0f, 1f);
    }

先谢谢了!!! :)

最佳答案

首先,我求求你,放弃固定的功能管道。它会蒙蔽你的双眼,限制你的理解力和创造力。转向核心3.1+,它的结构完美与它的潜力相匹配,协作的深思熟虑和创新将真正打动你。

现在,您需要将 Sprite 表图像存储为 Texture2DArray。我花了一些时间才弄清楚如何正确加载这些:

public SpriteSheet(string filename, int spriteWidth, int spriteHeight)
{
    // Assign ID and get name
    this.textureID = GL.GenTexture();
    this.spriteSheetName = Path.GetFileNameWithoutExtension(filename);

    // Bind the Texture Array and set appropriate parameters
    GL.BindTexture(TextureTarget.Texture2DArray, textureID);
    GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
    GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
    GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
    GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);

    // Load the image file
    Bitmap image = new Bitmap(@"Tiles/" + filename);
    BitmapData data = image.LockBits(new System.Drawing.Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

    // Determine columns and rows
    int spriteSheetwidth = image.Width;
    int spriteSheetheight = image.Height;
    int columns = spriteSheetwidth / spriteWidth;
    int rows = spriteSheetheight / spriteHeight;

    // Allocate storage
    GL.TexStorage3D(TextureTarget3d.Texture2DArray, 1, SizedInternalFormat.Rgba8, spriteWidth, spriteHeight, rows * columns);

    // Split the loaded image into individual Texture2D slices
    GL.PixelStore(PixelStoreParameter.UnpackRowLength, spriteSheetwidth);
    for (int i = 0; i < columns * rows; i++)
    {
        GL.TexSubImage3D(TextureTarget.Texture2DArray,
                         0, 0, 0, i, spriteWidth, spriteHeight, 1,
                         OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte,
                         data.Scan0 + (spriteWidth * 4 * (i % columns)) + (spriteSheetwidth * 4 * spriteHeight * (i / columns)));     // 4 bytes in an Bgra value.
    }
    image.UnlockBits(data);
}

然后你可以简单地绘制一个四边形,Z纹理坐标就是Texture2DArray中的Texture2D索引。注意 frag_texcoord 的类型为 vec3

#version 330 core

in vec3 frag_texcoord;
out vec4 outColor;

uniform sampler2DArray tex;

void main()
{
    outColor = texture(tex, vec3(frag_texcoord));
}

关于c# - OpenTK 中的 Sprite Sheet 动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40290790/

相关文章:

c# - 查看模型我们是检查 setter 中的相等性,还是总是设置和通知?

c# - 使用 LINQ 将列表投影到键/计数二维数组

c# - 我如何在 dot net Core 中排列应用程序 dll 文件

c# - Console.ReadLine 将 48 添加到 int

c# - 如何在 OpenTK 中使对象透明

c# - 我想从数据库中检索图像并根据用户需要裁剪它

c# - 如何使用 CodeXL 分析 OpenTK C# 应用程序?

c# - 如何使用 OpenTK 正确绘制多边形

c# - 在 OpenTK 上绑定(bind)多个纹理的正确方法是什么?

c# - 如何在单独的opengl数组对象中正确渲染网格?