Added better model shading, and visually stretched bullets for fancier appearance.

This commit is contained in:
Andrew Lalis 2022-07-25 16:37:28 +02:00
parent 4e0e1a32fa
commit 90c9ae22e8
8 changed files with 79 additions and 25 deletions

View File

@ -3,6 +3,7 @@ package nl.andrewl.aos2_client.model;
import nl.andrewl.aos2_client.Camera;
import nl.andrewl.aos_core.model.Player;
import nl.andrewl.aos_core.model.item.Inventory;
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import java.util.ArrayList;
@ -14,6 +15,9 @@ public class ClientPlayer extends Player {
private final Matrix4f heldItemTransform = new Matrix4f();
private final float[] heldItemTransformData = new float[16];
private final Matrix3f heldItemNormalTransform = new Matrix3f();
private final float[] heldItemNormalTransformData = new float[9];
public ClientPlayer(int id, String username) {
super(id, username);
this.health = 1;
@ -45,9 +49,16 @@ public class ClientPlayer extends Player {
.rotate(-cam.getOrientation().y + (float) Math.PI / 2, Camera.RIGHT)
.translate(-0.35f, -0.4f, 0.5f);
heldItemTransform.get(heldItemTransformData);
heldItemTransform.normal(heldItemNormalTransform);
heldItemNormalTransform.get(heldItemNormalTransformData);
}
public float[] getHeldItemTransformData() {
return heldItemTransformData;
}
public float[] getHeldItemNormalTransformData() {
return heldItemNormalTransformData;
}
}

View File

@ -3,6 +3,7 @@ package nl.andrewl.aos2_client.model;
import nl.andrewl.aos2_client.Camera;
import nl.andrewl.aos_core.model.Player;
import nl.andrewl.aos_core.model.item.ItemTypes;
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import org.joml.Vector3f;
@ -22,14 +23,15 @@ public class OtherPlayer extends Player {
*/
private byte selectedBlockValue;
/**
* The transformation used to render this player in the world.
*/
private final Matrix4f modelTransform = new Matrix4f();
private final float[] modelTransformData = new float[16];
private final Matrix3f normalTransform = new Matrix3f();
private final float[] normalTransformData = new float[9];
private final Matrix4f heldItemTransform = new Matrix4f();
private final float[] heldItemTransformData = new float[16];
private final Matrix3f heldItemNormalTransform = new Matrix3f();
private final float[] heldItemNormalTransformData = new float[9];
public OtherPlayer(int id, String username) {
super(id, username);
@ -61,17 +63,32 @@ public class OtherPlayer extends Player {
.translate(position)
.rotate(orientation.x, Camera.UP);
modelTransform.get(modelTransformData);
modelTransform.normal(normalTransform);
normalTransform.get(normalTransformData);
heldItemTransform.set(modelTransform)
.translate(0.5f, 1.1f, -0.5f)
.rotate((float) Math.PI, Camera.UP);
heldItemTransform.get(heldItemTransformData);
heldItemTransform.normal(heldItemNormalTransform);
heldItemNormalTransform.get(heldItemNormalTransformData);
}
public float[] getModelTransformData() {
return modelTransformData;
}
public float[] getNormalTransformData() {
return normalTransformData;
}
public float[] getHeldItemTransformData() {
return heldItemTransformData;
}
public float[] getHeldItemNormalTransformData() {
return heldItemNormalTransformData;
}
}

View File

@ -3,6 +3,7 @@ package nl.andrewl.aos2_client.render;
import nl.andrewl.aos2_client.Camera;
import nl.andrewl.aos2_client.Client;
import nl.andrewl.aos2_client.config.ClientConfig;
import nl.andrewl.aos2_client.model.ClientPlayer;
import nl.andrewl.aos2_client.render.chunk.ChunkRenderer;
import nl.andrewl.aos2_client.render.gui.GUIRenderer;
import nl.andrewl.aos2_client.render.gui.GUITexture;
@ -11,10 +12,12 @@ import nl.andrewl.aos_core.model.item.BlockItemStack;
import nl.andrewl.aos_core.model.item.Gun;
import nl.andrewl.aos_core.model.item.GunItemStack;
import nl.andrewl.aos_core.model.item.ItemTypes;
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GLUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -184,9 +187,11 @@ public class GameRenderer {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
chunkRenderer.draw(camera, client.getWorld().getChunkMeshesToDraw());
ClientPlayer myPlayer = client.getMyPlayer();
// Draw models. Use one texture at a time for efficiency.
modelRenderer.start(camera.getViewTransformData());
client.getMyPlayer().updateHeldItemTransform(camera);
myPlayer.updateHeldItemTransform(camera);
playerModel.bind();
for (var player : client.getPlayers().values()) {
@ -195,17 +200,17 @@ public class GameRenderer {
} else {
modelRenderer.setAspectColor(new Vector3f(0.3f, 0.3f, 0.3f));
}
modelRenderer.render(playerModel, player.getModelTransformData());
modelRenderer.render(playerModel, player.getModelTransformData(), player.getNormalTransformData());
}
playerModel.unbind();
rifleModel.bind();
if (client.getMyPlayer().getInventory().getSelectedItemStack().getType().getId() == ItemTypes.RIFLE.getId()) {
modelRenderer.render(rifleModel, client.getMyPlayer().getHeldItemTransformData());
if (myPlayer.getInventory().getSelectedItemStack().getType().getId() == ItemTypes.RIFLE.getId()) {
modelRenderer.render(rifleModel, myPlayer.getHeldItemTransformData(), myPlayer.getHeldItemNormalTransformData());
}
for (var player : client.getPlayers().values()) {
if (player.getHeldItemId() == ItemTypes.RIFLE.getId()) {
modelRenderer.render(rifleModel, player.getHeldItemTransformData());
modelRenderer.render(rifleModel, player.getHeldItemTransformData(), player.getHeldItemNormalTransformData());
}
}
rifleModel.unbind();
@ -214,23 +219,26 @@ public class GameRenderer {
if (client.getMyPlayer().getInventory().getSelectedItemStack().getType().getId() == ItemTypes.BLOCK.getId()) {
BlockItemStack stack = (BlockItemStack) client.getMyPlayer().getInventory().getSelectedItemStack();
modelRenderer.setAspectColor(client.getWorld().getPalette().getColor(stack.getSelectedValue()));
modelRenderer.render(blockModel, client.getMyPlayer().getHeldItemTransformData());
modelRenderer.render(blockModel, myPlayer.getHeldItemTransformData(), myPlayer.getHeldItemNormalTransformData());
}
modelRenderer.setAspectColor(new Vector3f(0.5f, 0.5f, 0.5f));
for (var player : client.getPlayers().values()) {
if (player.getHeldItemId() == ItemTypes.BLOCK.getId()) {
modelRenderer.render(blockModel, player.getHeldItemTransformData());
modelRenderer.render(blockModel, player.getHeldItemTransformData(), player.getHeldItemNormalTransformData());
}
}
blockModel.unbind();
bulletModel.bind();
Matrix4f projectileTransform = new Matrix4f();
Matrix3f projectileNormalTransform = new Matrix3f();
for (var projectile : client.getProjectiles().values()) {
projectileTransform.identity()
.translate(projectile.getPosition())
.rotateTowards(projectile.getVelocity(), Camera.UP);
modelRenderer.render(bulletModel, projectileTransform);
.rotateTowards(projectile.getVelocity(), Camera.UP)
.scale(1, 1, projectile.getVelocity().length() / 5);
projectileTransform.normal(projectileNormalTransform);
modelRenderer.render(bulletModel, projectileTransform, projectileNormalTransform);
}
bulletModel.unbind();

View File

@ -1,6 +1,7 @@
package nl.andrewl.aos2_client.render;
import nl.andrewl.aos2_client.render.model.Model;
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import org.joml.Vector3f;
@ -14,6 +15,7 @@ public class ModelRenderer {
private final int projectionUniform;
private final int viewUniform;
private final int modelUniform;
private final int normalUniform;
private final int textureSamplerUniform;
private final int colorUniform;
@ -22,10 +24,11 @@ public class ModelRenderer {
.withShader("shader/model/vertex.glsl", GL_VERTEX_SHADER)
.withShader("shader/model/fragment.glsl", GL_FRAGMENT_SHADER)
.build();
// System.out.println(glGetProgramInfoLog(shaderProgram.getId())); // Enable for debugging!
System.out.println(glGetProgramInfoLog(shaderProgram.getId())); // Enable for debugging!
projectionUniform = shaderProgram.getUniform("projectionTransform");
viewUniform = shaderProgram.getUniform("viewTransform");
modelUniform = shaderProgram.getUniform("modelTransform");
normalUniform = shaderProgram.getUniform("normalTransform");
colorUniform = shaderProgram.getUniform("aspectColor");
textureSamplerUniform = shaderProgram.getUniform("textureSampler");
}
@ -46,13 +49,15 @@ public class ModelRenderer {
glUniform3f(colorUniform, color.x, color.y, color.z);
}
public void render(Model model, Matrix4f modelTransform) {
public void render(Model model, Matrix4f modelTransform, Matrix3f normalTransform) {
glUniformMatrix4fv(modelUniform, false, modelTransform.get(new float[16]));
glUniformMatrix3fv(normalUniform, false, normalTransform.get(new float[16]));
model.draw();
}
public void render(Model model, float[] transformData) {
public void render(Model model, float[] transformData, float[] normalData) {
glUniformMatrix4fv(modelUniform, false, transformData);
glUniformMatrix3fv(normalUniform, false, normalData);
model.draw();
}

View File

@ -19,6 +19,7 @@ public class GUIRenderer {
private final int vertexCount;
private final ShaderProgram shaderProgram;
private final int transformUniformLocation;
private final int textureSamplerUniform;
private final Matrix4f transformMatrix;
private final float[] transformMatrixData;
@ -47,6 +48,7 @@ public class GUIRenderer {
.withShader("shader/gui/fragment.glsl", GL_FRAGMENT_SHADER)
.build();
transformUniformLocation = shaderProgram.getUniform("transform");
textureSamplerUniform = shaderProgram.getUniform("guiTexture");
shaderProgram.bindAttribute(0, "position");
this.transformMatrix = new Matrix4f();
this.transformMatrixData = new float[16];
@ -67,6 +69,7 @@ public class GUIRenderer {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_DEPTH_TEST);
glUniform1i(textureSamplerUniform, 0);
}
public void draw(String name, float scaleX, float scaleY, float x, float y) {

View File

@ -0,0 +1,6 @@
package nl.andrewl.aos2_client.render.model;
public interface ModelRenderable {
float[] getModelTransformData();
float[] getNormalTransformData();
}

View File

@ -1,7 +1,7 @@
#version 460 core
in vec2 textureCoords;
in vec3 vertexNormal;
in vec3 vertexColor;
out vec4 fragmentColor;
@ -14,12 +14,7 @@ void main() {
if (baseColor == templateColor) {
baseColor = vec4(aspectColor, 1.0);
}
vec3 lightDirection = normalize(vec3(0.5, -1.0, -0.5));// TODO: Add this via a uniform.
vec3 lightColor = vec3(1.0, 1.0, 0.9); // TODO: Add this via a uniform.
vec3 ambientComponent = vec3(0.1, 0.1, 0.1);
vec3 diffuseComponent = max(dot(vertexNormal * -1, lightDirection), 0.0) * lightColor;
// TODO: Add shading based on light.
// fragmentColor = vec4((ambientComponent + diffuseComponent), 1.0) * baseColor;
fragmentColor = baseColor;
fragmentColor = vec4(vertexColor * vec3(baseColor), 1.0);
}

View File

@ -7,12 +7,21 @@ layout (location = 2) in vec2 textureCoordsIn;
uniform mat4 projectionTransform;
uniform mat4 viewTransform;
uniform mat4 modelTransform;
uniform mat3 normalTransform;
out vec2 textureCoords;
out vec3 vertexNormal;
out vec3 vertexColor;
void main() {
gl_Position = projectionTransform * viewTransform * modelTransform * vec4(vertexPositionIn, 1.0);
vertexNormal = vec3(modelTransform * vec4(vertexNormalIn, 1.0));
vec3 vertexNormal = normalize(normalTransform * vertexNormalIn);
textureCoords = textureCoordsIn;
vec3 lightDirection = normalize(vec3(0.5, -1.0, -0.5));// TODO: Add this via a uniform.
vec3 lightColor = vec3(1.0, 1.0, 0.9); // TODO: Add this via a uniform.
float ambientComponent = 0.1;
float diffuseComponent = max(dot(-vertexNormal, lightDirection), 0.0);
vertexColor = (ambientComponent + diffuseComponent) * lightColor;
}