Add background image tileset support, some demo

This commit is contained in:
Chris N 2016-04-13 17:40:35 -10:00
parent c6aa1cbede
commit ae6c0af73a
11 changed files with 218 additions and 4 deletions

@ -0,0 +1,121 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using System.Drawing;
using System.IO;
namespace JustTheBasics
{
class BGTile
{
// Member variables
// Var for storing position (in pixels) on the screen
public Vector3 Position = Vector3.Zero;
// Store the factor by which the image is magnified or shrunk
public Vector3 Scale = Vector3.One;
// Number of vertices in a Quad
public int VertCount = 4;
// Number of indices for each array associated with this object
public int IndiceCount = 4;
// Number of colors specified for vertices (only when not drawing an image)
public int ColorDataCount = 4;
// OpenTK Matrices pertaining to storing the Sprite's properties as seen by the viewer
public Matrix4 ModelMatrix = Matrix4.Identity;
public Matrix4 ViewProjectionMatrix = Matrix4.Identity;
public Matrix4 ModelViewProjectionMatrix = Matrix4.Identity;
// Variables pertaining to whether an image texture is applied, and what it is
public bool IsTextured = true;
public int TextureID;
public int TextureCoordsCount;
// Variable to determine if the background image should be tiled in case it is too
// small for the window.
public bool repeat = true;
// Variables to hold the speed at which backgrounds should scroll as the camera moves
public float scrollX = 0.0f;
public float scrollY = 0.0f;
// Variable for tile size
public int tSize;
// Variable for tile index
public Vector2 index;
// Additional variables for scaling to viewport
public int Height = 0;
public int Width = 0;
// Function to return the coordinates of the quad's corners, in normalized screen space. (-1 ~ 1)
public Vector3[] GetVerts()
{
return new Vector3[] { new Vector3(-1f, -1f, 0f),
new Vector3( 1f, -1f, 0f),
new Vector3( 1f, 1f, 0f),
new Vector3( -1f, 1f, 0f)};
}
// Overload of above that takes window dimensions so the sprite is scaled to viewport
public Vector3[] GetVerts(float wWidth, float wHeight)
{
return new Vector3[] { new Vector3(-1f, -1f, 0f),
new Vector3( -1f + (tSize/wWidth), -1f, 0f),
new Vector3( -1f + (tSize/wWidth), -1f + (tSize/wHeight), 0f),
new Vector3( -1f, -1f + (tSize/wHeight), 0f)};
}
// Generate the int indices for a large array containing the vertices of every quad in the scene.
// The reason for this is that OpenTK uses unique indices for every visible object. Hence,
// we need to factor in an offset from the total number of verts already processed, and
// thereby prevent draw errors from OpenTK.
public int[] GetIndices(int offset = 0)
{
int[] inds = new int[] {
0, 1, 2, 3
};
if (offset != 0)
{
for (int i = 0; i < inds.Length; i++)
{
inds[i] += offset;
}
}
return inds;
}
// Return the coords for the corners of the texture as related to the quad's coords.
// This function assumes covering the whole quad.
public Vector2[] GetTextureCoords()
{
return new Vector2[]
{
new Vector2((tSize*index.X)/Width, (tSize*index.Y)/Height),
new Vector2(((tSize*index.X) + tSize)/Width, (tSize*index.Y)/Height),
new Vector2(((tSize*index.X) + tSize)/Width, ((tSize*index.Y) + tSize)/Height),
new Vector2((tSize*index.X)/Width, ((tSize*index.Y) + tSize)/Height)
};
}
// Get the color of each vertex. These will blend in the intermediate space.
public Vector3[] GetColorData()
{
return new Vector3[] { new Vector3(1f, 0f, 0f),
new Vector3( 0f, 0f, 1f),
new Vector3( 0f, 1f, 0f),
new Vector3( 1f, 1f, 1f)};
}
// Update the projection to the camera based on position and scale.
public void CalculateModelMatrix()
{
ModelMatrix = Matrix4.CreateScale(Scale) * Matrix4.CreateTranslation(Position);
}
}
}

Binary file not shown.

Before

(image error) Size: 7.3 KiB

After

(image error) Size: 34 KiB

@ -47,6 +47,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Background.cs" />
<Compile Include="BGTile.cs" />
<Compile Include="Camera.cs" />
<Compile Include="GameObject.cs" />
<Compile Include="Program.cs" />
@ -83,6 +84,9 @@
<Content Include="LifeIcon.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="NoImage.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Tile_Set_2.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>

Binary file not shown.

Before

(image error) Size: 405 B

After

(image error) Size: 494 B

Binary file not shown.

After

(image error) Size: 169 B

