mirror of
https://github.com/Retera/WarsmashModEngine.git
synced 2022-07-31 17:38:59 +02:00
Upgrade scene to have light manager
This commit is contained in:
parent
59d350dd9e
commit
b0b0745af9
@ -317,4 +317,8 @@ public abstract class Scene {
|
|||||||
return -Float.compare(o2.depth, o1.depth);
|
return -Float.compare(o2.depth, o1.depth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SceneLightManager getLightManager() {
|
||||||
|
return this.lightManager;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import com.etheller.warsmash.viewer5.Texture;
|
|||||||
import com.etheller.warsmash.viewer5.gl.DataTexture;
|
import com.etheller.warsmash.viewer5.gl.DataTexture;
|
||||||
import com.etheller.warsmash.viewer5.gl.WebGL;
|
import com.etheller.warsmash.viewer5.gl.WebGL;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.DynamicShadowManager;
|
import com.etheller.warsmash.viewer5.handlers.w3x.DynamicShadowManager;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.W3xSceneLightManager;
|
||||||
|
|
||||||
public class BatchGroup extends GenericGroup {
|
public class BatchGroup extends GenericGroup {
|
||||||
|
|
||||||
@ -36,6 +37,7 @@ public class BatchGroup extends GenericGroup {
|
|||||||
final WebGL webGL = viewer.webGL;
|
final WebGL webGL = viewer.webGL;
|
||||||
final boolean isExtended = this.isExtended;
|
final boolean isExtended = this.isExtended;
|
||||||
final ShaderProgram shader;
|
final ShaderProgram shader;
|
||||||
|
final W3xSceneLightManager lightManager = (W3xSceneLightManager) scene.getLightManager();
|
||||||
|
|
||||||
if (isExtended) {
|
if (isExtended) {
|
||||||
if (DynamicShadowManager.IS_SHADOW_MAPPING) {
|
if (DynamicShadowManager.IS_SHADOW_MAPPING) {
|
||||||
@ -59,6 +61,11 @@ public class BatchGroup extends GenericGroup {
|
|||||||
shader.setUniformMatrix("u_mvp", mvp);
|
shader.setUniformMatrix("u_mvp", mvp);
|
||||||
|
|
||||||
final DataTexture boneTexture = instance.boneTexture;
|
final DataTexture boneTexture = instance.boneTexture;
|
||||||
|
final DataTexture unitLightsTexture = lightManager.getUnitLightsTexture();
|
||||||
|
|
||||||
|
unitLightsTexture.bind(16);
|
||||||
|
shader.setUniformi("u_lightTexture", 16);
|
||||||
|
shader.setUniformf("u_lightCount", unitLightsTexture.getHeight());
|
||||||
|
|
||||||
// Instances of models with no bones don't have a bone texture.
|
// Instances of models with no bones don't have a bone texture.
|
||||||
if (boneTexture != null) {
|
if (boneTexture != null) {
|
||||||
|
@ -13,14 +13,18 @@ public class LightInstance implements UpdatableObject, SceneLightInstance {
|
|||||||
protected final Light light;
|
protected final Light light;
|
||||||
private boolean visible;
|
private boolean visible;
|
||||||
private boolean loadedInScene;
|
private boolean loadedInScene;
|
||||||
|
private final MdxComplexInstance instance;
|
||||||
|
|
||||||
public LightInstance(final MdxComplexInstance instance, final Light light) {
|
public LightInstance(final MdxComplexInstance instance, final Light light) {
|
||||||
|
this.instance = instance;
|
||||||
this.node = instance.nodes[light.index];
|
this.node = instance.nodes[light.index];
|
||||||
this.light = light;
|
this.light = light;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind(final int offset, final FloatBuffer floatBuffer, final int sequence, final int frame,
|
public void bind(final int offset, final FloatBuffer floatBuffer) {
|
||||||
final int counter) {
|
final int sequence = this.instance.sequence;
|
||||||
|
final int frame = this.instance.frame;
|
||||||
|
final int counter = this.instance.counter;
|
||||||
this.light.getAttenuationStart(scalarHeap, sequence, frame, counter);
|
this.light.getAttenuationStart(scalarHeap, sequence, frame, counter);
|
||||||
final float attenuationStart = scalarHeap[0];
|
final float attenuationStart = scalarHeap[0];
|
||||||
this.light.getAttenuationEnd(scalarHeap, sequence, frame, counter);
|
this.light.getAttenuationEnd(scalarHeap, sequence, frame, counter);
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package com.etheller.warsmash.viewer5.handlers.w3x;
|
package com.etheller.warsmash.viewer5.handlers.w3x;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -10,13 +13,19 @@ import com.etheller.warsmash.viewer5.handlers.mdx.LightInstance;
|
|||||||
|
|
||||||
public class W3xSceneLightManager implements SceneLightManager {
|
public class W3xSceneLightManager implements SceneLightManager {
|
||||||
public final List<LightInstance> lights;
|
public final List<LightInstance> lights;
|
||||||
|
private FloatBuffer lightDataCopyHeap;
|
||||||
private final DataTexture unitLightsTexture;
|
private final DataTexture unitLightsTexture;
|
||||||
private final DataTexture terrainLightsTexture;
|
private final DataTexture terrainLightsTexture;
|
||||||
|
private final War3MapViewer viewer;
|
||||||
|
private int terrainLightCount;
|
||||||
|
private int unitLightCount;
|
||||||
|
|
||||||
public W3xSceneLightManager(final War3MapViewer viewer) {
|
public W3xSceneLightManager(final War3MapViewer viewer) {
|
||||||
|
this.viewer = viewer;
|
||||||
this.lights = new ArrayList<>();
|
this.lights = new ArrayList<>();
|
||||||
this.unitLightsTexture = new DataTexture(viewer.gl, 4, 4, 1);
|
this.unitLightsTexture = new DataTexture(viewer.gl, 4, 4, 1);
|
||||||
this.terrainLightsTexture = new DataTexture(viewer.gl, 4, 4, 1);
|
this.terrainLightsTexture = new DataTexture(viewer.gl, 4, 4, 1);
|
||||||
|
this.lightDataCopyHeap = ByteBuffer.allocateDirect(16 * 1 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -24,6 +33,7 @@ public class W3xSceneLightManager implements SceneLightManager {
|
|||||||
// TODO redesign to avoid cast
|
// TODO redesign to avoid cast
|
||||||
final LightInstance mdxLight = (LightInstance) lightInstance;
|
final LightInstance mdxLight = (LightInstance) lightInstance;
|
||||||
this.lights.add(mdxLight);
|
this.lights.add(mdxLight);
|
||||||
|
rebind();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -31,5 +41,67 @@ public class W3xSceneLightManager implements SceneLightManager {
|
|||||||
// TODO redesign to avoid cast
|
// TODO redesign to avoid cast
|
||||||
final LightInstance mdxLight = (LightInstance) lightInstance;
|
final LightInstance mdxLight = (LightInstance) lightInstance;
|
||||||
this.lights.remove(mdxLight);
|
this.lights.remove(mdxLight);
|
||||||
|
rebind();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void rebind() {
|
||||||
|
final int numberOfLights = this.lights.size() + 1;
|
||||||
|
final int bytesNeeded = numberOfLights * 4 * 16;
|
||||||
|
if (bytesNeeded > (this.lightDataCopyHeap.capacity() * 4)) {
|
||||||
|
this.lightDataCopyHeap = ByteBuffer.allocateDirect(bytesNeeded).order(ByteOrder.nativeOrder())
|
||||||
|
.asFloatBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.unitLightCount = 0;
|
||||||
|
this.lightDataCopyHeap.clear();
|
||||||
|
int offset = 0;
|
||||||
|
if (this.viewer.dncUnit != null) {
|
||||||
|
if (!this.viewer.dncUnit.lights.isEmpty()) {
|
||||||
|
this.viewer.dncUnit.lights.get(0).bind(0, this.lightDataCopyHeap);
|
||||||
|
offset += 16;
|
||||||
|
this.unitLightCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (final LightInstance light : this.lights) {
|
||||||
|
light.bind(offset, this.lightDataCopyHeap);
|
||||||
|
offset += 16;
|
||||||
|
this.unitLightCount++;
|
||||||
|
}
|
||||||
|
this.lightDataCopyHeap.flip();
|
||||||
|
this.unitLightsTexture.bindAndUpdate(this.lightDataCopyHeap, 16, this.unitLightCount);
|
||||||
|
|
||||||
|
this.terrainLightCount = 0;
|
||||||
|
this.lightDataCopyHeap.clear();
|
||||||
|
offset = 0;
|
||||||
|
if (this.viewer.dncTerrain != null) {
|
||||||
|
if (!this.viewer.dncTerrain.lights.isEmpty()) {
|
||||||
|
this.viewer.dncTerrain.lights.get(0).bind(0, this.lightDataCopyHeap);
|
||||||
|
offset += 16;
|
||||||
|
this.terrainLightCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (final LightInstance light : this.lights) {
|
||||||
|
light.bind(offset, this.lightDataCopyHeap);
|
||||||
|
offset += 16;
|
||||||
|
this.terrainLightCount++;
|
||||||
|
}
|
||||||
|
this.lightDataCopyHeap.flip();
|
||||||
|
this.terrainLightsTexture.bindAndUpdate(this.lightDataCopyHeap, 16, this.terrainLightCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataTexture getUnitLightsTexture() {
|
||||||
|
return this.unitLightsTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUnitLightCount() {
|
||||||
|
return this.unitLightCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataTexture getTerrainLightsTexture() {
|
||||||
|
return this.terrainLightsTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTerrainLightCount() {
|
||||||
|
return this.terrainLightCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,8 +156,8 @@ public class War3MapViewer extends ModelViewer {
|
|||||||
public DataTable miscData;
|
public DataTable miscData;
|
||||||
private DataTable unitGlobalStrings;
|
private DataTable unitGlobalStrings;
|
||||||
private MdxComplexInstance confirmationInstance;
|
private MdxComplexInstance confirmationInstance;
|
||||||
private MdxComplexInstance dncUnit;
|
public MdxComplexInstance dncUnit;
|
||||||
private MdxComplexInstance dncTerrain;
|
public MdxComplexInstance dncTerrain;
|
||||||
public CSimulation simulation;
|
public CSimulation simulation;
|
||||||
private float updateTime;
|
private float updateTime;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user