mirror of
https://github.com/Eaglercraft-Archive/Eaglercraftx-1.8.8-src.git
synced 2025-06-27 18:38:14 -05:00
Update #34 - Add dynamic lights, fix vanilla world seeds
This commit is contained in:
@ -19,6 +19,7 @@ import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.StreamBuffer.StreamBufferInstance;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights.DynamicLightsStateManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.vector.Matrix4f;
|
||||
import net.lax1dude.eaglercraft.v1_8.vector.Vector4f;
|
||||
import net.minecraft.util.MathHelper;
|
||||
@ -904,7 +905,9 @@ public class FixedFunctionPipeline {
|
||||
_wglUniform3f(stateLightingAmbientUniform3f, r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(stateEnableMCLighting || DynamicLightsStateManager.isInDynamicLightsPass()) {
|
||||
if(!stateHasAttribNormal) {
|
||||
serial = GlStateManager.stateNormalSerial;
|
||||
if(stateNormalSerial != serial) {
|
||||
|
@ -808,6 +808,22 @@ public class GlStateManager {
|
||||
}
|
||||
}
|
||||
|
||||
public static final void getFloat(int pname, FloatBuffer params) {
|
||||
switch(pname) {
|
||||
case GL_MODELVIEW_MATRIX:
|
||||
modelMatrixStack[modelMatrixStackPointer].store(params);
|
||||
break;
|
||||
case GL_PROJECTION_MATRIX:
|
||||
projectionMatrixStack[projectionMatrixStackPointer].store(params);
|
||||
break;
|
||||
case GL_TEXTURE_MATRIX:
|
||||
textureMatrixStack[activeTexture][textureMatrixStackPointer[activeTexture]].store(params);
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("glGetFloat can only be used to retrieve matricies!");
|
||||
}
|
||||
}
|
||||
|
||||
public static final void ortho(double left, double right, double bottom, double top, double zNear, double zFar) {
|
||||
Matrix4f matrix;
|
||||
switch(stateMatrixMode) {
|
||||
|
@ -49,8 +49,8 @@ public class InstancedParticleRenderer {
|
||||
private static IUniformGL u_matrixTransform = null;
|
||||
private static FloatBuffer matrixCopyBuffer = null;
|
||||
private static IUniformGL u_texCoordSize2f_particleSize1f = null;
|
||||
private static IUniformGL u_transformParam_1_2_3_4_f = null;
|
||||
private static IUniformGL u_transformParam_5_f = null;
|
||||
private static IUniformGL u_transformParam_1_2_5_f = null;
|
||||
private static IUniformGL u_transformParam_3_4_f = null;
|
||||
private static IUniformGL u_color4f = null;
|
||||
|
||||
private static IBufferArrayGL vertexArray = null;
|
||||
@ -154,8 +154,8 @@ public class InstancedParticleRenderer {
|
||||
|
||||
u_matrixTransform = _wglGetUniformLocation(shaderProgram, "u_matrixTransform");
|
||||
u_texCoordSize2f_particleSize1f = _wglGetUniformLocation(shaderProgram, "u_texCoordSize2f_particleSize1f");
|
||||
u_transformParam_1_2_3_4_f = _wglGetUniformLocation(shaderProgram, "u_transformParam_1_2_3_4_f");
|
||||
u_transformParam_5_f = _wglGetUniformLocation(shaderProgram, "u_transformParam_5_f");
|
||||
u_transformParam_1_2_5_f = _wglGetUniformLocation(shaderProgram, "u_transformParam_1_2_5_f");
|
||||
u_transformParam_3_4_f = _wglGetUniformLocation(shaderProgram, "u_transformParam_3_4_f");
|
||||
u_color4f = _wglGetUniformLocation(shaderProgram, "u_color4f");
|
||||
|
||||
_wglUniform1i(_wglGetUniformLocation(shaderProgram, "u_inputTexture"), 0);
|
||||
@ -260,17 +260,17 @@ public class InstancedParticleRenderer {
|
||||
}
|
||||
|
||||
if (transformParam1 != stateTransformParam1 || transformParam2 != stateTransformParam2
|
||||
|| transformParam3 != stateTransformParam3 || transformParam4 != stateTransformParam4) {
|
||||
_wglUniform4f(u_transformParam_1_2_3_4_f, transformParam1, transformParam2, transformParam3, transformParam4);
|
||||
|| transformParam5 != stateTransformParam5) {
|
||||
_wglUniform3f(u_transformParam_1_2_5_f, transformParam1, transformParam2, transformParam5);
|
||||
stateTransformParam1 = transformParam1;
|
||||
stateTransformParam2 = transformParam2;
|
||||
stateTransformParam3 = transformParam3;
|
||||
stateTransformParam4 = transformParam4;
|
||||
stateTransformParam5 = transformParam5;
|
||||
}
|
||||
|
||||
if (transformParam5 != stateTransformParam5) {
|
||||
_wglUniform1f(u_transformParam_5_f, transformParam5);
|
||||
stateTransformParam5 = transformParam5;
|
||||
if (transformParam3 != stateTransformParam3 || transformParam4 != stateTransformParam4) {
|
||||
_wglUniform2f(u_transformParam_3_4_f, transformParam3, transformParam4);
|
||||
stateTransformParam3 = transformParam3;
|
||||
stateTransformParam4 = transformParam4;
|
||||
}
|
||||
|
||||
int serial = GlStateManager.stateColorSerial;
|
||||
@ -319,4 +319,8 @@ public class InstancedParticleRenderer {
|
||||
_wglDrawArraysInstanced(GL_TRIANGLES, 0, 6, particleCount);
|
||||
}
|
||||
|
||||
public static void stupidColorSetHack(IUniformGL color4f) {
|
||||
_wglUniform4f(color4f, GlStateManager.stateColorR, GlStateManager.stateColorG, GlStateManager.stateColorB, GlStateManager.stateColorA);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ public class DeferredStateManager {
|
||||
}
|
||||
|
||||
public static final boolean isInDeferredPass() {
|
||||
return GlStateManager.isExtensionPipeline();
|
||||
return EaglerDeferredPipeline.instance != null && GlStateManager.isExtensionPipeline();
|
||||
}
|
||||
|
||||
public static final boolean isInForwardPass() {
|
||||
@ -153,10 +153,17 @@ public class DeferredStateManager {
|
||||
}
|
||||
|
||||
public static final void reportForwardRenderObjectPosition2(float x, float y, float z) {
|
||||
float posX = (float)((x + TileEntityRendererDispatcher.staticPlayerX) - (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerX / 16.0) << 4));
|
||||
float posY = (float)((y + TileEntityRendererDispatcher.staticPlayerY) - (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerY / 16.0) << 4));
|
||||
float posZ = (float)((z + TileEntityRendererDispatcher.staticPlayerZ) - (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerZ / 16.0) << 4));
|
||||
reportForwardRenderObjectPosition((int)posX, (int)posY, (int)posZ);
|
||||
EaglerDeferredPipeline instance = EaglerDeferredPipeline.instance;
|
||||
if(instance != null && enableForwardRender) {
|
||||
EaglerDeferredConfig cfg = instance.config;
|
||||
if(!cfg.is_rendering_dynamicLights || !cfg.shaderPackInfo.DYNAMIC_LIGHTS) {
|
||||
return;
|
||||
}
|
||||
float posX = (float)((x + TileEntityRendererDispatcher.staticPlayerX) - (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerX / 16.0) << 4));
|
||||
float posY = (float)((y + TileEntityRendererDispatcher.staticPlayerY) - (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerY / 16.0) << 4));
|
||||
float posZ = (float)((z + TileEntityRendererDispatcher.staticPlayerZ) - (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerZ / 16.0) << 4));
|
||||
instance.loadLightSourceBucket((int)posX, (int)posY, (int)posZ);
|
||||
}
|
||||
}
|
||||
|
||||
public static final void setHDRTranslucentPassBlendFunc() {
|
||||
|
@ -2049,6 +2049,8 @@ public class EaglerDeferredPipeline {
|
||||
}
|
||||
}
|
||||
|
||||
truncateOverflowingLightBuffers();
|
||||
|
||||
DeferredStateManager.checkGLError("combineGBuffersAndIlluminate(): RENDER DYNAMIC LIGHTS");
|
||||
}
|
||||
|
||||
@ -2305,6 +2307,19 @@ public class EaglerDeferredPipeline {
|
||||
return radius2 >= 0.0f;
|
||||
}
|
||||
|
||||
private void truncateOverflowingLightBuffers() {
|
||||
for(int i = 0; i < this.lightSourceBuckets.length; ++i) {
|
||||
List<DynamicLightInstance> lst = this.lightSourceBuckets[i];
|
||||
int k = lst.size();
|
||||
if(k > MAX_LIGHTS_PER_CHUNK) {
|
||||
lst.sort(comparatorLightRadius);
|
||||
for(int l = MAX_LIGHTS_PER_CHUNK - 1; l >= MAX_LIGHTS_PER_CHUNK; --l) {
|
||||
lst.remove(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateLightSourceUBO() {
|
||||
if(currentLightSourceBucket == null) {
|
||||
currentBoundLightSourceBucket = null;
|
||||
@ -2332,7 +2347,6 @@ public class EaglerDeferredPipeline {
|
||||
}
|
||||
}
|
||||
|
||||
private static final List<DynamicLightInstance> tmpListLights = new ArrayList(32);
|
||||
private static final Comparator<DynamicLightInstance> comparatorLightRadius = (l1, l2) -> {
|
||||
return l1.radius < l2.radius ? 1 : -1;
|
||||
};
|
||||
@ -2340,10 +2354,6 @@ public class EaglerDeferredPipeline {
|
||||
private void populateLightSourceUBOFromBucket(List<DynamicLightInstance> lights) {
|
||||
int max = lights.size();
|
||||
if(max > MAX_LIGHTS_PER_CHUNK) {
|
||||
tmpListLights.clear();
|
||||
tmpListLights.addAll(lights);
|
||||
lights = tmpListLights;
|
||||
lights.sort(comparatorLightRadius);
|
||||
max = MAX_LIGHTS_PER_CHUNK;
|
||||
}
|
||||
chunkLightingDataCopyBuffer.clear();
|
||||
|
@ -124,8 +124,13 @@ public class ForwardAcceleratedEffectRenderer extends AbstractAcceleratedEffectR
|
||||
shaderProgram.useProgram();
|
||||
|
||||
_wglUniform3f(shaderProgram.uniforms.u_texCoordSize2f_particleSize1f, texCoordWidth, texCoordHeight, 0.0625f);
|
||||
_wglUniform4f(shaderProgram.uniforms.u_transformParam_1_2_3_4_f, f1, f5, f2, f3);
|
||||
_wglUniform1f(shaderProgram.uniforms.u_transformParam_5_f, f4);
|
||||
if(shaderProgram.uniforms.u_transformParam_1_2_5_f != null) {
|
||||
_wglUniform3f(shaderProgram.uniforms.u_transformParam_1_2_5_f, f1, f5, f4);
|
||||
_wglUniform2f(shaderProgram.uniforms.u_transformParam_3_4_f, f2, f3);
|
||||
}else {
|
||||
_wglUniform4f(shaderProgram.uniforms.u_transformParam_1_2_3_4_f, f1, f5, f2, f3);
|
||||
_wglUniform1f(shaderProgram.uniforms.u_transformParam_5_f, f4);
|
||||
}
|
||||
if(isMaterialNormalTexture) {
|
||||
_wglUniform2f(shaderProgram.uniforms.u_textureYScale2f, 0.5f, 0.5f);
|
||||
}else {
|
||||
|
@ -124,8 +124,13 @@ public class GBufferAcceleratedEffectRenderer extends AbstractAcceleratedEffectR
|
||||
shaderProgram.useProgram();
|
||||
|
||||
_wglUniform3f(shaderProgram.uniforms.u_texCoordSize2f_particleSize1f, texCoordWidth, texCoordHeight, 0.0625f);
|
||||
_wglUniform4f(shaderProgram.uniforms.u_transformParam_1_2_3_4_f, f1, f5, f2, f3);
|
||||
_wglUniform1f(shaderProgram.uniforms.u_transformParam_5_f, f4);
|
||||
if(shaderProgram.uniforms.u_transformParam_1_2_5_f != null) {
|
||||
_wglUniform3f(shaderProgram.uniforms.u_transformParam_1_2_5_f, f1, f5, f4);
|
||||
_wglUniform2f(shaderProgram.uniforms.u_transformParam_3_4_f, f2, f3);
|
||||
}else {
|
||||
_wglUniform4f(shaderProgram.uniforms.u_transformParam_1_2_3_4_f, f1, f5, f2, f3);
|
||||
_wglUniform1f(shaderProgram.uniforms.u_transformParam_5_f, f4);
|
||||
}
|
||||
if(isMaterialNormalTexture) {
|
||||
_wglUniform2f(shaderProgram.uniforms.u_textureYScale2f, 0.5f, 0.5f);
|
||||
}else {
|
||||
|
@ -69,6 +69,8 @@ public class PipelineShaderAccelParticleForward extends ShaderProgram<PipelineSh
|
||||
public IUniformGL u_texCoordSize2f_particleSize1f = null;
|
||||
public IUniformGL u_transformParam_1_2_3_4_f = null;
|
||||
public IUniformGL u_transformParam_5_f = null;
|
||||
public IUniformGL u_transformParam_1_2_5_f = null;
|
||||
public IUniformGL u_transformParam_3_4_f = null;
|
||||
public IUniformGL u_textureYScale2f = null;
|
||||
|
||||
public int u_chunkLightingDataBlockBinding = -1;
|
||||
@ -85,6 +87,8 @@ public class PipelineShaderAccelParticleForward extends ShaderProgram<PipelineSh
|
||||
u_texCoordSize2f_particleSize1f = _wglGetUniformLocation(prog, "u_texCoordSize2f_particleSize1f");
|
||||
u_transformParam_1_2_3_4_f = _wglGetUniformLocation(prog, "u_transformParam_1_2_3_4_f");
|
||||
u_transformParam_5_f = _wglGetUniformLocation(prog, "u_transformParam_5_f");
|
||||
u_transformParam_1_2_5_f = _wglGetUniformLocation(prog, "u_transformParam_1_2_5_f");
|
||||
u_transformParam_3_4_f = _wglGetUniformLocation(prog, "u_transformParam_3_4_f");
|
||||
u_textureYScale2f = _wglGetUniformLocation(prog, "u_textureYScale2f");
|
||||
_wglUniform1i(_wglGetUniformLocation(prog, "u_diffuseTexture"), 0);
|
||||
_wglUniform1i(_wglGetUniformLocation(prog, "u_samplerNormalMaterial"), 2);
|
||||
|
@ -53,6 +53,8 @@ public class PipelineShaderAccelParticleGBuffer extends ShaderProgram<PipelineSh
|
||||
public IUniformGL u_texCoordSize2f_particleSize1f = null;
|
||||
public IUniformGL u_transformParam_1_2_3_4_f = null;
|
||||
public IUniformGL u_transformParam_5_f = null;
|
||||
public IUniformGL u_transformParam_1_2_5_f = null;
|
||||
public IUniformGL u_transformParam_3_4_f = null;
|
||||
public IUniformGL u_textureYScale2f = null;
|
||||
|
||||
private Uniforms() {
|
||||
@ -64,6 +66,8 @@ public class PipelineShaderAccelParticleGBuffer extends ShaderProgram<PipelineSh
|
||||
u_texCoordSize2f_particleSize1f = _wglGetUniformLocation(prog, "u_texCoordSize2f_particleSize1f");
|
||||
u_transformParam_1_2_3_4_f = _wglGetUniformLocation(prog, "u_transformParam_1_2_3_4_f");
|
||||
u_transformParam_5_f = _wglGetUniformLocation(prog, "u_transformParam_5_f");
|
||||
u_transformParam_1_2_5_f = _wglGetUniformLocation(prog, "u_transformParam_1_2_5_f");
|
||||
u_transformParam_3_4_f = _wglGetUniformLocation(prog, "u_transformParam_3_4_f");
|
||||
u_textureYScale2f = _wglGetUniformLocation(prog, "u_textureYScale2f");
|
||||
_wglUniform1i(_wglGetUniformLocation(prog, "u_diffuseTexture"), 0);
|
||||
_wglUniform1i(_wglGetUniformLocation(prog, "u_samplerNormalMaterial"), 2);
|
||||
|
@ -92,6 +92,11 @@ public class ShaderSource {
|
||||
public static final ResourceLocation post_fxaa_fsh = new ResourceLocation("eagler:glsl/deferred/post_fxaa.fsh");
|
||||
public static final ResourceLocation hand_depth_mask_fsh = new ResourceLocation("eagler:glsl/deferred/hand_depth_mask.fsh");
|
||||
|
||||
public static final ResourceLocation core_dynamiclights_vsh = new ResourceLocation("eagler:glsl/dynamiclights/core_dynamiclights.vsh");
|
||||
public static final ResourceLocation core_dynamiclights_fsh = new ResourceLocation("eagler:glsl/dynamiclights/core_dynamiclights.fsh");
|
||||
public static final ResourceLocation accel_particle_dynamiclights_vsh = new ResourceLocation("eagler:glsl/dynamiclights/accel_particle_dynamiclights.vsh");
|
||||
public static final ResourceLocation accel_particle_dynamiclights_fsh = new ResourceLocation("eagler:glsl/dynamiclights/accel_particle_dynamiclights.fsh");
|
||||
|
||||
private static final Map<ResourceLocation, String> sourceCache = new HashMap();
|
||||
|
||||
private static boolean isHighP = false;
|
||||
|
@ -0,0 +1,287 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights;
|
||||
|
||||
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
|
||||
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
|
||||
import static net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.ExtGLEnums.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IBufferGL;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.EaglercraftGPU;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.ArrayListSerial;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.EaglerDeferredPipeline;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.ListSerial;
|
||||
import net.minecraft.util.MathHelper;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2023-2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class DynamicLightBucketLoader {
|
||||
|
||||
public IBufferGL buffer_chunkLightingData;
|
||||
private ByteBuffer chunkLightingDataCopyBuffer;
|
||||
private boolean isChunkLightingEnabled = false;
|
||||
public ListSerial<DynamicLightInstance> currentBoundLightSourceBucket;
|
||||
|
||||
public final ListSerial<DynamicLightInstance>[] lightSourceBuckets;
|
||||
public ListSerial<DynamicLightInstance> currentLightSourceBucket;
|
||||
|
||||
public static final int MAX_LIGHTS_PER_CHUNK = 12;
|
||||
|
||||
private final int lightSourceBucketsWidth;
|
||||
private final int lightSourceBucketsHeight;
|
||||
|
||||
private double currentRenderX = 0.0;
|
||||
private double currentRenderY = 0.0;
|
||||
private double currentRenderZ = 0.0;
|
||||
|
||||
public DynamicLightBucketLoader() {
|
||||
this.lightSourceBucketsWidth = 5;
|
||||
this.lightSourceBucketsHeight = 3;
|
||||
int cnt = 5 * 3 * 5;
|
||||
this.lightSourceBuckets = new ListSerial[cnt];
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
destroy();
|
||||
|
||||
buffer_chunkLightingData = _wglGenBuffers();
|
||||
EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingData);
|
||||
int lightingDataLength = 4 * MAX_LIGHTS_PER_CHUNK + 4;
|
||||
chunkLightingDataCopyBuffer = EagRuntime.allocateByteBuffer(lightingDataLength << 2);
|
||||
for(int i = 0; i < lightingDataLength; ++i) {
|
||||
chunkLightingDataCopyBuffer.putInt(0);
|
||||
}
|
||||
chunkLightingDataCopyBuffer.flip();
|
||||
_wglBufferData(_GL_UNIFORM_BUFFER, chunkLightingDataCopyBuffer, GL_DYNAMIC_DRAW);
|
||||
|
||||
for(int i = 0; i < this.lightSourceBuckets.length; ++i) {
|
||||
this.lightSourceBuckets[i] = new ArrayListSerial(16);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearBuckets() {
|
||||
for(int i = 0; i < this.lightSourceBuckets.length; ++i) {
|
||||
this.lightSourceBuckets[i].clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void loadLightSourceBucket(int relativeBlockX, int relativeBlockY, int relativeBlockZ) {
|
||||
int hw = lightSourceBucketsWidth / 2;
|
||||
int hh = lightSourceBucketsHeight / 2;
|
||||
int bucketX = (relativeBlockX >> 4) + hw;
|
||||
int bucketY = (relativeBlockY >> 4) + hh;
|
||||
int bucketZ = (relativeBlockZ >> 4) + hw;
|
||||
if(bucketX >= 0 && bucketY >= 0 && bucketZ >= 0 && bucketX < lightSourceBucketsWidth
|
||||
&& bucketY < lightSourceBucketsHeight && bucketZ < lightSourceBucketsWidth) {
|
||||
currentLightSourceBucket = lightSourceBuckets[bucketY * lightSourceBucketsWidth * lightSourceBucketsWidth
|
||||
+ bucketZ * lightSourceBucketsWidth + bucketX];
|
||||
}else {
|
||||
currentLightSourceBucket = null;
|
||||
}
|
||||
updateLightSourceUBO();
|
||||
}
|
||||
|
||||
public ListSerial<DynamicLightInstance> getLightSourceBucketRelativeChunkCoords(int cx, int cy, int cz) {
|
||||
int hw = lightSourceBucketsWidth / 2;
|
||||
int hh = lightSourceBucketsHeight / 2;
|
||||
cx += hw;
|
||||
cy += hh;
|
||||
cz += hw;
|
||||
if(cx < 0 || cx >= lightSourceBucketsWidth || cy < 0 || cy >= lightSourceBucketsHeight || cz < 0
|
||||
|| cz >= lightSourceBucketsWidth) {
|
||||
return null;
|
||||
}else {
|
||||
return lightSourceBuckets[cy * lightSourceBucketsWidth * lightSourceBucketsWidth
|
||||
+ cz * lightSourceBucketsWidth + cx];
|
||||
}
|
||||
}
|
||||
|
||||
public void addLightSourceToBucket(int cx, int cy, int cz, DynamicLightInstance dl) {
|
||||
ListSerial<DynamicLightInstance> lst = getLightSourceBucketRelativeChunkCoords(cx, cy, cz);
|
||||
if(lst != null) {
|
||||
lst.add(dl);
|
||||
}
|
||||
}
|
||||
|
||||
public void bucketLightSource(float x, float y, float z, DynamicLightInstance dl) {
|
||||
int bucketX = MathHelper.floor_float(x / 16.0f);
|
||||
int bucketY = MathHelper.floor_float(y / 16.0f);
|
||||
int bucketZ = MathHelper.floor_float(z / 16.0f);
|
||||
addLightSourceToBucket(bucketX, bucketY, bucketZ, dl);
|
||||
int minX = bucketX, maxX = bucketX;
|
||||
int minY = bucketY, maxY = bucketY;
|
||||
int minZ = bucketZ, maxZ = bucketZ;
|
||||
float lightLocalX = x - (bucketX << 4);
|
||||
float lightLocalY = y - (bucketY << 4);
|
||||
float lightLocalZ = z - (bucketZ << 4);
|
||||
float radius = dl.radius;
|
||||
boolean outOfBounds = false;
|
||||
if(lightLocalX - radius < 0.0f) {
|
||||
minX -= 1;
|
||||
outOfBounds = true;
|
||||
addLightSourceToBucket(bucketX - 1, bucketY, bucketZ, dl);
|
||||
}
|
||||
if(lightLocalY - radius < 0.0f) {
|
||||
minY -= 1;
|
||||
outOfBounds = true;
|
||||
addLightSourceToBucket(bucketX, bucketY - 1, bucketZ, dl);
|
||||
}
|
||||
if(lightLocalZ - radius < 0.0f) {
|
||||
minZ -= 1;
|
||||
outOfBounds = true;
|
||||
addLightSourceToBucket(bucketX, bucketY, bucketZ - 1, dl);
|
||||
}
|
||||
if(lightLocalX + radius >= 16.0f) {
|
||||
maxX += 1;
|
||||
outOfBounds = true;
|
||||
addLightSourceToBucket(bucketX + 1, bucketY, bucketZ, dl);
|
||||
}
|
||||
if(lightLocalY + radius >= 16.0f) {
|
||||
maxY += 1;
|
||||
outOfBounds = true;
|
||||
addLightSourceToBucket(bucketX, bucketY + 1, bucketZ, dl);
|
||||
}
|
||||
if(lightLocalZ + radius >= 16.0f) {
|
||||
maxZ += 1;
|
||||
outOfBounds = true;
|
||||
addLightSourceToBucket(bucketX, bucketY, bucketZ + 1, dl);
|
||||
}
|
||||
if(!outOfBounds) {
|
||||
return;
|
||||
}
|
||||
radius *= radius;
|
||||
for(int yy = minY; yy <= maxY; ++yy) {
|
||||
for(int zz = minZ; zz <= maxZ; ++zz) {
|
||||
for(int xx = minX; xx <= maxX; ++xx) {
|
||||
if((xx == bucketX ? 1 : 0) + (yy == bucketY ? 1 : 0) + (zz == bucketZ ? 1 : 0) > 1) {
|
||||
continue;
|
||||
}
|
||||
List<DynamicLightInstance> lst = getLightSourceBucketRelativeChunkCoords(xx, yy, zz);
|
||||
if(lst != null) {
|
||||
int bucketBoundsX = xx << 4;
|
||||
int bucketBoundsY = yy << 4;
|
||||
int bucketBoundsZ = zz << 4;
|
||||
if (EaglerDeferredPipeline.testAabSphere(bucketBoundsX, bucketBoundsY, bucketBoundsZ,
|
||||
bucketBoundsX + 16, bucketBoundsY + 16, bucketBoundsZ + 16, x, y, z, radius)) {
|
||||
lst.add(dl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void truncateOverflowingBuffers() {
|
||||
for(int i = 0; i < this.lightSourceBuckets.length; ++i) {
|
||||
List<DynamicLightInstance> lst = this.lightSourceBuckets[i];
|
||||
int k = lst.size();
|
||||
if(k > MAX_LIGHTS_PER_CHUNK) {
|
||||
lst.sort(comparatorLightRadius);
|
||||
for(int l = MAX_LIGHTS_PER_CHUNK - 1; l >= MAX_LIGHTS_PER_CHUNK; --l) {
|
||||
lst.remove(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateLightSourceUBO() {
|
||||
if(currentLightSourceBucket == null) {
|
||||
currentBoundLightSourceBucket = null;
|
||||
if(isChunkLightingEnabled) {
|
||||
isChunkLightingEnabled = false;
|
||||
EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingData);
|
||||
chunkLightingDataCopyBuffer.clear();
|
||||
chunkLightingDataCopyBuffer.putInt(0);
|
||||
chunkLightingDataCopyBuffer.flip();
|
||||
_wglBufferSubData(_GL_UNIFORM_BUFFER, 0, chunkLightingDataCopyBuffer);
|
||||
}
|
||||
}else {
|
||||
boolean isNew;
|
||||
if(!isChunkLightingEnabled) {
|
||||
isChunkLightingEnabled = true;
|
||||
isNew = true;
|
||||
}else {
|
||||
isNew = currentLightSourceBucket != currentBoundLightSourceBucket;
|
||||
}
|
||||
currentBoundLightSourceBucket = currentLightSourceBucket;
|
||||
if(isNew || currentBoundLightSourceBucket.eaglerCheck()) {
|
||||
populateLightSourceUBOFromBucket(currentBoundLightSourceBucket);
|
||||
currentBoundLightSourceBucket.eaglerResetCheck();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final Comparator<DynamicLightInstance> comparatorLightRadius = (l1, l2) -> {
|
||||
return l1.radius < l2.radius ? 1 : -1;
|
||||
};
|
||||
|
||||
private void populateLightSourceUBOFromBucket(List<DynamicLightInstance> lights) {
|
||||
int max = lights.size();
|
||||
if(max > MAX_LIGHTS_PER_CHUNK) {
|
||||
//tmpListLights.clear();
|
||||
//tmpListLights.addAll(lights);
|
||||
//lights = tmpListLights;
|
||||
//lights.sort(comparatorLightRadius);
|
||||
max = MAX_LIGHTS_PER_CHUNK;
|
||||
}
|
||||
chunkLightingDataCopyBuffer.clear();
|
||||
chunkLightingDataCopyBuffer.putInt(max);
|
||||
if(max > 0) {
|
||||
chunkLightingDataCopyBuffer.putInt(0); //padding
|
||||
chunkLightingDataCopyBuffer.putInt(0); //padding
|
||||
chunkLightingDataCopyBuffer.putInt(0); //padding
|
||||
for(int i = 0; i < max; ++i) {
|
||||
DynamicLightInstance dl = lights.get(i);
|
||||
chunkLightingDataCopyBuffer.putFloat((float)(dl.posX - currentRenderX));
|
||||
chunkLightingDataCopyBuffer.putFloat((float)(dl.posY - currentRenderY));
|
||||
chunkLightingDataCopyBuffer.putFloat((float)(dl.posZ - currentRenderZ));
|
||||
chunkLightingDataCopyBuffer.putFloat(dl.radius);
|
||||
}
|
||||
}
|
||||
chunkLightingDataCopyBuffer.flip();
|
||||
EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingData);
|
||||
_wglBufferSubData(_GL_UNIFORM_BUFFER, 0, chunkLightingDataCopyBuffer);
|
||||
}
|
||||
|
||||
public void setRenderPos(double currentRenderX, double currentRenderY, double currentRenderZ) {
|
||||
this.currentRenderX = currentRenderX;
|
||||
this.currentRenderY = currentRenderY;
|
||||
this.currentRenderZ = currentRenderZ;
|
||||
}
|
||||
|
||||
public void bindUniformBuffer(int index) {
|
||||
EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingData);
|
||||
EaglercraftGPU.bindUniformBufferRange(index, buffer_chunkLightingData, 0, chunkLightingDataCopyBuffer.capacity());
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
if(chunkLightingDataCopyBuffer != null) {
|
||||
EagRuntime.freeByteBuffer(chunkLightingDataCopyBuffer);
|
||||
chunkLightingDataCopyBuffer = null;
|
||||
}
|
||||
if(buffer_chunkLightingData != null) {
|
||||
_wglDeleteBuffers(buffer_chunkLightingData);
|
||||
buffer_chunkLightingData = null;
|
||||
}
|
||||
for(int i = 0; i < this.lightSourceBuckets.length; ++i) {
|
||||
this.lightSourceBuckets[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
class DynamicLightInstance {
|
||||
|
||||
public final String lightName;
|
||||
long lastCacheHit = 0l;
|
||||
|
||||
double posX;
|
||||
double posY;
|
||||
double posZ;
|
||||
float radius;
|
||||
|
||||
public DynamicLightInstance(String lightName) {
|
||||
this.lightName = lightName;
|
||||
}
|
||||
|
||||
public void updateLight(double posX, double posY, double posZ, float radius) {
|
||||
this.lastCacheHit = System.currentTimeMillis();
|
||||
this.posX = posX;
|
||||
this.posY = posY;
|
||||
this.posZ = posZ;
|
||||
this.radius = radius;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
|
||||
public float getRadiusInWorld() {
|
||||
return radius;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,230 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights;
|
||||
|
||||
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
|
||||
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IBufferArrayGL;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IBufferGL;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.buffer.FloatBuffer;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.EaglercraftGPU;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.InstancedParticleRenderer;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.AbstractAcceleratedEffectRenderer;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights.program.DynamicLightsAccelParticleShader;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.GLAllocation;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.MathHelper;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class DynamicLightsAcceleratedEffectRenderer extends AbstractAcceleratedEffectRenderer {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger("DynamicLightsAcceleratedEffectRenderer");
|
||||
|
||||
private ByteBuffer particleBuffer = null;
|
||||
private int particleCount = 0;
|
||||
private boolean particlesHasOverflowed = false;
|
||||
|
||||
private static final int BYTES_PER_PARTICLE = 24;
|
||||
private static final int PARTICLE_LIMIT = 5461;
|
||||
|
||||
private DynamicLightsAccelParticleShader shaderProgram = null;
|
||||
|
||||
private IBufferArrayGL vertexArray = null;
|
||||
private IBufferGL vertexBuffer = null;
|
||||
|
||||
private IBufferGL instancesBuffer = null;
|
||||
|
||||
private float f1;
|
||||
private float f2;
|
||||
private float f3;
|
||||
private float f4;
|
||||
private float f5;
|
||||
|
||||
public static boolean isMaterialNormalTexture = false;
|
||||
|
||||
public void initialize() {
|
||||
destroy();
|
||||
|
||||
if(DynamicLightsPipelineCompiler.matrixCopyBuffer == null) {
|
||||
DynamicLightsPipelineCompiler.matrixCopyBuffer = GLAllocation.createDirectFloatBuffer(16);
|
||||
}
|
||||
|
||||
shaderProgram = DynamicLightsAccelParticleShader.compile();
|
||||
shaderProgram.loadUniforms();
|
||||
|
||||
particleBuffer = EagRuntime.allocateByteBuffer(PARTICLE_LIMIT * BYTES_PER_PARTICLE);
|
||||
|
||||
vertexArray = _wglGenVertexArrays();
|
||||
vertexBuffer = _wglGenBuffers();
|
||||
instancesBuffer = _wglGenBuffers();
|
||||
|
||||
FloatBuffer verts = EagRuntime.allocateFloatBuffer(12);
|
||||
verts.put(new float[] {
|
||||
-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f,
|
||||
-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f
|
||||
});
|
||||
verts.flip();
|
||||
|
||||
EaglercraftGPU.bindGLBufferArray(vertexArray);
|
||||
|
||||
EaglercraftGPU.bindGLArrayBuffer(vertexBuffer);
|
||||
_wglBufferData(GL_ARRAY_BUFFER, verts, GL_STATIC_DRAW);
|
||||
|
||||
EagRuntime.freeFloatBuffer(verts);
|
||||
|
||||
_wglEnableVertexAttribArray(0);
|
||||
_wglVertexAttribPointer(0, 2, GL_FLOAT, false, 8, 0);
|
||||
_wglVertexAttribDivisor(0, 0);
|
||||
|
||||
EaglercraftGPU.bindGLArrayBuffer(instancesBuffer);
|
||||
_wglBufferData(GL_ARRAY_BUFFER, particleBuffer.remaining(), GL_STREAM_DRAW);
|
||||
|
||||
_wglEnableVertexAttribArray(1);
|
||||
_wglVertexAttribPointer(1, 3, GL_FLOAT, false, 24, 0);
|
||||
_wglVertexAttribDivisor(1, 1);
|
||||
|
||||
_wglEnableVertexAttribArray(2);
|
||||
_wglVertexAttribPointer(2, 2, GL_UNSIGNED_SHORT, false, 24, 12);
|
||||
_wglVertexAttribDivisor(2, 1);
|
||||
|
||||
_wglEnableVertexAttribArray(3);
|
||||
_wglVertexAttribPointer(3, 2, GL_UNSIGNED_BYTE, true, 24, 16);
|
||||
_wglVertexAttribDivisor(3, 1);
|
||||
|
||||
_wglEnableVertexAttribArray(4);
|
||||
_wglVertexAttribPointer(4, 2, GL_UNSIGNED_BYTE, false, 24, 18);
|
||||
_wglVertexAttribDivisor(4, 1);
|
||||
|
||||
_wglEnableVertexAttribArray(5);
|
||||
_wglVertexAttribPointer(5, 4, GL_UNSIGNED_BYTE, true, 24, 20);
|
||||
_wglVertexAttribDivisor(5, 1);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(float texCoordWidth, float texCoordHeight) {
|
||||
if(particleCount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
shaderProgram.useProgram();
|
||||
|
||||
_wglUniform3f(shaderProgram.uniforms.u_texCoordSize2f_particleSize1f, texCoordWidth, texCoordHeight, 0.0625f);
|
||||
_wglUniform3f(shaderProgram.uniforms.u_transformParam_1_2_5_f, f1, f5, f4);
|
||||
_wglUniform2f(shaderProgram.uniforms.u_transformParam_3_4_f, f2, f3);
|
||||
InstancedParticleRenderer.stupidColorSetHack(shaderProgram.uniforms.u_color4f);
|
||||
|
||||
FloatBuffer buf = DynamicLightsPipelineCompiler.matrixCopyBuffer;
|
||||
buf.clear();
|
||||
GlStateManager.getFloat(GL_MODELVIEW_MATRIX, buf);
|
||||
buf.flip();
|
||||
_wglUniformMatrix4fv(shaderProgram.uniforms.u_modelViewMatrix4f, false, buf);
|
||||
buf.clear();
|
||||
GlStateManager.getFloat(GL_PROJECTION_MATRIX, buf);
|
||||
buf.flip();
|
||||
_wglUniformMatrix4fv(shaderProgram.uniforms.u_projectionMatrix4f, false, buf);
|
||||
buf.clear();
|
||||
DynamicLightsStateManager.inverseViewMatrix.store(buf);
|
||||
buf.flip();
|
||||
_wglUniformMatrix4fv(shaderProgram.uniforms.u_inverseViewMatrix4f, false, buf);
|
||||
|
||||
EaglercraftGPU.bindGLArrayBuffer(instancesBuffer);
|
||||
EaglercraftGPU.bindGLBufferArray(vertexArray);
|
||||
|
||||
int p = particleBuffer.position();
|
||||
int l = particleBuffer.limit();
|
||||
|
||||
particleBuffer.flip();
|
||||
_wglBufferSubData(GL_ARRAY_BUFFER, 0, particleBuffer);
|
||||
|
||||
particleBuffer.position(p);
|
||||
particleBuffer.limit(l);
|
||||
|
||||
_wglDrawArraysInstanced(GL_TRIANGLES, 0, 6, particleCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void begin(float partialTicks) {
|
||||
this.partialTicks = partialTicks;
|
||||
|
||||
particleBuffer.clear();
|
||||
particleCount = 0;
|
||||
particlesHasOverflowed = false;
|
||||
|
||||
Entity et = Minecraft.getMinecraft().getRenderViewEntity();
|
||||
if(et != null) {
|
||||
f1 = MathHelper.cos(et.rotationYaw * 0.017453292F);
|
||||
f2 = MathHelper.sin(et.rotationYaw * 0.017453292F);
|
||||
f3 = -f2 * MathHelper.sin(et.rotationPitch * 0.017453292F);
|
||||
f4 = f1 * MathHelper.sin(et.rotationPitch * 0.017453292F);
|
||||
f5 = MathHelper.cos(et.rotationPitch * 0.017453292F);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawParticle(float posX, float posY, float posZ, int particleIndexX, int particleIndexY,
|
||||
int lightMapData, int texSize, float particleSize, int rgba) {
|
||||
if(particlesHasOverflowed) {
|
||||
return;
|
||||
}
|
||||
if(particleCount >= PARTICLE_LIMIT) {
|
||||
particlesHasOverflowed = true;
|
||||
logger.error("Particle buffer has overflowed! Exceeded {} particles, no more particles will be rendered.", PARTICLE_LIMIT);
|
||||
return;
|
||||
}
|
||||
++particleCount;
|
||||
ByteBuffer buf = particleBuffer;
|
||||
buf.putFloat(posX);
|
||||
buf.putFloat(posY);
|
||||
buf.putFloat(posZ);
|
||||
buf.putShort((short)particleIndexX);
|
||||
buf.putShort((short)particleIndexY);
|
||||
buf.put((byte)(lightMapData & 0xFF));
|
||||
buf.put((byte)((lightMapData >> 16) & 0xFF));
|
||||
buf.put((byte)(particleSize * 16.0f));
|
||||
buf.put((byte)texSize);
|
||||
buf.putInt(rgba);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
if(particleBuffer != null) {
|
||||
EagRuntime.freeByteBuffer(particleBuffer);
|
||||
particleBuffer = null;
|
||||
}
|
||||
if(shaderProgram != null) {
|
||||
shaderProgram.destroy();
|
||||
shaderProgram = null;
|
||||
}
|
||||
if(vertexArray != null) {
|
||||
_wglDeleteVertexArrays(vertexArray);
|
||||
vertexArray = null;
|
||||
}
|
||||
if(vertexBuffer != null) {
|
||||
_wglDeleteBuffers(vertexBuffer);
|
||||
vertexBuffer = null;
|
||||
}
|
||||
if(instancesBuffer != null) {
|
||||
_wglDeleteBuffers(instancesBuffer);
|
||||
instancesBuffer = null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights;
|
||||
|
||||
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IProgramGL;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.buffer.FloatBuffer;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.FixedFunctionShader.FixedFunctionState;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.IExtPipelineCompiler;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.program.ShaderSource;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights.program.DynamicLightsExtPipelineShader;
|
||||
import net.lax1dude.eaglercraft.v1_8.vector.Matrix4f;
|
||||
import net.minecraft.client.renderer.GLAllocation;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class DynamicLightsPipelineCompiler implements IExtPipelineCompiler {
|
||||
|
||||
static FloatBuffer matrixCopyBuffer = null;
|
||||
|
||||
private static class PipelineInstance {
|
||||
|
||||
private final int coreBits;
|
||||
private final int extBits;
|
||||
|
||||
private DynamicLightsExtPipelineShader shader;
|
||||
|
||||
public PipelineInstance(int coreBits, int extBits) {
|
||||
this.coreBits = coreBits;
|
||||
this.extBits = extBits;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getShaderSource(int stateCoreBits, int stateExtBits, Object[] userPointer) {
|
||||
if(matrixCopyBuffer == null) {
|
||||
matrixCopyBuffer = GLAllocation.createDirectFloatBuffer(16);
|
||||
}
|
||||
userPointer[0] = new PipelineInstance(stateCoreBits, stateExtBits);
|
||||
return new String[] {
|
||||
ShaderSource.getSourceFor(ShaderSource.core_dynamiclights_vsh),
|
||||
ShaderSource.getSourceFor(ShaderSource.core_dynamiclights_fsh)
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getExtensionStatesCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentExtensionStateBits(int stateCoreBits) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCoreStateMask(int stateExtBits) {
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeNewShader(IProgramGL compiledProg, int stateCoreBits, int stateExtBits,
|
||||
Object[] userPointer) {
|
||||
DynamicLightsExtPipelineShader newShader = new DynamicLightsExtPipelineShader(compiledProg, stateCoreBits);
|
||||
((PipelineInstance)userPointer[0]).shader = newShader;
|
||||
newShader.loadUniforms();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePipeline(IProgramGL compiledProg, int stateCoreBits, int stateExtBits, Object[] userPointer) {
|
||||
if((stateCoreBits & FixedFunctionState.STATE_ENABLE_LIGHTMAP) != 0) {
|
||||
DynamicLightsExtPipelineShader.Uniforms uniforms = ((PipelineInstance)userPointer[0]).shader.uniforms;
|
||||
if(uniforms.u_inverseViewMatrix4f != null) {
|
||||
int serial = DynamicLightsStateManager.inverseViewMatrixSerial;
|
||||
if(uniforms.inverseViewMatrixSerial != serial) {
|
||||
uniforms.inverseViewMatrixSerial = serial;
|
||||
FloatBuffer buf = matrixCopyBuffer;
|
||||
buf.clear();
|
||||
DynamicLightsStateManager.inverseViewMatrix.store(buf);
|
||||
buf.flip();
|
||||
_wglUniformMatrix4fv(uniforms.u_inverseViewMatrix4f, false, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyPipeline(IProgramGL shaderProgram, int stateCoreBits, int stateExtBits, Object[] userPointer) {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,169 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.FixedFunctionPipeline;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.vector.Matrix4f;
|
||||
import net.minecraft.client.particle.EffectRenderer;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||
import net.minecraft.util.MathHelper;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class DynamicLightsStateManager {
|
||||
|
||||
static final DynamicLightsPipelineCompiler deferredExtPipeline = new DynamicLightsPipelineCompiler();
|
||||
static final Map<String, DynamicLightInstance> lightRenderers = new HashMap();
|
||||
static final List<DynamicLightInstance> lightRenderList = new LinkedList();
|
||||
static final Matrix4f inverseViewMatrix = new Matrix4f();
|
||||
static int inverseViewMatrixSerial = 0;
|
||||
static DynamicLightBucketLoader bucketLoader = null;
|
||||
static DynamicLightsAcceleratedEffectRenderer accelParticleRenderer = null;
|
||||
static int lastTotal = 0;
|
||||
static long renderTimeout = 5000l;
|
||||
private static long lastTick = 0l;
|
||||
|
||||
public static final void enableDynamicLightsRender() {
|
||||
if(bucketLoader == null) {
|
||||
bucketLoader = new DynamicLightBucketLoader();
|
||||
bucketLoader.initialize();
|
||||
bucketLoader.bindUniformBuffer(0);
|
||||
FixedFunctionPipeline.loadExtensionPipeline(deferredExtPipeline);
|
||||
}
|
||||
if(accelParticleRenderer == null) {
|
||||
accelParticleRenderer = new DynamicLightsAcceleratedEffectRenderer();
|
||||
accelParticleRenderer.initialize();
|
||||
}
|
||||
}
|
||||
|
||||
public static final void bindAcceleratedEffectRenderer(EffectRenderer renderer) {
|
||||
renderer.acceleratedParticleRenderer = accelParticleRenderer;
|
||||
}
|
||||
|
||||
public static final void disableDynamicLightsRender(boolean unloadPipeline) {
|
||||
if(bucketLoader != null) {
|
||||
bucketLoader.destroy();
|
||||
bucketLoader = null;
|
||||
if(unloadPipeline) {
|
||||
FixedFunctionPipeline.loadExtensionPipeline(null);
|
||||
}
|
||||
}
|
||||
if(accelParticleRenderer != null) {
|
||||
accelParticleRenderer.destroy();
|
||||
accelParticleRenderer = null;
|
||||
}
|
||||
destroyAll();
|
||||
lightRenderList.clear();
|
||||
}
|
||||
|
||||
public static final boolean isDynamicLightsRender() {
|
||||
return bucketLoader != null;
|
||||
}
|
||||
|
||||
public static final boolean isInDynamicLightsPass() {
|
||||
return GlStateManager.isExtensionPipeline() && bucketLoader != null;
|
||||
}
|
||||
|
||||
public static final void reportForwardRenderObjectPosition(int centerX, int centerY, int centerZ) {
|
||||
if(bucketLoader != null) {
|
||||
bucketLoader.loadLightSourceBucket(centerX, centerY, centerZ);
|
||||
}
|
||||
}
|
||||
|
||||
public static final void reportForwardRenderObjectPosition2(float x, float y, float z) {
|
||||
if(bucketLoader != null) {
|
||||
float posX = (float)((x + TileEntityRendererDispatcher.staticPlayerX) - (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerX / 16.0) << 4));
|
||||
float posY = (float)((y + TileEntityRendererDispatcher.staticPlayerY) - (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerY / 16.0) << 4));
|
||||
float posZ = (float)((z + TileEntityRendererDispatcher.staticPlayerZ) - (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerZ / 16.0) << 4));
|
||||
bucketLoader.loadLightSourceBucket((int)posX, (int)posY, (int)posZ);
|
||||
}
|
||||
}
|
||||
|
||||
public static final void renderDynamicLight(String lightName, double posX, double posY, double posZ, float radius) {
|
||||
if(bucketLoader != null) {
|
||||
DynamicLightInstance dl = lightRenderers.get(lightName);
|
||||
if(dl == null) {
|
||||
lightRenderers.put(lightName, dl = new DynamicLightInstance(lightName));
|
||||
}
|
||||
dl.updateLight(posX, posY, posZ, radius);
|
||||
lightRenderList.add(dl);
|
||||
}
|
||||
}
|
||||
|
||||
public static final void clearRenderList() {
|
||||
lightRenderList.clear();
|
||||
}
|
||||
|
||||
public static final void commitLightSourceBuckets(double renderPosX, double renderPosY, double renderPosZ) {
|
||||
updateTimers();
|
||||
lastTotal = lightRenderList.size();
|
||||
if(bucketLoader != null) {
|
||||
bucketLoader.clearBuckets();
|
||||
int entityChunkOriginX = MathHelper.floor_double(renderPosX / 16.0) << 4;
|
||||
int entityChunkOriginY = MathHelper.floor_double(renderPosY / 16.0) << 4;
|
||||
int entityChunkOriginZ = MathHelper.floor_double(renderPosZ / 16.0) << 4;
|
||||
Iterator<DynamicLightInstance> itr = lightRenderList.iterator();
|
||||
while(itr.hasNext()) {
|
||||
DynamicLightInstance dl = itr.next();
|
||||
float lightChunkPosX = (float)(dl.posX - entityChunkOriginX);
|
||||
float lightChunkPosY = (float)(dl.posY - entityChunkOriginY);
|
||||
float lightChunkPosZ = (float)(dl.posZ - entityChunkOriginZ);
|
||||
bucketLoader.bucketLightSource(lightChunkPosX, lightChunkPosY, lightChunkPosZ, dl);
|
||||
}
|
||||
bucketLoader.setRenderPos(renderPosX, renderPosY, renderPosZ);
|
||||
bucketLoader.truncateOverflowingBuffers();
|
||||
}
|
||||
lightRenderList.clear();
|
||||
}
|
||||
|
||||
public static final void setupInverseViewMatrix() {
|
||||
Matrix4f.invert(GlStateManager.getModelViewReference(), inverseViewMatrix);
|
||||
inverseViewMatrixSerial = GlStateManager.getModelViewSerial();
|
||||
}
|
||||
|
||||
private static final void updateTimers() {
|
||||
long millis = System.currentTimeMillis();
|
||||
if(millis - lastTick > 1000l) {
|
||||
lastTick = millis;
|
||||
Iterator<DynamicLightInstance> itr = lightRenderers.values().iterator();
|
||||
while(itr.hasNext()) {
|
||||
DynamicLightInstance dl = itr.next();
|
||||
if(millis - dl.lastCacheHit > renderTimeout) {
|
||||
dl.destroy();
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final void destroyAll() {
|
||||
Iterator<DynamicLightInstance> itr = lightRenderers.values().iterator();
|
||||
while(itr.hasNext()) {
|
||||
itr.next().destroy();
|
||||
}
|
||||
lightRenderers.clear();
|
||||
}
|
||||
|
||||
public static String getF3String() {
|
||||
return "DynamicLightsTotal: " + lastTotal;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights.program;
|
||||
|
||||
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
|
||||
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.GL_FRAGMENT_SHADER;
|
||||
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.GL_VERTEX_SHADER;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IProgramGL;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IShaderGL;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IUniformGL;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.program.IProgramUniforms;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.program.ShaderCompiler;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.program.ShaderProgram;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.program.ShaderSource;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class DynamicLightsAccelParticleShader extends ShaderProgram<DynamicLightsAccelParticleShader.Uniforms> {
|
||||
|
||||
public static DynamicLightsAccelParticleShader compile() {
|
||||
IShaderGL accelParticleVSH = ShaderCompiler.compileShader("accel_particle_dynamiclights", GL_VERTEX_SHADER,
|
||||
ShaderSource.accel_particle_dynamiclights_vsh);
|
||||
IShaderGL accelParticleFSH = null;
|
||||
try {
|
||||
accelParticleFSH = ShaderCompiler.compileShader("accel_particle_dynamiclights", GL_FRAGMENT_SHADER,
|
||||
ShaderSource.accel_particle_dynamiclights_fsh);
|
||||
IProgramGL prog = ShaderCompiler.linkProgram("accel_particle_dynamiclights", accelParticleVSH, accelParticleFSH);
|
||||
return new DynamicLightsAccelParticleShader(prog);
|
||||
}finally {
|
||||
if(accelParticleVSH != null) {
|
||||
accelParticleVSH.free();
|
||||
}
|
||||
if(accelParticleFSH != null) {
|
||||
accelParticleFSH.free();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private DynamicLightsAccelParticleShader(IProgramGL prog) {
|
||||
super(prog, new Uniforms());
|
||||
}
|
||||
|
||||
public static class Uniforms implements IProgramUniforms {
|
||||
|
||||
public IUniformGL u_color4f = null;
|
||||
public IUniformGL u_modelViewMatrix4f = null;
|
||||
public IUniformGL u_projectionMatrix4f = null;
|
||||
public IUniformGL u_inverseViewMatrix4f = null;
|
||||
public IUniformGL u_texCoordSize2f_particleSize1f = null;
|
||||
public IUniformGL u_transformParam_1_2_5_f = null;
|
||||
public IUniformGL u_transformParam_3_4_f = null;
|
||||
|
||||
public int u_chunkLightingDataBlockBinding = -1;
|
||||
|
||||
private Uniforms() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadUniforms(IProgramGL prog) {
|
||||
u_modelViewMatrix4f = _wglGetUniformLocation(prog, "u_modelViewMatrix4f");
|
||||
u_projectionMatrix4f = _wglGetUniformLocation(prog, "u_projectionMatrix4f");
|
||||
u_inverseViewMatrix4f = _wglGetUniformLocation(prog, "u_inverseViewMatrix4f");
|
||||
u_texCoordSize2f_particleSize1f = _wglGetUniformLocation(prog, "u_texCoordSize2f_particleSize1f");
|
||||
u_transformParam_1_2_5_f = _wglGetUniformLocation(prog, "u_transformParam_1_2_5_f");
|
||||
u_transformParam_3_4_f = _wglGetUniformLocation(prog, "u_transformParam_3_4_f");
|
||||
u_color4f = _wglGetUniformLocation(prog, "u_color4f");
|
||||
_wglUniform1i(_wglGetUniformLocation(prog, "u_inputTexture"), 0);
|
||||
_wglUniform1i(_wglGetUniformLocation(prog, "u_lightmapTexture"), 1);
|
||||
int blockIndex = _wglGetUniformBlockIndex(prog, "u_chunkLightingData");
|
||||
if(blockIndex != -1) {
|
||||
_wglUniformBlockBinding(prog, blockIndex, 0);
|
||||
u_chunkLightingDataBlockBinding = 0;
|
||||
}else {
|
||||
u_chunkLightingDataBlockBinding = -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights.program;
|
||||
|
||||
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IProgramGL;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IUniformGL;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.program.IProgramUniforms;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.program.ShaderProgram;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class DynamicLightsExtPipelineShader extends ShaderProgram<DynamicLightsExtPipelineShader.Uniforms> {
|
||||
|
||||
public final int coreState;
|
||||
|
||||
public DynamicLightsExtPipelineShader(IProgramGL program, int coreState) {
|
||||
super(program, new Uniforms());
|
||||
this.coreState = coreState;
|
||||
}
|
||||
|
||||
public static class Uniforms implements IProgramUniforms {
|
||||
|
||||
public int u_chunkLightingDataBlockBinding = -1;
|
||||
|
||||
public int inverseViewMatrixSerial = -1;
|
||||
public IUniformGL u_inverseViewMatrix4f = null;
|
||||
|
||||
Uniforms() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadUniforms(IProgramGL prog) {
|
||||
u_inverseViewMatrix4f = _wglGetUniformLocation(prog, "u_inverseViewMatrix4f");
|
||||
int blockIndex = _wglGetUniformBlockIndex(prog, "u_chunkLightingData");
|
||||
if(blockIndex != -1) {
|
||||
_wglUniformBlockBinding(prog, blockIndex, 0);
|
||||
u_chunkLightingDataBlockBinding = 0;
|
||||
}else {
|
||||
u_chunkLightingDataBlockBinding = -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user