Merge branch 'Multi-Render-API' of

https://github.com/halotroop/Ginger3D.git into Multi-Render-API

Conflicts:
	src/main/java/com/github/hydos/ginger/engine/vulkan/model/VKModelData.java
pull/12/head
Caroline Bell 2020-03-03 20:25:38 -08:00
commit f425980c88
75 changed files with 1127 additions and 1478 deletions

View File

@ -2,6 +2,7 @@ package com.github.halotroop.litecraft;
import org.joml.*;
import com.github.halotroop.litecraft.gingeraddons.opengl.render.renderers.GLBlockRenderer;
import com.github.halotroop.litecraft.save.LitecraftSave;
import com.github.halotroop.litecraft.screens.*;
import com.github.halotroop.litecraft.types.block.Blocks;
@ -12,7 +13,7 @@ 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;
@ -29,7 +30,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;
@ -37,6 +37,7 @@ public class Litecraft extends Game
public int fps, ups, tps;
public Vector4i dbgStats = new Vector4i();
private long frameTimer;
public GLBlockRenderer glBlockRenderer;
public Litecraft()
{
@ -68,10 +69,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()
{
@ -86,32 +85,31 @@ 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(Game game)
{
GameData data = game.data;
GingerUtils.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);
if (data.handleGuis) ((GingerGL)engine).renderOverlays(game);
GingerUtils.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);
if (data.handleGuis) ((GingerGL) engine).renderOverlays(game);
}
@Override
public void update()
{
ups += 1;
}
{ ups += 1; }
private void setupConstants()
{
@ -132,31 +130,32 @@ public class Litecraft extends Game
MouseCallbackHandler.trackWindow(Window.getWindow());
// set up ginger utilities
GingerUtils.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 MasterRenderer(this.camera), INSTANCE);
((GingerGL)engine).setGlobalFont(font);
this.data.entities.add(this.player);
break;
}
case Vulkan:
{
this.engine = new GingerVK();
// 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 MasterRenderer(this.camera), INSTANCE);
((GingerGL) engine).setGlobalFont(font);
glBlockRenderer = new GLBlockRenderer(GingerRegister.getInstance().masterRenderer.getEntityShader(),
GingerRegister.getInstance().masterRenderer.getProjectionMatrix());
this.data.entities.add(this.player);
break;
}
case Vulkan:
{
this.engine = new GingerVK();
// 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);
@ -176,17 +175,14 @@ 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;
// Open the title screen if it's not 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());
if (this.player instanceof PlayerEntity && camera != null)
{
Input.invokeAllListeners();
@ -194,7 +190,7 @@ public class Litecraft extends Game
data.camera.updateMovement();
}
}
// @formatter=off
public static Litecraft getInstance()
{ return INSTANCE; }
@ -207,16 +203,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(glBlockRenderer); }
}

View File

@ -1,8 +1,9 @@
package com.github.halotroop.litecraft.render;
package com.github.halotroop.litecraft.gingeraddons.opengl.render.renderers;
import org.joml.Matrix4f;
import org.lwjgl.opengl.*;
import com.github.halotroop.litecraft.gingeraddons.opengl.utils.GLVoxelLoader;
import com.github.halotroop.litecraft.types.block.BlockInstance;
import com.github.halotroop.litecraft.world.gen.WorldGenConstants;
import com.github.hydos.ginger.engine.common.api.GingerRegister;
@ -12,20 +13,19 @@ import com.github.hydos.ginger.engine.common.math.Maths;
import com.github.hydos.ginger.engine.opengl.render.Renderer;
import com.github.hydos.ginger.engine.opengl.render.models.GLTexturedModel;
import com.github.hydos.ginger.engine.opengl.render.shaders.StaticShader;
import com.github.hydos.ginger.engine.opengl.utils.GLLoader;
public class BlockRenderer extends Renderer implements WorldGenConstants
public class GLBlockRenderer extends Renderer implements WorldGenConstants
{
public StaticShader shader;
public int atlasID;
public BlockRenderer(StaticShader shader, Matrix4f projectionMatrix)
public GLBlockRenderer(StaticShader shader, Matrix4f projectionMatrix)
{
this.shader = shader;
shader.start();
shader.loadProjectionMatrix(projectionMatrix);
shader.stop();
this.atlasID = GLLoader.createBlockAtlas();
this.atlasID = GLVoxelLoader.createBlockAtlas();
}
private void prepBlockInstance(RenderObject entity)
@ -52,12 +52,10 @@ public class BlockRenderer extends Renderer implements WorldGenConstants
}
public void enableWireframe()
{ if (GingerRegister.getInstance().wireframe)
GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE); }
{ if (GingerRegister.getInstance().wireframe) GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE); }
public void disableWireframe()
{ if (GingerRegister.getInstance().wireframe)
GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL); }
{ if (GingerRegister.getInstance().wireframe) GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL); }
public void prepareRender()
{
@ -75,17 +73,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();
}
}

View File

@ -0,0 +1,50 @@
package com.github.halotroop.litecraft.gingeraddons.opengl.utils;
import java.nio.ByteBuffer;
import org.lwjgl.opengl.GL11;
import com.github.halotroop.litecraft.types.block.*;
import com.github.hydos.ginger.engine.opengl.utils.GLLoader;
public class GLVoxelLoader extends GLLoader
{
public static int createBlockAtlas()
{
int width = 16;
int height = 16;
//Prepare the atlas texture and gen it
int atlasId = GL11.glGenTextures();
//Bind it to openGL
GL11.glBindTexture(GL11.GL_TEXTURE_2D, atlasId);
//Apply the settings for the texture
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"))
{
System.out.println(block.texture);
block.updateBlockModelData();
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());
currentX++;
}
}
return atlasId;
}
}

View File

@ -1,51 +0,0 @@
package com.github.halotroop.litecraft.render;
import java.nio.ByteBuffer;
import org.lwjgl.opengl.*;
import com.github.halotroop.litecraft.types.block.*;
import com.github.hydos.ginger.engine.opengl.utils.GLLoader;
public class VoxelLoader extends GLLoader
{
public static int createBlockAtlas()
{
int width = 16;
int height = 16;
//Prepare the atlas texture and gen it
int atlasId = GL40.glGenTextures();
//Bind it to openGL
GL40.glBindTexture(GL40.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) {
//just in case
if(!block.texture.equals("DONTLOAD")) {
System.out.println(block.texture);
block.updateBlockModelData();
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()
);
currentX++;
}
}
return atlasId;
}
}

View File

@ -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()

View File

@ -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

View File

@ -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

View File

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

View File

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

View File

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

View File

@ -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
}

View File

