Lots of little things (Part 1)
Featuring: - General safety - Small refactors - Micro-optimizations - Many manual code formats - Documentation - TODO and FIXME comments (Search for these!)pull/12/head
parent
ead57a9fa2
commit
3e3332271f
|
@ -24,37 +24,77 @@ import tk.valoeghese.gateways.client.io.*;
|
|||
|
||||
public class Litecraft extends Game
|
||||
{
|
||||
private static Litecraft INSTANCE;
|
||||
private World world;
|
||||
private LitecraftSave save;
|
||||
private Ginger ginger3D;
|
||||
private static Litecraft INSTANCE;
|
||||
private Ginger engine;
|
||||
public Player player;
|
||||
private Camera camera;
|
||||
//temp stuff to test out fbo fixes
|
||||
int oldWindowWidth = Window.getWidth();
|
||||
int oldWindowHeight = Window.getHeight();
|
||||
public int fps, ups, tps, binds;
|
||||
public Vector4i dbgStats;
|
||||
public int fps, ups, tps;
|
||||
public Vector4i dbgStats = new Vector4i();
|
||||
private long frameTimer;
|
||||
|
||||
public int threadWaitlist = 0;
|
||||
|
||||
public Litecraft()
|
||||
{
|
||||
Litecraft.INSTANCE = this;
|
||||
dbgStats = new Vector4i();
|
||||
// set constants
|
||||
this.setupConstants();
|
||||
this.setupWindow();
|
||||
Blocks.setup(); // make sure blocks are initialised
|
||||
GingerUtils.init(); // set up ginger utilities
|
||||
// set up Ginger3D stuff
|
||||
this.setupGinger();
|
||||
this.oldWindowWidth = Window.getWidth();
|
||||
this.oldWindowHeight = Window.getHeight();
|
||||
Blocks.init(); // make sure blocks are initialised
|
||||
this.frameTimer = System.currentTimeMillis();
|
||||
setupKeybinds(); // set up keybinds
|
||||
//start the game loop
|
||||
this.ginger3D.startGame();
|
||||
setupKeybinds(); // setup keybinds
|
||||
// start the game loop
|
||||
this.engine.startGameLoop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exit()
|
||||
{
|
||||
engine.openScreen(null);
|
||||
if (this.world != null)
|
||||
{
|
||||
System.out.println("Saving chunks...");
|
||||
this.world.unloadAllChunks();
|
||||
this.getSave().saveGlobalData(this.world.getSeed(), this.player);
|
||||
}
|
||||
engine.cleanup();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Things that ARE rendering: Anything that results in something being drawn to the frame buffer
|
||||
* Things that are NOT rendering: Things that happen to update between frames but do not result in things being drawn to the screen
|
||||
*/
|
||||
@Override
|
||||
public void render()
|
||||
{
|
||||
fps += 1; // This section updates the debug stats once per real-time second, regardless of how many frames have been rendered
|
||||
if (System.currentTimeMillis() > frameTimer + 1000)
|
||||
{
|
||||
this.dbgStats.set(fps, ups, tps, threadWaitlist);
|
||||
this.fps = 0;
|
||||
this.ups = 0;
|
||||
this.tps = 0;
|
||||
this.frameTimer += 1000;
|
||||
}
|
||||
/*
|
||||
* And now, the actual rendering:
|
||||
*/
|
||||
// Render shadows
|
||||
GingerRegister.getInstance().masterRenderer.renderShadowMap(data.entities, data.lights.get(0));
|
||||
// If there's a world, render it!
|
||||
if (this.world != null) this.engine.renderWorld(this);
|
||||
// Render any overlays (GUIs, HUDs)
|
||||
this.engine.renderOverlays(this);
|
||||
// Put what's stored in the inactive framebuffer on the screen
|
||||
Window.swapBuffers();
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
Input.invokeAllListeners();
|
||||
}
|
||||
|
||||
private void setupConstants()
|
||||
|
@ -65,11 +105,28 @@ public class Litecraft extends Game
|
|||
Constants.jumpPower = 0.00005f; // jump power
|
||||
}
|
||||
|
||||
private void setupWindow()
|
||||
// set up Ginger3D engine stuff
|
||||
private void setupGinger()
|
||||
{
|
||||
Window.create(1200, 800, "LiteCraft", 60); // create window
|
||||
KeyCallbackHandler.trackWindow(Window.window); // set up the gateways keybind key tracking
|
||||
MouseCallbackHandler.trackWindow(Window.window);
|
||||
if (engine == null) // Prevents this from being run more than once on accident.
|
||||
{
|
||||
this.setupWindow();
|
||||
GingerUtils.init(); // set up ginger utilities
|
||||
TexturedModel playerModel = ModelLoader.loadGenericCube("block/cubes/stone/brick/stonebrick.png");
|
||||
StaticCube.scaleCube(1f);
|
||||
Light sun = new Light(new Vector3f(0, 105, 0), new Vector3f(0.9765625f, 0.98828125f, 0.05859375f), new Vector3f(0.002f, 0.002f, 0.002f));
|
||||
FontType font = new FontType(Loader.loadFontAtlas("candara.png"), "candara.fnt");
|
||||
this.engine = new Ginger();
|
||||
this.player = new Player(playerModel, new Vector3f(0, 0, -3), 0, 180f, 0, new Vector3f(0.2f, 0.2f, 0.2f));
|
||||
this.camera = new FirstPersonCamera(player);
|
||||
this.player.setVisible(false);
|
||||
this.data = new GameData(this.player, this.camera, 20);
|
||||
this.data.handleGuis = false;
|
||||
this.engine.setup(new MasterRenderer(this.camera), INSTANCE);
|
||||
this.engine.setGlobalFont(font);
|
||||
this.data.lights.add(sun);
|
||||
this.data.entities.add(this.player);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupKeybinds()
|
||||
|
@ -85,87 +142,41 @@ public class Litecraft extends Game
|
|||
Input.addPressCallback(Keybind.FLY_DOWN, () -> this.movePlayer(RelativeDirection.DOWN));
|
||||
}
|
||||
|
||||
private void setupGinger()
|
||||
private void movePlayer(RelativeDirection direction)
|
||||
{ this.player.move(direction); }
|
||||
|
||||
private void setupWindow()
|
||||
{
|
||||
TexturedModel playerModel = ModelLoader.loadGenericCube("block/cubes/stone/brick/stonebrick.png");
|
||||
StaticCube.scaleCube(1f);
|
||||
this.player = new Player(playerModel, new Vector3f(0, 0, -3), 0, 180f, 0, new Vector3f(0.2f, 0.2f, 0.2f));
|
||||
this.camera = new FirstPersonCamera(player);
|
||||
this.player.isVisible = false;
|
||||
this.ginger3D = new Ginger();
|
||||
this.data = new GameData(this.player, this.camera, 20);
|
||||
this.data.handleGuis = false;
|
||||
this.ginger3D.setup(new MasterRenderer(this.camera), INSTANCE);
|
||||
FontType font = new FontType(Loader.loadFontAtlas("candara.png"), "candara.fnt");
|
||||
this.ginger3D.setGlobalFont(font);
|
||||
Light sun = new Light(new Vector3f(100, 105, -100), new Vector3f(1.3f, 1.3f, 1.3f), new Vector3f(0.0001f, 0.0001f, 0.0001f));
|
||||
this.data.lights.add(sun);
|
||||
this.data.entities.add(this.player);
|
||||
Window.create(1280, 720, "LiteCraft", 60); // create window
|
||||
KeyCallbackHandler.trackWindow(Window.getWindow()); // set up the gateways keybind key tracking
|
||||
MouseCallbackHandler.trackWindow(Window.getWindow());
|
||||
}
|
||||
|
||||
/*
|
||||
* Things that should be ticked: Entities when deciding an action, in-game timers (such as smelting), the in-game time
|
||||
* Things that should not be ticked: Rendering, input, player movement
|
||||
*/
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
// Open the title screen if it's not already open.
|
||||
if (GingerRegister.getInstance().currentScreen == null && world == null)
|
||||
engine.openScreen(new TitleScreen());
|
||||
}
|
||||
|
||||
// @formatter=off
|
||||
public static Litecraft getInstance()
|
||||
{ return INSTANCE; }
|
||||
|
||||
public Camera getCamera()
|
||||
{ return this.camera; }
|
||||
|
||||
@Override
|
||||
public void exit()
|
||||
{
|
||||
if (this.world != null)
|
||||
{
|
||||
System.out.println("Saving chunks...");
|
||||
this.world.unloadAllChunks();
|
||||
this.getSave().saveGlobalData(this.world.getSeed(), this.player);
|
||||
}
|
||||
ginger3D.cleanup();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
private void movePlayer(RelativeDirection direction)
|
||||
{ this.player.move(direction); }
|
||||
|
||||
@Override
|
||||
public void render()
|
||||
{
|
||||
this.fps++;
|
||||
//FPS stuff sorry if i forget to remove whitespace
|
||||
if (System.currentTimeMillis() > frameTimer + 1000) // wait for one second
|
||||
{
|
||||
this.dbgStats.set(fps, ups, tps, threadWaitlist);
|
||||
this.fps = 0;
|
||||
this.ups = 0;
|
||||
this.tps = 0;
|
||||
this.frameTimer += 1000; // reset the wait time
|
||||
}
|
||||
// TODO: Document this code!
|
||||
if (ginger3D.gingerRegister.currentScreen == null) ginger3D.openScreen(new TitleScreen());
|
||||
this.ginger3D.update(data); // FIXME: This should either be renamed to "render" or moved to tick() if it has nothing to do with rendering.
|
||||
if (oldWindowHeight != Window.getHeight() || oldWindowWidth != Window.getWidth() && Window.getHeight() > 10 && Window.getWidth() > 10)
|
||||
this.ginger3D.contrastFbo.resizeFBOs();
|
||||
this.oldWindowWidth = Window.getWidth();
|
||||
this.oldWindowHeight = Window.getHeight();
|
||||
this.ginger3D.gingerRegister.masterRenderer.renderShadowMap(data.entities, data.lights.get(0));
|
||||
if (this.world != null) this.ginger3D.renderWorld(this, this.world);
|
||||
this.ginger3D.renderOverlays(this);
|
||||
this.ginger3D.postRender();
|
||||
this.binds = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
this.tps++;
|
||||
Input.invokeAllListeners();
|
||||
data.player.updateMovement();
|
||||
}
|
||||
|
||||
public static Litecraft getInstance()
|
||||
{ return INSTANCE; }
|
||||
public LitecraftSave getSave()
|
||||
{ return save; }
|
||||
|
||||
public World getWorld()
|
||||
{ return this.world; }
|
||||
|
||||
public LitecraftSave getSave()
|
||||
{ return save; }
|
||||
|
||||
public void changeWorld(World world)
|
||||
{ this.world = world; }
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ public final class Blocks
|
|||
public static final Block DIORITE = new Block("block/cubes/stone/basic/diorite.png", new Properties("diorite"));
|
||||
public static final Block GRANITE = new Block("block/cubes/stone/basic/granite.png", new Properties("granite"));
|
||||
public static final Block GNEISS = new Block("block/cubes/stone/basic/gneiss.png", new Properties("gneiss"));
|
||||
public static Block setup()
|
||||
public static Block init()
|
||||
{
|
||||
return AIR;
|
||||
}
|
||||
|
|
|
@ -15,16 +15,18 @@ import tk.valoeghese.sod.*;
|
|||
|
||||
public class Chunk implements BlockAccess, WorldGenConstants, DataStorage
|
||||
{
|
||||
/** @param x in-chunk x coordinate.
|
||||
/*
|
||||
* @param x in-chunk x coordinate.
|
||||
* @param y in-chunk y coordinate.
|
||||
* @param z in-chunk z coordinate.
|
||||
* @return creates a long that represents a coordinate, for use as a key in the array. */
|
||||
* @return creates a long that represents a coordinate, for use as a key in the array.
|
||||
*/
|
||||
public static int index(int x, int y, int z)
|
||||
{ return (x & MAX_POS) | ((y & MAX_POS) << POS_SHIFT) | ((z & MAX_POS) << DOUBLE_SHIFT); }
|
||||
|
||||
private final Block[] blocks = new Block[CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE];
|
||||
private BlockInstance[] blockEntities = new BlockInstance[CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE];
|
||||
private boolean render = false;
|
||||
private boolean shouldRender = false;
|
||||
public final int chunkX, chunkY, chunkZ;
|
||||
public final int chunkStartX, chunkStartY, chunkStartZ;
|
||||
private boolean fullyGenerated = false;
|
||||
|
@ -44,7 +46,7 @@ public class Chunk implements BlockAccess, WorldGenConstants, DataStorage
|
|||
}
|
||||
|
||||
public boolean doRender()
|
||||
{ return this.render; }
|
||||
{ return this.shouldRender; }
|
||||
|
||||
public void setFullyGenerated(boolean fullyGenerated)
|
||||
{ this.fullyGenerated = fullyGenerated; }
|
||||
|
@ -66,16 +68,13 @@ public class Chunk implements BlockAccess, WorldGenConstants, DataStorage
|
|||
|
||||
public void render(BlockRenderer blockRenderer)
|
||||
{
|
||||
if (render)
|
||||
if (shouldRender)
|
||||
{
|
||||
if (dirty)
|
||||
{
|
||||
dirty = false;
|
||||
renderedBlocks = new BlockInstance[CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE];
|
||||
for (int x = 0; x < CHUNK_SIZE; x++)
|
||||
{
|
||||
for (int y = 0; y < CHUNK_SIZE; y++)
|
||||
{
|
||||
for (int z = 0; z < CHUNK_SIZE; z++)
|
||||
{
|
||||
BlockInstance block = getBlockInstance(x, y, z);
|
||||
|
@ -97,34 +96,38 @@ public class Chunk implements BlockAccess, WorldGenConstants, DataStorage
|
|||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
blockRenderer.render(renderedBlocks);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Change the block in this exact position
|
||||
* @param x, y, z The coordinate position of block to overwrite
|
||||
* @param block The block to place there
|
||||
*/
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, Block block)
|
||||
{
|
||||
if (x > MAX_POS)
|
||||
x = MAX_POS;
|
||||
// This section makes sure the blocks don't go out of range
|
||||
if (x > MAX_POS) x = MAX_POS;
|
||||
else if (x < 0) x = 0;
|
||||
if (y > MAX_POS)
|
||||
y = MAX_POS;
|
||||
if (y > MAX_POS) y = MAX_POS;
|
||||
else if (y < 0) y = 0;
|
||||
if (z > MAX_POS)
|
||||
z = MAX_POS;
|
||||
if (z > MAX_POS) z = MAX_POS;
|
||||
else if (z < 0) z = 0;
|
||||
//
|
||||
this.blocks[index(x, y, z)] = block;
|
||||
if (this.render)
|
||||
{ this.blockEntities[index(x, y, z)] = new BlockInstance(block, new Vector3f(this.chunkStartX + x, this.chunkStartY + y, this.chunkStartZ + z)); }
|
||||
if (this.shouldRender) this.blockEntities[index(x, y, z)] =
|
||||
new BlockInstance(block, new Vector3f(this.chunkStartX + x, this.chunkStartY + y, this.chunkStartZ + z));
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set whether or not the chunk should render
|
||||
*/
|
||||
public void setRender(boolean render)
|
||||
{
|
||||
if (render && !this.render) // if it has been changed to true
|
||||
if (render && !this.shouldRender) // if it has been changed to true
|
||||
for (int x = 0; x < CHUNK_SIZE; ++x)
|
||||
for (int y = 0; y < CHUNK_SIZE; ++y)
|
||||
for (int z = 0; z < CHUNK_SIZE; ++z)
|
||||
|
@ -137,11 +140,11 @@ public class Chunk implements BlockAccess, WorldGenConstants, DataStorage
|
|||
this.chunkStartY + y,
|
||||
this.chunkStartZ + z));
|
||||
}
|
||||
else if (!render && this.render) // else if it has been changed to false.
|
||||
else if (!render && this.shouldRender) // else if it has been changed to false.
|
||||
// we need to check both variables because there are two cases that make
|
||||
// the if statement fall to here
|
||||
blockEntities = new BlockInstance[CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE];
|
||||
this.render = render;
|
||||
this.shouldRender = render;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
|
@ -172,18 +175,14 @@ public class Chunk implements BlockAccess, WorldGenConstants, DataStorage
|
|||
//
|
||||
IntArrayDataSection blockData = data.getIntArray("block");
|
||||
int index = 0;
|
||||
//
|
||||
// Iterate over each block in the chunk
|
||||
for (int z = 0; z < CHUNK_SIZE; ++z) // z, y, x order for data saving and loading so we can use incremental pos hashes
|
||||
{
|
||||
for (int y = 0; y < CHUNK_SIZE; ++y)
|
||||
{
|
||||
for (int x = 0; x < CHUNK_SIZE; ++x)
|
||||
{
|
||||
blocks[index] = palette.get(blockData.readInt(index));
|
||||
++index;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
DataSection properties = data.get("properties");
|
||||
try
|
||||
|
@ -192,14 +191,15 @@ public class Chunk implements BlockAccess, WorldGenConstants, DataStorage
|
|||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (exceptionOccuredReadingNotif){
|
||||
if (!readExceptionNotif)
|
||||
{
|
||||
System.out.println("An exception occurred reading properties for a chunk! This could be a benign error due to updates to chunk properties.");
|
||||
exceptionOccuredReadingNotif = false;
|
||||
readExceptionNotif = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean exceptionOccuredReadingNotif = true;
|
||||
private static boolean readExceptionNotif = false;
|
||||
|
||||
private int nextId; // for saving
|
||||
|
||||
|
@ -214,17 +214,13 @@ public class Chunk implements BlockAccess, WorldGenConstants, DataStorage
|
|||
ToIntFunction<Block> nextIdProvider = b -> nextId++;
|
||||
//
|
||||
for (int z = 0; z < CHUNK_SIZE; ++z) // z, y, x order for data saving and loading so we can use incremental pos hashes
|
||||
{
|
||||
for (int y = 0; y < CHUNK_SIZE; ++y)
|
||||
{
|
||||
for (int x = 0; x < CHUNK_SIZE; ++x)
|
||||
{
|
||||
Block b = blocks[index];
|
||||
blockData.writeInt(palette.computeIntIfAbsent(b, nextIdProvider));
|
||||
++index;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
palette.forEach((b, id) ->
|
||||
{
|
||||
|
|
|
@ -34,7 +34,7 @@ public class World implements BlockAccess, WorldGenConstants
|
|||
{
|
||||
new DynamicChunkLoader(0, 0, 0, this);
|
||||
this.dummy = new BlockInstance(Blocks.ANDESITE, new Vector3f(0, 0, 0));
|
||||
this.dummy.isVisible = false;
|
||||
this.dummy.setVisible(false);
|
||||
this.chunks = new Long2ObjectArrayMap<>();
|
||||
this.seed = seed;
|
||||
this.chunkGenerator = dim.createChunkGenerator(seed);
|
||||
|
@ -77,7 +77,7 @@ public class World implements BlockAccess, WorldGenConstants
|
|||
// Player model and stuff
|
||||
TexturedModel dirtModel = ModelLoader.loadGenericCube("block/cubes/soil/dirt.png");
|
||||
this.player = new Player(dirtModel, new Vector3f(x, y, z), 0, 180f, 0, new Vector3f(0.2f, 0.2f, 0.2f));
|
||||
this.player.isVisible = false;
|
||||
this.player.setVisible(false);
|
||||
// Generate world around player
|
||||
long time = System.currentTimeMillis();
|
||||
System.out.println("Generating world!");
|
||||
|
|
|
@ -5,7 +5,6 @@ import org.joml.Vector2f;
|
|||
import com.github.halotroop.litecraft.Litecraft;
|
||||
import com.github.halotroop.litecraft.logic.Timer;
|
||||
import com.github.halotroop.litecraft.logic.Timer.TickListener;
|
||||
import com.github.halotroop.litecraft.world.World;
|
||||
import com.github.hydos.ginger.engine.api.game.*;
|
||||
import com.github.hydos.ginger.engine.elements.buttons.TextureButton;
|
||||
import com.github.hydos.ginger.engine.elements.objects.Player;
|
||||
|
@ -22,7 +21,7 @@ import com.github.hydos.multithreading.GingerThreading;
|
|||
public class Ginger
|
||||
{
|
||||
private static Ginger INSTANCE;
|
||||
public GingerRegister gingerRegister;
|
||||
private GingerRegister registry;
|
||||
public MousePicker picker;
|
||||
public FontType globalFont;
|
||||
public Fbo contrastFbo;
|
||||
|
@ -34,9 +33,8 @@ public class Ginger
|
|||
@Override
|
||||
public void onTick(float deltaTime)
|
||||
{
|
||||
gingerRegister.game.tick();
|
||||
if (gingerRegister.currentScreen != null)
|
||||
{ gingerRegister.currentScreen.tick(); }
|
||||
if (registry.game != null) registry.game.tick();
|
||||
if (registry.currentScreen != null) registry.currentScreen.tick();
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -45,33 +43,30 @@ public class Ginger
|
|||
Window.stop();
|
||||
PostProcessing.cleanUp();
|
||||
ParticleMaster.cleanUp();
|
||||
gingerRegister.masterRenderer.cleanUp();
|
||||
registry.masterRenderer.cleanUp();
|
||||
TextMaster.cleanUp();
|
||||
Loader.cleanUp();
|
||||
}
|
||||
|
||||
public void openScreen(Screen screen)
|
||||
{
|
||||
if (gingerRegister.currentScreen != null) gingerRegister.currentScreen.close();
|
||||
gingerRegister.currentScreen = screen;
|
||||
if (registry.currentScreen != null) registry.currentScreen.close();
|
||||
registry.currentScreen = screen;
|
||||
}
|
||||
|
||||
public void setGingerPlayer(Player player)
|
||||
{
|
||||
gingerRegister.game.data.entities.remove(Litecraft.getInstance().player); // remove the old player
|
||||
gingerRegister.game.data.player = player; // set all the player variables
|
||||
registry.game.data.entities.remove(Litecraft.getInstance().player); // remove the old player
|
||||
registry.game.data.player = player; // set all the player variables
|
||||
Litecraft.getInstance().player = player;
|
||||
Litecraft.getInstance().getCamera().player = player;
|
||||
gingerRegister.game.data.entities.add(player); // add the new player
|
||||
registry.game.data.entities.add(player); // add the new player
|
||||
}
|
||||
|
||||
public void postRender()
|
||||
{ Window.swapBuffers(); }
|
||||
|
||||
public TextureButton registerButton(String resourceLocation, Vector2f position, Vector2f scale)
|
||||
{
|
||||
TextureButton button = new TextureButton(resourceLocation, position, scale);
|
||||
gingerRegister.registerButton(button);
|
||||
registry.registerButton(button);
|
||||
return button;
|
||||
}
|
||||
|
||||
|
@ -79,28 +74,27 @@ public class Ginger
|
|||
{
|
||||
GUIText text = new GUIText(string, textSize, globalFont, position, maxLineLength, false);
|
||||
text.textID = id;
|
||||
gingerRegister.registerText(text);
|
||||
registry.registerText(text);
|
||||
return text;
|
||||
}
|
||||
|
||||
public void renderOverlays(Game game)
|
||||
{
|
||||
gingerRegister.masterRenderer.renderGuis(game.data.guis);
|
||||
if (gingerRegister.currentScreen != null)
|
||||
{ gingerRegister.masterRenderer.renderGuis(gingerRegister.currentScreen.elements); }
|
||||
registry.masterRenderer.renderGuis(game.data.guis);
|
||||
if (registry.currentScreen != null) registry.masterRenderer.renderGuis(registry.currentScreen.elements);
|
||||
TextMaster.render();
|
||||
}
|
||||
|
||||
public void renderWorld(Game game, World world)
|
||||
public void renderWorld(Litecraft game)
|
||||
{
|
||||
GingerUtils.preRenderScene(gingerRegister.masterRenderer);
|
||||
GameData data = game.data;
|
||||
GingerUtils.preRenderScene(registry.masterRenderer);
|
||||
contrastFbo.bindFBO();
|
||||
gingerRegister.masterRenderer.renderScene(game.data.entities, game.data.normalMapEntities, game.data.lights, game.data.camera, game.data.clippingPlane, world);
|
||||
ParticleMaster.renderParticles(game.data.camera);
|
||||
registry.masterRenderer.renderScene(data.entities, data.normalMapEntities, data.lights, data.camera, data.clippingPlane, game.getWorld());
|
||||
ParticleMaster.renderParticles(data.camera);
|
||||
contrastFbo.unbindFBO();
|
||||
PostProcessing.doPostProcessing(contrastFbo.colorTexture);
|
||||
if (game.data.handleGuis)
|
||||
{ renderOverlays(game); }
|
||||
if (data.handleGuis) renderOverlays(game);
|
||||
}
|
||||
|
||||
public void setGlobalFont(FontType font)
|
||||
|
@ -109,37 +103,44 @@ public class Ginger
|
|||
public void setup(MasterRenderer masterRenderer, Game game)
|
||||
{
|
||||
INSTANCE = this;
|
||||
gingerRegister = new GingerRegister();
|
||||
registry = new GingerRegister();
|
||||
threading = new GingerThreading();
|
||||
gingerRegister.registerGame(game);
|
||||
registry.registerGame(game);
|
||||
timer = new Timer(game.data.tickSpeed);
|
||||
timer.addTickListener(gameTickListener);
|
||||
contrastFbo = new Fbo(new ContrastChanger());
|
||||
gingerRegister.masterRenderer = masterRenderer;
|
||||
registry.masterRenderer = masterRenderer;
|
||||
picker = new MousePicker(game.data.camera, masterRenderer.getProjectionMatrix());
|
||||
PostProcessing.init();
|
||||
ParticleMaster.init(masterRenderer.getProjectionMatrix());
|
||||
}
|
||||
|
||||
public void startGame()
|
||||
public void startGameLoop()
|
||||
{
|
||||
if (!threading.isAlive()) // Prevents this from accidentally being run twice
|
||||
{
|
||||
threading.start();
|
||||
while (!Window.closed())
|
||||
{
|
||||
Litecraft.getInstance().ups++;
|
||||
timer.tick();
|
||||
if (Window.shouldRender()) gingerRegister.game.render();
|
||||
update(Litecraft.getInstance().data); // Run this regardless, (so as fast as possible)
|
||||
if (timer.tick()) Litecraft.getInstance().tps += 1; // Run this only [ticklimit] times per second (This invokes gameTickListener.onTick!)
|
||||
if (Window.shouldRender()) registry.game.render(); // Run this only [framelimit] times per second
|
||||
}
|
||||
gingerRegister.game.exit();
|
||||
}
|
||||
registry.game.exit();
|
||||
}
|
||||
|
||||
// Things that should be run as often as possible, without limits
|
||||
public void update(GameData data)
|
||||
{
|
||||
data.camera.move();
|
||||
GingerUtils.update();
|
||||
registry.game.update();
|
||||
data.player.updateMovement();
|
||||
data.camera.updateMovement();
|
||||
picker.update();
|
||||
GingerUtils.update();
|
||||
ParticleMaster.update(data.camera);
|
||||
Window.update();
|
||||
Litecraft.getInstance().ups += 1;
|
||||
}
|
||||
|
||||
public static Ginger getInstance()
|
||||
|
|
|
@ -12,4 +12,6 @@ public abstract class Game
|
|||
public abstract void render();
|
||||
|
||||
public abstract void tick();
|
||||
|
||||
public abstract void update();
|
||||
}
|
|
@ -71,7 +71,7 @@ public class Camera
|
|||
|
||||
private void calculateZoom()
|
||||
{
|
||||
GLFW.glfwSetScrollCallback(Window.window, new GLFWScrollCallback()
|
||||
GLFW.glfwSetScrollCallback(Window.getWindow(), new GLFWScrollCallback()
|
||||
{
|
||||
@Override
|
||||
public void invoke(long win, double dx, double dy)
|
||||
|
@ -97,7 +97,7 @@ public class Camera
|
|||
public void invertPitch()
|
||||
{ this.pitch = -pitch; }
|
||||
|
||||
public void move()
|
||||
public void updateMovement()
|
||||
{
|
||||
calculateZoom();
|
||||
calculatePitch();
|
||||
|
|
|
@ -14,7 +14,7 @@ public class FirstPersonCamera extends Camera
|
|||
public FirstPersonCamera(Player player)
|
||||
{
|
||||
super(player);
|
||||
player.isVisible = false;
|
||||
player.setVisible(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -34,7 +34,7 @@ public class FirstPersonCamera extends Camera
|
|||
{ return yaw; }
|
||||
|
||||
@Override
|
||||
public void move()
|
||||
public void updateMovement()
|
||||
{
|
||||
position.x = player.getPosition().x;
|
||||
position.z = player.getPosition().z;
|
||||
|
|
|
@ -82,7 +82,7 @@ public class Player extends RenderObject implements WorldGenConstants
|
|||
public void updateMovement()
|
||||
{
|
||||
super.increasePosition(0, (float) (upwardsSpeed * (Window.getTime())), 0);
|
||||
upwardsSpeed += Constants.gravity.y() * Window.getTime();
|
||||
upwardsSpeed += Constants.gravity.y() * Window.getTime(); // TODO: Implement 3D gravity
|
||||
isInAir = false;
|
||||
upwardsSpeed = 0;
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ public class RenderObject
|
|||
public Vector3f position;
|
||||
private float rotX = 0, rotY = 0, rotZ = 0;
|
||||
private Vector3f scale;
|
||||
public boolean isVisible = true;
|
||||
private boolean visible = true;
|
||||
|
||||
public RenderObject(TexturedModel model, Vector3f position, float rotX, float rotY, float rotZ, Vector3f scale)
|
||||
{
|
||||
|
@ -80,4 +80,14 @@ public class RenderObject
|
|||
|
||||
public void setScale(Vector3f scale)
|
||||
{ this.scale = scale; }
|
||||
|
||||
public boolean isVisible()
|
||||
{
|
||||
return visible;
|
||||
}
|
||||
|
||||
public void setVisible(boolean visible)
|
||||
{
|
||||
this.visible = visible;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import org.lwjgl.BufferUtils;
|
|||
import org.lwjgl.glfw.*;
|
||||
import org.lwjgl.opengl.*;
|
||||
|
||||
import com.github.hydos.ginger.engine.api.Ginger;
|
||||
import com.github.hydos.ginger.engine.render.texture.Image;
|
||||
|
||||
public class Window
|
||||
|
@ -28,7 +29,7 @@ public class Window
|
|||
|
||||
private static int width, height;
|
||||
private static String title;
|
||||
public static long window;
|
||||
private static long window;
|
||||
private static Vector3f backgroundColour = new Vector3f(118f, 215f, 234f);
|
||||
private static boolean[] mouseButtons = new boolean[GLFW.GLFW_MOUSE_BUTTON_LAST];
|
||||
private static GLFWImage.Buffer iconBuffer = null;
|
||||
|
@ -41,10 +42,13 @@ public class Window
|
|||
static double newX = 0;
|
||||
static double newY = 0;
|
||||
public static GLCapabilities glContext;
|
||||
public static int actuallWidth, actuallHeight;
|
||||
public static int actualWidth, actualHeight;
|
||||
//temp stuff to test out fbo fixes
|
||||
private static int oldWindowWidth = Window.getWidth();
|
||||
private static int oldWindowHeight = Window.getHeight();
|
||||
|
||||
public static boolean closed()
|
||||
{ return GLFW.glfwWindowShouldClose(window); }
|
||||
{ return GLFW.glfwWindowShouldClose(getWindow()); }
|
||||
|
||||
public static void create()
|
||||
{
|
||||
|
@ -60,31 +64,34 @@ public class Window
|
|||
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_FORWARD_COMPAT, GL11.GL_TRUE);
|
||||
GLFW.glfwWindowHint(GLFW.GLFW_RESIZABLE, GLFW.GLFW_TRUE);
|
||||
GLFWVidMode vidmode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor());
|
||||
window = GLFW.glfwCreateWindow(actuallWidth, actuallHeight, title, (fullscreen) ? GLFW.glfwGetPrimaryMonitor() : 0, window);
|
||||
if (window == 0)
|
||||
window = GLFW.glfwCreateWindow(actualWidth, actualHeight, title, (fullscreen) ? GLFW.glfwGetPrimaryMonitor() : 0, getWindow());
|
||||
if (getWindow() == 0)
|
||||
{
|
||||
System.err.println("Error: Couldnt initilize window");
|
||||
System.exit(-1);
|
||||
}
|
||||
GLFW.glfwMakeContextCurrent(window);
|
||||
GLFW.glfwMakeContextCurrent(getWindow());
|
||||
glContext = GL.createCapabilities();
|
||||
GL11.glEnable(GL11.GL_DEPTH_TEST);
|
||||
GLFW.glfwSetWindowPos(window, (vidmode.width() - actuallWidth) / 2, (vidmode.height() - actuallHeight) / 2);
|
||||
GLFW.glfwShowWindow(window);
|
||||
GLFW.glfwSetWindowPos(getWindow(), (vidmode.width() - actualWidth) / 2, (vidmode.height() - actualHeight) / 2);
|
||||
GLFW.glfwShowWindow(getWindow());
|
||||
time = getTime();
|
||||
getCurrentTime();
|
||||
|
||||
oldWindowWidth = getWidth();
|
||||
oldWindowHeight = getHeight();
|
||||
}
|
||||
|
||||
public static void create(int width, int height, String title, int fps)
|
||||
public static void create(int width, int height, String title, int fpsCap)
|
||||
{
|
||||
Window.width = width / 2;
|
||||
Window.height = height / 2;
|
||||
Window.actuallHeight = height;
|
||||
Window.actuallWidth = width;
|
||||
Window.actualHeight = height;
|
||||
Window.actualWidth = width;
|
||||
Window.title = title;
|
||||
fpsCap = fps;
|
||||
create();
|
||||
setIcon();
|
||||
Window.fpsCap = fpsCap;
|
||||
Window.create();
|
||||
Window.setIcon();
|
||||
}
|
||||
|
||||
public static Vector3f getColour()
|
||||
|
@ -102,14 +109,14 @@ public class Window
|
|||
public static double getMouseX()
|
||||
{
|
||||
DoubleBuffer buffer = BufferUtils.createDoubleBuffer(1);
|
||||
GLFW.glfwGetCursorPos(window, buffer, null);
|
||||
GLFW.glfwGetCursorPos(getWindow(), buffer, null);
|
||||
return buffer.get(0);
|
||||
}
|
||||
|
||||
public static double getMouseY()
|
||||
{
|
||||
DoubleBuffer buffer = BufferUtils.createDoubleBuffer(1);
|
||||
GLFW.glfwGetCursorPos(window, null, buffer);
|
||||
GLFW.glfwGetCursorPos(getWindow(), null, buffer);
|
||||
return buffer.get(0);
|
||||
}
|
||||
|
||||
|
@ -127,10 +134,10 @@ public class Window
|
|||
}
|
||||
|
||||
public static boolean isKeyDown(int keycode)
|
||||
{ return GLFW.glfwGetKey(window, keycode) == 1; }
|
||||
{ return GLFW.glfwGetKey(getWindow(), keycode) == 1; }
|
||||
|
||||
public static boolean isMouseDown(int mouseButton)
|
||||
{ return GLFW.glfwGetMouseButton(window, mouseButton) == 1; }
|
||||
{ return GLFW.glfwGetMouseButton(getWindow(), mouseButton) == 1; }
|
||||
|
||||
public static boolean isMousePressed(int keyCode)
|
||||
{ return isMouseDown(keyCode) && !mouseButtons[keyCode]; }
|
||||
|
@ -144,7 +151,7 @@ public class Window
|
|||
double passedTime = nextTime - time;
|
||||
processedTime += passedTime;
|
||||
time = nextTime;
|
||||
while (processedTime > 1.0 / fpsCap)
|
||||
if (processedTime > 1.0 / fpsCap)
|
||||
{
|
||||
processedTime -= 1.0 / fpsCap;
|
||||
return true;
|
||||
|
@ -153,7 +160,7 @@ public class Window
|
|||
}
|
||||
|
||||
public static void lockMouse()
|
||||
{ GLFW.glfwSetInputMode(window, GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_DISABLED); }
|
||||
{ GLFW.glfwSetInputMode(getWindow(), GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_DISABLED); }
|
||||
|
||||
private static void setIcon()
|
||||
{
|
||||
|
@ -162,29 +169,34 @@ public class Window
|
|||
iconBuffer = GLFWImage.malloc(1);
|
||||
iconImage.set(icon.getWidth(), icon.getHeight(), icon.getImage());
|
||||
iconBuffer.put(0, iconImage);
|
||||
GLFW.glfwSetWindowIcon(window, iconBuffer);
|
||||
GLFW.glfwSetWindowIcon(getWindow(), iconBuffer);
|
||||
}
|
||||
|
||||
public static void showIcon()
|
||||
{
|
||||
if (iconBuffer != null)
|
||||
{ GLFW.glfwSetWindowIcon(window, iconBuffer); }
|
||||
}
|
||||
{ if (iconBuffer != null) GLFW.glfwSetWindowIcon(getWindow(), iconBuffer); }
|
||||
|
||||
public static void stop()
|
||||
{ GLFW.glfwTerminate(); }
|
||||
|
||||
public static void swapBuffers()
|
||||
{ GLFW.glfwSwapBuffers(window); }
|
||||
{ GLFW.glfwSwapBuffers(getWindow()); }
|
||||
|
||||
public static void unlockMouse()
|
||||
{ GLFW.glfwSetInputMode(window, GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_NORMAL); }
|
||||
{ GLFW.glfwSetInputMode(getWindow(), GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_NORMAL); }
|
||||
|
||||
public static void update()
|
||||
{
|
||||
// Hack to make the FBO update when the screen size is changed
|
||||
if ((oldWindowHeight != Window.getHeight() || oldWindowWidth != Window.getWidth()) && Window.getHeight() > 10 && Window.getWidth() > 10)
|
||||
{
|
||||
Ginger.getInstance().contrastFbo.resizeFBOs();
|
||||
oldWindowWidth = Window.getWidth();
|
||||
oldWindowHeight = Window.getHeight();
|
||||
}
|
||||
|
||||
IntBuffer widthBuffer = BufferUtils.createIntBuffer(1);
|
||||
IntBuffer heightBuffer = BufferUtils.createIntBuffer(1);
|
||||
GLFW.glfwGetWindowSize(window, widthBuffer, heightBuffer);
|
||||
GLFW.glfwGetWindowSize(getWindow(), widthBuffer, heightBuffer);
|
||||
width = widthBuffer.get(0);
|
||||
height = heightBuffer.get(0);
|
||||
GL11.glViewport(0, 0, width, height);
|
||||
|
@ -201,4 +213,9 @@ public class Window
|
|||
|
||||
public static void fullscreen()
|
||||
{ Window.fullscreen = !Window.isFullscreen(); }
|
||||
|
||||
public static long getWindow()
|
||||
{
|
||||
return window;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,9 +37,9 @@ public class Fbo
|
|||
public Fbo(FboCallbackHandler handler)
|
||||
{
|
||||
this.handler = handler;
|
||||
this.window = Window.window;
|
||||
width = Window.actuallWidth;
|
||||
height = Window.actuallHeight;
|
||||
this.window = Window.getWindow();
|
||||
width = Window.actualWidth;
|
||||
height = Window.actualHeight;
|
||||
createFBO();
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ public class Fbo
|
|||
|
||||
public void createFBO()
|
||||
{
|
||||
this.window = Window.window;
|
||||
this.window = Window.getWindow();
|
||||
this.width = Window.getWidth();
|
||||
this.height = Window.getHeight();
|
||||
/* Create multisampled FBO */
|
||||
|
|
|
@ -66,7 +66,7 @@ public class ObjectRenderer extends Renderer
|
|||
List<RenderObject> batch = entities.get(model);
|
||||
for (RenderObject entity : batch)
|
||||
{
|
||||
if (entity.isVisible)
|
||||
if (entity.isVisible())
|
||||
{
|
||||
prepareInstance(entity);
|
||||
GL11.glDrawElements(GL11.GL_TRIANGLES, model.getRawModel().getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
|
||||
|
|
Loading…
Reference in New Issue