Added face culling state stack and disabled face culling for entities

This commit is contained in:
OLEGSHA 2020-09-05 23:26:54 +03:00
parent 9dc3154874
commit c613bef8c5
11 changed files with 146 additions and 49 deletions

View File

@ -26,8 +26,10 @@ public class TestEntityRenderJavapony extends EntityRender {
private final Renderable body; private final Renderable body;
private final Renderable head; private final Renderable head;
private final Renderable foreLeg; private final Renderable leftForeLeg;
private final Renderable hindLeg; private final Renderable leftHindLeg;
private final Renderable rightForeLeg;
private final Renderable rightHindLeg;
public TestEntityRenderJavapony() { public TestEntityRenderJavapony() {
super("Test", "Javapony"); super("Test", "Javapony");
@ -39,8 +41,10 @@ public class TestEntityRenderJavapony extends EntityRender {
this.body = createBody(texture); this.body = createBody(texture);
this.head = createHead(texture); this.head = createHead(texture);
this.foreLeg = createForeLeg(texture); this.leftForeLeg = createLeg(texture, 160, 0, true);
this.hindLeg = createHindLeg(texture); this.rightForeLeg = createLeg(texture, 160, 0, false);
this.leftHindLeg = createLeg(texture, 0, 0, true);
this.rightHindLeg = createLeg(texture, 0, 0, false);
} }
private static Renderable createBody(ComplexTexture texture) { private static Renderable createBody(ComplexTexture texture) {
@ -75,7 +79,7 @@ public class TestEntityRenderJavapony extends EntityRender {
) )
) )
.setOrigin(0, -8, 8) .setOrigin(0, -8, 8)
.setWidth(16).setDepth(16).setHeight(4, 0, 16) .setWidth(16).setDepth(16).setHeight(2, 0, 16)
.create() .create()
); );
@ -243,7 +247,7 @@ public class TestEntityRenderJavapony extends EntityRender {
// Left ear // Left ear
b.addPart(new PppBuilder( b.addPart(new PppBuilder(
program, texture.getCuboidTextures(48, 128-80, 8) program, texture.getCuboidTextures(48, 128-80, 8)
).setOrigin(-16 + 3, 16 - 8, 32).setSize(8).create()); ).setOrigin(-16 + 3, +16, 32).setSize(8, -8, 8).flip().create());
// Muzzle // Muzzle
b.addPart(new PppBuilder( b.addPart(new PppBuilder(
@ -255,7 +259,7 @@ public class TestEntityRenderJavapony extends EntityRender {
texture.get(32, 64, 0, 0), texture.get(32, 64, 0, 0),
texture.get(32, 64, 0, 0) texture.get(32, 64, 0, 0)
) )
).setOrigin(16, -8, 0).setSize(16, 4, 8).create()); ).setOrigin(16, -8, 0).setSize(4, 16, 8).create());
// Nose // Nose
b.addPart(new PppBuilder( b.addPart(new PppBuilder(
@ -267,23 +271,26 @@ public class TestEntityRenderJavapony extends EntityRender {
texture.get(32, 64, 0, 0), texture.get(32, 64, 0, 0),
texture.get(32, 64, 0, 0) texture.get(32, 64, 0, 0)
) )
).setOrigin(16, -4, 8).setSize(8, 4, 4).create()); ).setOrigin(16, -4, 8).setSize(4, 8, 4).create());
return new StaticModel(b); return new StaticModel(b);
} }
private static Renderable createForeLeg(ComplexTexture texture) { private static Renderable createLeg(
return new PppBuilder( ComplexTexture texture,
int textureX, int textureY,
boolean isLeft
) {
PppBuilder b = new PppBuilder(
WorldRenderProgram.getDefault(), WorldRenderProgram.getDefault(),
texture.getCuboidTextures(160, 0, 16, 48, 16) texture.getCuboidTextures(textureX, textureY, 16, 48, 16)
).setOrigin(-8, -8, -48).setSize(16, 16, 48).create(); )
} .setOrigin(-8, isLeft ? +8 : -8, -48)
.setSize(16, isLeft ? -16 : +16, 48);
private static Renderable createHindLeg(ComplexTexture texture) { if (isLeft) b.flip();
return new PppBuilder(
WorldRenderProgram.getDefault(), return b.create();
texture.getCuboidTextures(0, 0, 16, 48, 16)
).setOrigin(-8, -8, -48).setSize(16, 16, 48).create();
} }
private static Renderable createTail(ComplexTexture texture) { private static Renderable createTail(ComplexTexture texture) {
@ -312,12 +319,21 @@ public class TestEntityRenderJavapony extends EntityRender {
new QuadripedModel.Body(body), new QuadripedModel.Body(body),
new QuadripedModel.Head( new QuadripedModel.Head(
head, new Vec3(16, 0, 20), 60, 45 head, new Vec3(12, 0, 20), 60, 45
), ),
new QuadripedModel.Leg(foreLeg, new Vec3( 6, +8.1f, -16), 0.0f), new QuadripedModel.Leg(
new QuadripedModel.Leg(foreLeg, new Vec3( 6, -8.1f, -16), 2.5f), leftForeLeg, new Vec3( 6, +8.1f, -16), 0.0f
new QuadripedModel.Leg(hindLeg, new Vec3(-36, +8.2f, -16), 2.5f), ),
new QuadripedModel.Leg(hindLeg, new Vec3(-36, -8.2f, -16), 0.0f), new QuadripedModel.Leg(
rightForeLeg, new Vec3( 6, -8.1f, -16), 2.5f
),
new QuadripedModel.Leg(
leftHindLeg, new Vec3(-36, +8.2f, -16), 2.5f
),
new QuadripedModel.Leg(
rightHindLeg, new Vec3(-36, -8.2f, -16), 0.0f
),
1 / 96f 1 / 96f
); );
} }

