Skip to content

Commit

Permalink
#30 - Implemented SpriteBatch class
Browse files Browse the repository at this point in the history
  • Loading branch information
sriharshachilakapati committed Jun 2, 2015
1 parent 00b562a commit a81b1f2
Show file tree
Hide file tree
Showing 6 changed files with 345 additions and 5 deletions.
14 changes: 14 additions & 0 deletions src/main/java/com/shc/silenceengine/graphics/GraphicsEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import com.shc.silenceengine.graphics.programs.DefaultProgram;
import com.shc.silenceengine.graphics.programs.DirectionalLightProgram;
import com.shc.silenceengine.graphics.programs.PointLightProgram;
import org.lwjgl.opengl.ContextCapabilities;
import org.lwjgl.opengl.GL;

import static org.lwjgl.opengl.GL11.*;

Expand All @@ -50,6 +52,7 @@ public class GraphicsEngine implements IEngine
private Material currentMaterial;
private Batcher batcher;
private ModelBatch modelBatch;
private SpriteBatch spriteBatch;

public Material getCurrentMaterial()
{
Expand Down Expand Up @@ -94,6 +97,7 @@ public void init()
setClearColor(clearColor);

modelBatch = new ModelBatch();
spriteBatch = new SpriteBatch();

// Default font!!
TrueTypeFont.DEFAULT = new TrueTypeFont("Verdana", TrueTypeFont.STYLE_NORMAL, 16);
Expand Down Expand Up @@ -180,6 +184,16 @@ public ModelBatch getModelBatch()
return modelBatch;
}

public SpriteBatch getSpriteBatch()
{
return spriteBatch;
}

public ContextCapabilities getGLCapabilities()
{
return GL.getCapabilities();
}

