[Refactor] Last format and cleanup before removing Litecraft
parent
a9aded799a
commit
4b36a78a4d
|
@ -12,12 +12,12 @@ import com.github.hydos.ginger.engine.common.Constants;
|
|||
import com.github.hydos.ginger.engine.common.api.*;
|
||||
import com.github.hydos.ginger.engine.common.api.game.*;
|
||||
import com.github.hydos.ginger.engine.common.cameras.*;
|
||||
import com.github.hydos.ginger.engine.common.elements.objects.*;
|
||||
import com.github.hydos.ginger.engine.common.elements.objects.Light;
|
||||
import com.github.hydos.ginger.engine.common.font.FontType;
|
||||
import com.github.hydos.ginger.engine.common.info.RenderAPI;
|
||||
import com.github.hydos.ginger.engine.common.io.Window;
|
||||
import com.github.hydos.ginger.engine.common.obj.ModelLoader;
|
||||
import com.github.hydos.ginger.engine.opengl.api.*;
|
||||
import com.github.hydos.ginger.engine.opengl.api.GingerGL;
|
||||
import com.github.hydos.ginger.engine.opengl.postprocessing.PostProcessing;
|
||||
import com.github.hydos.ginger.engine.opengl.render.GLRenderManager;
|
||||
import com.github.hydos.ginger.engine.opengl.render.models.GLTexturedModel;
|
||||
|
@ -28,7 +28,6 @@ import tk.valoeghese.gateways.client.io.*;
|
|||
public class Litecraft extends Game
|
||||
{
|
||||
// FIXME: search for ((GingerGL)engine) and properly implement both render APIs when Vulkan is complete.
|
||||
|
||||
private static Litecraft INSTANCE;
|
||||
private World world;
|
||||
private LitecraftSave save;
|
||||
|
@ -49,7 +48,7 @@ public class Litecraft extends Game
|
|||
// setup keybinds
|
||||
setupKeybinds();
|
||||
// Open the title screen if nothing is already open.
|
||||
if (GingerRegister.getInstance().currentScreen == null && world == null) ((GingerGL)engine).openScreen(new TitleScreen());
|
||||
if (GingerRegister.getInstance().currentScreen == null && world == null) ((GingerGL) engine).openScreen(new TitleScreen());
|
||||
// start the game loop
|
||||
this.engine.startGameLoop();
|
||||
}
|
||||
|
@ -71,10 +70,8 @@ public class Litecraft extends Game
|
|||
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
|
||||
*/
|
||||
/** 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()
|
||||
{
|
||||
|
@ -89,34 +86,33 @@ public class Litecraft extends Game
|
|||
// Put what's stored in the inactive framebuffer on the screen
|
||||
Window.swapBuffers();
|
||||
}
|
||||
|
||||
|
||||
// Updates the debug stats once per real-time second, regardless of how many frames have been rendered
|
||||
private void updateDebugStats()
|
||||
{
|
||||
this.dbgStats.set(fps, ups, tps, 0);
|
||||
this.fps=0;
|
||||
this.ups=0;
|
||||
this.tps=0;
|
||||
this.fps = 0;
|
||||
this.ups = 0;
|
||||
this.tps = 0;
|
||||
this.frameTimer += 1000;
|
||||
}
|
||||
|
||||
|
||||
public void renderWorld()
|
||||
{
|
||||
GameData data = GingerRegister.getInstance().game.data;
|
||||
if (Window.renderAPI == RenderAPI.OpenGL)
|
||||
{
|
||||
GLUtils.preRenderScene(((GingerGL)engine).getRegistry().masterRenderer);
|
||||
((GingerGL)engine).contrastFbo.bindFBO();
|
||||
((GingerGL)engine).getRegistry().masterRenderer.renderScene(data.entities, data.normalMapEntities, data.lights, data.camera, data.clippingPlane);
|
||||
((GingerGL)engine).contrastFbo.unbindFBO();
|
||||
PostProcessing.doPostProcessing(((GingerGL)engine).contrastFbo.colorTexture);
|
||||
GLUtils.preRenderScene(((GingerGL) engine).getRegistry().masterRenderer);
|
||||
((GingerGL) engine).contrastFbo.bindFBO();
|
||||
((GingerGL) engine).getRegistry().masterRenderer.renderScene(data.entities, data.normalMapEntities, data.lights, data.camera, data.clippingPlane);
|
||||
((GingerGL) engine).contrastFbo.unbindFBO();
|
||||
PostProcessing.doPostProcessing(((GingerGL) engine).contrastFbo.colorTexture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void update()
|
||||
{
|
||||
ups += 1;
|
||||
}
|
||||
{ ups += 1; }
|
||||
|
||||
private void setupConstants()
|
||||
{
|
||||
|
@ -137,30 +133,29 @@ public class Litecraft extends Game
|
|||
MouseCallbackHandler.trackWindow(Window.getWindow());
|
||||
// set up ginger utilities
|
||||
GLUtils.init();
|
||||
|
||||
switch (Window.renderAPI)
|
||||
{
|
||||
case OpenGL:
|
||||
{
|
||||
this.engine = new GingerGL();
|
||||
//Set the player model
|
||||
GLTexturedModel playerModel = ModelLoader.loadGenericCube("block/cubes/stone/brick/stonebrick.png");
|
||||
FontType font = new FontType(GLLoader.loadFontAtlas("candara.png"), "candara.fnt");
|
||||
this.player = new PlayerEntity(playerModel, new Vector3f(0, 0, -3), 0, 180f, 0, new Vector3f(0.2f, 0.2f, 0.2f));
|
||||
this.camera = new FirstPersonCamera(player);
|
||||
this.data = new GameData(this.player, this.camera, 20);
|
||||
this.data.handleGuis = false;
|
||||
((GingerGL)engine).setup(new GLRenderManager(this.camera), INSTANCE);
|
||||
((GingerGL)engine).setGlobalFont(font);
|
||||
this.data.entities.add(this.player);
|
||||
break;
|
||||
}
|
||||
case Vulkan:
|
||||
{
|
||||
// TODO: Setup Vulkan
|
||||
exit();
|
||||
break;
|
||||
}
|
||||
case OpenGL:
|
||||
{
|
||||
this.engine = new GingerGL();
|
||||
//Set the player model
|
||||
GLTexturedModel playerModel = ModelLoader.loadGenericCube("block/cubes/stone/brick/stonebrick.png");
|
||||
FontType font = new FontType(GLLoader.loadFontAtlas("candara.png"), "candara.fnt");
|
||||
this.player = new PlayerEntity(playerModel, new Vector3f(0, 0, -3), 0, 180f, 0, new Vector3f(0.2f, 0.2f, 0.2f));
|
||||
this.camera = new FirstPersonCamera(player);
|
||||
this.data = new GameData(this.player, this.camera, 20);
|
||||
this.data.handleGuis = false;
|
||||
((GingerGL) engine).setup(new GLRenderManager(this.camera), INSTANCE);
|
||||
((GingerGL) engine).setGlobalFont(font);
|
||||
this.data.entities.add(this.player);
|
||||
break;
|
||||
}
|
||||
case Vulkan:
|
||||
{
|
||||
// TODO: Setup Vulkan
|
||||
exit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
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));
|
||||
this.data.lights.add(sun);
|
||||
|
@ -180,14 +175,12 @@ public class Litecraft extends Game
|
|||
Input.addPressCallback(Keybind.FLY_DOWN, () -> ((PlayerEntity) this.player).move(RelativeDirection.DOWN));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
/** 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()
|
||||
{
|
||||
tps += 1;
|
||||
tps += 1;
|
||||
if (this.player instanceof PlayerEntity && camera != null)
|
||||
{
|
||||
Input.invokeAllListeners();
|
||||
|
@ -195,7 +188,7 @@ public class Litecraft extends Game
|
|||
camera.updateMovement();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// @formatter=off
|
||||
public static Litecraft getInstance()
|
||||
{ return INSTANCE; }
|
||||
|
@ -208,16 +201,14 @@ public class Litecraft extends Game
|
|||
|
||||
public World getWorld()
|
||||
{ return this.world; }
|
||||
|
||||
|
||||
public void changeWorld(World world)
|
||||
{ this.world = world; }
|
||||
|
||||
|
||||
public void setSave(LitecraftSave save)
|
||||
{ this.save = save; }
|
||||
|
||||
@Override
|
||||
public void renderScene()
|
||||
{
|
||||
world.render(GingerRegister.getInstance().masterRenderer.blockRenderer);
|
||||
}
|
||||
{ world.render(GingerRegister.getInstance().masterRenderer.blockRenderer); }
|
||||
}
|
|
@ -75,17 +75,17 @@ public class BlockRenderer extends Renderer implements WorldGenConstants
|
|||
public void render(BlockInstance[] renderList)
|
||||
{
|
||||
prepareRender();
|
||||
|
||||
for (BlockInstance entity : renderList) {
|
||||
if (entity != null && entity.getModel() != null)
|
||||
{
|
||||
GLTexturedModel blockModel = entity.getModel();
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, blockModel.getTexture().getTextureID());
|
||||
prepBlockInstance(entity);
|
||||
GL11.glDrawElements(GL11.GL_TRIANGLES, blockModel.getRawModel().getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
}
|
||||
// disableWireframe();
|
||||
// shader.stop();
|
||||
for (BlockInstance entity : renderList)
|
||||
{
|
||||
if (entity != null && entity.getModel() != null)
|
||||
{
|
||||
GLTexturedModel blockModel = entity.getModel();
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, blockModel.getTexture().getTextureID());
|
||||
prepBlockInstance(entity);
|
||||
GL11.glDrawElements(GL11.GL_TRIANGLES, blockModel.getRawModel().getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
}
|
||||
// disableWireframe();
|
||||
// shader.stop();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,37 +14,36 @@ public class VoxelLoader extends GLLoader
|
|||
int width = 16;
|
||||
int height = 16;
|
||||
//Prepare the atlas texture and gen it
|
||||
int atlasId = GL40.glGenTextures();
|
||||
int atlasId = GL11.glGenTextures();
|
||||
//Bind it to openGL
|
||||
GL40.glBindTexture(GL40.GL_TEXTURE_2D, atlasId);
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, atlasId);
|
||||
//Apply the settings for the texture
|
||||
GL40.glTexParameteri(GL40.GL_TEXTURE_2D, GL40.GL_TEXTURE_MIN_FILTER, GL40.GL_NEAREST);
|
||||
GL40.glTexParameteri(GL40.GL_TEXTURE_2D, GL40.GL_TEXTURE_MAG_FILTER, GL40.GL_NEAREST);
|
||||
//Fill the image with blank image data
|
||||
GL40.glTexImage2D(GL40.GL_TEXTURE_2D, 0, GL11.GL_RGBA, width*2, height*2, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, (ByteBuffer) null);
|
||||
|
||||
long maxX = Math.round(Math.sqrt(Blocks.blocks.size()));
|
||||
int currentX = 0;
|
||||
int currentY = 0;
|
||||
for(Block block: Blocks.blocks) {
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
|
||||
//Fill the image with blank image data
|
||||
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, width * 2, height * 2, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, (ByteBuffer) null);
|
||||
long maxX = Math.round(Math.sqrt(Blocks.blocks.size()));
|
||||
int currentX = 0;
|
||||
int currentY = 0;
|
||||
for (Block block : Blocks.blocks)
|
||||
{
|
||||
//just in case
|
||||
|
||||
if(!block.texture.equals("DONTLOAD")) {
|
||||
if (!block.texture.equals("DONTLOAD"))
|
||||
{
|
||||
System.out.println(block.texture);
|
||||
block.updateBlockModelData();
|
||||
if(currentX > maxX) {
|
||||
if (currentX > maxX)
|
||||
{
|
||||
currentX = 0;
|
||||
currentY--;
|
||||
}
|
||||
GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, 0,
|
||||
currentX*width, currentY*height,
|
||||
width, height,
|
||||
GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE,
|
||||
block.model.getTexture().getTexture().getImage()
|
||||
);
|
||||
GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, 0,
|
||||
currentX * width, currentY * height,
|
||||
width, height,
|
||||
GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE,
|
||||
block.model.getTexture().getTexture().getImage());
|
||||
currentX++;
|
||||
}
|
||||
|
||||
}
|
||||
return atlasId;
|
||||
}
|
||||
|
|
|
@ -13,18 +13,16 @@ public class ExitGameScreen extends Screen
|
|||
private GUIText infoText;
|
||||
// TODO: Add Vulkan text renderer
|
||||
private GingerEngine engine = GingerGL.getInstance();
|
||||
|
||||
|
||||
public ExitGameScreen()
|
||||
{
|
||||
infoText = ((GingerGL)engine).registerText("Saving and exiting...", 3, new Vector2f(Window.getWidth() / 2, Window.getHeight() / 2), 1f, true, "info");
|
||||
infoText = ((GingerGL) engine).registerText("Saving and exiting...", 3, new Vector2f(Window.getWidth() / 2, Window.getHeight() / 2), 1f, true, "info");
|
||||
infoText.setBorderWidth(0.5f);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void render()
|
||||
{
|
||||
|
||||
}
|
||||
{}
|
||||
|
||||
@Override
|
||||
public void tick()
|
||||
|
|
|
@ -15,32 +15,30 @@ public class IngameHUD extends Screen
|
|||
// TODO: Add Vulkan text renderer
|
||||
private GingerEngine engine = GingerGL.getInstance();
|
||||
private Litecraft litecraft = Litecraft.getInstance();
|
||||
|
||||
|
||||
public IngameHUD()
|
||||
{
|
||||
debugText = ((GingerGL)engine).registerText("Loading...", 2, new Vector2f(0, 0), 1f, true, "debugInfo");
|
||||
debugText = ((GingerGL) engine).registerText("Loading...", 2, new Vector2f(0, 0), 1f, true, "debugInfo");
|
||||
debugText.setBorderWidth(0.5f);
|
||||
positionText = ((GingerGL)engine).registerText("Loading...", 2, new Vector2f(0, -0.1f), 1f, true, "posInfo");
|
||||
positionText = ((GingerGL) engine).registerText("Loading...", 2, new Vector2f(0, -0.1f), 1f, true, "posInfo");
|
||||
positionText.setBorderWidth(0.5f);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void render()
|
||||
{
|
||||
|
||||
}
|
||||
{}
|
||||
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
// long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
// long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
long totalMemory = Runtime.getRuntime().totalMemory();
|
||||
long freeMemory = Runtime.getRuntime().freeMemory();
|
||||
long usedMemory = (totalMemory - freeMemory) / 1024 / 1024;
|
||||
Vector4i dbg = litecraft.dbgStats;
|
||||
Vector3f position = GingerRegister.getInstance().game.data.playerObject.getPosition();
|
||||
debugText.setText("FPS: " + dbg.x() + " UPS: " + dbg.y() + " TPS: " + dbg.z() + " TWL: " + dbg.w() + " Mem: " + usedMemory + "MB");
|
||||
positionText.setText("Position: " + (int) position.x() + ", " + (int) position.y() + ", "+ (int) position.z() );
|
||||
positionText.setText("Position: " + (int) position.x() + ", " + (int) position.y() + ", " + (int) position.z());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -15,9 +15,7 @@ import com.github.hydos.ginger.engine.common.io.Window;
|
|||
import com.github.hydos.ginger.engine.common.screen.Screen;
|
||||
import com.github.hydos.ginger.engine.opengl.api.GingerGL;
|
||||
|
||||
/**
|
||||
* YeS
|
||||
*/
|
||||
/** YeS */
|
||||
public class TitleScreen extends Screen
|
||||
{
|
||||
private GUIText debugText;
|
||||
|
@ -29,9 +27,9 @@ public class TitleScreen extends Screen
|
|||
public TitleScreen()
|
||||
{
|
||||
elements = new ArrayList<GuiTexture>();
|
||||
playButton = ((GingerGL)engine).registerButton("/textures/guis/playbutton.png", new Vector2f(0, 0), new Vector2f(0.25f, 0.1f));
|
||||
playButton = ((GingerGL) engine).registerButton("/textures/guis/playbutton.png", new Vector2f(0, 0), new Vector2f(0.25f, 0.1f));
|
||||
playButton.show(Litecraft.getInstance().data.guis);
|
||||
debugText = ((GingerGL)engine).registerText("Loading...", 2, new Vector2f(0, 0), 1f, true, "debugInfo");
|
||||
debugText = ((GingerGL) engine).registerText("Loading...", 2, new Vector2f(0, 0), 1f, true, "debugInfo");
|
||||
debugText.setBorderWidth(0.5f);
|
||||
}
|
||||
|
||||
|
@ -48,16 +46,15 @@ public class TitleScreen extends Screen
|
|||
if (playButton.isClicked())
|
||||
{
|
||||
Window.lockMouse();
|
||||
|
||||
if (Litecraft.getInstance().getWorld() == null)
|
||||
{
|
||||
Litecraft.getInstance().setSave(new LitecraftSave("SegregatedOrdinalData", false));
|
||||
Litecraft.getInstance().changeWorld(Litecraft.getInstance().getSave().getWorldOrCreate(Dimensions.OVERWORLD));
|
||||
((GingerGL)engine).setGingerPlayer(Litecraft.getInstance().getWorld().playerEntity);
|
||||
((GingerGL) engine).setGingerPlayer(Litecraft.getInstance().getWorld().playerEntity);
|
||||
}
|
||||
if (Litecraft.getInstance().getWorld() != null)
|
||||
{
|
||||
((GingerGL)engine).openScreen(new IngameHUD());
|
||||
((GingerGL) engine).openScreen(new IngameHUD());
|
||||
this.cleanup();
|
||||
}
|
||||
//TODO: add world creation gui so it takes u to world creation place
|
||||
|
|
|
@ -13,7 +13,7 @@ public class Block
|
|||
private boolean fullCube = true;
|
||||
private float caveCarveThreshold = -1f; // cannot carve
|
||||
private final String identifier;
|
||||
|
||||
|
||||
public Properties(String identifier)
|
||||
{ this.identifier = identifier; }
|
||||
|
||||
|
@ -55,8 +55,8 @@ public class Block
|
|||
{ this((GLTexturedModel) null, properties); }
|
||||
|
||||
protected Block(String texture, Properties properties)
|
||||
{
|
||||
this(ModelLoader.loadGenericCube("block/"+texture), properties);
|
||||
{
|
||||
this(ModelLoader.loadGenericCube("block/" + texture), properties);
|
||||
this.texture = texture;
|
||||
}
|
||||
|
||||
|
@ -67,20 +67,24 @@ public class Block
|
|||
this.fullCube = properties.fullCube;
|
||||
this.identifier = properties.identifier;
|
||||
this.caveCarveThreshold = properties.caveCarveThreshold;
|
||||
if(model != null) {
|
||||
if (model != null)
|
||||
{
|
||||
this.texture = model.getTexture().getTexture().getLocation();
|
||||
}else {
|
||||
}
|
||||
else
|
||||
{
|
||||
this.texture = "DONTLOAD";
|
||||
}
|
||||
IDENTIFIER_TO_BLOCK.put(this.identifier, this);
|
||||
Blocks.blocks.add(this);
|
||||
}
|
||||
|
||||
public void updateBlockModelData() {
|
||||
System.out.println("Updating block with texture at block/"+texture);
|
||||
this.model = ModelLoader.loadGenericCube("block/"+texture);
|
||||
|
||||
public void updateBlockModelData()
|
||||
{
|
||||
System.out.println("Updating block with texture at block/" + texture);
|
||||
this.model = ModelLoader.loadGenericCube("block/" + texture);
|
||||
}
|
||||
|
||||
|
||||
public static final Block getBlock(String identifier)
|
||||
{ return IDENTIFIER_TO_BLOCK.get(identifier); }
|
||||
|
||||
|
|
|
@ -6,9 +6,7 @@ import com.github.halotroop.litecraft.types.block.Block.Properties;
|
|||
|
||||
public final class Blocks
|
||||
{
|
||||
|
||||
public static ArrayList<Block> blocks = new ArrayList<Block>();
|
||||
|
||||
public static final Block AIR = new Block(new Properties("air").visible(false).fullCube(false));
|
||||
public static final Block GRASS = new Block(new Properties("cubes/soil/grass/grass_top.png").caveCarveThreshold(0.04f));
|
||||
public static final Block DIRT = new Block("cubes/soil/dirt.png", new Properties("dirt").caveCarveThreshold(0.04f));
|
||||
|
@ -18,7 +16,5 @@ public final class Blocks
|
|||
public static final Block GNEISS = new Block("cubes/stone/basic/gneiss.png", new Properties("gneiss").caveCarveThreshold(0.09f));
|
||||
|
||||
public static Block init()
|
||||
{
|
||||
return AIR;
|
||||
}
|
||||
{ return AIR; }
|
||||
}
|
||||
|
|
|
@ -50,7 +50,8 @@ public class PlayerEntity extends Entity implements WorldGenConstants
|
|||
position.x += Math.sin(ry) * Constants.movementSpeed;
|
||||
break;
|
||||
case UP:
|
||||
if (this.noWeight) position.y += Constants.movementSpeed;
|
||||
if (this.noWeight)
|
||||
position.y += Constants.movementSpeed;
|
||||
else this.jump();
|
||||
break;
|
||||
case DOWN:
|
||||
|
@ -85,11 +86,9 @@ public class PlayerEntity extends Entity implements WorldGenConstants
|
|||
upwardsSpeed += Constants.gravity.y() * Window.getTime(); // TODO: Implement 3D gravity
|
||||
isInAir = false;
|
||||
upwardsSpeed = 0;
|
||||
|
||||
int newChunkX = (int) position.x >> POS_SHIFT;
|
||||
int newChunkY = (int) position.y >> POS_SHIFT;
|
||||
int newChunkZ = (int) position.z >> POS_SHIFT;
|
||||
|
||||
if (newChunkX != this.chunkX || newChunkY != this.chunkY || newChunkZ != this.chunkZ)
|
||||
{
|
||||
Litecraft.getInstance().getWorld().updateLoadedChunks(newChunkX, newChunkY, newChunkZ);
|
||||
|
|
|
@ -2,10 +2,10 @@ package com.github.halotroop.litecraft.util;
|
|||
|
||||
public enum RelativeDirection
|
||||
{
|
||||
UP, // up up
|
||||
DOWN, // down down
|
||||
LEFT, // >left< right
|
||||
RIGHT, // left >right<
|
||||
FORWARD,// b
|
||||
UP, // up up
|
||||
DOWN, // down down
|
||||
LEFT, // >left< right
|
||||
RIGHT, // left >right<
|
||||
FORWARD, // b
|
||||
BACKWARD,// a
|
||||
}
|
||||
|
|
|
@ -9,9 +9,7 @@ public final class OctaveSimplexNoise
|
|||
private double spread, amplitudeLow, amplitudeHigh;
|
||||
|
||||
public OctaveSimplexNoise(Random rand, int octaves)
|
||||
{
|
||||
this(rand, octaves, 1D, 1D, 1D);
|
||||
}
|
||||
{ this(rand, octaves, 1D, 1D, 1D); }
|
||||
|
||||
public OctaveSimplexNoise(Random rand, int octaves, double spread, double amplitudeHigh, double amplitudeLow)
|
||||
{
|
||||
|
|
|
@ -1,20 +1,17 @@
|
|||
package com.github.halotroop.litecraft.util.noise;
|
||||
|
||||
/**
|
||||
* OpenSimplex Noise in Java.
|
||||
/** OpenSimplex Noise in Java.
|
||||
* (Using implementation by Kurt Spencer)
|
||||
*
|
||||
* v1.1 (October 5, 2014)
|
||||
* - Added 2D and 4D implementations.
|
||||
* - Proper gradient sets for all dimensions, from a
|
||||
* dimensionally-generalizable scheme with an actual
|
||||
* rhyme and reason behind it.
|
||||
* dimensionally-generalizable scheme with an actual
|
||||
* rhyme and reason behind it.
|
||||
* - Removed default permutation array in favor of
|
||||
* default seed.
|
||||
* default seed.
|
||||
* - Changed seed-based constructor to be independent
|
||||
* of any particular randomization library, so results
|
||||
* will be the same when ported to other languages.
|
||||
*/
|
||||
* of any particular randomization library, so results
|
||||
* will be the same when ported to other languages. */
|
||||
public class SimplexNoise
|
||||
{
|
||||
private static final double STRETCH_CONSTANT_2D = -0.211324865405187; //(1/Math.sqrt(2+1)-1)/2;
|
||||
|
|
|
@ -16,12 +16,10 @@ import tk.valoeghese.sod.*;
|
|||
|
||||
public class Chunk implements BlockAccess, WorldGenConstants, SODSerializable
|
||||
{
|
||||
/**
|
||||
* @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 arrays.
|
||||
*/
|
||||
/** @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 arrays. */
|
||||
public static int index(int x, int y, int z)
|
||||
{ return (x & MAX_POS) | ((y & MAX_POS) << POS_SHIFT) | ((z & MAX_POS) << DOUBLE_SHIFT); }
|
||||
|
||||
|
@ -33,10 +31,8 @@ public class Chunk implements BlockAccess, WorldGenConstants, SODSerializable
|
|||
private boolean fullyGenerated = false;
|
||||
public final int dimension;
|
||||
private boolean dirty = true;
|
||||
/**
|
||||
* A holder for the rendered blocks in this chunk. This array is *NOT* safe to use for getting BIs at a position!
|
||||
* It can vary in size from 0 to 512 elements long and must only be read linearly.
|
||||
*/
|
||||
/** A holder for the rendered blocks in this chunk. This array is *NOT* safe to use for getting BIs at a position!
|
||||
* It can vary in size from 0 to 512 elements long and must only be read linearly. */
|
||||
private BlockInstance[] renderedBlocks = new BlockInstance[CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE];
|
||||
|
||||
public Chunk(World world, int chunkX, int chunkY, int chunkZ, int dimension)
|
||||
|
@ -83,81 +79,74 @@ public class Chunk implements BlockAccess, WorldGenConstants, SODSerializable
|
|||
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);
|
||||
|
||||
// Check for chunk edges to avoid errors when get the neighboring blocks, TODO fix this
|
||||
if (x == 0 || x == CHUNK_SIZE - 1 || z == 0 || z == CHUNK_SIZE - 1 || y == 0 || y == CHUNK_SIZE - 1)
|
||||
{
|
||||
tempList.add(block);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for air. Yes this is stupid, TODO fix this too
|
||||
try
|
||||
{
|
||||
if (getBlockInstance(x - 1, y, z).getModel() == null || getBlockInstance(x + 1, y, z).getModel() == null ||
|
||||
getBlockInstance(x, y - 1, z).getModel() == null || getBlockInstance(x, y + 1, z).getModel() == null ||
|
||||
getBlockInstance(x, y, z - 1).getModel() == null || getBlockInstance(x, y, z + 1).getModel() == null)
|
||||
{
|
||||
tempList.add(block);
|
||||
}
|
||||
} catch (NullPointerException e)
|
||||
{ // this seems to be a hotspot for errors
|
||||
e.printStackTrace(); // so I can add a debug breakpoint on this line
|
||||
throw e; // e
|
||||
}
|
||||
|
||||
}
|
||||
{
|
||||
BlockInstance block = getBlockInstance(x, y, z);
|
||||
// Check for chunk edges to avoid errors when get the neighboring blocks, TODO fix this
|
||||
if (x == 0 || x == CHUNK_SIZE - 1 || z == 0 || z == CHUNK_SIZE - 1 || y == 0 || y == CHUNK_SIZE - 1)
|
||||
{
|
||||
tempList.add(block);
|
||||
continue;
|
||||
}
|
||||
// Check for air. Yes this is stupid, TODO fix this too
|
||||
try
|
||||
{
|
||||
if (getBlockInstance(x - 1, y, z).getModel() == null || getBlockInstance(x + 1, y, z).getModel() == null ||
|
||||
getBlockInstance(x, y - 1, z).getModel() == null || getBlockInstance(x, y + 1, z).getModel() == null ||
|
||||
getBlockInstance(x, y, z - 1).getModel() == null || getBlockInstance(x, y, z + 1).getModel() == null)
|
||||
{ tempList.add(block); }
|
||||
}
|
||||
catch (NullPointerException e)
|
||||
{ // this seems to be a hotspot for errors
|
||||
e.printStackTrace(); // so I can add a debug breakpoint on this line
|
||||
throw e; // e
|
||||
}
|
||||
}
|
||||
renderedBlocks = tempList.toArray(BlockInstance[]::new);
|
||||
}
|
||||
|
||||
blockRenderer.prepareRender();
|
||||
blockRenderer.render(renderedBlocks);
|
||||
blockRenderer.shader.stop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
/** 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)
|
||||
{
|
||||
// This section makes sure the blocks don't go out of range
|
||||
if (x > MAX_POS) x = MAX_POS;
|
||||
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.shouldRender) this.blockInstances[index(x, y, z)] =
|
||||
new BlockInstance(block, new Vector3f(this.chunkStartX + x, this.chunkStartY + y, this.chunkStartZ + z));
|
||||
if (this.shouldRender) this.blockInstances[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
|
||||
*/
|
||||
/** Set whether or not the chunk should render */
|
||||
public void setRender(boolean render)
|
||||
{
|
||||
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)
|
||||
{
|
||||
Block block = this.blocks[index(x, y, z)];
|
||||
|
||||
this.blockInstances[index(x, y, z)] = new BlockInstance(block,
|
||||
new Vector3f(
|
||||
this.chunkStartX + x,
|
||||
this.chunkStartY + y,
|
||||
this.chunkStartZ + z));
|
||||
}
|
||||
{
|
||||
Block block = this.blocks[index(x, y, z)];
|
||||
this.blockInstances[index(x, y, z)] = new BlockInstance(block,
|
||||
new Vector3f(
|
||||
this.chunkStartX + x,
|
||||
this.chunkStartY + y,
|
||||
this.chunkStartZ + z));
|
||||
}
|
||||
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
|
||||
|
@ -197,10 +186,10 @@ public class Chunk implements BlockAccess, WorldGenConstants, SODSerializable
|
|||
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;
|
||||
}
|
||||
{
|
||||
blocks[index] = palette.get(blockData.readInt(index));
|
||||
++index;
|
||||
}
|
||||
//
|
||||
DataSection properties = data.get("properties");
|
||||
try
|
||||
|
@ -218,7 +207,6 @@ public class Chunk implements BlockAccess, WorldGenConstants, SODSerializable
|
|||
}
|
||||
|
||||
private static boolean readExceptionNotif = false;
|
||||
|
||||
private int nextId; // for saving
|
||||
|
||||
@Override
|
||||
|
@ -234,11 +222,11 @@ public class Chunk implements BlockAccess, WorldGenConstants, SODSerializable
|
|||
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;
|
||||
}
|
||||
{
|
||||
Block b = blocks[index];
|
||||
blockData.writeInt(palette.computeIntIfAbsent(b, nextIdProvider));
|
||||
++index;
|
||||
}
|
||||
//
|
||||
palette.forEach((b, id) ->
|
||||
{
|
||||
|
|
|
@ -33,6 +33,7 @@ public class World implements BlockAccess, WorldGenConstants
|
|||
int renderBoundVertical;
|
||||
// dummy block instance for retrieving the default block model
|
||||
private final BlockInstance dummy;
|
||||
|
||||
public World(long seed, int renderSize, Dimension<?> dim, LitecraftSave save)
|
||||
{
|
||||
this.threadPool = new ForkJoinPool(4, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true);
|
||||
|
@ -44,32 +45,26 @@ public class World implements BlockAccess, WorldGenConstants
|
|||
this.worldModifiers = dim.getWorldModifierArray();
|
||||
// initialize world modifiers with seed
|
||||
for (WorldModifier modifier : this.worldModifiers)
|
||||
{
|
||||
modifier.initialize(seed);
|
||||
}
|
||||
{ modifier.initialize(seed); }
|
||||
this.genBlockAccess = new GenerationWorld(this);
|
||||
this.save = save;
|
||||
this.dimension = dim.id;
|
||||
this.renderBound = renderSize / 2;
|
||||
this.renderBoundVertical = this.renderBound / 2;
|
||||
if (this.renderBoundVertical < 2)
|
||||
{
|
||||
this.renderBoundVertical = 2;
|
||||
}
|
||||
{ this.renderBoundVertical = 2; }
|
||||
}
|
||||
|
||||
public int findAir(int x, int z)
|
||||
{
|
||||
int y = SEA_LEVEL;
|
||||
int attemptsRemaining = 255;
|
||||
|
||||
while (attemptsRemaining-- > 0)
|
||||
{
|
||||
// DO NOT CHANGE TO y++
|
||||
if (this.getBlock(x, ++y, z) == Blocks.AIR)
|
||||
return y;
|
||||
}
|
||||
|
||||
return -1; // if it fails, returns -1
|
||||
}
|
||||
|
||||
|
@ -78,7 +73,6 @@ public class World implements BlockAccess, WorldGenConstants
|
|||
int y = this.findAir(0, 0);
|
||||
if (y == -1)
|
||||
y = 300; // yeet
|
||||
|
||||
this.spawnPlayer(0, y, -3);
|
||||
}
|
||||
|
||||
|
@ -86,7 +80,6 @@ public class World implements BlockAccess, WorldGenConstants
|
|||
{
|
||||
this.playerEntity = (PlayerEntity) Litecraft.getInstance().player;
|
||||
this.playerEntity.setVisible(false);
|
||||
|
||||
// Generate world around player
|
||||
long time = System.currentTimeMillis();
|
||||
System.out.println("Generating world!");
|
||||
|
@ -142,9 +135,7 @@ public class World implements BlockAccess, WorldGenConstants
|
|||
}
|
||||
|
||||
void populateChunk(Chunk chunk)
|
||||
{
|
||||
this.populateChunk(chunk.chunkX, chunk.chunkY, chunk.chunkZ, chunk.chunkStartX, chunk.chunkStartY, chunk.chunkStartZ);
|
||||
}
|
||||
{ this.populateChunk(chunk.chunkX, chunk.chunkY, chunk.chunkZ, chunk.chunkStartX, chunk.chunkStartY, chunk.chunkStartZ); }
|
||||
|
||||
private void populateChunk(int chunkX, int chunkY, int chunkZ, int chunkStartX, int chunkStartY, int chunkStartZ)
|
||||
{
|
||||
|
@ -178,7 +169,7 @@ public class World implements BlockAccess, WorldGenConstants
|
|||
public void render(BlockRenderer blockRenderer)
|
||||
{
|
||||
blockRenderer.prepareModel(this.dummy.getModel());
|
||||
this.chunks.forEach((pos, c) ->
|
||||
this.chunks.forEach((pos, c) ->
|
||||
{
|
||||
if (c != null && c.isFullyGenerated())
|
||||
c.render(blockRenderer);
|
||||
|
@ -220,7 +211,6 @@ public class World implements BlockAccess, WorldGenConstants
|
|||
for (int z = chunkZ - this.renderBound; z < chunkZ + this.renderBound; z++)
|
||||
for (int y = chunkY - this.renderBound; y < chunkY + this.renderBound; y++)
|
||||
toKeep.add(this.getChunkToLoad(x, y, z));
|
||||
|
||||
LongList toRemove = new LongArrayList();
|
||||
// check which loaded chunks are not neccesary
|
||||
chunks.forEach((pos, chunk) ->
|
||||
|
@ -230,7 +220,6 @@ public class World implements BlockAccess, WorldGenConstants
|
|||
});
|
||||
// unload unneccesary chunks from chunk array
|
||||
toRemove.forEach((LongConsumer) this::unloadChunk);
|
||||
|
||||
toKeep.forEach(chunk ->
|
||||
{
|
||||
if (!chunk.isFullyGenerated())
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.github.halotroop.litecraft.world.gen.WorldGenConstants;
|
|||
public class CavesModifier implements WorldModifier, WorldGenConstants
|
||||
{
|
||||
private OctaveSimplexNoise caveNoise;
|
||||
|
||||
@Override
|
||||
public void initialize(long seed)
|
||||
{
|
||||
|
@ -21,7 +22,6 @@ public class CavesModifier implements WorldModifier, WorldGenConstants
|
|||
public void modifyWorld(BlockAccess world, Random rand, int chunkStartX, int chunkStartY, int chunkStartZ)
|
||||
{
|
||||
final int subChunks = CHUNK_SIZE >> 2; // in 4x4x4 blocks
|
||||
|
||||
for (int subChunkX = 0; subChunkX < subChunks; subChunkX++)
|
||||
{
|
||||
int scOffsetX = subChunkX << 2; // sub chunk offset x
|
||||
|
@ -34,7 +34,7 @@ public class CavesModifier implements WorldModifier, WorldGenConstants
|
|||
{
|
||||
int scOffsetY = subChunkY << 2; // sub chunk offset y
|
||||
int scTotalY = scOffsetY + chunkStartY;
|
||||
double scSampleY = (double) scTotalY * 1.5; // squish caves along y axis a bit
|
||||
double scSampleY = scTotalY * 1.5; // squish caves along y axis a bit
|
||||
double scUpperYOffset = 4.0 * 1.5;
|
||||
// calculate noise at each corner of the cube [lower|upper][south|north][west|east]
|
||||
double noiseLSW = this.caveNoise.sample(scTotalX, scSampleY, scTotalZ); // base = lower south west
|
||||
|
@ -82,9 +82,7 @@ public class CavesModifier implements WorldModifier, WorldGenConstants
|
|||
// if the noise is within the threshold for that block for caves
|
||||
float threshold = world.getBlock(totalX, totalY, totalZ).getCaveCarveThreshold();
|
||||
if (-threshold < lerpNoise && lerpNoise < threshold)
|
||||
{
|
||||
world.setBlock(totalX, totalY, totalZ, Blocks.AIR);
|
||||
}
|
||||
{ world.setBlock(totalX, totalY, totalZ, Blocks.AIR); }
|
||||
// add progress to the noise
|
||||
lerpNoise += lerpProg;
|
||||
}
|
||||
|
|
|
@ -7,5 +7,6 @@ import com.github.halotroop.litecraft.world.BlockAccess;
|
|||
public interface WorldModifier
|
||||
{
|
||||
void modifyWorld(BlockAccess world, Random rand, int chunkStartX, int chunkStartY, int chunkStartZ);
|
||||
|
||||
void initialize(long seed);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,12 +10,10 @@ public abstract class GingerEngine
|
|||
{
|
||||
protected static GingerEngine INSTANCE;
|
||||
protected GingerRegister registry;
|
||||
|
||||
|
||||
public static GingerEngine getInstance()
|
||||
{
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
{ return INSTANCE; }
|
||||
|
||||
protected Timer timer;
|
||||
protected TickListener gameTickListener = new TickListener()
|
||||
{
|
||||
|
@ -26,7 +24,7 @@ public abstract class GingerEngine
|
|||
if (GingerRegister.getInstance().currentScreen != null) GingerRegister.getInstance().currentScreen.tick();
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
public void startGameLoop()
|
||||
{
|
||||
while (!Window.closed())
|
||||
|
|
|
@ -26,9 +26,7 @@ public class GingerRegister
|
|||
public boolean wireframe = false;
|
||||
|
||||
public GingerRegister()
|
||||
{
|
||||
INSTANCE = this;
|
||||
}
|
||||
{ INSTANCE = this; }
|
||||
|
||||
public void registerButton(TextureButton button)
|
||||
{
|
||||
|
@ -59,9 +57,7 @@ public class GingerRegister
|
|||
}
|
||||
|
||||
public void toggleWireframe()
|
||||
{
|
||||
this.wireframe = !this.wireframe;
|
||||
}
|
||||
{ this.wireframe = !this.wireframe; }
|
||||
|
||||
public GUIText retrieveText(String string)
|
||||
{
|
||||
|
|
|
@ -17,7 +17,7 @@ public abstract class Game
|
|||
public abstract void render();
|
||||
|
||||
public abstract void renderScene();
|
||||
|
||||
|
||||
public abstract void tick();
|
||||
|
||||
public abstract void update();
|
||||
|
|
|
@ -8,10 +8,8 @@ import com.github.hydos.ginger.engine.common.cameras.Camera;
|
|||
import com.github.hydos.ginger.engine.common.elements.GuiTexture;
|
||||
import com.github.hydos.ginger.engine.common.elements.objects.*;
|
||||
|
||||
/**
|
||||
* Used for storing essential engine game data so main class isn't messy
|
||||
* Also in general used with Game Class
|
||||
*/
|
||||
/** Used for storing essential engine game data so main class isn't messy
|
||||
* Also in general used with Game Class */
|
||||
public class GameData
|
||||
{
|
||||
public List<GuiTexture> guis;
|
||||
|
|
|
@ -12,7 +12,7 @@ public abstract class Camera
|
|||
|
||||
public Vector3f getPosition()
|
||||
{ return position; }
|
||||
|
||||
|
||||
public float getPitch()
|
||||
{ return pitch; }
|
||||
|
||||
|
|
|
@ -17,18 +17,23 @@ public class FirstPersonCamera extends Camera
|
|||
playerEntity.setVisible(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getPitch()
|
||||
{ return pitch; }
|
||||
|
||||
@Override
|
||||
public Vector3f getPosition()
|
||||
{ return position; }
|
||||
|
||||
@Override
|
||||
public float getRoll()
|
||||
{ return roll; }
|
||||
|
||||
@Override
|
||||
public float getYaw()
|
||||
{ return yaw; }
|
||||
|
||||
@Override
|
||||
public void updateMovement()
|
||||
{
|
||||
position.x = player.getPosition().x;
|
||||
|
|
|
@ -8,12 +8,11 @@ import com.github.hydos.ginger.engine.common.io.Window;
|
|||
public class ThirdPersonCamera extends Camera
|
||||
{
|
||||
public ThirdPersonCamera(RenderObject playerEntity)
|
||||
{
|
||||
this.player = playerEntity;
|
||||
}
|
||||
{ this.player = playerEntity; }
|
||||
|
||||
private float distanceFromPlayer = 5;
|
||||
private float angleAroundPlayer = 0;
|
||||
|
||||
private void calculatePitch()
|
||||
{
|
||||
if (Window.isMouseDown(1))
|
||||
|
@ -28,7 +27,8 @@ public class ThirdPersonCamera extends Camera
|
|||
{ setPitch(90); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void updateMovement()
|
||||
{
|
||||
calculateZoom();
|
||||
|
|
|
@ -50,7 +50,8 @@ public class Player extends RenderObject implements WorldGenConstants
|
|||
position.x += Math.sin(ry) * Constants.movementSpeed;
|
||||
break;
|
||||
case UP:
|
||||
if (this.noWeight) position.y += Constants.movementSpeed;
|
||||
if (this.noWeight)
|
||||
position.y += Constants.movementSpeed;
|
||||
else this.jump();
|
||||
break;
|
||||
case DOWN:
|
||||
|
@ -85,11 +86,9 @@ public class Player extends RenderObject implements WorldGenConstants
|
|||
upwardsSpeed += Constants.gravity.y() * Window.getTime(); // TODO: Implement 3D gravity
|
||||
isInAir = false;
|
||||
upwardsSpeed = 0;
|
||||
|
||||
int newChunkX = (int) position.x >> POS_SHIFT;
|
||||
int newChunkY = (int) position.y >> POS_SHIFT;
|
||||
int newChunkZ = (int) position.z >> POS_SHIFT;
|
||||
|
||||
if (newChunkX != this.chunkX || newChunkY != this.chunkY || newChunkZ != this.chunkZ)
|
||||
{
|
||||
Litecraft.getInstance().getWorld().updateLoadedChunks(newChunkX, newChunkY, newChunkZ);
|
||||
|
|
|
@ -82,12 +82,8 @@ public class RenderObject
|
|||
{ this.scale = scale; }
|
||||
|
||||
public boolean isVisible()
|
||||
{
|
||||
return visible;
|
||||
}
|
||||
{ return visible; }
|
||||
|
||||
public void setVisible(boolean visible)
|
||||
{
|
||||
this.visible = visible;
|
||||
}
|
||||
{ this.visible = visible; }
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.github.hydos.ginger.engine.common.font;
|
|||
|
||||
import java.util.*;
|
||||
|
||||
import com.github.hydos.ginger.engine.common.api.GingerEngine;
|
||||
import com.github.hydos.ginger.engine.common.info.RenderAPI;
|
||||
import com.github.hydos.ginger.engine.common.io.Window;
|
||||
import com.github.hydos.ginger.engine.opengl.api.GingerGL;
|
||||
|
@ -51,10 +52,10 @@ public class TextMaster
|
|||
if (Window.renderAPI == RenderAPI.OpenGL)
|
||||
{
|
||||
Map<FontType, List<GUIText>> oldTexts = texts;
|
||||
List<GUIText> oldFontText = texts.get(((GingerGL)GingerGL.getInstance()).globalFont);
|
||||
List<GUIText> oldFontText = texts.get(((GingerGL) GingerEngine.getInstance()).globalFont);
|
||||
oldFontText.add(buildText);
|
||||
texts.clear();
|
||||
texts.put(((GingerGL)GingerGL.getInstance()).globalFont, oldFontText);
|
||||
texts.put(((GingerGL) GingerEngine.getInstance()).globalFont, oldFontText);
|
||||
texts = oldTexts;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
package com.github.hydos.ginger.engine.common.info;
|
||||
|
||||
public enum RenderAPI
|
||||
{OpenGL, Vulkan}
|
||||
{
|
||||
OpenGL, Vulkan
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import org.lwjgl.BufferUtils;
|
|||
import org.lwjgl.glfw.*;
|
||||
import org.lwjgl.opengl.*;
|
||||
|
||||
import com.github.hydos.ginger.engine.common.api.GingerEngine;
|
||||
import com.github.hydos.ginger.engine.common.info.RenderAPI;
|
||||
import com.github.hydos.ginger.engine.opengl.api.GingerGL;
|
||||
import com.github.hydos.ginger.engine.opengl.render.texture.Image;
|
||||
|
@ -29,7 +30,7 @@ public class Window
|
|||
|
||||
public static boolean isFullscreen()
|
||||
{ return fullscreen; }
|
||||
|
||||
|
||||
public static RenderAPI renderAPI;
|
||||
public static int width;
|
||||
public static int height;
|
||||
|
@ -63,7 +64,7 @@ public class Window
|
|||
System.exit(-1);
|
||||
}
|
||||
renderAPI = api;
|
||||
if(renderAPI == RenderAPI.OpenGL)
|
||||
if (renderAPI == RenderAPI.OpenGL)
|
||||
{
|
||||
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 6);
|
||||
|
@ -72,10 +73,9 @@ public class Window
|
|||
}
|
||||
else if (renderAPI == RenderAPI.Vulkan)
|
||||
{
|
||||
GLFW.glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
if (!GLFWVulkan.glfwVulkanSupported()) {
|
||||
throw new AssertionError("GLFW failed to find the Vulkan loader");
|
||||
}
|
||||
GLFW.glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
if (!GLFWVulkan.glfwVulkanSupported())
|
||||
{ throw new AssertionError("GLFW failed to find the Vulkan loader"); }
|
||||
}
|
||||
GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE);
|
||||
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
|
@ -91,7 +91,8 @@ public class Window
|
|||
System.exit(-1);
|
||||
}
|
||||
GLFW.glfwMakeContextCurrent(getWindow());
|
||||
if(api == RenderAPI.OpenGL) {
|
||||
if (api == RenderAPI.OpenGL)
|
||||
{
|
||||
glContext = GL.createCapabilities();
|
||||
GL11.glEnable(GL11.GL_DEPTH_TEST);
|
||||
}
|
||||
|
@ -99,7 +100,6 @@ public class Window
|
|||
GLFW.glfwShowWindow(getWindow());
|
||||
time = getTime();
|
||||
getCurrentTime();
|
||||
|
||||
oldWindowWidth = getWidth();
|
||||
oldWindowHeight = getHeight();
|
||||
}
|
||||
|
@ -208,15 +208,16 @@ public class Window
|
|||
|
||||
public static void update()
|
||||
{
|
||||
if(renderAPI == RenderAPI.OpenGL) {
|
||||
if (renderAPI == RenderAPI.OpenGL)
|
||||
{
|
||||
if ((oldWindowHeight != Window.getHeight() || oldWindowWidth != Window.getWidth()) && Window.getHeight() > 10 && Window.getWidth() > 10)
|
||||
{
|
||||
((GingerGL)GingerGL.getInstance()).contrastFbo.resizeFBOs();
|
||||
((GingerGL) GingerEngine.getInstance()).contrastFbo.resizeFBOs();
|
||||
oldWindowWidth = Window.getWidth();
|
||||
oldWindowHeight = Window.getHeight();
|
||||
}
|
||||
GL11.glViewport(0, 0, width, height);
|
||||
GL11.glClearColor(backgroundColour.x/255, backgroundColour.y/255, backgroundColour.z/255, 1.0f);
|
||||
GL11.glClearColor(backgroundColour.x / 255, backgroundColour.y / 255, backgroundColour.z / 255, 1.0f);
|
||||
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
IntBuffer widthBuffer = BufferUtils.createIntBuffer(1);
|
||||
|
@ -237,7 +238,5 @@ public class Window
|
|||
{ Window.fullscreen = !Window.isFullscreen(); }
|
||||
|
||||
public static long getWindow()
|
||||
{
|
||||
return window;
|
||||
}
|
||||
{ return window; }
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@ public class Maths
|
|||
private static final Vector3f ZVEC = new Vector3f(0, 0, 1);
|
||||
private static final Matrix4f matrix = new Matrix4f();
|
||||
|
||||
|
||||
public static Matrix4f createTransformationMatrix(Vector3f translation, float rx, float ry, float rz, Vector3f scale)
|
||||
{
|
||||
matrix.zero();
|
||||
|
|
|
@ -13,18 +13,18 @@ public class ModelLoader
|
|||
GLTexturedModel tm = new GLTexturedModel(GLLoader.loadToVAO(data.getVertices(), data.getIndices(), data.getNormals(), data.getTextureCoords()), new ModelTexture(cubeTexture));
|
||||
return tm;
|
||||
}
|
||||
|
||||
public static Mesh getCubeMesh() {
|
||||
return StaticCube.getCube();
|
||||
}
|
||||
|
||||
public static Mesh getCubeMesh()
|
||||
{ return StaticCube.getCube(); }
|
||||
|
||||
public static GLTexturedModel loadModel(String objPath, String texturePath)
|
||||
{
|
||||
Mesh data = OBJFileLoader.loadModel(objPath);
|
||||
return new GLTexturedModel(GLLoader.loadToVAO(data.getVertices(), data.getIndices(), data.getNormals(), data.getTextureCoords()), new ModelTexture(texturePath));
|
||||
}
|
||||
|
||||
public static Mesh loadMesh(String meshPath) {
|
||||
|
||||
public static Mesh loadMesh(String meshPath)
|
||||
{
|
||||
Mesh data = OBJFileLoader.loadModel(meshPath);
|
||||
return data;
|
||||
}
|
||||
|
|
|
@ -15,9 +15,9 @@ public class OBJFileLoader
|
|||
{
|
||||
scene = Assimp.aiImportFile(resourceLocation + filePath, Assimp.aiProcess_JoinIdenticalVertices | Assimp.aiProcess_Triangulate);
|
||||
if (scene == null)
|
||||
{
|
||||
{
|
||||
System.err.println("The model " + resourceLocation + filePath + " has failed to load");
|
||||
return new Mesh(new float[0], new float[0], new float[0], new int[0], 1F);
|
||||
return new Mesh(new float[0], new float[0], new float[0], new int[0], 1F);
|
||||
}
|
||||
AIMesh mesh = AIMesh.create(scene.mMeshes().get(0));
|
||||
int vertexCount = mesh.mNumVertices();
|
||||
|
|
|
@ -8,9 +8,9 @@ public abstract class Screen
|
|||
{
|
||||
public List<GuiTexture> elements;
|
||||
|
||||
public abstract void render(); // FIXME: This never gets called!!!
|
||||
public abstract void render(); // FIXME: This never gets called!!!
|
||||
|
||||
public abstract void tick();
|
||||
|
||||
|
||||
public abstract void cleanup();
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ public class GingerGL extends GingerEngine
|
|||
public FontType globalFont;
|
||||
public FrameBufferObject contrastFbo;
|
||||
|
||||
@Override
|
||||
public void cleanup()
|
||||
{
|
||||
Window.stop();
|
||||
|
@ -30,12 +31,13 @@ public class GingerGL extends GingerEngine
|
|||
GLLoader.cleanUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openScreen(Screen screen)
|
||||
{
|
||||
if (getRegistry().currentScreen != null) getRegistry().currentScreen.cleanup();
|
||||
getRegistry().currentScreen = screen;
|
||||
}
|
||||
|
||||
|
||||
public void setGingerPlayer(RenderObject player)
|
||||
{
|
||||
registry.game.data.entities.remove(registry.game.player); // remove the old player
|
||||
|
@ -60,6 +62,7 @@ public class GingerGL extends GingerEngine
|
|||
return text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderOverlays()
|
||||
{
|
||||
getRegistry().masterRenderer.renderGuis(getRegistry().game.data.guis);
|
||||
|
@ -82,7 +85,7 @@ public class GingerGL extends GingerEngine
|
|||
picker = new MousePicker(game.data.camera, masterRenderer.getProjectionMatrix());
|
||||
PostProcessing.init();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void update()
|
||||
{
|
||||
|
@ -92,7 +95,5 @@ public class GingerGL extends GingerEngine
|
|||
}
|
||||
|
||||
public GingerRegister getRegistry()
|
||||
{
|
||||
return registry;
|
||||
}
|
||||
{ return registry; }
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
package com.github.hydos.ginger.engine.opengl.api;
|
||||
|
||||
/**
|
||||
* make your own resource manager if you want!
|
||||
*/
|
||||
/** make your own resource manager if you want! */
|
||||
public abstract class ResourceManager
|
||||
{
|
||||
public abstract boolean getResourceInternally(String path);
|
||||
|
|
|
@ -37,7 +37,7 @@ public class GLRenderManager
|
|||
public GLObjectRenderer entityRenderer;
|
||||
private GuiShader guiShader;
|
||||
private GLGuiRenderer guiRenderer;
|
||||
// private SkyboxRenderer skyboxRenderer;
|
||||
// private SkyboxRenderer skyboxRenderer;
|
||||
private GLNormalMappingRenderer normalRenderer;
|
||||
private Matrix4f projectionMatrix;
|
||||
private ShadowMapMasterRenderer shadowMapRenderer;
|
||||
|
@ -162,7 +162,7 @@ public class GLRenderManager
|
|||
renderEntities(entities, camera, lights);
|
||||
renderNormalEntities(normalEntities, lights, camera, clipPlane);
|
||||
GingerRegister.getInstance().game.renderScene();
|
||||
// skyboxRenderer.render(camera);
|
||||
// skyboxRenderer.render(camera);
|
||||
}
|
||||
|
||||
public void renderShadowMap(List<RenderObject> entityList, Light sun)
|
||||
|
|
|
@ -40,7 +40,6 @@ public class GLGuiRenderer extends Renderer
|
|||
GL11.glEnable(GL11.GL_BLEND);
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST);
|
||||
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
for (GuiTexture gui : guis)
|
||||
{
|
||||
GL13.glActiveTexture(GL13.GL_TEXTURE0);
|
||||
|
|
|
@ -64,7 +64,6 @@ public class Image
|
|||
public IntBuffer getComp()
|
||||
{ return comp; }
|
||||
|
||||
public String getLocation() {
|
||||
return location;
|
||||
}
|
||||
public String getLocation()
|
||||
{ return location; }
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.github.hydos.ginger.engine.opengl.utils;
|
||||
|
||||
import java.nio.*;
|
||||
|
@ -47,11 +46,14 @@ public class GLLoader
|
|||
public static int createEmptyVbo(int floatCount)
|
||||
{
|
||||
int vbo;
|
||||
if (Window.glContext.GL_ARB_vertex_buffer_object) { //checks if gpu can handle faster vbos
|
||||
if (Window.glContext.GL_ARB_vertex_buffer_object)
|
||||
{ //checks if gpu can handle faster vbos
|
||||
IntBuffer buffer = BufferUtils.createIntBuffer(1);
|
||||
ARBVertexBufferObject.glGenBuffersARB(buffer);
|
||||
vbo = buffer.get(0);
|
||||
}else {
|
||||
}
|
||||
else
|
||||
{
|
||||
vbo = GL15.glGenBuffers();
|
||||
}
|
||||
vbos.add(vbo);
|
||||
|
@ -102,47 +104,46 @@ public class GLLoader
|
|||
|
||||
public static int loadTexture(String path)
|
||||
{ return loadTextureDirectly("/textures/" + path); }
|
||||
|
||||
|
||||
public static int createBlockAtlas()
|
||||
{
|
||||
int width = 16;
|
||||
int height = 16;
|
||||
//Prepare the atlas texture and gen it
|
||||
int atlasId = GL40.glGenTextures();
|
||||
int atlasId = GL11.glGenTextures();
|
||||
//Bind it to openGL
|
||||
GL40.glBindTexture(GL40.GL_TEXTURE_2D, atlasId);
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, atlasId);
|
||||
//Apply the settings for the texture
|
||||
GL40.glTexParameteri(GL40.GL_TEXTURE_2D, GL40.GL_TEXTURE_MIN_FILTER, GL40.GL_NEAREST);
|
||||
GL40.glTexParameteri(GL40.GL_TEXTURE_2D, GL40.GL_TEXTURE_MAG_FILTER, GL40.GL_NEAREST);
|
||||
//Fill the image with blank image data
|
||||
GL40.glTexImage2D(GL40.GL_TEXTURE_2D, 0, GL11.GL_RGBA, width*2, height*2, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, (ByteBuffer) null);
|
||||
|
||||
long maxX = Math.round(Math.sqrt(Blocks.blocks.size()));
|
||||
int currentX = 0;
|
||||
int currentY = 0;
|
||||
for(Block block: Blocks.blocks) {
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
|
||||
//Fill the image with blank image data
|
||||
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, width * 2, height * 2, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, (ByteBuffer) null);
|
||||
long maxX = Math.round(Math.sqrt(Blocks.blocks.size()));
|
||||
int currentX = 0;
|
||||
int currentY = 0;
|
||||
for (Block block : Blocks.blocks)
|
||||
{
|
||||
//just in case
|
||||
|
||||
if(!block.texture.equals("DONTLOAD")) {
|
||||
if (!block.texture.equals("DONTLOAD"))
|
||||
{
|
||||
System.out.println(block.texture);
|
||||
block.updateBlockModelData();
|
||||
if(currentX > maxX) {
|
||||
if (currentX > maxX)
|
||||
{
|
||||
currentX = 0;
|
||||
currentY--;
|
||||
}
|
||||
GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, 0,
|
||||
currentX*width, currentY*height,
|
||||
width, height,
|
||||
GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE,
|
||||
block.model.getTexture().getTexture().getImage()
|
||||
);
|
||||
GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, 0,
|
||||
currentX * width, currentY * height,
|
||||
width, height,
|
||||
GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE,
|
||||
block.model.getTexture().getTexture().getImage());
|
||||
currentX++;
|
||||
}
|
||||
|
||||
}
|
||||
return atlasId;
|
||||
}
|
||||
|
||||
|
||||
public static int loadTextureDirectly(String path)
|
||||
{
|
||||
int textureID = GL11.glGenTextures();
|
||||
|
|
|
@ -2,7 +2,4 @@ package com.github.hydos.ginger.engine.vulkan;
|
|||
|
||||
public class VKRegister
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -4,48 +4,40 @@ import java.util.*;
|
|||
|
||||
import org.joml.*;
|
||||
|
||||
/**
|
||||
* An utility class for dealing with alignments in Uniform Buffer Objects
|
||||
*
|
||||
/** An utility class for dealing with alignments in Uniform Buffer Objects
|
||||
* Vulkan expects the data in your structure to be aligned in memory in a specific way, for example:
|
||||
*
|
||||
* Scalars have to be aligned by N (= 4 bytes given 32 bit floats).
|
||||
* A vec2 must be aligned by 2N (= 8 bytes)
|
||||
* A vec3 or vec4 must be aligned by 4N (= 16 bytes)
|
||||
* A nested structure must be aligned by the base alignment of its members rounded up to a multiple of 16.
|
||||
* A mat4 matrix must have the same alignment as a vec4.
|
||||
*
|
||||
* */
|
||||
public final class AlignmentUtils {
|
||||
* A mat4 matrix must have the same alignment as a vec4. */
|
||||
public final class AlignmentUtils
|
||||
{
|
||||
private AlignmentUtils()
|
||||
{}
|
||||
|
||||
private AlignmentUtils() {}
|
||||
public static int sizeof(Object obj)
|
||||
{ return obj == null ? 0 : SIZEOF_CACHE.getOrDefault(obj.getClass(), 0); }
|
||||
|
||||
public static int sizeof(Object obj) {
|
||||
return obj == null ? 0 : SIZEOF_CACHE.getOrDefault(obj.getClass(), 0);
|
||||
}
|
||||
public static int alignof(Object obj)
|
||||
{ return obj == null ? 0 : SIZEOF_CACHE.getOrDefault(obj.getClass(), Integer.BYTES); }
|
||||
|
||||
public static int alignof(Object obj) {
|
||||
return obj == null ? 0 : SIZEOF_CACHE.getOrDefault(obj.getClass(), Integer.BYTES);
|
||||
}
|
||||
public static int alignas(int offset, int alignment)
|
||||
{ return offset % alignment == 0 ? offset : ((offset - 1) | (alignment - 1)) + 1; }
|
||||
|
||||
public static int alignas(int offset, int alignment) {
|
||||
return offset % alignment == 0 ? offset : ((offset - 1) | (alignment - 1)) + 1;
|
||||
}
|
||||
|
||||
private static final Map<Class<?>, Integer> SIZEOF_CACHE = new HashMap<>();
|
||||
static {
|
||||
SIZEOF_CACHE.put(Byte.class, Byte.BYTES);
|
||||
SIZEOF_CACHE.put(Character.class, Character.BYTES);
|
||||
SIZEOF_CACHE.put(Short.class, Short.BYTES);
|
||||
SIZEOF_CACHE.put(Integer.class, Integer.BYTES);
|
||||
SIZEOF_CACHE.put(Float.class, Float.BYTES);
|
||||
SIZEOF_CACHE.put(Long.class, Long.BYTES);
|
||||
SIZEOF_CACHE.put(Double.class, Double.BYTES);
|
||||
|
||||
SIZEOF_CACHE.put(Vector2f.class, 2 * Float.BYTES);
|
||||
SIZEOF_CACHE.put(Vector3f.class, 3 * Float.BYTES);
|
||||
SIZEOF_CACHE.put(Vector4f.class, 4 * Float.BYTES);
|
||||
|
||||
SIZEOF_CACHE.put(Matrix4f.class, SIZEOF_CACHE.get(Vector4f.class));
|
||||
}
|
||||
private static final Map<Class<?>, Integer> SIZEOF_CACHE = new HashMap<>();
|
||||
static
|
||||
{
|
||||
SIZEOF_CACHE.put(Byte.class, Byte.BYTES);
|
||||
SIZEOF_CACHE.put(Character.class, Character.BYTES);
|
||||
SIZEOF_CACHE.put(Short.class, Short.BYTES);
|
||||
SIZEOF_CACHE.put(Integer.class, Integer.BYTES);
|
||||
SIZEOF_CACHE.put(Float.class, Float.BYTES);
|
||||
SIZEOF_CACHE.put(Long.class, Long.BYTES);
|
||||
SIZEOF_CACHE.put(Double.class, Double.BYTES);
|
||||
SIZEOF_CACHE.put(Vector2f.class, 2 * Float.BYTES);
|
||||
SIZEOF_CACHE.put(Vector3f.class, 3 * Float.BYTES);
|
||||
SIZEOF_CACHE.put(Vector4f.class, 4 * Float.BYTES);
|
||||
SIZEOF_CACHE.put(Matrix4f.class, SIZEOF_CACHE.get(Vector4f.class));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,47 +1,39 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.misc;
|
||||
|
||||
import java.nio.LongBuffer;
|
||||
|
||||
import static org.lwjgl.system.MemoryStack.stackGet;
|
||||
|
||||
/**
|
||||
* Wraps the needed sync objects for an in flight frame
|
||||
*
|
||||
* This frame's sync objects must be deleted manually
|
||||
* */
|
||||
public class Frame {
|
||||
import java.nio.LongBuffer;
|
||||
|
||||
private final long imageAvailableSemaphore;
|
||||
private final long renderFinishedSemaphore;
|
||||
private final long fence;
|
||||
/** Wraps the needed sync objects for an in flight frame
|
||||
* This frame's sync objects must be deleted manually */
|
||||
public class Frame
|
||||
{
|
||||
private final long imageAvailableSemaphore;
|
||||
private final long renderFinishedSemaphore;
|
||||
private final long fence;
|
||||
|
||||
public Frame(long imageAvailableSemaphore, long renderFinishedSemaphore, long fence) {
|
||||
this.imageAvailableSemaphore = imageAvailableSemaphore;
|
||||
this.renderFinishedSemaphore = renderFinishedSemaphore;
|
||||
this.fence = fence;
|
||||
}
|
||||
public Frame(long imageAvailableSemaphore, long renderFinishedSemaphore, long fence)
|
||||
{
|
||||
this.imageAvailableSemaphore = imageAvailableSemaphore;
|
||||
this.renderFinishedSemaphore = renderFinishedSemaphore;
|
||||
this.fence = fence;
|
||||
}
|
||||
|
||||
public long imageAvailableSemaphore() {
|
||||
return imageAvailableSemaphore;
|
||||
}
|
||||
public long imageAvailableSemaphore()
|
||||
{ return imageAvailableSemaphore; }
|
||||
|
||||
public LongBuffer pImageAvailableSemaphore() {
|
||||
return stackGet().longs(imageAvailableSemaphore);
|
||||
}
|
||||
public LongBuffer pImageAvailableSemaphore()
|
||||
{ return stackGet().longs(imageAvailableSemaphore); }
|
||||
|
||||
public long renderFinishedSemaphore() {
|
||||
return renderFinishedSemaphore;
|
||||
}
|
||||
public long renderFinishedSemaphore()
|
||||
{ return renderFinishedSemaphore; }
|
||||
|
||||
public LongBuffer pRenderFinishedSemaphore() {
|
||||
return stackGet().longs(renderFinishedSemaphore);
|
||||
}
|
||||
public LongBuffer pRenderFinishedSemaphore()
|
||||
{ return stackGet().longs(renderFinishedSemaphore); }
|
||||
|
||||
public long fence() {
|
||||
return fence;
|
||||
}
|
||||
public long fence()
|
||||
{ return fence; }
|
||||
|
||||
public LongBuffer pFence() {
|
||||
return stackGet().longs(fence);
|
||||
}
|
||||
public LongBuffer pFence()
|
||||
{ return stackGet().longs(fence); }
|
||||
}
|
||||
|
|
|
@ -11,110 +11,93 @@ import org.joml.*;
|
|||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.assimp.*;
|
||||
|
||||
public class VKModelLoader {
|
||||
public class VKModelLoader
|
||||
{
|
||||
public static VKMesh loadModel(File file, int flags)
|
||||
{
|
||||
try (AIScene scene = aiImportFile(file.getAbsolutePath(), flags))
|
||||
{
|
||||
if (scene == null || scene.mRootNode() == null)
|
||||
{ throw new RuntimeException("Could not load model: " + aiGetErrorString()); }
|
||||
VKMesh model = new VKMesh();
|
||||
processNode(scene.mRootNode(), scene, model);
|
||||
return model;
|
||||
}
|
||||
}
|
||||
|
||||
public static VKMesh loadModel(File file, int flags) {
|
||||
private static void processNode(AINode node, AIScene scene, VKMesh model)
|
||||
{
|
||||
if (node.mMeshes() != null)
|
||||
{ processNodeMeshes(scene, node, model); }
|
||||
if (node.mChildren() != null)
|
||||
{
|
||||
PointerBuffer children = node.mChildren();
|
||||
for (int i = 0; i < node.mNumChildren(); i++)
|
||||
{ processNode(AINode.create(children.get(i)), scene, model); }
|
||||
}
|
||||
}
|
||||
|
||||
try(AIScene scene = aiImportFile(file.getAbsolutePath(), flags)) {
|
||||
private static void processNodeMeshes(AIScene scene, AINode node, VKMesh model)
|
||||
{
|
||||
PointerBuffer pMeshes = scene.mMeshes();
|
||||
IntBuffer meshIndices = node.mMeshes();
|
||||
for (int i = 0; i < meshIndices.capacity(); i++)
|
||||
{
|
||||
AIMesh mesh = AIMesh.create(pMeshes.get(meshIndices.get(i)));
|
||||
processMesh(scene, mesh, model);
|
||||
}
|
||||
}
|
||||
|
||||
if(scene == null || scene.mRootNode() == null) {
|
||||
throw new RuntimeException("Could not load model: " + aiGetErrorString());
|
||||
}
|
||||
private static void processMesh(AIScene scene, AIMesh mesh, VKMesh model)
|
||||
{
|
||||
processPositions(mesh, model.positions);
|
||||
processTexCoords(mesh, model.texCoords);
|
||||
processIndices(mesh, model.indices);
|
||||
}
|
||||
|
||||
VKMesh model = new VKMesh();
|
||||
private static void processPositions(AIMesh mesh, List<Vector3fc> positions)
|
||||
{
|
||||
AIVector3D.Buffer vertices = requireNonNull(mesh.mVertices());
|
||||
for (int i = 0; i < vertices.capacity(); i++)
|
||||
{
|
||||
AIVector3D position = vertices.get(i);
|
||||
positions.add(new Vector3f(position.x(), position.y(), position.z()));
|
||||
}
|
||||
}
|
||||
|
||||
processNode(scene.mRootNode(), scene, model);
|
||||
private static void processTexCoords(AIMesh mesh, List<Vector2fc> texCoords)
|
||||
{
|
||||
AIVector3D.Buffer aiTexCoords = requireNonNull(mesh.mTextureCoords(0));
|
||||
for (int i = 0; i < aiTexCoords.capacity(); i++)
|
||||
{
|
||||
final AIVector3D coords = aiTexCoords.get(i);
|
||||
texCoords.add(new Vector2f(coords.x(), coords.y()));
|
||||
}
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
}
|
||||
|
||||
private static void processNode(AINode node, AIScene scene, VKMesh model) {
|
||||
|
||||
if(node.mMeshes() != null) {
|
||||
processNodeMeshes(scene, node, model);
|
||||
}
|
||||
|
||||
if(node.mChildren() != null) {
|
||||
|
||||
PointerBuffer children = node.mChildren();
|
||||
|
||||
for(int i = 0;i < node.mNumChildren();i++) {
|
||||
processNode(AINode.create(children.get(i)), scene, model);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void processNodeMeshes(AIScene scene, AINode node, VKMesh model) {
|
||||
|
||||
PointerBuffer pMeshes = scene.mMeshes();
|
||||
IntBuffer meshIndices = node.mMeshes();
|
||||
|
||||
for(int i = 0;i < meshIndices.capacity();i++) {
|
||||
AIMesh mesh = AIMesh.create(pMeshes.get(meshIndices.get(i)));
|
||||
processMesh(scene, mesh, model);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void processMesh(AIScene scene, AIMesh mesh, VKMesh model) {
|
||||
|
||||
processPositions(mesh, model.positions);
|
||||
processTexCoords(mesh, model.texCoords);
|
||||
|
||||
processIndices(mesh, model.indices);
|
||||
}
|
||||
|
||||
private static void processPositions(AIMesh mesh, List<Vector3fc> positions) {
|
||||
|
||||
AIVector3D.Buffer vertices = requireNonNull(mesh.mVertices());
|
||||
|
||||
for(int i = 0;i < vertices.capacity();i++) {
|
||||
AIVector3D position = vertices.get(i);
|
||||
positions.add(new Vector3f(position.x(), position.y(), position.z()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void processTexCoords(AIMesh mesh, List<Vector2fc> texCoords) {
|
||||
|
||||
AIVector3D.Buffer aiTexCoords = requireNonNull(mesh.mTextureCoords(0));
|
||||
|
||||
for(int i = 0;i < aiTexCoords.capacity();i++) {
|
||||
final AIVector3D coords = aiTexCoords.get(i);
|
||||
texCoords.add(new Vector2f(coords.x(), coords.y()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void processIndices(AIMesh mesh, List<Integer> indices) {
|
||||
|
||||
AIFace.Buffer aiFaces = mesh.mFaces();
|
||||
|
||||
for(int i = 0;i < mesh.mNumFaces();i++) {
|
||||
AIFace face = aiFaces.get(i);
|
||||
IntBuffer pIndices = face.mIndices();
|
||||
for(int j = 0;j < face.mNumIndices();j++) {
|
||||
indices.add(pIndices.get(j));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class VKMesh {
|
||||
|
||||
public final List<Vector3fc> positions;
|
||||
public final List<Vector2fc> texCoords;
|
||||
public final List<Integer> indices;
|
||||
|
||||
public VKMesh() {
|
||||
this.positions = new ArrayList<>();
|
||||
this.texCoords = new ArrayList<>();
|
||||
this.indices = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
private static void processIndices(AIMesh mesh, List<Integer> indices)
|
||||
{
|
||||
AIFace.Buffer aiFaces = mesh.mFaces();
|
||||
for (int i = 0; i < mesh.mNumFaces(); i++)
|
||||
{
|
||||
AIFace face = aiFaces.get(i);
|
||||
IntBuffer pIndices = face.mIndices();
|
||||
for (int j = 0; j < face.mNumIndices(); j++)
|
||||
{ indices.add(pIndices.get(j)); }
|
||||
}
|
||||
}
|
||||
|
||||
public static class VKMesh
|
||||
{
|
||||
public final List<Vector3fc> positions;
|
||||
public final List<Vector2fc> texCoords;
|
||||
public final List<Integer> indices;
|
||||
|
||||
public VKMesh()
|
||||
{
|
||||
this.positions = new ArrayList<>();
|
||||
this.texCoords = new ArrayList<>();
|
||||
this.indices = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,156 +15,118 @@ import com.github.hydos.ginger.engine.vulkan.shaders.VKShaderUtils.SPIRV;
|
|||
|
||||
public class VKPipelineManager
|
||||
{
|
||||
|
||||
public static void createGraphicsPipeline() {
|
||||
|
||||
try(MemoryStack stack = stackPush()) {
|
||||
SPIRV vertShaderSPIRV = VKShaderUtils.compileShaderFile("vulkan/shaders/entity.vert", VKShaderUtils.ShaderType.VERTEX_SHADER);
|
||||
SPIRV fragShaderSPIRV = VKShaderUtils.compileShaderFile("vulkan/shaders/entity.frag", VKShaderUtils.ShaderType.FRAGMENT_SHADER);
|
||||
|
||||
long vertShaderModule = VKShaderManager.createShaderModule(vertShaderSPIRV.bytecode());
|
||||
long fragShaderModule = VKShaderManager.createShaderModule(fragShaderSPIRV.bytecode());
|
||||
|
||||
ByteBuffer entryPoint = stack.UTF8("main");
|
||||
|
||||
VkPipelineShaderStageCreateInfo.Buffer shaderStages = VkPipelineShaderStageCreateInfo.callocStack(2, stack);
|
||||
|
||||
VkPipelineShaderStageCreateInfo vertShaderStageInfo = shaderStages.get(0);
|
||||
|
||||
vertShaderStageInfo.sType(VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO);
|
||||
vertShaderStageInfo.stage(VK_SHADER_STAGE_VERTEX_BIT);
|
||||
vertShaderStageInfo.module(vertShaderModule);
|
||||
vertShaderStageInfo.pName(entryPoint);
|
||||
|
||||
VkPipelineShaderStageCreateInfo fragShaderStageInfo = shaderStages.get(1);
|
||||
|
||||
fragShaderStageInfo.sType(VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO);
|
||||
fragShaderStageInfo.stage(VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
fragShaderStageInfo.module(fragShaderModule);
|
||||
fragShaderStageInfo.pName(entryPoint);
|
||||
|
||||
// VERTEX STAGE
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo vertexInputInfo = VkPipelineVertexInputStateCreateInfo.callocStack(stack);
|
||||
vertexInputInfo.sType(VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO);
|
||||
vertexInputInfo.pVertexBindingDescriptions(Vertex.getBindingDescription());
|
||||
vertexInputInfo.pVertexAttributeDescriptions(Vertex.getAttributeDescriptions());
|
||||
|
||||
// ASSEMBLY STAGE
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo inputAssembly = VkPipelineInputAssemblyStateCreateInfo.callocStack(stack);
|
||||
inputAssembly.sType(VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO);
|
||||
inputAssembly.topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
|
||||
inputAssembly.primitiveRestartEnable(false);
|
||||
|
||||
// VIEWPORT & SCISSOR
|
||||
|
||||
VkViewport.Buffer viewport = VkViewport.callocStack(1, stack);
|
||||
viewport.x(0.0f);
|
||||
viewport.y(0.0f);
|
||||
viewport.width(VulkanExample.VulkanDemoGinger2.swapChainExtent.width());
|
||||
viewport.height(VulkanExample.VulkanDemoGinger2.swapChainExtent.height());
|
||||
viewport.minDepth(0.0f);
|
||||
viewport.maxDepth(1.0f);
|
||||
|
||||
VkRect2D.Buffer scissor = VkRect2D.callocStack(1, stack);
|
||||
scissor.offset(VkOffset2D.callocStack(stack).set(0, 0));
|
||||
scissor.extent(VulkanExample.VulkanDemoGinger2.swapChainExtent);
|
||||
|
||||
VkPipelineViewportStateCreateInfo viewportState = VkPipelineViewportStateCreateInfo.callocStack(stack);
|
||||
viewportState.sType(VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO);
|
||||
viewportState.pViewports(viewport);
|
||||
viewportState.pScissors(scissor);
|
||||
|
||||
// RASTERIZATION STAGE
|
||||
|
||||
VkPipelineRasterizationStateCreateInfo rasterizer = VkPipelineRasterizationStateCreateInfo.callocStack(stack);
|
||||
rasterizer.sType(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO);
|
||||
rasterizer.depthClampEnable(false);
|
||||
rasterizer.rasterizerDiscardEnable(false);
|
||||
rasterizer.polygonMode(VK_POLYGON_MODE_FILL);
|
||||
rasterizer.lineWidth(1.0f);
|
||||
rasterizer.cullMode(VK_CULL_MODE_BACK_BIT);
|
||||
rasterizer.frontFace(VK_FRONT_FACE_COUNTER_CLOCKWISE);
|
||||
rasterizer.depthBiasEnable(false);
|
||||
|
||||
// MULTISAMPLING
|
||||
|
||||
VkPipelineMultisampleStateCreateInfo multisampling = VkPipelineMultisampleStateCreateInfo.callocStack(stack);
|
||||
multisampling.sType(VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO);
|
||||
multisampling.sampleShadingEnable(true);
|
||||
multisampling.minSampleShading(0.2f); // Enable sample shading in the pipeline
|
||||
multisampling.rasterizationSamples(VulkanExample.VulkanDemoGinger2.msaaSamples); // Min fraction for sample shading; closer to one is smoother
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencil = VkPipelineDepthStencilStateCreateInfo.callocStack(stack);
|
||||
depthStencil.sType(VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO);
|
||||
depthStencil.depthTestEnable(true);
|
||||
depthStencil.depthWriteEnable(true);
|
||||
depthStencil.depthCompareOp(VK_COMPARE_OP_LESS);
|
||||
depthStencil.depthBoundsTestEnable(false);
|
||||
depthStencil.minDepthBounds(0.0f);
|
||||
depthStencil.maxDepthBounds(1.0f);
|
||||
depthStencil.stencilTestEnable(false);
|
||||
|
||||
// COLOR BLENDING
|
||||
|
||||
VkPipelineColorBlendAttachmentState.Buffer colorBlendAttachment = VkPipelineColorBlendAttachmentState.callocStack(1, stack);
|
||||
colorBlendAttachment.colorWriteMask(VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT);
|
||||
colorBlendAttachment.blendEnable(false);
|
||||
|
||||
VkPipelineColorBlendStateCreateInfo colorBlending = VkPipelineColorBlendStateCreateInfo.callocStack(stack);
|
||||
colorBlending.sType(VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO);
|
||||
colorBlending.logicOpEnable(false);
|
||||
colorBlending.logicOp(VK_LOGIC_OP_COPY);
|
||||
colorBlending.pAttachments(colorBlendAttachment);
|
||||
colorBlending.blendConstants(stack.floats(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
|
||||
// PIPELINE LAYOUT CREATION
|
||||
|
||||
VkPipelineLayoutCreateInfo pipelineLayoutInfo = VkPipelineLayoutCreateInfo.callocStack(stack);
|
||||
pipelineLayoutInfo.sType(VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO);
|
||||
pipelineLayoutInfo.pSetLayouts(stack.longs(VulkanExample.VulkanDemoGinger2.descriptorSetLayout));
|
||||
|
||||
LongBuffer pPipelineLayout = stack.longs(VK_NULL_HANDLE);
|
||||
|
||||
if(vkCreatePipelineLayout(VulkanExample.VulkanDemoGinger2.device, pipelineLayoutInfo, null, pPipelineLayout) != VK_SUCCESS) {
|
||||
throw new RuntimeException("Failed to create pipeline layout");
|
||||
}
|
||||
|
||||
VulkanExample.VulkanDemoGinger2.pipelineLayout = pPipelineLayout.get(0);
|
||||
|
||||
VkGraphicsPipelineCreateInfo.Buffer pipelineInfo = VkGraphicsPipelineCreateInfo.callocStack(1, stack);
|
||||
pipelineInfo.sType(VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO);
|
||||
pipelineInfo.pStages(shaderStages);
|
||||
pipelineInfo.pVertexInputState(vertexInputInfo);
|
||||
pipelineInfo.pInputAssemblyState(inputAssembly);
|
||||
pipelineInfo.pViewportState(viewportState);
|
||||
pipelineInfo.pRasterizationState(rasterizer);
|
||||
pipelineInfo.pMultisampleState(multisampling);
|
||||
pipelineInfo.pDepthStencilState(depthStencil);
|
||||
pipelineInfo.pColorBlendState(colorBlending);
|
||||
pipelineInfo.layout(VulkanExample.VulkanDemoGinger2.pipelineLayout);
|
||||
pipelineInfo.renderPass(VulkanExample.VulkanDemoGinger2.renderPass);
|
||||
pipelineInfo.subpass(0);
|
||||
pipelineInfo.basePipelineHandle(VK_NULL_HANDLE);
|
||||
pipelineInfo.basePipelineIndex(-1);
|
||||
|
||||
LongBuffer pGraphicsPipeline = stack.mallocLong(1);
|
||||
|
||||
if(vkCreateGraphicsPipelines(VulkanExample.VulkanDemoGinger2.device, VK_NULL_HANDLE, pipelineInfo, null, pGraphicsPipeline) != VK_SUCCESS) {
|
||||
throw new RuntimeException("Failed to create graphics pipeline");
|
||||
}
|
||||
|
||||
VulkanExample.VulkanDemoGinger2.graphicsPipeline = pGraphicsPipeline.get(0);
|
||||
|
||||
// Cleanup
|
||||
|
||||
vkDestroyShaderModule(VulkanExample.VulkanDemoGinger2.device, vertShaderModule, null);
|
||||
vkDestroyShaderModule(VulkanExample.VulkanDemoGinger2.device, fragShaderModule, null);
|
||||
|
||||
vertShaderSPIRV.free();
|
||||
fragShaderSPIRV.free();
|
||||
}
|
||||
}
|
||||
|
||||
public static void createGraphicsPipeline()
|
||||
{
|
||||
try (MemoryStack stack = stackPush())
|
||||
{
|
||||
SPIRV vertShaderSPIRV = VKShaderUtils.compileShaderFile("vulkan/shaders/entity.vert", VKShaderUtils.ShaderType.VERTEX_SHADER);
|
||||
SPIRV fragShaderSPIRV = VKShaderUtils.compileShaderFile("vulkan/shaders/entity.frag", VKShaderUtils.ShaderType.FRAGMENT_SHADER);
|
||||
long vertShaderModule = VKShaderManager.createShaderModule(vertShaderSPIRV.bytecode());
|
||||
long fragShaderModule = VKShaderManager.createShaderModule(fragShaderSPIRV.bytecode());
|
||||
ByteBuffer entryPoint = stack.UTF8("main");
|
||||
VkPipelineShaderStageCreateInfo.Buffer shaderStages = VkPipelineShaderStageCreateInfo.callocStack(2, stack);
|
||||
VkPipelineShaderStageCreateInfo vertShaderStageInfo = shaderStages.get(0);
|
||||
vertShaderStageInfo.sType(VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO);
|
||||
vertShaderStageInfo.stage(VK_SHADER_STAGE_VERTEX_BIT);
|
||||
vertShaderStageInfo.module(vertShaderModule);
|
||||
vertShaderStageInfo.pName(entryPoint);
|
||||
VkPipelineShaderStageCreateInfo fragShaderStageInfo = shaderStages.get(1);
|
||||
fragShaderStageInfo.sType(VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO);
|
||||
fragShaderStageInfo.stage(VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
fragShaderStageInfo.module(fragShaderModule);
|
||||
fragShaderStageInfo.pName(entryPoint);
|
||||
// VERTEX STAGE
|
||||
VkPipelineVertexInputStateCreateInfo vertexInputInfo = VkPipelineVertexInputStateCreateInfo.callocStack(stack);
|
||||
vertexInputInfo.sType(VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO);
|
||||
vertexInputInfo.pVertexBindingDescriptions(Vertex.getBindingDescription());
|
||||
vertexInputInfo.pVertexAttributeDescriptions(Vertex.getAttributeDescriptions());
|
||||
// ASSEMBLY STAGE
|
||||
VkPipelineInputAssemblyStateCreateInfo inputAssembly = VkPipelineInputAssemblyStateCreateInfo.callocStack(stack);
|
||||
inputAssembly.sType(VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO);
|
||||
inputAssembly.topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
|
||||
inputAssembly.primitiveRestartEnable(false);
|
||||
// VIEWPORT & SCISSOR
|
||||
VkViewport.Buffer viewport = VkViewport.callocStack(1, stack);
|
||||
viewport.x(0.0f);
|
||||
viewport.y(0.0f);
|
||||
viewport.width(VulkanExample.VulkanDemoGinger2.swapChainExtent.width());
|
||||
viewport.height(VulkanExample.VulkanDemoGinger2.swapChainExtent.height());
|
||||
viewport.minDepth(0.0f);
|
||||
viewport.maxDepth(1.0f);
|
||||
VkRect2D.Buffer scissor = VkRect2D.callocStack(1, stack);
|
||||
scissor.offset(VkOffset2D.callocStack(stack).set(0, 0));
|
||||
scissor.extent(VulkanExample.VulkanDemoGinger2.swapChainExtent);
|
||||
VkPipelineViewportStateCreateInfo viewportState = VkPipelineViewportStateCreateInfo.callocStack(stack);
|
||||
viewportState.sType(VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO);
|
||||
viewportState.pViewports(viewport);
|
||||
viewportState.pScissors(scissor);
|
||||
// RASTERIZATION STAGE
|
||||
VkPipelineRasterizationStateCreateInfo rasterizer = VkPipelineRasterizationStateCreateInfo.callocStack(stack);
|
||||
rasterizer.sType(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO);
|
||||
rasterizer.depthClampEnable(false);
|
||||
rasterizer.rasterizerDiscardEnable(false);
|
||||
rasterizer.polygonMode(VK_POLYGON_MODE_FILL);
|
||||
rasterizer.lineWidth(1.0f);
|
||||
rasterizer.cullMode(VK_CULL_MODE_BACK_BIT);
|
||||
rasterizer.frontFace(VK_FRONT_FACE_COUNTER_CLOCKWISE);
|
||||
rasterizer.depthBiasEnable(false);
|
||||
// MULTISAMPLING
|
||||
VkPipelineMultisampleStateCreateInfo multisampling = VkPipelineMultisampleStateCreateInfo.callocStack(stack);
|
||||
multisampling.sType(VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO);
|
||||
multisampling.sampleShadingEnable(true);
|
||||
multisampling.minSampleShading(0.2f); // Enable sample shading in the pipeline
|
||||
multisampling.rasterizationSamples(VulkanExample.VulkanDemoGinger2.msaaSamples); // Min fraction for sample shading; closer to one is smoother
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencil = VkPipelineDepthStencilStateCreateInfo.callocStack(stack);
|
||||
depthStencil.sType(VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO);
|
||||
depthStencil.depthTestEnable(true);
|
||||
depthStencil.depthWriteEnable(true);
|
||||
depthStencil.depthCompareOp(VK_COMPARE_OP_LESS);
|
||||
depthStencil.depthBoundsTestEnable(false);
|
||||
depthStencil.minDepthBounds(0.0f);
|
||||
depthStencil.maxDepthBounds(1.0f);
|
||||
depthStencil.stencilTestEnable(false);
|
||||
// COLOR BLENDING
|
||||
VkPipelineColorBlendAttachmentState.Buffer colorBlendAttachment = VkPipelineColorBlendAttachmentState.callocStack(1, stack);
|
||||
colorBlendAttachment.colorWriteMask(VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT);
|
||||
colorBlendAttachment.blendEnable(false);
|
||||
VkPipelineColorBlendStateCreateInfo colorBlending = VkPipelineColorBlendStateCreateInfo.callocStack(stack);
|
||||
colorBlending.sType(VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO);
|
||||
colorBlending.logicOpEnable(false);
|
||||
colorBlending.logicOp(VK_LOGIC_OP_COPY);
|
||||
colorBlending.pAttachments(colorBlendAttachment);
|
||||
colorBlending.blendConstants(stack.floats(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
// PIPELINE LAYOUT CREATION
|
||||
VkPipelineLayoutCreateInfo pipelineLayoutInfo = VkPipelineLayoutCreateInfo.callocStack(stack);
|
||||
pipelineLayoutInfo.sType(VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO);
|
||||
pipelineLayoutInfo.pSetLayouts(stack.longs(VulkanExample.VulkanDemoGinger2.descriptorSetLayout));
|
||||
LongBuffer pPipelineLayout = stack.longs(VK_NULL_HANDLE);
|
||||
if (vkCreatePipelineLayout(VulkanExample.VulkanDemoGinger2.device, pipelineLayoutInfo, null, pPipelineLayout) != VK_SUCCESS)
|
||||
{ throw new RuntimeException("Failed to create pipeline layout"); }
|
||||
VulkanExample.VulkanDemoGinger2.pipelineLayout = pPipelineLayout.get(0);
|
||||
VkGraphicsPipelineCreateInfo.Buffer pipelineInfo = VkGraphicsPipelineCreateInfo.callocStack(1, stack);
|
||||
pipelineInfo.sType(VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO);
|
||||
pipelineInfo.pStages(shaderStages);
|
||||
pipelineInfo.pVertexInputState(vertexInputInfo);
|
||||
pipelineInfo.pInputAssemblyState(inputAssembly);
|
||||
pipelineInfo.pViewportState(viewportState);
|
||||
pipelineInfo.pRasterizationState(rasterizer);
|
||||
pipelineInfo.pMultisampleState(multisampling);
|
||||
pipelineInfo.pDepthStencilState(depthStencil);
|
||||
pipelineInfo.pColorBlendState(colorBlending);
|
||||
pipelineInfo.layout(VulkanExample.VulkanDemoGinger2.pipelineLayout);
|
||||
pipelineInfo.renderPass(VulkanExample.VulkanDemoGinger2.renderPass);
|
||||
pipelineInfo.subpass(0);
|
||||
pipelineInfo.basePipelineHandle(VK_NULL_HANDLE);
|
||||
pipelineInfo.basePipelineIndex(-1);
|
||||
LongBuffer pGraphicsPipeline = stack.mallocLong(1);
|
||||
if (vkCreateGraphicsPipelines(VulkanExample.VulkanDemoGinger2.device, VK_NULL_HANDLE, pipelineInfo, null, pGraphicsPipeline) != VK_SUCCESS)
|
||||
{ throw new RuntimeException("Failed to create graphics pipeline"); }
|
||||
VulkanExample.VulkanDemoGinger2.graphicsPipeline = pGraphicsPipeline.get(0);
|
||||
// Cleanup
|
||||
vkDestroyShaderModule(VulkanExample.VulkanDemoGinger2.device, vertShaderModule, null);
|
||||
vkDestroyShaderModule(VulkanExample.VulkanDemoGinger2.device, fragShaderModule, null);
|
||||
vertShaderSPIRV.free();
|
||||
fragShaderSPIRV.free();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.render.renderers;
|
||||
/**
|
||||
* used to manage all the renderers and shaders to go with them
|
||||
* @author hydos
|
||||
*
|
||||
*/
|
||||
|
||||
/** used to manage all the renderers and shaders to go with them
|
||||
*
|
||||
* @author hydos */
|
||||
public class VKRenderManager
|
||||
{
|
||||
}
|
||||
|
|
|
@ -10,31 +10,22 @@ import org.lwjgl.vulkan.VkShaderModuleCreateInfo;
|
|||
|
||||
import com.github.hydos.ginger.VulkanExample;
|
||||
|
||||
/**
|
||||
* will be used in the future to manage multiple shaders
|
||||
* @author hydos
|
||||
*
|
||||
*/
|
||||
/** will be used in the future to manage multiple shaders
|
||||
*
|
||||
* @author hydos */
|
||||
public class VKShaderManager
|
||||
{
|
||||
public static long createShaderModule(ByteBuffer spirvCode) {
|
||||
|
||||
try(MemoryStack stack = stackPush()) {
|
||||
|
||||
VkShaderModuleCreateInfo createInfo = VkShaderModuleCreateInfo.callocStack(stack);
|
||||
|
||||
createInfo.sType(VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO);
|
||||
createInfo.pCode(spirvCode);
|
||||
|
||||
LongBuffer pShaderModule = stack.mallocLong(1);
|
||||
|
||||
if(vkCreateShaderModule(VulkanExample.VulkanDemoGinger2.device, createInfo, null, pShaderModule) != VK_SUCCESS) {
|
||||
throw new RuntimeException("Failed to create shader module");
|
||||
}
|
||||
|
||||
return pShaderModule.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static long createShaderModule(ByteBuffer spirvCode)
|
||||
{
|
||||
try (MemoryStack stack = stackPush())
|
||||
{
|
||||
VkShaderModuleCreateInfo createInfo = VkShaderModuleCreateInfo.callocStack(stack);
|
||||
createInfo.sType(VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO);
|
||||
createInfo.pCode(spirvCode);
|
||||
LongBuffer pShaderModule = stack.mallocLong(1);
|
||||
if (vkCreateShaderModule(VulkanExample.VulkanDemoGinger2.device, createInfo, null, pShaderModule) != VK_SUCCESS)
|
||||
{ throw new RuntimeException("Failed to create shader module"); }
|
||||
return pShaderModule.get(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,89 +1,80 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.shaders;
|
||||
|
||||
import org.lwjgl.system.NativeResource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static java.lang.ClassLoader.getSystemClassLoader;
|
||||
import static org.lwjgl.system.MemoryUtil.NULL;
|
||||
import static org.lwjgl.util.shaderc.Shaderc.*;
|
||||
|
||||
public class VKShaderUtils {
|
||||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.file.*;
|
||||
|
||||
public static SPIRV compileShaderFile(String shaderFile, ShaderType shaderKind) {
|
||||
return compileShaderAbsoluteFile(getSystemClassLoader().getResource(shaderFile).toExternalForm(), shaderKind);
|
||||
}
|
||||
import org.lwjgl.system.NativeResource;
|
||||
|
||||
public static SPIRV compileShaderAbsoluteFile(String shaderFile, ShaderType shaderKind) {
|
||||
try {
|
||||
String source = new String(Files.readAllBytes(Paths.get(new URI(shaderFile))));
|
||||
return compileShader(shaderFile, source, shaderKind);
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public class VKShaderUtils
|
||||
{
|
||||
public static SPIRV compileShaderFile(String shaderFile, ShaderType shaderKind)
|
||||
{ return compileShaderAbsoluteFile(getSystemClassLoader().getResource(shaderFile).toExternalForm(), shaderKind); }
|
||||
|
||||
public static SPIRV compileShader(String filename, String source, ShaderType shaderKind) {
|
||||
public static SPIRV compileShaderAbsoluteFile(String shaderFile, ShaderType shaderKind)
|
||||
{
|
||||
try
|
||||
{
|
||||
String source = new String(Files.readAllBytes(Paths.get(new URI(shaderFile))));
|
||||
return compileShader(shaderFile, source, shaderKind);
|
||||
}
|
||||
catch (IOException | URISyntaxException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
long compiler = shaderc_compiler_initialize();
|
||||
public static SPIRV compileShader(String filename, String source, ShaderType shaderKind)
|
||||
{
|
||||
long compiler = shaderc_compiler_initialize();
|
||||
if (compiler == NULL)
|
||||
{ throw new RuntimeException("Failed to create shader compiler"); }
|
||||
long result = shaderc_compile_into_spv(compiler, source, shaderKind.kind, filename, "main", NULL);
|
||||
if (result == NULL)
|
||||
{ throw new RuntimeException("Failed to compile shader " + filename + " into SPIR-V"); }
|
||||
if (shaderc_result_get_compilation_status(result) != shaderc_compilation_status_success)
|
||||
{ throw new RuntimeException("Failed to compile shader " + filename + "into SPIR-V:\n " + shaderc_result_get_error_message(result)); }
|
||||
shaderc_compiler_release(compiler);
|
||||
return new SPIRV(result, shaderc_result_get_bytes(result));
|
||||
}
|
||||
|
||||
if(compiler == NULL) {
|
||||
throw new RuntimeException("Failed to create shader compiler");
|
||||
}
|
||||
public enum ShaderType
|
||||
{
|
||||
VERTEX_SHADER(shaderc_glsl_vertex_shader),
|
||||
GEOMETRY_SHADER(shaderc_glsl_geometry_shader),
|
||||
FRAGMENT_SHADER(shaderc_glsl_fragment_shader);
|
||||
|
||||
long result = shaderc_compile_into_spv(compiler, source, shaderKind.kind, filename, "main", NULL);
|
||||
private final int kind;
|
||||
|
||||
if(result == NULL) {
|
||||
throw new RuntimeException("Failed to compile shader " + filename + " into SPIR-V");
|
||||
}
|
||||
ShaderType(int kind)
|
||||
{ this.kind = kind; }
|
||||
}
|
||||
|
||||
if(shaderc_result_get_compilation_status(result) != shaderc_compilation_status_success) {
|
||||
throw new RuntimeException("Failed to compile shader " + filename + "into SPIR-V:\n " + shaderc_result_get_error_message(result));
|
||||
}
|
||||
public static final class SPIRV implements NativeResource
|
||||
{
|
||||
private final long handle;
|
||||
private ByteBuffer bytecode;
|
||||
|
||||
shaderc_compiler_release(compiler);
|
||||
public SPIRV(long handle, ByteBuffer bytecode)
|
||||
{
|
||||
this.handle = handle;
|
||||
this.bytecode = bytecode;
|
||||
}
|
||||
|
||||
return new SPIRV(result, shaderc_result_get_bytes(result));
|
||||
}
|
||||
|
||||
public enum ShaderType {
|
||||
|
||||
VERTEX_SHADER(shaderc_glsl_vertex_shader),
|
||||
GEOMETRY_SHADER(shaderc_glsl_geometry_shader),
|
||||
FRAGMENT_SHADER(shaderc_glsl_fragment_shader);
|
||||
|
||||
private final int kind;
|
||||
|
||||
ShaderType(int kind) {
|
||||
this.kind = kind;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class SPIRV implements NativeResource {
|
||||
|
||||
private final long handle;
|
||||
private ByteBuffer bytecode;
|
||||
|
||||
public SPIRV(long handle, ByteBuffer bytecode) {
|
||||
this.handle = handle;
|
||||
this.bytecode = bytecode;
|
||||
}
|
||||
|
||||
public ByteBuffer bytecode() {
|
||||
return bytecode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void free() {
|
||||
shaderc_result_release(handle);
|
||||
bytecode = null; // Help the GC
|
||||
}
|
||||
}
|
||||
public ByteBuffer bytecode()
|
||||
{ return bytecode; }
|
||||
|
||||
@Override
|
||||
public void free()
|
||||
{
|
||||
shaderc_result_release(handle);
|
||||
bytecode = null; // Help the GC
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,143 +19,107 @@ import com.github.hydos.ginger.engine.vulkan.render.pipelines.VKPipelineManager;
|
|||
|
||||
public class VKSwapchainManager
|
||||
{
|
||||
|
||||
public static void cleanupSwapChain() {
|
||||
public static void cleanupSwapChain()
|
||||
{
|
||||
vkDestroyImageView(VulkanDemoGinger2.device, VulkanDemoGinger2.colorImageView, null);
|
||||
vkDestroyImage(VulkanDemoGinger2.device, VulkanDemoGinger2.colorImage, null);
|
||||
vkFreeMemory(VulkanDemoGinger2.device, VulkanDemoGinger2.colorImageMemory, null);
|
||||
vkDestroyImageView(VulkanDemoGinger2.device, VulkanDemoGinger2.depthImageView, null);
|
||||
vkDestroyImage(VulkanDemoGinger2.device, VulkanDemoGinger2.depthImage, null);
|
||||
vkFreeMemory(VulkanDemoGinger2.device, VulkanDemoGinger2.depthImageMemory, null);
|
||||
VulkanDemoGinger2.uniformBuffers.forEach(ubo -> vkDestroyBuffer(VulkanDemoGinger2.device, ubo, null));
|
||||
VulkanDemoGinger2.uniformBuffersMemory.forEach(uboMemory -> vkFreeMemory(VulkanDemoGinger2.device, uboMemory, null));
|
||||
vkDestroyDescriptorPool(VulkanDemoGinger2.device, VulkanDemoGinger2.descriptorPool, null);
|
||||
VulkanDemoGinger2.swapChainFramebuffers.forEach(framebuffer -> vkDestroyFramebuffer(VulkanDemoGinger2.device, framebuffer, null));
|
||||
vkFreeCommandBuffers(VulkanDemoGinger2.device, VulkanDemoGinger2.commandPool, VulkanDemoGinger2.asPointerBuffer(VulkanDemoGinger2.commandBuffers));
|
||||
vkDestroyPipeline(VulkanDemoGinger2.device, VulkanDemoGinger2.graphicsPipeline, null);
|
||||
vkDestroyPipelineLayout(VulkanDemoGinger2.device, VulkanDemoGinger2.pipelineLayout, null);
|
||||
vkDestroyRenderPass(VulkanDemoGinger2.device, VulkanDemoGinger2.renderPass, null);
|
||||
VulkanDemoGinger2.swapChainImageViews.forEach(imageView -> vkDestroyImageView(VulkanDemoGinger2.device, imageView, null));
|
||||
vkDestroySwapchainKHR(VulkanDemoGinger2.device, VulkanDemoGinger2.swapChain, null);
|
||||
}
|
||||
|
||||
vkDestroyImageView(VulkanDemoGinger2.device, VulkanDemoGinger2.colorImageView, null);
|
||||
vkDestroyImage(VulkanDemoGinger2.device, VulkanDemoGinger2.colorImage, null);
|
||||
vkFreeMemory(VulkanDemoGinger2.device, VulkanDemoGinger2.colorImageMemory, null);
|
||||
public static void recreateSwapChain()
|
||||
{
|
||||
try (MemoryStack stack = stackPush())
|
||||
{
|
||||
IntBuffer width = stack.ints(0);
|
||||
IntBuffer height = stack.ints(0);
|
||||
while (width.get(0) == 0 && height.get(0) == 0)
|
||||
{
|
||||
glfwGetFramebufferSize(Window.getWindow(), width, height);
|
||||
glfwWaitEvents();
|
||||
}
|
||||
}
|
||||
vkDeviceWaitIdle(VulkanDemoGinger2.device);
|
||||
VKSwapchainManager.cleanupSwapChain();
|
||||
createSwapChainObjects();
|
||||
}
|
||||
|
||||
vkDestroyImageView(VulkanDemoGinger2.device, VulkanDemoGinger2.depthImageView, null);
|
||||
vkDestroyImage(VulkanDemoGinger2.device, VulkanDemoGinger2.depthImage, null);
|
||||
vkFreeMemory(VulkanDemoGinger2.device, VulkanDemoGinger2.depthImageMemory, null);
|
||||
public static void createSwapChain()
|
||||
{
|
||||
try (MemoryStack stack = stackPush())
|
||||
{
|
||||
SwapChainSupportDetails swapChainSupport = VulkanDemoGinger2.querySwapChainSupport(VulkanDemoGinger2.physicalDevice, stack);
|
||||
VkSurfaceFormatKHR surfaceFormat = VulkanDemoGinger2.chooseSwapSurfaceFormat(swapChainSupport.formats);
|
||||
int presentMode = VulkanDemoGinger2.chooseSwapPresentMode(swapChainSupport.presentModes);
|
||||
VkExtent2D extent = VulkanDemoGinger2.chooseSwapExtent(swapChainSupport.capabilities);
|
||||
IntBuffer imageCount = stack.ints(swapChainSupport.capabilities.minImageCount() + 1);
|
||||
if (swapChainSupport.capabilities.maxImageCount() > 0 && imageCount.get(0) > swapChainSupport.capabilities.maxImageCount())
|
||||
{ imageCount.put(0, swapChainSupport.capabilities.maxImageCount()); }
|
||||
VkSwapchainCreateInfoKHR createInfo = VkSwapchainCreateInfoKHR.callocStack(stack);
|
||||
createInfo.sType(VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR);
|
||||
createInfo.surface(VulkanDemoGinger2.surface);
|
||||
// Image settings
|
||||
createInfo.minImageCount(imageCount.get(0));
|
||||
createInfo.imageFormat(surfaceFormat.format());
|
||||
createInfo.imageColorSpace(surfaceFormat.colorSpace());
|
||||
createInfo.imageExtent(extent);
|
||||
createInfo.imageArrayLayers(1);
|
||||
createInfo.imageUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
QueueFamilyIndices indices = VulkanDemoGinger2.findQueueFamilies(VulkanDemoGinger2.physicalDevice);
|
||||
if (!indices.graphicsFamily.equals(indices.presentFamily))
|
||||
{
|
||||
createInfo.imageSharingMode(VK_SHARING_MODE_CONCURRENT);
|
||||
createInfo.pQueueFamilyIndices(stack.ints(indices.graphicsFamily, indices.presentFamily));
|
||||
}
|
||||
else
|
||||
{
|
||||
createInfo.imageSharingMode(VK_SHARING_MODE_EXCLUSIVE);
|
||||
}
|
||||
createInfo.preTransform(swapChainSupport.capabilities.currentTransform());
|
||||
createInfo.compositeAlpha(VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR);
|
||||
createInfo.presentMode(presentMode);
|
||||
createInfo.clipped(true);
|
||||
createInfo.oldSwapchain(VK_NULL_HANDLE);
|
||||
LongBuffer pSwapChain = stack.longs(VK_NULL_HANDLE);
|
||||
if (vkCreateSwapchainKHR(VulkanDemoGinger2.device, createInfo, null, pSwapChain) != VK_SUCCESS)
|
||||
{ throw new RuntimeException("Failed to create swap chain"); }
|
||||
VulkanDemoGinger2.swapChain = pSwapChain.get(0);
|
||||
vkGetSwapchainImagesKHR(VulkanDemoGinger2.device, VulkanDemoGinger2.swapChain, imageCount, null);
|
||||
LongBuffer pSwapchainImages = stack.mallocLong(imageCount.get(0));
|
||||
vkGetSwapchainImagesKHR(VulkanDemoGinger2.device, VulkanDemoGinger2.swapChain, imageCount, pSwapchainImages);
|
||||
VulkanDemoGinger2.swapChainImages = new ArrayList<>(imageCount.get(0));
|
||||
for (int i = 0; i < pSwapchainImages.capacity(); i++)
|
||||
{ VulkanDemoGinger2.swapChainImages.add(pSwapchainImages.get(i)); }
|
||||
VulkanDemoGinger2.swapChainImageFormat = surfaceFormat.format();
|
||||
VulkanDemoGinger2.swapChainExtent = VkExtent2D.create().set(extent);
|
||||
}
|
||||
}
|
||||
|
||||
VulkanDemoGinger2.uniformBuffers.forEach(ubo -> vkDestroyBuffer(VulkanDemoGinger2.device, ubo, null));
|
||||
VulkanDemoGinger2.uniformBuffersMemory.forEach(uboMemory -> vkFreeMemory(VulkanDemoGinger2.device, uboMemory, null));
|
||||
|
||||
vkDestroyDescriptorPool(VulkanDemoGinger2.device, VulkanDemoGinger2.descriptorPool, null);
|
||||
|
||||
VulkanDemoGinger2.swapChainFramebuffers.forEach(framebuffer -> vkDestroyFramebuffer(VulkanDemoGinger2.device, framebuffer, null));
|
||||
|
||||
vkFreeCommandBuffers(VulkanDemoGinger2.device, VulkanDemoGinger2.commandPool, VulkanDemoGinger2.asPointerBuffer(VulkanDemoGinger2.commandBuffers));
|
||||
|
||||
vkDestroyPipeline(VulkanDemoGinger2.device, VulkanDemoGinger2.graphicsPipeline, null);
|
||||
|
||||
vkDestroyPipelineLayout(VulkanDemoGinger2.device, VulkanDemoGinger2.pipelineLayout, null);
|
||||
|
||||
vkDestroyRenderPass(VulkanDemoGinger2.device, VulkanDemoGinger2.renderPass, null);
|
||||
|
||||
VulkanDemoGinger2.swapChainImageViews.forEach(imageView -> vkDestroyImageView(VulkanDemoGinger2.device, imageView, null));
|
||||
|
||||
vkDestroySwapchainKHR(VulkanDemoGinger2.device, VulkanDemoGinger2.swapChain, null);
|
||||
}
|
||||
|
||||
public static void recreateSwapChain() {
|
||||
|
||||
try(MemoryStack stack = stackPush()) {
|
||||
|
||||
IntBuffer width = stack.ints(0);
|
||||
IntBuffer height = stack.ints(0);
|
||||
|
||||
while(width.get(0) == 0 && height.get(0) == 0) {
|
||||
glfwGetFramebufferSize(Window.getWindow(), width, height);
|
||||
glfwWaitEvents();
|
||||
}
|
||||
}
|
||||
|
||||
vkDeviceWaitIdle(VulkanDemoGinger2.device);
|
||||
|
||||
VKSwapchainManager.cleanupSwapChain();
|
||||
|
||||
createSwapChainObjects();
|
||||
}
|
||||
|
||||
public static void createSwapChain() {
|
||||
|
||||
try(MemoryStack stack = stackPush()) {
|
||||
|
||||
SwapChainSupportDetails swapChainSupport = VulkanDemoGinger2.querySwapChainSupport(VulkanDemoGinger2.physicalDevice, stack);
|
||||
|
||||
VkSurfaceFormatKHR surfaceFormat = VulkanDemoGinger2.chooseSwapSurfaceFormat(swapChainSupport.formats);
|
||||
int presentMode = VulkanDemoGinger2.chooseSwapPresentMode(swapChainSupport.presentModes);
|
||||
VkExtent2D extent = VulkanDemoGinger2.chooseSwapExtent(swapChainSupport.capabilities);
|
||||
|
||||
IntBuffer imageCount = stack.ints(swapChainSupport.capabilities.minImageCount() + 1);
|
||||
|
||||
if(swapChainSupport.capabilities.maxImageCount() > 0 && imageCount.get(0) > swapChainSupport.capabilities.maxImageCount()) {
|
||||
imageCount.put(0, swapChainSupport.capabilities.maxImageCount());
|
||||
}
|
||||
|
||||
VkSwapchainCreateInfoKHR createInfo = VkSwapchainCreateInfoKHR.callocStack(stack);
|
||||
|
||||
createInfo.sType(VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR);
|
||||
createInfo.surface(VulkanDemoGinger2.surface);
|
||||
|
||||
// Image settings
|
||||
createInfo.minImageCount(imageCount.get(0));
|
||||
createInfo.imageFormat(surfaceFormat.format());
|
||||
createInfo.imageColorSpace(surfaceFormat.colorSpace());
|
||||
createInfo.imageExtent(extent);
|
||||
createInfo.imageArrayLayers(1);
|
||||
createInfo.imageUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
|
||||
QueueFamilyIndices indices = VulkanDemoGinger2.findQueueFamilies(VulkanDemoGinger2.physicalDevice);
|
||||
|
||||
if(!indices.graphicsFamily.equals(indices.presentFamily)) {
|
||||
createInfo.imageSharingMode(VK_SHARING_MODE_CONCURRENT);
|
||||
createInfo.pQueueFamilyIndices(stack.ints(indices.graphicsFamily, indices.presentFamily));
|
||||
} else {
|
||||
createInfo.imageSharingMode(VK_SHARING_MODE_EXCLUSIVE);
|
||||
}
|
||||
|
||||
createInfo.preTransform(swapChainSupport.capabilities.currentTransform());
|
||||
createInfo.compositeAlpha(VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR);
|
||||
createInfo.presentMode(presentMode);
|
||||
createInfo.clipped(true);
|
||||
|
||||
createInfo.oldSwapchain(VK_NULL_HANDLE);
|
||||
|
||||
LongBuffer pSwapChain = stack.longs(VK_NULL_HANDLE);
|
||||
|
||||
if(vkCreateSwapchainKHR(VulkanDemoGinger2.device, createInfo, null, pSwapChain) != VK_SUCCESS) {
|
||||
throw new RuntimeException("Failed to create swap chain");
|
||||
}
|
||||
|
||||
VulkanDemoGinger2.swapChain = pSwapChain.get(0);
|
||||
|
||||
vkGetSwapchainImagesKHR(VulkanDemoGinger2.device, VulkanDemoGinger2.swapChain, imageCount, null);
|
||||
|
||||
LongBuffer pSwapchainImages = stack.mallocLong(imageCount.get(0));
|
||||
|
||||
vkGetSwapchainImagesKHR(VulkanDemoGinger2.device, VulkanDemoGinger2.swapChain, imageCount, pSwapchainImages);
|
||||
|
||||
VulkanDemoGinger2.swapChainImages = new ArrayList<>(imageCount.get(0));
|
||||
|
||||
for(int i = 0;i < pSwapchainImages.capacity();i++) {
|
||||
VulkanDemoGinger2.swapChainImages.add(pSwapchainImages.get(i));
|
||||
}
|
||||
|
||||
VulkanDemoGinger2.swapChainImageFormat = surfaceFormat.format();
|
||||
VulkanDemoGinger2.swapChainExtent = VkExtent2D.create().set(extent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* i tried organising it but if i change the order everything breaks
|
||||
*/
|
||||
public static void createSwapChainObjects() {
|
||||
createSwapChain();
|
||||
VulkanDemoGinger2.createImageViews();
|
||||
VulkanDemoGinger2.createRenderPass();
|
||||
VKPipelineManager.createGraphicsPipeline();
|
||||
VulkanDemoGinger2.createColorResources();
|
||||
VulkanDemoGinger2.createDepthResources();
|
||||
VulkanDemoGinger2.createFramebuffers();
|
||||
VulkanDemoGinger2.createUniformBuffers();
|
||||
VulkanDemoGinger2.createDescriptorPool();
|
||||
VulkanDemoGinger2.createDescriptorSets();
|
||||
VulkanDemoGinger2.createCommandBuffers();
|
||||
}
|
||||
|
||||
/** i tried organising it but if i change the order everything breaks */
|
||||
public static void createSwapChainObjects()
|
||||
{
|
||||
createSwapChain();
|
||||
VulkanDemoGinger2.createImageViews();
|
||||
VulkanDemoGinger2.createRenderPass();
|
||||
VKPipelineManager.createGraphicsPipeline();
|
||||
VulkanDemoGinger2.createColorResources();
|
||||
VulkanDemoGinger2.createDepthResources();
|
||||
VulkanDemoGinger2.createFramebuffers();
|
||||
VulkanDemoGinger2.createUniformBuffers();
|
||||
VulkanDemoGinger2.createDescriptorPool();
|
||||
VulkanDemoGinger2.createDescriptorSets();
|
||||
VulkanDemoGinger2.createCommandBuffers();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package tk.valoeghese.gateways.client.io;
|
||||
|
||||
/**
|
||||
* Author: Valoeghese
|
||||
*/
|
||||
/** Author: Valoeghese */
|
||||
public final class InitialPressHandler implements KeyListener
|
||||
{
|
||||
private boolean activatedPreviously = false;
|
||||
|
|
|
@ -2,9 +2,7 @@ package tk.valoeghese.gateways.client.io;
|
|||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Author: Valoeghese
|
||||
*/
|
||||
/** Author: Valoeghese */
|
||||
public class Input
|
||||
{
|
||||
private static final Map<Keybind, List<KeyCallback>> CALLBACKS = new HashMap<>();
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package tk.valoeghese.gateways.client.io;
|
||||
|
||||
/**
|
||||
* Author: Valoeghese
|
||||
*/
|
||||
/** Author: Valoeghese */
|
||||
public interface KeyCallback
|
||||
{
|
||||
public void onCallback();
|
||||
|
|
|
@ -2,9 +2,7 @@ package tk.valoeghese.gateways.client.io;
|
|||
|
||||
import org.lwjgl.glfw.*;
|
||||
|
||||
/**
|
||||
* Author: Valoeghese
|
||||
*/
|
||||
/** Author: Valoeghese */
|
||||
public class KeyCallbackHandler extends GLFWKeyCallback
|
||||
{
|
||||
private static final KeyCallbackHandler INSTANCE = new KeyCallbackHandler();
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package tk.valoeghese.gateways.client.io;
|
||||
|
||||
/**
|
||||
* Author: Valoeghese
|
||||
*/
|
||||
/** Author: Valoeghese */
|
||||
public interface KeyListener
|
||||
{
|
||||
public void listen(boolean active);
|
||||
|
|
|
@ -2,9 +2,7 @@ package tk.valoeghese.gateways.client.io;
|
|||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
/**
|
||||
* Author: Valoeghese
|
||||
*/
|
||||
/** Author: Valoeghese */
|
||||
public enum Keybind
|
||||
{
|
||||
MOVE_FORWARD(GLFW.GLFW_KEY_W, false), // Move the player forward relative to its facing direction
|
||||
|
@ -15,15 +13,15 @@ public enum Keybind
|
|||
FLY_DOWN(GLFW.GLFW_KEY_LEFT_SHIFT, false), // Move the player downward
|
||||
BREAK(GLFW.GLFW_MOUSE_BUTTON_1, true), // Place a block in front of the player
|
||||
PLACE(GLFW.GLFW_MOUSE_BUTTON_2, true), // Break the block in front of the player
|
||||
SLOT_1(GLFW.GLFW_KEY_1, false), // Select the first item slot in the toolbar
|
||||
SLOT_2(GLFW.GLFW_KEY_2, false), // Select the second item slot in the toolbar
|
||||
SLOT_3(GLFW.GLFW_KEY_3, false), // Select the third item slot in the toolbar
|
||||
SLOT_4(GLFW.GLFW_KEY_4, false), // Select the fourth item slot in the toolbar
|
||||
SLOT_5(GLFW.GLFW_KEY_5, false), // Select the fifth item slot in the toolbar
|
||||
SLOT_6(GLFW.GLFW_KEY_6, false), // Select the sixth item slot in the toolbar
|
||||
SLOT_7(GLFW.GLFW_KEY_7, false), // Select the seventh item slot in the toolbar
|
||||
SLOT_8(GLFW.GLFW_KEY_8, false), // Select the eighth item slot in the toolbar
|
||||
SLOT_9(GLFW.GLFW_KEY_9, false), // Select the ninth item slot in the toolbar
|
||||
SLOT_1(GLFW.GLFW_KEY_1, false), // Select the first item slot in the toolbar
|
||||
SLOT_2(GLFW.GLFW_KEY_2, false), // Select the second item slot in the toolbar
|
||||
SLOT_3(GLFW.GLFW_KEY_3, false), // Select the third item slot in the toolbar
|
||||
SLOT_4(GLFW.GLFW_KEY_4, false), // Select the fourth item slot in the toolbar
|
||||
SLOT_5(GLFW.GLFW_KEY_5, false), // Select the fifth item slot in the toolbar
|
||||
SLOT_6(GLFW.GLFW_KEY_6, false), // Select the sixth item slot in the toolbar
|
||||
SLOT_7(GLFW.GLFW_KEY_7, false), // Select the seventh item slot in the toolbar
|
||||
SLOT_8(GLFW.GLFW_KEY_8, false), // Select the eighth item slot in the toolbar
|
||||
SLOT_9(GLFW.GLFW_KEY_9, false), // Select the ninth item slot in the toolbar
|
||||
SLOT_10(GLFW.GLFW_KEY_0, false), // Select the tenth item slot in the toolbar
|
||||
EXIT(GLFW.GLFW_KEY_ESCAPE, false), // Save and exit the game // (Open the pause menu later)
|
||||
DEBUG(GLFW.GLFW_KEY_F3, false), // Toggle debug text onscreen
|
||||
|
|
|
@ -2,9 +2,7 @@ package tk.valoeghese.gateways.client.io;
|
|||
|
||||
import org.lwjgl.glfw.*;
|
||||
|
||||
/**
|
||||
* Author: Valoeghese
|
||||
*/
|
||||
/** Author: Valoeghese */
|
||||
public class MouseCallbackHandler extends GLFWMouseButtonCallback
|
||||
{
|
||||
private static final MouseCallbackHandler INSTANCE = new MouseCallbackHandler();
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
package tk.valoeghese.sod;
|
||||
|
||||
interface BaseDataSection<E> extends Iterable<E> {
|
||||
/**
|
||||
* @deprecated Should only be used by the parser! Please use the type specific methods instead for writing data.
|
||||
*/
|
||||
interface BaseDataSection<E> extends Iterable<E>
|
||||
{
|
||||
/** @deprecated Should only be used by the parser! Please use the type specific methods instead for writing data. */
|
||||
@Deprecated
|
||||
<T> void writeForParser(T data);
|
||||
}
|
||||
|
|
|
@ -6,62 +6,55 @@ import java.util.*;
|
|||
import tk.valoeghese.sod.exception.SODParseException;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class BinaryData implements Iterable<Map.Entry<String, BaseDataSection>> {
|
||||
public BinaryData() {
|
||||
this.sections = new HashMap<>();
|
||||
}
|
||||
public class BinaryData implements Iterable<Map.Entry<String, BaseDataSection>>
|
||||
{
|
||||
public BinaryData()
|
||||
{ this.sections = new HashMap<>(); }
|
||||
|
||||
private final Map<String, BaseDataSection> sections;
|
||||
|
||||
public DataSection get(String name) {
|
||||
return (DataSection) this.sections.get(name);
|
||||
}
|
||||
public DataSection get(String name)
|
||||
{ return (DataSection) this.sections.get(name); }
|
||||
|
||||
public ByteArrayDataSection getByteArray(String name) {
|
||||
return (ByteArrayDataSection) this.sections.get(name);
|
||||
}
|
||||
public ByteArrayDataSection getByteArray(String name)
|
||||
{ return (ByteArrayDataSection) this.sections.get(name); }
|
||||
|
||||
public ShortArrayDataSection getShortArray(String name) {
|
||||
return (ShortArrayDataSection) this.sections.get(name);
|
||||
}
|
||||
public ShortArrayDataSection getShortArray(String name)
|
||||
{ return (ShortArrayDataSection) this.sections.get(name); }
|
||||
|
||||
public IntArrayDataSection getIntArray(String name) {
|
||||
return (IntArrayDataSection) this.sections.get(name);
|
||||
}
|
||||
public IntArrayDataSection getIntArray(String name)
|
||||
{ return (IntArrayDataSection) this.sections.get(name); }
|
||||
|
||||
public LongArrayDataSection getLongArray(String name) {
|
||||
return (LongArrayDataSection) this.sections.get(name);
|
||||
}
|
||||
public LongArrayDataSection getLongArray(String name)
|
||||
{ return (LongArrayDataSection) this.sections.get(name); }
|
||||
|
||||
public FloatArrayDataSection getFloatArray(String name) {
|
||||
return (FloatArrayDataSection) this.sections.get(name);
|
||||
}
|
||||
public FloatArrayDataSection getFloatArray(String name)
|
||||
{ return (FloatArrayDataSection) this.sections.get(name); }
|
||||
|
||||
public DoubleArrayDataSection getDoubleArray(String name) {
|
||||
return (DoubleArrayDataSection) this.sections.get(name);
|
||||
}
|
||||
public DoubleArrayDataSection getDoubleArray(String name)
|
||||
{ return (DoubleArrayDataSection) this.sections.get(name); }
|
||||
|
||||
public StringArrayDataSection getStringArray(String name) {
|
||||
return (StringArrayDataSection) this.sections.get(name);
|
||||
}
|
||||
public StringArrayDataSection getStringArray(String name)
|
||||
{ return (StringArrayDataSection) this.sections.get(name); }
|
||||
|
||||
public DataSection getOrCreate(String name) {
|
||||
return (DataSection) this.sections.computeIfAbsent(name, k -> new DataSection());
|
||||
}
|
||||
public DataSection getOrCreate(String name)
|
||||
{ return (DataSection) this.sections.computeIfAbsent(name, k -> new DataSection()); }
|
||||
|
||||
public void put(String name, BaseDataSection section) {
|
||||
this.sections.put(name, section);
|
||||
}
|
||||
public void put(String name, BaseDataSection section)
|
||||
{ this.sections.put(name, section); }
|
||||
|
||||
public boolean containsSection(String name) {
|
||||
return this.sections.containsKey(name);
|
||||
}
|
||||
public boolean containsSection(String name)
|
||||
{ return this.sections.containsKey(name); }
|
||||
|
||||
public boolean write(File file) {
|
||||
try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(file))) {
|
||||
public boolean write(File file)
|
||||
{
|
||||
try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(file)))
|
||||
{
|
||||
Parser.write(this, dos);
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
@ -76,11 +69,8 @@ public class BinaryData implements Iterable<Map.Entry<String, BaseDataSection>>
|
|||
try (DataInputStream dis = new DataInputStream(new FileInputStream(file)))
|
||||
{
|
||||
long magic = dis.readLong();
|
||||
|
||||
if (magic != 0xA77D1E) {
|
||||
throw new SODParseException("Not a valid SOD file!");
|
||||
}
|
||||
|
||||
if (magic != 0xA77D1E)
|
||||
{ throw new SODParseException("Not a valid SOD file!"); }
|
||||
return Parser.parse(dis);
|
||||
}
|
||||
catch (IOException e)
|
||||
|
|
|
@ -4,40 +4,38 @@ import java.util.Iterator;
|
|||
|
||||
import it.unimi.dsi.fastutil.bytes.*;
|
||||
|
||||
public class ByteArrayDataSection implements BaseDataSection<Byte> {
|
||||
public ByteArrayDataSection() {
|
||||
this.array = new ByteArrayList();
|
||||
}
|
||||
public class ByteArrayDataSection implements BaseDataSection<Byte>
|
||||
{
|
||||
public ByteArrayDataSection()
|
||||
{ this.array = new ByteArrayList(); }
|
||||
|
||||
private final ByteList array;
|
||||
|
||||
public void writeByte(byte value) {
|
||||
this.array.add(value);
|
||||
}
|
||||
public void writeByte(byte value)
|
||||
{ this.array.add(value); }
|
||||
|
||||
public int size() {
|
||||
return array.size();
|
||||
}
|
||||
public int size()
|
||||
{ return array.size(); }
|
||||
|
||||
/**
|
||||
* @deprecated Should only be used by the parser! Please use the type specific methods instead for writing data.
|
||||
*/
|
||||
/** @deprecated Should only be used by the parser! Please use the type specific methods instead for writing data. */
|
||||
@Deprecated
|
||||
@Override
|
||||
public <T> void writeForParser(T data) throws UnsupportedOperationException {
|
||||
if (data instanceof Byte) {
|
||||
public <T> void writeForParser(T data) throws UnsupportedOperationException
|
||||
{
|
||||
if (data instanceof Byte)
|
||||
{
|
||||
this.writeByte((byte) data);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new UnsupportedOperationException("Invalid data type parameter for this data section");
|
||||
}
|
||||
}
|
||||
|
||||
public byte readByte(int index) {
|
||||
return this.array.getByte(index);
|
||||
}
|
||||
public byte readByte(int index)
|
||||
{ return this.array.getByte(index); }
|
||||
|
||||
@Override
|
||||
public Iterator<Byte> iterator() {
|
||||
return this.array.iterator();
|
||||
}
|
||||
public Iterator<Byte> iterator()
|
||||
{ return this.array.iterator(); }
|
||||
}
|
||||
|
|
|
@ -2,118 +2,91 @@ package tk.valoeghese.sod;
|
|||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Represents a section of SOD data.
|
||||
* @author Valoeghese
|
||||
*/
|
||||
public class DataSection implements BaseDataSection<Object> {
|
||||
public DataSection() {
|
||||
this.data = new ArrayList<>();
|
||||
}
|
||||
/** Represents a section of SOD data.
|
||||
*
|
||||
* @author Valoeghese */
|
||||
public class DataSection implements BaseDataSection<Object>
|
||||
{
|
||||
public DataSection()
|
||||
{ this.data = new ArrayList<>(); }
|
||||
|
||||
private final List<Object> data;
|
||||
private final List<Object> data;
|
||||
|
||||
/**
|
||||
* @deprecated Should only be used by the parser! Please use the type specific methods instead for writing data.
|
||||
*/
|
||||
/** @deprecated Should only be used by the parser! Please use the type specific methods instead for writing data. */
|
||||
@Deprecated
|
||||
@Override
|
||||
public <T> void writeForParser(T data) {
|
||||
this.data.add(data);
|
||||
}
|
||||
public <T> void writeForParser(T data)
|
||||
{ this.data.add(data); }
|
||||
|
||||
public void writeByte(byte data) {
|
||||
this.data.add(data);
|
||||
}
|
||||
public void writeByte(byte data)
|
||||
{ this.data.add(data); }
|
||||
|
||||
public void writeShort(short data) {
|
||||
this.data.add(data);
|
||||
}
|
||||
public void writeShort(short data)
|
||||
{ this.data.add(data); }
|
||||
|
||||
public void writeInt(int data) {
|
||||
this.data.add(data);
|
||||
}
|
||||
public void writeInt(int data)
|
||||
{ this.data.add(data); }
|
||||
|
||||
public void writeLong(long data) {
|
||||
this.data.add(data);
|
||||
}
|
||||
public void writeLong(long data)
|
||||
{ this.data.add(data); }
|
||||
|
||||
public void writeFloat(float data) {
|
||||
this.data.add(data);
|
||||
}
|
||||
public void writeFloat(float data)
|
||||
{ this.data.add(data); }
|
||||
|
||||
public void writeDouble(double data) {
|
||||
this.data.add(data);
|
||||
}
|
||||
public void writeDouble(double data)
|
||||
{ this.data.add(data); }
|
||||
|
||||
public void writeString(String data) {
|
||||
this.data.add(data);
|
||||
}
|
||||
public void writeString(String data)
|
||||
{ this.data.add(data); }
|
||||
|
||||
public void writeBoolean(boolean data) {
|
||||
this.data.add(data ? (byte) 1 : (byte) 0);
|
||||
}
|
||||
|
||||
public <T extends Enum<?>> void writeEnum(T enumValue) {
|
||||
this.data.add(enumValue.ordinal());
|
||||
}
|
||||
public void writeBoolean(boolean data)
|
||||
{ this.data.add(data ? (byte) 1 : (byte) 0); }
|
||||
|
||||
public <T extends Enum<?>> void writeEnumAsString(T enumValue) {
|
||||
this.data.add(enumValue.toString());
|
||||
}
|
||||
public <T extends Enum<?>> void writeEnum(T enumValue)
|
||||
{ this.data.add(enumValue.ordinal()); }
|
||||
|
||||
public int size() {
|
||||
return this.data.size();
|
||||
}
|
||||
public <T extends Enum<?>> void writeEnumAsString(T enumValue)
|
||||
{ this.data.add(enumValue.toString()); }
|
||||
|
||||
public byte readByte(int index) {
|
||||
return (byte) this.data.get(index);
|
||||
}
|
||||
public int size()
|
||||
{ return this.data.size(); }
|
||||
|
||||
public short readShort(int index) {
|
||||
return (short) this.data.get(index);
|
||||
}
|
||||
public byte readByte(int index)
|
||||
{ return (byte) this.data.get(index); }
|
||||
|
||||
public int readInt(int index) {
|
||||
return (int) this.data.get(index);
|
||||
}
|
||||
public short readShort(int index)
|
||||
{ return (short) this.data.get(index); }
|
||||
|
||||
public long readLong(int index) {
|
||||
return (long) this.data.get(index);
|
||||
}
|
||||
public int readInt(int index)
|
||||
{ return (int) this.data.get(index); }
|
||||
|
||||
public float readFloat(int index) {
|
||||
return (float) this.data.get(index);
|
||||
}
|
||||
public long readLong(int index)
|
||||
{ return (long) this.data.get(index); }
|
||||
|
||||
public double readDouble(int index) {
|
||||
return (double) this.data.get(index);
|
||||
}
|
||||
public float readFloat(int index)
|
||||
{ return (float) this.data.get(index); }
|
||||
|
||||
public String readString(int index) {
|
||||
return (String) this.data.get(index);
|
||||
}
|
||||
public double readDouble(int index)
|
||||
{ return (double) this.data.get(index); }
|
||||
|
||||
public boolean readBoolean(int index) {
|
||||
return ((byte) this.data.get(index)) != 0;
|
||||
}
|
||||
public String readString(int index)
|
||||
{ return (String) this.data.get(index); }
|
||||
|
||||
public <T extends Enum<T>> T readEnumString(int index, Class<T> type) {
|
||||
return Enum.valueOf(type, (String) this.data.get(index));
|
||||
}
|
||||
public boolean readBoolean(int index)
|
||||
{ return ((byte) this.data.get(index)) != 0; }
|
||||
|
||||
public <T extends Enum<?>> T readEnum(int index, T[] values) {
|
||||
public <T extends Enum<T>> T readEnumString(int index, Class<T> type)
|
||||
{ return Enum.valueOf(type, (String) this.data.get(index)); }
|
||||
|
||||
public <T extends Enum<?>> T readEnum(int index, T[] values)
|
||||
{
|
||||
Integer i = (Integer) this.data.get(index);
|
||||
|
||||
if (i == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (i == null)
|
||||
{ return null; }
|
||||
return values[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Object> iterator() {
|
||||
return this.data.iterator();
|
||||
}
|
||||
public Iterator<Object> iterator()
|
||||
{ return this.data.iterator(); }
|
||||
}
|
||||
|
|
|
@ -4,40 +4,38 @@ import java.util.Iterator;
|
|||
|
||||
import it.unimi.dsi.fastutil.doubles.*;
|
||||
|
||||
public class DoubleArrayDataSection implements BaseDataSection<Double> {
|
||||
public DoubleArrayDataSection() {
|
||||
this.array = new DoubleArrayList();
|
||||
}
|
||||
public class DoubleArrayDataSection implements BaseDataSection<Double>
|
||||
{
|
||||
public DoubleArrayDataSection()
|
||||
{ this.array = new DoubleArrayList(); }
|
||||
|
||||
private final DoubleList array;
|
||||
|
||||
public void writeDouble(double value) {
|
||||
this.array.add(value);
|
||||
}
|
||||
public void writeDouble(double value)
|
||||
{ this.array.add(value); }
|
||||
|
||||
public int size() {
|
||||
return array.size();
|
||||
}
|
||||
public int size()
|
||||
{ return array.size(); }
|
||||
|
||||
/**
|
||||
* @deprecated Should only be used by the parser! Please use the type specific methods instead for writing data.
|
||||
*/
|
||||
/** @deprecated Should only be used by the parser! Please use the type specific methods instead for writing data. */
|
||||
@Deprecated
|
||||
@Override
|
||||
public <T> void writeForParser(T data) throws UnsupportedOperationException {
|
||||
if (data instanceof Double) {
|
||||
public <T> void writeForParser(T data) throws UnsupportedOperationException
|
||||
{
|
||||
if (data instanceof Double)
|
||||
{
|
||||
this.writeDouble((double) data);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new UnsupportedOperationException("Invalid data type parameter for this data section");
|
||||
}
|
||||
}
|
||||
|
||||
public double readDouble(int index) {
|
||||
return this.array.getDouble(index);
|
||||
}
|
||||
public double readDouble(int index)
|
||||
{ return this.array.getDouble(index); }
|
||||
|
||||
@Override
|
||||
public Iterator<Double> iterator() {
|
||||
return this.array.iterator();
|
||||
}
|
||||
public Iterator<Double> iterator()
|
||||
{ return this.array.iterator(); }
|
||||
}
|
||||
|
|
|
@ -4,40 +4,38 @@ import java.util.Iterator;
|
|||
|
||||
import it.unimi.dsi.fastutil.floats.*;
|
||||
|
||||
public class FloatArrayDataSection implements BaseDataSection<Float> {
|
||||
public FloatArrayDataSection() {
|
||||
this.array = new FloatArrayList();
|
||||
}
|
||||
public class FloatArrayDataSection implements BaseDataSection<Float>
|
||||
{
|
||||
public FloatArrayDataSection()
|
||||
{ this.array = new FloatArrayList(); }
|
||||
|
||||
private final FloatList array;
|
||||
|
||||
public void writeFloat(float value) {
|
||||
this.array.add(value);
|
||||
}
|
||||
public void writeFloat(float value)
|
||||
{ this.array.add(value); }
|
||||
|
||||
public int size() {
|
||||
return array.size();
|
||||
}
|
||||
public int size()
|
||||
{ return array.size(); }
|
||||
|
||||
/**
|
||||
* @deprecated Should only be used by the parser! Please use the type specific methods instead for writing data.
|
||||
*/
|
||||
/** @deprecated Should only be used by the parser! Please use the type specific methods instead for writing data. */
|
||||
@Deprecated
|
||||
@Override
|
||||
public <T> void writeForParser(T data) throws UnsupportedOperationException {
|
||||
if (data instanceof Float) {
|
||||
public <T> void writeForParser(T data) throws UnsupportedOperationException
|
||||
{
|
||||
if (data instanceof Float)
|
||||
{
|
||||
this.writeFloat((float) data);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new UnsupportedOperationException("Invalid data type parameter for this data section");
|
||||
}
|
||||
}
|
||||
|
||||
public float readFloat(int index) {
|
||||
return this.array.getFloat(index);
|
||||
}
|
||||
public float readFloat(int index)
|
||||
{ return this.array.getFloat(index); }
|
||||
|
||||
@Override
|
||||
public Iterator<Float> iterator() {
|
||||
return this.array.iterator();
|
||||
}
|
||||
public Iterator<Float> iterator()
|
||||
{ return this.array.iterator(); }
|
||||
}
|
||||
|
|
|
@ -4,40 +4,38 @@ import java.util.Iterator;
|
|||
|
||||
import it.unimi.dsi.fastutil.ints.*;
|
||||
|
||||
public class IntArrayDataSection implements BaseDataSection<Integer> {
|
||||
public IntArrayDataSection() {
|
||||
this.array = new IntArrayList();
|
||||
}
|
||||
public class IntArrayDataSection implements BaseDataSection<Integer>
|
||||
{
|
||||
public IntArrayDataSection()
|
||||
{ this.array = new IntArrayList(); }
|
||||
|
||||
private final IntList array;
|
||||
|
||||
public void writeInt(int value) {
|
||||
this.array.add(value);
|
||||
}
|
||||
public void writeInt(int value)
|
||||
{ this.array.add(value); }
|
||||
|
||||
public int size() {
|
||||
return array.size();
|
||||
}
|
||||
public int size()
|
||||
{ return array.size(); }
|
||||
|
||||
/**
|
||||
* @deprecated Should only be used by the parser! Please use the type specific methods instead for writing data.
|
||||
*/
|
||||
/** @deprecated Should only be used by the parser! Please use the type specific methods instead for writing data. */
|
||||
@Deprecated
|
||||
@Override
|
||||
public <T> void writeForParser(T data) throws UnsupportedOperationException {
|
||||
if (data instanceof Integer) {
|
||||
public <T> void writeForParser(T data) throws UnsupportedOperationException
|
||||
{
|
||||
if (data instanceof Integer)
|
||||
{
|
||||
this.writeInt((int) data);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new UnsupportedOperationException("Invalid data type parameter for this data section");
|
||||
}
|
||||
}
|
||||
|
||||
public int readInt(int index) {
|
||||
return this.array.getInt(index);
|
||||
}
|
||||
public int readInt(int index)
|
||||
{ return this.array.getInt(index); }
|
||||
|
||||
@Override
|
||||
public Iterator<Integer> iterator() {
|
||||
return this.array.iterator();
|
||||
}
|
||||
public Iterator<Integer> iterator()
|
||||
{ return this.array.iterator(); }
|
||||
}
|
||||
|
|
|
@ -4,40 +4,38 @@ import java.util.Iterator;
|
|||
|
||||
import it.unimi.dsi.fastutil.longs.*;
|
||||
|
||||
public class LongArrayDataSection implements BaseDataSection<Long> {
|
||||
public LongArrayDataSection() {
|
||||
this.array = new LongArrayList();
|
||||
}
|
||||
public class LongArrayDataSection implements BaseDataSection<Long>
|
||||
{
|
||||
public LongArrayDataSection()
|
||||
{ this.array = new LongArrayList(); }
|
||||
|
||||
private final LongList array;
|
||||
|
||||
public void writeLong(long value) {
|
||||
this.array.add(value);
|
||||
}
|
||||
public void writeLong(long value)
|
||||
{ this.array.add(value); }
|
||||
|
||||
public int size() {
|
||||
return array.size();
|
||||
}
|
||||
public int size()
|
||||
{ return array.size(); }
|
||||
|
||||
/**
|
||||
* @deprecated Should only be used by the parser! Please use the type specific methods instead for writing data.
|
||||
*/
|
||||
/** @deprecated Should only be used by the parser! Please use the type specific methods instead for writing data. */
|
||||
@Deprecated
|
||||
@Override
|
||||
public <T> void writeForParser(T data) throws UnsupportedOperationException {
|
||||
if (data instanceof Long) {
|
||||
public <T> void writeForParser(T data) throws UnsupportedOperationException
|
||||
{
|
||||
if (data instanceof Long)
|
||||
{
|
||||
this.writeLong((long) data);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new UnsupportedOperationException("Invalid data type parameter for this data section");
|
||||
}
|
||||
}
|
||||
|
||||
public long readLong(int index) {
|
||||
return this.array.getLong(index);
|
||||
}
|
||||
public long readLong(int index)
|
||||
{ return this.array.getLong(index); }
|
||||
|
||||
@Override
|
||||
public Iterator<Long> iterator() {
|
||||
return this.array.iterator();
|
||||
}
|
||||
public Iterator<Long> iterator()
|
||||
{ return this.array.iterator(); }
|
||||
}
|
||||
|
|
|
@ -5,168 +5,186 @@ import java.util.*;
|
|||
|
||||
import tk.valoeghese.sod.exception.SODParseException;
|
||||
|
||||
final class Parser {
|
||||
@SuppressWarnings({"deprecation", "rawtypes", "unchecked"})
|
||||
static BinaryData parse(DataInputStream input) throws IOException, SODParseException {
|
||||
final class Parser
|
||||
{
|
||||
@SuppressWarnings(
|
||||
{
|
||||
"deprecation", "rawtypes", "unchecked"
|
||||
})
|
||||
static BinaryData parse(DataInputStream input) throws IOException, SODParseException
|
||||
{
|
||||
BinaryData data = new BinaryData();
|
||||
|
||||
DataType dataType;
|
||||
DataType sectionType;
|
||||
dataType = DataType.of(input.readByte());
|
||||
sectionType = dataType;
|
||||
|
||||
BaseDataSection currentSection;
|
||||
int arraySizeCountdown = 0;
|
||||
|
||||
try {
|
||||
try
|
||||
{
|
||||
currentSection = dataType.createSection();
|
||||
if (dataType != DataType.SECTION) {
|
||||
arraySizeCountdown = input.readInt();
|
||||
}
|
||||
} catch (SODParseException e) {
|
||||
if (dataType != DataType.SECTION)
|
||||
{ arraySizeCountdown = input.readInt(); }
|
||||
}
|
||||
catch (SODParseException e)
|
||||
{
|
||||
throw new SODParseException("Data must be segregated into sections!");
|
||||
}
|
||||
|
||||
data.put(input.readUTF(), currentSection);
|
||||
|
||||
while (input.available() > 0) {
|
||||
switch (sectionType) {
|
||||
while (input.available() > 0)
|
||||
{
|
||||
switch (sectionType)
|
||||
{
|
||||
case BYTE_ARRAY_SECTION:
|
||||
while (arraySizeCountdown --> 0) {
|
||||
currentSection.writeForParser(input.readByte());
|
||||
}
|
||||
while (arraySizeCountdown-- > 0)
|
||||
{ currentSection.writeForParser(input.readByte()); }
|
||||
// create new section if available
|
||||
if (input.available() > 0) {
|
||||
try {
|
||||
if (input.available() > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
dataType = DataType.of(input.readByte());
|
||||
sectionType = dataType;
|
||||
currentSection = dataType.createSection();
|
||||
data.put(input.readUTF(), currentSection);
|
||||
// set countdown
|
||||
if (dataType != DataType.SECTION) {
|
||||
arraySizeCountdown = input.readInt();
|
||||
}
|
||||
} catch (SODParseException e) {
|
||||
if (dataType != DataType.SECTION)
|
||||
{ arraySizeCountdown = input.readInt(); }
|
||||
}
|
||||
catch (SODParseException e)
|
||||
{
|
||||
throw new RuntimeException("This error should never be thrown! If this error occurs, the parser is not properly dealing with a most-likely-invalid data type.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SHORT_ARRAY_SECTION:
|
||||
while (arraySizeCountdown --> 0) {
|
||||
currentSection.writeForParser(input.readShort());
|
||||
}
|
||||
while (arraySizeCountdown-- > 0)
|
||||
{ currentSection.writeForParser(input.readShort()); }
|
||||
// create new section if available
|
||||
if (input.available() > 0) {
|
||||
try {
|
||||
if (input.available() > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
dataType = DataType.of(input.readByte());
|
||||
sectionType = dataType;
|
||||
currentSection = dataType.createSection();
|
||||
data.put(input.readUTF(), currentSection);
|
||||
// set countdown
|
||||
if (dataType != DataType.SECTION) {
|
||||
arraySizeCountdown = input.readInt();
|
||||
}
|
||||
} catch (SODParseException e) {
|
||||
if (dataType != DataType.SECTION)
|
||||
{ arraySizeCountdown = input.readInt(); }
|
||||
}
|
||||
catch (SODParseException e)
|
||||
{
|
||||
throw new RuntimeException("This error should never be thrown! If this error occurs, the parser is not properly dealing with a most-likely-invalid data type.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case INT_ARRAY_SECTION:
|
||||
while (arraySizeCountdown --> 0) {
|
||||
currentSection.writeForParser(input.readInt());
|
||||
}
|
||||
while (arraySizeCountdown-- > 0)
|
||||
{ currentSection.writeForParser(input.readInt()); }
|
||||
// create new section if available
|
||||
if (input.available() > 0) {
|
||||
try {
|
||||
if (input.available() > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
dataType = DataType.of(input.readByte());
|
||||
sectionType = dataType;
|
||||
currentSection = dataType.createSection();
|
||||
data.put(input.readUTF(), currentSection);
|
||||
// set countdown
|
||||
if (dataType != DataType.SECTION) {
|
||||
arraySizeCountdown = input.readInt();
|
||||
}
|
||||
} catch (SODParseException e) {
|
||||
if (dataType != DataType.SECTION)
|
||||
{ arraySizeCountdown = input.readInt(); }
|
||||
}
|
||||
catch (SODParseException e)
|
||||
{
|
||||
throw new RuntimeException("This error should never be thrown! If this error occurs, the parser is not properly dealing with a most-likely-invalid data type.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LONG_ARRAY_SECTION:
|
||||
while (arraySizeCountdown --> 0) {
|
||||
currentSection.writeForParser(input.readLong());
|
||||
}
|
||||
while (arraySizeCountdown-- > 0)
|
||||
{ currentSection.writeForParser(input.readLong()); }
|
||||
// create new section if available
|
||||
if (input.available() > 0) {
|
||||
try {
|
||||
if (input.available() > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
dataType = DataType.of(input.readByte());
|
||||
sectionType = dataType;
|
||||
currentSection = dataType.createSection();
|
||||
data.put(input.readUTF(), currentSection);
|
||||
// set countdown
|
||||
if (dataType != DataType.SECTION) {
|
||||
arraySizeCountdown = input.readInt();
|
||||
}
|
||||
} catch (SODParseException e) {
|
||||
if (dataType != DataType.SECTION)
|
||||
{ arraySizeCountdown = input.readInt(); }
|
||||
}
|
||||
catch (SODParseException e)
|
||||
{
|
||||
throw new RuntimeException("This error should never be thrown! If this error occurs, the parser is not properly dealing with a most-likely-invalid data type.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FLOAT_ARRAY_SECTION:
|
||||
while (arraySizeCountdown --> 0) {
|
||||
currentSection.writeForParser(input.readFloat());
|
||||
}
|
||||
while (arraySizeCountdown-- > 0)
|
||||
{ currentSection.writeForParser(input.readFloat()); }
|
||||
// create new section if available
|
||||
if (input.available() > 0) {
|
||||
try {
|
||||
if (input.available() > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
dataType = DataType.of(input.readByte());
|
||||
sectionType = dataType;
|
||||
currentSection = dataType.createSection();
|
||||
data.put(input.readUTF(), currentSection);
|
||||
// set countdown
|
||||
if (dataType != DataType.SECTION) {
|
||||
arraySizeCountdown = input.readInt();
|
||||
}
|
||||
} catch (SODParseException e) {
|
||||
if (dataType != DataType.SECTION)
|
||||
{ arraySizeCountdown = input.readInt(); }
|
||||
}
|
||||
catch (SODParseException e)
|
||||
{
|
||||
throw new RuntimeException("This error should never be thrown! If this error occurs, the parser is not properly dealing with a most-likely-invalid data type.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DOUBLE_ARRAY_SECTION:
|
||||
while (arraySizeCountdown --> 0) {
|
||||
currentSection.writeForParser(input.readDouble());
|
||||
}
|
||||
while (arraySizeCountdown-- > 0)
|
||||
{ currentSection.writeForParser(input.readDouble()); }
|
||||
// create new section if available
|
||||
if (input.available() > 0) {
|
||||
try {
|
||||
if (input.available() > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
dataType = DataType.of(input.readByte());
|
||||
sectionType = dataType;
|
||||
currentSection = dataType.createSection();
|
||||
data.put(input.readUTF(), currentSection);
|
||||
// set countdown
|
||||
if (dataType != DataType.SECTION) {
|
||||
arraySizeCountdown = input.readInt();
|
||||
}
|
||||
} catch (SODParseException e) {
|
||||
if (dataType != DataType.SECTION)
|
||||
{ arraySizeCountdown = input.readInt(); }
|
||||
}
|
||||
catch (SODParseException e)
|
||||
{
|
||||
throw new RuntimeException("This error should never be thrown! If this error occurs, the parser is not properly dealing with a most-likely-invalid data type.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STRING_ARRAY_SECTION:
|
||||
while (arraySizeCountdown --> 0) {
|
||||
currentSection.writeForParser(input.readUTF());
|
||||
}
|
||||
while (arraySizeCountdown-- > 0)
|
||||
{ currentSection.writeForParser(input.readUTF()); }
|
||||
// create new section if available
|
||||
if (input.available() > 0) {
|
||||
try {
|
||||
if (input.available() > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
dataType = DataType.of(input.readByte());
|
||||
sectionType = dataType;
|
||||
currentSection = dataType.createSection();
|
||||
data.put(input.readUTF(), currentSection);
|
||||
// set countdown
|
||||
if (dataType != DataType.SECTION) {
|
||||
arraySizeCountdown = input.readInt();
|
||||
}
|
||||
} catch (SODParseException e) {
|
||||
if (dataType != DataType.SECTION)
|
||||
{ arraySizeCountdown = input.readInt(); }
|
||||
}
|
||||
catch (SODParseException e)
|
||||
{
|
||||
throw new RuntimeException("This error should never be thrown! If this error occurs, the parser is not properly dealing with a most-likely-invalid data type.");
|
||||
}
|
||||
}
|
||||
|
@ -174,8 +192,8 @@ final class Parser {
|
|||
case SECTION:
|
||||
default:
|
||||
dataType = DataType.of(input.readByte());
|
||||
|
||||
switch (dataType) {
|
||||
switch (dataType)
|
||||
{
|
||||
case BYTE:
|
||||
currentSection.writeForParser(input.readByte());
|
||||
break;
|
||||
|
@ -198,14 +216,16 @@ final class Parser {
|
|||
currentSection.writeForParser(input.readUTF());
|
||||
break;
|
||||
default:
|
||||
try {
|
||||
try
|
||||
{
|
||||
currentSection = dataType.createSection();
|
||||
sectionType = dataType;
|
||||
data.put(input.readUTF(), currentSection);
|
||||
if (dataType != DataType.SECTION) {
|
||||
arraySizeCountdown = input.readInt();
|
||||
}
|
||||
} catch (SODParseException e) {
|
||||
if (dataType != DataType.SECTION)
|
||||
{ arraySizeCountdown = input.readInt(); }
|
||||
}
|
||||
catch (SODParseException e)
|
||||
{
|
||||
throw new RuntimeException("This error should never be thrown! If this error occurs, the parser is not properly dealing with a most-likely-invalid data type.");
|
||||
}
|
||||
break;
|
||||
|
@ -213,114 +233,125 @@ final class Parser {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
static void write(BinaryData data, DataOutputStream dos) throws IOException {
|
||||
static void write(BinaryData data, DataOutputStream dos) throws IOException
|
||||
{
|
||||
dos.writeLong(0xA77D1E);
|
||||
|
||||
Iterator<Map.Entry<String, BaseDataSection>> sectionStream = data.iterator();
|
||||
|
||||
while (sectionStream.hasNext()) {
|
||||
while (sectionStream.hasNext())
|
||||
{
|
||||
Map.Entry<String, BaseDataSection> entry = sectionStream.next();
|
||||
BaseDataSection section = entry.getValue();
|
||||
|
||||
if (section instanceof DataSection) {
|
||||
if (section instanceof DataSection)
|
||||
{
|
||||
dos.writeByte(DataType.SECTION.id);
|
||||
dos.writeUTF(entry.getKey());
|
||||
|
||||
Iterator<Object> dataStream = ((DataSection) section).iterator();
|
||||
|
||||
while (dataStream.hasNext()) {
|
||||
while (dataStream.hasNext())
|
||||
{
|
||||
Object o = dataStream.next();
|
||||
|
||||
if (o instanceof Byte) {
|
||||
if (o instanceof Byte)
|
||||
{
|
||||
dos.writeByte(DataType.BYTE.id);
|
||||
dos.writeByte((byte) o);
|
||||
} else if (o instanceof Short) {
|
||||
}
|
||||
else if (o instanceof Short)
|
||||
{
|
||||
dos.writeByte(DataType.SHORT.id);
|
||||
dos.writeShort((short) o);
|
||||
} else if (o instanceof Integer) {
|
||||
}
|
||||
else if (o instanceof Integer)
|
||||
{
|
||||
dos.writeByte(DataType.INT.id);
|
||||
dos.writeInt((int) o);
|
||||
} else if (o instanceof Long) {
|
||||
}
|
||||
else if (o instanceof Long)
|
||||
{
|
||||
dos.writeByte(DataType.LONG.id);
|
||||
dos.writeLong((long) o);
|
||||
} else if (o instanceof Float) {
|
||||
}
|
||||
else if (o instanceof Float)
|
||||
{
|
||||
dos.writeByte(DataType.FLOAT.id);
|
||||
dos.writeFloat((float) o);
|
||||
} else if (o instanceof Double) {
|
||||
}
|
||||
else if (o instanceof Double)
|
||||
{
|
||||
dos.writeByte(DataType.DOUBLE.id);
|
||||
dos.writeDouble((double) o);
|
||||
} else if (o instanceof String) {
|
||||
}
|
||||
else if (o instanceof String)
|
||||
{
|
||||
dos.writeByte(DataType.STRING.id);
|
||||
dos.writeUTF((String) o);
|
||||
}
|
||||
}
|
||||
} else if (section instanceof ByteArrayDataSection) { // byte array
|
||||
}
|
||||
else if (section instanceof ByteArrayDataSection)
|
||||
{ // byte array
|
||||
dos.writeByte(DataType.BYTE_ARRAY_SECTION.id);
|
||||
dos.writeUTF(entry.getKey());
|
||||
dos.writeInt(((ByteArrayDataSection) section).size());
|
||||
|
||||
for (byte b : (ByteArrayDataSection) section) {
|
||||
dos.writeByte(b);
|
||||
}
|
||||
} else if (section instanceof ShortArrayDataSection) { // short array
|
||||
for (byte b : (ByteArrayDataSection) section)
|
||||
{ dos.writeByte(b); }
|
||||
}
|
||||
else if (section instanceof ShortArrayDataSection)
|
||||
{ // short array
|
||||
dos.writeByte(DataType.SHORT_ARRAY_SECTION.id);
|
||||
dos.writeUTF(entry.getKey());
|
||||
dos.writeInt(((ShortArrayDataSection) section).size());
|
||||
|
||||
for (short s : (ShortArrayDataSection) section) {
|
||||
dos.writeShort(s);
|
||||
}
|
||||
} else if (section instanceof IntArrayDataSection) { // int array
|
||||
for (short s : (ShortArrayDataSection) section)
|
||||
{ dos.writeShort(s); }
|
||||
}
|
||||
else if (section instanceof IntArrayDataSection)
|
||||
{ // int array
|
||||
dos.writeByte(DataType.INT_ARRAY_SECTION.id);
|
||||
dos.writeUTF(entry.getKey());
|
||||
dos.writeInt(((IntArrayDataSection) section).size());
|
||||
|
||||
for (int i : (IntArrayDataSection) section) {
|
||||
dos.writeInt(i);
|
||||
}
|
||||
} else if (section instanceof LongArrayDataSection) { // long array
|
||||
for (int i : (IntArrayDataSection) section)
|
||||
{ dos.writeInt(i); }
|
||||
}
|
||||
else if (section instanceof LongArrayDataSection)
|
||||
{ // long array
|
||||
dos.writeByte(DataType.LONG_ARRAY_SECTION.id);
|
||||
dos.writeUTF(entry.getKey());
|
||||
dos.writeInt(((LongArrayDataSection) section).size());
|
||||
|
||||
for (long l : (LongArrayDataSection) section) {
|
||||
dos.writeLong(l);
|
||||
}
|
||||
} else if (section instanceof FloatArrayDataSection) { // float array
|
||||
for (long l : (LongArrayDataSection) section)
|
||||
{ dos.writeLong(l); }
|
||||
}
|
||||
else if (section instanceof FloatArrayDataSection)
|
||||
{ // float array
|
||||
dos.writeByte(DataType.FLOAT_ARRAY_SECTION.id);
|
||||
dos.writeUTF(entry.getKey());
|
||||
dos.writeInt(((FloatArrayDataSection) section).size());
|
||||
|
||||
for (float f: (FloatArrayDataSection) section) {
|
||||
dos.writeFloat(f);
|
||||
}
|
||||
} else if (section instanceof DoubleArrayDataSection) { // double array
|
||||
for (float f : (FloatArrayDataSection) section)
|
||||
{ dos.writeFloat(f); }
|
||||
}
|
||||
else if (section instanceof DoubleArrayDataSection)
|
||||
{ // double array
|
||||
dos.writeByte(DataType.DOUBLE_ARRAY_SECTION.id);
|
||||
dos.writeUTF(entry.getKey());
|
||||
dos.writeInt(((DoubleArrayDataSection) section).size());
|
||||
|
||||
for (double d : (DoubleArrayDataSection) section) {
|
||||
dos.writeDouble(d);
|
||||
}
|
||||
} else if (section instanceof StringArrayDataSection) { // string array
|
||||
for (double d : (DoubleArrayDataSection) section)
|
||||
{ dos.writeDouble(d); }
|
||||
}
|
||||
else if (section instanceof StringArrayDataSection)
|
||||
{ // string array
|
||||
dos.writeByte(DataType.STRING_ARRAY_SECTION.id);
|
||||
dos.writeUTF(entry.getKey());
|
||||
dos.writeInt(((StringArrayDataSection) section).size());
|
||||
|
||||
for (String s : (StringArrayDataSection) section) {
|
||||
dos.writeUTF(s);
|
||||
}
|
||||
for (String s : (StringArrayDataSection) section)
|
||||
{ dos.writeUTF(s); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum DataType {
|
||||
enum DataType
|
||||
{
|
||||
SECTION(0),
|
||||
BYTE(1),
|
||||
SHORT(2),
|
||||
|
@ -337,14 +368,15 @@ enum DataType {
|
|||
DOUBLE_ARRAY_SECTION(13),
|
||||
STRING_ARRAY_SECTION(14);
|
||||
|
||||
private DataType(int id) {
|
||||
this.id = (byte) id;
|
||||
}
|
||||
private DataType(int id)
|
||||
{ this.id = (byte) id; }
|
||||
|
||||
public final byte id;
|
||||
|
||||
public static DataType of(byte id) throws SODParseException {
|
||||
switch (id) {
|
||||
public static DataType of(byte id) throws SODParseException
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case 0:
|
||||
return SECTION;
|
||||
case 1:
|
||||
|
@ -381,8 +413,10 @@ enum DataType {
|
|||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
BaseDataSection createSection() {
|
||||
switch (this) {
|
||||
BaseDataSection createSection()
|
||||
{
|
||||
switch (this)
|
||||
{
|
||||
case SECTION:
|
||||
return new DataSection();
|
||||
case BYTE_ARRAY_SECTION:
|
||||
|
|
|
@ -4,40 +4,38 @@ import java.util.Iterator;
|
|||
|
||||
import it.unimi.dsi.fastutil.shorts.*;
|
||||
|
||||
public class ShortArrayDataSection implements BaseDataSection<Short> {
|
||||
public ShortArrayDataSection() {
|
||||
this.array = new ShortArrayList();
|
||||
}
|
||||
public class ShortArrayDataSection implements BaseDataSection<Short>
|
||||
{
|
||||
public ShortArrayDataSection()
|
||||
{ this.array = new ShortArrayList(); }
|
||||
|
||||
private final ShortList array;
|
||||
|
||||
public void writeShort(short value) {
|
||||
this.array.add(value);
|
||||
}
|
||||
public void writeShort(short value)
|
||||
{ this.array.add(value); }
|
||||
|
||||
public int size() {
|
||||
return array.size();
|
||||
}
|
||||
public int size()
|
||||
{ return array.size(); }
|
||||
|
||||
/**
|
||||
* @deprecated Should only be used by the parser! Please use the type specific methods instead for writing data.
|
||||
*/
|
||||
/** @deprecated Should only be used by the parser! Please use the type specific methods instead for writing data. */
|
||||
@Deprecated
|
||||
@Override
|
||||
public <T> void writeForParser(T data) throws UnsupportedOperationException {
|
||||
if (data instanceof Short) {
|
||||
public <T> void writeForParser(T data) throws UnsupportedOperationException
|
||||
{
|
||||
if (data instanceof Short)
|
||||
{
|
||||
this.writeShort((short) data);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new UnsupportedOperationException("Invalid data type parameter for this data section");
|
||||
}
|
||||
}
|
||||
|
||||
public short readShort(int index) {
|
||||
return this.array.getShort(index);
|
||||
}
|
||||
public short readShort(int index)
|
||||
{ return this.array.getShort(index); }
|
||||
|
||||
@Override
|
||||
public Iterator<Short> iterator() {
|
||||
return this.array.iterator();
|
||||
}
|
||||
public Iterator<Short> iterator()
|
||||
{ return this.array.iterator(); }
|
||||
}
|
||||
|
|
|
@ -2,40 +2,38 @@ package tk.valoeghese.sod;
|
|||
|
||||
import java.util.*;
|
||||
|
||||
public class StringArrayDataSection implements BaseDataSection<String> {
|
||||
public StringArrayDataSection() {
|
||||
this.array = new ArrayList<String>();
|
||||
}
|
||||
public class StringArrayDataSection implements BaseDataSection<String>
|
||||
{
|
||||
public StringArrayDataSection()
|
||||
{ this.array = new ArrayList<String>(); }
|
||||
|
||||
private final List<String> array;
|
||||
|
||||
public void writeString(String value) {
|
||||
this.array.add(value);
|
||||
}
|
||||
public void writeString(String value)
|
||||
{ this.array.add(value); }
|
||||
|
||||
public int size() {
|
||||
return array.size();
|
||||
}
|
||||
public int size()
|
||||
{ return array.size(); }
|
||||
|
||||
/**
|
||||
* @deprecated Should only be used by the parser! Please use the type specific methods instead for writing data.
|
||||
*/
|
||||
/** @deprecated Should only be used by the parser! Please use the type specific methods instead for writing data. */
|
||||
@Deprecated
|
||||
@Override
|
||||
public <T> void writeForParser(T data) throws UnsupportedOperationException {
|
||||
if (data instanceof String) {
|
||||
public <T> void writeForParser(T data) throws UnsupportedOperationException
|
||||
{
|
||||
if (data instanceof String)
|
||||
{
|
||||
this.writeString((String) data);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new UnsupportedOperationException("Invalid data type parameter for this data section");
|
||||
}
|
||||
}
|
||||
|
||||
public String readString(int index) {
|
||||
return this.array.get(index);
|
||||
}
|
||||
public String readString(int index)
|
||||
{ return this.array.get(index); }
|
||||
|
||||
@Override
|
||||
public Iterator<String> iterator() {
|
||||
return this.array.iterator();
|
||||
}
|
||||
public Iterator<String> iterator()
|
||||
{ return this.array.iterator(); }
|
||||
}
|
||||
|
|
|
@ -2,75 +2,60 @@ package tk.valoeghese.sod;
|
|||
|
||||
import java.io.*;
|
||||
|
||||
class TestMain {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
class TestMain
|
||||
{
|
||||
public static void main(String[] args) throws IOException
|
||||
{
|
||||
writeTest();
|
||||
readTest();
|
||||
}
|
||||
|
||||
static void readTest() throws IOException {
|
||||
static void readTest() throws IOException
|
||||
{
|
||||
File f = new File("../test.sod");
|
||||
|
||||
if (!f.createNewFile()) {
|
||||
if (!f.createNewFile())
|
||||
{
|
||||
BinaryData bd = BinaryData.read(f);
|
||||
|
||||
StringArrayDataSection ds0 = bd.getStringArray("StringArray");
|
||||
|
||||
for (String s : ds0) {
|
||||
System.out.println(s);
|
||||
}
|
||||
|
||||
for (String s : ds0)
|
||||
{ System.out.println(s); }
|
||||
DataSection ds1 = bd.get("DS1");
|
||||
|
||||
for (Object i : ds1) {
|
||||
System.out.println(i);
|
||||
}
|
||||
|
||||
for (Object i : ds1)
|
||||
{ System.out.println(i); }
|
||||
DataSection ds2 = bd.get("yeet");
|
||||
|
||||
for (Object i : ds2) {
|
||||
System.out.println(i);
|
||||
}
|
||||
|
||||
for (Object i : ds2)
|
||||
{ System.out.println(i); }
|
||||
ByteArrayDataSection ds3 = bd.getByteArray("ByteArray");
|
||||
|
||||
for (byte i : ds3) {
|
||||
System.out.println(i);
|
||||
}
|
||||
for (byte i : ds3)
|
||||
{ System.out.println(i); }
|
||||
}
|
||||
}
|
||||
|
||||
static void writeTest() throws IOException {
|
||||
static void writeTest() throws IOException
|
||||
{
|
||||
File f = new File("../test.sod");
|
||||
f.createNewFile();
|
||||
BinaryData bd = new BinaryData();
|
||||
|
||||
StringArrayDataSection ds0 = new StringArrayDataSection();
|
||||
ds0.writeString("Once upon a time");
|
||||
ds0.writeString("There was a programmer who went by the username of \"Valoeghese\"");
|
||||
ds0.writeString("One day he updated his data format SOD to have array sections");
|
||||
bd.put("StringArray", ds0);
|
||||
|
||||
DataSection ds1 = bd.getOrCreate("DS1");
|
||||
ds1.writeBoolean(false);
|
||||
ds1.writeDouble(0.666D);
|
||||
ds1.writeLong(69696969);
|
||||
ds1.writeString("yaY33T");
|
||||
|
||||
DataSection ds2 = bd.getOrCreate("yeet");
|
||||
ds2.writeByte((byte) 4);
|
||||
ds2.writeFloat(1.3F);
|
||||
ds2.writeString("e");
|
||||
ds2.writeString("ff");
|
||||
|
||||
ByteArrayDataSection ds3 = new ByteArrayDataSection();
|
||||
ds3.writeByte((byte)0);
|
||||
ds3.writeByte((byte)9);
|
||||
ds3.writeByte((byte)-10);
|
||||
ds3.writeByte((byte) 0);
|
||||
ds3.writeByte((byte) 9);
|
||||
ds3.writeByte((byte) -10);
|
||||
bd.put("ByteArray", ds3);
|
||||
|
||||
bd.write(f);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package tk.valoeghese.sod.exception;
|
||||
|
||||
public class SODParseException extends RuntimeException {
|
||||
public class SODParseException extends RuntimeException
|
||||
{
|
||||
private static final long serialVersionUID = -3337517517501006140L;
|
||||
|
||||
public SODParseException(String message) {
|
||||
super(message);
|
||||
}
|
||||
public SODParseException(String message)
|
||||
{ super(message); }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue