Skip to content

Commit

Permalink
Add CubeEntityRenderer
Browse files Browse the repository at this point in the history
  • Loading branch information
squid233 committed Jul 30, 2024
1 parent c789cd5 commit 1eb0250
Show file tree
Hide file tree
Showing 20 changed files with 272 additions and 82 deletions.
133 changes: 72 additions & 61 deletions modules/freeworld.client/src/main/java/freeworld/client/Freeworld.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
import freeworld.client.render.screen.Screen;
import freeworld.client.render.screen.ingame.CreativeTabScreen;
import freeworld.client.render.screen.ingame.PauseScreen;
import freeworld.client.render.world.BlockHitResult;
import freeworld.client.render.world.entity.EntityRenderers;
import freeworld.world.block.BlockHitResult;
import freeworld.client.render.world.WorldRenderer;
import freeworld.math.Vector2d;
import freeworld.math.Vector3d;
Expand Down Expand Up @@ -124,11 +125,6 @@ public void start() {

BlockTypes.bootstrap();
EntityTypes.bootstrap();

blockModelManager = new BlockModelManager();
blockModelManager.bootstrap();

setScreen(new PauseScreen(this));
world = new World("New world", new Random().nextLong());
player = world.createEntity(EntityTypes.PLAYER, new Vector3d(0.0, 64.0, 0.0));

Expand Down Expand Up @@ -236,65 +232,73 @@ private void onScroll(double x, double y) {
}
}

private void worldInput() {
double speed;
if (player.flying()) {
speed = 0.5; // TODO: this value is only for test
} else {
if (player.onGround()) {
speed = 0.1;
} else {
speed = 0.02;
}
}
if (glfw.getKey(window, GLFW.KEY_LEFT_CONTROL) == GLFW.PRESS) speed *= 2.0;
double xo = 0.0;
double yo = 0.0;
double zo = 0.0;
if (glfw.getKey(window, GLFW.KEY_W) == GLFW.PRESS) zo -= 1.0;
if (glfw.getKey(window, GLFW.KEY_S) == GLFW.PRESS) zo += 1.0;
if (glfw.getKey(window, GLFW.KEY_A) == GLFW.PRESS) xo -= 1.0;
if (glfw.getKey(window, GLFW.KEY_D) == GLFW.PRESS) xo += 1.0;
if ((player.onGround() || player.flying()) && glfw.getKey(window, GLFW.KEY_SPACE) == GLFW.PRESS) {
yo += 1.0;
}
if (player.flying() && glfw.getKey(window, GLFW.KEY_LEFT_SHIFT) == GLFW.PRESS) {
yo -= 1.0;
}
player.acceleration = MathUtil.moveRelative(xo, yo * (player.flying() ? speed : 0.5), zo, player.rotation().y(), speed);

if (blockDestroyTimer >= 2) {
final BlockHitResult hitResult = gameRenderer.hitResult();
if (!hitResult.missed() &&
glfw.getMouseButton(window, GLFW.MOUSE_BUTTON_LEFT) == GLFW.PRESS) {
Vector3i position = hitResult.position();
world.setBlockType(position.x(), position.y(), position.z(), BlockTypes.AIR);
blockDestroyTimer = 0;
}
}
if (blockPlaceTimer >= 2) {
final BlockHitResult hitResult = gameRenderer.hitResult();
if (!hitResult.missed() &&
glfw.getMouseButton(window, GLFW.MOUSE_BUTTON_RIGHT) == GLFW.PRESS) {
final Direction face = hitResult.face();
final BlockType type = player.getHandItem();
if (!type.air()) {
Vector3i axis = face.axis();
Vector3i position = hitResult.position();
Vector3i add = position.add(axis);
if (world.getBlockType(position.x(), position.y(), position.z()).replaceable() ||
world.getBlockType(add.x(), add.y(), add.z()).replaceable()) {
world.setBlockType(add.x(), add.y(), add.z(), type);
}
}
blockPlaceTimer = 0;
}
}
blockDestroyTimer++;
blockPlaceTimer++;

if (glfw.getKey(window, GLFW.KEY_G) == GLFW.PRESS) {
world.createEntity(EntityTypes.CUBE, player.position());
}
}

