mirror of
https://github.com/Eaglercraft-Archive/Eaglercraftx-1.8.8-src.git
synced 2025-06-27 18:38:14 -05:00
Update #37 - Touch support without userscript, many other feats
This commit is contained in:
@ -3,15 +3,16 @@ package net.lax1dude.eaglercraft.v1_8.opengl;
|
||||
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
|
||||
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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.IShaderGL;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.buffer.FloatBuffer;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.FixedFunctionShader.FixedFunctionConstants;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude. All Rights Reserved.
|
||||
* Copyright (c) 2022-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
|
||||
@ -28,17 +29,19 @@ import net.lax1dude.eaglercraft.v1_8.opengl.FixedFunctionShader.FixedFunctionCon
|
||||
public class DrawUtils {
|
||||
|
||||
public static final String vertexShaderPath = "/assets/eagler/glsl/local.vsh";
|
||||
public static final String vertexShaderPrecision = "precision highp float;\n";
|
||||
|
||||
public static IBufferArrayGL standardQuad2DVAO = null;
|
||||
public static IBufferArrayGL standardQuad3DVAO = null;
|
||||
public static IBufferGL standardQuadVBO = null;
|
||||
|
||||
public static IShaderGL vshLocal = null;
|
||||
public static List<VSHInputLayoutParser.ShaderInput> vshLocalLayout = null;
|
||||
|
||||
static void init() {
|
||||
if(standardQuad2DVAO == null) {
|
||||
standardQuad2DVAO = _wglGenVertexArrays();
|
||||
standardQuad3DVAO = _wglGenVertexArrays();
|
||||
standardQuad2DVAO = EaglercraftGPU.createGLBufferArray();
|
||||
standardQuad3DVAO = EaglercraftGPU.createGLBufferArray();
|
||||
standardQuadVBO = _wglGenBuffers();
|
||||
|
||||
FloatBuffer verts = EagRuntime.allocateFloatBuffer(18);
|
||||
@ -48,30 +51,29 @@ public class DrawUtils {
|
||||
});
|
||||
verts.flip();
|
||||
|
||||
EaglercraftGPU.bindGLArrayBuffer(standardQuadVBO);
|
||||
EaglercraftGPU.bindVAOGLArrayBufferNow(standardQuadVBO);
|
||||
_wglBufferData(GL_ARRAY_BUFFER, verts, GL_STATIC_DRAW);
|
||||
EagRuntime.freeFloatBuffer(verts);
|
||||
|
||||
EaglercraftGPU.bindGLBufferArray(standardQuad2DVAO);
|
||||
|
||||
_wglEnableVertexAttribArray(0);
|
||||
_wglVertexAttribPointer(0, 2, GL_FLOAT, false, 12, 0);
|
||||
EaglercraftGPU.enableVertexAttribArray(0);
|
||||
EaglercraftGPU.vertexAttribPointer(0, 2, GL_FLOAT, false, 12, 0);
|
||||
|
||||
EaglercraftGPU.bindGLBufferArray(standardQuad3DVAO);
|
||||
|
||||
_wglEnableVertexAttribArray(0);
|
||||
_wglVertexAttribPointer(0, 3, GL_FLOAT, false, 12, 0);
|
||||
EaglercraftGPU.enableVertexAttribArray(0);
|
||||
EaglercraftGPU.vertexAttribPointer(0, 3, GL_FLOAT, false, 12, 0);
|
||||
}
|
||||
|
||||
if(vshLocal == null) {
|
||||
String vertexSource = EagRuntime.getResourceString(vertexShaderPath);
|
||||
if(vertexSource == null) {
|
||||
throw new RuntimeException("vertex shader \"" + vertexShaderPath + "\" is missing!");
|
||||
}
|
||||
|
||||
String vertexSource = EagRuntime.getRequiredResourceString(vertexShaderPath);
|
||||
|
||||
vshLocalLayout = VSHInputLayoutParser.getShaderInputs(vertexSource);
|
||||
|
||||
vshLocal = _wglCreateShader(GL_VERTEX_SHADER);
|
||||
|
||||
_wglShaderSource(vshLocal, FixedFunctionConstants.VERSION + "\n" + vertexSource);
|
||||
|
||||
_wglShaderSource(vshLocal, GLSLHeader.getVertexHeaderCompat(vertexSource, vertexShaderPrecision));
|
||||
_wglCompileShader(vshLocal);
|
||||
|
||||
if(_wglGetShaderi(vshLocal, GL_COMPILE_STATUS) != GL_TRUE) {
|
||||
@ -90,12 +92,32 @@ public class DrawUtils {
|
||||
|
||||
public static void drawStandardQuad2D() {
|
||||
EaglercraftGPU.bindGLBufferArray(standardQuad2DVAO);
|
||||
_wglDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
EaglercraftGPU.doDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
|
||||
public static void drawStandardQuad3D() {
|
||||
EaglercraftGPU.bindGLBufferArray(standardQuad3DVAO);
|
||||
_wglDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
EaglercraftGPU.doDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
|
||||
public static void destroy() {
|
||||
if(standardQuad2DVAO != null) {
|
||||
EaglercraftGPU.destroyGLBufferArray(standardQuad2DVAO);
|
||||
standardQuad2DVAO = null;
|
||||
}
|
||||
if(standardQuad3DVAO != null) {
|
||||
EaglercraftGPU.destroyGLBufferArray(standardQuad3DVAO);
|
||||
standardQuad3DVAO = null;
|
||||
}
|
||||
if(standardQuadVBO != null) {
|
||||
_wglDeleteBuffers(standardQuadVBO);
|
||||
standardQuadVBO = null;
|
||||
}
|
||||
if(vshLocal != null) {
|
||||
vshLocal.free();
|
||||
vshLocal = null;
|
||||
vshLocalLayout = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ public class EaglerMeshLoader implements IResourceManagerReloadListener {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger("EaglerMeshLoader");
|
||||
|
||||
private static final Map<ResourceLocation, HighPolyMesh> meshCache = new HashMap();
|
||||
private static final Map<ResourceLocation, HighPolyMesh> meshCache = new HashMap<>();
|
||||
|
||||
public static HighPolyMesh getEaglerMesh(ResourceLocation meshLoc) {
|
||||
if(meshLoc.cachedPointerType == ResourceLocation.CACHED_POINTER_EAGLER_MESH) {
|
||||
@ -104,7 +104,7 @@ public class EaglerMeshLoader implements IResourceManagerReloadListener {
|
||||
}
|
||||
|
||||
if(meshStruct.vertexArray == null) {
|
||||
meshStruct.vertexArray = _wglGenVertexArrays();
|
||||
meshStruct.vertexArray = EaglercraftGPU.createGLBufferArray();
|
||||
}
|
||||
if(meshStruct.vertexBuffer == null) {
|
||||
meshStruct.vertexBuffer = _wglGenBuffers();
|
||||
@ -115,29 +115,29 @@ public class EaglerMeshLoader implements IResourceManagerReloadListener {
|
||||
|
||||
up1.position(0).limit(intsOfVertex);
|
||||
|
||||
EaglercraftGPU.bindGLArrayBuffer(meshStruct.vertexBuffer);
|
||||
EaglercraftGPU.bindVAOGLArrayBufferNow(meshStruct.vertexBuffer);
|
||||
_wglBufferData(GL_ARRAY_BUFFER, up1, GL_STATIC_DRAW);
|
||||
|
||||
EaglercraftGPU.bindGLBufferArray(meshStruct.vertexArray);
|
||||
|
||||
up1.position(intsOfVertex).limit(intsTotal);
|
||||
|
||||
_wglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshStruct.indexBuffer);
|
||||
EaglercraftGPU.bindVAOGLElementArrayBufferNow(meshStruct.indexBuffer);
|
||||
_wglBufferData(GL_ELEMENT_ARRAY_BUFFER, up1, GL_STATIC_DRAW);
|
||||
|
||||
_wglEnableVertexAttribArray(0);
|
||||
_wglVertexAttribPointer(0, 3, GL_FLOAT, false, stride, 0);
|
||||
EaglercraftGPU.enableVertexAttribArray(0);
|
||||
EaglercraftGPU.vertexAttribPointer(0, 3, GL_FLOAT, false, stride, 0);
|
||||
|
||||
if(meshStruct.hasTexture) {
|
||||
_wglEnableVertexAttribArray(1);
|
||||
_wglVertexAttribPointer(1, 2, GL_FLOAT, false, stride, 16);
|
||||
EaglercraftGPU.enableVertexAttribArray(1);
|
||||
EaglercraftGPU.vertexAttribPointer(1, 2, GL_FLOAT, false, stride, 16);
|
||||
}
|
||||
|
||||
_wglEnableVertexAttribArray(meshStruct.hasTexture ? 2 : 1);
|
||||
_wglVertexAttribPointer(meshStruct.hasTexture ? 2 : 1, 4, GL_BYTE, true, stride, 12);
|
||||
EaglercraftGPU.enableVertexAttribArray(meshStruct.hasTexture ? 2 : 1);
|
||||
EaglercraftGPU.vertexAttribPointer(meshStruct.hasTexture ? 2 : 1, 4, GL_BYTE, true, stride, 12);
|
||||
}catch(Throwable ex) {
|
||||
if(meshStruct.vertexArray != null) {
|
||||
_wglDeleteVertexArrays(meshStruct.vertexArray);
|
||||
EaglercraftGPU.destroyGLBufferArray(meshStruct.vertexArray);
|
||||
meshStruct.vertexArray = null;
|
||||
}
|
||||
if(meshStruct.vertexBuffer != null) {
|
||||
|
@ -5,6 +5,7 @@ import net.lax1dude.eaglercraft.v1_8.internal.buffer.FloatBuffer;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.buffer.IntBuffer;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
import net.minecraft.util.MathHelper;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -16,7 +17,6 @@ import net.lax1dude.eaglercraft.v1_8.internal.IBufferGL;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IProgramGL;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IQueryGL;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.ITextureGL;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformBufferFunctions;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL;
|
||||
|
||||
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
|
||||
@ -39,12 +39,15 @@ import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
|
||||
*/
|
||||
public class EaglercraftGPU {
|
||||
|
||||
static final GLObjectMap<ITextureGL> mapTexturesGL = new GLObjectMap(32767);
|
||||
static final GLObjectMap<IQueryGL> mapQueriesGL = new GLObjectMap(32767);
|
||||
static final GLObjectMap<DisplayList> mapDisplayListsGL = new GLObjectMap(32767);
|
||||
static final GLObjectMap<ITextureGL> mapTexturesGL = new GLObjectMap<>(8192);
|
||||
static final GLObjectMap<IQueryGL> mapQueriesGL = new GLObjectMap<>(8192);
|
||||
static final GLObjectMap<DisplayList> mapDisplayListsGL = new GLObjectMap<>(8192);
|
||||
|
||||
static final Logger logger = LogManager.getLogger("EaglercraftGPU");
|
||||
|
||||
static boolean emulatedVAOs = false;
|
||||
static SoftGLBufferState emulatedVAOState = new SoftGLBufferState();
|
||||
|
||||
public static final String gluErrorString(int i) {
|
||||
switch(i) {
|
||||
case GL_INVALID_ENUM: return "GL_INVALID_ENUM";
|
||||
@ -87,16 +90,16 @@ public class EaglercraftGPU {
|
||||
EaglercraftGPU.bindGLBufferArray(dp.vertexArray);
|
||||
int c = 0;
|
||||
if((dp.attribs & ATTRIB_TEXTURE) == ATTRIB_TEXTURE) {
|
||||
_wglDisableVertexAttribArray(++c);
|
||||
EaglercraftGPU.disableVertexAttribArray(++c);
|
||||
}
|
||||
if((dp.attribs & ATTRIB_COLOR) == ATTRIB_COLOR) {
|
||||
_wglDisableVertexAttribArray(++c);
|
||||
EaglercraftGPU.disableVertexAttribArray(++c);
|
||||
}
|
||||
if((dp.attribs & ATTRIB_NORMAL) == ATTRIB_NORMAL) {
|
||||
_wglDisableVertexAttribArray(++c);
|
||||
EaglercraftGPU.disableVertexAttribArray(++c);
|
||||
}
|
||||
if((dp.attribs & ATTRIB_LIGHTMAP) == ATTRIB_LIGHTMAP) {
|
||||
_wglDisableVertexAttribArray(++c);
|
||||
EaglercraftGPU.disableVertexAttribArray(++c);
|
||||
}
|
||||
}
|
||||
dp.attribs = -1;
|
||||
@ -109,7 +112,7 @@ public class EaglercraftGPU {
|
||||
if(displayListBuffer.capacity() < wantSize) {
|
||||
int newSize = (wantSize & 0xFFFE0000) + 0x40000;
|
||||
ByteBuffer newBuffer = EagRuntime.allocateByteBuffer(newSize);
|
||||
PlatformBufferFunctions.put(newBuffer, (ByteBuffer)displayListBuffer.flip());
|
||||
newBuffer.put((ByteBuffer)displayListBuffer.flip());
|
||||
EagRuntime.freeByteBuffer(displayListBuffer);
|
||||
displayListBuffer = newBuffer;
|
||||
}
|
||||
@ -123,7 +126,7 @@ public class EaglercraftGPU {
|
||||
|
||||
if(dp.attribs == -1) {
|
||||
if(dp.vertexArray != null) {
|
||||
_wglDeleteVertexArrays(dp.vertexArray);
|
||||
EaglercraftGPU.destroyGLBufferArray(dp.vertexArray);
|
||||
dp.vertexArray = null;
|
||||
}
|
||||
if(dp.vertexBuffer != null) {
|
||||
@ -135,7 +138,7 @@ public class EaglercraftGPU {
|
||||
}
|
||||
|
||||
if(dp.vertexArray == null) {
|
||||
dp.vertexArray = _wglGenVertexArrays();
|
||||
dp.vertexArray = createGLBufferArray();
|
||||
dp.bindQuad16 = false;
|
||||
dp.bindQuad32 = false;
|
||||
}
|
||||
@ -143,7 +146,7 @@ public class EaglercraftGPU {
|
||||
dp.vertexBuffer = _wglGenBuffers();
|
||||
}
|
||||
|
||||
bindGLArrayBuffer(dp.vertexBuffer);
|
||||
bindVAOGLArrayBufferNow(dp.vertexBuffer);
|
||||
displayListBuffer.flip();
|
||||
_wglBufferData(GL_ARRAY_BUFFER, displayListBuffer, GL_STATIC_DRAW);
|
||||
displayListBuffer.clear();
|
||||
@ -194,7 +197,7 @@ public class EaglercraftGPU {
|
||||
}
|
||||
dp.attribs = -1;
|
||||
if(dp.vertexArray != null) {
|
||||
_wglDeleteVertexArrays(dp.vertexArray);
|
||||
EaglercraftGPU.destroyGLBufferArray(dp.vertexArray);
|
||||
dp.vertexArray = null;
|
||||
}
|
||||
if(dp.vertexBuffer != null) {
|
||||
@ -210,7 +213,7 @@ public class EaglercraftGPU {
|
||||
++GlStateManager.stateNormalSerial;
|
||||
}
|
||||
|
||||
private static final Map<Integer,String> stringCache = new HashMap();
|
||||
private static final Map<Integer,String> stringCache = new HashMap<>();
|
||||
|
||||
public static final String glGetString(int param) {
|
||||
String str = stringCache.get(param);
|
||||
@ -238,9 +241,24 @@ public class EaglercraftGPU {
|
||||
return _wglGetInteger(param);
|
||||
}
|
||||
|
||||
public static final void glTexImage2D(int target, int level, int internalFormat, int w, int h, int unused,
|
||||
int format, int type, ByteBuffer pixels) {
|
||||
if(glesVers >= 300) {
|
||||
_wglTexImage2D(target, level, internalFormat, w, h, unused, format, type, pixels);
|
||||
}else {
|
||||
int tv = TextureFormatHelper.trivializeInternalFormatToGLES20(internalFormat);
|
||||
_wglTexImage2D(target, level, tv, w, h, unused, tv, type, pixels);
|
||||
}
|
||||
}
|
||||
|
||||
public static final void glTexImage2D(int target, int level, int internalFormat, int w, int h, int unused,
|
||||
int format, int type, IntBuffer pixels) {
|
||||
_wglTexImage2D(target, level, internalFormat, w, h, unused, format, type, pixels);
|
||||
if(glesVers >= 300) {
|
||||
_wglTexImage2D(target, level, internalFormat, w, h, unused, format, type, pixels);
|
||||
}else {
|
||||
int tv = TextureFormatHelper.trivializeInternalFormatToGLES20(internalFormat);
|
||||
_wglTexImage2D(target, level, tv, w, h, unused, tv, type, pixels);
|
||||
}
|
||||
}
|
||||
|
||||
public static final void glTexSubImage2D(int target, int level, int x, int y, int w, int h, int format,
|
||||
@ -249,9 +267,32 @@ public class EaglercraftGPU {
|
||||
}
|
||||
|
||||
public static final void glTexStorage2D(int target, int levels, int internalFormat, int w, int h) {
|
||||
_wglTexStorage2D(target, levels, internalFormat, w, h);
|
||||
if(texStorageCapable && (glesVers >= 300 || levels == 1 || (MathHelper.calculateLogBaseTwo(Math.max(w, h)) + 1) == levels)) {
|
||||
_wglTexStorage2D(target, levels, internalFormat, w, h);
|
||||
}else {
|
||||
int tv = TextureFormatHelper.trivializeInternalFormatToGLES20(internalFormat);
|
||||
int type = TextureFormatHelper.getTypeFromInternal(internalFormat);
|
||||
for(int i = 0; i < levels; ++i) {
|
||||
_wglTexImage2D(target, i, tv, Math.max(w >> i, 1), Math.max(h >> i, 1), 0, tv, type, (ByteBuffer)null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static final void glReadPixels(int x, int y, int width, int height, int format, int type, ByteBuffer buffer) {
|
||||
switch(type) {
|
||||
case GL_FLOAT:
|
||||
_wglReadPixels(x, y, width, height, format, GL_FLOAT, buffer.asFloatBuffer());
|
||||
break;
|
||||
case 0x140B: // GL_HALF_FLOAT
|
||||
_wglReadPixels_u16(x, y, width, height, format, glesVers == 200 ? 0x8D61 : 0x140B, buffer);
|
||||
break;
|
||||
case GL_UNSIGNED_BYTE:
|
||||
default:
|
||||
_wglReadPixels(x, y, width, height, format, type, buffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static final void glLineWidth(float f) {
|
||||
_wglLineWidth(f);
|
||||
}
|
||||
@ -284,7 +325,7 @@ public class EaglercraftGPU {
|
||||
DisplayList d = mapDisplayListsGL.free(id);
|
||||
if(d != null) {
|
||||
if(d.vertexArray != null) {
|
||||
_wglDeleteVertexArrays(d.vertexArray);
|
||||
EaglercraftGPU.destroyGLBufferArray(d.vertexArray);
|
||||
}
|
||||
if(d.vertexBuffer != null) {
|
||||
_wglDeleteBuffers(d.vertexBuffer);
|
||||
@ -302,18 +343,197 @@ public class EaglercraftGPU {
|
||||
GlStateManager.stateBlendEquation = equation;
|
||||
}
|
||||
}
|
||||
|
||||
private static IBufferArrayGL currentBufferArray = null;
|
||||
|
||||
public static final void bindGLBufferArray(IBufferArrayGL buffer) {
|
||||
if(currentBufferArray != buffer) {
|
||||
_wglBindVertexArray(buffer);
|
||||
currentBufferArray = buffer;
|
||||
|
||||
public static final boolean areVAOsEmulated() {
|
||||
return emulatedVAOs;
|
||||
}
|
||||
|
||||
public static final IBufferArrayGL createGLBufferArray() {
|
||||
if(emulatedVAOs) {
|
||||
return new SoftGLBufferArray();
|
||||
}else {
|
||||
return _wglGenVertexArrays();
|
||||
}
|
||||
}
|
||||
|
||||
public static final void destroyGLBufferArray(IBufferArrayGL buffer) {
|
||||
if(!emulatedVAOs) {
|
||||
_wglDeleteVertexArrays(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public static final void enableVertexAttribArray(int index) {
|
||||
if(emulatedVAOs) {
|
||||
if(currentBufferArray == null) {
|
||||
logger.warn("Skipping enable attrib with emulated VAO because no known VAO is bound!");
|
||||
return;
|
||||
}
|
||||
((SoftGLBufferArray)currentBufferArray).enableAttrib(index, true);
|
||||
}else {
|
||||
_wglEnableVertexAttribArray(index);
|
||||
}
|
||||
}
|
||||
|
||||
public static final void disableVertexAttribArray(int index) {
|
||||
if(emulatedVAOs) {
|
||||
if(currentBufferArray == null) {
|
||||
logger.warn("Skipping disable attrib with emulated VAO because no known VAO is bound!");
|
||||
return;
|
||||
}
|
||||
((SoftGLBufferArray)currentBufferArray).enableAttrib(index, false);
|
||||
}else {
|
||||
_wglDisableVertexAttribArray(index);
|
||||
}
|
||||
}
|
||||
|
||||
public static final void vertexAttribPointer(int index, int size, int format, boolean normalized, int stride, int offset) {
|
||||
if(emulatedVAOs) {
|
||||
if(currentBufferArray == null) {
|
||||
logger.warn("Skipping vertexAttribPointer with emulated VAO because no known VAO is bound!");
|
||||
return;
|
||||
}
|
||||
if(currentVAOArrayBuffer == null) {
|
||||
logger.warn("Skipping vertexAttribPointer with emulated VAO because no VAO array buffer is bound!");
|
||||
return;
|
||||
}
|
||||
((SoftGLBufferArray)currentBufferArray).setAttrib(currentVAOArrayBuffer, index, size, format, normalized, stride, offset);
|
||||
}else {
|
||||
_wglVertexAttribPointer(index, size, format, normalized, stride, offset);
|
||||
}
|
||||
}
|
||||
|
||||
public static final void vertexAttribDivisor(int index, int divisor) {
|
||||
if(emulatedVAOs) {
|
||||
if(currentBufferArray == null) {
|
||||
logger.warn("Skipping vertexAttribPointer with emulated VAO because no known VAO is bound!");
|
||||
return;
|
||||
}
|
||||
((SoftGLBufferArray)currentBufferArray).setAttribDivisor(index, divisor);
|
||||
}else {
|
||||
_wglVertexAttribDivisor(index, divisor);
|
||||
}
|
||||
}
|
||||
|
||||
public static final void doDrawArrays(int mode, int first, int count) {
|
||||
if(emulatedVAOs) {
|
||||
if(currentBufferArray == null) {
|
||||
logger.warn("Skipping draw call with emulated VAO because no known VAO is bound!");
|
||||
return;
|
||||
}
|
||||
((SoftGLBufferArray)currentBufferArray).transitionToState(emulatedVAOState, false);
|
||||
}
|
||||
_wglDrawArrays(mode, first, count);
|
||||
}
|
||||
|
||||
public static final void doDrawElements(int mode, int count, int type, int offset) {
|
||||
if(emulatedVAOs) {
|
||||
if(currentBufferArray == null) {
|
||||
logger.warn("Skipping draw call with emulated VAO because no known VAO is bound!");
|
||||
return;
|
||||
}
|
||||
((SoftGLBufferArray)currentBufferArray).transitionToState(emulatedVAOState, true);
|
||||
}
|
||||
_wglDrawElements(mode, count, type, offset);
|
||||
}
|
||||
|
||||
public static final void doDrawArraysInstanced(int mode, int first, int count, int instances) {
|
||||
if(emulatedVAOs) {
|
||||
if(currentBufferArray == null) {
|
||||
logger.warn("Skipping instanced draw call with emulated VAO because no known VAO is bound!");
|
||||
return;
|
||||
}
|
||||
((SoftGLBufferArray)currentBufferArray).transitionToState(emulatedVAOState, false);
|
||||
}
|
||||
_wglDrawArraysInstanced(mode, first, count, instances);
|
||||
}
|
||||
|
||||
public static final void doDrawElementsInstanced(int mode, int count, int type, int offset, int instances) {
|
||||
if(emulatedVAOs) {
|
||||
if(currentBufferArray == null) {
|
||||
logger.warn("Skipping instanced draw call with emulated VAO because no known VAO is bound!");
|
||||
return;
|
||||
}
|
||||
((SoftGLBufferArray)currentBufferArray).transitionToState(emulatedVAOState, true);
|
||||
}
|
||||
_wglDrawElementsInstanced(mode, count, type, offset, instances);
|
||||
}
|
||||
|
||||
static IBufferArrayGL currentBufferArray = null;
|
||||
|
||||
private static IBufferGL currentArrayBuffer = null;
|
||||
|
||||
public static final void bindGLBufferArray(IBufferArrayGL buffer) {
|
||||
if(emulatedVAOs) {
|
||||
currentBufferArray = buffer;
|
||||
}else {
|
||||
if(currentBufferArray != buffer) {
|
||||
_wglBindVertexArray(buffer);
|
||||
currentBufferArray = buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static IBufferGL currentArrayBuffer = null;
|
||||
|
||||
// only used when VAOs are emulated
|
||||
static IBufferGL currentVAOArrayBuffer = null;
|
||||
|
||||
public static final void bindVAOGLArrayBuffer(IBufferGL buffer) {
|
||||
if(emulatedVAOs) {
|
||||
currentVAOArrayBuffer = buffer;
|
||||
}else {
|
||||
if(currentArrayBuffer != buffer) {
|
||||
_wglBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||
currentArrayBuffer = buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final void bindVAOGLArrayBufferNow(IBufferGL buffer) {
|
||||
if(emulatedVAOs) {
|
||||
currentVAOArrayBuffer = buffer;
|
||||
}
|
||||
if(currentArrayBuffer != buffer) {
|
||||
_wglBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||
currentArrayBuffer = buffer;
|
||||
}
|
||||
}
|
||||
|
||||
public static final void bindVAOGLElementArrayBuffer(IBufferGL buffer) {
|
||||
if(emulatedVAOs) {
|
||||
if(currentBufferArray == null) {
|
||||
logger.warn("Skipping set element array buffer with emulated VAO because no known VAO is bound!");
|
||||
return;
|
||||
}
|
||||
((SoftGLBufferArray)currentBufferArray).setIndexBuffer(buffer);
|
||||
}else {
|
||||
_wglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
static final void bindVAOGLElementArrayBufferNow(IBufferGL buffer) {
|
||||
if(emulatedVAOs) {
|
||||
if(currentBufferArray == null) {
|
||||
logger.warn("Skipping set element array buffer with emulated VAO because no known VAO is bound!");
|
||||
return;
|
||||
}
|
||||
((SoftGLBufferArray)currentBufferArray).setIndexBuffer(buffer);
|
||||
if(currentEmulatedVAOIndexBuffer != buffer) {
|
||||
_wglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
|
||||
currentEmulatedVAOIndexBuffer = buffer;
|
||||
}
|
||||
}else {
|
||||
_wglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
static IBufferGL currentEmulatedVAOIndexBuffer = null;
|
||||
|
||||
static final void bindEmulatedVAOIndexBuffer(IBufferGL buffer) {
|
||||
if(currentEmulatedVAOIndexBuffer != buffer) {
|
||||
_wglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
|
||||
currentEmulatedVAOIndexBuffer = buffer;
|
||||
}
|
||||
}
|
||||
|
||||
public static final void bindGLArrayBuffer(IBufferGL buffer) {
|
||||
if(currentArrayBuffer != buffer) {
|
||||
_wglBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||
@ -321,7 +541,7 @@ public class EaglercraftGPU {
|
||||
}
|
||||
}
|
||||
|
||||
private static IBufferGL currentUniformBuffer = null;
|
||||
static IBufferGL currentUniformBuffer = null;
|
||||
|
||||
public static final void bindGLUniformBuffer(IBufferGL buffer) {
|
||||
if(currentUniformBuffer != buffer) {
|
||||
@ -330,7 +550,7 @@ public class EaglercraftGPU {
|
||||
}
|
||||
}
|
||||
|
||||
private static IProgramGL currentShaderProgram = null;
|
||||
static IProgramGL currentShaderProgram = null;
|
||||
|
||||
public static final void bindGLShaderProgram(IProgramGL prog) {
|
||||
if(currentShaderProgram != prog) {
|
||||
@ -352,6 +572,38 @@ public class EaglercraftGPU {
|
||||
currentUniformBlockBindingSize[index] = size;
|
||||
}
|
||||
}
|
||||
|
||||
public static final int CLEAR_BINDING_TEXTURE = 1;
|
||||
public static final int CLEAR_BINDING_TEXTURE0 = 2;
|
||||
public static final int CLEAR_BINDING_ACTIVE_TEXTURE = 4;
|
||||
public static final int CLEAR_BINDING_BUFFER_ARRAY = 8;
|
||||
public static final int CLEAR_BINDING_ARRAY_BUFFER = 16;
|
||||
public static final int CLEAR_BINDING_SHADER_PROGRAM = 32;
|
||||
|
||||
public static final void clearCurrentBinding(int mask) {
|
||||
if((mask & CLEAR_BINDING_TEXTURE) != 0) {
|
||||
int[] i = GlStateManager.boundTexture;
|
||||
for(int j = 0; j < i.length; ++j) {
|
||||
i[j] = -1;
|
||||
}
|
||||
}
|
||||
if((mask & CLEAR_BINDING_TEXTURE0) != 0) {
|
||||
GlStateManager.boundTexture[0] = -1;
|
||||
}
|
||||
if((mask & CLEAR_BINDING_ACTIVE_TEXTURE) != 0) {
|
||||
GlStateManager.activeTexture = 0;
|
||||
_wglActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
if((mask & CLEAR_BINDING_BUFFER_ARRAY) != 0) {
|
||||
currentBufferArray = null;
|
||||
}
|
||||
if((mask & CLEAR_BINDING_ARRAY_BUFFER) != 0) {
|
||||
currentArrayBuffer = currentVAOArrayBuffer = null;
|
||||
}
|
||||
if((mask & CLEAR_BINDING_SHADER_PROGRAM) != 0) {
|
||||
currentShaderProgram = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static final int ATTRIB_TEXTURE = 1;
|
||||
public static final int ATTRIB_COLOR = 2;
|
||||
@ -414,7 +666,7 @@ public class EaglercraftGPU {
|
||||
if(newSize > 0xFFFF) {
|
||||
newSize = 0xFFFF;
|
||||
}
|
||||
_wglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
|
||||
EaglercraftGPU.bindVAOGLElementArrayBufferNow(buf);
|
||||
resizeQuad16EmulationBuffer(newSize >> 2);
|
||||
}else {
|
||||
int cnt = quad16EmulationBufferSize;
|
||||
@ -423,10 +675,10 @@ public class EaglercraftGPU {
|
||||
if(newSize > 0xFFFF) {
|
||||
newSize = 0xFFFF;
|
||||
}
|
||||
_wglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
|
||||
EaglercraftGPU.bindVAOGLElementArrayBufferNow(buf);
|
||||
resizeQuad16EmulationBuffer(newSize >> 2);
|
||||
}else if(bind) {
|
||||
_wglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
|
||||
EaglercraftGPU.bindVAOGLElementArrayBuffer(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -436,16 +688,16 @@ public class EaglercraftGPU {
|
||||
if(buf == null) {
|
||||
quad32EmulationBuffer = buf = _wglGenBuffers();
|
||||
int newSize = quad32EmulationBufferSize = (vertexCount & 0xFFFFC000) + 0x8000;
|
||||
_wglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
|
||||
EaglercraftGPU.bindVAOGLElementArrayBufferNow(buf);
|
||||
resizeQuad32EmulationBuffer(newSize >> 2);
|
||||
}else {
|
||||
int cnt = quad32EmulationBufferSize;
|
||||
if(cnt < vertexCount) {
|
||||
int newSize = quad32EmulationBufferSize = (vertexCount & 0xFFFFC000) + 0x8000;
|
||||
_wglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
|
||||
EaglercraftGPU.bindVAOGLElementArrayBufferNow(buf);
|
||||
resizeQuad32EmulationBuffer(newSize >> 2);
|
||||
}else if(bind) {
|
||||
_wglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
|
||||
EaglercraftGPU.bindVAOGLElementArrayBuffer(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -508,9 +760,19 @@ public class EaglercraftGPU {
|
||||
p.drawElements(GL_TRIANGLES, mesh.indexCount, GL_UNSIGNED_SHORT, 0);
|
||||
}
|
||||
|
||||
static int glesVers = -1;
|
||||
static boolean hasFramebufferHDR16FSupport = false;
|
||||
static boolean hasFramebufferHDR32FSupport = false;
|
||||
static boolean hasLinearHDR16FSupport = false;
|
||||
static boolean hasLinearHDR32FSupport = false;
|
||||
static boolean fboRenderMipmapCapable = false;
|
||||
static boolean vertexArrayCapable = false;
|
||||
static boolean instancingCapable = false;
|
||||
static boolean texStorageCapable = false;
|
||||
static boolean textureLODCapable = false;
|
||||
static boolean shader5Capable = false;
|
||||
static boolean npotCapable = false;
|
||||
static int uniformBufferOffsetAlignment = -1;
|
||||
|
||||
public static final void createFramebufferHDR16FTexture(int target, int level, int w, int h, int format, boolean allow32bitFallback) {
|
||||
createFramebufferHDR16FTexture(target, level, w, h, format, allow32bitFallback, null);
|
||||
@ -525,19 +787,24 @@ public class EaglercraftGPU {
|
||||
int internalFormat;
|
||||
switch(format) {
|
||||
case GL_RED:
|
||||
internalFormat = 0x822D; // GL_R16F
|
||||
if(glesVers == 200) {
|
||||
format = GL_LUMINANCE;
|
||||
internalFormat = GL_LUMINANCE;
|
||||
}else {
|
||||
internalFormat = glesVers == 200 ? GL_LUMINANCE : 0x822D; // GL_R16F
|
||||
}
|
||||
break;
|
||||
case 0x8227: // GL_RG
|
||||
internalFormat = 0x822F; // GL_RG16F
|
||||
internalFormat = glesVers == 200 ? 0x8227 : 0x822F; // GL_RG16F
|
||||
case GL_RGB:
|
||||
throw new UnsupportedOperationException("GL_RGB16F isn't supported specifically in WebGL 2.0 for some goddamn reason");
|
||||
case GL_RGBA:
|
||||
internalFormat = 0x881A; // GL_RGBA16F
|
||||
internalFormat = glesVers == 200 ? GL_RGBA : 0x881A; // GL_RGBA16F
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unknown format: " + format);
|
||||
}
|
||||
_wglTexImage2Du16(target, level, internalFormat, w, h, 0, format, 0x140B, pixelData);
|
||||
_wglTexImage2Du16(target, level, internalFormat, w, h, 0, format, glesVers == 200 ? 0x8D61 : 0x140B, pixelData);
|
||||
}else {
|
||||
if(allow32bitFallback) {
|
||||
if(hasFramebufferHDR32FSupport) {
|
||||
@ -567,7 +834,7 @@ public class EaglercraftGPU {
|
||||
internalFormat = 0x822E; // GL_R32F
|
||||
break;
|
||||
case 0x8227: // GL_RG
|
||||
internalFormat = 0x822F; // GL_RG32F
|
||||
internalFormat = 0x8230; // GL_RG32F
|
||||
case GL_RGB:
|
||||
throw new UnsupportedOperationException("GL_RGB32F isn't supported specifically in WebGL 2.0 for some goddamn reason");
|
||||
case GL_RGBA:
|
||||
@ -594,19 +861,38 @@ public class EaglercraftGPU {
|
||||
EaglercraftGPU.glGetString(7936);
|
||||
EaglercraftGPU.glGetString(7937);
|
||||
EaglercraftGPU.glGetString(7938);
|
||||
glesVers = PlatformOpenGL.checkOpenGLESVersion();
|
||||
vertexArrayCapable = PlatformOpenGL.checkVAOCapable();
|
||||
emulatedVAOs = !vertexArrayCapable;
|
||||
fboRenderMipmapCapable = PlatformOpenGL.checkFBORenderMipmapCapable();
|
||||
instancingCapable = PlatformOpenGL.checkInstancingCapable();
|
||||
texStorageCapable = PlatformOpenGL.checkTexStorageCapable();
|
||||
textureLODCapable = PlatformOpenGL.checkTextureLODCapable();
|
||||
shader5Capable = PlatformOpenGL.checkOESGPUShader5Capable() || PlatformOpenGL.checkEXTGPUShader5Capable();
|
||||
npotCapable = PlatformOpenGL.checkNPOTCapable();
|
||||
uniformBufferOffsetAlignment = glesVers >= 300 ? _wglGetInteger(0x8A34) : -1;
|
||||
if(!npotCapable) {
|
||||
logger.warn("NPOT texture support detected as false, texture wrapping must be set to GL_CLAMP_TO_EDGE if the texture's width or height is not a power of 2");
|
||||
}
|
||||
hasFramebufferHDR16FSupport = PlatformOpenGL.checkHDRFramebufferSupport(16);
|
||||
if(hasFramebufferHDR16FSupport) {
|
||||
logger.info("16-bit HDR render target support: true");
|
||||
}else {
|
||||
logger.error("16-bit HDR render target support: false");
|
||||
}
|
||||
hasLinearHDR16FSupport = PlatformOpenGL.checkLinearHDRFilteringSupport(16);
|
||||
if(hasLinearHDR16FSupport) {
|
||||
logger.info("16-bit HDR linear filter support: true");
|
||||
}else {
|
||||
logger.error("16-bit HDR linear filter support: false");
|
||||
}
|
||||
hasFramebufferHDR32FSupport = PlatformOpenGL.checkHDRFramebufferSupport(32);
|
||||
if(hasFramebufferHDR32FSupport) {
|
||||
logger.info("32-bit HDR render target support: true");
|
||||
}else {
|
||||
logger.error("32-bit HDR render target support: false");
|
||||
}
|
||||
hasLinearHDR32FSupport = PlatformOpenGL.checkLinearHDR32FSupport();
|
||||
hasLinearHDR32FSupport = PlatformOpenGL.checkLinearHDRFilteringSupport(32);
|
||||
if(hasLinearHDR32FSupport) {
|
||||
logger.info("32-bit HDR linear filter support: true");
|
||||
}else {
|
||||
@ -615,16 +901,86 @@ public class EaglercraftGPU {
|
||||
if(!checkHasHDRFramebufferSupportWithFilter()) {
|
||||
logger.error("No HDR render target support was detected! Shaders will be disabled.");
|
||||
}
|
||||
if(emulatedVAOs) {
|
||||
logger.info("Note: Could not unlock VAOs via OpenGL extensions, emulating them instead");
|
||||
}
|
||||
if(!instancingCapable) {
|
||||
logger.info("Note: Could not unlock instancing via OpenGL extensions, using slow vanilla font and particle rendering");
|
||||
}
|
||||
emulatedVAOState = emulatedVAOs ? new SoftGLBufferState() : null;
|
||||
PlatformOpenGL.enterVAOEmulationHook();
|
||||
GLSLHeader.init();
|
||||
DrawUtils.init();
|
||||
SpriteLevelMixer.initialize();
|
||||
InstancedFontRenderer.initialize();
|
||||
InstancedParticleRenderer.initialize();
|
||||
if(instancingCapable) {
|
||||
InstancedFontRenderer.initialize();
|
||||
InstancedParticleRenderer.initialize();
|
||||
}
|
||||
EffectPipelineFXAA.initialize();
|
||||
TextureCopyUtil.initialize();
|
||||
DrawUtils.vshLocal.free();
|
||||
DrawUtils.vshLocal = null;
|
||||
}
|
||||
|
||||
public static final void destroyCache() {
|
||||
stringCache.clear();
|
||||
mapTexturesGL.clear();
|
||||
mapQueriesGL.clear();
|
||||
mapDisplayListsGL.clear();
|
||||
emulatedVAOs = false;
|
||||
emulatedVAOState = null;
|
||||
glesVers = -1;
|
||||
fboRenderMipmapCapable = false;
|
||||
vertexArrayCapable = false;
|
||||
instancingCapable = false;
|
||||
hasFramebufferHDR16FSupport = false;
|
||||
hasFramebufferHDR32FSupport = false;
|
||||
hasLinearHDR32FSupport = false;
|
||||
GLSLHeader.destroy();
|
||||
DrawUtils.destroy();
|
||||
SpriteLevelMixer.destroy();
|
||||
InstancedFontRenderer.destroy();
|
||||
InstancedParticleRenderer.destroy();
|
||||
EffectPipelineFXAA.destroy();
|
||||
TextureCopyUtil.destroy();
|
||||
}
|
||||
|
||||
public static final int checkOpenGLESVersion() {
|
||||
return glesVers;
|
||||
}
|
||||
|
||||
public static final boolean checkFBORenderMipmapCapable() {
|
||||
return fboRenderMipmapCapable;
|
||||
}
|
||||
|
||||
public static final boolean checkVAOCapable() {
|
||||
return vertexArrayCapable;
|
||||
}
|
||||
|
||||
public static final boolean checkInstancingCapable() {
|
||||
return instancingCapable;
|
||||
}
|
||||
|
||||
public static final boolean checkTexStorageCapable() {
|
||||
return texStorageCapable;
|
||||
}
|
||||
|
||||
public static final boolean checkTextureLODCapable() {
|
||||
return textureLODCapable;
|
||||
}
|
||||
|
||||
public static final boolean checkShader5Capable() {
|
||||
return shader5Capable;
|
||||
}
|
||||
|
||||
public static final boolean checkNPOTCapable() {
|
||||
return npotCapable;
|
||||
}
|
||||
|
||||
public static final int getUniformBufferOffsetAlignment() {
|
||||
return uniformBufferOffsetAlignment;
|
||||
}
|
||||
|
||||
public static final boolean checkHDRFramebufferSupport(int bits) {
|
||||
switch(bits) {
|
||||
case 16:
|
||||
@ -636,15 +992,28 @@ public class EaglercraftGPU {
|
||||
}
|
||||
}
|
||||
|
||||
public static final boolean checkLinearHDRFilteringSupport(int bits) {
|
||||
switch(bits) {
|
||||
case 16:
|
||||
return hasLinearHDR16FSupport;
|
||||
case 32:
|
||||
return hasLinearHDR32FSupport;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static final boolean checkHasHDRFramebufferSupport() {
|
||||
return hasFramebufferHDR16FSupport || hasFramebufferHDR32FSupport;
|
||||
}
|
||||
|
||||
public static final boolean checkHasHDRFramebufferSupportWithFilter() {
|
||||
return hasFramebufferHDR16FSupport || (hasFramebufferHDR32FSupport && hasLinearHDR32FSupport);
|
||||
return (hasFramebufferHDR16FSupport && hasLinearHDR16FSupport) || (hasFramebufferHDR32FSupport && hasLinearHDR32FSupport);
|
||||
}
|
||||
|
||||
//legacy
|
||||
public static final boolean checkLinearHDR32FSupport() {
|
||||
return hasLinearHDR32FSupport;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import net.lax1dude.eaglercraft.v1_8.internal.IUniformGL;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.FixedFunctionShader.FixedFunctionConstants;
|
||||
|
||||
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
|
||||
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
|
||||
@ -35,11 +34,13 @@ public class EffectPipelineFXAA {
|
||||
private static final Logger logger = LogManager.getLogger("EffectPipelineFXAA");
|
||||
|
||||
public static final String fragmentShaderPath = "/assets/eagler/glsl/post_fxaa.fsh";
|
||||
public static final String fragmentShaderPrecision = "precision lowp int;\nprecision mediump float;\nprecision mediump sampler2D;\n";
|
||||
|
||||
private static final int _GL_FRAMEBUFFER = 0x8D40;
|
||||
private static final int _GL_RENDERBUFFER = 0x8D41;
|
||||
private static final int _GL_COLOR_ATTACHMENT0 = 0x8CE0;
|
||||
private static final int _GL_DEPTH_ATTACHMENT = 0x8D00;
|
||||
private static final int _GL_DEPTH_COMPONENT16 = 0x81A5;
|
||||
private static final int _GL_DEPTH_COMPONENT32F = 0x8CAC;
|
||||
|
||||
private static IProgramGL shaderProgram = null;
|
||||
@ -53,14 +54,11 @@ public class EffectPipelineFXAA {
|
||||
private static int currentHeight = -1;
|
||||
|
||||
static void initialize() {
|
||||
String fragmentSource = EagRuntime.getResourceString(fragmentShaderPath);
|
||||
if(fragmentSource == null) {
|
||||
throw new RuntimeException("EffectPipelineFXAA shader \"" + fragmentShaderPath + "\" is missing!");
|
||||
}
|
||||
String fragmentSource = EagRuntime.getRequiredResourceString(fragmentShaderPath);
|
||||
|
||||
IShaderGL frag = _wglCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
_wglShaderSource(frag, FixedFunctionConstants.VERSION + "\n" + fragmentSource);
|
||||
_wglShaderSource(frag, GLSLHeader.getFragmentHeaderCompat(fragmentSource, fragmentShaderPrecision));
|
||||
_wglCompileShader(frag);
|
||||
|
||||
if(_wglGetShaderi(frag, GL_COMPILE_STATUS) != GL_TRUE) {
|
||||
@ -80,6 +78,10 @@ public class EffectPipelineFXAA {
|
||||
_wglAttachShader(shaderProgram, DrawUtils.vshLocal);
|
||||
_wglAttachShader(shaderProgram, frag);
|
||||
|
||||
if(EaglercraftGPU.checkOpenGLESVersion() == 200) {
|
||||
VSHInputLayoutParser.applyLayout(shaderProgram, DrawUtils.vshLocalLayout);
|
||||
}
|
||||
|
||||
_wglLinkProgram(shaderProgram);
|
||||
|
||||
_wglDetachShader(shaderProgram, DrawUtils.vshLocal);
|
||||
@ -130,10 +132,10 @@ public class EffectPipelineFXAA {
|
||||
currentHeight = height;
|
||||
|
||||
GlStateManager.bindTexture(framebufferColor);
|
||||
_wglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (ByteBuffer)null);
|
||||
EaglercraftGPU.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (ByteBuffer)null);
|
||||
|
||||
_wglBindRenderbuffer(_GL_RENDERBUFFER, framebufferDepth);
|
||||
_wglRenderbufferStorage(_GL_RENDERBUFFER, _GL_DEPTH_COMPONENT32F, width, height);
|
||||
_wglRenderbufferStorage(_GL_RENDERBUFFER, EaglercraftGPU.checkOpenGLESVersion() == 200 ? _GL_DEPTH_COMPONENT16 : _GL_DEPTH_COMPONENT32F, width, height);
|
||||
}
|
||||
|
||||
_wglBindFramebuffer(_GL_FRAMEBUFFER, framebuffer);
|
||||
@ -155,4 +157,24 @@ public class EffectPipelineFXAA {
|
||||
DrawUtils.drawStandardQuad2D();
|
||||
}
|
||||
|
||||
public static void destroy() {
|
||||
if(shaderProgram != null) {
|
||||
_wglDeleteProgram(shaderProgram);
|
||||
shaderProgram = null;
|
||||
}
|
||||
u_screenSize2f = null;
|
||||
if(framebuffer != null) {
|
||||
_wglDeleteFramebuffer(framebuffer);
|
||||
framebuffer = null;
|
||||
}
|
||||
if(framebufferColor != -1) {
|
||||
GlStateManager.deleteTexture(framebufferColor);
|
||||
framebufferColor = -2;
|
||||
}
|
||||
if(framebufferDepth != null) {
|
||||
_wglDeleteRenderbuffer(framebufferDepth);
|
||||
framebufferDepth = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -98,33 +98,33 @@ public class FixedFunctionPipeline {
|
||||
}
|
||||
|
||||
EaglercraftGPU.bindGLBufferArray(list.vertexArray);
|
||||
EaglercraftGPU.bindGLArrayBuffer(list.vertexBuffer);
|
||||
EaglercraftGPU.bindVAOGLArrayBuffer(list.vertexBuffer);
|
||||
|
||||
_wglEnableVertexAttribArray(0);
|
||||
_wglVertexAttribPointer(0, VertexFormat.COMPONENT_POSITION_SIZE,
|
||||
EaglercraftGPU.enableVertexAttribArray(0);
|
||||
EaglercraftGPU.vertexAttribPointer(0, VertexFormat.COMPONENT_POSITION_SIZE,
|
||||
VertexFormat.COMPONENT_POSITION_FORMAT, false, self.attribStride, 0);
|
||||
|
||||
if(self.attribTextureIndex != -1) {
|
||||
_wglEnableVertexAttribArray(self.attribTextureIndex);
|
||||
_wglVertexAttribPointer(self.attribTextureIndex, VertexFormat.COMPONENT_TEX_SIZE,
|
||||
EaglercraftGPU.enableVertexAttribArray(self.attribTextureIndex);
|
||||
EaglercraftGPU.vertexAttribPointer(self.attribTextureIndex, VertexFormat.COMPONENT_TEX_SIZE,
|
||||
VertexFormat.COMPONENT_TEX_FORMAT, false, self.attribStride, self.attribTextureOffset);
|
||||
}
|
||||
|
||||
if(self.attribColorIndex != -1) {
|
||||
_wglEnableVertexAttribArray(self.attribColorIndex);
|
||||
_wglVertexAttribPointer(self.attribColorIndex, VertexFormat.COMPONENT_COLOR_SIZE,
|
||||
EaglercraftGPU.enableVertexAttribArray(self.attribColorIndex);
|
||||
EaglercraftGPU.vertexAttribPointer(self.attribColorIndex, VertexFormat.COMPONENT_COLOR_SIZE,
|
||||
VertexFormat.COMPONENT_COLOR_FORMAT, true, self.attribStride, self.attribColorOffset);
|
||||
}
|
||||
|
||||
if(self.attribNormalIndex != -1) {
|
||||
_wglEnableVertexAttribArray(self.attribNormalIndex);
|
||||
_wglVertexAttribPointer(self.attribNormalIndex, VertexFormat.COMPONENT_NORMAL_SIZE,
|
||||
EaglercraftGPU.enableVertexAttribArray(self.attribNormalIndex);
|
||||
EaglercraftGPU.vertexAttribPointer(self.attribNormalIndex, VertexFormat.COMPONENT_NORMAL_SIZE,
|
||||
VertexFormat.COMPONENT_NORMAL_FORMAT, true, self.attribStride, self.attribNormalOffset);
|
||||
}
|
||||
|
||||
if(self.attribLightmapIndex != -1) {
|
||||
_wglEnableVertexAttribArray(self.attribLightmapIndex);
|
||||
_wglVertexAttribPointer(self.attribLightmapIndex, VertexFormat.COMPONENT_LIGHTMAP_SIZE,
|
||||
EaglercraftGPU.enableVertexAttribArray(self.attribLightmapIndex);
|
||||
EaglercraftGPU.vertexAttribPointer(self.attribLightmapIndex, VertexFormat.COMPONENT_LIGHTMAP_SIZE,
|
||||
VertexFormat.COMPONENT_LIGHTMAP_FORMAT, false, self.attribStride, self.attribLightmapOffset);
|
||||
}
|
||||
|
||||
@ -145,7 +145,7 @@ public class FixedFunctionPipeline {
|
||||
|
||||
void drawArrays(int mode, int offset, int count) {
|
||||
EaglercraftGPU.bindGLShaderProgram(shaderProgram);
|
||||
PlatformOpenGL._wglDrawArrays(mode, offset, count);
|
||||
EaglercraftGPU.doDrawArrays(mode, offset, count);
|
||||
}
|
||||
|
||||
void drawDirectArrays(int mode, int offset, int count) {
|
||||
@ -160,7 +160,7 @@ public class FixedFunctionPipeline {
|
||||
}else {
|
||||
EaglercraftGPU.attachQuad32EmulationBuffer(count, false);
|
||||
}
|
||||
PlatformOpenGL._wglDrawElements(GL_TRIANGLES, count + (count >> 1),
|
||||
EaglercraftGPU.doDrawElements(GL_TRIANGLES, count + (count >> 1),
|
||||
GL_UNSIGNED_INT, 0);
|
||||
}else {
|
||||
if(!sb.bindQuad16) {
|
||||
@ -170,17 +170,17 @@ public class FixedFunctionPipeline {
|
||||
}else {
|
||||
EaglercraftGPU.attachQuad16EmulationBuffer(count, false);
|
||||
}
|
||||
PlatformOpenGL._wglDrawElements(GL_TRIANGLES, count + (count >> 1),
|
||||
EaglercraftGPU.doDrawElements(GL_TRIANGLES, count + (count >> 1),
|
||||
GL_UNSIGNED_SHORT, 0);
|
||||
}
|
||||
}else {
|
||||
PlatformOpenGL._wglDrawArrays(mode, offset, count);
|
||||
EaglercraftGPU.doDrawArrays(mode, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
void drawElements(int mode, int count, int type, int offset) {
|
||||
EaglercraftGPU.bindGLShaderProgram(shaderProgram);
|
||||
PlatformOpenGL._wglDrawElements(mode, count, type, offset);
|
||||
EaglercraftGPU.doDrawElements(mode, count, type, offset);
|
||||
}
|
||||
|
||||
private static IExtPipelineCompiler extensionProvider;
|
||||
@ -192,7 +192,7 @@ public class FixedFunctionPipeline {
|
||||
|
||||
private static final FixedFunctionPipeline[] pipelineStateCache = new FixedFunctionPipeline[fixedFunctionStatesBits + 1];
|
||||
private static final FixedFunctionPipeline[][] pipelineExtStateCache = new FixedFunctionPipeline[fixedFunctionStatesBits + 1][];
|
||||
private static final List<FixedFunctionPipeline> pipelineListTracker = new ArrayList(1024);
|
||||
private static final List<FixedFunctionPipeline> pipelineListTracker = new ArrayList<>(1024);
|
||||
|
||||
private static String shaderSourceCacheVSH = null;
|
||||
private static String shaderSourceCacheFSH = null;
|
||||
@ -232,22 +232,16 @@ public class FixedFunctionPipeline {
|
||||
fshSource = extSource[1];
|
||||
}else {
|
||||
if(shaderSourceCacheVSH == null) {
|
||||
shaderSourceCacheVSH = EagRuntime.getResourceString(FILENAME_VSH);
|
||||
if(shaderSourceCacheVSH == null) {
|
||||
throw new RuntimeException("Could not load: " + FILENAME_VSH);
|
||||
}
|
||||
shaderSourceCacheVSH = EagRuntime.getRequiredResourceString(FILENAME_VSH);
|
||||
}
|
||||
vshSource = shaderSourceCacheVSH;
|
||||
if(shaderSourceCacheFSH == null) {
|
||||
shaderSourceCacheFSH = EagRuntime.getResourceString(FILENAME_FSH);
|
||||
if(shaderSourceCacheFSH == null) {
|
||||
throw new RuntimeException("Could not load: " + FILENAME_FSH);
|
||||
}
|
||||
shaderSourceCacheFSH = EagRuntime.getRequiredResourceString(FILENAME_FSH);
|
||||
}
|
||||
fshSource = shaderSourceCacheFSH;
|
||||
}
|
||||
|
||||
StringBuilder macros = new StringBuilder(VERSION + "\n");
|
||||
StringBuilder macros = new StringBuilder();
|
||||
if((coreBits & STATE_HAS_ATTRIB_TEXTURE) != 0) {
|
||||
macros.append("#define " + MACRO_ATTRIB_TEXTURE + "\n");
|
||||
}
|
||||
@ -291,7 +285,8 @@ public class FixedFunctionPipeline {
|
||||
|
||||
IShaderGL vsh = _wglCreateShader(GL_VERTEX_SHADER);
|
||||
|
||||
_wglShaderSource(vsh, macros.toString() + vshSource);
|
||||
String macrosStr = macros.toString();
|
||||
_wglShaderSource(vsh, GLSLHeader.getVertexHeaderCompat(vshSource, macrosStr));
|
||||
_wglCompileShader(vsh);
|
||||
|
||||
if(_wglGetShaderi(vsh, GL_COMPILE_STATUS) != GL_TRUE) {
|
||||
@ -309,7 +304,7 @@ public class FixedFunctionPipeline {
|
||||
|
||||
IShaderGL fsh = _wglCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
_wglShaderSource(fsh, macros.toString() + fshSource);
|
||||
_wglShaderSource(fsh, GLSLHeader.getFragmentHeaderCompat(fshSource, macrosStr));
|
||||
_wglCompileShader(fsh);
|
||||
|
||||
if(_wglGetShaderi(fsh, GL_COMPILE_STATUS) != GL_TRUE) {
|
||||
@ -581,45 +576,45 @@ public class FixedFunctionPipeline {
|
||||
streamBuffer = new StreamBuffer(FixedFunctionShader.initialSize, FixedFunctionShader.initialCount,
|
||||
FixedFunctionShader.maxCount, (vertexArray, vertexBuffer) -> {
|
||||
EaglercraftGPU.bindGLBufferArray(vertexArray);
|
||||
EaglercraftGPU.bindGLArrayBuffer(vertexBuffer);
|
||||
EaglercraftGPU.bindVAOGLArrayBuffer(vertexBuffer);
|
||||
|
||||
_wglEnableVertexAttribArray(0);
|
||||
_wglVertexAttribPointer(0, VertexFormat.COMPONENT_POSITION_SIZE,
|
||||
EaglercraftGPU.enableVertexAttribArray(0);
|
||||
EaglercraftGPU.vertexAttribPointer(0, VertexFormat.COMPONENT_POSITION_SIZE,
|
||||
VertexFormat.COMPONENT_POSITION_FORMAT, false, attribStride, 0);
|
||||
|
||||
if(attribTextureIndex != -1) {
|
||||
_wglEnableVertexAttribArray(attribTextureIndex);
|
||||
_wglVertexAttribPointer(attribTextureIndex, VertexFormat.COMPONENT_TEX_SIZE,
|
||||
EaglercraftGPU.enableVertexAttribArray(attribTextureIndex);
|
||||
EaglercraftGPU.vertexAttribPointer(attribTextureIndex, VertexFormat.COMPONENT_TEX_SIZE,
|
||||
VertexFormat.COMPONENT_TEX_FORMAT, false, attribStride, attribTextureOffset);
|
||||
}
|
||||
|
||||
if(attribColorIndex != -1) {
|
||||
_wglEnableVertexAttribArray(attribColorIndex);
|
||||
_wglVertexAttribPointer(attribColorIndex, VertexFormat.COMPONENT_COLOR_SIZE,
|
||||
EaglercraftGPU.enableVertexAttribArray(attribColorIndex);
|
||||
EaglercraftGPU.vertexAttribPointer(attribColorIndex, VertexFormat.COMPONENT_COLOR_SIZE,
|
||||
VertexFormat.COMPONENT_COLOR_FORMAT, true, attribStride, attribColorOffset);
|
||||
}
|
||||
|
||||
if(attribNormalIndex != -1) {
|
||||
_wglEnableVertexAttribArray(attribNormalIndex);
|
||||
_wglVertexAttribPointer(attribNormalIndex, VertexFormat.COMPONENT_NORMAL_SIZE,
|
||||
EaglercraftGPU.enableVertexAttribArray(attribNormalIndex);
|
||||
EaglercraftGPU.vertexAttribPointer(attribNormalIndex, VertexFormat.COMPONENT_NORMAL_SIZE,
|
||||
VertexFormat.COMPONENT_NORMAL_FORMAT, true, attribStride, attribNormalOffset);
|
||||
}
|
||||
|
||||
if(attribLightmapIndex != -1) {
|
||||
_wglEnableVertexAttribArray(attribLightmapIndex);
|
||||
_wglVertexAttribPointer(attribLightmapIndex, VertexFormat.COMPONENT_LIGHTMAP_SIZE,
|
||||
EaglercraftGPU.enableVertexAttribArray(attribLightmapIndex);
|
||||
EaglercraftGPU.vertexAttribPointer(attribLightmapIndex, VertexFormat.COMPONENT_LIGHTMAP_SIZE,
|
||||
VertexFormat.COMPONENT_LIGHTMAP_FORMAT, false, attribStride, attribLightmapOffset);
|
||||
}
|
||||
});
|
||||
|
||||
stateEnableTexture2D = (bits & STATE_ENABLE_TEXTURE2D) == STATE_ENABLE_TEXTURE2D;
|
||||
stateEnableLightmap = (bits & STATE_ENABLE_LIGHTMAP) == STATE_ENABLE_LIGHTMAP;
|
||||
stateEnableAlphaTest = (bits & STATE_ENABLE_ALPHA_TEST) == STATE_ENABLE_ALPHA_TEST;
|
||||
stateEnableMCLighting = (bits & STATE_ENABLE_MC_LIGHTING) == STATE_ENABLE_MC_LIGHTING;
|
||||
stateEnableEndPortal = (bits & STATE_ENABLE_END_PORTAL) == STATE_ENABLE_END_PORTAL;
|
||||
stateEnableAnisotropicFix = (bits & STATE_ENABLE_ANISOTROPIC_FIX) == STATE_ENABLE_ANISOTROPIC_FIX;
|
||||
stateEnableFog = (bits & STATE_ENABLE_FOG) == STATE_ENABLE_FOG;
|
||||
stateEnableBlendAdd = (bits & STATE_ENABLE_BLEND_ADD) == STATE_ENABLE_BLEND_ADD;
|
||||
stateEnableTexture2D = (bits & STATE_ENABLE_TEXTURE2D) != 0;
|
||||
stateEnableLightmap = (bits & STATE_ENABLE_LIGHTMAP) != 0;
|
||||
stateEnableAlphaTest = (bits & STATE_ENABLE_ALPHA_TEST) != 0;
|
||||
stateEnableMCLighting = (bits & STATE_ENABLE_MC_LIGHTING) != 0;
|
||||
stateEnableEndPortal = (bits & STATE_ENABLE_END_PORTAL) != 0;
|
||||
stateEnableAnisotropicFix = (bits & STATE_ENABLE_ANISOTROPIC_FIX) != 0;
|
||||
stateEnableFog = (bits & STATE_ENABLE_FOG) != 0;
|
||||
stateEnableBlendAdd = (bits & STATE_ENABLE_BLEND_ADD) != 0;
|
||||
|
||||
for(int i = 0; i < stateLightsVectors.length; ++i) {
|
||||
stateLightsVectors[i] = new Vector4f(-999.0f, -999.0f, -999.0f, 0.0f);
|
||||
@ -1068,7 +1063,6 @@ public class FixedFunctionPipeline {
|
||||
}
|
||||
|
||||
static void optimize() {
|
||||
FixedFunctionPipeline pp;
|
||||
for(int i = 0, l = pipelineListTracker.size(); i < l; ++i) {
|
||||
pipelineListTracker.get(i).streamBuffer.optimize();
|
||||
}
|
||||
|
@ -44,7 +44,6 @@ public class FixedFunctionShader {
|
||||
|
||||
public class FixedFunctionConstants {
|
||||
|
||||
public static final String VERSION = "#version 300 es";
|
||||
public static final String FILENAME_VSH = "/assets/eagler/glsl/core.vsh";
|
||||
public static final String FILENAME_FSH = "/assets/eagler/glsl/core.fsh";
|
||||
|
||||
|
@ -0,0 +1,99 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.opengl;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL;
|
||||
|
||||
/**
|
||||
* 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 GLSLHeader {
|
||||
|
||||
public static final String GLES2_COMPAT_FILE_NAME = "/assets/eagler/glsl/gles2_compat.glsl";
|
||||
|
||||
private static String header = null;
|
||||
private static String gles2CompatFile = null;
|
||||
|
||||
static void init() {
|
||||
gles2CompatFile = EagRuntime.getRequiredResourceString(GLES2_COMPAT_FILE_NAME);
|
||||
int glesVersion = EaglercraftGPU.checkOpenGLESVersion();
|
||||
StringBuilder headerBuilder;
|
||||
if(glesVersion >= 310) {
|
||||
headerBuilder = new StringBuilder("#version 310 es");
|
||||
boolean oes5 = PlatformOpenGL.checkOESGPUShader5Capable();
|
||||
boolean ext5 = !oes5 && PlatformOpenGL.checkEXTGPUShader5Capable();
|
||||
if(oes5) {
|
||||
headerBuilder.append("\n#extension GL_OES_gpu_shader5 : enable");
|
||||
}else if(ext5) {
|
||||
headerBuilder.append("\n#extension GL_EXT_gpu_shader5 : enable");
|
||||
}
|
||||
headerBuilder.append("\n#define EAGLER_IS_GLES_310");
|
||||
headerBuilder.append("\n#define EAGLER_HAS_GLES_310");
|
||||
headerBuilder.append("\n#define EAGLER_HAS_GLES_300");
|
||||
headerBuilder.append("\n#define EAGLER_HAS_GLES_200");
|
||||
if(oes5 || ext5) {
|
||||
headerBuilder.append("\n#define EAGLER_HAS_GLES_310_SHADER_5");
|
||||
}
|
||||
}else if(glesVersion == 300) {
|
||||
headerBuilder = new StringBuilder("#version 300 es");
|
||||
headerBuilder.append("\n#define EAGLER_IS_GLES_300");
|
||||
headerBuilder.append("\n#define EAGLER_HAS_GLES_300");
|
||||
headerBuilder.append("\n#define EAGLER_HAS_GLES_200");
|
||||
}else if(glesVersion == 200) {
|
||||
boolean texLOD = PlatformOpenGL.checkTextureLODCapable();
|
||||
headerBuilder = new StringBuilder("#version 100");
|
||||
if(texLOD) {
|
||||
headerBuilder.append("\n#extension GL_EXT_shader_texture_lod : enable");
|
||||
}
|
||||
headerBuilder.append("\n#define EAGLER_HAS_GLES_200");
|
||||
headerBuilder.append("\n#define EAGLER_IS_GLES_200");
|
||||
if(texLOD) {
|
||||
headerBuilder.append("\n#define EAGLER_HAS_GLES_200_SHADER_TEXTURE_LOD");
|
||||
}
|
||||
}else {
|
||||
throw new IllegalStateException("Unsupported OpenGL ES version: " + glesVersion);
|
||||
}
|
||||
header = headerBuilder.append('\n').toString();
|
||||
}
|
||||
|
||||
static void destroy() {
|
||||
header = null;
|
||||
}
|
||||
|
||||
public static String getHeader() {
|
||||
if(header == null) throw new IllegalStateException();
|
||||
return header;
|
||||
}
|
||||
|
||||
public static String getVertexHeader(String shaderSrc) {
|
||||
if(header == null) throw new IllegalStateException();
|
||||
return header + "#define EAGLER_IS_VERTEX_SHADER\n" + shaderSrc;
|
||||
}
|
||||
|
||||
public static String getFragmentHeader(String shaderSrc) {
|
||||
if(header == null) throw new IllegalStateException();
|
||||
return header + "#define EAGLER_IS_FRAGMENT_SHADER\n" + shaderSrc;
|
||||
}
|
||||
|
||||
public static String getVertexHeaderCompat(String shaderSrc, String precisions) {
|
||||
if(header == null || gles2CompatFile == null) throw new IllegalStateException();
|
||||
return header + "#define EAGLER_IS_VERTEX_SHADER\n" + (precisions == null ? "" : precisions + "\n") + gles2CompatFile + "\n" + shaderSrc;
|
||||
}
|
||||
|
||||
public static String getFragmentHeaderCompat(String shaderSrc, String precisions) {
|
||||
if(header == null || gles2CompatFile == null) throw new IllegalStateException();
|
||||
return header + "#define EAGLER_IS_FRAGMENT_SHADER\n"+ (precisions == null ? "" : precisions + "\n") + gles2CompatFile + "\n" + shaderSrc;
|
||||
}
|
||||
|
||||
}
|
@ -5,10 +5,13 @@ import net.lax1dude.eaglercraft.v1_8.internal.IRenderbufferGL;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
|
||||
|
||||
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
|
||||
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude. All Rights Reserved.
|
||||
* Copyright (c) 2022-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
|
||||
@ -40,10 +43,20 @@ public class GameOverlayFramebuffer {
|
||||
|
||||
private int framebufferColor = -1;
|
||||
|
||||
public void beginRender(int width, int height) {
|
||||
private final boolean enableDepth;
|
||||
|
||||
public GameOverlayFramebuffer() {
|
||||
this(true);
|
||||
}
|
||||
|
||||
public GameOverlayFramebuffer(boolean enableDepth) {
|
||||
this.enableDepth = enableDepth;
|
||||
}
|
||||
|
||||
public boolean beginRender(int width, int height) {
|
||||
if(framebuffer == null) {
|
||||
framebuffer = _wglCreateFramebuffer();
|
||||
depthBuffer = _wglCreateRenderbuffer();
|
||||
depthBuffer = enableDepth ? _wglCreateRenderbuffer() : null;
|
||||
framebufferColor = GlStateManager.generateTexture();
|
||||
_wglBindFramebuffer(_GL_FRAMEBUFFER, framebuffer);
|
||||
GlStateManager.bindTexture(framebufferColor);
|
||||
@ -52,29 +65,35 @@ public class GameOverlayFramebuffer {
|
||||
_wglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
_wglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
_wglFramebufferTexture2D(_GL_FRAMEBUFFER, _GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, EaglercraftGPU.getNativeTexture(framebufferColor), 0);
|
||||
_wglBindRenderbuffer(_GL_RENDERBUFFER, depthBuffer);
|
||||
_wglFramebufferRenderbuffer(_GL_FRAMEBUFFER, _GL_DEPTH_ATTACHMENT, _GL_RENDERBUFFER, depthBuffer);
|
||||
if(enableDepth) {
|
||||
_wglBindRenderbuffer(_GL_RENDERBUFFER, depthBuffer);
|
||||
_wglFramebufferRenderbuffer(_GL_FRAMEBUFFER, _GL_DEPTH_ATTACHMENT, _GL_RENDERBUFFER, depthBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
if(currentWidth != width || currentHeight != height) {
|
||||
boolean resized = currentWidth != width || currentHeight != height;
|
||||
if(resized) {
|
||||
currentWidth = width;
|
||||
currentHeight = height;
|
||||
GlStateManager.bindTexture(framebufferColor);
|
||||
_wglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (ByteBuffer)null);
|
||||
_wglBindRenderbuffer(_GL_RENDERBUFFER, depthBuffer);
|
||||
_wglRenderbufferStorage(_GL_RENDERBUFFER, _GL_DEPTH_COMPONENT16, width, height);
|
||||
EaglercraftGPU.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (ByteBuffer)null);
|
||||
if(enableDepth) {
|
||||
_wglBindRenderbuffer(_GL_RENDERBUFFER, depthBuffer);
|
||||
_wglRenderbufferStorage(_GL_RENDERBUFFER, _GL_DEPTH_COMPONENT16, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
_wglBindFramebuffer(_GL_FRAMEBUFFER, framebuffer);
|
||||
return resized;
|
||||
}
|
||||
|
||||
public void endRender() {
|
||||
_wglBindFramebuffer(_GL_FRAMEBUFFER, null);
|
||||
age = System.currentTimeMillis();
|
||||
age = EagRuntime.steadyTimeMillis();
|
||||
}
|
||||
|
||||
public long getAge() {
|
||||
return age == -1l ? -1l : (System.currentTimeMillis() - age);
|
||||
return age == -1l ? -1l : (EagRuntime.steadyTimeMillis() - age);
|
||||
}
|
||||
|
||||
public int getTexture() {
|
||||
@ -84,7 +103,9 @@ public class GameOverlayFramebuffer {
|
||||
public void destroy() {
|
||||
if(framebuffer != null) {
|
||||
_wglDeleteFramebuffer(framebuffer);
|
||||
_wglDeleteRenderbuffer(depthBuffer);
|
||||
if(enableDepth) {
|
||||
_wglDeleteRenderbuffer(depthBuffer);
|
||||
}
|
||||
GlStateManager.deleteTexture(framebufferColor);
|
||||
framebuffer = null;
|
||||
depthBuffer = null;
|
||||
|
@ -30,10 +30,12 @@ public class GlStateManager {
|
||||
static final Logger logger = LogManager.getLogger("GlStateManager");
|
||||
|
||||
static boolean stateDepthTest = false;
|
||||
static boolean stateDepthTestStash = false;
|
||||
static int stateDepthFunc = -1;
|
||||
static boolean stateDepthMask = true;
|
||||
|
||||
static boolean stateCull = false;
|
||||
static boolean stateCullStash = false;
|
||||
static int stateCullFace = GL_BACK;
|
||||
|
||||
static boolean statePolygonOffset = false;
|
||||
@ -58,6 +60,7 @@ public class GlStateManager {
|
||||
static boolean stateEnableShaderBlendColor = false;
|
||||
|
||||
static boolean stateBlend = false;
|
||||
static boolean stateBlendStash = false;
|
||||
static boolean stateGlobalBlend = true;
|
||||
static int stateBlendEquation = -1;
|
||||
static int stateBlendSRC = -1;
|
||||
@ -312,6 +315,30 @@ public class GlStateManager {
|
||||
}
|
||||
}
|
||||
|
||||
public static final void eagPushStateForGLES2BlitHack() {
|
||||
stateDepthTestStash = stateDepthTest;
|
||||
stateCullStash = stateCull;
|
||||
stateBlendStash = stateBlend;
|
||||
}
|
||||
|
||||
public static final void eagPopStateForGLES2BlitHack() {
|
||||
if(stateDepthTestStash) {
|
||||
enableDepth();
|
||||
}else {
|
||||
disableDepth();
|
||||
}
|
||||
if(stateCullStash) {
|
||||
enableCull();
|
||||
}else {
|
||||
disableCull();
|
||||
}
|
||||
if(stateBlendStash) {
|
||||
enableBlend();
|
||||
}else {
|
||||
disableBlend();
|
||||
}
|
||||
}
|
||||
|
||||
public static final void depthFunc(int depthFunc) {
|
||||
int rev = depthFunc;
|
||||
switch(depthFunc) {
|
||||
@ -603,7 +630,9 @@ public class GlStateManager {
|
||||
f2 = f1;
|
||||
}
|
||||
_wglBindTexture(GL_TEXTURE_2D, null);
|
||||
_wglBindTexture(GL_TEXTURE_3D, null);
|
||||
if(EaglercraftGPU.checkOpenGLESVersion() >= 300) {
|
||||
_wglBindTexture(GL_TEXTURE_3D, null);
|
||||
}
|
||||
boundTexture[i] = -1;
|
||||
}
|
||||
}
|
||||
|
@ -56,6 +56,22 @@ public class ImageData {
|
||||
return new ImageData(pw, ph, img, alpha);
|
||||
}
|
||||
|
||||
public static String getMimeFromType(String nameOrPath) {
|
||||
if(nameOrPath == null) return "image/png";
|
||||
nameOrPath = nameOrPath.toLowerCase();
|
||||
if(nameOrPath.endsWith(".png")) {
|
||||
return "image/png";
|
||||
}else if(nameOrPath.endsWith(".jpg") || nameOrPath.endsWith(".jpeg")) {
|
||||
return "image/jpeg";
|
||||
}else if(nameOrPath.endsWith(".gif")) {
|
||||
return "image/gif";
|
||||
}else if(nameOrPath.endsWith(".bmp")) {
|
||||
return "image/bmp";
|
||||
}else {
|
||||
return "image/png"; // rip
|
||||
}
|
||||
}
|
||||
|
||||
public static final ImageData loadImageFile(String path) {
|
||||
byte[] fileData = EagRuntime.getResourceBytes(path);
|
||||
if(fileData != null) {
|
||||
@ -73,6 +89,23 @@ public class ImageData {
|
||||
return PlatformAssets.loadImageFile(data);
|
||||
}
|
||||
|
||||
public static final ImageData loadImageFile(String path, String mime) {
|
||||
byte[] fileData = EagRuntime.getResourceBytes(path);
|
||||
if(fileData != null) {
|
||||
return loadImageFile(fileData, mime);
|
||||
}else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static final ImageData loadImageFile(InputStream data, String mime) {
|
||||
return PlatformAssets.loadImageFile(data, mime);
|
||||
}
|
||||
|
||||
public static final ImageData loadImageFile(byte[] data, String mime) {
|
||||
return PlatformAssets.loadImageFile(data, mime);
|
||||
}
|
||||
|
||||
public void getRGB(int startX, int startY, int w, int h,
|
||||
int[] rgbArray, int offset, int scansize) {
|
||||
for(int y = 0; y < h; ++y) {
|
||||
@ -147,5 +180,22 @@ public class ImageData {
|
||||
public static int swapRB(int c) {
|
||||
return (c & 0xFF00FF00) | ((c & 0x00FF0000) >>> 16) | ((c & 0x000000FF) << 16);
|
||||
}
|
||||
|
||||
public static int[] swapRB(int[] arr) {
|
||||
for(int i = 0; i < arr.length; ++i) {
|
||||
int j = arr[i];
|
||||
arr[i] = (j & 0xFF00FF00) | ((j & 0x00FF0000) >>> 16) |
|
||||
((j & 0x000000FF) << 16);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
public boolean isNPOT() {
|
||||
return (width & (width - 1)) != 0 || (height & (height - 1)) != 0;
|
||||
}
|
||||
|
||||
public static boolean isNPOTStatic(int w, int h) {
|
||||
return (w & (w - 1)) != 0 || (h & (h - 1)) != 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,13 +13,12 @@ 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.FixedFunctionShader.FixedFunctionConstants;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.DeferredStateManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.vector.Matrix4f;
|
||||
import net.lax1dude.eaglercraft.v1_8.vector.Vector4f;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 lax1dude. All Rights Reserved.
|
||||
* Copyright (c) 2022-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
|
||||
@ -38,7 +37,10 @@ public class InstancedFontRenderer {
|
||||
private static final Logger logger = LogManager.getLogger("InstancedFontRenderer");
|
||||
|
||||
public static final String vertexShaderPath = "/assets/eagler/glsl/accel_font.vsh";
|
||||
public static final String vertexShaderPrecision = "precision lowp int;\nprecision highp float;\nprecision mediump sampler2D;\n";
|
||||
|
||||
public static final String fragmentShaderPath = "/assets/eagler/glsl/accel_font.fsh";
|
||||
public static final String fragmentShaderPrecision = "precision lowp int;\nprecision highp float;\nprecision mediump sampler2D;\n";
|
||||
|
||||
private static final int BYTES_PER_CHARACTER = 10;
|
||||
private static final int CHARACTER_LIMIT = 6553;
|
||||
@ -78,21 +80,13 @@ public class InstancedFontRenderer {
|
||||
private static float charCoordHeightValue = -1.0f;
|
||||
|
||||
static void initialize() {
|
||||
|
||||
String vertexSource = EagRuntime.getResourceString(vertexShaderPath);
|
||||
if(vertexSource == null) {
|
||||
throw new RuntimeException("InstancedFontRenderer shader \"" + vertexShaderPath + "\" is missing!");
|
||||
}
|
||||
|
||||
String fragmentSource = EagRuntime.getResourceString(fragmentShaderPath);
|
||||
if(fragmentSource == null) {
|
||||
throw new RuntimeException("InstancedFontRenderer shader \"" + fragmentShaderPath + "\" is missing!");
|
||||
}
|
||||
String vertexSource = EagRuntime.getRequiredResourceString(vertexShaderPath);
|
||||
String fragmentSource = EagRuntime.getRequiredResourceString(fragmentShaderPath);
|
||||
|
||||
IShaderGL vert = _wglCreateShader(GL_VERTEX_SHADER);
|
||||
IShaderGL frag = _wglCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
_wglShaderSource(vert, FixedFunctionConstants.VERSION + "\n" + vertexSource);
|
||||
_wglShaderSource(vert, GLSLHeader.getVertexHeaderCompat(vertexSource, vertexShaderPrecision));
|
||||
_wglCompileShader(vert);
|
||||
|
||||
if(_wglGetShaderi(vert, GL_COMPILE_STATUS) != GL_TRUE) {
|
||||
@ -107,7 +101,7 @@ public class InstancedFontRenderer {
|
||||
throw new IllegalStateException("Vertex shader \"" + vertexShaderPath + "\" could not be compiled!");
|
||||
}
|
||||
|
||||
_wglShaderSource(frag, FixedFunctionConstants.VERSION + "\n" + fragmentSource);
|
||||
_wglShaderSource(frag, GLSLHeader.getFragmentHeaderCompat(fragmentSource, fragmentShaderPrecision));
|
||||
_wglCompileShader(frag);
|
||||
|
||||
if(_wglGetShaderi(frag, GL_COMPILE_STATUS) != GL_TRUE) {
|
||||
@ -127,6 +121,10 @@ public class InstancedFontRenderer {
|
||||
_wglAttachShader(shaderProgram, vert);
|
||||
_wglAttachShader(shaderProgram, frag);
|
||||
|
||||
if(EaglercraftGPU.checkOpenGLESVersion() == 200) {
|
||||
VSHInputLayoutParser.applyLayout(shaderProgram, VSHInputLayoutParser.getShaderInputs(vertexSource));
|
||||
}
|
||||
|
||||
_wglLinkProgram(shaderProgram);
|
||||
|
||||
_wglDetachShader(shaderProgram, vert);
|
||||
@ -161,60 +159,62 @@ public class InstancedFontRenderer {
|
||||
|
||||
_wglUniform1i(_wglGetUniformLocation(shaderProgram, "u_inputTexture"), 0);
|
||||
|
||||
vertexArray = _wglGenVertexArrays();
|
||||
vertexArray = EaglercraftGPU.createGLBufferArray();
|
||||
vertexBuffer = _wglGenBuffers();
|
||||
instancesBuffer = _wglGenBuffers();
|
||||
|
||||
FloatBuffer verts = EagRuntime.allocateFloatBuffer(108);
|
||||
float paddingA = 0.005f;
|
||||
float paddingB = 1.0f - paddingA;
|
||||
verts.put(new float[] {
|
||||
|
||||
// (0 - 6 - 12) regular:
|
||||
|
||||
0.0f, 0.0f, 0.25f, 0.0f, 1.0f, 0.25f, 1.0f, 0.0f, 0.25f,
|
||||
1.0f, 0.0f, 0.25f, 0.0f, 1.0f, 0.25f, 1.0f, 1.0f, 0.25f,
|
||||
0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
|
||||
paddingA, paddingA, 0.25f, paddingA, paddingB, 0.25f, paddingB, paddingA, 0.25f,
|
||||
paddingB, paddingA, 0.25f, paddingA, paddingB, 0.25f, paddingB, paddingB, 0.25f,
|
||||
paddingA, paddingA, 0.0f, paddingA, paddingB, 0.0f, paddingB, paddingA, 0.0f,
|
||||
paddingB, paddingA, 0.0f, paddingA, paddingB, 0.0f, paddingB, paddingB, 0.0f,
|
||||
|
||||
// (12 - 24 - 36) bold shadow:
|
||||
|
||||
0.0f, 0.0f, 0.25f, 0.0f, 1.0f, 0.25f, 1.0f, 0.0f, 0.25f,
|
||||
1.0f, 0.0f, 0.25f, 0.0f, 1.0f, 0.25f, 1.0f, 1.0f, 0.25f,
|
||||
0.0f, 0.0f, 0.75f, 0.0f, 1.0f, 0.75f, 1.0f, 0.0f, 0.75f,
|
||||
1.0f, 0.0f, 0.75f, 0.0f, 1.0f, 0.75f, 1.0f, 1.0f, 0.75f,
|
||||
paddingA, paddingA, 0.25f, paddingA, paddingB, 0.25f, paddingB, paddingA, 0.25f,
|
||||
paddingB, paddingA, 0.25f, paddingA, paddingB, 0.25f, paddingB, paddingB, 0.25f,
|
||||
paddingA, paddingA, 0.75f, paddingA, paddingB, 0.75f, paddingB, paddingA, 0.75f,
|
||||
paddingB, paddingA, 0.75f, paddingA, paddingB, 0.75f, paddingB, paddingB, 0.75f,
|
||||
|
||||
0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.5f, 0.0f, 1.0f, 0.5f, 1.0f, 0.0f, 0.5f,
|
||||
1.0f, 0.0f, 0.5f, 0.0f, 1.0f, 0.5f, 1.0f, 1.0f, 0.5f
|
||||
paddingA, paddingA, 0.0f, paddingA, paddingB, 0.0f, paddingB, paddingA, 0.0f,
|
||||
paddingB, paddingA, 0.0f, paddingA, paddingB, 0.0f, paddingB, paddingB, 0.0f,
|
||||
paddingA, paddingA, 0.5f, paddingA, paddingB, 0.5f, paddingB, paddingA, 0.5f,
|
||||
paddingB, paddingA, 0.5f, paddingA, paddingB, 0.5f, paddingB, paddingB, 0.5f
|
||||
|
||||
});
|
||||
verts.flip();
|
||||
|
||||
EaglercraftGPU.bindGLBufferArray(vertexArray);
|
||||
|
||||
EaglercraftGPU.bindGLArrayBuffer(vertexBuffer);
|
||||
EaglercraftGPU.bindVAOGLArrayBufferNow(vertexBuffer);
|
||||
_wglBufferData(GL_ARRAY_BUFFER, verts, GL_STATIC_DRAW);
|
||||
|
||||
EagRuntime.freeFloatBuffer(verts);
|
||||
|
||||
_wglEnableVertexAttribArray(0);
|
||||
_wglVertexAttribPointer(0, 3, GL_FLOAT, false, 12, 0);
|
||||
_wglVertexAttribDivisor(0, 0);
|
||||
EaglercraftGPU.enableVertexAttribArray(0);
|
||||
EaglercraftGPU.vertexAttribPointer(0, 3, GL_FLOAT, false, 12, 0);
|
||||
EaglercraftGPU.vertexAttribDivisor(0, 0);
|
||||
|
||||
EaglercraftGPU.bindGLArrayBuffer(instancesBuffer);
|
||||
EaglercraftGPU.bindVAOGLArrayBufferNow(instancesBuffer);
|
||||
_wglBufferData(GL_ARRAY_BUFFER, fontDataBuffer.remaining(), GL_STREAM_DRAW);
|
||||
|
||||
_wglEnableVertexAttribArray(1);
|
||||
_wglVertexAttribPointer(1, 2, GL_SHORT, false, 10, 0);
|
||||
_wglVertexAttribDivisor(1, 1);
|
||||
EaglercraftGPU.enableVertexAttribArray(1);
|
||||
EaglercraftGPU.vertexAttribPointer(1, 2, GL_SHORT, false, 10, 0);
|
||||
EaglercraftGPU.vertexAttribDivisor(1, 1);
|
||||
|
||||
_wglEnableVertexAttribArray(2);
|
||||
_wglVertexAttribPointer(2, 2, GL_UNSIGNED_BYTE, false, 10, 4);
|
||||
_wglVertexAttribDivisor(2, 1);
|
||||
EaglercraftGPU.enableVertexAttribArray(2);
|
||||
EaglercraftGPU.vertexAttribPointer(2, 2, GL_UNSIGNED_BYTE, false, 10, 4);
|
||||
EaglercraftGPU.vertexAttribDivisor(2, 1);
|
||||
|
||||
_wglEnableVertexAttribArray(3);
|
||||
_wglVertexAttribPointer(3, 4, GL_UNSIGNED_BYTE, true, 10, 6);
|
||||
_wglVertexAttribDivisor(3, 1);
|
||||
EaglercraftGPU.enableVertexAttribArray(3);
|
||||
EaglercraftGPU.vertexAttribPointer(3, 4, GL_UNSIGNED_BYTE, true, 10, 6);
|
||||
EaglercraftGPU.vertexAttribDivisor(3, 1);
|
||||
|
||||
}
|
||||
|
||||
@ -381,7 +381,7 @@ public class InstancedFontRenderer {
|
||||
fontDataBuffer.position(p);
|
||||
fontDataBuffer.limit(l);
|
||||
|
||||
_wglDrawArraysInstanced(GL_TRIANGLES, shadow ? 0 : 6, shadow ? 12 : 6, charactersDrawn);
|
||||
EaglercraftGPU.doDrawArraysInstanced(GL_TRIANGLES, shadow ? 0 : 6, shadow ? 12 : 6, charactersDrawn);
|
||||
}
|
||||
|
||||
if(boldCharactersDrawn > 0) {
|
||||
@ -394,7 +394,7 @@ public class InstancedFontRenderer {
|
||||
fontBoldDataBuffer.position(p);
|
||||
fontBoldDataBuffer.limit(l);
|
||||
|
||||
_wglDrawArraysInstanced(GL_TRIANGLES, shadow ? 12 : 24, shadow ? 24 : 12, boldCharactersDrawn);
|
||||
EaglercraftGPU.doDrawArraysInstanced(GL_TRIANGLES, shadow ? 12 : 24, shadow ? 24 : 12, boldCharactersDrawn);
|
||||
}
|
||||
}
|
||||
|
||||
@ -455,4 +455,40 @@ public class InstancedFontRenderer {
|
||||
if(y > heightCalcMost || heightCalcMost == Integer.MAX_VALUE) heightCalcMost = y;
|
||||
}
|
||||
|
||||
public static void destroy() {
|
||||
if(fontDataBuffer != null) {
|
||||
EagRuntime.freeByteBuffer(fontDataBuffer);
|
||||
fontDataBuffer = null;
|
||||
}
|
||||
if(fontBoldDataBuffer != null) {
|
||||
EagRuntime.freeByteBuffer(fontBoldDataBuffer);
|
||||
fontBoldDataBuffer = null;
|
||||
}
|
||||
if(shaderProgram != null) {
|
||||
_wglDeleteProgram(shaderProgram);
|
||||
shaderProgram = null;
|
||||
}
|
||||
if(matrixCopyBuffer != null) {
|
||||
EagRuntime.freeFloatBuffer(matrixCopyBuffer);
|
||||
matrixCopyBuffer = null;
|
||||
}
|
||||
u_matrixTransform = null;
|
||||
u_charSize2f = null;
|
||||
u_charCoordSize2f = null;
|
||||
u_color4f = null;
|
||||
u_colorBias4f = null;
|
||||
if(vertexArray != null) {
|
||||
EaglercraftGPU.destroyGLBufferArray(vertexArray);
|
||||
vertexArray = null;
|
||||
}
|
||||
if(vertexBuffer != null) {
|
||||
_wglDeleteBuffers(vertexBuffer);
|
||||
vertexBuffer = null;
|
||||
}
|
||||
if(instancesBuffer != null) {
|
||||
_wglDeleteBuffers(instancesBuffer);
|
||||
instancesBuffer = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,11 +13,10 @@ 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.FixedFunctionShader.FixedFunctionConstants;
|
||||
import net.lax1dude.eaglercraft.v1_8.vector.Matrix4f;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 lax1dude. All Rights Reserved.
|
||||
* Copyright (c) 2022-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
|
||||
@ -36,7 +35,10 @@ public class InstancedParticleRenderer {
|
||||
private static final Logger logger = LogManager.getLogger("InstancedParticleRenderer");
|
||||
|
||||
public static final String vertexShaderPath = "/assets/eagler/glsl/accel_particle.vsh";
|
||||
public static final String vertexShaderPrecision = "precision lowp int;\nprecision highp float;\nprecision mediump sampler2D;\n";
|
||||
|
||||
public static final String fragmentShaderPath = "/assets/eagler/glsl/accel_particle.fsh";
|
||||
public static final String fragmentShaderPrecision = "precision lowp int;\nprecision mediump float;\nprecision mediump sampler2D;\n";
|
||||
|
||||
private static ByteBuffer particleBuffer = null;
|
||||
private static int particleCount = 0;
|
||||
@ -79,20 +81,13 @@ public class InstancedParticleRenderer {
|
||||
private static float stateTransformParam5 = -999.0f;
|
||||
|
||||
static void initialize() {
|
||||
String vertexSource = EagRuntime.getResourceString(vertexShaderPath);
|
||||
if(vertexSource == null) {
|
||||
throw new RuntimeException("InstancedParticleRenderer shader \"" + vertexShaderPath + "\" is missing!");
|
||||
}
|
||||
|
||||
String fragmentSource = EagRuntime.getResourceString(fragmentShaderPath);
|
||||
if(fragmentSource == null) {
|
||||
throw new RuntimeException("InstancedParticleRenderer shader \"" + fragmentShaderPath + "\" is missing!");
|
||||
}
|
||||
String vertexSource = EagRuntime.getRequiredResourceString(vertexShaderPath);
|
||||
String fragmentSource = EagRuntime.getRequiredResourceString(fragmentShaderPath);
|
||||
|
||||
IShaderGL vert = _wglCreateShader(GL_VERTEX_SHADER);
|
||||
IShaderGL frag = _wglCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
_wglShaderSource(vert, FixedFunctionConstants.VERSION + "\n" + vertexSource);
|
||||
_wglShaderSource(vert, GLSLHeader.getVertexHeaderCompat(vertexSource, vertexShaderPrecision));
|
||||
_wglCompileShader(vert);
|
||||
|
||||
if(_wglGetShaderi(vert, GL_COMPILE_STATUS) != GL_TRUE) {
|
||||
@ -107,7 +102,7 @@ public class InstancedParticleRenderer {
|
||||
throw new IllegalStateException("Vertex shader \"" + vertexShaderPath + "\" could not be compiled!");
|
||||
}
|
||||
|
||||
_wglShaderSource(frag, FixedFunctionConstants.VERSION + "\n" + fragmentSource);
|
||||
_wglShaderSource(frag, GLSLHeader.getFragmentHeaderCompat(fragmentSource, fragmentShaderPrecision));
|
||||
_wglCompileShader(frag);
|
||||
|
||||
if(_wglGetShaderi(frag, GL_COMPILE_STATUS) != GL_TRUE) {
|
||||
@ -127,6 +122,10 @@ public class InstancedParticleRenderer {
|
||||
_wglAttachShader(shaderProgram, vert);
|
||||
_wglAttachShader(shaderProgram, frag);
|
||||
|
||||
if(EaglercraftGPU.checkOpenGLESVersion() == 200) {
|
||||
VSHInputLayoutParser.applyLayout(shaderProgram, VSHInputLayoutParser.getShaderInputs(vertexSource));
|
||||
}
|
||||
|
||||
_wglLinkProgram(shaderProgram);
|
||||
|
||||
_wglDetachShader(shaderProgram, vert);
|
||||
@ -161,7 +160,7 @@ public class InstancedParticleRenderer {
|
||||
_wglUniform1i(_wglGetUniformLocation(shaderProgram, "u_inputTexture"), 0);
|
||||
_wglUniform1i(_wglGetUniformLocation(shaderProgram, "u_lightmapTexture"), 1);
|
||||
|
||||
vertexArray = _wglGenVertexArrays();
|
||||
vertexArray = EaglercraftGPU.createGLBufferArray();
|
||||
vertexBuffer = _wglGenBuffers();
|
||||
instancesBuffer = _wglGenBuffers();
|
||||
|
||||
@ -174,37 +173,37 @@ public class InstancedParticleRenderer {
|
||||
|
||||
EaglercraftGPU.bindGLBufferArray(vertexArray);
|
||||
|
||||
EaglercraftGPU.bindGLArrayBuffer(vertexBuffer);
|
||||
EaglercraftGPU.bindVAOGLArrayBufferNow(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.enableVertexAttribArray(0);
|
||||
EaglercraftGPU.vertexAttribPointer(0, 2, GL_FLOAT, false, 8, 0);
|
||||
EaglercraftGPU.vertexAttribDivisor(0, 0);
|
||||
|
||||
EaglercraftGPU.bindGLArrayBuffer(instancesBuffer);
|
||||
EaglercraftGPU.bindVAOGLArrayBufferNow(instancesBuffer);
|
||||
_wglBufferData(GL_ARRAY_BUFFER, particleBuffer.remaining(), GL_STREAM_DRAW);
|
||||
|
||||
_wglEnableVertexAttribArray(1);
|
||||
_wglVertexAttribPointer(1, 3, GL_FLOAT, false, 24, 0);
|
||||
_wglVertexAttribDivisor(1, 1);
|
||||
EaglercraftGPU.enableVertexAttribArray(1);
|
||||
EaglercraftGPU.vertexAttribPointer(1, 3, GL_FLOAT, false, 24, 0);
|
||||
EaglercraftGPU.vertexAttribDivisor(1, 1);
|
||||
|
||||
_wglEnableVertexAttribArray(2);
|
||||
_wglVertexAttribPointer(2, 2, GL_UNSIGNED_SHORT, false, 24, 12);
|
||||
_wglVertexAttribDivisor(2, 1);
|
||||
EaglercraftGPU.enableVertexAttribArray(2);
|
||||
EaglercraftGPU.vertexAttribPointer(2, 2, GL_UNSIGNED_SHORT, false, 24, 12);
|
||||
EaglercraftGPU.vertexAttribDivisor(2, 1);
|
||||
|
||||
_wglEnableVertexAttribArray(3);
|
||||
_wglVertexAttribPointer(3, 2, GL_UNSIGNED_BYTE, true, 24, 16);
|
||||
_wglVertexAttribDivisor(3, 1);
|
||||
EaglercraftGPU.enableVertexAttribArray(3);
|
||||
EaglercraftGPU.vertexAttribPointer(3, 2, GL_UNSIGNED_BYTE, true, 24, 16);
|
||||
EaglercraftGPU.vertexAttribDivisor(3, 1);
|
||||
|
||||
_wglEnableVertexAttribArray(4);
|
||||
_wglVertexAttribPointer(4, 2, GL_UNSIGNED_BYTE, false, 24, 18);
|
||||
_wglVertexAttribDivisor(4, 1);
|
||||
EaglercraftGPU.enableVertexAttribArray(4);
|
||||
EaglercraftGPU.vertexAttribPointer(4, 2, GL_UNSIGNED_BYTE, false, 24, 18);
|
||||
EaglercraftGPU.vertexAttribDivisor(4, 1);
|
||||
|
||||
_wglEnableVertexAttribArray(5);
|
||||
_wglVertexAttribPointer(5, 4, GL_UNSIGNED_BYTE, true, 24, 20);
|
||||
_wglVertexAttribDivisor(5, 1);
|
||||
EaglercraftGPU.enableVertexAttribArray(5);
|
||||
EaglercraftGPU.vertexAttribPointer(5, 4, GL_UNSIGNED_BYTE, true, 24, 20);
|
||||
EaglercraftGPU.vertexAttribDivisor(5, 1);
|
||||
|
||||
}
|
||||
|
||||
@ -316,11 +315,43 @@ public class InstancedParticleRenderer {
|
||||
particleBuffer.position(p);
|
||||
particleBuffer.limit(l);
|
||||
|
||||
_wglDrawArraysInstanced(GL_TRIANGLES, 0, 6, particleCount);
|
||||
EaglercraftGPU.doDrawArraysInstanced(GL_TRIANGLES, 0, 6, particleCount);
|
||||
}
|
||||
|
||||
public static void stupidColorSetHack(IUniformGL color4f) {
|
||||
_wglUniform4f(color4f, GlStateManager.stateColorR, GlStateManager.stateColorG, GlStateManager.stateColorB, GlStateManager.stateColorA);
|
||||
}
|
||||
|
||||
public static void destroy() {
|
||||
if(particleBuffer != null) {
|
||||
EagRuntime.freeByteBuffer(particleBuffer);
|
||||
particleBuffer = null;
|
||||
}
|
||||
if(shaderProgram != null) {
|
||||
_wglDeleteProgram(shaderProgram);
|
||||
shaderProgram = null;
|
||||
}
|
||||
if(matrixCopyBuffer != null) {
|
||||
EagRuntime.freeFloatBuffer(matrixCopyBuffer);
|
||||
matrixCopyBuffer = null;
|
||||
}
|
||||
u_matrixTransform = null;
|
||||
u_texCoordSize2f_particleSize1f = null;
|
||||
u_transformParam_1_2_5_f = null;
|
||||
u_transformParam_3_4_f = null;
|
||||
u_color4f = null;
|
||||
if(vertexArray != null) {
|
||||
EaglercraftGPU.destroyGLBufferArray(vertexArray);
|
||||
vertexArray = null;
|
||||
}
|
||||
if(vertexBuffer != null) {
|
||||
_wglDeleteBuffers(vertexBuffer);
|
||||
vertexBuffer = null;
|
||||
}
|
||||
if(instancesBuffer != null) {
|
||||
_wglDeleteBuffers(instancesBuffer);
|
||||
instancesBuffer = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.opengl;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 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
|
||||
|
@ -0,0 +1,225 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.opengl;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IBufferArrayGL;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IBufferGL;
|
||||
|
||||
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
|
||||
|
||||
/**
|
||||
* 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 SoftGLBufferArray implements IBufferArrayGL {
|
||||
|
||||
Attrib[] attribs = new Attrib[4];
|
||||
int[] attribDivisors = null;
|
||||
int hasAttribDivisorMask = 0;
|
||||
int enabled = 0;
|
||||
int enabledCnt = -1;
|
||||
IBufferGL indexBuffer = null;
|
||||
|
||||
SoftGLBufferArray() {
|
||||
}
|
||||
|
||||
void setAttrib(IBufferGL buffer, int index, int size, int format, boolean normalized, int stride, int offset) {
|
||||
if(index >= attribs.length) {
|
||||
int newLen = attribs.length << 1;
|
||||
while(newLen <= index) {
|
||||
newLen <<= 1;
|
||||
}
|
||||
Attrib[] newAttrib = new Attrib[newLen];
|
||||
System.arraycopy(attribs, 0, newAttrib, 0, attribs.length);
|
||||
attribs = newAttrib;
|
||||
}
|
||||
attribs[index] = new Attrib(buffer, size, format, normalized, stride, offset);
|
||||
}
|
||||
|
||||
void setAttribDivisor(int index, int divisor) {
|
||||
if(attribDivisors == null) {
|
||||
if(divisor != 0) {
|
||||
int newLen = 8;
|
||||
while(newLen <= index) {
|
||||
newLen <<= 1;
|
||||
}
|
||||
attribDivisors = new int[newLen];
|
||||
}
|
||||
}else if(index >= attribDivisors.length) {
|
||||
int newLen = attribDivisors.length << 1;
|
||||
while(newLen <= index) {
|
||||
newLen <<= 1;
|
||||
}
|
||||
int[] newDivisor = new int[newLen];
|
||||
System.arraycopy(attribDivisors, 0, newDivisor, 0, attribDivisors.length);
|
||||
attribDivisors = newDivisor;
|
||||
}
|
||||
if(attribDivisors != null) {
|
||||
attribDivisors[index] = divisor;
|
||||
if(divisor != 0) {
|
||||
hasAttribDivisorMask |= (1 << index);
|
||||
}else {
|
||||
hasAttribDivisorMask &= ~(1 << index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void enableAttrib(int index, boolean en) {
|
||||
if(en) {
|
||||
enabled |= (1 << index);
|
||||
}else {
|
||||
enabled &= ~(1 << index);
|
||||
}
|
||||
enabledCnt = 32 - Integer.numberOfLeadingZeros(enabled);
|
||||
}
|
||||
|
||||
void setIndexBuffer(IBufferGL buffer) {
|
||||
indexBuffer = buffer;
|
||||
}
|
||||
|
||||
void transitionToState(SoftGLBufferState previousState, boolean elements) {
|
||||
int oldEnabled = previousState.oldEnabled;
|
||||
int oldEnabledCnt = previousState.oldEnabledCnt;
|
||||
int[] oldAttribDivisors = previousState.attribDivisors;
|
||||
int oldHasAttribDivisorMask = previousState.hasAttribDivisorMask;
|
||||
Attrib[] oldAttrs = previousState.attribs;
|
||||
boolean instancingCapable = EaglercraftGPU.checkInstancingCapable();
|
||||
int enCnt = enabledCnt;
|
||||
int en = enabled;
|
||||
Attrib[] attrs = attribs;
|
||||
int[] divs = attribDivisors;
|
||||
int hasDivs = hasAttribDivisorMask;
|
||||
if(oldEnabledCnt >= 0) {
|
||||
int enMax = Math.max(enCnt, oldEnabledCnt);
|
||||
for(int i = 0, ii; i < enMax; ++i) {
|
||||
ii = (1 << i);
|
||||
boolean old = i < oldEnabledCnt && (oldEnabled & ii) != 0;
|
||||
boolean _new = i < enCnt && (en & ii) != 0;
|
||||
if(_new) {
|
||||
if(!old) {
|
||||
_wglEnableVertexAttribArray(i);
|
||||
}
|
||||
Attrib attr = i < attrs.length ? attrs[i] : null;
|
||||
if(attr != null) {
|
||||
Attrib oldAttr = oldAttrs[i];
|
||||
if(oldAttr == null || !oldAttr.equalsExplicit(attr)) {
|
||||
EaglercraftGPU.bindGLArrayBuffer(attr.buffer);
|
||||
_wglVertexAttribPointer(i, attr.size, attr.format, attr.normalized, attr.stride, attr.offset);
|
||||
oldAttrs[i] = attr;
|
||||
}
|
||||
}else {
|
||||
oldAttrs[i] = null;
|
||||
}
|
||||
if(instancingCapable) {
|
||||
// instancing is uncommon
|
||||
if((hasDivs & ii) != 0) {
|
||||
int newDivisor = divs[i];
|
||||
if((oldHasAttribDivisorMask & ii) == 0 || newDivisor != oldAttribDivisors[i]) {
|
||||
_wglVertexAttribDivisor(i, newDivisor);
|
||||
oldAttribDivisors[i] = newDivisor;
|
||||
previousState.hasAttribDivisorMask |= ii;
|
||||
}
|
||||
}else {
|
||||
if((oldHasAttribDivisorMask & ii) != 0) {
|
||||
_wglVertexAttribDivisor(i, 0);
|
||||
oldAttribDivisors[i] = 0;
|
||||
previousState.hasAttribDivisorMask &= ~ii;
|
||||
}
|
||||
}
|
||||
}
|
||||
}else if(old) {
|
||||
_wglDisableVertexAttribArray(i);
|
||||
}
|
||||
}
|
||||
}else {
|
||||
// Bootstrap code for the emulator's first draw
|
||||
for(int i = 0; i < enCnt; ++i) {
|
||||
int ii = (1 << i);
|
||||
if((en & ii) != 0) {
|
||||
_wglEnableVertexAttribArray(i);
|
||||
Attrib attr = attrs[i];
|
||||
if(attr != null) {
|
||||
EaglercraftGPU.bindGLArrayBuffer(attr.buffer);
|
||||
_wglVertexAttribPointer(i, attr.size, attr.format, attr.normalized, attr.stride, attr.offset);
|
||||
oldAttrs[i] = attr;
|
||||
}else {
|
||||
oldAttrs[i] = null;
|
||||
}
|
||||
if(instancingCapable) {
|
||||
if((hasDivs & ii) != 0) {
|
||||
int newDivisor = divs[i];
|
||||
_wglVertexAttribDivisor(i, newDivisor);
|
||||
oldAttribDivisors[i] = newDivisor;
|
||||
previousState.hasAttribDivisorMask |= ii;
|
||||
}else {
|
||||
_wglVertexAttribDivisor(i, 0);
|
||||
oldAttribDivisors[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(elements) {
|
||||
IBufferGL indexBufferL = indexBuffer;
|
||||
if(indexBufferL != null) {
|
||||
EaglercraftGPU.bindEmulatedVAOIndexBuffer(indexBufferL);
|
||||
}
|
||||
}
|
||||
previousState.oldEnabled = en & ((1 << enCnt) - 1);
|
||||
previousState.oldEnabledCnt = enCnt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void free() {
|
||||
}
|
||||
|
||||
static class Attrib {
|
||||
|
||||
final IBufferGL buffer;
|
||||
final int size;
|
||||
final int format;
|
||||
final boolean normalized;
|
||||
final int stride;
|
||||
final int offset;
|
||||
final int hash;
|
||||
final int checkVal;
|
||||
|
||||
Attrib(IBufferGL buffer, int size, int format, boolean normalized, int stride, int offset) {
|
||||
this.buffer = buffer;
|
||||
this.size = size;
|
||||
this.format = format;
|
||||
this.normalized = normalized;
|
||||
this.stride = stride;
|
||||
this.offset = offset;
|
||||
this.checkVal = ((size - 1) & 3) | (normalized ? 4 : 0) | (format << 4);
|
||||
this.hash = (((((31 + buffer.hashCode()) * 31 + size) * 31 + format) * 31 + (normalized ? 1 : 0)) * 31
|
||||
+ stride) * 31 + offset;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if(obj == this) return true;
|
||||
if(!(obj instanceof Attrib)) return false;
|
||||
Attrib o2 = (Attrib)obj;
|
||||
return o2.hash == hash && o2.buffer == buffer && o2.checkVal == checkVal && o2.stride == stride && o2.offset == offset;
|
||||
}
|
||||
|
||||
public boolean equalsExplicit(Attrib o2) {
|
||||
return o2 == this || (o2.hash == hash && o2.buffer == buffer && o2.checkVal == checkVal && o2.stride == stride && o2.offset == offset);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.opengl;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.SoftGLBufferArray.Attrib;
|
||||
|
||||
/**
|
||||
* 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 SoftGLBufferState {
|
||||
|
||||
final Attrib[] attribs = new Attrib[24];
|
||||
int[] attribDivisors = new int[24];
|
||||
int hasAttribDivisorMask = 0;
|
||||
int oldEnabled = 0;
|
||||
int oldEnabledCnt = -1;
|
||||
|
||||
SoftGLBufferState() {
|
||||
}
|
||||
|
||||
}
|
@ -10,7 +10,6 @@ import net.lax1dude.eaglercraft.v1_8.internal.IUniformGL;
|
||||
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.FixedFunctionShader.FixedFunctionConstants;
|
||||
import net.lax1dude.eaglercraft.v1_8.vector.Matrix3f;
|
||||
|
||||
/**
|
||||
@ -33,6 +32,7 @@ public class SpriteLevelMixer {
|
||||
private static final Logger LOGGER = LogManager.getLogger("SpriteLevelMixer");
|
||||
|
||||
public static final String fragmentShaderPath = "/assets/eagler/glsl/texture_mix.fsh";
|
||||
public static final String fragmentShaderPrecision = "precision lowp int;\nprecision highp float;\nprecision highp sampler2D;\n";
|
||||
|
||||
private static IProgramGL shaderProgram = null;
|
||||
|
||||
@ -61,15 +61,11 @@ public class SpriteLevelMixer {
|
||||
private static final Matrix3f identityMatrix = new Matrix3f();
|
||||
|
||||
static void initialize() {
|
||||
|
||||
String fragmentSource = EagRuntime.getResourceString(fragmentShaderPath);
|
||||
if(fragmentSource == null) {
|
||||
throw new RuntimeException("SpriteLevelMixer shader \"" + fragmentShaderPath + "\" is missing!");
|
||||
}
|
||||
String fragmentSource = EagRuntime.getRequiredResourceString(fragmentShaderPath);
|
||||
|
||||
IShaderGL frag = _wglCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
_wglShaderSource(frag, FixedFunctionConstants.VERSION + "\n" + fragmentSource);
|
||||
_wglShaderSource(frag, GLSLHeader.getFragmentHeaderCompat(fragmentSource, fragmentShaderPrecision));
|
||||
_wglCompileShader(frag);
|
||||
|
||||
if(_wglGetShaderi(frag, GL_COMPILE_STATUS) != GL_TRUE) {
|
||||
@ -89,6 +85,10 @@ public class SpriteLevelMixer {
|
||||
_wglAttachShader(shaderProgram, DrawUtils.vshLocal);
|
||||
_wglAttachShader(shaderProgram, frag);
|
||||
|
||||
if(EaglercraftGPU.checkOpenGLESVersion() == 200) {
|
||||
VSHInputLayoutParser.applyLayout(shaderProgram, DrawUtils.vshLocalLayout);
|
||||
}
|
||||
|
||||
_wglLinkProgram(shaderProgram);
|
||||
|
||||
_wglDetachShader(shaderProgram, DrawUtils.vshLocal);
|
||||
@ -155,7 +155,14 @@ public class SpriteLevelMixer {
|
||||
public static void drawSprite(float level) {
|
||||
EaglercraftGPU.bindGLShaderProgram(shaderProgram);
|
||||
|
||||
_wglUniform1f(u_textureLod1f, level);
|
||||
if(EaglercraftGPU.checkTextureLODCapable()) {
|
||||
_wglUniform1f(u_textureLod1f, level);
|
||||
}else {
|
||||
if(level != 0.0f) {
|
||||
LOGGER.error("Tried to copy from mipmap level {}, but this GPU does not support textureLod!", level);
|
||||
}
|
||||
_wglUniform1f(u_textureLod1f, 0.0f);
|
||||
}
|
||||
|
||||
if(blendColorChanged) {
|
||||
_wglUniform4f(u_blendFactor4f, blendColorR, blendColorG, blendColorB, blendColorA);
|
||||
@ -178,4 +185,19 @@ public class SpriteLevelMixer {
|
||||
DrawUtils.drawStandardQuad2D();
|
||||
}
|
||||
|
||||
public static void destroy() {
|
||||
if(matrixCopyBuffer != null) {
|
||||
EagRuntime.freeFloatBuffer(matrixCopyBuffer);
|
||||
matrixCopyBuffer = null;
|
||||
}
|
||||
if(shaderProgram != null) {
|
||||
_wglDeleteProgram(shaderProgram);
|
||||
shaderProgram = null;
|
||||
}
|
||||
u_textureLod1f = null;
|
||||
u_blendFactor4f = null;
|
||||
u_blendBias4f = null;
|
||||
u_matrixTransform = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ public class StreamBuffer {
|
||||
next.vertexBuffer = _wglGenBuffers();
|
||||
}
|
||||
if(next.vertexArray == null) {
|
||||
next.vertexArray = _wglGenVertexArrays();
|
||||
next.vertexArray = EaglercraftGPU.createGLBufferArray();
|
||||
initializer.initialize(next.vertexArray, next.vertexBuffer);
|
||||
}
|
||||
if(next.vertexBufferSize < requiredMemory) {
|
||||
@ -100,7 +100,7 @@ public class StreamBuffer {
|
||||
newArray[i] = buffers[i];
|
||||
}else {
|
||||
if(buffers[i].vertexArray != null) {
|
||||
_wglDeleteVertexArrays(buffers[i].vertexArray);
|
||||
EaglercraftGPU.destroyGLBufferArray(buffers[i].vertexArray);
|
||||
}
|
||||
if(buffers[i].vertexBuffer != null) {
|
||||
_wglDeleteBuffers(buffers[i].vertexBuffer);
|
||||
@ -135,7 +135,7 @@ public class StreamBuffer {
|
||||
for(int i = 0; i < buffers.length; ++i) {
|
||||
StreamBufferInstance next = buffers[i];
|
||||
if(next.vertexArray != null) {
|
||||
_wglDeleteVertexArrays(next.vertexArray);
|
||||
EaglercraftGPU.destroyGLBufferArray(next.vertexArray);
|
||||
}
|
||||
if(next.vertexBuffer != null) {
|
||||
_wglDeleteBuffers(next.vertexBuffer);
|
||||
|
@ -3,16 +3,17 @@ package net.lax1dude.eaglercraft.v1_8.opengl;
|
||||
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
|
||||
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
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.log4j.LogManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.FixedFunctionShader.FixedFunctionConstants;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2023 lax1dude. All Rights Reserved.
|
||||
* 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
|
||||
@ -31,9 +32,13 @@ public class TextureCopyUtil {
|
||||
private static final Logger LOGGER = LogManager.getLogger("TextureCopyUtil");
|
||||
|
||||
public static final String vertexShaderPath = "/assets/eagler/glsl/texture_blit.vsh";
|
||||
public static final String vertexShaderPrecision = "precision lowp int;\nprecision highp float;\nprecision highp sampler2D;\n";
|
||||
|
||||
public static final String fragmentShaderPath = "/assets/eagler/glsl/texture_blit.fsh";
|
||||
public static final String fragmentShaderPrecision = "precision lowp int;\nprecision highp float;\nprecision highp sampler2D;\n";
|
||||
|
||||
private static String vshSource = null;
|
||||
private static List<VSHInputLayoutParser.ShaderInput> vshSourceLayout = null;
|
||||
private static String fshSource = null;
|
||||
|
||||
private static IShaderGL vshShader = null;
|
||||
@ -54,6 +59,17 @@ public class TextureCopyUtil {
|
||||
this.u_pixelAlignmentSizes4f = _wglGetUniformLocation(shaderProgram, "u_pixelAlignmentSizes4f");
|
||||
this.u_pixelAlignmentOffset2f = _wglGetUniformLocation(shaderProgram, "u_pixelAlignmentOffset2f");
|
||||
}
|
||||
private void destroy() {
|
||||
if(shaderProgram != null) {
|
||||
_wglDeleteProgram(shaderProgram);
|
||||
shaderProgram = null;
|
||||
}
|
||||
u_srcCoords4f = null;
|
||||
u_dstCoords4f = null;
|
||||
u_textureLod1f = null;
|
||||
u_pixelAlignmentSizes4f = null;
|
||||
u_pixelAlignmentOffset2f = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static TextureCopyShader textureBlit = null;
|
||||
@ -74,19 +90,12 @@ public class TextureCopyUtil {
|
||||
private static float alignOffsetY = 0.0f;
|
||||
|
||||
static void initialize() {
|
||||
vshSource = EagRuntime.getResourceString(vertexShaderPath);
|
||||
if(vshSource == null) {
|
||||
throw new RuntimeException("TextureCopyUtil shader \"" + vertexShaderPath + "\" is missing!");
|
||||
}
|
||||
|
||||
fshSource = EagRuntime.getResourceString(fragmentShaderPath);
|
||||
if(fshSource == null) {
|
||||
throw new RuntimeException("TextureCopyUtil shader \"" + fragmentShaderPath + "\" is missing!");
|
||||
}
|
||||
vshSource = EagRuntime.getRequiredResourceString(vertexShaderPath);
|
||||
fshSource = EagRuntime.getRequiredResourceString(fragmentShaderPath);
|
||||
|
||||
vshShader = _wglCreateShader(GL_VERTEX_SHADER);
|
||||
|
||||
_wglShaderSource(vshShader, FixedFunctionConstants.VERSION + "\n" + vshSource);
|
||||
_wglShaderSource(vshShader, GLSLHeader.getVertexHeaderCompat(vshSource, vertexShaderPrecision));
|
||||
_wglCompileShader(vshShader);
|
||||
|
||||
if(_wglGetShaderi(vshShader, GL_COMPILE_STATUS) != GL_TRUE) {
|
||||
@ -100,14 +109,17 @@ public class TextureCopyUtil {
|
||||
}
|
||||
throw new IllegalStateException("Vertex shader \"" + vertexShaderPath + "\" could not be compiled!");
|
||||
}
|
||||
|
||||
if(EaglercraftGPU.checkOpenGLESVersion() == 200) {
|
||||
vshSourceLayout = VSHInputLayoutParser.getShaderInputs(vshSource);
|
||||
}
|
||||
}
|
||||
|
||||
private static TextureCopyShader compileShader(boolean align, boolean depth) {
|
||||
IShaderGL frag = _wglCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
_wglShaderSource(frag,
|
||||
FixedFunctionConstants.VERSION + "\n" + (align ? "#define COMPILE_PIXEL_ALIGNMENT\n" : "")
|
||||
+ (depth ? "#define COMPILE_BLIT_DEPTH\n" : "") + fshSource);
|
||||
_wglShaderSource(frag, GLSLHeader.getFragmentHeaderCompat(fshSource, fragmentShaderPrecision
|
||||
+ (align ? "#define COMPILE_PIXEL_ALIGNMENT\n" : "") + (depth ? "#define COMPILE_BLIT_DEPTH\n" : "")));
|
||||
_wglCompileShader(frag);
|
||||
|
||||
if(_wglGetShaderi(frag, GL_COMPILE_STATUS) != GL_TRUE) {
|
||||
@ -127,6 +139,10 @@ public class TextureCopyUtil {
|
||||
_wglAttachShader(shaderProgram, vshShader);
|
||||
_wglAttachShader(shaderProgram, frag);
|
||||
|
||||
if(EaglercraftGPU.checkOpenGLESVersion() == 200) {
|
||||
VSHInputLayoutParser.applyLayout(shaderProgram, vshSourceLayout);
|
||||
}
|
||||
|
||||
_wglLinkProgram(shaderProgram);
|
||||
|
||||
_wglDetachShader(shaderProgram, vshShader);
|
||||
@ -226,7 +242,14 @@ public class TextureCopyUtil {
|
||||
_wglUniform4f(shaderObj.u_srcCoords4f, (float)srcX / srcViewW, (float)srcY / srcViewH, (float)srcW / srcViewW, (float)srcH / srcViewH);
|
||||
_wglUniform4f(shaderObj.u_dstCoords4f, (float) dstX / dstViewW - 1.0f, (float) dstY / dstViewH - 1.0f,
|
||||
(float) dstW / dstViewW, (float) dstH / dstViewH);
|
||||
_wglUniform1f(shaderObj.u_textureLod1f, lvl);
|
||||
if(EaglercraftGPU.checkTextureLODCapable()) {
|
||||
_wglUniform1f(shaderObj.u_textureLod1f, lvl);
|
||||
}else {
|
||||
if(lvl != 0.0f) {
|
||||
LOGGER.error("Tried to copy from mipmap level {}, but this GPU does not support textureLod!", lvl);
|
||||
}
|
||||
_wglUniform1f(shaderObj.u_textureLod1f, 0.0f);
|
||||
}
|
||||
if(isAligned) {
|
||||
_wglUniform4f(shaderObj.u_pixelAlignmentSizes4f, alignW, alignH, 1.0f / alignW, 1.0f / alignH);
|
||||
_wglUniform2f(shaderObj.u_pixelAlignmentOffset2f, alignOffsetX, alignOffsetY);
|
||||
@ -244,7 +267,14 @@ public class TextureCopyUtil {
|
||||
EaglercraftGPU.bindGLShaderProgram(shaderObj.shaderProgram);
|
||||
_wglUniform4f(shaderObj.u_srcCoords4f, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||
_wglUniform4f(shaderObj.u_dstCoords4f, -1.0f, -1.0f, 2.0f, 2.0f);
|
||||
_wglUniform1f(shaderObj.u_textureLod1f, lvl);
|
||||
if(EaglercraftGPU.checkTextureLODCapable()) {
|
||||
_wglUniform1f(shaderObj.u_textureLod1f, lvl);
|
||||
}else {
|
||||
if(lvl != 0.0f) {
|
||||
LOGGER.error("Tried to copy from mipmap level {}, but this GPU does not support textureLod!", lvl);
|
||||
}
|
||||
_wglUniform1f(shaderObj.u_textureLod1f, 0.0f);
|
||||
}
|
||||
if(isAligned) {
|
||||
_wglUniform4f(shaderObj.u_pixelAlignmentSizes4f, alignW, alignH, 1.0f / alignW, 1.0f / alignH);
|
||||
_wglUniform2f(shaderObj.u_pixelAlignmentOffset2f, alignOffsetX, alignOffsetY);
|
||||
@ -271,7 +301,14 @@ public class TextureCopyUtil {
|
||||
GlStateManager.viewport(dstX, dstY, dstW, dstH);
|
||||
_wglUniform4f(shaderObj.u_srcCoords4f, (float)srcX / srcViewW, (float)srcY / srcViewH, (float)srcW / srcViewW, (float)srcH / srcViewH);
|
||||
_wglUniform4f(shaderObj.u_dstCoords4f, -1.0f, -1.0f, 2.0f, 2.0f);
|
||||
_wglUniform1f(shaderObj.u_textureLod1f, lvl);
|
||||
if(EaglercraftGPU.checkTextureLODCapable()) {
|
||||
_wglUniform1f(shaderObj.u_textureLod1f, lvl);
|
||||
}else {
|
||||
if(lvl != 0.0f) {
|
||||
LOGGER.error("Tried to copy from mipmap level {}, but this GPU does not support textureLod!", lvl);
|
||||
}
|
||||
_wglUniform1f(shaderObj.u_textureLod1f, 0.0f);
|
||||
}
|
||||
if(isAligned) {
|
||||
_wglUniform4f(shaderObj.u_pixelAlignmentSizes4f, alignW, alignH, 1.0f / alignW, 1.0f / alignH);
|
||||
_wglUniform2f(shaderObj.u_pixelAlignmentOffset2f, alignOffsetX, alignOffsetY);
|
||||
@ -298,7 +335,14 @@ public class TextureCopyUtil {
|
||||
_wglUniform4f(shaderObj.u_srcCoords4f, (float)srcX / srcViewW, (float)srcY / srcViewH, (float)srcW / srcViewW, (float)srcH / srcViewH);
|
||||
_wglUniform4f(shaderObj.u_dstCoords4f, (float) dstX / dstViewW - 1.0f, (float) dstY / dstViewH - 1.0f,
|
||||
(float) dstW / dstViewW, (float) dstH / dstViewH);
|
||||
_wglUniform1f(shaderObj.u_textureLod1f, lvl);
|
||||
if(EaglercraftGPU.checkTextureLODCapable()) {
|
||||
_wglUniform1f(shaderObj.u_textureLod1f, lvl);
|
||||
}else {
|
||||
if(lvl != 0.0f) {
|
||||
LOGGER.error("Tried to copy from mipmap level {}, but this GPU does not support textureLod!", lvl);
|
||||
}
|
||||
_wglUniform1f(shaderObj.u_textureLod1f, 0.0f);
|
||||
}
|
||||
if(isAligned) {
|
||||
_wglUniform4f(shaderObj.u_pixelAlignmentSizes4f, alignW, alignH, 1.0f / alignW, 1.0f / alignH);
|
||||
_wglUniform2f(shaderObj.u_pixelAlignmentOffset2f, alignOffsetX, alignOffsetY);
|
||||
@ -316,7 +360,14 @@ public class TextureCopyUtil {
|
||||
EaglercraftGPU.bindGLShaderProgram(shaderObj.shaderProgram);
|
||||
_wglUniform4f(shaderObj.u_srcCoords4f, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||
_wglUniform4f(shaderObj.u_dstCoords4f, -1.0f, -1.0f, 2.0f, 2.0f);
|
||||
_wglUniform1f(shaderObj.u_textureLod1f, lvl);
|
||||
if(EaglercraftGPU.checkTextureLODCapable()) {
|
||||
_wglUniform1f(shaderObj.u_textureLod1f, lvl);
|
||||
}else {
|
||||
if(lvl != 0.0f) {
|
||||
LOGGER.error("Tried to copy from mipmap level {}, but this GPU does not support textureLod!", lvl);
|
||||
}
|
||||
_wglUniform1f(shaderObj.u_textureLod1f, 0.0f);
|
||||
}
|
||||
if(isAligned) {
|
||||
_wglUniform4f(shaderObj.u_pixelAlignmentSizes4f, alignW, alignH, 1.0f / alignW, 1.0f / alignH);
|
||||
_wglUniform2f(shaderObj.u_pixelAlignmentOffset2f, alignOffsetX, alignOffsetY);
|
||||
@ -343,7 +394,14 @@ public class TextureCopyUtil {
|
||||
GlStateManager.viewport(dstX, dstY, dstW, dstH);
|
||||
_wglUniform4f(shaderObj.u_srcCoords4f, (float)srcX / srcViewW, (float)srcY / srcViewH, (float)srcW / srcViewW, (float)srcH / srcViewH);
|
||||
_wglUniform4f(shaderObj.u_dstCoords4f, -1.0f, -1.0f, 2.0f, 2.0f);
|
||||
_wglUniform1f(shaderObj.u_textureLod1f, lvl);
|
||||
if(EaglercraftGPU.checkTextureLODCapable()) {
|
||||
_wglUniform1f(shaderObj.u_textureLod1f, lvl);
|
||||
}else {
|
||||
if(lvl != 0.0f) {
|
||||
LOGGER.error("Tried to copy from mipmap level {}, but this GPU does not support textureLod!", lvl);
|
||||
}
|
||||
_wglUniform1f(shaderObj.u_textureLod1f, 0.0f);
|
||||
}
|
||||
if(isAligned) {
|
||||
_wglUniform4f(shaderObj.u_pixelAlignmentSizes4f, alignW, alignH, 1.0f / alignW, 1.0f / alignH);
|
||||
_wglUniform2f(shaderObj.u_pixelAlignmentOffset2f, alignOffsetX, alignOffsetY);
|
||||
@ -351,4 +409,27 @@ public class TextureCopyUtil {
|
||||
}
|
||||
DrawUtils.drawStandardQuad2D();
|
||||
}
|
||||
|
||||
public static void destroy() {
|
||||
if(vshShader != null) {
|
||||
_wglDeleteShader(vshShader);
|
||||
vshShader = null;
|
||||
}
|
||||
if(textureBlit != null) {
|
||||
textureBlit.destroy();
|
||||
textureBlit = null;
|
||||
}
|
||||
if(textureBlitAligned != null) {
|
||||
textureBlitAligned.destroy();
|
||||
textureBlitAligned = null;
|
||||
}
|
||||
if(textureBlitDepth != null) {
|
||||
textureBlitDepth.destroy();
|
||||
textureBlitDepth = null;
|
||||
}
|
||||
if(textureBlitDepthAligned != null) {
|
||||
textureBlitDepthAligned.destroy();
|
||||
textureBlitDepthAligned = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,81 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.opengl;
|
||||
|
||||
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
|
||||
import static net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.ExtGLEnums.*;
|
||||
|
||||
/**
|
||||
* 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 TextureFormatHelper {
|
||||
|
||||
public static int getFormatFromInternal(int internalFormat) {
|
||||
switch(internalFormat) {
|
||||
case _GL_R8:
|
||||
case 0x822D: // GL_R16F
|
||||
case 0x822E: // GL_R32F
|
||||
return GL_RED;
|
||||
case _GL_RG8:
|
||||
case 0x822F: // GL_RG16F
|
||||
case 0x8230: // GL_RG32F
|
||||
return _GL_RG;
|
||||
case GL_RGB8:
|
||||
case _GL_RGB16F:
|
||||
case 0x8815: // GL_RGB32F
|
||||
return GL_RGB;
|
||||
case GL_RGBA8:
|
||||
case 0x881A: // GL_RGBA16F
|
||||
case 0x8814: // GL_RGBA32F
|
||||
return GL_RGBA;
|
||||
default:
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
public static int getTypeFromInternal(int internalFormat) {
|
||||
switch(internalFormat) {
|
||||
case _GL_R8:
|
||||
case _GL_RG8:
|
||||
case GL_RGB8:
|
||||
case GL_RGBA8:
|
||||
return GL_UNSIGNED_BYTE;
|
||||
case 0x822D: // GL_R16F
|
||||
case 0x822F: // GL_RG16F
|
||||
case _GL_RGB16F:
|
||||
case 0x881A: // GL_RGBA16F
|
||||
return _GL_HALF_FLOAT;
|
||||
case 0x822E: // GL_R32F
|
||||
case 0x8230: // GL_RG32F
|
||||
case 0x8815: // GL_RGB32F
|
||||
case 0x8814: // GL_RGBA32F
|
||||
return GL_FLOAT;
|
||||
default:
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
public static int trivializeInternalFormatToGLES20(int internalFormat) {
|
||||
switch(internalFormat) {
|
||||
case _GL_R8:
|
||||
return GL_LUMINANCE;
|
||||
case GL_RGB8:
|
||||
return GL_RGB;
|
||||
case GL_RGBA8:
|
||||
return GL_RGBA;
|
||||
default:
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.opengl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EagUtils;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IProgramGL;
|
||||
|
||||
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
|
||||
|
||||
/**
|
||||
* 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 VSHInputLayoutParser {
|
||||
|
||||
public static class ShaderInput {
|
||||
|
||||
public final int index;
|
||||
public final String type;
|
||||
public final String name;
|
||||
|
||||
public ShaderInput(int index, String type, String name) {
|
||||
this.index = index;
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class ShaderLayoutParseException extends RuntimeException {
|
||||
|
||||
public ShaderLayoutParseException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ShaderLayoutParseException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static List<ShaderInput> getShaderInputs(String vshSource) {
|
||||
int idx1 = vshSource.indexOf("EAGLER_VSH_LAYOUT_BEGIN()");
|
||||
if(idx1 == -1) {
|
||||
throw new ShaderLayoutParseException("Could not find \"EAGLER_VSH_LAYOUT_BEGIN()\" delimiter!");
|
||||
}
|
||||
int idx2 = vshSource.indexOf("EAGLER_VSH_LAYOUT_END()", idx1 + 25);
|
||||
if(idx2 == -1) {
|
||||
throw new ShaderLayoutParseException("Could not find \"EAGLER_VSH_LAYOUT_END()\" delimiter!");
|
||||
}
|
||||
List<String> lines = EagUtils.linesList(vshSource.substring(idx1 + 25, idx2));
|
||||
List<ShaderInput> ret = new ArrayList<>();
|
||||
for(int i = 0, l = lines.size(); i < l; ++i) {
|
||||
String ln = lines.get(i);
|
||||
ln = ln.trim();
|
||||
if(ln.startsWith("EAGLER_IN(") && ln.endsWith(")")) {
|
||||
String[] tokens = ln.substring(10, ln.length() - 1).split(",", 3);
|
||||
if(tokens.length == 3) {
|
||||
int idx;
|
||||
try {
|
||||
idx = Integer.parseInt(tokens[0].trim());
|
||||
}catch(NumberFormatException ex) {
|
||||
continue;
|
||||
}
|
||||
ret.add(new ShaderInput(idx, tokens[1].trim(), tokens[2].trim()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void applyLayout(IProgramGL program, List<ShaderInput> layout) {
|
||||
for(int i = 0, l = layout.size(); i < l; ++i) {
|
||||
ShaderInput itm = layout.get(i);
|
||||
_wglBindAttribLocation(program, itm.index, itm.name);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -8,7 +8,6 @@ import java.util.BitSet;
|
||||
import java.util.Comparator;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformBufferFunctions;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.vector.Vector3f;
|
||||
import net.minecraft.client.renderer.GLAllocation;
|
||||
@ -121,7 +120,7 @@ public class WorldRenderer {
|
||||
for (int k1 = ainteger[i1].intValue(); j1 != l1; k1 = ainteger[k1].intValue()) {
|
||||
this.intBuffer.limit(k1 * l + l);
|
||||
this.intBuffer.position(k1 * l);
|
||||
IntBuffer intbuffer = this.intBuffer.slice();
|
||||
IntBuffer intbuffer = this.intBuffer.duplicate();
|
||||
this.intBuffer.limit(j1 * l + l);
|
||||
this.intBuffer.position(j1 * l);
|
||||
this.intBuffer.put(intbuffer);
|
||||
@ -178,7 +177,10 @@ public class WorldRenderer {
|
||||
*/
|
||||
public void setVertexState(WorldRenderer.State state) {
|
||||
this.grow(state.getRawBuffer().length);
|
||||
PlatformBufferFunctions.put(this.intBuffer, 0, state.getRawBuffer());
|
||||
int p = intBuffer.position();
|
||||
this.intBuffer.position(0);
|
||||
this.intBuffer.put(state.getRawBuffer());
|
||||
this.intBuffer.position(p);
|
||||
this.vertexCount = state.getVertexCount();
|
||||
this.vertexFormat = state.getVertexFormat();
|
||||
}
|
||||
@ -339,7 +341,10 @@ public class WorldRenderer {
|
||||
*/
|
||||
public void addVertexData(int[] vertexData) {
|
||||
this.grow(vertexData.length);
|
||||
PlatformBufferFunctions.put(this.intBuffer, (this.vertexCount * this.vertexFormat.attribStride) >> 2, vertexData);
|
||||
int p = this.intBuffer.position();
|
||||
this.intBuffer.position((this.vertexCount * this.vertexFormat.attribStride) >> 2);
|
||||
this.intBuffer.put(vertexData);
|
||||
this.intBuffer.position(p);
|
||||
this.vertexCount += vertexData.length / (this.vertexFormat.attribStride >> 2);
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ public class BlockVertexIDs implements IResourceManagerReloadListener {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger("BlockVertexIDsCSV");
|
||||
|
||||
public static final Map<String,Integer> modelToID = new HashMap();
|
||||
public static final Map<String,Integer> modelToID = new HashMap<>();
|
||||
|
||||
public static int builtin_water_still_vertex_id = 0;
|
||||
public static int builtin_water_flow_vertex_id = 0;
|
||||
|
@ -103,7 +103,7 @@ public class CloudRenderWorker {
|
||||
static void initialize() {
|
||||
destroy();
|
||||
|
||||
cloudStartTimer = System.currentTimeMillis();
|
||||
cloudStartTimer = EagRuntime.steadyTimeMillis();
|
||||
cloudRenderProgress = 0;
|
||||
cloudRenderPeriod = 500;
|
||||
cloudRenderPhase = 0;
|
||||
@ -168,7 +168,7 @@ public class CloudRenderWorker {
|
||||
_wglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
_wglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
_wglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
byte[] cloudShapeTexture = EagRuntime.getResourceBytes("/assets/eagler/glsl/deferred/clouds_shapes.bmp");
|
||||
byte[] cloudShapeTexture = EagRuntime.getRequiredResourceBytes("/assets/eagler/glsl/deferred/clouds_shapes.bmp");
|
||||
cloudNoiseDatBuffer = EagRuntime.allocateByteBuffer(cloudShapeTexture.length);
|
||||
cloudNoiseDatBuffer.put(cloudShapeTexture);
|
||||
cloudNoiseDatBuffer.flip();
|
||||
@ -207,7 +207,7 @@ public class CloudRenderWorker {
|
||||
}
|
||||
|
||||
static void update() {
|
||||
long millis = System.currentTimeMillis();
|
||||
long millis = EagRuntime.steadyTimeMillis();
|
||||
int cloudProgress = (int)(millis - cloudStartTimer);
|
||||
int totalCloudSteps = 32 + 32 - 1;
|
||||
int currentCloudStep = cloudProgress * totalCloudSteps / cloudRenderPeriod;
|
||||
@ -268,7 +268,7 @@ public class CloudRenderWorker {
|
||||
cloudColorB += (currentSunAngle.z - cloudColorB) * 0.1f;
|
||||
_wglUniform3f(shader_clouds_sample.uniforms.u_sunColor3f, cloudColorR, cloudColorG, cloudColorB);
|
||||
|
||||
float cloudDensityTimer = (float)((System.currentTimeMillis() % 10000000l) * 0.001);
|
||||
float cloudDensityTimer = (float)((EagRuntime.steadyTimeMillis() % 10000000l) * 0.001);
|
||||
cloudDensityTimer += MathHelper.sin(cloudDensityTimer * 1.5f) * 1.5f;
|
||||
float x = cloudDensityTimer * 0.004f;
|
||||
float f1 = MathHelper.sin(x + 0.322f) * 0.544f + MathHelper.sin(x * 4.5f + 1.843f) * 0.69f + MathHelper.sin(x * 3.4f + 0.8f) * 0.6f + MathHelper.sin(x * 6.1f + 1.72f) * 0.7f;
|
||||
@ -404,7 +404,7 @@ public class CloudRenderWorker {
|
||||
|
||||
if(b) {
|
||||
cloudRenderProgress = 0;
|
||||
cloudStartTimer = System.currentTimeMillis();
|
||||
cloudStartTimer = EagRuntime.steadyTimeMillis();
|
||||
cloudProgress = 0;
|
||||
cloudRenderPhase = (cloudRenderPhase + 1) % 3;
|
||||
}else {
|
||||
@ -539,7 +539,7 @@ public class CloudRenderWorker {
|
||||
}
|
||||
|
||||
private static void updateShape() {
|
||||
long millis = System.currentTimeMillis();
|
||||
long millis = EagRuntime.steadyTimeMillis();
|
||||
float dt = (float)((millis - shapeUpdateTimer) * 0.001);
|
||||
shapeUpdateTimer = millis;
|
||||
if(millis > nextShapeAppearance) {
|
||||
|
@ -4,12 +4,12 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.DrawUtils;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.program.PipelineShaderGBufferDebugView;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Gui;
|
||||
import net.minecraft.client.gui.ScaledResolution;
|
||||
|
||||
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
|
||||
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
|
||||
@ -249,7 +249,7 @@ public class DebugFramebufferView {
|
||||
PipelineShaderGBufferDebugView dbg = pipeline.useDebugViewShader(18);
|
||||
GlStateManager.setActiveTexture(GL_TEXTURE0);
|
||||
GlStateManager.bindTexture3D(CloudRenderWorker.cloud3DSamplesTexture);
|
||||
_wglUniform1f(_wglGetUniformLocation(dbg.program, "u_fuckU1f"), (float)((System.currentTimeMillis() % 5000l) / 5000.0));
|
||||
_wglUniform1f(_wglGetUniformLocation(dbg.program, "u_fuckU1f"), (float)((EagRuntime.steadyTimeMillis() % 5000l) / 5000.0));
|
||||
DrawUtils.drawStandardQuad2D();
|
||||
})),
|
||||
(new DebugFramebufferView("Clouds Back Buffer", (pipeline) -> {
|
||||
@ -449,19 +449,18 @@ public class DebugFramebufferView {
|
||||
GlStateManager.clear(GL_COLOR_BUFFER_BIT);
|
||||
noData = true;
|
||||
}
|
||||
long millis = System.currentTimeMillis();
|
||||
long millis = EagRuntime.steadyTimeMillis();
|
||||
long elapsed = millis - debugViewNameTimer;
|
||||
if(elapsed < 2000l || noData) {
|
||||
GlStateManager.matrixMode(GL_PROJECTION);
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.matrixMode(GL_MODELVIEW);
|
||||
GlStateManager.pushMatrix();
|
||||
ScaledResolution scaledresolution = new ScaledResolution(mc);
|
||||
int w = scaledresolution.getScaledWidth();
|
||||
int w = mc.scaledResolution.getScaledWidth();
|
||||
mc.entityRenderer.setupOverlayRendering();
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
int h = scaledresolution.getScaledHeight() / 2;
|
||||
int h = mc.scaledResolution.getScaledHeight() / 2;
|
||||
|
||||
if(noData) {
|
||||
String noDataTxt = "No Data";
|
||||
@ -507,13 +506,13 @@ public class DebugFramebufferView {
|
||||
public static void toggleDebugView() {
|
||||
debugViewShown = !debugViewShown;
|
||||
if(debugViewShown) {
|
||||
debugViewNameTimer = System.currentTimeMillis();
|
||||
debugViewNameTimer = EagRuntime.steadyTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
public static void switchView(int dir) {
|
||||
if(!debugViewShown) return;
|
||||
debugViewNameTimer = System.currentTimeMillis();
|
||||
debugViewNameTimer = EagRuntime.steadyTimeMillis();
|
||||
currentDebugView += dir;
|
||||
if(currentDebugView < 0) currentDebugView = views.size() - 1;
|
||||
if(currentDebugView >= views.size()) currentDebugView = 0;
|
||||
|
@ -148,7 +148,7 @@ public class DeferredStateManager {
|
||||
if(!cfg.is_rendering_dynamicLights || !cfg.shaderPackInfo.DYNAMIC_LIGHTS) {
|
||||
return;
|
||||
}
|
||||
instance.loadLightSourceBucket(centerX, centerY, centerZ);
|
||||
instance.bindLightSourceBucket(centerX, centerY, centerZ, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,7 +162,7 @@ public class DeferredStateManager {
|
||||
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);
|
||||
instance.bindLightSourceBucket((int)posX, (int)posY, (int)posZ, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2023 lax1dude. All Rights Reserved.
|
||||
*
|
||||
@ -35,7 +37,7 @@ class DynamicLightInstance {
|
||||
}
|
||||
|
||||
public void updateLight(double posX, double posY, double posZ, float red, float green, float blue) {
|
||||
this.lastCacheHit = System.currentTimeMillis();
|
||||
this.lastCacheHit = EagRuntime.steadyTimeMillis();
|
||||
this.posX = posX;
|
||||
this.posY = posY;
|
||||
this.posZ = posZ;
|
||||
|
@ -6,6 +6,8 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2023 lax1dude. All Rights Reserved.
|
||||
*
|
||||
@ -23,8 +25,8 @@ import java.util.Map;
|
||||
*/
|
||||
public class DynamicLightManager {
|
||||
|
||||
static final Map<String, DynamicLightInstance> lightRenderers = new HashMap();
|
||||
static final List<DynamicLightInstance> lightRenderList = new LinkedList();
|
||||
static final Map<String, DynamicLightInstance> lightRenderers = new HashMap<>();
|
||||
static final List<DynamicLightInstance> lightRenderList = new LinkedList<>();
|
||||
static long renderTimeout = 5000l;
|
||||
static boolean isRenderLightsPass = false;
|
||||
|
||||
@ -51,7 +53,7 @@ public class DynamicLightManager {
|
||||
}
|
||||
|
||||
static void updateTimers() {
|
||||
long millis = System.currentTimeMillis();
|
||||
long millis = EagRuntime.steadyTimeMillis();
|
||||
if(millis - lastTick > 1000l) {
|
||||
lastTick = millis;
|
||||
Iterator<DynamicLightInstance> itr = lightRenderers.values().iterator();
|
||||
|
@ -71,7 +71,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2023 lax1dude. All Rights Reserved.
|
||||
* 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
|
||||
@ -112,6 +112,7 @@ public class EaglerDeferredPipeline {
|
||||
public double currentRenderX = 0.0;
|
||||
public double currentRenderY = 0.0;
|
||||
public double currentRenderZ = 0.0;
|
||||
public int currentRenderPosSerial = 0;
|
||||
|
||||
public IFramebufferGL gBufferFramebuffer = null;
|
||||
|
||||
@ -307,6 +308,7 @@ public class EaglerDeferredPipeline {
|
||||
private ByteBuffer worldLightingDataCopyBuffer;
|
||||
|
||||
public IBufferGL buffer_chunkLightingData;
|
||||
public IBufferGL buffer_chunkLightingDataZero;
|
||||
private ByteBuffer chunkLightingDataCopyBuffer;
|
||||
private boolean isChunkLightingEnabled = false;
|
||||
public ListSerial<DynamicLightInstance> currentBoundLightSourceBucket;
|
||||
@ -336,9 +338,20 @@ public class EaglerDeferredPipeline {
|
||||
public static final Vector3f tmpVector4 = new Vector3f();
|
||||
|
||||
public final ListSerial<DynamicLightInstance>[] lightSourceBuckets;
|
||||
private final int[] lightSourceBucketSerials;
|
||||
private final int[] lightSourceRenderPosSerials;
|
||||
public ListSerial<DynamicLightInstance> currentLightSourceBucket;
|
||||
private int currentLightSourceBucketId = -1;
|
||||
private int lightingBufferSliceLength = -1;
|
||||
|
||||
public static final int MAX_LIGHTS_PER_CHUNK = 12;
|
||||
public static final int LIGHTING_BUFFER_LENGTH = 32 * MAX_LIGHTS_PER_CHUNK + 16;
|
||||
|
||||
private int uniformBufferOffsetAlignment = -1;
|
||||
|
||||
private int uboAlign(int offset) {
|
||||
return MathHelper.ceiling_float_int((float)offset / (float)uniformBufferOffsetAlignment) * uniformBufferOffsetAlignment;
|
||||
}
|
||||
|
||||
private final int lightSourceBucketsWidth;
|
||||
private final int lightSourceBucketsHeight;
|
||||
@ -372,13 +385,18 @@ public class EaglerDeferredPipeline {
|
||||
this.lightSourceBucketsHeight = 3;
|
||||
int cnt = 5 * 3 * 5;
|
||||
this.lightSourceBuckets = new ListSerial[cnt];
|
||||
this.lightSourceBucketSerials = new int[cnt];
|
||||
this.lightSourceRenderPosSerials = new int[cnt];
|
||||
for(int i = 0; i < cnt; ++i) {
|
||||
this.lightSourceBuckets[i] = new ArrayListSerial(16);
|
||||
this.lightSourceBuckets[i] = new ArrayListSerial<>(16);
|
||||
this.lightSourceBucketSerials[i] = -1;
|
||||
this.lightSourceRenderPosSerials[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
public void rebuild(EaglerDeferredConfig config) {
|
||||
destroy();
|
||||
uniformBufferOffsetAlignment = EaglercraftGPU.getUniformBufferOffsetAlignment();
|
||||
DeferredStateManager.doCheckErrors = EagRuntime.getConfiguration().isCheckShaderGLErrors();
|
||||
DeferredStateManager.checkGLError("Pre: rebuild pipeline");
|
||||
this.config = config;
|
||||
@ -544,7 +562,7 @@ public class EaglerDeferredPipeline {
|
||||
GlStateManager.bindTexture(ssaoNoiseTexture);
|
||||
setNearest();
|
||||
int noiseTexSize = 64, noiseTexLen = 16384;
|
||||
byte[] noiseTexDat = EagRuntime.getResourceBytes("assets/eagler/glsl/deferred/ssao_noise.bmp");
|
||||
byte[] noiseTexDat = EagRuntime.getRequiredResourceBytes("assets/eagler/glsl/deferred/ssao_noise.bmp");
|
||||
if(noiseTexDat == null || noiseTexDat.length != noiseTexLen) {
|
||||
noiseTexDat = new byte[noiseTexLen];
|
||||
for(int i = 0; i < 4096; ++i) {
|
||||
@ -592,7 +610,7 @@ public class EaglerDeferredPipeline {
|
||||
GlStateManager.bindTexture(brdfTexture);
|
||||
setLinear();
|
||||
int brdfLutW = 64, brdfLutH = 64, brdfLutLen = 8192;
|
||||
byte[] brdfLutDat = EagRuntime.getResourceBytes("assets/eagler/glsl/deferred/brdf_lut.bmp");
|
||||
byte[] brdfLutDat = EagRuntime.getRequiredResourceBytes("assets/eagler/glsl/deferred/brdf_lut.bmp");
|
||||
if(brdfLutDat == null || brdfLutDat.length != brdfLutLen) {
|
||||
brdfLutDat = new byte[brdfLutLen];
|
||||
for(int i = 0; i < 4096; ++i) {
|
||||
@ -748,7 +766,9 @@ public class EaglerDeferredPipeline {
|
||||
_wglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
ByteBuffer copyBuffer = EagRuntime.allocateByteBuffer(262144);
|
||||
int mip = 0;
|
||||
try(DataInputStream dis = new DataInputStream(EagRuntime.getResourceStream("/assets/eagler/glsl/deferred/eagler_moon.bmp"))) {
|
||||
|
||||
try (DataInputStream dis = new DataInputStream(mc.getResourceManager()
|
||||
.getResource(new ResourceLocation("eagler:glsl/deferred/eagler_moon.bmp")).getInputStream())) {
|
||||
while(dis.read() == 'E') {
|
||||
int w = dis.readShort();
|
||||
int h = dis.readShort();
|
||||
@ -873,7 +893,7 @@ public class EaglerDeferredPipeline {
|
||||
_wglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
_wglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
String realistic_water_noise_filename = "assets/eagler/glsl/deferred/realistic_water_noise.bmp";
|
||||
byte[] bitmapBytes = EagRuntime.getResourceBytes(realistic_water_noise_filename);
|
||||
byte[] bitmapBytes = EagRuntime.getRequiredResourceBytes(realistic_water_noise_filename);
|
||||
try {
|
||||
if(bitmapBytes.length != 32768) {
|
||||
throw new IOException("File is length " + bitmapBytes.length + ", expected " + 32768);
|
||||
@ -1008,15 +1028,22 @@ public class EaglerDeferredPipeline {
|
||||
shader_lighting_point = PipelineShaderLightingPoint.compile(false);
|
||||
shader_lighting_point.loadUniforms();
|
||||
|
||||
buffer_chunkLightingData = _wglGenBuffers();
|
||||
EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingData);
|
||||
int lightingDataLength = 8 * MAX_LIGHTS_PER_CHUNK + 4;
|
||||
chunkLightingDataCopyBuffer = EagRuntime.allocateByteBuffer(lightingDataLength << 2);
|
||||
for(int i = 0; i < lightingDataLength; ++i) {
|
||||
lightingBufferSliceLength = uboAlign(LIGHTING_BUFFER_LENGTH);
|
||||
|
||||
chunkLightingDataCopyBuffer = EagRuntime.allocateByteBuffer(LIGHTING_BUFFER_LENGTH);
|
||||
for(int i = 0; i < LIGHTING_BUFFER_LENGTH; i += 4) {
|
||||
chunkLightingDataCopyBuffer.putInt(0);
|
||||
}
|
||||
chunkLightingDataCopyBuffer.flip();
|
||||
_wglBufferData(_GL_UNIFORM_BUFFER, chunkLightingDataCopyBuffer, GL_DYNAMIC_DRAW);
|
||||
|
||||
buffer_chunkLightingData = _wglGenBuffers();
|
||||
EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingData);
|
||||
int cnt = lightSourceBucketsWidth * lightSourceBucketsHeight * lightSourceBucketsWidth;
|
||||
_wglBufferData(_GL_UNIFORM_BUFFER, cnt * lightingBufferSliceLength, GL_DYNAMIC_DRAW);
|
||||
|
||||
buffer_chunkLightingDataZero = _wglGenBuffers();
|
||||
EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingDataZero);
|
||||
_wglBufferData(_GL_UNIFORM_BUFFER, chunkLightingDataCopyBuffer, GL_STATIC_DRAW);
|
||||
|
||||
DeferredStateManager.checkGLError("Post: rebuild pipeline: dynamic lights");
|
||||
}
|
||||
@ -1042,6 +1069,16 @@ public class EaglerDeferredPipeline {
|
||||
DeferredStateManager.checkGLError("Post: rebuild pipeline");
|
||||
}
|
||||
|
||||
public void setRenderPosGlobal(double renderPosX, double renderPosY, double renderPosZ) {
|
||||
if (renderPosX != currentRenderX || renderPosY != currentRenderY || renderPosZ != currentRenderZ
|
||||
|| currentRenderPosSerial == 0) {
|
||||
currentRenderX = renderPosX;
|
||||
currentRenderY = renderPosY;
|
||||
currentRenderZ = renderPosZ;
|
||||
++currentRenderPosSerial;
|
||||
}
|
||||
}
|
||||
|
||||
public void updateReprojectionCoordinates(double worldX, double worldY, double worldZ) {
|
||||
double distX = worldX - reprojectionOriginCoordinateX;
|
||||
double distY = worldY - reprojectionOriginCoordinateY;
|
||||
@ -1467,7 +1504,7 @@ public class EaglerDeferredPipeline {
|
||||
float sunKelvin = 1500.0f + (2500.0f * Math.max(-currentSunAngle.y, 0.0f));
|
||||
float fff = mc.theWorld.getRainStrength(partialTicks);
|
||||
float ff2 = mc.theWorld.getThunderStrength(partialTicks);
|
||||
long millis = System.currentTimeMillis();
|
||||
long millis = EagRuntime.steadyTimeMillis();
|
||||
int dim = Minecraft.getMinecraft().theWorld.provider.getDimensionId();
|
||||
|
||||
// ==================== UPDATE CLOUD RENDERER ===================== //
|
||||
@ -2172,7 +2209,7 @@ public class EaglerDeferredPipeline {
|
||||
GlStateManager.disableBlend();
|
||||
}
|
||||
|
||||
public void loadLightSourceBucket(int relativeBlockX, int relativeBlockY, int relativeBlockZ) {
|
||||
public void bindLightSourceBucket(int relativeBlockX, int relativeBlockY, int relativeBlockZ, int uboIndex) {
|
||||
int hw = lightSourceBucketsWidth / 2;
|
||||
int hh = lightSourceBucketsHeight / 2;
|
||||
int bucketX = (relativeBlockX >> 4) + hw;
|
||||
@ -2180,12 +2217,51 @@ public class EaglerDeferredPipeline {
|
||||
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];
|
||||
currentLightSourceBucketId = bucketY * lightSourceBucketsWidth * lightSourceBucketsWidth
|
||||
+ bucketZ * lightSourceBucketsWidth + bucketX;
|
||||
currentLightSourceBucket = lightSourceBuckets[currentLightSourceBucketId];
|
||||
int ser = currentLightSourceBucket.getEaglerSerial();
|
||||
int max = currentLightSourceBucket.size();
|
||||
if(max > 0) {
|
||||
EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingData);
|
||||
int offset = currentLightSourceBucketId * lightingBufferSliceLength;
|
||||
if (lightSourceBucketSerials[currentLightSourceBucketId] != ser
|
||||
|| lightSourceRenderPosSerials[currentLightSourceBucketId] != currentRenderPosSerial) {
|
||||
lightSourceBucketSerials[currentLightSourceBucketId] = ser;
|
||||
lightSourceRenderPosSerials[currentLightSourceBucketId] = currentRenderPosSerial;
|
||||
if(max > MAX_LIGHTS_PER_CHUNK) {
|
||||
max = MAX_LIGHTS_PER_CHUNK;
|
||||
}
|
||||
chunkLightingDataCopyBuffer.clear();
|
||||
chunkLightingDataCopyBuffer.putInt(max);
|
||||
chunkLightingDataCopyBuffer.putInt(0); //padding
|
||||
chunkLightingDataCopyBuffer.putInt(0); //padding
|
||||
chunkLightingDataCopyBuffer.putInt(0); //padding
|
||||
for(int i = 0; i < max; ++i) {
|
||||
DynamicLightInstance dl = currentLightSourceBucket.get(i);
|
||||
chunkLightingDataCopyBuffer.putFloat((float)(dl.posX - currentRenderX));
|
||||
chunkLightingDataCopyBuffer.putFloat((float)(dl.posY - currentRenderY));
|
||||
chunkLightingDataCopyBuffer.putFloat((float)(dl.posZ - currentRenderZ));
|
||||
chunkLightingDataCopyBuffer.putInt(0); //padding
|
||||
chunkLightingDataCopyBuffer.putFloat(dl.red);
|
||||
chunkLightingDataCopyBuffer.putFloat(dl.green);
|
||||
chunkLightingDataCopyBuffer.putFloat(dl.blue);
|
||||
chunkLightingDataCopyBuffer.putInt(0); //padding
|
||||
}
|
||||
chunkLightingDataCopyBuffer.flip();
|
||||
_wglBufferSubData(_GL_UNIFORM_BUFFER, offset, chunkLightingDataCopyBuffer);
|
||||
}
|
||||
EaglercraftGPU.bindUniformBufferRange(uboIndex, buffer_chunkLightingData, offset, LIGHTING_BUFFER_LENGTH);
|
||||
}else {
|
||||
EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingDataZero);
|
||||
EaglercraftGPU.bindUniformBufferRange(uboIndex, buffer_chunkLightingDataZero, 0, LIGHTING_BUFFER_LENGTH);
|
||||
}
|
||||
}else {
|
||||
currentLightSourceBucketId = -1;
|
||||
currentLightSourceBucket = null;
|
||||
EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingDataZero);
|
||||
EaglercraftGPU.bindUniformBufferRange(uboIndex, buffer_chunkLightingDataZero, 0, LIGHTING_BUFFER_LENGTH);
|
||||
}
|
||||
updateLightSourceUBO();
|
||||
}
|
||||
|
||||
public ListSerial<DynamicLightInstance> getLightSourceBucketRelativeChunkCoords(int cx, int cy, int cz) {
|
||||
@ -2319,65 +2395,10 @@ public class EaglerDeferredPipeline {
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
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.putInt(0); //padding
|
||||
chunkLightingDataCopyBuffer.putFloat(dl.red);
|
||||
chunkLightingDataCopyBuffer.putFloat(dl.green);
|
||||
chunkLightingDataCopyBuffer.putFloat(dl.blue);
|
||||
chunkLightingDataCopyBuffer.putInt(0); //padding
|
||||
}
|
||||
}
|
||||
chunkLightingDataCopyBuffer.flip();
|
||||
EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingData);
|
||||
_wglBufferSubData(_GL_UNIFORM_BUFFER, 0, chunkLightingDataCopyBuffer);
|
||||
}
|
||||
|
||||
public void beginDrawEnvMap() {
|
||||
DeferredStateManager.checkGLError("Pre: beginDrawEnvMap()");
|
||||
GlStateManager.enableDepth();
|
||||
@ -2797,7 +2818,7 @@ public class EaglerDeferredPipeline {
|
||||
GlStateManager.bindTexture(realisticWaterNoiseMap);
|
||||
|
||||
shader_realistic_water_noise.useProgram();
|
||||
float waveTimer = (float)((System.currentTimeMillis() % 600000l) * 0.001);
|
||||
float waveTimer = (float)((EagRuntime.steadyTimeMillis() % 600000l) * 0.001);
|
||||
_wglUniform4f(shader_realistic_water_noise.uniforms.u_waveTimer4f, waveTimer, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
DrawUtils.drawStandardQuad2D();
|
||||
@ -3147,7 +3168,7 @@ public class EaglerDeferredPipeline {
|
||||
|
||||
// ================ DOWNSCALE AND AVERAGE LUMA =============== //
|
||||
|
||||
long millis = System.currentTimeMillis();
|
||||
long millis = EagRuntime.steadyTimeMillis();
|
||||
if(millis - lastExposureUpdate > 33l) {
|
||||
if(lumaAvgDownscaleFramebuffers.length == 0) {
|
||||
_wglBindFramebuffer(_GL_FRAMEBUFFER, exposureBlendFramebuffer);
|
||||
@ -3925,6 +3946,10 @@ public class EaglerDeferredPipeline {
|
||||
_wglDeleteBuffers(buffer_chunkLightingData);
|
||||
buffer_chunkLightingData = null;
|
||||
}
|
||||
if(buffer_chunkLightingDataZero != null) {
|
||||
_wglDeleteBuffers(buffer_chunkLightingDataZero);
|
||||
buffer_chunkLightingDataZero = null;
|
||||
}
|
||||
if(buffer_worldLightingData != null) {
|
||||
_wglDeleteBuffers(buffer_worldLightingData);
|
||||
buffer_worldLightingData = null;
|
||||
@ -3939,8 +3964,11 @@ public class EaglerDeferredPipeline {
|
||||
}
|
||||
for(int i = 0; i < lightSourceBuckets.length; ++i) {
|
||||
lightSourceBuckets[i].clear();
|
||||
lightSourceBucketSerials[i] = -1;
|
||||
lightSourceRenderPosSerials[i] = -1;
|
||||
}
|
||||
currentLightSourceBucket = null;
|
||||
currentLightSourceBucketId = -1;
|
||||
currentBoundLightSourceBucket = null;
|
||||
isChunkLightingEnabled = false;
|
||||
for(int i = 0; i < shader_gbuffer_debug_view.length; ++i) {
|
||||
@ -3993,11 +4021,13 @@ public class EaglerDeferredPipeline {
|
||||
}
|
||||
|
||||
public static final boolean isSupported() {
|
||||
return EaglercraftGPU.checkHasHDRFramebufferSupportWithFilter();
|
||||
return EaglercraftGPU.checkOpenGLESVersion() >= 300 && EaglercraftGPU.checkHasHDRFramebufferSupportWithFilter();
|
||||
}
|
||||
|
||||
public static final String getReasonUnsupported() {
|
||||
if(!EaglercraftGPU.checkHasHDRFramebufferSupportWithFilter()) {
|
||||
if(EaglercraftGPU.checkOpenGLESVersion() < 300) {
|
||||
return I18n.format("shaders.gui.unsupported.reason.oldOpenGLVersion");
|
||||
}else if(!EaglercraftGPU.checkHasHDRFramebufferSupportWithFilter()) {
|
||||
return I18n.format("shaders.gui.unsupported.reason.hdrFramebuffer");
|
||||
}else {
|
||||
return null;
|
||||
@ -4015,7 +4045,7 @@ public class EaglerDeferredPipeline {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.matrixMode(GL_MODELVIEW);
|
||||
GlStateManager.pushMatrix();
|
||||
ScaledResolution scaledresolution = new ScaledResolution(mc);
|
||||
ScaledResolution scaledresolution = mc.scaledResolution;
|
||||
int w = scaledresolution.getScaledWidth();
|
||||
mc.entityRenderer.setupOverlayRendering();
|
||||
GlStateManager.enableAlpha();
|
||||
|
@ -22,7 +22,7 @@ import java.util.List;
|
||||
*/
|
||||
public class ForwardRenderCallbackHandler {
|
||||
|
||||
public final List<ShadersRenderPassFuture> renderPassList = new ArrayList(1024);
|
||||
public final List<ShadersRenderPassFuture> renderPassList = new ArrayList<>(1024);
|
||||
|
||||
public void push(ShadersRenderPassFuture f) {
|
||||
renderPassList.add(f);
|
||||
|
@ -8,7 +8,6 @@ import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglerInputStream;
|
||||
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;
|
||||
@ -20,6 +19,7 @@ import net.lax1dude.eaglercraft.v1_8.vector.Matrix3f;
|
||||
import net.lax1dude.eaglercraft.v1_8.vector.Vector3f;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2023 lax1dude. All Rights Reserved.
|
||||
@ -38,8 +38,8 @@ import net.minecraft.util.MathHelper;
|
||||
*/
|
||||
public class LensFlareMeshRenderer {
|
||||
|
||||
public static final String streaksTextureLocation ="assets/eagler/glsl/deferred/lens_streaks.bmp";
|
||||
public static final String ghostsTextureLocation = "assets/eagler/glsl/deferred/lens_ghosts.bmp";
|
||||
public static final ResourceLocation streaksTextureLocation = new ResourceLocation("eagler:glsl/deferred/lens_streaks.bmp");
|
||||
public static final ResourceLocation ghostsTextureLocation = new ResourceLocation("eagler:glsl/deferred/lens_ghosts.bmp");
|
||||
public static final int ghostsSpriteCount = 4;
|
||||
|
||||
static IBufferArrayGL streaksVertexArray = null;
|
||||
@ -157,11 +157,8 @@ public class LensFlareMeshRenderer {
|
||||
|
||||
streaksTexture = GlStateManager.generateTexture();
|
||||
GlStateManager.bindTexture(streaksTexture);
|
||||
byte[] flareTex = EagRuntime.getResourceBytes(streaksTextureLocation);
|
||||
if(flareTex == null) {
|
||||
throw new RuntimeException("Could not locate: " + streaksTextureLocation);
|
||||
}
|
||||
try(DataInputStream dis = new DataInputStream(new EaglerInputStream(flareTex))) {
|
||||
try (DataInputStream dis = new DataInputStream(
|
||||
Minecraft.getMinecraft().getResourceManager().getResource(streaksTextureLocation).getInputStream())) {
|
||||
loadFlareTexture(copyBuffer, dis);
|
||||
}catch(IOException ex) {
|
||||
EagRuntime.freeByteBuffer(copyBuffer);
|
||||
@ -170,11 +167,8 @@ public class LensFlareMeshRenderer {
|
||||
|
||||
ghostsTexture = GlStateManager.generateTexture();
|
||||
GlStateManager.bindTexture(ghostsTexture);
|
||||
flareTex = EagRuntime.getResourceBytes(ghostsTextureLocation);
|
||||
if(flareTex == null) {
|
||||
throw new RuntimeException("Could not locate: " + ghostsTextureLocation);
|
||||
}
|
||||
try(DataInputStream dis = new DataInputStream(new EaglerInputStream(flareTex))) {
|
||||
try (DataInputStream dis = new DataInputStream(
|
||||
Minecraft.getMinecraft().getResourceManager().getResource(ghostsTextureLocation).getInputStream())) {
|
||||
loadFlareTexture(copyBuffer, dis);
|
||||
}catch(IOException ex) {
|
||||
EagRuntime.freeByteBuffer(copyBuffer);
|
||||
|
@ -52,7 +52,7 @@ public class ShaderPackInfo {
|
||||
vers = json.optString("vers", "Unknown");
|
||||
author = json.optString("author", "Unknown");
|
||||
apiVers = json.optInt("api_vers", -1);
|
||||
supportedFeatures = new HashSet();
|
||||
supportedFeatures = new HashSet<>();
|
||||
JSONArray features = json.getJSONArray("features");
|
||||
if(features.length() == 0) {
|
||||
throw new JSONException("No supported features list has been defined for this shader pack!");
|
||||
|
@ -103,6 +103,11 @@ public class GuiShaderConfig extends GuiScreen {
|
||||
listView.handleMouseInput();
|
||||
}
|
||||
|
||||
public void handleTouchInput() throws IOException {
|
||||
super.handleTouchInput();
|
||||
listView.handleTouchInput();
|
||||
}
|
||||
|
||||
protected void mouseClicked(int parInt1, int parInt2, int parInt3) {
|
||||
super.mouseClicked(parInt1, parInt2, parInt3);
|
||||
listView.mouseClicked(parInt1, parInt2, parInt3);
|
||||
|
@ -35,7 +35,7 @@ public class GuiShaderConfigList extends GuiListExtended {
|
||||
|
||||
private final GuiShaderConfig screen;
|
||||
|
||||
private final List<IGuiListEntry> list = new ArrayList();
|
||||
private final List<IGuiListEntry> list = new ArrayList<>();
|
||||
|
||||
private static abstract class ShaderOption {
|
||||
|
||||
@ -56,7 +56,7 @@ public class GuiShaderConfigList extends GuiListExtended {
|
||||
}
|
||||
|
||||
private static List<String> loadDescription(String key) {
|
||||
List<String> ret = new ArrayList();
|
||||
List<String> ret = new ArrayList<>();
|
||||
String msg;
|
||||
int i = 0;
|
||||
while(true) {
|
||||
@ -112,7 +112,7 @@ public class GuiShaderConfigList extends GuiListExtended {
|
||||
this.list.add(new ListEntrySpacing());
|
||||
this.list.add(new ListEntrySpacing());
|
||||
this.list.add(new ListEntryHeader(I18n.format("shaders.gui.headerTier1")));
|
||||
List<ShaderOption> opts = new ArrayList();
|
||||
List<ShaderOption> opts = new ArrayList<>();
|
||||
EaglerDeferredConfig conf = mcIn.gameSettings.deferredShaderConf;
|
||||
if(conf.shaderPackInfo.WAVING_BLOCKS) {
|
||||
opts.add(new ShaderOption(loadShaderLbl("WAVING_BLOCKS"), loadShaderDesc("WAVING_BLOCKS")) {
|
||||
@ -550,6 +550,7 @@ public class GuiShaderConfigList extends GuiListExtended {
|
||||
|
||||
@Override
|
||||
public boolean mousePressed(int var1, int var2, int var3, int var4, int var5, int var6) {
|
||||
if(var4 != 0) return false;
|
||||
if(this.button1 != null) {
|
||||
if(this.button1.yPosition + 15 < bottom && this.button1.yPosition + 5 > top) {
|
||||
if(this.button1.mousePressed(mc, var2, var3)) {
|
||||
@ -610,7 +611,7 @@ public class GuiShaderConfigList extends GuiListExtended {
|
||||
}
|
||||
|
||||
private void renderTooltip(int x, int y, int width, List<String> msg) {
|
||||
ArrayList tooltipList = new ArrayList(msg.size() * 2);
|
||||
List<String> tooltipList = new ArrayList<>(msg.size() * 2);
|
||||
for(int i = 0, l = msg.size(); i < l; ++i) {
|
||||
String s = msg.get(i);
|
||||
if(s.length() > 0) {
|
||||
|
@ -32,7 +32,7 @@ public class PipelineShaderAccelParticleForward extends ShaderProgram<PipelineSh
|
||||
ShaderSource.accel_particle_vsh, "COMPILE_FORWARD_VSH");
|
||||
IShaderGL accelParticleFSH = null;
|
||||
try {
|
||||
List<String> lst = new ArrayList(2);
|
||||
List<String> lst = new ArrayList<>(2);
|
||||
if(dynamicLights) {
|
||||
lst.add("COMPILE_DYNAMIC_LIGHTS");
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ public class PipelineShaderGBufferCombine extends ShaderProgram<PipelineShaderGB
|
||||
|
||||
public static PipelineShaderGBufferCombine compile(boolean ssao, boolean env, boolean ssr) throws ShaderException {
|
||||
IShaderGL coreGBuffer = null;
|
||||
List<String> compileFlags = new ArrayList(2);
|
||||
List<String> compileFlags = new ArrayList<>(2);
|
||||
if(ssao) {
|
||||
compileFlags.add("COMPILE_GLOBAL_AMBIENT_OCCLUSION");
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ import net.lax1dude.eaglercraft.v1_8.internal.IUniformGL;
|
||||
public class PipelineShaderGBufferFog extends ShaderProgram<PipelineShaderGBufferFog.Uniforms> {
|
||||
|
||||
public static PipelineShaderGBufferFog compile(boolean linear, boolean atmosphere, boolean lightShafts) {
|
||||
List<String> macros = new ArrayList(3);
|
||||
List<String> macros = new ArrayList<>(3);
|
||||
if(linear) {
|
||||
macros.add("COMPILE_FOG_LINEAR");
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ public class PipelineShaderLightingPoint extends ShaderProgram<PipelineShaderLig
|
||||
|
||||
public static PipelineShaderLightingPoint compile(boolean shadows)
|
||||
throws ShaderException {
|
||||
List<String> compileFlags = new ArrayList(2);
|
||||
List<String> compileFlags = new ArrayList<>(2);
|
||||
if(shadows) {
|
||||
compileFlags.add("COMPILE_PARABOLOID_SHADOW");
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ public class PipelineShaderLightingSun extends ShaderProgram<PipelineShaderLight
|
||||
|
||||
public static PipelineShaderLightingSun compile(int shadowsSun, boolean coloredShadows) throws ShaderException {
|
||||
IShaderGL sunShader = null;
|
||||
List<String> compileFlags = new ArrayList(1);
|
||||
List<String> compileFlags = new ArrayList<>(1);
|
||||
if(shadowsSun > 0) {
|
||||
compileFlags.add("COMPILE_SUN_SHADOW");
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ import net.lax1dude.eaglercraft.v1_8.internal.IUniformGL;
|
||||
public class PipelineShaderPostExposureAvg extends ShaderProgram<PipelineShaderPostExposureAvg.Uniforms> {
|
||||
|
||||
public static PipelineShaderPostExposureAvg compile(boolean luma) throws ShaderException {
|
||||
List<String> compileFlags = new ArrayList(1);
|
||||
List<String> compileFlags = new ArrayList<>(1);
|
||||
if(luma) {
|
||||
compileFlags.add("CALCULATE_LUMINANCE");
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ import net.lax1dude.eaglercraft.v1_8.internal.IUniformGL;
|
||||
public class PipelineShaderReprojControl extends ShaderProgram<PipelineShaderReprojControl.Uniforms> {
|
||||
|
||||
public static PipelineShaderReprojControl compile(boolean ssao, boolean ssr) throws ShaderException {
|
||||
List<String> compileFlags = new ArrayList(2);
|
||||
List<String> compileFlags = new ArrayList<>(2);
|
||||
if(ssao) {
|
||||
compileFlags.add("COMPILE_REPROJECT_SSAO");
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ public class PipelineShaderShadowsSun extends ShaderProgram<PipelineShaderShadow
|
||||
public static PipelineShaderShadowsSun compile(int shadowsSun, boolean shadowsSunSmooth, boolean coloredShadows)
|
||||
throws ShaderException {
|
||||
IShaderGL shadowShader = null;
|
||||
List<String> compileFlags = new ArrayList(2);
|
||||
List<String> compileFlags = new ArrayList<>(2);
|
||||
if(shadowsSun == 0) {
|
||||
throw new IllegalStateException("Enable shadows to compile this shader");
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ import java.util.List;
|
||||
public class PipelineShaderSkyboxRender extends ShaderProgram<PipelineShaderSkyboxRender.Uniforms> {
|
||||
|
||||
public static PipelineShaderSkyboxRender compile(boolean paraboloid, boolean clouds) throws ShaderException {
|
||||
List<String> compileFlags = new ArrayList();
|
||||
List<String> compileFlags = new ArrayList<>();
|
||||
if(paraboloid) {
|
||||
compileFlags.add("COMPILE_PARABOLOID_SKY");
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import net.lax1dude.eaglercraft.v1_8.internal.IProgramGL;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IShaderGL;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.FixedFunctionShader;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.GLSLHeader;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
@ -47,7 +47,7 @@ public class ShaderCompiler {
|
||||
public static IShaderGL compileShader(String name, int stage, String filename, String source, List<String> compileFlags) throws ShaderCompileException {
|
||||
logger.info("Compiling Shader: " + filename);
|
||||
StringBuilder srcCat = new StringBuilder();
|
||||
srcCat.append(FixedFunctionShader.FixedFunctionConstants.VERSION).append('\n');
|
||||
srcCat.append(GLSLHeader.getHeader()).append('\n');
|
||||
|
||||
if(compileFlags != null && compileFlags.size() > 0) {
|
||||
for(int i = 0, l = compileFlags.size(); i < l; ++i) {
|
||||
|
@ -97,7 +97,7 @@ public class ShaderSource {
|
||||
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 final Map<ResourceLocation, String> sourceCache = new HashMap<>();
|
||||
|
||||
private static boolean isHighP = false;
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.texture;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
@ -121,7 +120,7 @@ public class EaglerTextureAtlasSpritePBR extends EaglerTextureAtlasSprite {
|
||||
|
||||
this.animationMetadata = meta;
|
||||
} else {
|
||||
ArrayList arraylist = Lists.newArrayList();
|
||||
List<AnimationFrame> arraylist = Lists.newArrayList();
|
||||
|
||||
for (int l1 = 0; l1 < j1; ++l1) {
|
||||
this.frameTextureDataPBR[0].add(getFrameTextureData(aint[0], k1, l, l1));
|
||||
|
@ -34,7 +34,7 @@ public class EmissiveItems implements IResourceManagerReloadListener {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger("EmissiveItemsCSV");
|
||||
|
||||
private static final Map<String,float[]> entries = new HashMap();
|
||||
private static final Map<String,float[]> entries = new HashMap<>();
|
||||
|
||||
public static float[] getItemEmission(ItemStack itemStack) {
|
||||
return getItemEmission(itemStack.getItem(), itemStack.getItemDamage());
|
||||
|
@ -34,7 +34,7 @@ public class PBRMaterialConstants implements IResourceManagerReloadListener {
|
||||
public static final Logger logger = LogManager.getLogger("PBRMaterialConstants");
|
||||
|
||||
public final ResourceLocation resourceLocation;
|
||||
public final Map<String,Integer> spriteNameToMaterialConstants = new HashMap();
|
||||
public final Map<String,Integer> spriteNameToMaterialConstants = new HashMap<>();
|
||||
|
||||
public int defaultMaterial = 0x00000A77;
|
||||
|
||||
|
@ -34,14 +34,19 @@ import net.minecraft.util.MathHelper;
|
||||
public class DynamicLightBucketLoader {
|
||||
|
||||
public IBufferGL buffer_chunkLightingData;
|
||||
public IBufferGL buffer_chunkLightingDataZero;
|
||||
private ByteBuffer chunkLightingDataCopyBuffer;
|
||||
private boolean isChunkLightingEnabled = false;
|
||||
public ListSerial<DynamicLightInstance> currentBoundLightSourceBucket;
|
||||
|
||||
public final ListSerial<DynamicLightInstance>[] lightSourceBuckets;
|
||||
private final int[] lightSourceBucketsSerials;
|
||||
private final int[] lightSourceRenderPosSerials;
|
||||
public ListSerial<DynamicLightInstance> currentLightSourceBucket;
|
||||
private int currentLightSourceBucketId = -1;
|
||||
private int lightingBufferSliceLength = -1;
|
||||
|
||||
public static final int MAX_LIGHTS_PER_CHUNK = 12;
|
||||
public static final int LIGHTING_BUFFER_LENGTH = 16 * MAX_LIGHTS_PER_CHUNK + 16;
|
||||
|
||||
private final int lightSourceBucketsWidth;
|
||||
private final int lightSourceBucketsHeight;
|
||||
@ -49,29 +54,42 @@ public class DynamicLightBucketLoader {
|
||||
private double currentRenderX = 0.0;
|
||||
private double currentRenderY = 0.0;
|
||||
private double currentRenderZ = 0.0;
|
||||
private int currentRenderPosSerial = 0;
|
||||
|
||||
public DynamicLightBucketLoader() {
|
||||
this.lightSourceBucketsWidth = 5;
|
||||
this.lightSourceBucketsHeight = 3;
|
||||
int cnt = 5 * 3 * 5;
|
||||
this.lightSourceBuckets = new ListSerial[cnt];
|
||||
this.lightSourceBucketsSerials = new int[cnt];
|
||||
this.lightSourceRenderPosSerials = new int[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) {
|
||||
int alignment = EaglercraftGPU.getUniformBufferOffsetAlignment();
|
||||
lightingBufferSliceLength = MathHelper.ceiling_float_int((float)LIGHTING_BUFFER_LENGTH / (float)alignment) * alignment;
|
||||
|
||||
chunkLightingDataCopyBuffer = EagRuntime.allocateByteBuffer(LIGHTING_BUFFER_LENGTH);
|
||||
for(int i = 0; i < LIGHTING_BUFFER_LENGTH; i += 4) {
|
||||
chunkLightingDataCopyBuffer.putInt(0);
|
||||
}
|
||||
chunkLightingDataCopyBuffer.flip();
|
||||
_wglBufferData(_GL_UNIFORM_BUFFER, chunkLightingDataCopyBuffer, GL_DYNAMIC_DRAW);
|
||||
|
||||
buffer_chunkLightingData = _wglGenBuffers();
|
||||
EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingData);
|
||||
int cnt = lightSourceBucketsWidth * lightSourceBucketsHeight * lightSourceBucketsWidth;
|
||||
_wglBufferData(_GL_UNIFORM_BUFFER, cnt * lightingBufferSliceLength, GL_DYNAMIC_DRAW);
|
||||
|
||||
buffer_chunkLightingDataZero = _wglGenBuffers();
|
||||
EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingDataZero);
|
||||
_wglBufferData(_GL_UNIFORM_BUFFER, chunkLightingDataCopyBuffer, GL_STATIC_DRAW);
|
||||
|
||||
for(int i = 0; i < this.lightSourceBuckets.length; ++i) {
|
||||
this.lightSourceBuckets[i] = new ArrayListSerial(16);
|
||||
this.lightSourceBuckets[i] = new ArrayListSerial<>(16);
|
||||
this.lightSourceBucketsSerials[i] = -1;
|
||||
this.lightSourceRenderPosSerials[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,7 +99,7 @@ public class DynamicLightBucketLoader {
|
||||
}
|
||||
}
|
||||
|
||||
public void loadLightSourceBucket(int relativeBlockX, int relativeBlockY, int relativeBlockZ) {
|
||||
public void bindLightSourceBucket(int relativeBlockX, int relativeBlockY, int relativeBlockZ, int uboIndex) {
|
||||
int hw = lightSourceBucketsWidth / 2;
|
||||
int hh = lightSourceBucketsHeight / 2;
|
||||
int bucketX = (relativeBlockX >> 4) + hw;
|
||||
@ -89,12 +107,47 @@ public class DynamicLightBucketLoader {
|
||||
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];
|
||||
currentLightSourceBucketId = bucketY * lightSourceBucketsWidth * lightSourceBucketsWidth
|
||||
+ bucketZ * lightSourceBucketsWidth + bucketX;
|
||||
currentLightSourceBucket = lightSourceBuckets[currentLightSourceBucketId];
|
||||
int ser = currentLightSourceBucket.getEaglerSerial();
|
||||
int max = currentLightSourceBucket.size();
|
||||
if(max > 0) {
|
||||
EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingData);
|
||||
int offset = currentLightSourceBucketId * lightingBufferSliceLength;
|
||||
if (lightSourceBucketsSerials[currentLightSourceBucketId] != ser
|
||||
|| lightSourceRenderPosSerials[currentLightSourceBucketId] != currentRenderPosSerial) {
|
||||
lightSourceBucketsSerials[currentLightSourceBucketId] = ser;
|
||||
lightSourceRenderPosSerials[currentLightSourceBucketId] = currentRenderPosSerial;
|
||||
if(max > MAX_LIGHTS_PER_CHUNK) {
|
||||
max = MAX_LIGHTS_PER_CHUNK;
|
||||
}
|
||||
chunkLightingDataCopyBuffer.clear();
|
||||
chunkLightingDataCopyBuffer.putInt(max);
|
||||
chunkLightingDataCopyBuffer.putInt(0); //padding
|
||||
chunkLightingDataCopyBuffer.putInt(0); //padding
|
||||
chunkLightingDataCopyBuffer.putInt(0); //padding
|
||||
for(int i = 0; i < max; ++i) {
|
||||
DynamicLightInstance dl = currentLightSourceBucket.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();
|
||||
_wglBufferSubData(_GL_UNIFORM_BUFFER, offset, chunkLightingDataCopyBuffer);
|
||||
}
|
||||
EaglercraftGPU.bindUniformBufferRange(uboIndex, buffer_chunkLightingData, offset, LIGHTING_BUFFER_LENGTH);
|
||||
}else {
|
||||
EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingDataZero);
|
||||
EaglercraftGPU.bindUniformBufferRange(uboIndex, buffer_chunkLightingDataZero, 0, LIGHTING_BUFFER_LENGTH);
|
||||
}
|
||||
}else {
|
||||
currentLightSourceBucketId = -1;
|
||||
currentLightSourceBucket = null;
|
||||
EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingDataZero);
|
||||
EaglercraftGPU.bindUniformBufferRange(uboIndex, buffer_chunkLightingDataZero, 0, LIGHTING_BUFFER_LENGTH);
|
||||
}
|
||||
updateLightSourceUBO();
|
||||
}
|
||||
|
||||
public ListSerial<DynamicLightInstance> getLightSourceBucketRelativeChunkCoords(int cx, int cy, int cz) {
|
||||
@ -188,8 +241,8 @@ public class DynamicLightBucketLoader {
|
||||
}
|
||||
|
||||
public void truncateOverflowingBuffers() {
|
||||
for(int i = 0; i < this.lightSourceBuckets.length; ++i) {
|
||||
List<DynamicLightInstance> lst = this.lightSourceBuckets[i];
|
||||
for(int i = 0; i < lightSourceBuckets.length; ++i) {
|
||||
List<DynamicLightInstance> lst = lightSourceBuckets[i];
|
||||
int k = lst.size();
|
||||
if(k > MAX_LIGHTS_PER_CHUNK) {
|
||||
lst.sort(comparatorLightRadius);
|
||||
@ -200,74 +253,18 @@ public class DynamicLightBucketLoader {
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
if (this.currentRenderX != currentRenderX || this.currentRenderY != currentRenderY
|
||||
|| this.currentRenderZ != currentRenderZ || this.currentRenderPosSerial == 0) {
|
||||
this.currentRenderX = currentRenderX;
|
||||
this.currentRenderY = currentRenderY;
|
||||
this.currentRenderZ = currentRenderZ;
|
||||
++this.currentRenderPosSerial;
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
@ -279,8 +276,16 @@ public class DynamicLightBucketLoader {
|
||||
_wglDeleteBuffers(buffer_chunkLightingData);
|
||||
buffer_chunkLightingData = null;
|
||||
}
|
||||
for(int i = 0; i < this.lightSourceBuckets.length; ++i) {
|
||||
this.lightSourceBuckets[i] = null;
|
||||
if(buffer_chunkLightingDataZero != null) {
|
||||
_wglDeleteBuffers(buffer_chunkLightingDataZero);
|
||||
buffer_chunkLightingDataZero = null;
|
||||
}
|
||||
for(int i = 0; i < lightSourceBuckets.length; ++i) {
|
||||
lightSourceBuckets[i] = null;
|
||||
lightSourceBucketsSerials[i] = -1;
|
||||
lightSourceRenderPosSerials[i] = -1;
|
||||
}
|
||||
currentLightSourceBucket = null;
|
||||
currentLightSourceBucketId = -1;
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.EaglercraftGPU;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.FixedFunctionPipeline;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.vector.Matrix4f;
|
||||
@ -30,10 +32,10 @@ import net.minecraft.util.MathHelper;
|
||||
public class DynamicLightsStateManager {
|
||||
|
||||
static final DynamicLightsPipelineCompiler deferredExtPipeline = new DynamicLightsPipelineCompiler();
|
||||
private static List<DynamicLightInstance> lightInstancePool = new ArrayList();
|
||||
private static List<DynamicLightInstance> lightInstancePool = new ArrayList<>();
|
||||
private static int instancePoolIndex = 0;
|
||||
private static int maxListLengthTracker = 0;
|
||||
static final List<DynamicLightInstance> lightRenderList = new LinkedList();
|
||||
static final List<DynamicLightInstance> lightRenderList = new LinkedList<>();
|
||||
static final Matrix4f inverseViewMatrix = new Matrix4f();
|
||||
static int inverseViewMatrixSerial = 0;
|
||||
static DynamicLightBucketLoader bucketLoader = null;
|
||||
@ -45,7 +47,7 @@ public class DynamicLightsStateManager {
|
||||
if(bucketLoader == null) {
|
||||
bucketLoader = new DynamicLightBucketLoader();
|
||||
bucketLoader.initialize();
|
||||
bucketLoader.bindUniformBuffer(0);
|
||||
bucketLoader.bindLightSourceBucket(-999, -999, -999, 0);
|
||||
FixedFunctionPipeline.loadExtensionPipeline(deferredExtPipeline);
|
||||
}
|
||||
if(accelParticleRenderer == null) {
|
||||
@ -89,7 +91,7 @@ public class DynamicLightsStateManager {
|
||||
|
||||
public static final void reportForwardRenderObjectPosition(int centerX, int centerY, int centerZ) {
|
||||
if(bucketLoader != null) {
|
||||
bucketLoader.loadLightSourceBucket(centerX, centerY, centerZ);
|
||||
bucketLoader.bindLightSourceBucket(centerX, centerY, centerZ, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,7 +100,7 @@ public class DynamicLightsStateManager {
|
||||
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);
|
||||
bucketLoader.bindLightSourceBucket((int)posX, (int)posY, (int)posZ, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,11 +154,11 @@ public class DynamicLightsStateManager {
|
||||
}
|
||||
|
||||
private static final void updateTimers() {
|
||||
long millis = System.currentTimeMillis();
|
||||
long millis = EagRuntime.steadyTimeMillis();
|
||||
if(millis - lastTick > 5000l) {
|
||||
lastTick = millis;
|
||||
if(maxListLengthTracker < (lightInstancePool.size() >> 1)) {
|
||||
List<DynamicLightInstance> newPool = new ArrayList(Math.max(maxListLengthTracker, 16));
|
||||
List<DynamicLightInstance> newPool = new ArrayList<>(Math.max(maxListLengthTracker, 16));
|
||||
for(int i = 0; i < maxListLengthTracker; ++i) {
|
||||
newPool.add(lightInstancePool.get(i));
|
||||
}
|
||||
@ -167,11 +169,15 @@ public class DynamicLightsStateManager {
|
||||
}
|
||||
|
||||
public static final void destroyAll() {
|
||||
lightInstancePool = new ArrayList();
|
||||
lightInstancePool = new ArrayList<>();
|
||||
}
|
||||
|
||||
public static String getF3String() {
|
||||
return "DynamicLightsTotal: " + lastTotal;
|
||||
}
|
||||
|
||||
public static boolean isSupported() {
|
||||
return EaglercraftGPU.checkOpenGLESVersion() >= 300;
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user