static
{
DEFAULT_MATERIAL = new Material();
Expand Down
23 changes: 18 additions & 5 deletions src/main/java/com/shc/silenceengine/graphics/Sprite.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,32 @@ public class Sprite

public Sprite()
{
animation = new Animation();
id = IDGenerator.generate();
this(new Animation(), 1, 1, 0);
}

public Sprite(Animation animation)
{
this.animation = animation.copy();
id = IDGenerator.generate();
this(animation, 1, 1, 0);
}

public Sprite(Texture texture)
{
this();
this(texture, 1, 1, 0);
}

public Sprite(Animation animation, float scaleX, float scaleY, float rotation)
{
id = IDGenerator.generate();

this.animation = animation.copy();
this.scaleX = scaleX;
this.scaleY = scaleY;
this.rotation = rotation;
}

public Sprite(Texture texture, float scaleX, float scaleY, float rotation)
{
this(new Animation(), scaleX, scaleY, rotation);
setTexture(texture);
}

Expand Down
163 changes: 163 additions & 0 deletions src/main/java/com/shc/silenceengine/graphics/SpriteBatch.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2015 Sri Harsha Chilakapati
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package com.shc.silenceengine.graphics;

import com.shc.silenceengine.core.SilenceEngine;
import com.shc.silenceengine.core.SilenceException;
import com.shc.silenceengine.graphics.opengl.Primitive;
import com.shc.silenceengine.graphics.opengl.Texture;
import com.shc.silenceengine.math.Vector2;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* @author Sri Harsha Chilakapati
*/
public class SpriteBatch
{
private List<Sprite> sprites;
private Map<Integer, Vector2> spritePositionMap;

private boolean active;

public SpriteBatch()
{
sprites = new ArrayList<>();
spritePositionMap = new HashMap<>();
active = false;
}

public void begin()
{
if (active)
throw new SilenceException("SpriteBatch already active");

sprites.clear();

active = true;
}

public void flush()
{
if (sprites.size() == 0)
return;

sortSprites();

Batcher batcher = SilenceEngine.graphics.getBatcher();

Texture originalTexture = Texture.CURRENT;

Texture texture = sprites.get(0).getTexture();
texture.bind();

Vector2 temp = Vector2.REUSABLE_STACK.pop();

batcher.begin(Primitive.TRIANGLES);
{
for (Sprite sprite : sprites)
{
Texture t = sprite.getTexture();

if (t.getId() != texture.getId())
{
batcher.end();

texture = t;
t.bind();

batcher.begin();
}

Vector2 position = spritePositionMap.get(sprite.getID());

// Triangle 1
batcher.vertex(temp.set(-texture.getWidth() / 2, -texture.getHeight() / 2) // Top-left
.rotateSelf(sprite.getRotation())
.scaleSelf(sprite.getScaleX(), sprite.getScaleY())
.addSelf(position).addSelf(texture.getWidth()/2, texture.getHeight()/2));
batcher.texCoord(texture.getMinU(), texture.getMinV());
batcher.vertex(temp.set(texture.getWidth() / 2, -texture.getHeight() / 2) // Top-right
.rotateSelf(sprite.getRotation())
.scaleSelf(sprite.getScaleX(), sprite.getScaleY())
.addSelf(position).addSelf(texture.getWidth() / 2, texture.getHeight() / 2));
batcher.texCoord(texture.getMaxU(), texture.getMinV());
batcher.vertex(temp.set(-texture.getWidth() / 2, texture.getHeight() / 2) // Bottom-left
.rotateSelf(sprite.getRotation())
.scaleSelf(sprite.getScaleX(), sprite.getScaleY())
.addSelf(position).addSelf(texture.getWidth() / 2, texture.getHeight() / 2));
batcher.texCoord(texture.getMinU(), texture.getMaxV());

// Triangle 2
batcher.vertex(temp.set(texture.getWidth() / 2, -texture.getHeight() / 2) // Top-right
.rotateSelf(sprite.getRotation())
.scaleSelf(sprite.getScaleX(), sprite.getScaleY())
.addSelf(position).addSelf(texture.getWidth() / 2, texture.getHeight() / 2));
batcher.texCoord(texture.getMaxU(), texture.getMinV());
batcher.vertex(temp.set(texture.getWidth() / 2, texture.getHeight() / 2) // Bottom-right
.rotateSelf(sprite.getRotation())
.scaleSelf(sprite.getScaleX(), sprite.getScaleY())
.addSelf(position).addSelf(texture.getWidth() / 2, texture.getHeight() / 2));
batcher.texCoord(texture.getMaxU(), texture.getMaxV());
batcher.vertex(temp.set(-texture.getWidth() / 2, texture.getHeight() / 2) // Bottom-left
.rotateSelf(sprite.getRotation())
.scaleSelf(sprite.getScaleX(), sprite.getScaleY())
.addSelf(position).addSelf(texture.getWidth()/2, texture.getHeight()/2));
batcher.texCoord(texture.getMinU(), texture.getMaxV());
}
}
batcher.end();

Vector2.REUSABLE_STACK.push(temp);

sprites.clear();
spritePositionMap.clear();

originalTexture.bind();
}

public void end()
{
if (!active)
throw new SilenceException("SpriteBatch is not active");

flush();
active = false;
}

private void sortSprites()
{
sprites.sort((s1, s2) -> s1.getTexture().getId() < s2.getTexture().getId() ? 1 : -1);
}

public void addSprite(Sprite sprite, Vector2 position)
{
sprites.add(sprite);
spritePositionMap.put(sprite.getID(), position);
}
}
1 change: 1 addition & 0 deletions src/main/java/com/shc/silenceengine/models/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public void render(Batcher batcher, Transform transform)
Texture originalTexture = Texture.CURRENT;

SilenceEngine.graphics.useMaterial(m.getMaterial());
m.getMaterial().getDiffuseMap().bind();

if (transform != null) batcher.applyTransform(transform);
batcher.begin();
Expand Down

0 comments on commit a81b1f2

Please sign in to comment.