private void tick() {
if (world != null) {
camera.preUpdate();
if (screen == null) {
double speed;
if (player.flying()) {
speed = 0.5; // TODO: this value is only for test
} else {
if (player.onGround()) {
speed = 0.1;
} else {
speed = 0.02;
}
}
if (glfw.getKey(window, GLFW.KEY_LEFT_CONTROL) == GLFW.PRESS) speed *= 2.0;
double xo = 0.0;
double yo = 0.0;
double zo = 0.0;
if (glfw.getKey(window, GLFW.KEY_W) == GLFW.PRESS) zo -= 1.0;
if (glfw.getKey(window, GLFW.KEY_S) == GLFW.PRESS) zo += 1.0;
if (glfw.getKey(window, GLFW.KEY_A) == GLFW.PRESS) xo -= 1.0;
if (glfw.getKey(window, GLFW.KEY_D) == GLFW.PRESS) xo += 1.0;
if ((player.onGround() || player.flying()) && glfw.getKey(window, GLFW.KEY_SPACE) == GLFW.PRESS) {
yo += 1.0;
}
if (player.flying() && glfw.getKey(window, GLFW.KEY_LEFT_SHIFT) == GLFW.PRESS) {
yo -= 1.0;
}
player.acceleration = MathUtil.moveRelative(xo, yo * (player.flying() ? speed : 0.5), zo, player.rotation().y(), speed);

if (blockDestroyTimer >= 2) {
final BlockHitResult hitResult = gameRenderer.hitResult();
if (!hitResult.missed() &&
glfw.getMouseButton(window, GLFW.MOUSE_BUTTON_LEFT) == GLFW.PRESS) {
Vector3i position = hitResult.position();
world.setBlockType(position.x(), position.y(), position.z(), BlockTypes.AIR);
blockDestroyTimer = 0;
}
}
if (blockPlaceTimer >= 2) {
final BlockHitResult hitResult = gameRenderer.hitResult();
if (!hitResult.missed() &&
glfw.getMouseButton(window, GLFW.MOUSE_BUTTON_RIGHT) == GLFW.PRESS) {
final Direction face = hitResult.face();
final BlockType type = player.getHandItem();
if (!type.air()) {
Vector3i axis = face.axis();
Vector3i position = hitResult.position();
Vector3i add = position.add(axis);
if (world.getBlockType(position.x(), position.y(), position.z()).replaceable() ||
world.getBlockType(add.x(), add.y(), add.z()).replaceable()) {
world.setBlockType(add.x(), add.y(), add.z(), type);
}
}
blockPlaceTimer = 0;
}
}
blockDestroyTimer++;
blockPlaceTimer++;
worldInput();
}
world.tick();
}
Expand All @@ -310,8 +314,15 @@ private void initGL() {

RenderSystem.initialize(gl);

blockModelManager = new BlockModelManager();
blockModelManager.bootstrap();

EntityRenderers.bootstrap();

gameRenderer = new GameRenderer(this);
gameRenderer.init(gl);

setScreen(new PauseScreen(this));
}

public void run() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,18 @@
import freeworld.client.render.texture.TextureManager;
import freeworld.client.render.vertex.VertexLayout;
import freeworld.client.render.vertex.VertexLayouts;
import freeworld.client.render.world.BlockHitResult;
import freeworld.client.render.world.BlockRenderer;
import freeworld.client.render.world.WorldRenderer;
import freeworld.client.render.world.block.BlockRenderer;
import freeworld.client.render.world.entity.EntityRenderers;
import freeworld.client.world.chunk.ClientChunk;
import freeworld.util.Identifier;
import freeworld.math.Matrix4f;
import freeworld.math.Vector3i;
import freeworld.registry.Registries;
import freeworld.util.Direction;
import freeworld.util.Identifier;
import freeworld.util.Logging;
import freeworld.util.math.Lined;
import freeworld.world.block.BlockHitResult;
import freeworld.world.entity.Entity;
import org.slf4j.Logger;
import overrungl.opengl.GL10C;
Expand Down Expand Up @@ -194,6 +196,20 @@ private void renderWorld(GLStateMgr gl, double partialTick) {
}
tessellator.end(gl);
}

renderWorldEntities(gl, partialTick);
}

private void renderWorldEntities(GLStateMgr gl, double partialTick) {
RenderSystem.useProgram(positionColorProgram);
RenderSystem.updateMatrices();
for (Entity entity : client.world().entities()) {
entity.interpolatePosition(partialTick);
var factory = EntityRenderers.registry().getById(Registries.ENTITY_TYPE.getId(entity.entityType()));
if (factory != null) {
factory.create(client).render(gl, partialTick, Matrix4f.translation(entity.interpolatedPosition().toVector3f()), entity);
}
}
}

private void renderHud(GLStateMgr gl, double partialTick) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public void bootstrap() {
}

public BlockModel get(Identifier identifier) {
return registry.get(identifier);
return registry.getById(identifier);
}

public DefaultedRegistry<BlockModel> registry() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import freeworld.util.math.HitResult;
import freeworld.world.World;
import freeworld.world.WorldListener;
import freeworld.world.block.BlockHitResult;
import freeworld.world.block.BlockType;
import freeworld.world.entity.Entity;
import org.slf4j.Logger;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* only version 2.1 of the License.
*/

package freeworld.client.render.world;
package freeworld.client.render.world.block;

