Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add water component objects #24

Merged
merged 6 commits into from
May 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ allprojects {
mockitoVersion = '1.10.19'
commonsIoVersion = '2.5'
commonsLangVersion = '3.12.0'
guacamoleVersion = '0.3.1'
gltfVersion = 'master-SNAPSHOT'

ktxVersion = '1.10.0-b2'
Expand All @@ -57,6 +58,8 @@ project(":commons") {
testCompile "junit:junit:$junitVersion"

testCompile "org.mockito:mockito-all:$mockitoVersion"

implementation "com.github.crykn.guacamole:gdx:$guacamoleVersion"
}
}

Expand Down
102 changes: 101 additions & 1 deletion commons/src/main/com/mbrlabs/mundus/commons/Scene.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,14 @@
package com.mbrlabs.mundus.commons;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g3d.ModelBatch;
import com.badlogic.gdx.graphics.glutils.FrameBuffer;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Disposable;
import com.mbrlabs.mundus.commons.assets.TerrainAsset;
Expand All @@ -27,6 +33,8 @@
import com.mbrlabs.mundus.commons.scene3d.GameObject;
import com.mbrlabs.mundus.commons.scene3d.SceneGraph;
import com.mbrlabs.mundus.commons.skybox.Skybox;
import com.mbrlabs.mundus.commons.water.WaterResolution;
import de.damios.guacamole.gdx.graphics.NestableFrameBuffer;

/**
* @author Marcus Brummer
Expand All @@ -40,6 +48,8 @@ public class Scene implements Disposable {
public SceneGraph sceneGraph;
public MundusEnvironment environment;
public Skybox skybox;
public float waterHeight = 0f;
public WaterResolution waterResolution = WaterResolution.DEFAULT_WATER_RESOLUTION;

@Deprecated // TODO not here
public Array<TerrainAsset> terrains;
Expand All @@ -49,6 +59,15 @@ public class Scene implements Disposable {
public PerspectiveCamera cam;
public ModelBatch batch;

private FrameBuffer fboWaterReflection;
private FrameBuffer fboWaterRefraction;

protected Vector3 clippingPlaneDisable = new Vector3(0.0f, 0f, 0.0f);
protected Vector3 clippingPlaneReflection = new Vector3(0.0f, 1f, 0.0f);
protected Vector3 clippingPlaneRefraction = new Vector3(0.0f, -1f, 0.0f);

private final float distortionEdgeCorrection = 1f;

public Scene() {
environment = new MundusEnvironment();
currentSelection = null;
Expand Down Expand Up @@ -76,9 +95,84 @@ public void render() {
}

public void render(float delta) {
if (fboWaterReflection == null) {
Vector2 res = waterResolution.getResolutionValues();
initFrameBuffers((int) res.x, (int) res.y);
}

if (sceneGraph.isContainsWater()) {
captureReflectionFBO(delta);
captureRefractionFBO(delta);
}

renderSkybox();

// Render objects
batch.begin(cam);
sceneGraph.render(delta, clippingPlaneDisable, 0);
batch.end();

if (sceneGraph.isContainsWater()) {
Texture refraction = fboWaterRefraction.getColorBufferTexture();
Texture reflection = fboWaterReflection.getColorBufferTexture();

// Render Water
batch.begin(cam);
sceneGraph.renderWater(delta, reflection, refraction);
batch.end();
}

}

private void initFrameBuffers(int width, int height) {
fboWaterReflection = new NestableFrameBuffer(Pixmap.Format.RGBA8888, width, height, true);
fboWaterRefraction = new NestableFrameBuffer(Pixmap.Format.RGBA8888, width, height, true);
}

private void captureReflectionFBO(float delta) {
// Calc vertical distance for camera for reflection FBO
float camReflectionDistance = 2 * (cam.position.y - waterHeight);

// Save current cam positions
Vector3 camPos = cam.position.cpy();
Vector3 camDir = cam.direction.cpy();

// Position camera for reflection capture
cam.direction.scl(1, -1, 1).nor();
cam.position.sub(0, camReflectionDistance, 0);
cam.update();

// Render reflections to FBO
fboWaterReflection.begin();
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
renderSkybox();
batch.begin(cam);
sceneGraph.render(delta, clippingPlaneReflection, -waterHeight + distortionEdgeCorrection);
batch.end();
fboWaterReflection.end();

// Restore camera positions
cam.direction.set(camDir);
cam.position.set(camPos);
cam.update();
}

private void renderSkybox() {
if (skybox != null) {
batch.begin(cam);
batch.render(skybox.getSkyboxInstance(), environment, skybox.shader);
batch.end();
}
}

private void captureRefractionFBO(float delta) {
// Render refractions to FBO
fboWaterRefraction.begin();
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
batch.begin(cam);
sceneGraph.render(delta);
sceneGraph.render(delta, clippingPlaneRefraction, waterHeight + distortionEdgeCorrection);
batch.end();
fboWaterRefraction.end();
}

public String getName() {
Expand All @@ -97,6 +191,12 @@ public void setId(long id) {
this.id = id;
}

public void setWaterResolution(WaterResolution resolution) {
this.waterResolution = resolution;
Vector2 res = waterResolution.getResolutionValues();
initFrameBuffers((int) res.x, (int) res.y);
}

@Override
public void dispose() {
if (skybox != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,9 @@ public Asset loadAsset(Meta meta) throws MetaFileParseException, AssetNotFoundEx
case MATERIAL:
asset = loadMaterialAsset(meta, assetFile);
break;
case WATER:
asset = loadWaterAsset(meta, assetFile);
break;
default:
return null;
}
Expand Down Expand Up @@ -295,6 +298,12 @@ private ModelAsset loadModelAsset(Meta meta, FileHandle assetFile) {
return asset;
}

private WaterAsset loadWaterAsset(Meta meta, FileHandle assetFile) {
WaterAsset asset = new WaterAsset(meta, assetFile);
asset.load();
return asset;
}

@Override
public void dispose() {
for (Asset asset : assets) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,7 @@ public enum AssetType {
/** Terra file. Contains height data for terrains. */
TERRAIN,
/** Material file. Mundus material file contains material information. */
MATERIAL
MATERIAL,
/** Water file. Contains data for water. */
WATER
}
76 changes: 76 additions & 0 deletions commons/src/main/com/mbrlabs/mundus/commons/assets/WaterAsset.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.mbrlabs.mundus.commons.assets;