@ -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)
{

View File

@ -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;

View File

@ -5,8 +5,8 @@ import java.util.function.ToIntFunction;
import org.joml.Vector3f;
import com.github.halotroop.litecraft.gingeraddons.opengl.render.renderers.GLBlockRenderer;
import com.github.halotroop.litecraft.logic.SODSerializable;
import com.github.halotroop.litecraft.render.BlockRenderer;
import com.github.halotroop.litecraft.types.block.*;
import com.github.halotroop.litecraft.world.gen.WorldGenConstants;
@ -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)
@ -71,7 +67,7 @@ public class Chunk implements BlockAccess, WorldGenConstants, SODSerializable
return this.blockInstances[index(x, y, z)];
}
public void render(BlockRenderer blockRenderer)
public void render(GLBlockRenderer gLBlockRenderer)
{
if (shouldRender)
{
@ -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();
gLBlockRenderer.prepareRender();
gLBlockRenderer.render(renderedBlocks);
gLBlockRenderer.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) ->
{

View File

@ -8,7 +8,7 @@ import java.util.function.LongConsumer;
import org.joml.Vector3f;
import com.github.halotroop.litecraft.Litecraft;
import com.github.halotroop.litecraft.render.BlockRenderer;
import com.github.halotroop.litecraft.gingeraddons.opengl.render.renderers.GLBlockRenderer;
import com.github.halotroop.litecraft.save.LitecraftSave;
import com.github.halotroop.litecraft.types.block.*;
import com.github.halotroop.litecraft.types.entity.PlayerEntity;
@ -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)
{
@ -175,18 +166,18 @@ public class World implements BlockAccess, WorldGenConstants
public Chunk optimiseChunk(Chunk chunk)
{ return chunk; }
public void render(BlockRenderer blockRenderer)
public void render(GLBlockRenderer gLBlockRenderer)
{
blockRenderer.prepareModel(this.dummy.getModel());
gLBlockRenderer.prepareModel(this.dummy.getModel());
try
{
this.chunks.forEach((pos, c) -> c.render(blockRenderer));
this.chunks.forEach((pos, c) -> c.render(gLBlockRenderer));
}
catch (NullPointerException e)
{
System.out.println("Null chunk - we should look into fixing this");
}
blockRenderer.unbindModel();
gLBlockRenderer.unbindModel();
}
public void unloadAllChunks()
@ -223,7 +214,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) ->
@ -233,7 +223,6 @@ public class World implements BlockAccess, WorldGenConstants
});
// unload unneccesary chunks from chunk array
toRemove.forEach((LongConsumer) this::unloadChunk);
toKeep.forEach(chunk ->
{
if (!chunk.isFullyGenerated())

View File

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

View File

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

View File

@ -8,15 +8,16 @@ import org.lwjgl.glfw.*;
import org.lwjgl.system.MemoryUtil;
import org.lwjgl.vulkan.*;
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.common.obj.ModelLoader;
import com.github.hydos.ginger.engine.vulkan.*;
import com.github.hydos.ginger.engine.vulkan.VKConstants;
import com.github.hydos.ginger.engine.vulkan.api.GingerVK;
import com.github.hydos.ginger.engine.vulkan.model.*;
import com.github.hydos.ginger.engine.vulkan.registers.VKRegister;
import com.github.hydos.ginger.engine.vulkan.render.RenderUtils;
import com.github.hydos.ginger.engine.vulkan.render.renderers.*;
import com.github.hydos.ginger.engine.vulkan.render.renderers.VKMasterRenderer;
import com.github.hydos.ginger.engine.vulkan.render.ubo.*;
import com.github.hydos.ginger.engine.vulkan.shaders.*;
import com.github.hydos.ginger.engine.vulkan.utils.*;
@ -31,18 +32,18 @@ public class VulkanStarter
// Start with the highest precision packed format
int[] depthFormats =
{
VK12.VK_FORMAT_D32_SFLOAT_S8_UINT,
VK12.VK_FORMAT_D32_SFLOAT,
VK12.VK_FORMAT_D24_UNORM_S8_UINT,
VK12.VK_FORMAT_D16_UNORM_S8_UINT,
VK12.VK_FORMAT_D16_UNORM
VK10.VK_FORMAT_D32_SFLOAT_S8_UINT,
VK10.VK_FORMAT_D32_SFLOAT,
VK10.VK_FORMAT_D24_UNORM_S8_UINT,
VK10.VK_FORMAT_D16_UNORM_S8_UINT,
VK10.VK_FORMAT_D16_UNORM
};
VkFormatProperties formatProps = VkFormatProperties.calloc();
for (int format : depthFormats)
{
VK12.vkGetPhysicalDeviceFormatProperties(physicalDevice, format, formatProps);
VK10.vkGetPhysicalDeviceFormatProperties(physicalDevice, format, formatProps);
// Format must support depth stencil attachment for optimal tiling
if ((formatProps.optimalTilingFeatures() & VK12.VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
if ((formatProps.optimalTilingFeatures() & VK10.VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
{
depthFormat.put(0, format);
return true;
@ -61,15 +62,15 @@ public class VulkanStarter
private static long createCommandPool(VkDevice device, int queueNodeIndex)
{
VkCommandPoolCreateInfo cmdPoolInfo = VkCommandPoolCreateInfo.calloc()
.sType(VK12.VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO)
.sType(VK10.VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO)
.queueFamilyIndex(queueNodeIndex)
.flags(VK12.VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
.flags(VK10.VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
LongBuffer pCmdPool = MemoryUtil.memAllocLong(1);
int err = VK12.vkCreateCommandPool(device, cmdPoolInfo, null, pCmdPool);
int err = VK10.vkCreateCommandPool(device, cmdPoolInfo, null, pCmdPool);
long commandPool = pCmdPool.get(0);
cmdPoolInfo.free();
MemoryUtil.memFree(pCmdPool);
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to create command pool: " + VKUtils.translateVulkanResult(err)); }
return commandPool;
}
@ -77,7 +78,7 @@ public class VulkanStarter
private static VkQueue createDeviceQueue(VkDevice device, int queueFamilyIndex)
{
PointerBuffer pQueue = MemoryUtil.memAllocPointer(1);
VK12.vkGetDeviceQueue(device, queueFamilyIndex, 0, pQueue);
VK10.vkGetDeviceQueue(device, queueFamilyIndex, 0, pQueue);
long queue = pQueue.get(0);
MemoryUtil.memFree(pQueue);
return new VkQueue(queue, device);
@ -86,16 +87,16 @@ public class VulkanStarter
private static VkCommandBuffer createCommandBuffer(VkDevice device, long commandPool)
{
VkCommandBufferAllocateInfo cmdBufAllocateInfo = VkCommandBufferAllocateInfo.calloc()
.sType(VK12.VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO)
.sType(VK10.VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO)
.commandPool(commandPool)
.level(VK12.VK_COMMAND_BUFFER_LEVEL_PRIMARY)
.level(VK10.VK_COMMAND_BUFFER_LEVEL_PRIMARY)
.commandBufferCount(1);
PointerBuffer pCommandBuffer = MemoryUtil.memAllocPointer(1);
int err = VK12.vkAllocateCommandBuffers(device, cmdBufAllocateInfo, pCommandBuffer);
int err = VK10.vkAllocateCommandBuffers(device, cmdBufAllocateInfo, pCommandBuffer);
cmdBufAllocateInfo.free();
long commandBuffer = pCommandBuffer.get(0);
MemoryUtil.memFree(pCommandBuffer);
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to allocate command buffer: " + VKUtils.translateVulkanResult(err)); }
return new VkCommandBuffer(commandBuffer, device);
}
@ -117,15 +118,15 @@ public class VulkanStarter
if (commandBuffer == null || commandBuffer.address() == MemoryUtil.NULL)
return;
VkSubmitInfo submitInfo = VkSubmitInfo.calloc()
.sType(VK12.VK_STRUCTURE_TYPE_SUBMIT_INFO);
.sType(VK10.VK_STRUCTURE_TYPE_SUBMIT_INFO);
PointerBuffer pCommandBuffers = MemoryUtil.memAllocPointer(1)
.put(commandBuffer)
.flip();
submitInfo.pCommandBuffers(pCommandBuffers);
int err = VK12.vkQueueSubmit(queue, submitInfo, VK12.VK_NULL_HANDLE);
int err = VK10.vkQueueSubmit(queue, submitInfo, VK10.VK_NULL_HANDLE);
MemoryUtil.memFree(pCommandBuffers);
submitInfo.free();
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to submit command buffer: " + VKUtils.translateVulkanResult(err)); }
}
@ -135,7 +136,7 @@ public class VulkanStarter
VkDescriptorPoolSize.Buffer typeCounts = VkDescriptorPoolSize.calloc(1)
// This example only uses one descriptor type (uniform buffer) and only
// requests one descriptor of this type
.type(VK12.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
.type(VK10.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
.descriptorCount(1);
// For additional types you need to add new entries in the type count list
// E.g. for two combined image samplers :
@ -144,18 +145,18 @@ public class VulkanStarter
// Create the global descriptor pool
// All descriptors used in this example are allocated from this pool
VkDescriptorPoolCreateInfo descriptorPoolInfo = VkDescriptorPoolCreateInfo.calloc()
.sType(VK12.VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO)
.sType(VK10.VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO)
.pPoolSizes(typeCounts)
// Set the max. number of sets that can be requested
// Requesting descriptors beyond maxSets will result in an error
.maxSets(1);
LongBuffer pDescriptorPool = MemoryUtil.memAllocLong(1);
int err = VK12.vkCreateDescriptorPool(device, descriptorPoolInfo, null, pDescriptorPool);
int err = VK10.vkCreateDescriptorPool(device, descriptorPoolInfo, null, pDescriptorPool);
long descriptorPool = pDescriptorPool.get(0);
MemoryUtil.memFree(pDescriptorPool);
descriptorPoolInfo.free();
typeCounts.free();
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to create descriptor pool: " + VKUtils.translateVulkanResult(err)); }
return descriptorPool;
}
@ -165,16 +166,16 @@ public class VulkanStarter
LongBuffer pDescriptorSetLayout = MemoryUtil.memAllocLong(1);
pDescriptorSetLayout.put(0, descriptorSetLayout);
VkDescriptorSetAllocateInfo allocInfo = VkDescriptorSetAllocateInfo.calloc()
.sType(VK12.VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO)
.sType(VK10.VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO)
.descriptorPool(descriptorPool)
.pSetLayouts(pDescriptorSetLayout);
LongBuffer pDescriptorSet = MemoryUtil.memAllocLong(1);
int err = VK12.vkAllocateDescriptorSets(device, allocInfo, pDescriptorSet);
int err = VK10.vkAllocateDescriptorSets(device, allocInfo, pDescriptorSet);
long descriptorSet = pDescriptorSet.get(0);
MemoryUtil.memFree(pDescriptorSet);
allocInfo.free();
MemoryUtil.memFree(pDescriptorSetLayout);
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to create descriptor set: " + VKUtils.translateVulkanResult(err)); }
// Update descriptor sets determining the shader binding points
// For every binding point used in a shader there needs to be one
@ -185,13 +186,13 @@ public class VulkanStarter
.offset(uniformDataVSDescriptor.offset);
// Binding 0 : Uniform buffer
VkWriteDescriptorSet.Buffer writeDescriptorSet = VkWriteDescriptorSet.calloc(1)
.sType(VK12.VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET)
.sType(VK10.VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET)
.dstSet(descriptorSet)
.descriptorCount(1)
.descriptorType(VK12.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
.descriptorType(VK10.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
.pBufferInfo(descriptor)
.dstBinding(0); // Binds this uniform buffer to binding point 0
VK12.vkUpdateDescriptorSets(device, writeDescriptorSet, null);
VK10.vkUpdateDescriptorSets(device, writeDescriptorSet, null);
writeDescriptorSet.free();
descriptor.free();
return descriptorSet;
@ -203,20 +204,20 @@ public class VulkanStarter
// One binding for a UBO used in a vertex shader
VkDescriptorSetLayoutBinding.Buffer layoutBinding = VkDescriptorSetLayoutBinding.calloc(1)
.binding(ShaderType.vertexShader) // <- Binding 0 : Uniform buffer (Vertex shader)
.descriptorType(VK12.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
.descriptorType(VK10.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
.descriptorCount(1)
.stageFlags(VK12.VK_SHADER_STAGE_VERTEX_BIT);
.stageFlags(VK10.VK_SHADER_STAGE_VERTEX_BIT);
// Build a create-info struct to create the descriptor set layout
VkDescriptorSetLayoutCreateInfo descriptorLayout = VkDescriptorSetLayoutCreateInfo.calloc()
.sType(VK12.VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO)
.sType(VK10.VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO)
.pBindings(layoutBinding);
LongBuffer pDescriptorSetLayout = MemoryUtil.memAllocLong(1);
err = VK12.vkCreateDescriptorSetLayout(device, descriptorLayout, null, pDescriptorSetLayout);
err = VK10.vkCreateDescriptorSetLayout(device, descriptorLayout, null, pDescriptorSetLayout);
long descriptorSetLayout = pDescriptorSetLayout.get(0);
MemoryUtil.memFree(pDescriptorSetLayout);
descriptorLayout.free();
layoutBinding.free();
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to create descriptor set layout: " + VKUtils.translateVulkanResult(err)); }
return descriptorSetLayout;
}
@ -250,6 +251,7 @@ public class VulkanStarter
GLFWKeyCallback keyCallback;
GLFW.glfwSetKeyCallback(Window.getWindow(), keyCallback = new GLFWKeyCallback()
{
@Override
public void invoke(long window, int key, int scancode, int action, int mods)
{
if (action != GLFW.GLFW_RELEASE)
@ -261,7 +263,7 @@ public class VulkanStarter
LongBuffer pSurface = MemoryUtil.memAllocLong(1);
int err = GLFWVulkan.glfwCreateWindowSurface(vulkanInstance, Window.getWindow(), null, pSurface);
final long surface = pSurface.get(0);
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to create surface: " + VKUtils.translateVulkanResult(err)); }
// Create static Vulkan resources
final ColorAndDepthFormatAndSpace colorAndDepthFormatAndSpace = VKMasterRenderer.getColorFormatAndSpace(VKRegister.physicalDevice, surface);
@ -285,29 +287,29 @@ public class VulkanStarter
{
// Begin the setup command buffer (the one we will use for swapchain/framebuffer creation)
VkCommandBufferBeginInfo cmdBufInfo = VkCommandBufferBeginInfo.calloc()
.sType(VK12.VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO);
int err = VK12.vkBeginCommandBuffer(setupCommandBuffer, cmdBufInfo);
.sType(VK10.VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO);
int err = VK10.vkBeginCommandBuffer(setupCommandBuffer, cmdBufInfo);
cmdBufInfo.free();
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to begin setup command buffer: " + VKUtils.translateVulkanResult(err)); }
long oldChain = swapchain != null ? swapchain.swapchainHandle : VK12.VK_NULL_HANDLE;
long oldChain = swapchain != null ? swapchain.swapchainHandle : VK10.VK_NULL_HANDLE;
// Create the swapchain (this will also add a memory barrier to initialize the framebuffer images)
swapchain = VKMasterRenderer.createSwapChain(VKRegister.device, VKRegister.physicalDevice, surface, oldChain, setupCommandBuffer,
Window.getWidth(), Window.getHeight(), colorAndDepthFormatAndSpace.colorFormat, colorAndDepthFormatAndSpace.colorSpace);
// Create depth-stencil image
depthStencil = VKMasterRenderer.createDepthStencil(VKRegister.device, memoryProperties, colorAndDepthFormatAndSpace.depthFormat, setupCommandBuffer);
err = VK12.vkEndCommandBuffer(setupCommandBuffer);
if (err != VK12.VK_SUCCESS)
err = VK10.vkEndCommandBuffer(setupCommandBuffer);
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to end setup command buffer: " + VKUtils.translateVulkanResult(err)); }
submitCommandBuffer(VKRegister.queue, setupCommandBuffer);
VK12.vkQueueWaitIdle(VKRegister.queue);
VK10.vkQueueWaitIdle(VKRegister.queue);
if (framebuffers != null)
{ for (int i = 0; i < framebuffers.length; i++)
VK12.vkDestroyFramebuffer(VKRegister.device, framebuffers[i], null); }
VK10.vkDestroyFramebuffer(VKRegister.device, framebuffers[i], null); }
framebuffers = RenderUtils.createFramebuffers(VKRegister.device, swapchain, renderPass, Window.getWidth(), Window.getHeight(), depthStencil);
// Create render command buffers
if (renderCommandBuffers != null)
{ VK12.vkResetCommandPool(VKRegister.device, renderCommandPool, VKUtils.VK_FLAGS_NONE); }
{ VK10.vkResetCommandPool(VKRegister.device, renderCommandPool, VKUtils.VK_FLAGS_NONE); }
renderCommandBuffers = VKUtils.setupRenderCommandBuffer(VKRegister.device, renderCommandPool, framebuffers, renderPass, Window.getWidth(), Window.getHeight(), pipeline, descriptorSet,
vertices.vkVerticiesBuffer);
mustRecreate = false;
@ -317,6 +319,7 @@ public class VulkanStarter
// Handle canvas resize
GLFWFramebufferSizeCallback framebufferSizeCallback = new GLFWFramebufferSizeCallback()
{
@Override
public void invoke(long window, int width, int height)
{
if (width <= 0 || height <= 0)
@ -335,12 +338,12 @@ public class VulkanStarter
LongBuffer pRenderCompleteSemaphore = MemoryUtil.memAllocLong(1);
// Info struct to create a semaphore
VkSemaphoreCreateInfo semaphoreCreateInfo = VkSemaphoreCreateInfo.calloc()
.sType(VK12.VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO);
.sType(VK10.VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO);
// Info struct to submit a command buffer which will wait on the semaphore
IntBuffer pWaitDstStageMask = MemoryUtil.memAllocInt(1);
pWaitDstStageMask.put(0, VK12.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
pWaitDstStageMask.put(0, VK10.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
VkSubmitInfo submitInfo = VkSubmitInfo.calloc()
.sType(VK12.VK_STRUCTURE_TYPE_SUBMIT_INFO)
.sType(VK10.VK_STRUCTURE_TYPE_SUBMIT_INFO)
.waitSemaphoreCount(pImageAcquiredSemaphore.remaining())
.pWaitSemaphores(pImageAcquiredSemaphore)
.pWaitDstStageMask(pWaitDstStageMask)
@ -362,20 +365,18 @@ public class VulkanStarter
Window.update();
if (swapchainRecreator.mustRecreate)
swapchainRecreator.recreate();
err = VK12.vkCreateSemaphore(VKRegister.device, semaphoreCreateInfo, null, pImageAcquiredSemaphore);
if (err != VK12.VK_SUCCESS)
err = VK10.vkCreateSemaphore(VKRegister.device, semaphoreCreateInfo, null, pImageAcquiredSemaphore);
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to create image acquired semaphore: " + VKUtils.translateVulkanResult(err)); }
// Create a semaphore to wait for the render to complete, before presenting
err = VK12.vkCreateSemaphore(VKRegister.device, semaphoreCreateInfo, null, pRenderCompleteSemaphore);
if (err != VK12.VK_SUCCESS)
err = VK10.vkCreateSemaphore(VKRegister.device, semaphoreCreateInfo, null, pRenderCompleteSemaphore);
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to create render complete semaphore: " + VKUtils.translateVulkanResult(err)); }
// Get next image from the swap chain (back/front buffer).
// This will setup the imageAquiredSemaphore to be signalled when the operation is complete
err = KHRSwapchain.vkAcquireNextImageKHR(VKRegister.device, swapchain.swapchainHandle, VKConstants.MAX_UNSIGNED_INT, pImageAcquiredSemaphore.get(0), VK12.VK_NULL_HANDLE, pImageIndex);
err = KHRSwapchain.vkAcquireNextImageKHR(VKRegister.device, swapchain.swapchainHandle, VKConstants.MAX_UNSIGNED_INT, pImageAcquiredSemaphore.get(0), VK10.VK_NULL_HANDLE, pImageIndex);
currentBuffer = pImageIndex.get(0);
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to acquire next swapchain image: " + VKUtils.translateVulkanResult(err)); }
// Select the command buffer for the current framebuffer image/attachment
pCommandBuffers.put(0, renderCommandBuffers[currentBuffer]);
@ -385,22 +386,21 @@ public class VulkanStarter
lastTime = thisTime;
ubo.updateUbo(VKRegister.device, time);
// Submit to the graphics queue
err = VK12.vkQueueSubmit(VKRegister.queue, submitInfo, VK12.VK_NULL_HANDLE);
if (err != VK12.VK_SUCCESS)
err = VK10.vkQueueSubmit(VKRegister.queue, submitInfo, VK10.VK_NULL_HANDLE);
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to submit render queue: " + VKUtils.translateVulkanResult(err)); }
// Present the current buffer to the swap chain
// This will display the image
pSwapchains.put(0, swapchain.swapchainHandle);
err = KHRSwapchain.vkQueuePresentKHR(VKRegister.queue, presentInfo);
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to present the swapchain image: " + VKUtils.translateVulkanResult(err)); }
// Create and submit post present barrier
VK12.vkQueueWaitIdle(VKRegister.queue);
VK10.vkQueueWaitIdle(VKRegister.queue);
// Destroy this semaphore (we will create a new one in the next frame)
VK12.vkDestroySemaphore(VKRegister.device, pImageAcquiredSemaphore.get(0), null);
VK12.vkDestroySemaphore(VKRegister.device, pRenderCompleteSemaphore.get(0), null);
VK10.vkDestroySemaphore(VKRegister.device, pImageAcquiredSemaphore.get(0), null);
VK10.vkDestroySemaphore(VKRegister.device, pRenderCompleteSemaphore.get(0), null);
}
((GingerVK)GingerVK.getInstance()).end(pWaitDstStageMask, pImageAcquiredSemaphore, pRenderCompleteSemaphore, pSwapchains, pCommandBuffers, semaphoreCreateInfo, submitInfo, presentInfo, vulkanInstance, debugCallbackHandle, framebufferSizeCallback, keyCallback);
((GingerVK) GingerEngine.getInstance()).end(pWaitDstStageMask, pImageAcquiredSemaphore, pRenderCompleteSemaphore, pSwapchains, pCommandBuffers, semaphoreCreateInfo, submitInfo, presentInfo, vulkanInstance, debugCallbackHandle, framebufferSizeCallback, keyCallback);
}
}

View File

@ -3,20 +3,18 @@ package com.github.hydos.ginger.engine.common.api;
import com.github.hydos.ginger.engine.common.api.game.Game;
import com.github.hydos.ginger.engine.common.io.Window;
import com.github.hydos.ginger.engine.common.screen.Screen;
import com.github.hydos.ginger.engine.common.util.Timer;
import com.github.hydos.ginger.engine.common.util.Timer.TickListener;
import com.github.hydos.ginger.engine.common.utils.Timer;
import com.github.hydos.ginger.engine.common.utils.Timer.TickListener;
import com.github.hydos.ginger.engine.opengl.api.GingerUtils;
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()
{
@ -27,7 +25,7 @@ public abstract class GingerEngine
if (GingerRegister.getInstance().currentScreen != null) GingerRegister.getInstance().currentScreen.tick();
};
};
public void startGameLoop()
{
while (!Window.closed())

View File

@ -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)
{

View File

@ -17,7 +17,7 @@ public abstract class Game
public abstract void render();
public abstract void renderScene();
public abstract void tick();
public abstract void update();

View File

@ -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;

View File

@ -1,101 +0,0 @@
package com.github.hydos.ginger.engine.common.elements.objects;
import org.joml.Vector3f;
import com.github.halotroop.litecraft.Litecraft;
import com.github.halotroop.litecraft.util.RelativeDirection;
import com.github.halotroop.litecraft.world.gen.WorldGenConstants;
import com.github.hydos.ginger.engine.common.Constants;
import com.github.hydos.ginger.engine.common.api.GingerRegister;
import com.github.hydos.ginger.engine.common.io.Window;
import com.github.hydos.ginger.engine.opengl.render.models.GLTexturedModel;
public class Player extends RenderObject implements WorldGenConstants
{
private boolean isInAir = false;
private double upwardsSpeed;
private boolean noWeight = true; // because the force of gravity on an object's mass is called WEIGHT, not gravity
private int chunkX, chunkY, chunkZ;
public Player(GLTexturedModel model, Vector3f position, float rotX, float rotY, float rotZ, Vector3f scale)
{
super(model, position, rotX, rotY, rotZ, scale);
this.chunkX = (int) position.x >> POS_SHIFT;
this.chunkY = (int) position.y >> POS_SHIFT;
this.chunkZ = (int) position.z >> POS_SHIFT;
}
public void move(RelativeDirection direction)
{
float ry = (float) Math.toRadians(GingerRegister.getInstance().game.data.camera.getYaw());
switch (direction)
{
case FORWARD:
default:
position.z -= Math.cos(ry) * Constants.movementSpeed;
position.x += Math.sin(ry) * Constants.movementSpeed;
break;
case BACKWARD:
position.z += Math.cos(ry) * Constants.movementSpeed;
position.x -= Math.sin(ry) * Constants.movementSpeed;
break;
case LEFT:
ry -= RIGHT_ANGLE;
position.z -= Math.cos(ry) * Constants.movementSpeed;
position.x += Math.sin(ry) * Constants.movementSpeed;
break;
case RIGHT:
ry += RIGHT_ANGLE;
position.z -= Math.cos(ry) * Constants.movementSpeed;
position.x += Math.sin(ry) * Constants.movementSpeed;
break;
case UP:
if (this.noWeight) position.y += Constants.movementSpeed;
else this.jump();
break;
case DOWN:
position.y -= Constants.movementSpeed;
break;
}
}
private static final float RIGHT_ANGLE = (float) (Math.PI / 2f);
private void jump()
{
if (!isInAir)
{
isInAir = true;
this.upwardsSpeed = Constants.jumpPower;
}
}
public int getChunkX()
{ return this.chunkX; }
public int getChunkY()
{ return this.chunkY; }
public int getChunkZ()
{ return this.chunkZ; }
public void updateMovement()
{
super.increasePosition(0, (float) (upwardsSpeed * (Window.getTime())), 0);
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);
this.chunkX = newChunkX;
this.chunkY = newChunkY;
this.chunkZ = newChunkZ;
}
}
}

View File

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

View File

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

View File

@ -1,4 +1,6 @@
package com.github.hydos.ginger.engine.common.info;
public enum RenderAPI
{OpenGL, Vulkan}
{
OpenGL, Vulkan
}

View File

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

View File

@ -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();

View File

@ -13,10 +13,9 @@ 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)
{

View File

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

View File

@ -1,4 +1,4 @@
package com.github.hydos.ginger.engine.common.util;
package com.github.hydos.ginger.engine.common.utils;
import java.util.*;

View File

@ -10,7 +10,7 @@ import com.github.hydos.ginger.engine.common.font.*;
import com.github.hydos.ginger.engine.common.io.Window;
import com.github.hydos.ginger.engine.common.screen.Screen;
import com.github.hydos.ginger.engine.common.tools.MousePicker;
import com.github.hydos.ginger.engine.common.util.Timer;
import com.github.hydos.ginger.engine.common.utils.Timer;
import com.github.hydos.ginger.engine.opengl.postprocessing.*;
import com.github.hydos.ginger.engine.opengl.render.MasterRenderer;
import com.github.hydos.ginger.engine.opengl.utils.GLLoader;
@ -21,6 +21,7 @@ public class GingerGL extends GingerEngine
public FontType globalFont;
public Fbo 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(Game game)
{
getRegistry().masterRenderer.renderGuis(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; }
}

View File

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

View File

@ -6,7 +6,6 @@ import java.util.*;
import org.joml.*;
import org.lwjgl.opengl.*;
import com.github.halotroop.litecraft.render.BlockRenderer;
import com.github.hydos.ginger.engine.common.api.GingerRegister;
import com.github.hydos.ginger.engine.common.cameras.Camera;
import com.github.hydos.ginger.engine.common.elements.GuiTexture;
@ -32,12 +31,11 @@ public class MasterRenderer
// GL11.glCullFace(GL11.GL_BACK);
}
public BlockRenderer blockRenderer;
private StaticShader entityShader;
public ObjectRenderer entityRenderer;
private GuiShader guiShader;
private GuiRenderer guiRenderer;
// private SkyboxRenderer skyboxRenderer;
// private SkyboxRenderer skyboxRenderer;
private NormalMappingRenderer normalRenderer;
private Matrix4f projectionMatrix;
private ShadowMapMasterRenderer shadowMapRenderer;
@ -48,8 +46,7 @@ public class MasterRenderer
{
createProjectionMatrix();
entityShader = new StaticShader();
blockRenderer = new BlockRenderer(entityShader, projectionMatrix);
entityRenderer = new ObjectRenderer(entityShader, projectionMatrix);
entityRenderer = new ObjectRenderer(getEntityShader(), projectionMatrix);
guiShader = new GuiShader();
guiRenderer = new GuiRenderer(guiShader);
normalRenderer = new NormalMappingRenderer(projectionMatrix);
@ -58,7 +55,7 @@ public class MasterRenderer
public void cleanUp()
{
entityShader.cleanUp();
getEntityShader().cleanUp();
guiRenderer.cleanUp();
shadowMapRenderer.cleanUp();
normalRenderer.cleanUp();
@ -130,12 +127,12 @@ public class MasterRenderer
for (RenderObject entity : entities)
{ processEntity(entity); }
entityRenderer.prepare();
entityShader.start();
entityShader.loadSkyColour(Window.getColour());
entityShader.loadLights(lights);
entityShader.loadViewMatrix(camera);
getEntityShader().start();
getEntityShader().loadSkyColour(Window.getColour());
getEntityShader().loadLights(lights);
getEntityShader().loadViewMatrix(camera);
entityRenderer.render(this.entities);
entityShader.stop();
getEntityShader().stop();
this.entities.clear();
}
@ -162,7 +159,7 @@ public class MasterRenderer
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)
@ -172,4 +169,7 @@ public class MasterRenderer
shadowMapRenderer.render(entities, sun);
entities.clear();
}
public StaticShader getEntityShader()
{ return entityShader; }
}

View File

@ -40,7 +40,6 @@ public class GuiRenderer 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);

View File

@ -64,7 +64,6 @@ public class Image
public IntBuffer getComp()
{ return comp; }
public String getLocation() {
return location;
}
public String getLocation()
{ return location; }
}

View File

@ -1,4 +1,3 @@
package com.github.hydos.ginger.engine.opengl.utils;
import java.nio.*;
@ -7,7 +6,6 @@ import java.util.*;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.*;
import com.github.halotroop.litecraft.types.block.*;
import com.github.hydos.ginger.engine.common.io.Window;
import com.github.hydos.ginger.engine.opengl.render.models.RawModel;
import com.github.hydos.ginger.engine.opengl.render.texture.Image;
@ -47,11 +45,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 +103,7 @@ 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();
//Bind it to openGL
GL40.glBindTexture(GL40.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) {
//just in case
if(!block.texture.equals("DONTLOAD")) {
System.out.println(block.texture);
block.updateBlockModelData();
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()
);
currentX++;
}
}
return atlasId;
}
public static int loadTextureDirectly(String path)
{
int textureID = GL11.glGenTextures();

View File

@ -5,6 +5,4 @@ import org.lwjgl.vulkan.VkQueue;
public class VKRenderRegister
{
public static VkQueue renderQueue;//used for queueing up render updates
}

View File

@ -1,18 +1,11 @@
package com.github.hydos.ginger.engine.vulkan.api;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.*;
import org.lwjgl.PointerBuffer;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWFramebufferSizeCallback;
import org.lwjgl.glfw.GLFWKeyCallback;
import org.lwjgl.glfw.*;
import org.lwjgl.system.MemoryUtil;
import org.lwjgl.vulkan.EXTDebugReport;
import org.lwjgl.vulkan.VkInstance;
import org.lwjgl.vulkan.VkPresentInfoKHR;
import org.lwjgl.vulkan.VkSemaphoreCreateInfo;
import org.lwjgl.vulkan.VkSubmitInfo;
import org.lwjgl.vulkan.*;
import com.github.hydos.ginger.engine.common.api.GingerEngine;
import com.github.hydos.ginger.engine.common.api.game.Game;
@ -22,12 +15,10 @@ import com.github.hydos.ginger.engine.common.screen.Screen;
public class GingerVK extends GingerEngine
{
public GingerVK()
{
INSTANCE = this;
}
{ INSTANCE = this; }
public void end(IntBuffer pWaitDstStageMask, LongBuffer pImageAcquiredSemaphore, LongBuffer pRenderCompleteSemaphore, LongBuffer pSwapchains, PointerBuffer pCommandBuffers, VkSemaphoreCreateInfo semaphoreCreateInfo, VkSubmitInfo submitInfo, VkPresentInfoKHR presentInfo, VkInstance vulkanInstance, long debugCallbackHandle, GLFWFramebufferSizeCallback framebufferSizeCallback, GLFWKeyCallback keyCallback)
{
{
MemoryUtil.memFree(pWaitDstStageMask);
MemoryUtil.memFree(pImageAcquiredSemaphore);
MemoryUtil.memFree(pRenderCompleteSemaphore);
@ -60,5 +51,4 @@ public class GingerVK extends GingerEngine
{
// TODO
}
}

View File

@ -4,8 +4,8 @@ import java.nio.IntBuffer;
import org.lwjgl.vulkan.VkPhysicalDeviceMemoryProperties;
public class VKMemory {
public class VKMemory
{
public static boolean getMemoryType(VkPhysicalDeviceMemoryProperties deviceMemoryProperties, int typeBits, int properties, IntBuffer typeIndex)
{
int bits = typeBits;
@ -23,6 +23,4 @@ public class VKMemory {
}
return false;
}
}

View File

@ -13,62 +13,60 @@ import com.github.hydos.ginger.engine.vulkan.utils.VKUtils;
public class VKModelConverter
{
public static VKVertices convertModel(Mesh mesh, VkPhysicalDeviceMemoryProperties deviceMemoryProperties, VkDevice device)
{
ByteBuffer vertexBuffer = memAlloc(mesh.getVertices().length * 4);
FloatBuffer bufferVertices = vertexBuffer.asFloatBuffer();
for(float vertex: mesh.getVertices()) {
bufferVertices.put(vertex);
}
for (float vertex : mesh.getVertices())
{ bufferVertices.put(vertex); }
VkMemoryAllocateInfo memAlloc = VkMemoryAllocateInfo.calloc()
.sType(VK12.VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
.sType(VK10.VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
VkMemoryRequirements memReqs = VkMemoryRequirements.calloc();
int err;
// Generate vertex buffer
// Setup
VkBufferCreateInfo bufInfo = VkBufferCreateInfo.calloc()
.sType(VK12.VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO)
.sType(VK10.VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO)
.size(vertexBuffer.remaining())
.usage(VK12.VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
.usage(VK10.VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
LongBuffer pBuffer = memAllocLong(1);
err = VK12.vkCreateBuffer(device, bufInfo, null, pBuffer);
err = VK10.vkCreateBuffer(device, bufInfo, null, pBuffer);
long verticesBuf = pBuffer.get(0);
memFree(pBuffer);
bufInfo.free();
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to create vertex buffer: " + VKUtils.translateVulkanResult(err)); }
VK12.vkGetBufferMemoryRequirements(device, verticesBuf, memReqs);
VK10.vkGetBufferMemoryRequirements(device, verticesBuf, memReqs);
memAlloc.allocationSize(memReqs.size());
IntBuffer memoryTypeIndex = memAllocInt(1);
VKMemory.getMemoryType(deviceMemoryProperties, memReqs.memoryTypeBits(), VK12.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, memoryTypeIndex);
VKMemory.getMemoryType(deviceMemoryProperties, memReqs.memoryTypeBits(), VK10.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, memoryTypeIndex);
memAlloc.memoryTypeIndex(memoryTypeIndex.get(0));
memFree(memoryTypeIndex);
memReqs.free();
LongBuffer pMemory = memAllocLong(1);
err = VK12.vkAllocateMemory(device, memAlloc, null, pMemory);
err = VK10.vkAllocateMemory(device, memAlloc, null, pMemory);
long verticesMem = pMemory.get(0);
memFree(pMemory);
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to allocate vertex memory: " + VKUtils.translateVulkanResult(err)); }
PointerBuffer pData = memAllocPointer(1);
err = VK12.vkMapMemory(device, verticesMem, 0, vertexBuffer.remaining(), 0, pData);
err = VK10.vkMapMemory(device, verticesMem, 0, vertexBuffer.remaining(), 0, pData);
memAlloc.free();
long data = pData.get(0);
memFree(pData);
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to map vertex memory: " + VKUtils.translateVulkanResult(err)); }
memCopy(memAddress(vertexBuffer), data, vertexBuffer.remaining());
memFree(vertexBuffer);
VK12.vkUnmapMemory(device, verticesMem);
err = VK12.vkBindBufferMemory(device, verticesBuf, verticesMem, 0);
if (err != VK12.VK_SUCCESS)
VK10.vkUnmapMemory(device, verticesMem);
err = VK10.vkBindBufferMemory(device, verticesBuf, verticesMem, 0);
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to bind memory to vertex buffer: " + VKUtils.translateVulkanResult(err)); }
// Binding description
VkVertexInputBindingDescription.Buffer bindingDescriptor = VkVertexInputBindingDescription.calloc(1)
.binding(0) // <- we bind our vertex buffer to point 0
.stride((3 + 3) * 4)
.inputRate(VK12.VK_VERTEX_INPUT_RATE_VERTEX);
.inputRate(VK10.VK_VERTEX_INPUT_RATE_VERTEX);
// Attribute descriptions
// Describes memory layout and shader attribute locations
VkVertexInputAttributeDescription.Buffer attributeDescriptions = VkVertexInputAttributeDescription.calloc(2);
@ -76,17 +74,17 @@ public class VKModelConverter
attributeDescriptions.get(0)
.binding(0) // <- binding point used in the VkVertexInputBindingDescription
.location(0) // <- location in the shader's attribute layout (inside the shader source)
.format(VK12.VK_FORMAT_R32G32B32_SFLOAT)
.format(VK10.VK_FORMAT_R32G32B32_SFLOAT)
.offset(0);
// Location 1 : Color
attributeDescriptions.get(1)
.binding(0) // <- binding point used in the VkVertexInputBindingDescription
.location(1) // <- location in the shader's attribute layout (inside the shader source)
.format(VK12.VK_FORMAT_R32G32B32_SFLOAT)
.format(VK10.VK_FORMAT_R32G32B32_SFLOAT)
.offset(3 * 4);
// Assign to vertex buffer
VkPipelineVertexInputStateCreateInfo vi = VkPipelineVertexInputStateCreateInfo.calloc();
vi.sType(VK12.VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO);
vi.sType(VK10.VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO);
vi.pVertexBindingDescriptions(bindingDescriptor);
vi.pVertexAttributeDescriptions(attributeDescriptions);
VKVertices ret = new VKVertices();
@ -94,5 +92,4 @@ public class VKModelConverter
ret.vkVerticiesBuffer = verticesBuf;
return ret;
}
}

View File

@ -13,62 +13,60 @@ import com.github.hydos.ginger.engine.vulkan.registers.VKRegister;
public class VKModelData
{
public Mesh mesh;
public long vertexBuffer;
public long vertexBufferMemory;
public long indexBuffer;
public long indexBufferMemory;
public void loadModel() {
this.mesh = ModelLoader.getCubeMesh();
createVertexBuffer();
createIndexBuffer();
}
public int findMemoryType(int typeFilter, int properties) {
VkPhysicalDeviceMemoryProperties memProperties = VkPhysicalDeviceMemoryProperties.mallocStack();
VK12.vkGetPhysicalDeviceMemoryProperties(VKRegister.physicalDevice, memProperties);
public void loadModel()
{
this.mesh = ModelLoader.getCubeMesh();
createVertexBuffer();
createIndexBuffer();
}
for(int i = 0;i < memProperties.memoryTypeCount();i++) {
if((typeFilter & (1 << i)) != 0 && (memProperties.memoryTypes(i).propertyFlags() & properties) == properties) {
return i;
}
}
public int findMemoryType(int typeFilter, int properties)
{
VkPhysicalDeviceMemoryProperties memProperties = VkPhysicalDeviceMemoryProperties.mallocStack();
VK10.vkGetPhysicalDeviceMemoryProperties(VKRegister.physicalDevice, memProperties);
for (int i = 0; i < memProperties.memoryTypeCount(); i++)
{
if ((typeFilter & (1 << i)) != 0 && (memProperties.memoryTypes(i).propertyFlags() & properties) == properties)
{ return i; }
}
throw new RuntimeException("Failed to find suitable memory type");
}
throw new RuntimeException("Failed to find suitable memory type");
}
public void createBuffer(long size, int usage, int properties, LongBuffer pBuffer, LongBuffer pBufferMemory) {
public void createBuffer(long size, int usage, int properties, LongBuffer pBuffer, LongBuffer pBufferMemory)
{
try (MemoryStack stack = stackPush())
{
VkBufferCreateInfo bufferInfo = VkBufferCreateInfo.callocStack(stack);
bufferInfo.sType(VK10.VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
bufferInfo.size(size);
bufferInfo.usage(usage);
bufferInfo.sharingMode(VK10.VK_SHARING_MODE_EXCLUSIVE);
if (VK10.vkCreateBuffer(VKRegister.device, bufferInfo, null, pBuffer) != VK10.VK_SUCCESS)
{ throw new RuntimeException("Failed to create vertex buffer"); }
VkMemoryRequirements memRequirements = VkMemoryRequirements.mallocStack(stack);
VK10.vkGetBufferMemoryRequirements(VKRegister.device, pBuffer.get(0), memRequirements);
VkMemoryAllocateInfo allocInfo = VkMemoryAllocateInfo.callocStack(stack);
allocInfo.sType(VK10.VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
allocInfo.allocationSize(memRequirements.size());
allocInfo.memoryTypeIndex(findMemoryType(memRequirements.memoryTypeBits(), properties));
if (VK10.vkAllocateMemory(VKRegister.device, allocInfo, null, pBufferMemory) != VK10.VK_SUCCESS)
{ throw new RuntimeException("Failed to allocate vertex buffer memory"); }
VK10.vkBindBufferMemory(VKRegister.device, pBuffer.get(0), pBufferMemory.get(0), 0);
}
}
try(MemoryStack stack = stackPush()) {
VkBufferCreateInfo bufferInfo = VkBufferCreateInfo.callocStack(stack);
bufferInfo.sType(VK12.VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
bufferInfo.size(size);
bufferInfo.usage(usage);
bufferInfo.sharingMode(VK12.VK_SHARING_MODE_EXCLUSIVE);
if(VK12.vkCreateBuffer(VKRegister.device, bufferInfo, null, pBuffer) != VK12.VK_SUCCESS) {
throw new RuntimeException("Failed to create vertex buffer");
}
VkMemoryRequirements memRequirements = VkMemoryRequirements.mallocStack(stack);
VK12.vkGetBufferMemoryRequirements(VKRegister.device, pBuffer.get(0), memRequirements);
VkMemoryAllocateInfo allocInfo = VkMemoryAllocateInfo.callocStack(stack);
allocInfo.sType(VK12.VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
allocInfo.allocationSize(memRequirements.size());
allocInfo.memoryTypeIndex(findMemoryType(memRequirements.memoryTypeBits(), properties));
if(VK12.vkAllocateMemory(VKRegister.device, allocInfo, null, pBufferMemory) != VK12.VK_SUCCESS) {
throw new RuntimeException("Failed to allocate vertex buffer memory");
}
VK12.vkBindBufferMemory(VKRegister.device, pBuffer.get(0), pBufferMemory.get(0), 0);
}
}
private void memcpyIndices(ByteBuffer buffer, int[] indices)
{
for (int index : indices)
{ buffer.putInt(index); }
buffer.rewind();
}
private void endSingleTimeCommands(VkCommandBuffer commandBuffer) {
@ -199,45 +197,36 @@ public class VKModelData
buffer.rewind();
}
private void createIndexBuffer() {
try(MemoryStack stack = stackPush()) {
long bufferSize = Integer.BYTES * mesh.getIndices().length;
LongBuffer pBuffer = stack.mallocLong(1);
LongBuffer pBufferMemory = stack.mallocLong(1);
createBuffer(bufferSize,
VK12.VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK12.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK12.VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
pBuffer,
pBufferMemory);
long stagingBuffer = pBuffer.get(0);
long stagingBufferMemory = pBufferMemory.get(0);
PointerBuffer data = stack.mallocPointer(1);
VK12.vkMapMemory(VKRegister.device, stagingBufferMemory, 0, bufferSize, 0, data);
{
memcpy(data.getByteBuffer(0, (int) bufferSize), mesh.getIndices());
}
VK12.vkUnmapMemory(VKRegister.device, stagingBufferMemory);
createBuffer(bufferSize,
VK12.VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK12.VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
VK12.VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
pBuffer,
pBufferMemory);
indexBuffer = pBuffer.get(0);
indexBufferMemory = pBufferMemory.get(0);
copyBuffer(stagingBuffer, indexBuffer, bufferSize);
VK12.vkDestroyBuffer(VKRegister.device, stagingBuffer, null);
VK12.vkFreeMemory(VKRegister.device, stagingBufferMemory, null);
}
}
private void createIndexBuffer()
{
try (MemoryStack stack = stackPush())
{
long bufferSize = Integer.BYTES * mesh.getIndices().length;
LongBuffer pBuffer = stack.mallocLong(1);
LongBuffer pBufferMemory = stack.mallocLong(1);
createBuffer(bufferSize,
VK10.VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK10.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK10.VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
pBuffer,
pBufferMemory);
long stagingBuffer = pBuffer.get(0);
long stagingBufferMemory = pBufferMemory.get(0);
PointerBuffer data = stack.mallocPointer(1);
VK10.vkMapMemory(VKRegister.device, stagingBufferMemory, 0, bufferSize, 0, data);
{
memcpyIndices(data.getByteBuffer(0, (int) bufferSize), mesh.getIndices());
}
VK10.vkUnmapMemory(VKRegister.device, stagingBufferMemory);
createBuffer(bufferSize,
VK10.VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK10.VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
VK10.VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
pBuffer,
pBufferMemory);
indexBuffer = pBuffer.get(0);
indexBufferMemory = pBufferMemory.get(0);
copyBuffer(stagingBuffer, indexBuffer, bufferSize);
VK10.vkDestroyBuffer(VKRegister.device, stagingBuffer, null);
VK10.vkFreeMemory(VKRegister.device, stagingBufferMemory, null);
}
}
}

View File

@ -6,13 +6,9 @@ import com.github.hydos.ginger.engine.vulkan.model.VKModelData;
public class VKRegister
{
public static VkDevice device;
public static VkQueue queue;
public static long commandPool;
public static VkPhysicalDevice physicalDevice;
public static VKModelData exampleVKModel;
}

View File

@ -1,83 +1,59 @@
package com.github.hydos.ginger.engine.vulkan.render;
import static org.lwjgl.system.MemoryUtil.memAddress;
import static org.lwjgl.system.MemoryUtil.memAlloc;
import static org.lwjgl.system.MemoryUtil.memAllocInt;
import static org.lwjgl.system.MemoryUtil.memAllocLong;
import static org.lwjgl.system.MemoryUtil.memAllocPointer;
import static org.lwjgl.system.MemoryUtil.memCopy;
import static org.lwjgl.system.MemoryUtil.memFree;
import static org.lwjgl.system.MemoryUtil.*;
import static org.lwjgl.vulkan.KHRSwapchain.VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.*;
import org.lwjgl.PointerBuffer;
import org.lwjgl.vulkan.VK12;
import org.lwjgl.vulkan.VkAttachmentDescription;
import org.lwjgl.vulkan.VkAttachmentReference;
import org.lwjgl.vulkan.VkBufferCreateInfo;
import org.lwjgl.vulkan.VkDevice;
import org.lwjgl.vulkan.VkFramebufferCreateInfo;
import org.lwjgl.vulkan.VkMemoryAllocateInfo;
import org.lwjgl.vulkan.VkMemoryRequirements;
import org.lwjgl.vulkan.VkPhysicalDeviceMemoryProperties;
import org.lwjgl.vulkan.VkPipelineVertexInputStateCreateInfo;
import org.lwjgl.vulkan.VkRenderPassCreateInfo;
import org.lwjgl.vulkan.VkSubpassDescription;
import org.lwjgl.vulkan.VkVertexInputAttributeDescription;
import org.lwjgl.vulkan.VkVertexInputBindingDescription;
import org.lwjgl.vulkan.*;
import com.github.hydos.ginger.VulkanStarter.DepthStencil;
import com.github.hydos.ginger.VulkanStarter.Swapchain;
import com.github.hydos.ginger.VulkanStarter.*;
import com.github.hydos.ginger.engine.vulkan.memory.VKMemory;
import com.github.hydos.ginger.engine.vulkan.model.VKVertices;
import com.github.hydos.ginger.engine.vulkan.utils.VKUtils;
public class RenderUtils
{
public static long createRenderPass(VkDevice device, int colorFormat, int depthFormat)
{
VkAttachmentDescription.Buffer attachments = VkAttachmentDescription.calloc(2);
attachments.get(0) // <- color attachment
.format(colorFormat)
.samples(VK12.VK_SAMPLE_COUNT_1_BIT)
.loadOp(VK12.VK_ATTACHMENT_LOAD_OP_CLEAR)
.storeOp(VK12.VK_ATTACHMENT_STORE_OP_STORE)
.stencilLoadOp(VK12.VK_ATTACHMENT_LOAD_OP_DONT_CARE)
.stencilStoreOp(VK12.VK_ATTACHMENT_STORE_OP_DONT_CARE)
.initialLayout(VK12.VK_IMAGE_LAYOUT_UNDEFINED)
.samples(VK10.VK_SAMPLE_COUNT_1_BIT)
.loadOp(VK10.VK_ATTACHMENT_LOAD_OP_CLEAR)
.storeOp(VK10.VK_ATTACHMENT_STORE_OP_STORE)
.stencilLoadOp(VK10.VK_ATTACHMENT_LOAD_OP_DONT_CARE)
.stencilStoreOp(VK10.VK_ATTACHMENT_STORE_OP_DONT_CARE)
.initialLayout(VK10.VK_IMAGE_LAYOUT_UNDEFINED)
.finalLayout(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
attachments.get(1) // <- depth-stencil attachment
.format(depthFormat)
.samples(VK12.VK_SAMPLE_COUNT_1_BIT)
.loadOp(VK12.VK_ATTACHMENT_LOAD_OP_CLEAR)
.storeOp(VK12.VK_ATTACHMENT_STORE_OP_STORE)
.stencilLoadOp(VK12.VK_ATTACHMENT_LOAD_OP_DONT_CARE)
.stencilStoreOp(VK12.VK_ATTACHMENT_STORE_OP_DONT_CARE)
.initialLayout(VK12.VK_IMAGE_LAYOUT_UNDEFINED)
.samples(VK10.VK_SAMPLE_COUNT_1_BIT)
.loadOp(VK10.VK_ATTACHMENT_LOAD_OP_CLEAR)
.storeOp(VK10.VK_ATTACHMENT_STORE_OP_STORE)
.stencilLoadOp(VK10.VK_ATTACHMENT_LOAD_OP_DONT_CARE)
.stencilStoreOp(VK10.VK_ATTACHMENT_STORE_OP_DONT_CARE)
.initialLayout(VK10.VK_IMAGE_LAYOUT_UNDEFINED)
.finalLayout(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
VkAttachmentReference.Buffer colorReference = VkAttachmentReference.calloc(1)
.attachment(0)
.layout(VK12.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
.layout(VK10.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
VkAttachmentReference depthReference = VkAttachmentReference.calloc()
.attachment(1)
.layout(VK12.VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
.layout(VK10.VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
VkSubpassDescription.Buffer subpass = VkSubpassDescription.calloc(1)
.pipelineBindPoint(VK12.VK_PIPELINE_BIND_POINT_GRAPHICS)
.pipelineBindPoint(VK10.VK_PIPELINE_BIND_POINT_GRAPHICS)
.colorAttachmentCount(colorReference.remaining())
.pColorAttachments(colorReference) // <- only color attachment
.pDepthStencilAttachment(depthReference) // <- and depth-stencil
;
VkRenderPassCreateInfo renderPassInfo = VkRenderPassCreateInfo.calloc()
.sType(VK12.VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO)
.sType(VK10.VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO)
.pAttachments(attachments)
.pSubpasses(subpass);
LongBuffer pRenderPass = memAllocLong(1);
int err = VK12.vkCreateRenderPass(device, renderPassInfo, null, pRenderPass);
int err = VK10.vkCreateRenderPass(device, renderPassInfo, null, pRenderPass);
long renderPass = pRenderPass.get(0);
memFree(pRenderPass);
renderPassInfo.free();
@ -85,7 +61,7 @@ public class RenderUtils
colorReference.free();
subpass.free();
attachments.free();
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to create clear render pass: " + VKUtils.translateVulkanResult(err)); }
return renderPass;
}
@ -95,7 +71,7 @@ public class RenderUtils
LongBuffer attachments = memAllocLong(2);
attachments.put(1, depthStencil.view);
VkFramebufferCreateInfo fci = VkFramebufferCreateInfo.calloc()
.sType(VK12.VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO)
.sType(VK10.VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO)
.pAttachments(attachments)
.height(height)
.width(width)
@ -107,9 +83,9 @@ public class RenderUtils
for (int i = 0; i < swapchain.images.length; i++)
{
attachments.put(0, swapchain.imageViews[i]);
int err = VK12.vkCreateFramebuffer(device, fci, null, pFramebuffer);
int err = VK10.vkCreateFramebuffer(device, fci, null, pFramebuffer);
long framebuffer = pFramebuffer.get(0);
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to create framebuffer: " + VKUtils.translateVulkanResult(err)); }
framebuffers[i] = framebuffer;
}
@ -118,7 +94,7 @@ public class RenderUtils
fci.free();
return framebuffers;
}
public static VKVertices createVertices(VkPhysicalDeviceMemoryProperties deviceMemoryProperties, VkDevice device)
{
ByteBuffer vertexBuffer = memAlloc(2 * 3 * (3 + 3) * 4);
@ -132,53 +108,53 @@ public class RenderUtils
fb.put(-0.5f).put(-0.5f).put(-0.5f).put(0.0f).put(1.0f).put(1.0f);
fb.put(0.0f).put(0.5f).put(-0.5f).put(1.0f).put(0.0f).put(1.0f);
VkMemoryAllocateInfo memAlloc = VkMemoryAllocateInfo.calloc()
.sType(VK12.VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
.sType(VK10.VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
VkMemoryRequirements memReqs = VkMemoryRequirements.calloc();
int err;
// Generate vertex buffer
// Setup
VkBufferCreateInfo bufInfo = VkBufferCreateInfo.calloc()
.sType(VK12.VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO)
.sType(VK10.VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO)
.size(vertexBuffer.remaining())
.usage(VK12.VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
.usage(VK10.VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
LongBuffer pBuffer = memAllocLong(1);
err = VK12.vkCreateBuffer(device, bufInfo, null, pBuffer);
err = VK10.vkCreateBuffer(device, bufInfo, null, pBuffer);
long verticesBuf = pBuffer.get(0);
memFree(pBuffer);
bufInfo.free();
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to create vertex buffer: " + VKUtils.translateVulkanResult(err)); }
VK12.vkGetBufferMemoryRequirements(device, verticesBuf, memReqs);
VK10.vkGetBufferMemoryRequirements(device, verticesBuf, memReqs);
memAlloc.allocationSize(memReqs.size());
IntBuffer memoryTypeIndex = memAllocInt(1);
VKMemory.getMemoryType(deviceMemoryProperties, memReqs.memoryTypeBits(), VK12.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, memoryTypeIndex);
VKMemory.getMemoryType(deviceMemoryProperties, memReqs.memoryTypeBits(), VK10.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, memoryTypeIndex);
memAlloc.memoryTypeIndex(memoryTypeIndex.get(0));
memFree(memoryTypeIndex);
memReqs.free();
LongBuffer pMemory = memAllocLong(1);
err = VK12.vkAllocateMemory(device, memAlloc, null, pMemory);
err = VK10.vkAllocateMemory(device, memAlloc, null, pMemory);
long verticesMem = pMemory.get(0);
memFree(pMemory);
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to allocate vertex memory: " + VKUtils.translateVulkanResult(err)); }
PointerBuffer pData = memAllocPointer(1);
err = VK12.vkMapMemory(device, verticesMem, 0, vertexBuffer.remaining(), 0, pData);
err = VK10.vkMapMemory(device, verticesMem, 0, vertexBuffer.remaining(), 0, pData);
memAlloc.free();
long data = pData.get(0);
memFree(pData);
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to map vertex memory: " + VKUtils.translateVulkanResult(err)); }
memCopy(memAddress(vertexBuffer), data, vertexBuffer.remaining());
memFree(vertexBuffer);
VK12.vkUnmapMemory(device, verticesMem);
err = VK12.vkBindBufferMemory(device, verticesBuf, verticesMem, 0);
if (err != VK12.VK_SUCCESS)
VK10.vkUnmapMemory(device, verticesMem);
err = VK10.vkBindBufferMemory(device, verticesBuf, verticesMem, 0);
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to bind memory to vertex buffer: " + VKUtils.translateVulkanResult(err)); }
// Binding description
VkVertexInputBindingDescription.Buffer bindingDescriptor = VkVertexInputBindingDescription.calloc(1)
.binding(0) // <- we bind our vertex buffer to point 0
.stride((3 + 3) * 4)
.inputRate(VK12.VK_VERTEX_INPUT_RATE_VERTEX);
.inputRate(VK10.VK_VERTEX_INPUT_RATE_VERTEX);
// Attribute descriptions
// Describes memory layout and shader attribute locations
VkVertexInputAttributeDescription.Buffer attributeDescriptions = VkVertexInputAttributeDescription.calloc(2);
@ -186,17 +162,17 @@ public class RenderUtils
attributeDescriptions.get(0)
.binding(0) // <- binding point used in the VkVertexInputBindingDescription
.location(0) // <- location in the shader's attribute layout (inside the shader source)
.format(VK12.VK_FORMAT_R32G32B32_SFLOAT)
.format(VK10.VK_FORMAT_R32G32B32_SFLOAT)
.offset(0);
// Location 1 : Color
attributeDescriptions.get(1)
.binding(0) // <- binding point used in the VkVertexInputBindingDescription
.location(1) // <- location in the shader's attribute layout (inside the shader source)
.format(VK12.VK_FORMAT_R32G32B32_SFLOAT)
.format(VK10.VK_FORMAT_R32G32B32_SFLOAT)
.offset(3 * 4);
// Assign to vertex buffer
VkPipelineVertexInputStateCreateInfo vi = VkPipelineVertexInputStateCreateInfo.calloc();
vi.sType(VK12.VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO);
vi.sType(VK10.VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO);
vi.pVertexBindingDescriptions(bindingDescriptor);
vi.pVertexAttributeDescriptions(attributeDescriptions);
VKVertices ret = new VKVertices();

View File

@ -11,38 +11,30 @@ import com.github.hydos.ginger.engine.vulkan.registers.VKRegister;
public class EntityRenderer extends VKRenderer
{
@Override
public void render(MemoryStack stack, VkCommandBuffer renderCommandBuffer)
{
// //Bind the models buffers
// LongBuffer offsets = memAllocLong(1);
// offsets.put(0, 0L);
// LongBuffer vertexBuffers = stack.longs(VKRegister.exampleVKModel.vertexBuffer);
// VK12.vkCmdBindVertexBuffers(renderCommandBuffer, 0, vertexBuffers, offsets);
// VK12.vkCmdBindIndexBuffer(renderCommandBuffer, VKRegister.exampleVKModel.indexBuffer, 0, 3);// 3 = VK_INDEX_TYPE_UINT32
// memFree(offsets);
//
// //Render the texture
// VK12.vkCmdDrawIndexed(renderCommandBuffer, VKRegister.exampleVKModel.mesh.getIndices().length, 1, 0, 0, 0);
// FIXME: make master render get instance render with this instead, etc u get the point
//Bind the models buffers
LongBuffer offsets = memAllocLong(1);
offsets.put(0, 0L);
LongBuffer vertexBuffers = stack.longs(VKRegister.exampleVKModel.vertexBuffer);
VK10.vkCmdBindVertexBuffers(renderCommandBuffer, 0, vertexBuffers, offsets);
VK10.vkCmdBindIndexBuffer(renderCommandBuffer, VKRegister.exampleVKModel.indexBuffer, 0, 3);// 3 = VK_INDEX_TYPE_UINT32
memFree(offsets);
//Render the texture
VK10.vkCmdDrawIndexed(renderCommandBuffer, VKRegister.exampleVKModel.mesh.getIndices().length, 1, 0, 0, 0);
}
public static void tempStaticRender(MemoryStack stack, VkCommandBuffer renderCommandBuffer)
{
//Bind the models buffers
LongBuffer offsets = memAllocLong(1);
offsets.put(0, 0L);
LongBuffer vertexBuffers = stack.longs(VKRegister.exampleVKModel.vertexBuffer);
VK12.vkCmdBindVertexBuffers(renderCommandBuffer, 0, vertexBuffers, offsets);
VK12.vkCmdBindIndexBuffer(renderCommandBuffer, VKRegister.exampleVKModel.indexBuffer, 0, 0);// 3 = VK_INDEX_TYPE_UINT32
LongBuffer vertexBuffers = stack.longs(VKRegister.exampleVKModel.vertexBuffer);
VK10.vkCmdBindVertexBuffers(renderCommandBuffer, 0, vertexBuffers, offsets);
VK10.vkCmdBindIndexBuffer(renderCommandBuffer, VKRegister.exampleVKModel.indexBuffer, 0, 3);// 3 = VK_INDEX_TYPE_UINT32
memFree(offsets);
//Render the texture
VK12.vkCmdDrawIndexed(renderCommandBuffer, VKRegister.exampleVKModel.mesh.getIndices().length, 1, 0, 0, 0);
VK10.vkCmdDrawIndexed(renderCommandBuffer, VKRegister.exampleVKModel.mesh.getIndices().length, 1, 0, 0, 0);
}
}

View File

@ -1,58 +1,28 @@
package com.github.hydos.ginger.engine.vulkan.render.renderers;
import static org.lwjgl.system.MemoryUtil.memAllocInt;
import static org.lwjgl.system.MemoryUtil.memAllocLong;
import static org.lwjgl.system.MemoryUtil.memFree;
import static org.lwjgl.vulkan.KHRSurface.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
import static org.lwjgl.vulkan.KHRSurface.VK_PRESENT_MODE_FIFO_KHR;
import static org.lwjgl.vulkan.KHRSurface.VK_PRESENT_MODE_IMMEDIATE_KHR;
import static org.lwjgl.vulkan.KHRSurface.VK_PRESENT_MODE_MAILBOX_KHR;
import static org.lwjgl.vulkan.KHRSurface.VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
import static org.lwjgl.vulkan.KHRSurface.vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
import static org.lwjgl.vulkan.KHRSurface.vkGetPhysicalDeviceSurfaceFormatsKHR;
import static org.lwjgl.vulkan.KHRSurface.vkGetPhysicalDeviceSurfacePresentModesKHR;
import static org.lwjgl.vulkan.KHRSurface.vkGetPhysicalDeviceSurfaceSupportKHR;
import static org.lwjgl.vulkan.KHRSwapchain.VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
import static org.lwjgl.vulkan.KHRSwapchain.vkCreateSwapchainKHR;
import static org.lwjgl.vulkan.KHRSwapchain.vkDestroySwapchainKHR;
import static org.lwjgl.vulkan.KHRSwapchain.vkGetSwapchainImagesKHR;
import static org.lwjgl.system.MemoryUtil.*;
import static org.lwjgl.vulkan.KHRSurface.*;
import static org.lwjgl.vulkan.KHRSwapchain.*;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.*;
import org.lwjgl.vulkan.VK12;
import org.lwjgl.vulkan.VkCommandBuffer;
import org.lwjgl.vulkan.VkDevice;
import org.lwjgl.vulkan.VkExtent2D;
import org.lwjgl.vulkan.VkImageCreateInfo;
import org.lwjgl.vulkan.VkImageViewCreateInfo;
import org.lwjgl.vulkan.VkMemoryAllocateInfo;
import org.lwjgl.vulkan.VkMemoryRequirements;
import org.lwjgl.vulkan.VkPhysicalDevice;
import org.lwjgl.vulkan.VkPhysicalDeviceMemoryProperties;
import org.lwjgl.vulkan.VkQueueFamilyProperties;
import org.lwjgl.vulkan.VkSurfaceCapabilitiesKHR;
import org.lwjgl.vulkan.VkSurfaceFormatKHR;
import org.lwjgl.vulkan.VkSwapchainCreateInfoKHR;
import org.lwjgl.vulkan.*;
import com.github.hydos.ginger.VulkanStarter;
import com.github.hydos.ginger.VulkanStarter.ColorAndDepthFormatAndSpace;
import com.github.hydos.ginger.VulkanStarter.DepthStencil;
import com.github.hydos.ginger.VulkanStarter.Swapchain;
import com.github.hydos.ginger.VulkanStarter.*;
import com.github.hydos.ginger.engine.common.io.Window;
import com.github.hydos.ginger.engine.vulkan.memory.VKMemory;
import com.github.hydos.ginger.engine.vulkan.utils.VKUtils;
public class VKMasterRenderer
{
public static ColorAndDepthFormatAndSpace getColorFormatAndSpace(VkPhysicalDevice physicalDevice, long surface)
{
IntBuffer pQueueFamilyPropertyCount = memAllocInt(1);
VK12.vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, null);
VK10.vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, null);
int queueCount = pQueueFamilyPropertyCount.get(0);
VkQueueFamilyProperties.Buffer queueProps = VkQueueFamilyProperties.calloc(queueCount);
VK12.vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, queueProps);
VK10.vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, queueProps);
memFree(pQueueFamilyPropertyCount);
// Iterate over each queue to learn whether it supports presenting:
IntBuffer supportsPresent = memAllocInt(queueCount);
@ -60,7 +30,7 @@ public class VKMasterRenderer
{
supportsPresent.position(i);
int err = vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, i, surface, supportsPresent);
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to physical device surface support: " + VKUtils.translateVulkanResult(err)); }
}
// Search for a graphics and a present queue in the array of queue families, try to find one that supports both
@ -68,11 +38,11 @@ public class VKMasterRenderer
int presentQueueNodeIndex = Integer.MAX_VALUE;
for (int i = 0; i < queueCount; i++)
{
if ((queueProps.get(i).queueFlags() & VK12.VK_QUEUE_GRAPHICS_BIT) != 0)
if ((queueProps.get(i).queueFlags() & VK10.VK_QUEUE_GRAPHICS_BIT) != 0)
{
if (graphicsQueueNodeIndex == Integer.MAX_VALUE)
{ graphicsQueueNodeIndex = i; }
if (supportsPresent.get(i) == VK12.VK_TRUE)
if (supportsPresent.get(i) == VK10.VK_TRUE)
{
graphicsQueueNodeIndex = i;
presentQueueNodeIndex = i;
@ -86,7 +56,7 @@ public class VKMasterRenderer
// If there's no queue that supports both present and graphics try to find a separate present queue
for (int i = 0; i < queueCount; ++i)
{
if (supportsPresent.get(i) == VK12.VK_TRUE)
if (supportsPresent.get(i) == VK10.VK_TRUE)
{
presentQueueNodeIndex = i;
break;
@ -105,17 +75,17 @@ public class VKMasterRenderer
IntBuffer pFormatCount = memAllocInt(1);
int err = vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, pFormatCount, null);
int formatCount = pFormatCount.get(0);
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to query number of physical device surface formats: " + VKUtils.translateVulkanResult(err)); }
VkSurfaceFormatKHR.Buffer surfFormats = VkSurfaceFormatKHR.calloc(formatCount);
err = vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, pFormatCount, surfFormats);
memFree(pFormatCount);
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to query physical device surface formats: " + VKUtils.translateVulkanResult(err)); }
int colorFormat;
if (formatCount == 1 && surfFormats.get(0).format() == VK12.VK_FORMAT_UNDEFINED)
if (formatCount == 1 && surfFormats.get(0).format() == VK10.VK_FORMAT_UNDEFINED)
{
colorFormat = VK12.VK_FORMAT_B8G8R8A8_UNORM;
colorFormat = VK10.VK_FORMAT_B8G8R8A8_UNORM;
}
else
{
@ -137,63 +107,63 @@ public class VKMasterRenderer
public static DepthStencil createDepthStencil(VkDevice device, VkPhysicalDeviceMemoryProperties physicalDeviceMemoryProperties, int depthFormat, VkCommandBuffer setupCmdBuffer)
{
VkImageCreateInfo imageCreateInfo = VkImageCreateInfo.calloc()
.sType(VK12.VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO)
.imageType(VK12.VK_IMAGE_TYPE_2D)
.sType(VK10.VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO)
.imageType(VK10.VK_IMAGE_TYPE_2D)
.format(depthFormat)
.mipLevels(1)
.arrayLayers(1)
.samples(VK12.VK_SAMPLE_COUNT_1_BIT)
.tiling(VK12.VK_IMAGE_TILING_OPTIMAL)
.usage(VK12.VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK12.VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
.samples(VK10.VK_SAMPLE_COUNT_1_BIT)
.tiling(VK10.VK_IMAGE_TILING_OPTIMAL)
.usage(VK10.VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK10.VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
imageCreateInfo.extent().width(Window.getWidth()).height(Window.getHeight()).depth(1);
VkMemoryAllocateInfo mem_alloc = VkMemoryAllocateInfo.calloc()
.sType(VK12.VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
.sType(VK10.VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
VkImageViewCreateInfo depthStencilViewCreateInfo = VkImageViewCreateInfo.calloc()
.sType(VK12.VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO)
.viewType(VK12.VK_IMAGE_VIEW_TYPE_2D)
.sType(VK10.VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO)
.viewType(VK10.VK_IMAGE_VIEW_TYPE_2D)
.format(depthFormat);
depthStencilViewCreateInfo.subresourceRange()
.aspectMask(VK12.VK_IMAGE_ASPECT_DEPTH_BIT | VK12.VK_IMAGE_ASPECT_STENCIL_BIT)
.aspectMask(VK10.VK_IMAGE_ASPECT_DEPTH_BIT | VK10.VK_IMAGE_ASPECT_STENCIL_BIT)
.levelCount(1)
.layerCount(1);
VkMemoryRequirements memReqs = VkMemoryRequirements.calloc();
int err;
LongBuffer pDepthStencilImage = memAllocLong(1);
err = VK12.vkCreateImage(device, imageCreateInfo, null, pDepthStencilImage);
err = VK10.vkCreateImage(device, imageCreateInfo, null, pDepthStencilImage);
long depthStencilImage = pDepthStencilImage.get(0);
memFree(pDepthStencilImage);
imageCreateInfo.free();
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to create depth-stencil image: " + VKUtils.translateVulkanResult(err)); }
VK12.vkGetImageMemoryRequirements(device, depthStencilImage, memReqs);
VK10.vkGetImageMemoryRequirements(device, depthStencilImage, memReqs);
mem_alloc.allocationSize(memReqs.size());
IntBuffer pMemoryTypeIndex = memAllocInt(1);
VKMemory.getMemoryType(physicalDeviceMemoryProperties, memReqs.memoryTypeBits(), VK12.VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, pMemoryTypeIndex);
VKMemory.getMemoryType(physicalDeviceMemoryProperties, memReqs.memoryTypeBits(), VK10.VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, pMemoryTypeIndex);
mem_alloc.memoryTypeIndex(pMemoryTypeIndex.get(0));
memFree(pMemoryTypeIndex);
LongBuffer pDepthStencilMem = memAllocLong(1);
err = VK12.vkAllocateMemory(device, mem_alloc, null, pDepthStencilMem);
err = VK10.vkAllocateMemory(device, mem_alloc, null, pDepthStencilMem);
long depthStencilMem = pDepthStencilMem.get(0);
memFree(pDepthStencilMem);
mem_alloc.free();
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to create depth-stencil memory: " + VKUtils.translateVulkanResult(err)); }
err = VK12.vkBindImageMemory(device, depthStencilImage, depthStencilMem, 0);
if (err != VK12.VK_SUCCESS)
err = VK10.vkBindImageMemory(device, depthStencilImage, depthStencilMem, 0);
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to bind depth-stencil image to memory: " + VKUtils.translateVulkanResult(err)); }
depthStencilViewCreateInfo.image(depthStencilImage);
LongBuffer pDepthStencilView = memAllocLong(1);
err = VK12.vkCreateImageView(device, depthStencilViewCreateInfo, null, pDepthStencilView);
err = VK10.vkCreateImageView(device, depthStencilViewCreateInfo, null, pDepthStencilView);
long depthStencilView = pDepthStencilView.get(0);
memFree(pDepthStencilView);
depthStencilViewCreateInfo.free();
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to create depth-stencil image view: " + VKUtils.translateVulkanResult(err)); }
DepthStencil ret = new DepthStencil();
ret.view = depthStencilView;
return ret;
}
public static Swapchain createSwapChain(VkDevice device, VkPhysicalDevice physicalDevice, long surface, long oldSwapChain, VkCommandBuffer commandBuffer, int newWidth,
int newHeight, int colorFormat, int colorSpace)
{
@ -201,17 +171,17 @@ public class VKMasterRenderer
// Get physical device surface properties and formats
VkSurfaceCapabilitiesKHR surfCaps = VkSurfaceCapabilitiesKHR.calloc();
err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, surfCaps);
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to get physical device surface capabilities: " + VKUtils.translateVulkanResult(err)); }
IntBuffer pPresentModeCount = memAllocInt(1);
err = vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, pPresentModeCount, null);
int presentModeCount = pPresentModeCount.get(0);
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to get number of physical device surface presentation modes: " + VKUtils.translateVulkanResult(err)); }
IntBuffer pPresentModes = memAllocInt(presentModeCount);
err = vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, pPresentModeCount, pPresentModes);
memFree(pPresentModeCount);
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to get physical device surface presentation modes: " + VKUtils.translateVulkanResult(err)); }
// Try to use mailbox mode. Low latency and non-tearing
int swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
@ -259,10 +229,10 @@ public class VKMasterRenderer
.minImageCount(desiredNumberOfSwapchainImages)
.imageFormat(colorFormat)
.imageColorSpace(colorSpace)
.imageUsage(VK12.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
.imageUsage(VK10.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
.preTransform(preTransform)
.imageArrayLayers(1)
.imageSharingMode(VK12.VK_SHARING_MODE_EXCLUSIVE)
.imageSharingMode(VK10.VK_SHARING_MODE_EXCLUSIVE)
.presentMode(swapchainPresentMode)
.oldSwapchain(oldSwapChain)
.clipped(true)
@ -275,40 +245,40 @@ public class VKMasterRenderer
swapchainCI.free();
long swapChain = pSwapChain.get(0);
memFree(pSwapChain);
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to create swap chain: " + VKUtils.translateVulkanResult(err)); }
// If we just re-created an existing swapchain, we should destroy the old swapchain at this point.
// Note: destroying the swapchain also cleans up all its associated presentable images once the platform is done with them.
if (oldSwapChain != VK12.VK_NULL_HANDLE)
if (oldSwapChain != VK10.VK_NULL_HANDLE)
{ vkDestroySwapchainKHR(device, oldSwapChain, null); }
IntBuffer pImageCount = memAllocInt(1);
err = vkGetSwapchainImagesKHR(device, swapChain, pImageCount, null);
int imageCount = pImageCount.get(0);
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to get number of swapchain images: " + VKUtils.translateVulkanResult(err)); }
LongBuffer pSwapchainImages = memAllocLong(imageCount);
err = vkGetSwapchainImagesKHR(device, swapChain, pImageCount, pSwapchainImages);
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to get swapchain images: " + VKUtils.translateVulkanResult(err)); }
memFree(pImageCount);
long[] images = new long[imageCount];
long[] imageViews = new long[imageCount];
LongBuffer pBufferView = memAllocLong(1);
VkImageViewCreateInfo colorAttachmentView = VkImageViewCreateInfo.calloc()
.sType(VK12.VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO)
.sType(VK10.VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO)
.format(colorFormat)
.viewType(VK12.VK_IMAGE_VIEW_TYPE_2D);
.viewType(VK10.VK_IMAGE_VIEW_TYPE_2D);
colorAttachmentView.subresourceRange()
.aspectMask(VK12.VK_IMAGE_ASPECT_COLOR_BIT)
.aspectMask(VK10.VK_IMAGE_ASPECT_COLOR_BIT)
.levelCount(1)
.layerCount(1);
for (int i = 0; i < imageCount; i++)
{
images[i] = pSwapchainImages.get(i);
colorAttachmentView.image(images[i]);
err = VK12.vkCreateImageView(device, colorAttachmentView, null, pBufferView);
err = VK10.vkCreateImageView(device, colorAttachmentView, null, pBufferView);
imageViews[i] = pBufferView.get(0);
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to create image view: " + VKUtils.translateVulkanResult(err)); }
}
colorAttachmentView.free();
@ -320,5 +290,4 @@ public class VKMasterRenderer
ret.swapchainHandle = swapChain;
return ret;
}
}

View File

@ -5,7 +5,5 @@ import org.lwjgl.vulkan.VkCommandBuffer;
public abstract class VKRenderer
{
public abstract void render(MemoryStack stack, VkCommandBuffer renderCommandBuffer);
}

View File

@ -12,17 +12,16 @@ import org.lwjgl.vulkan.*;
import com.github.hydos.ginger.engine.common.io.Window;
import com.github.hydos.ginger.engine.vulkan.memory.VKMemory;
import com.github.hydos.ginger.engine.vulkan.utils.VKUtils;
/**
* A UBO is a uniform buffer object
/** A UBO is a uniform buffer object
* i believe its used to give data from code to the shaders
* @author hydos
*
*/
public class Ubo {
*
* @author hydos */
public class Ubo
{
public UboDescriptor uboData;
public Ubo(VkPhysicalDeviceMemoryProperties deviceMemoryProperties, VkDevice device)
public Ubo(VkPhysicalDeviceMemoryProperties deviceMemoryProperties, VkDevice device)
{
int err;
// Create a new buffer
@ -72,7 +71,7 @@ public class Ubo {
ret.range = 16 * 4;
this.uboData = ret;
}
public void updateUbo(VkDevice device, float angle)
{
Matrix4f m = new Matrix4f()
@ -92,5 +91,4 @@ public class Ubo {
m.get(matrixBuffer);
vkUnmapMemory(device, uboData.memory);
}
}

View File

@ -14,7 +14,7 @@ public class Pipeline
{
public long pipeline;
public long layout;
public static Pipeline createPipeline(VkDevice device, long renderPass, VkPipelineVertexInputStateCreateInfo vi, long descriptorSetLayout) throws IOException
{
int err;

View File

@ -3,5 +3,4 @@ package com.github.hydos.ginger.engine.vulkan.shaders;
public class ShaderType
{
public final static int vertexShader = 0;
}

View File

@ -10,8 +10,8 @@ import org.lwjgl.vulkan.*;
import com.github.hydos.ginger.engine.vulkan.utils.VKUtils;
public class VKShaderManager {
public class VKShaderManager
{
public static VkPipelineShaderStageCreateInfo loadShader(VkDevice device, String classPath, int stage) throws IOException
{
VkPipelineShaderStageCreateInfo shaderStage = VkPipelineShaderStageCreateInfo.calloc()
@ -21,7 +21,7 @@ public class VKShaderManager {
.pName(memUTF8("main"));
return shaderStage;
}
public static long loadShader(String classPath, VkDevice device, int stage) throws IOException
{
ByteBuffer shaderCode = VKUtils.glslToSpirv(classPath, stage);

View File

@ -10,44 +10,45 @@ import org.lwjgl.vulkan.*;
import com.github.hydos.ginger.engine.vulkan.VKConstants;
public class VKDeviceProperties {
public class VKDeviceProperties
{
public VkDevice device;
public int queueFamilyIndex;
public VkPhysicalDeviceMemoryProperties memoryProperties;
public static VkPhysicalDevice getFirstPhysicalDevice(VkInstance instance)
{
IntBuffer pPhysicalDeviceCount = memAllocInt(1);
int err = VK12.vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, null);
if (err != VK12.VK_SUCCESS)
int err = VK10.vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, null);
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to get number of physical devices: " + VKUtils.translateVulkanResult(err)); }
PointerBuffer pPhysicalDevices = memAllocPointer(pPhysicalDeviceCount.get(0));
err = VK12.vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
err = VK10.vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
long physicalDevice = pPhysicalDevices.get(0);
memFree(pPhysicalDeviceCount);
memFree(pPhysicalDevices);
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to get physical devices: " + VKUtils.translateVulkanResult(err)); }
return new VkPhysicalDevice(physicalDevice, instance);
}
public static VKDeviceProperties initDeviceProperties(VkPhysicalDevice physicalDevice)
{
IntBuffer pQueueFamilyPropertyCount = memAllocInt(1);
VK12.vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, null);
VK10.vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, null);
int queueCount = pQueueFamilyPropertyCount.get(0);
VkQueueFamilyProperties.Buffer queueProps = VkQueueFamilyProperties.calloc(queueCount);
VK12.vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, queueProps);
VK10.vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, queueProps);
memFree(pQueueFamilyPropertyCount);
int graphicsQueueFamilyIndex;
for (graphicsQueueFamilyIndex = 0; graphicsQueueFamilyIndex < queueCount; graphicsQueueFamilyIndex++)
{ if ((queueProps.get(graphicsQueueFamilyIndex).queueFlags() & VK12.VK_QUEUE_GRAPHICS_BIT) != 0)
{ if ((queueProps.get(graphicsQueueFamilyIndex).queueFlags() & VK10.VK_QUEUE_GRAPHICS_BIT) != 0)
break; }
queueProps.free();
FloatBuffer pQueuePriorities = memAllocFloat(1).put(0.0f);
pQueuePriorities.flip();
VkDeviceQueueCreateInfo.Buffer queueCreateInfo = VkDeviceQueueCreateInfo.calloc(1)
.sType(VK12.VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO)
.sType(VK10.VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO)
.queueFamilyIndex(graphicsQueueFamilyIndex)
.pQueuePriorities(pQueuePriorities);
PointerBuffer extensions = memAllocPointer(1);
@ -59,18 +60,18 @@ public class VKDeviceProperties {
ppEnabledLayerNames.put(VKConstants.layers[i]);
ppEnabledLayerNames.flip();
VkDeviceCreateInfo deviceCreateInfo = VkDeviceCreateInfo.calloc()
.sType(VK12.VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO)
.sType(VK10.VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO)
.pQueueCreateInfos(queueCreateInfo)
.ppEnabledExtensionNames(extensions)
.ppEnabledLayerNames(ppEnabledLayerNames);
PointerBuffer pDevice = memAllocPointer(1);
int err = VK12.vkCreateDevice(physicalDevice, deviceCreateInfo, null, pDevice);
int err = VK10.vkCreateDevice(physicalDevice, deviceCreateInfo, null, pDevice);
long device = pDevice.get(0);
memFree(pDevice);
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to create device: " + VKUtils.translateVulkanResult(err)); }
VkPhysicalDeviceMemoryProperties memoryProperties = VkPhysicalDeviceMemoryProperties.calloc();
VK12.vkGetPhysicalDeviceMemoryProperties(physicalDevice, memoryProperties);
VK10.vkGetPhysicalDeviceMemoryProperties(physicalDevice, memoryProperties);
VKDeviceProperties ret = new VKDeviceProperties();
ret.device = new VkDevice(device, physicalDevice, deviceCreateInfo);
ret.queueFamilyIndex = graphicsQueueFamilyIndex;

View File

@ -16,42 +16,42 @@ import com.github.hydos.ginger.engine.vulkan.VKConstants;
* used to load vulkan related objects such as textures */
public class VKLoader
{
public static VkInstance createInstance(PointerBuffer requiredExtensions) {
VkApplicationInfo appInfo = VkApplicationInfo.calloc()
.sType(VK_STRUCTURE_TYPE_APPLICATION_INFO)
.apiVersion(VK_API_VERSION_1_2);
PointerBuffer ppEnabledExtensionNames = memAllocPointer(requiredExtensions.remaining() + 1);
ppEnabledExtensionNames.put(requiredExtensions);
ByteBuffer VK_EXT_DEBUG_REPORT_EXTENSION = memUTF8(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
ppEnabledExtensionNames.put(VK_EXT_DEBUG_REPORT_EXTENSION);
ppEnabledExtensionNames.flip();
PointerBuffer ppEnabledLayerNames = memAllocPointer(VKConstants.layers.length);
for (int i = 0; VKConstants.debug && i < VKConstants.layers.length; i++)
ppEnabledLayerNames.put(VKConstants.layers[i]);
ppEnabledLayerNames.flip();
VkInstanceCreateInfo pCreateInfo = VkInstanceCreateInfo.calloc()
.sType(VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO)
.pApplicationInfo(appInfo)
.ppEnabledExtensionNames(ppEnabledExtensionNames)
.ppEnabledLayerNames(ppEnabledLayerNames);
PointerBuffer pInstance = memAllocPointer(1);
int err = vkCreateInstance(pCreateInfo, null, pInstance);
long instance = pInstance.get(0);
memFree(pInstance);
if (err != VK_SUCCESS) {
throw new AssertionError("Failed to create VkInstance: " + VKUtils.translateVulkanResult(err));
}
VkInstance ret = new VkInstance(instance, pCreateInfo);
pCreateInfo.free();
memFree(ppEnabledLayerNames);
memFree(VK_EXT_DEBUG_REPORT_EXTENSION);
memFree(ppEnabledExtensionNames);
memFree(appInfo.pApplicationName());
memFree(appInfo.pEngineName());
appInfo.free();
return ret;
}
public static VkInstance createInstance(PointerBuffer requiredExtensions)
{
VkApplicationInfo appInfo = VkApplicationInfo.calloc()
.sType(VK_STRUCTURE_TYPE_APPLICATION_INFO)
.apiVersion(VK_API_VERSION_1_2);
PointerBuffer ppEnabledExtensionNames = memAllocPointer(requiredExtensions.remaining() + 1);
ppEnabledExtensionNames.put(requiredExtensions);
ByteBuffer VK_EXT_DEBUG_REPORT_EXTENSION = memUTF8(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
ppEnabledExtensionNames.put(VK_EXT_DEBUG_REPORT_EXTENSION);
ppEnabledExtensionNames.flip();
PointerBuffer ppEnabledLayerNames = memAllocPointer(VKConstants.layers.length);
for (int i = 0; VKConstants.debug && i < VKConstants.layers.length; i++)
ppEnabledLayerNames.put(VKConstants.layers[i]);
ppEnabledLayerNames.flip();
VkInstanceCreateInfo pCreateInfo = VkInstanceCreateInfo.calloc()
.sType(VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO)
.pApplicationInfo(appInfo)
.ppEnabledExtensionNames(ppEnabledExtensionNames)
.ppEnabledLayerNames(ppEnabledLayerNames);
PointerBuffer pInstance = memAllocPointer(1);
int err = vkCreateInstance(pCreateInfo, null, pInstance);
long instance = pInstance.get(0);
memFree(pInstance);
if (err != VK_SUCCESS)
{ throw new AssertionError("Failed to create VkInstance: " + VKUtils.translateVulkanResult(err)); }
VkInstance ret = new VkInstance(instance, pCreateInfo);
pCreateInfo.free();
memFree(ppEnabledLayerNames);
memFree(VK_EXT_DEBUG_REPORT_EXTENSION);
memFree(ppEnabledExtensionNames);
memFree(appInfo.pApplicationName());
memFree(appInfo.pEngineName());
appInfo.free();
return ret;
}
public void setupVulkan()
{}
}

View File

@ -23,7 +23,6 @@ import com.github.hydos.ginger.engine.vulkan.shaders.Pipeline;
* a util library for Vulkan */
public class VKUtils
{
public static final int VK_FLAGS_NONE = 0;
public static long startVulkanDebugging(VkInstance instance, int flags, VkDebugReportCallbackEXT callback)
@ -37,11 +36,11 @@ public class VKUtils
long callbackHandle = pCallback.get(0);
memFree(pCallback);
dbgCreateInfo.free();
if (err != VK12.VK_SUCCESS)
if (err != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to create VkInstance: " + VKUtils.translateVulkanResult(err)); }
return callbackHandle;
}
private static int vulkanStageToShaderc(int stage)
{
switch (stage)
@ -74,6 +73,7 @@ public class VKUtils
shaderc_compile_options_set_optimization_level(options, shaderc_optimization_level_performance);
shaderc_compile_options_set_include_callbacks(options, resolver = new ShadercIncludeResolve()
{
@Override
public long invoke(long user_data, long requested_source, int type, long requesting_source, long include_depth)
{
ShadercIncludeResult res = ShadercIncludeResult.calloc();
@ -91,6 +91,7 @@ public class VKUtils
}
}, releaser = new ShadercIncludeResultRelease()
{
@Override
public void invoke(long user_data, long include_result)
{
ShadercIncludeResult result = ShadercIncludeResult.create(include_result);
@ -167,7 +168,7 @@ public class VKUtils
return String.format("%s [%d]", "Is an unknown vulkan result", Integer.valueOf(vulkanResult));
}
}
public static VkCommandBuffer[] setupRenderCommandBuffer(VkDevice device, long commandPool, long[] framebuffers, long renderPass, int width, int height,
Pipeline pipeline, long descriptorSet, long verticesBuf)
{
@ -175,13 +176,13 @@ public class VKUtils
{
// Create the render command buffers (one command buffer per framebuffer image)
VkCommandBufferAllocateInfo cmdBufAllocateInfo = VkCommandBufferAllocateInfo.calloc()
.sType(VK12.VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO)
.sType(VK10.VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO)
.commandPool(commandPool)
.level(VK12.VK_COMMAND_BUFFER_LEVEL_PRIMARY)
.level(VK10.VK_COMMAND_BUFFER_LEVEL_PRIMARY)
.commandBufferCount(framebuffers.length);
PointerBuffer pCommandBuffer = memAllocPointer(framebuffers.length);
int result = VK12.vkAllocateCommandBuffers(device, cmdBufAllocateInfo, pCommandBuffer);
if (result != VK12.VK_SUCCESS)
int result = VK10.vkAllocateCommandBuffers(device, cmdBufAllocateInfo, pCommandBuffer);
if (result != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to create render command buffer: " + VKUtils.translateVulkanResult(result)); }
VkCommandBuffer[] renderCommandBuffers = new VkCommandBuffer[framebuffers.length];
for (int i = 0; i < framebuffers.length; i++)
@ -190,7 +191,7 @@ public class VKUtils
cmdBufAllocateInfo.free();
// Create the command buffer begin structure
VkCommandBufferBeginInfo cmdBufInfo = VkCommandBufferBeginInfo.calloc()
.sType(VK12.VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO);
.sType(VK10.VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO);
// Specify clear colour
VkClearValue.Buffer clearValues = VkClearValue.calloc(2);
clearValues.get(0).color()
@ -202,7 +203,7 @@ public class VKUtils
clearValues.get(1).depthStencil().depth(1.0f).stencil(0);
// Specify everything to begin a render pass
VkRenderPassBeginInfo renderPassBeginInfo = VkRenderPassBeginInfo.calloc()
.sType(VK12.VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO)
.sType(VK10.VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO)
.renderPass(renderPass)
.pClearValues(clearValues);
VkRect2D renderArea = renderPassBeginInfo.renderArea();
@ -212,35 +213,34 @@ public class VKUtils
{
// Set target frame buffer
renderPassBeginInfo.framebuffer(framebuffers[i]);
result = VK12.vkBeginCommandBuffer(renderCommandBuffers[i], cmdBufInfo);
if (result != VK12.VK_SUCCESS)
result = VK10.vkBeginCommandBuffer(renderCommandBuffers[i], cmdBufInfo);
if (result != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to begin render command buffer: " + VKUtils.translateVulkanResult(result)); }
VK12.vkCmdBeginRenderPass(renderCommandBuffers[i], renderPassBeginInfo, VK12.VK_SUBPASS_CONTENTS_INLINE);
VK10.vkCmdBeginRenderPass(renderCommandBuffers[i], renderPassBeginInfo, VK10.VK_SUBPASS_CONTENTS_INLINE);
// Update dynamic viewport state
VkViewport.Buffer viewport = VkViewport.calloc(1)
.height(height)
.width(width)
.minDepth(0.0f)
.maxDepth(1.0f);
VK12.vkCmdSetViewport(renderCommandBuffers[i], 0, viewport);
VK10.vkCmdSetViewport(renderCommandBuffers[i], 0, viewport);
viewport.free();
// Update dynamic scissor state
VkRect2D.Buffer scissor = VkRect2D.calloc(1);
scissor.extent().set(width, height);
scissor.offset().set(0, 0);
VK12.vkCmdSetScissor(renderCommandBuffers[i], 0, scissor);
VK10.vkCmdSetScissor(renderCommandBuffers[i], 0, scissor);
scissor.free();
// Bind descriptor sets describing shader binding points
LongBuffer descriptorSets = memAllocLong(1).put(0, descriptorSet);
VK12.vkCmdBindDescriptorSets(renderCommandBuffers[i], VK12.VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.layout, 0, descriptorSets, null);
VK10.vkCmdBindDescriptorSets(renderCommandBuffers[i], VK10.VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.layout, 0, descriptorSets, null);
memFree(descriptorSets);
// Bind the rendering pipeline (including the shaders)
VK12.vkCmdBindPipeline(renderCommandBuffers[i], VK12.VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipeline);
VK10.vkCmdBindPipeline(renderCommandBuffers[i], VK10.VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipeline);
EntityRenderer.tempStaticRender(stack, renderCommandBuffers[i]);
VK12.vkCmdEndRenderPass(renderCommandBuffers[i]);
result = VK12.vkEndCommandBuffer(renderCommandBuffers[i]);
if (result != VK12.VK_SUCCESS)
VK10.vkCmdEndRenderPass(renderCommandBuffers[i]);
result = VK10.vkEndCommandBuffer(renderCommandBuffers[i]);
if (result != VK10.VK_SUCCESS)
{ throw new AssertionError("Failed to begin render command buffer: " + VKUtils.translateVulkanResult(result)); }
}
renderPassBeginInfo.free();
@ -248,14 +248,13 @@ public class VKUtils
cmdBufInfo.free();
return renderCommandBuffers;
}
}
public static void setupVulkanDebugCallback()
{
VKConstants.debugCallback = new VkDebugReportCallbackEXT()
{
@Override
public int invoke(int flags, int objectType, long object, long location, int messageCode, long pLayerPrefix, long pMessage, long pUserData)
{
System.err.println("ERROR OCCURED: " + VkDebugReportCallbackEXT.getString(pMessage));

View File

@ -12,12 +12,9 @@ import static org.lwjgl.vulkan.VK10.*;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.util.vma.*;
import org.lwjgl.vulkan.*;
/**
*
* @author hydos
* used to make the vulkan api more readable
*
*/
/** @author hydos
* used to make the vulkan api more readable */
public class VulkanFuncWrapper
{
public static VmaVulkanFunctions VmaVulkanFunctions(MemoryStack stack)

View File

@ -1,8 +1,6 @@
package tk.valoeghese.gateways.client.io;
/**
* Author: Valoeghese
*/
/** Author: Valoeghese */
public final class InitialPressHandler implements KeyListener
{
private boolean activatedPreviously = false;

View File

@ -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<>();

View File

@ -1,8 +1,6 @@
package tk.valoeghese.gateways.client.io;
/**
* Author: Valoeghese
*/
/** Author: Valoeghese */
public interface KeyCallback
{
public void onCallback();

View File

@ -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();

View File

@ -1,8 +1,6 @@
package tk.valoeghese.gateways.client.io;
/**
* Author: Valoeghese
*/
/** Author: Valoeghese */
public interface KeyListener
{
public void listen(boolean active);

View File

@ -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

View File

@ -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();

View File

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

View File

@ -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)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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:

View File

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

View File

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

View File

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

View File

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