import freeworld.client.render.model.block.BlockModel;
import freeworld.client.render.model.block.BlockModelFace;
Expand Down Expand Up @@ -47,6 +47,7 @@ private void emitVertices(VertexBuilder builder, Matrix4f matrix, Vector3f from,
case NORTH, SOUTH -> 0.8f;
};
Vector4i vertexIndices = direction.vertexIndices();
builder.indices(0, 1, 2, 2, 3, 0);
builder.position(matrix, AABBox.getPoint(from, to, vertexIndices.x())).color(color, color, color).texCoord(uvFrom.x(), uvFrom.y()).emit();
builder.position(matrix, AABBox.getPoint(from, to, vertexIndices.y())).color(color, color, color).texCoord(uvFrom.x(), uvTo.y()).emit();
builder.position(matrix, AABBox.getPoint(from, to, vertexIndices.z())).color(color, color, color).texCoord(uvTo.x(), uvTo.y()).emit();
Expand All @@ -73,7 +74,6 @@ public void renderBlockModel(VertexBuilder builder, BlockModel model, Matrix4f m
final Vector2f uvFrom = face.uvFrom().mul(region.width(), region.height()).add(region.x(), region.y()).div(width, height);
final Vector2f uvTo = face.uvTo().mul(region.width(), region.height()).add(region.x(), region.y()).div(width, height);

builder.indices(0, 1, 2, 2, 3, 0);
emitVertices(builder, matrix, from, to, uvFrom, uvTo, e.getKey());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
* only version 2.1 of the License.
*/

package freeworld.client.render.world;
package freeworld.client.render.world.chunk;

import freeworld.client.render.vertex.VertexBuilder;
import freeworld.client.render.model.block.BlockModel;
import freeworld.client.render.model.block.BlockModelManager;
import freeworld.client.render.world.block.BlockRenderer;
import freeworld.client.world.chunk.ChunkVertexData;
import freeworld.registry.Registries;
import freeworld.math.Vector3i;
import freeworld.world.chunk.Chunk;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* freeworld - 3D sandbox game
* Copyright (C) 2024 XenFork Union
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* only version 2.1 of the License.
*/

package freeworld.client.render.world.entity;

import freeworld.client.Freeworld;
import freeworld.client.render.RenderSystem;
import freeworld.client.render.Tessellator;
import freeworld.client.render.gl.GLDrawMode;
import freeworld.client.render.gl.GLStateMgr;
import freeworld.math.Matrix4f;
import freeworld.world.entity.CubeEntity;

/**
* @author squid233
* @since 0.1.0
*/
public class CubeEntityRenderer extends EntityRenderer<CubeEntity> {
public CubeEntityRenderer(Freeworld client) {
super(client);
}

@Override
public void render(GLStateMgr gl, double partialTick, Matrix4f positionMatrix, CubeEntity entity) {
RenderSystem.useProgram(client.gameRenderer().positionColorProgram());
Tessellator t = Tessellator.getInstance();
t.begin(GLDrawMode.TRIANGLES);

// +z
t.indices(0, 1, 2, 2, 3, 0);
t.position(positionMatrix, 0.0f, 1.0f, 1.0f).color(0, 148, 255).texCoord(0, 0).emit();
t.position(positionMatrix, 0.0f, 0.0f, 1.0f).color(0, 148, 255).texCoord(0, 0).emit();
t.position(positionMatrix, 1.0f, 0.0f, 1.0f).color(0, 148, 255).texCoord(0, 0).emit();
t.position(positionMatrix, 1.0f, 1.0f, 1.0f).color(0, 148, 255).texCoord(0, 0).emit();

t.end(gl);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* freeworld - 3D sandbox game
* Copyright (C) 2024 XenFork Union
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* only version 2.1 of the License.
*/

package freeworld.client.render.world.entity;

import freeworld.client.Freeworld;
import freeworld.client.render.gl.GLStateMgr;
import freeworld.math.Matrix4f;
import freeworld.world.entity.Entity;

/**
* @author squid233
* @since 0.1.0
*/
public abstract class EntityRenderer<T extends Entity> {
protected final Freeworld client;

protected EntityRenderer(Freeworld client) {
this.client = client;
}

public interface Factory<T extends Entity> {
EntityRenderer<T> create(Freeworld client);
}

public abstract void render(GLStateMgr gl, double partialTick, Matrix4f positionMatrix, T entity);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* freeworld - 3D sandbox game
* Copyright (C) 2024 XenFork Union
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* only version 2.1 of the License.
*/

package freeworld.client.render.world.entity;

import freeworld.registry.MappedRegistry;
import freeworld.registry.Registries;
import freeworld.registry.Registry;
import freeworld.util.Identifier;
import freeworld.world.entity.Entity;
import freeworld.world.entity.EntityType;
import freeworld.world.entity.EntityTypes;

/**
* @author squid233
* @since 0.1.0
*/
public final class EntityRenderers {
private static final MappedRegistry<EntityRenderer.Factory<Entity>> REGISTRY = new MappedRegistry<>(Identifier.ofBuiltin("entity_renderer"));

private EntityRenderers() {
}

public static void bootstrap() {
register(EntityTypes.CUBE, CubeEntityRenderer::new);
}

public static <T extends Entity> void register(EntityType<T> entityType, EntityRenderer.Factory<T> renderer) {
Registry.register(REGISTRY, Registries.ENTITY_TYPE.getId(entityType), (EntityRenderer.Factory<Entity>) renderer);
}

public static Registry<EntityRenderer.Factory<Entity>> registry() {
return REGISTRY;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* only version 2.1 of the License.
*/

package freeworld.client.render.world;
package freeworld.client.world.chunk;

import freeworld.client.render.vertex.VertexLayout;

Expand Down
Loading

0 comments on commit 1eb0250

Please sign in to comment.