import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Texture;
import com.mbrlabs.mundus.commons.assets.meta.Meta;
import com.mbrlabs.mundus.commons.water.Water;

import java.util.Map;

public class WaterAsset extends Asset {

public Water water;
public TextureAsset waterTexture;
public TextureAsset dudvTexture;
public TextureAsset normalMapTexture;

public WaterAsset(Meta meta, FileHandle assetFile) {
super(meta, assetFile);
}

@Override
public void load() {
water = new Water(meta.getWater().getSize());
water.init();
water.setTiling(meta.getWater().getTiling());
water.setWaveStrength(meta.getWater().getWaveStrength());
water.setWaveSpeed(meta.getWater().getWaveSpeed());
}

@Override
public void resolveDependencies(Map<String, Asset> assets) {
String id = meta.getWater().getDudvMap();
if (id != null && assets.containsKey(id)) {
dudvTexture = (TextureAsset) assets.get(id);
}

id = meta.getWater().getNormalMap();
if (id != null && assets.containsKey(id)) {
normalMapTexture = (TextureAsset) assets.get(id);
}
}

@Override
public void applyDependencies() {
if (waterTexture != null) {
water.setWaterReflection(waterTexture.getTexture());
}

if (dudvTexture != null) {
water.setDudvTexture(dudvTexture.getTexture());
}

if (normalMapTexture != null) {
water.setNormalMap(normalMapTexture.getTexture());
}
}

public void setWaterReflectionTexture(Texture texture){
water.setWaterReflection(texture);
}

public void setWaterRefractionTexture(Texture texture){
water.setWaterRefractionTexture(texture);
}

@Override
public void dispose() {

}

@Override
public boolean usesAsset(Asset assetToCheck) {
return false;
}

}
10 changes: 10 additions & 0 deletions commons/src/main/com/mbrlabs/mundus/commons/assets/meta/Meta.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class Meta {
public static final String JSON_UUID = "id";
public static final String JSON_TYPE = "t";
public static final String JSON_TERRAIN = "ter";
public static final String JSON_WATER = "wat";
public static final String JSON_MODEL = "mdl";

private int version;
Expand All @@ -44,6 +45,7 @@ public class Meta {

private MetaModel model;
private MetaTerrain terrain;
private MetaWater water;

private FileHandle file;

Expand Down Expand Up @@ -103,6 +105,14 @@ public void setTerrain(MetaTerrain terrain) {
this.terrain = terrain;
}

public MetaWater getWater() {
return water;
}

public void setWater(MetaWater water) {
this.water = water;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public Meta load(FileHandle file) throws MetaFileParseException {
parseTerrain(meta, json.get(Meta.JSON_TERRAIN));
} else if(meta.getType() == AssetType.MODEL) {
parseModel(meta, json.get(Meta.JSON_MODEL));
} else if(meta.getType() == AssetType.WATER) {
parseWater(meta, json.get(Meta.JSON_WATER));
}

return meta;
Expand Down Expand Up @@ -69,6 +71,20 @@ private void parseTerrain(Meta meta, JsonValue jsonTerrain) {
meta.setTerrain(terrain);
}

private void parseWater(Meta meta, JsonValue jsonValue) {
if(jsonValue == null) return;

final MetaWater water = new MetaWater();
water.setSize(jsonValue.getInt(MetaWater.JSON_SIZE));
water.setDudvMap(jsonValue.getString(MetaWater.JSON_DUDV));
water.setNormalMap(jsonValue.getString(MetaWater.JSON_NORMAL_MAP));
water.setTiling(jsonValue.getFloat(MetaWater.JSON_TILING));
water.setWaveStrength(jsonValue.getFloat(MetaWater.JSON_WAVE_STRENGTH));
water.setWaveSpeed(jsonValue.getFloat(MetaWater.JSON_WAVE_SPEED));

meta.setWater(water);
}

private void parseModel(Meta meta, JsonValue jsonModel) {
if(jsonModel == null) return;

Expand Down
Loading