View File

@ -0,0 +1,27 @@
package ru.windcorp.progressia.client.graphics.backend;
import java.util.ArrayDeque;
import java.util.Deque;
public class FaceCulling {
private static final Deque<Boolean> STACK = new ArrayDeque<>();
public static void push(boolean useFaceCulling) {
GraphicsBackend.setFaceCulling(useFaceCulling);
STACK.push(Boolean.valueOf(useFaceCulling));
}
public static void pop() {
STACK.pop();
if (STACK.isEmpty()) {
GraphicsBackend.setFaceCulling(false);
} else {
GraphicsBackend.setFaceCulling(STACK.getFirst());
}
}
private FaceCulling() {}
}

View File

@ -35,6 +35,8 @@ public class GraphicsBackend {
private static long framesRendered = 0; private static long framesRendered = 0;
private static double frameStart = Double.NaN; private static double frameStart = Double.NaN;
private static boolean faceCullingEnabled = false;
private GraphicsBackend() {} private GraphicsBackend() {}
public static void initialize() { public static void initialize() {
@ -110,4 +112,16 @@ public class GraphicsBackend {
glClear(GL_DEPTH_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT);
} }
public static void setFaceCulling(boolean useFaceCulling) {
if (useFaceCulling == faceCullingEnabled) return;
if (useFaceCulling) {
glEnable(GL_CULL_FACE);
} else {
glDisable(GL_CULL_FACE);
}
faceCullingEnabled = useFaceCulling;
}
} }

View File

