Skip to content

Commit

Permalink
Update vertex layout
Browse files Browse the repository at this point in the history
  • Loading branch information
squid233 committed Mar 17, 2024
1 parent 09ac1b4 commit a595c83
Show file tree
Hide file tree
Showing 9 changed files with 184 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public final class Freeworld implements AutoCloseable {
private static final Logger logger = Logging.caller();
private static final int INIT_WINDOW_WIDTH = 854;
private static final int INIT_WINDOW_HEIGHT = 480;
private static final double MOUSE_SENSITIVITY = 0.15;
private final GLFW glfw;
private GLFlags glFlags;
private GLStateMgr gl;
Expand All @@ -57,6 +58,7 @@ public final class Freeworld implements AutoCloseable {
private double cursorY;
private double cursorDeltaX;
private double cursorDeltaY;
private boolean disableCursor = false;
private GameRenderer gameRenderer;
private World world;
private Entity player;
Expand Down Expand Up @@ -87,11 +89,12 @@ public void start() {
glfw.windowHint(GLFW.POSITION_Y, (videoMode.height() - INIT_WINDOW_HEIGHT) / 2);
}

window = glfw.createWindow(INIT_WINDOW_WIDTH, INIT_WINDOW_HEIGHT, "freeworld", MemorySegment.NULL, MemorySegment.NULL);
window = glfw.createWindow(INIT_WINDOW_WIDTH, INIT_WINDOW_HEIGHT, "freeworld ~: toggle camera", MemorySegment.NULL, MemorySegment.NULL);
if (Unmarshal.isNullPointer(window)) {
throw new IllegalStateException("Failed to create GLFW window");
}

glfw.setKeyCallback(window, (_, key, scancode, action, mods) -> onKey(key, scancode, action, mods));
glfw.setFramebufferSizeCallback(window, (_, width, height) -> onResize(width, height));
glfw.setCursorPosCallback(window, (_, xpos, ypos) -> onCursorPos(xpos, ypos));

Expand All @@ -115,6 +118,19 @@ public void start() {
logger.info("Closing client");
}

private void onKey(int key, int scancode, int action, int mods) {
switch (action) {
case GLFW.RELEASE -> {
switch (key) {
case GLFW.KEY_GRAVE_ACCENT -> {
disableCursor = !disableCursor;
glfw.setInputMode(window, GLFW.CURSOR, disableCursor ? GLFW.CURSOR_DISABLED : GLFW.CURSOR_NORMAL);
}
}
}
}
}

private void onResize(int width, int height) {
framebufferWidth = width;
framebufferHeight = height;
Expand All @@ -124,8 +140,8 @@ private void onResize(int width, int height) {
private void onCursorPos(double x, double y) {
cursorDeltaX = x - cursorX;
cursorDeltaY = y - cursorY;
if (glfw.getMouseButton(window, GLFW.MOUSE_BUTTON_RIGHT) == GLFW.PRESS) {
camera.rotate(-cursorDeltaY * 0.7, -cursorDeltaX * 0.7);
if (disableCursor) {
camera.rotate(-cursorDeltaY * MOUSE_SENSITIVITY, -cursorDeltaX * MOUSE_SENSITIVITY);
}
cursorX = x;
cursorY = y;
Expand Down Expand Up @@ -164,6 +180,7 @@ public void run() {
tick();
}
gameRenderer.render(gl, timer.partialTick());
glfw.swapBuffers(window);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
package io.github.xenfork.freeworld.client.render;

import io.github.xenfork.freeworld.client.Freeworld;
import io.github.xenfork.freeworld.client.render.gl.GLDrawMode;
import io.github.xenfork.freeworld.client.render.gl.GLProgram;
import io.github.xenfork.freeworld.client.render.gl.GLResource;
import io.github.xenfork.freeworld.client.render.gl.GLStateMgr;
Expand Down Expand Up @@ -48,6 +49,7 @@ public final class GameRenderer implements GLResource {
private TextureManager textureManager;
private BlockRenderer blockRenderer;
private WorldRenderer worldRenderer;
private Tessellator tessellator;

public GameRenderer(Freeworld client) {
this.client = client;
Expand All @@ -68,6 +70,8 @@ public void init(GLStateMgr gl) {

blockRenderer = new BlockRenderer(this);
worldRenderer = new WorldRenderer(client, this, client.world());

tessellator = new Tessellator();
}

private void initGLPrograms(GLStateMgr gl) {
Expand All @@ -87,13 +91,13 @@ private GLProgram initBootstrapProgram(GLStateMgr gl, String path, VertexLayout
public void render(GLStateMgr gl, double partialTick) {
gl.clear(GL10C.COLOR_BUFFER_BIT | GL10C.DEPTH_BUFFER_BIT);

gl.enable(GL10C.CULL_FACE);
gl.enable(GL10C.DEPTH_TEST);
gl.depthFunc(GL10C.LEQUAL);
gl.enableCullFace();
gl.enableDepthTest();
gl.setDepthFunc(GL10C.LEQUAL);
texture.bind(gl);
positionColorTexProgram.use(gl);
projectionView.setPerspective(
(float) Math.toRadians(90.0),
(float) Math.toRadians(70.0),
(float) client.framebufferWidth() / client.framebufferHeight(),
0.01f,
1000.0f
Expand All @@ -102,12 +106,43 @@ public void render(GLStateMgr gl, double partialTick) {
camera.updateLerp(partialTick);
camera.updateViewMatrix();
projectionView.mul(camera.viewMatrix());
matrix.identity();
positionColorTexProgram.getUniform(GLProgram.UNIFORM_PROJECTION_VIEW_MATRIX).set(projectionView);
positionColorTexProgram.getUniform(GLProgram.UNIFORM_MODEL_MATRIX).set(matrix);
positionColorTexProgram.uploadUniforms(gl);
worldRenderer.render(gl);
worldRenderer.render(gl, tessellator);

renderGui(gl, partialTick);
}

client.glfw().swapBuffers(client.window());
private void renderGui(GLStateMgr gl, double partialTick) {
final int width = client.framebufferWidth();
final int height = client.framebufferHeight();

gl.clear(GL10C.DEPTH_BUFFER_BIT);

gl.disableCullFace();
gl.disableDepthTest();
gl.setTextureBinding2D(0);
positionColorProgram.use(gl);
projectionView.setOrtho(0.0f, width, 0.0f, height, -100.0f, 100.0f);
matrix.translation(width * 0.5f, height * 0.5f, 0.0f);
positionColorProgram.getUniform(GLProgram.UNIFORM_PROJECTION_VIEW_MATRIX).set(projectionView);
positionColorProgram.getUniform(GLProgram.UNIFORM_MODEL_MATRIX).set(matrix);
positionColorProgram.uploadUniforms(gl);
tessellator.begin(GLDrawMode.TRIANGLES);
tessellator.color(1.0f, 1.0f, 1.0f);
tessellator.index(gl, 0, 1, 2, 2, 3, 0);
tessellator.position(-8, 1, 0).emit(gl);
tessellator.position(-8, -1, 0).emit(gl);
tessellator.position(8, -1, 0).emit(gl);
tessellator.position(8, 1, 0).emit(gl);
tessellator.index(gl, 0, 1, 2, 2, 3, 0);
tessellator.position(1, 8, 0).emit(gl);
tessellator.position(1, -8, 0).emit(gl);
tessellator.position(-1, -8, 0).emit(gl);
tessellator.position(-1, 8, 0).emit(gl);
tessellator.end(gl);
}

@Override
Expand All @@ -119,7 +154,7 @@ public void close(GLStateMgr gl) {
if (positionColorProgram != null) positionColorProgram.close(gl);
if (positionColorTexProgram != null) positionColorTexProgram.close(gl);

Tessellator.free(gl);
if (tessellator != null) tessellator.close(gl);
}

public GLProgram positionColorProgram() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
package io.github.xenfork.freeworld.client.render;

import io.github.xenfork.freeworld.client.render.gl.GLDrawMode;
import io.github.xenfork.freeworld.client.render.gl.GLResource;
import io.github.xenfork.freeworld.client.render.gl.GLStateMgr;
import io.github.xenfork.freeworld.client.render.model.VertexFormat;
import io.github.xenfork.freeworld.client.render.model.VertexLayout;
import io.github.xenfork.freeworld.client.render.model.VertexLayouts;
import overrungl.opengl.GL10C;
Expand All @@ -32,47 +34,51 @@
* @author squid233
* @since 0.1.0
*/
public final class Tessellator {
public final class Tessellator implements GLResource {
private static final int MAX_VERTEX_COUNT = 60000;
private static final int MAX_INDEX_COUNT = 90000;
private static final VertexLayout VERTEX_LAYOUT = VertexLayouts.POSITION_COLOR_TEX;
private static final StructLayout LAYOUT = VERTEX_LAYOUT.layout();
private static final String POSITION_NAME = VertexFormat.POSITION.name();
private static final String COLOR_NAME = VertexFormat.COLOR.name();
private static final String UV_NAME = VertexFormat.UV.name();
private static final VarHandle X = LAYOUT.arrayElementVarHandle(
PathElement.groupElement(VertexLayouts.NAME_POSITION),
PathElement.groupElement(POSITION_NAME),
PathElement.sequenceElement(0L)
);
private static final VarHandle Y = LAYOUT.arrayElementVarHandle(
PathElement.groupElement(VertexLayouts.NAME_POSITION),
PathElement.groupElement(POSITION_NAME),
PathElement.sequenceElement(1L)
);
private static final VarHandle Z = LAYOUT.arrayElementVarHandle(
PathElement.groupElement(VertexLayouts.NAME_POSITION),
PathElement.groupElement(POSITION_NAME),
PathElement.sequenceElement(2L)
);
private static final VarHandle R = LAYOUT.arrayElementVarHandle(
PathElement.groupElement(VertexLayouts.NAME_COLOR),
PathElement.groupElement(COLOR_NAME),
PathElement.sequenceElement(0L)
);
private static final VarHandle G = LAYOUT.arrayElementVarHandle(
PathElement.groupElement(VertexLayouts.NAME_COLOR),
PathElement.groupElement(COLOR_NAME),
PathElement.sequenceElement(1L)
);
private static final VarHandle B = LAYOUT.arrayElementVarHandle(
PathElement.groupElement(VertexLayouts.NAME_COLOR),
PathElement.groupElement(COLOR_NAME),
PathElement.sequenceElement(2L)
);
private static final VarHandle A = LAYOUT.arrayElementVarHandle(
PathElement.groupElement(VertexLayouts.NAME_COLOR),
PathElement.groupElement(COLOR_NAME),
PathElement.sequenceElement(3L)
);
private static final VarHandle U = LAYOUT.arrayElementVarHandle(
PathElement.groupElement(VertexLayouts.NAME_UV),
PathElement.groupElement(UV_NAME),
PathElement.sequenceElement(0L)
);
private static final VarHandle V = LAYOUT.arrayElementVarHandle(
PathElement.groupElement(VertexLayouts.NAME_UV),
PathElement.groupElement(UV_NAME),
PathElement.sequenceElement(1L)
);
private final Arena arena;
private final MemorySegment buffer;
private final MemorySegment indexBuffer;
private int vertexCount = 0;
Expand All @@ -92,27 +98,10 @@ public final class Tessellator {
private float u = 0f;
private float v = 0f;

private Tessellator() {
final Arena arena = Arena.ofAuto();
buffer = arena.allocate(LAYOUT, MAX_VERTEX_COUNT);
indexBuffer = arena.allocate(ValueLayout.JAVA_INT, MAX_INDEX_COUNT);
}

/**
* @author squid233
* @since 0.1.0
*/
private static final class Holder {
private static final Tessellator INSTANCE = new Tessellator();
}

public static Tessellator getInstance() {
return Holder.INSTANCE;
}

public static void free(GLStateMgr gl) {
gl.deleteVertexArrays(Holder.INSTANCE.vao);
gl.deleteBuffers(Holder.INSTANCE.vbo, Holder.INSTANCE.ebo);
public Tessellator() {
this.arena = Arena.ofConfined();
this.buffer = arena.allocate(LAYOUT, MAX_VERTEX_COUNT);
this.indexBuffer = arena.allocate(ValueLayout.JAVA_INT, MAX_INDEX_COUNT);
}

public Tessellator position(float x, float y, float z) {
Expand Down Expand Up @@ -222,4 +211,11 @@ public void end(GLStateMgr gl) {
flush(gl);
drawing = false;
}

@Override
public void close(GLStateMgr gl) {
arena.close();
gl.deleteVertexArrays(vao);
gl.deleteBuffers(vbo, ebo);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ public abstract class GLStateMgr implements
GL41C,
DirectAccess {
private int arrayBufferBinding = 0;
private boolean cullFace = false;
private int currentProgram = 0;
private int depthFunc = LESS;
private boolean depthTest = false;
private int textureBinding2D = 0;
private int vertexArrayBinding = 0;

Expand All @@ -43,6 +46,27 @@ public int arrayBufferBinding() {
return arrayBufferBinding;
}

@Skip
public void enableCullFace() {
if (!this.cullFace) {
this.cullFace = true;
enable(CULL_FACE);
}
}

@Skip
public void disableCullFace() {
if (this.cullFace) {
this.cullFace = false;
disable(CULL_FACE);
}
}

@Skip
public boolean cullFace() {
return cullFace;
}

@Skip
public void setCurrentProgram(int currentProgram) {
if (this.currentProgram != currentProgram) {
Expand All @@ -56,6 +80,40 @@ public int currentProgram() {
return currentProgram;
}

@Skip
public void setDepthFunc(int depthFunc) {
if (this.depthFunc != depthFunc) {
this.depthFunc = depthFunc;
depthFunc(depthFunc);
}
}

@Skip
public int depthFunc() {
return depthFunc;
}

@Skip
public void enableDepthTest() {
if (!this.depthTest) {
this.depthTest = true;
enable(DEPTH_TEST);
}
}

@Skip
public void disableDepthTest() {
if (this.depthTest) {
this.depthTest = false;
disable(DEPTH_TEST);
}
}

@Skip
public boolean depthTest() {
return depthTest;
}

@Skip
public void setTextureBinding2D(int textureBinding2D) {
if (this.textureBinding2D != textureBinding2D) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
* @author squid233
* @since 0.1.0
*/
public record DefaultVertexFormat(int size, GLDataType type, boolean normalized) implements VertexFormat {
public record DefaultVertexFormat(String name, int size, GLDataType type, boolean normalized) implements VertexFormat {
@Override
public int usedAttribCount() {
return 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@
* @since 0.1.0
*/
public interface VertexFormat {
VertexFormat POSITION = new DefaultVertexFormat(3, GLDataType.FLOAT, false);
VertexFormat COLOR = new DefaultVertexFormat(4, GLDataType.UNSIGNED_BYTE, true);
VertexFormat UV = new DefaultVertexFormat(2, GLDataType.FLOAT, false);
VertexFormat POSITION = new DefaultVertexFormat("Position", 3, GLDataType.FLOAT, false);
VertexFormat COLOR = new DefaultVertexFormat("Color", 4, GLDataType.UNSIGNED_BYTE, true);
VertexFormat UV = new DefaultVertexFormat("UV", 2, GLDataType.FLOAT, false);

String name();

int size();

Expand Down
Loading

0 comments on commit a595c83

Please sign in to comment.