2016-10-27 8 views
1

Ich habe versucht, meine allererste Spiel-Engine (in OpenTK und Im stecken. Ich versuche, Animationen zu inkzeptieren und ich versuche, Sprite-Blätter zu verwenden, weil sie Dateigröße erheblich verringern würde.Sprite Sheet Animation in OpenTK

ich weiß, dass ich eine for-Schleife verwenden, müssen alle Sprites in Folge zu ziehen, aber ich nicht einen Anhaltspunkt über das, was ich tun sollte, um es mit spritesheets arbeiten zu lassen.


Hier ist meine aktuelle Zeichnung code:

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

Vielen Dank im Voraus !!! :)

Antwort

1

Erstens, ich bitte Sie, verlassen Sie die feste Funktion Pipeline. Es blendet Sie und schränkt Ihr Verständnis und Ihre Kreativität ein. Gehen Sie zu Core 3.1+ über, es ist strukturelle Perfektion, die nur durch ihre Potentialität erreicht wird, und die kollaborative Voraussicht und Innovation wird Sie wirklich bewegen.

Jetzt möchten Sie Ihre Sprite-Sheet-Bilder als Texture2DArray speichern. Es dauerte einige Zeit, um herauszufinden, wie diese richtig zu laden:

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

Dann können Sie einfach ein Quad zeichnen, und das Z-Textur-Koordinate ist der Texture2D Index im Texture2DArray. Hinweis frag_texcoord ist vom Typ vec3.

#version 330 core 

in vec3 frag_texcoord; 
out vec4 outColor; 

uniform sampler2DArray tex; 

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

Danke !! Das hat gut für mich funktioniert und ich werde Ihren Rat beherzigen, keine feste Funktionspipeline zu verwenden. Danke noch einmal!! –

+0

Schön, ich freue mich, Ihnen etwas Zeit zu sparen. –