@ -50,6 +50,9 @@ namespace JustTheBasics
// Dictionary to store background images
Dictionary<string, Background> BGs = new Dictionary<string, Background>();
// Dictionary for background tiles
Dictionary<string, BGTile> BGTiles = new Dictionary<string, BGTile>();
// Default constructor that sets window size to 512x512 and adds some antialiasing (the GraphicsMode part)
public Game() : base(800, 600, new OpenTK.Graphics.GraphicsMode(32, 24, 0, 4))
{
@ -85,11 +88,11 @@ namespace JustTheBasics
tc.TextureID = textures["LifeIcon.png"];
// Create a new GameObject
Vector2 startPos = new Vector2(16, 16);
Vector2[] spawn = new Vector2[] { new Vector2(0, 32), new Vector2(32, 32), new Vector2(32, 0) };
Vector2 startPos = new Vector2(64, 64);
Vector2[] spawn = new Vector2[] { new Vector2(0, 64), new Vector2(64, 64), new Vector2(64, 0) };
float[] map = new float[] { 0f, 0f, Width, Height };
GameObject objPlayer = new GameObject("Player", startPos, spawn, map, 1.0f, 0f, true, tc);
GameObject objPlayer = new GameObject("Player", startPos, spawn, map, 4.0f, 0f, true, tc);
// Add the sprite to our list of active Sprites
objects[1].Add(objPlayer);
@ -106,18 +109,53 @@ namespace JustTheBasics
// Create a new GameObject
Vector2 sPos2 = new Vector2(128, 128);
Vector2[] spawnBrick = new Vector2[] { new Vector2(0, 64), new Vector2(64, 64), new Vector2(64, 0) };
Vector2[] spawnBrick = new Vector2[] { new Vector2(0, 128), new Vector2(128, 128), new Vector2(128, 0) };
GameObject objBricks = new GameObject("Bricks", sPos2, spawnBrick, map, 0.0f, 0.0f, true, bc);
// Add the sprite to our list of active Sprites
objects[2].Add(objBricks);
// Make some invisible walls
int wallX = 0;
int wallY = 0;
textures.Add("NoImage.png", loadImage("NoImage.png", out wallX, out wallY, true));
for (int i = 0; i < 1600; i += 64)
{
Sprite ws = new Sprite();
ws.Width = wallX;
ws.Height = wallY;
ws.TextureID = textures["NoImage.png"];
Vector2[] spawnWall = new Vector2[] { new Vector2(0, 64), new Vector2(64, 64), new Vector2(64, 0) };
GameObject wall = new GameObject("Wall" + i.ToString(), new Vector2(i, 0f), spawnWall, map, 0f, 0f, true, ws);
objects[2].Add(wall);
}
// Create a background
Background bg = new Background();
textures.Add("circuit.png", loadImage("CircuitBOTTOM.png", bg, true));
bg.TextureID = textures["circuit.png"];
BGs.Add("circuit", bg);
// Create background tiles
int tilesetSizeX = 0;
int tilesetSizeY = 0;
textures.Add("Tile_Set_2.png", loadImage("Tile_Set_2.png", out tilesetSizeX, out tilesetSizeY, true));
for (int i = 0; i < 1600; i += 64)
{
BGTile bgt = new BGTile();
bgt.Width = tilesetSizeX;
bgt.Height = tilesetSizeY;
bgt.TextureID = textures["Tile_Set_2.png"];
bgt.Position = new Vector3(i/(float)Width, 0, 0);
bgt.index = new Vector2((i/64)%2 + 1, 1);
bgt.tSize = 64;
BGTiles.Add("Tile"+i.ToString(), bgt);
// Update the matrix used to calculate the Sprite's visuals
bgt.CalculateModelMatrix();
// Offset it by our viewport matrix (for things like scrolling levels)
bgt.ModelViewProjectionMatrix = bgt.ModelMatrix;// * ortho;
}
}
// This function overrides the base OnLoad function
@ -168,6 +206,16 @@ namespace JustTheBasics
vertcount += bg.VertCount;
texcoords.AddRange(bg.GetTextureCoords());
}
// Set up rendering for background tiles
foreach (BGTile bgt in BGTiles.Values)
{
// Populate the previously defined lists
verts.AddRange(bgt.GetVerts(Width, Height).ToList());
inds.AddRange(bgt.GetIndices(vertcount).ToList());
colors.AddRange(bgt.GetColorData().ToList());
vertcount += bgt.VertCount;
texcoords.AddRange(bgt.GetTextureCoords());
}
// Stack for LIFO behavior in drawing sprites
Stack<GameObject> objLists = new Stack<GameObject>();
@ -296,6 +344,29 @@ namespace JustTheBasics
indiceat += bg.IndiceCount;
}
// Loop over every background tile and render it
foreach (BGTile bgt in BGTiles.Values)
{
// Tell OpenTK to associate the given texture to the VBO we're drawing
GL.BindTexture(TextureTarget.Texture2D, bgt.TextureID);
// Allow tiling of images
// Send our projection matrix to the GLSL shader
GL.UniformMatrix4(shaders[activeShader].GetUniform("modelview"), false, ref bgt.ModelViewProjectionMatrix);
// If shader uses textures, send the image to the shader code for processing
if (shaders[activeShader].GetAttribute("maintexture") != -1)
{
GL.Uniform1(shaders[activeShader].GetAttribute("maintexture"), bgt.TextureID);
}
// Draw a square/rectangle
GL.DrawElements(BeginMode.Quads, bgt.IndiceCount, DrawElementsType.UnsignedInt, indiceat * sizeof(uint));
// Increment our index counter by the number of indices processed
indiceat += bgt.IndiceCount;
}
// Loop over every GameObject in the game
// First put the highest-draw layer objects at the bottom so they draw last
// Stack for LIFO behavior in drawing sprites
@ -439,6 +510,24 @@ namespace JustTheBasics
return -1;
}
}
// Another overload, does the same as above, but also takes two ints
// into as arguments, so that it can return the height and width of the sprite.
int loadImage(string filename, out int x, out int y, bool tile = false)
{
try
{
Bitmap file = new Bitmap(filename);
x = file.Width;
y = file.Height;
return loadImage(file, tile);
}
catch (FileNotFoundException e)
{
x = 0;
y = 0;
return -1;
}
}
}
// Small class that basically is a Main() function and just runs the game.

Binary file not shown.

Before

(image error) Size: 6.7 KiB

After

(image error) Size: 8.7 KiB

Binary file not shown.

Before

(image error) Size: 7.3 KiB

After

(image error) Size: 34 KiB

Binary file not shown.

Before

(image error) Size: 405 B

After

(image error) Size: 494 B

Binary file not shown.

After

(image error) Size: 169 B

Binary file not shown.

Before

(image error) Size: 6.7 KiB

After

(image error) Size: 8.7 KiB