@ -81,7 +81,6 @@ class LWJGLInitializer {
private static void initializeOpenGL() { private static void initializeOpenGL() {
GL.createCapabilities(); GL.createCapabilities();
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
} }

View File

@ -18,6 +18,7 @@
package ru.windcorp.progressia.client.graphics.flat; package ru.windcorp.progressia.client.graphics.flat;
import ru.windcorp.progressia.client.graphics.Layer; import ru.windcorp.progressia.client.graphics.Layer;
import ru.windcorp.progressia.client.graphics.backend.FaceCulling;
public abstract class AssembledFlatLayer extends Layer { public abstract class AssembledFlatLayer extends Layer {
@ -48,11 +49,15 @@ public abstract class AssembledFlatLayer extends Layer {
@Override @Override
protected void doRender() { protected void doRender() {
FaceCulling.push(false);
for (RenderTarget.Clip clip : clips) { for (RenderTarget.Clip clip : clips) {
clip.render(helper); clip.render(helper);
} }
helper.reset(); helper.reset();
FaceCulling.pop();
} }
} }

View File

@ -17,8 +17,6 @@
*******************************************************************************/ *******************************************************************************/
package ru.windcorp.progressia.client.graphics.flat; package ru.windcorp.progressia.client.graphics.flat;
import static org.lwjgl.opengl.GL11.*;
import java.nio.FloatBuffer; import java.nio.FloatBuffer;
import com.google.common.collect.ObjectArrays; import com.google.common.collect.ObjectArrays;
@ -81,9 +79,7 @@ public class FlatRenderProgram extends ShapeRenderProgram {
@Override @Override
public void render(ShapeRenderHelper helper, Shape shape) { public void render(ShapeRenderHelper helper, Shape shape) {
glDisable(GL_CULL_FACE);
super.render(helper, shape); super.render(helper, shape);
glEnable(GL_CULL_FACE);
} }
@Override @Override

View File

@ -43,7 +43,9 @@ public class Shapes {
Texture northTexture, Texture northTexture,
Texture southTexture, Texture southTexture,
Texture eastTexture, Texture eastTexture,
Texture westTexture Texture westTexture,
boolean flip
) { ) {
Vec3 faceOrigin = Vectors.grab3(); Vec3 faceOrigin = Vectors.grab3();
@ -55,7 +57,7 @@ public class Shapes {
faceOrigin.set(origin).add(height).add(width), faceOrigin.set(origin).add(height).add(width),
faceWidth.set(width).negate(), faceWidth.set(width).negate(),
depth, depth,
false flip
); );
Face bottom = Faces.createRectangle( Face bottom = Faces.createRectangle(
@ -64,7 +66,7 @@ public class Shapes {
origin, origin,
width, width,
depth, depth,
false flip
); );
Face north = Faces.createRectangle( Face north = Faces.createRectangle(
@ -73,7 +75,7 @@ public class Shapes {
faceOrigin.set(origin).add(depth), faceOrigin.set(origin).add(depth),
width, width,
height, height,
false flip
); );
Face south = Faces.createRectangle( Face south = Faces.createRectangle(
@ -82,7 +84,7 @@ public class Shapes {
faceOrigin.set(origin).add(width), faceOrigin.set(origin).add(width),
faceWidth.set(width).negate(), faceWidth.set(width).negate(),
height, height,
false flip
); );
Face east = Faces.createRectangle( Face east = Faces.createRectangle(
@ -91,7 +93,7 @@ public class Shapes {
origin, origin,
depth, depth,
height, height,
false flip
); );
Face west = Faces.createRectangle( Face west = Faces.createRectangle(
@ -100,7 +102,7 @@ public class Shapes {
faceOrigin.set(origin).add(width).add(depth), faceOrigin.set(origin).add(width).add(depth),
faceWidth.set(depth).negate(), faceWidth.set(depth).negate(),
height, height,
false flip
); );
Shape result = new Shape( Shape result = new Shape(
@ -134,6 +136,8 @@ public class Shapes {
private final Texture eastTexture; private final Texture eastTexture;
private final Texture westTexture; private final Texture westTexture;
private boolean flip = false;
public PppBuilder( public PppBuilder(
ShapeRenderProgram program, ShapeRenderProgram program,
Texture top, Texture top,
@ -237,13 +241,18 @@ public class Shapes {
} }
public PppBuilder setSize(float x, float y, float z) { public PppBuilder setSize(float x, float y, float z) {
return this.setWidth(x).setDepth(y).setHeight(z); return this.setDepth(x).setWidth(y).setHeight(z);
} }
public PppBuilder setSize(float size) { public PppBuilder setSize(float size) {
return this.setSize(size, size, size); return this.setSize(size, size, size);
} }
public PppBuilder flip() {
this.flip = true;
return this;
}
public Shape create() { public Shape create() {
return createParallelepiped( return createParallelepiped(
program, program,
@ -255,7 +264,8 @@ public class Shapes {
northTexture, northTexture,
southTexture, southTexture,
eastTexture, eastTexture,
westTexture westTexture,
flip
); );
} }

View File

@ -24,6 +24,7 @@ import glm.vec._3.Vec3;
import ru.windcorp.progressia.client.Client; import ru.windcorp.progressia.client.Client;
import ru.windcorp.progressia.client.comms.controls.InputBasedControls; import ru.windcorp.progressia.client.comms.controls.InputBasedControls;
import ru.windcorp.progressia.client.graphics.Layer; import ru.windcorp.progressia.client.graphics.Layer;
import ru.windcorp.progressia.client.graphics.backend.FaceCulling;
import ru.windcorp.progressia.client.graphics.backend.GraphicsBackend; import ru.windcorp.progressia.client.graphics.backend.GraphicsBackend;
import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface; import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface;
import ru.windcorp.progressia.client.graphics.input.CursorMoveEvent; import ru.windcorp.progressia.client.graphics.input.CursorMoveEvent;
@ -102,7 +103,9 @@ public class LayerWorld extends Layer {
} }
private void renderWorld() { private void renderWorld() {
FaceCulling.push(true);
this.client.getWorld().render(helper); this.client.getWorld().render(helper);
FaceCulling.pop();
} }
@Override @Override

View File

@ -92,12 +92,6 @@ public class ChunkRender {
model.render(renderer); model.render(renderer);
renderer.popTransform(); renderer.popTransform();
getData().forEachEntity(entityData -> {
renderer.pushTransform().translate(entityData.getPosition());
getWorld().getEntityRenderable(entityData).render(renderer);
renderer.popTransform();
});
} }
private void buildModel() { private void buildModel() {

View File

@ -24,6 +24,7 @@ import java.util.Map;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import glm.vec._3.i.Vec3i; import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.client.graphics.backend.FaceCulling;
import ru.windcorp.progressia.client.graphics.model.Renderable; import ru.windcorp.progressia.client.graphics.model.Renderable;
import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper; import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper;
import ru.windcorp.progressia.client.world.entity.EntityRenderRegistry; import ru.windcorp.progressia.client.world.entity.EntityRenderRegistry;
@ -67,6 +68,22 @@ public class WorldRender {
for (ChunkRender chunk : getChunks()) { for (ChunkRender chunk : getChunks()) {
chunk.render(renderer); chunk.render(renderer);
} }
renderEntities(renderer);
}
private void renderEntities(ShapeRenderHelper renderer) {
FaceCulling.push(false);
for (ChunkRender chunk : getChunks()) {
chunk.getData().forEachEntity(entity -> {
renderer.pushTransform().translate(entity.getPosition());
getEntityRenderable(entity).render(renderer);
renderer.popTransform();
});
}
FaceCulling.pop();
} }
public Renderable getEntityRenderable(EntityData entity) { public Renderable getEntityRenderable(EntityData entity) {

View File

@ -99,6 +99,11 @@ public class QuadripedModel implements Renderable {
private float velocityCoeff = 0; private float velocityCoeff = 0;
private float velocity = 0; private float velocity = 0;
/**
* Controls how quickly velocityCoeff approaches 1
*/
private float velocityCutoff = 10;
private float walkingFrequency = 0.15f; private float walkingFrequency = 0.15f;
private float walkingSwing = (float) toRadians(30); private float walkingSwing = (float) toRadians(30);
@ -129,8 +134,8 @@ public class QuadripedModel implements Renderable {
@Override @Override
public void render(ShapeRenderHelper renderer) { public void render(ShapeRenderHelper renderer) {
evaluateAngles();
accountForVelocity(); accountForVelocity();
evaluateAngles();
renderer.pushTransform().scale(scale).rotateZ(bodyYaw); renderer.pushTransform().scale(scale).rotateZ(bodyYaw);
body.render(renderer, this); body.render(renderer, this);
@ -171,13 +176,15 @@ public class QuadripedModel implements Renderable {
} }
private void accountForVelocity() { private void accountForVelocity() {
// TODO switch to world time
Vec3 horizontal = Vectors.grab3(); Vec3 horizontal = Vectors.grab3();
horizontal.set(entity.getVelocity()); horizontal.set(entity.getVelocity());
horizontal.z = 0; horizontal.z = 0;
velocity = (float) (horizontal.length()); velocity = horizontal.length();
velocityCoeff = -1 / (velocity * 1000 + 1) + 1;
evaluateVelocityCoeff();
// TODO switch to world time
walkingAnimationParameter += velocity * GraphicsInterface.getFrameLength() * 1000; walkingAnimationParameter += velocity * GraphicsInterface.getFrameLength() * 1000;
bodyYaw += velocityCoeff * normalizeAngle( bodyYaw += velocityCoeff * normalizeAngle(
@ -186,6 +193,15 @@ public class QuadripedModel implements Renderable {
Vectors.release(horizontal); Vectors.release(horizontal);
} }
private void evaluateVelocityCoeff() {
if (velocity * velocityCutoff > 1) {
velocityCoeff = 1;
} else {
velocityCoeff = velocity * velocityCutoff;
velocityCoeff *= velocityCoeff;
}
}
private static float normalizeAngle(float x) { private static float normalizeAngle(float x) {
final float half = (float) (PI); final float half = (float) (PI);
final float full = (float) (2 * PI); final float full = (float) (2 * PI);