Merge branch distant-horizons-core:main into fix/close-db-file
This commit is contained in:
+144
-16
@@ -1,51 +1,179 @@
|
||||
package com.seibel.distanthorizons.coreapi.util.jar;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Deletes the first file in the arguments when a lock is lifted from it (for Windows) <br>
|
||||
* DON'T MOVE: If this class is moved, then the updater will no longer work on Windows
|
||||
* Attempts to delete a given file path repeatedly until the file is unlocked. <br>
|
||||
* NOTE: don't move this class. If this class is moved, then old jars won't be able to find it.
|
||||
*
|
||||
* @author coolgi
|
||||
*/
|
||||
public class DeleteOnUnlock
|
||||
{
|
||||
public static int SUCCESS_EXIT_CODE = 0;
|
||||
public static int FAIL_EXIT_CODE = 1;
|
||||
public static int ERROR_EXIT_CODE = 2;
|
||||
|
||||
/** How long to wait after attempting once (milliseconds) */
|
||||
private static final int attemptSpeed = 100;
|
||||
/** How many minutes of attempting before it stops */
|
||||
private static final int timeout = 60; // Will continue attempting for an hour, if it doesnt unlock by then, then the computer must be way to slow
|
||||
private static final int ATTEMPT_SPEED_IN_MS = 100;
|
||||
/**
|
||||
* How many minutes of attempting before it stops <br>
|
||||
* If the file isn't unlocked by then, the computer must be extremely slow or there is a bigger issue.
|
||||
*/
|
||||
private static final int TIMEOUT_IN_MINUTES = 60;
|
||||
|
||||
/** can be null */
|
||||
private static FileWriter logFileWriter;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param args Takes whatever the first argument is, treats it as a file, and deletes it once a process lock is lifted from it <br>
|
||||
* Note: This argument should also be encoded in UTF-8
|
||||
* <strong>args[0]</strong> the file path to delete. Should be encoded in UTF-8.
|
||||
* <strong>args[1]</strong> the file path to write logs to, can be null.
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
String filePathToDelete = args[0];
|
||||
|
||||
// can be null, should only be used when debugging
|
||||
String logFilePath = null;
|
||||
if (args.length >= 2)
|
||||
{
|
||||
logFilePath = args[1]; // example: "C:/Users/James/Desktop/delete.log"
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
File file = new File(
|
||||
URLDecoder.decode(args[0], "UTF-8")
|
||||
);
|
||||
//===============//
|
||||
// logging setup //
|
||||
//===============//
|
||||
|
||||
// General logging note:
|
||||
// system.err/out will only show up when debugging this program,
|
||||
// when running DH as a whole it won't be shown.
|
||||
// This is why file logging is necessary
|
||||
|
||||
for (int i = 0; i < (60 / ((float) attemptSpeed/1000) ) * timeout; i++)
|
||||
// does nothing if no log path was given
|
||||
if (logFilePath != null && logFilePath.trim().length() != 0)
|
||||
{
|
||||
if (file.renameTo(file)) // If it is able to be renamed, then it is unlocked and can be deleted
|
||||
// create the file writer
|
||||
File logFile = new File(logFilePath);
|
||||
logFileWriter = new FileWriter(logFile, true);
|
||||
|
||||
// create the log file if necessary
|
||||
try
|
||||
{
|
||||
Files.delete(file.toPath());
|
||||
break;
|
||||
if (!logFile.createNewFile() && !logFile.exists())
|
||||
{
|
||||
System.err.println("Unable to create log file at: [" + logFile.getPath() + "]");
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
System.err.println(e.getMessage());
|
||||
}
|
||||
TimeUnit.MILLISECONDS.sleep(attemptSpeed);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//====================//
|
||||
// file deletion loop //
|
||||
//====================//
|
||||
|
||||
File fileToDelete = new File(URLDecoder.decode(filePathToDelete, "UTF-8"));
|
||||
log("starting deletion loop... Attempting to delete: ["+fileToDelete.getPath()+"].");
|
||||
|
||||
for (int i = 0; i < (60 / ((float) ATTEMPT_SPEED_IN_MS /1000) ) * TIMEOUT_IN_MINUTES; i++)
|
||||
{
|
||||
log("delete attempt ["+i+"]");
|
||||
|
||||
// If the file can be renamed then it is unlocked and can be deleted
|
||||
if (fileToDelete.exists() && fileToDelete.renameTo(fileToDelete))
|
||||
{
|
||||
try
|
||||
{
|
||||
Files.delete(fileToDelete.toPath());
|
||||
|
||||
if (!fileToDelete.exists())
|
||||
{
|
||||
log("success");
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// shouldn't normally happen, but just in case
|
||||
log("failed to delete without error");
|
||||
}
|
||||
}
|
||||
catch (NoSuchFileException e)
|
||||
{
|
||||
// accidental success, the file is no longer there
|
||||
log("no file found");
|
||||
break;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log("failed to delete with error: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
TimeUnit.MILLISECONDS.sleep(ATTEMPT_SPEED_IN_MS);
|
||||
}
|
||||
|
||||
|
||||
//==================//
|
||||
// cleanup and exit //
|
||||
//==================//
|
||||
|
||||
boolean programSuccess = !fileToDelete.exists();
|
||||
log("delete program completed " + (programSuccess ? "successfully" : "unsuccessfully"));
|
||||
System.exit(programSuccess ? SUCCESS_EXIT_CODE : FAIL_EXIT_CODE);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
String stackTrace = "";
|
||||
for (StackTraceElement stackTraceElement : e.getStackTrace())
|
||||
{
|
||||
stackTrace += stackTraceElement.toString() + "\n";
|
||||
}
|
||||
log("Unexpected exception occurred: " + e.getMessage() + "\n\n" + stackTrace);
|
||||
|
||||
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Deletion failed");
|
||||
System.exit(ERROR_EXIT_CODE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** writes the given message to the log file if a log file is present. */
|
||||
private static void log(String message)
|
||||
{
|
||||
if (logFileWriter != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
String localDateTime = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE) + " " + LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME);
|
||||
logFileWriter.write(localDateTime + " - " + message + "\n");
|
||||
|
||||
// necessary to make sure the log file is written to
|
||||
logFileWriter.flush();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// Note: this will only show up when debugging this program, when running DH as a whole it won't be shown
|
||||
System.err.println("Error writing to log: "+e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ public class DhApiGraphicsConfig implements IDhApiGraphicsConfig
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Integer> chunkRenderDistance()
|
||||
{ return new DhApiConfigValue<Integer, Integer>(Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistance); }
|
||||
{ return new DhApiConfigValue<Integer, Integer>(Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Boolean> renderingEnabled()
|
||||
|
||||
@@ -31,7 +31,6 @@ import com.seibel.distanthorizons.core.config.types.enums.*;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.jar.EPlatform;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.util.EnumUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import com.seibel.distanthorizons.coreapi.util.StringUtil;
|
||||
@@ -71,7 +70,7 @@ public class Config
|
||||
.setAppearance(EConfigEntryAppearance.ONLY_IN_GUI)
|
||||
.build();
|
||||
|
||||
public static ConfigLinkedEntry quickLodChunkRenderDistance = new ConfigLinkedEntry(Advanced.Graphics.Quality.lodChunkRenderDistance);
|
||||
public static ConfigLinkedEntry quickLodChunkRenderDistance = new ConfigLinkedEntry(Advanced.Graphics.Quality.lodChunkRenderDistanceRadius);
|
||||
|
||||
public static ConfigEntry<EQualityPreset> qualityPresetSetting = new ConfigEntry.Builder<EQualityPreset>()
|
||||
.set(EQualityPreset.MEDIUM) // the default value is set via the listener when accessed
|
||||
@@ -155,7 +154,7 @@ public class Config
|
||||
.setPerformance(EConfigEntryPerformance.MEDIUM)
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<Integer> lodChunkRenderDistance = new ConfigEntry.Builder<Integer>()
|
||||
public static ConfigEntry<Integer> lodChunkRenderDistanceRadius = new ConfigEntry.Builder<Integer>()
|
||||
.setMinDefaultMax(32, 128, 4096)
|
||||
.comment("The radius of the mod's render distance. (measured in chunks)")
|
||||
.setPerformance(EConfigEntryPerformance.HIGH)
|
||||
@@ -998,8 +997,7 @@ public class Config
|
||||
public static ConfigEntry<Boolean> enableAutoUpdater = new ConfigEntry.Builder<Boolean>()
|
||||
.set(
|
||||
!SingletonInjector.INSTANCE.get(IMinecraftSharedWrapper.class).getInstallationDirectory().getName().equals("run") // Guesses that a dev would use the directory called "run" as their running directory, and clients wont
|
||||
&& !EPlatform.get().equals(EPlatform.WINDOWS) // FIXME: Updater on Windows is broken atm (and I have no idea on how to fix it)
|
||||
) // disable the update notification in dev clients
|
||||
) // disable the updater in dev clients
|
||||
.comment(""
|
||||
+ "Automatically check for updates on game launch?")
|
||||
.build();
|
||||
@@ -1228,30 +1226,32 @@ public class Config
|
||||
+ "")
|
||||
.build();
|
||||
|
||||
//public static ConfigEntry<Integer> glContextMajorVersion = new ConfigEntry.Builder<Integer>()
|
||||
// .setMinDefaultMax(3, 3, 4)
|
||||
// .comment("" +
|
||||
// "Can be changed if you experience crashing when loading into a world.\n" +
|
||||
// "Note: setting to an invalid version may also cause the game to crash.\n" +
|
||||
// "\n" +
|
||||
// "Defines the requested OpenGL context major version Distant Horizons will create. \n" +
|
||||
// "Possible values (DH requires 3.2 or higher at minimum): \n" +
|
||||
// "4.6, 4.5, 4.4, 4.3, 4.2, 4.1, 4.0 \n" +
|
||||
// "3.3, 3.2 \n" +
|
||||
// "")
|
||||
// .build();
|
||||
//public static ConfigEntry<Integer> glContextMinorVersion = new ConfigEntry.Builder<Integer>()
|
||||
// .setMinDefaultMax(0, 2, 6)
|
||||
// .comment("" +
|
||||
// "Can be changed if you experience crashing when loading into a world.\n" +
|
||||
// "Note: setting to an invalid version may also cause the game to crash.\n" +
|
||||
// "\n" +
|
||||
// "Defines the requested OpenGL context major version Distant Horizons will create. \n" +
|
||||
// "Possible values (DH requires 3.2 or higher at minimum): \n" +
|
||||
// "4.6, 4.5, 4.4, 4.3, 4.2, 4.1, 4.0 \n" +
|
||||
// "3.3, 3.2 \n" +
|
||||
// "")
|
||||
// .build();
|
||||
public static ConfigEntry<Integer> glContextMajorVersion = new ConfigEntry.Builder<Integer>()
|
||||
.setMinDefaultMax(0, 0, 4)
|
||||
.comment("" +
|
||||
"Can be changed if you experience crashing when loading into a world.\n" +
|
||||
"Note: setting to an invalid version may also cause the game to crash.\n" +
|
||||
"\n" +
|
||||
"Leaving this value at causes DH to try all supported GL versions. \n" +
|
||||
"\n" +
|
||||
"Defines the requested OpenGL context major version Distant Horizons will create. \n" +
|
||||
"Possible values (DH requires 3.2 or higher at minimum): \n" +
|
||||
"4.6, 4.5, 4.4, 4.3, 4.2, 4.1, 4.0 \n" +
|
||||
"3.3, 3.2 \n" +
|
||||
"")
|
||||
.build();
|
||||
public static ConfigEntry<Integer> glContextMinorVersion = new ConfigEntry.Builder<Integer>()
|
||||
.setMinDefaultMax(0, 0, 6)
|
||||
.comment("" +
|
||||
"Can be changed if you experience crashing when loading into a world.\n" +
|
||||
"Note: setting to an invalid version may also cause the game to crash.\n" +
|
||||
"\n" +
|
||||
"Defines the requested OpenGL context major version Distant Horizons will create. \n" +
|
||||
"Possible values (DH requires 3.2 or higher at minimum): \n" +
|
||||
"4.6, 4.5, 4.4, 4.3, 4.2, 4.1, 4.0 \n" +
|
||||
"3.3, 3.2 \n" +
|
||||
"")
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<EGlProfileMode> glProfileMode = new ConfigEntry.Builder<EGlProfileMode>()
|
||||
.set(EGlProfileMode.CORE)
|
||||
|
||||
+8
-9
@@ -20,13 +20,12 @@
|
||||
package com.seibel.distanthorizons.core.config.gui;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.config.EGpuUploadMethod;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLState;
|
||||
import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer;
|
||||
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexAttribute;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.AbstractVertexAttribute;
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexPointer;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
@@ -40,19 +39,19 @@ public class OpenGLConfigScreen extends AbstractScreen
|
||||
ShaderProgram basicShader;
|
||||
GLVertexBuffer sameContextBuffer;
|
||||
GLVertexBuffer sharedContextBuffer;
|
||||
VertexAttribute va;
|
||||
AbstractVertexAttribute va;
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
System.out.println("init");
|
||||
|
||||
va = VertexAttribute.create();
|
||||
va = AbstractVertexAttribute.create();
|
||||
va.bind();
|
||||
// Pos
|
||||
va.setVertexAttribute(0, 0, VertexAttribute.VertexPointer.addVec2Pointer(false));
|
||||
va.setVertexAttribute(0, 0, VertexPointer.addVec2Pointer(false));
|
||||
// Color
|
||||
va.setVertexAttribute(0, 1, VertexAttribute.VertexPointer.addVec4Pointer(false));
|
||||
va.setVertexAttribute(0, 1, VertexPointer.addVec4Pointer(false));
|
||||
va.completeAndCheck(Float.BYTES * 6);
|
||||
basicShader = new ShaderProgram("shaders/test/vert.vert", "shaders/test/frag.frag",
|
||||
"fragColor", new String[]{"vPosition", "color"});
|
||||
@@ -109,12 +108,12 @@ public class OpenGLConfigScreen extends AbstractScreen
|
||||
if (System.currentTimeMillis() % 2000 < 1000)
|
||||
{
|
||||
sameContextBuffer.bind();
|
||||
va.bindBufferToAllBindingPoint(sameContextBuffer.getId());
|
||||
va.bindBufferToAllBindingPoints(sameContextBuffer.getId());
|
||||
}
|
||||
else
|
||||
{
|
||||
sameContextBuffer.bind();
|
||||
va.bindBufferToAllBindingPoint(sharedContextBuffer.getId());
|
||||
va.bindBufferToAllBindingPoints(sharedContextBuffer.getId());
|
||||
}
|
||||
// Render the square
|
||||
GL32.glDrawArrays(GL32.GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
@@ -21,7 +21,6 @@ package com.seibel.distanthorizons.core.jar.updater;
|
||||
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.jar.EPlatform;
|
||||
import com.seibel.distanthorizons.core.jar.JarUtils;
|
||||
import com.seibel.distanthorizons.core.jar.ModGitInfo;
|
||||
import com.seibel.distanthorizons.core.jar.installer.GitlabGetter;
|
||||
@@ -34,11 +33,10 @@ import com.seibel.distanthorizons.coreapi.util.jar.DeleteOnUnlock;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.*;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
@@ -53,7 +51,7 @@ public class SelfUpdater
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger(SelfUpdater.class.getSimpleName());
|
||||
|
||||
/** As we cannot delete(or replace) the jar while the mod is running, we just have this to delete it once the game closes */
|
||||
public static boolean deleteOldOnClose = false;
|
||||
public static boolean deleteOldJarOnJvmShutdown = false;
|
||||
|
||||
private static String currentJarSha = "";
|
||||
private static String mcVersion = SingletonInjector.INSTANCE.get(IVersionConstants.class).getMinecraftVersion();
|
||||
@@ -205,7 +203,7 @@ public class SelfUpdater
|
||||
throw new Exception("Checksum failed");
|
||||
}
|
||||
|
||||
deleteOldOnClose = true;
|
||||
deleteOldJarOnJvmShutdown = true;
|
||||
|
||||
LOGGER.info(ModInfo.READABLE_NAME + " successfully updated. It will apply on game's relaunch");
|
||||
new Thread(() -> {
|
||||
@@ -253,7 +251,7 @@ public class SelfUpdater
|
||||
}
|
||||
fos.close();
|
||||
|
||||
deleteOldOnClose = true;
|
||||
deleteOldJarOnJvmShutdown = true;
|
||||
|
||||
LOGGER.info(ModInfo.READABLE_NAME + " successfully updated. It will apply on game's relaunch");
|
||||
new Thread(() -> {
|
||||
@@ -291,46 +289,108 @@ public class SelfUpdater
|
||||
*/
|
||||
public static void onClose()
|
||||
{
|
||||
if (deleteOldOnClose)
|
||||
if (!deleteOldJarOnJvmShutdown)
|
||||
{
|
||||
try
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Path newJarPath = newFileLocation.toPath();
|
||||
Path finalJarPath = JarUtils.jarFile.getParentFile().toPath().resolve(newFileLocation.getName());
|
||||
|
||||
try
|
||||
{
|
||||
// if a jar with the same already exists in the final location, delete it first (otherwise file move issues will occur)
|
||||
Files.deleteIfExists(finalJarPath);
|
||||
|
||||
// move the new jar...
|
||||
Files.move(newJarPath, finalJarPath);
|
||||
// ...and delete the temp folder
|
||||
Files.delete(newFileLocation.getParentFile().toPath());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.warn("Failed to move updated fire from [" + newFileLocation.getAbsolutePath() + "] " +
|
||||
"to [" + JarUtils.jarFile.getParentFile().getAbsolutePath() + "], " +
|
||||
"please move it manually", e);
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
// Get the Java binary
|
||||
String javaHome = System.getProperty("java.home");
|
||||
String javaBin = javaHome + File.separator + "bin" + File.separator + "java";
|
||||
|
||||
// Run the file deletion jar in a new OS process,
|
||||
// this is done to allow for deleting the current jar if the OS has a lock on it
|
||||
String execCommand = "\""+ javaBin +"\" -cp \""+
|
||||
finalJarPath.toAbsolutePath()+"\" " // run the deletion code from the new jar
|
||||
+DeleteOnUnlock.class.getCanonicalName()+" "+
|
||||
URLEncoder.encode(JarUtils.jarFile.getAbsolutePath(), "UTF-8"); // Encode the file location to prevent issues with special characters and spaces
|
||||
Process deleteProcess = Runtime.getRuntime().exec(execCommand);
|
||||
|
||||
// check if the pro
|
||||
if (deleteProcess.isAlive())
|
||||
{
|
||||
Files.move(newFileLocation.toPath(), JarUtils.jarFile.getParentFile().toPath().resolve(newFileLocation.getName()));
|
||||
Files.delete(newFileLocation.getParentFile().toPath());
|
||||
LOGGER.info(DeleteOnUnlock.class.getSimpleName()+" process started...");
|
||||
}
|
||||
catch (Exception e)
|
||||
else
|
||||
{
|
||||
LOGGER.warn("Failed to move updated fire from [" + newFileLocation.getAbsolutePath() + "] to [" + JarUtils.jarFile.getParentFile().getAbsolutePath() + "], please move it manually");
|
||||
e.printStackTrace();
|
||||
LOGGER.error(DeleteOnUnlock.class.getSimpleName()+" process failed to start.");
|
||||
}
|
||||
try
|
||||
|
||||
// wait a moment so we can catch if there are any immediate issues with the process
|
||||
Thread.sleep(250);
|
||||
|
||||
if (deleteProcess.isAlive())
|
||||
{
|
||||
if (EPlatform.get() != EPlatform.WINDOWS)
|
||||
LOGGER.info(DeleteOnUnlock.class.getSimpleName()+" running, old jar file at ["+JarUtils.jarFile.getAbsolutePath()+"] should be deleted after Minecraft's JVM shutdown has completed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
int processExitCode = deleteProcess.exitValue();
|
||||
if (processExitCode != DeleteOnUnlock.SUCCESS_EXIT_CODE)
|
||||
{
|
||||
Files.delete(JarUtils.jarFile.toPath());
|
||||
String failReason = (processExitCode == DeleteOnUnlock.FAIL_EXIT_CODE) ? "Timed out and was unable to delete the file." : "Ran into an unexpected error.";
|
||||
LOGGER.error(DeleteOnUnlock.class.getSimpleName() + " " + failReason);
|
||||
LOGGER.error(DeleteOnUnlock.class.getSimpleName() + " Logs are listed below:");
|
||||
|
||||
// record the process' logs
|
||||
String normalOutput = convertInputStreamToString(deleteProcess.getInputStream());
|
||||
LOGGER.info("process output: \n\n" + normalOutput);
|
||||
|
||||
// record the process' error logs
|
||||
String errorOutput = convertInputStreamToString(deleteProcess.getInputStream());
|
||||
LOGGER.error("process error output: \n\n" + errorOutput);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Gets the Java binary
|
||||
String javaHome = System.getProperty("java.home");
|
||||
String javaBin = javaHome + File.separator + "bin" + File.separator + "java";
|
||||
|
||||
// Execute the new jar, to delete the old jar once it detects the lock has been lifted
|
||||
Runtime.getRuntime().exec(
|
||||
"\""+ javaBin +"\" -cp \""+
|
||||
newFileLocation.getAbsolutePath()
|
||||
+"\" "+
|
||||
DeleteOnUnlock.class.getCanonicalName()
|
||||
+" "+
|
||||
URLEncoder.encode(JarUtils.jarFile.getAbsolutePath(), "UTF-8") // Encode the file location so that it doesnt have any spaces
|
||||
);
|
||||
LOGGER.info(DeleteOnUnlock.class.getSimpleName() + " completed before JVM shutdown.");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.warn("Failed to delete previous " + ModInfo.READABLE_NAME + " file, please delete it manually at [" + JarUtils.jarFile + "]");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.warn("Failed to delete previous " + ModInfo.READABLE_NAME + " file, please delete it manually at [" + JarUtils.jarFile + "]", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String convertInputStreamToString(InputStream inputStream)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] bytes = new byte[inputStream.available()];
|
||||
DataInputStream dataInputStream = new DataInputStream(inputStream);
|
||||
dataInputStream.readFully(bytes);
|
||||
return new String(bytes);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
return e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -79,15 +79,21 @@ public class ClientLevelModule implements Closeable
|
||||
}
|
||||
// TODO this should probably be handled via a config change listener
|
||||
// recreate the RenderState if the render distance changes
|
||||
if (clientRenderState.quadtree.blockRenderDistanceRadius != Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH)
|
||||
if (clientRenderState.quadtree.blockRenderDistanceDiameter != Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius.get() * LodUtil.CHUNK_WIDTH * 2)
|
||||
{
|
||||
if (!this.ClientRenderStateRef.compareAndSet(clientRenderState, null))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IClientLevelWrapper clientLevelWrapper = this.parentClientLevel.getClientLevelWrapper();
|
||||
if (clientLevelWrapper == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
clientRenderState.close();
|
||||
clientRenderState = new ClientRenderState(parentClientLevel, parentClientLevel.getFileHandler(), parentClientLevel.getSaveStructure());
|
||||
clientRenderState = new ClientRenderState(this.parentClientLevel, clientLevelWrapper, this.parentClientLevel.getFileHandler(), this.parentClientLevel.getSaveStructure());
|
||||
if (!this.ClientRenderStateRef.compareAndSet(null, clientRenderState))
|
||||
{
|
||||
//FIXME: How to handle this?
|
||||
@@ -117,9 +123,9 @@ public class ClientLevelModule implements Closeable
|
||||
//========//
|
||||
|
||||
/** @return if the {@link ClientRenderState} was successfully swapped */
|
||||
public boolean startRenderer()
|
||||
public boolean startRenderer(IClientLevelWrapper clientLevelWrapper)
|
||||
{
|
||||
ClientRenderState ClientRenderState = new ClientRenderState(parentClientLevel, parentClientLevel.getFileHandler(), parentClientLevel.getSaveStructure());
|
||||
ClientRenderState ClientRenderState = new ClientRenderState(parentClientLevel, clientLevelWrapper, parentClientLevel.getFileHandler(), parentClientLevel.getSaveStructure());
|
||||
if (!this.ClientRenderStateRef.compareAndSet(null, ClientRenderState))
|
||||
{
|
||||
LOGGER.warn("Failed to start renderer due to concurrency");
|
||||
@@ -280,13 +286,13 @@ public class ClientLevelModule implements Closeable
|
||||
public final LodRenderer renderer;
|
||||
|
||||
public ClientRenderState(
|
||||
IDhClientLevel dhClientLevel, IFullDataSourceProvider fullDataSourceProvider,
|
||||
IDhClientLevel dhClientLevel, IClientLevelWrapper clientLevelWrapper, IFullDataSourceProvider fullDataSourceProvider,
|
||||
AbstractSaveStructure saveStructure)
|
||||
{
|
||||
this.clientLevelWrapper = dhClientLevel.getClientLevelWrapper();
|
||||
this.clientLevelWrapper = clientLevelWrapper;
|
||||
this.renderSourceFileHandler = new RenderSourceFileHandler(fullDataSourceProvider, dhClientLevel, saveStructure);
|
||||
|
||||
this.quadtree = new LodQuadTree(dhClientLevel, Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH,
|
||||
this.quadtree = new LodQuadTree(dhClientLevel, Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius.get() * LodUtil.CHUNK_WIDTH * 2,
|
||||
// initial position is (0,0) just in case the player hasn't loaded in yet, the tree will be moved once the level starts ticking
|
||||
0, 0,
|
||||
this.renderSourceFileHandler);
|
||||
|
||||
@@ -64,7 +64,7 @@ public class DhClientLevel extends DhLevel implements IDhClientLevel
|
||||
|
||||
if (enableRendering)
|
||||
{
|
||||
this.clientside.startRenderer();
|
||||
this.clientside.startRenderer(clientLevelWrapper);
|
||||
LOGGER.info("Started DHLevel for " + this.levelWrapper + " with saves at " + this.saveStructure);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,10 +120,7 @@ public class DhClientServerLevel extends DhLevel implements IDhClientLevel, IDhS
|
||||
// render //
|
||||
//========//
|
||||
|
||||
public void startRenderer(IClientLevelWrapper clientLevel)
|
||||
{
|
||||
clientside.startRenderer();
|
||||
}
|
||||
public void startRenderer(IClientLevelWrapper clientLevel) { this.clientside.startRenderer(clientLevel); }
|
||||
|
||||
public void stopRenderer() { this.clientside.stopRenderer(); }
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ public class LodQuadTree extends QuadTree<LodRenderSection> implements AutoClose
|
||||
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
|
||||
public final int blockRenderDistanceRadius;
|
||||
public final int blockRenderDistanceDiameter;
|
||||
private final IRenderSourceProvider renderSourceProvider;
|
||||
|
||||
/**
|
||||
@@ -77,15 +77,15 @@ public class LodQuadTree extends QuadTree<LodRenderSection> implements AutoClose
|
||||
//==============//
|
||||
|
||||
public LodQuadTree(
|
||||
IDhClientLevel level, int viewDistanceInBlocks,
|
||||
IDhClientLevel level, int viewDiameterInBlocks,
|
||||
int initialPlayerBlockX, int initialPlayerBlockZ,
|
||||
IRenderSourceProvider provider)
|
||||
{
|
||||
super(viewDistanceInBlocks, new DhBlockPos2D(initialPlayerBlockX, initialPlayerBlockZ), TREE_LOWEST_DETAIL_LEVEL);
|
||||
super(viewDiameterInBlocks, new DhBlockPos2D(initialPlayerBlockX, initialPlayerBlockZ), TREE_LOWEST_DETAIL_LEVEL);
|
||||
|
||||
this.level = level;
|
||||
this.renderSourceProvider = provider;
|
||||
this.blockRenderDistanceRadius = viewDistanceInBlocks;
|
||||
this.blockRenderDistanceDiameter = viewDiameterInBlocks;
|
||||
|
||||
this.horizontalScaleChangeListener = new ConfigChangeListener<>(Config.Client.Advanced.Graphics.Quality.horizontalQuality, (newHorizontalScale) -> this.onHorizontalQualityChange());
|
||||
}
|
||||
@@ -364,7 +364,7 @@ public class LodQuadTree extends QuadTree<LodRenderSection> implements AutoClose
|
||||
}
|
||||
else if (detail >= Byte.MAX_VALUE)
|
||||
{
|
||||
return this.blockRenderDistanceRadius * 2;
|
||||
return this.blockRenderDistanceDiameter * 2;
|
||||
}
|
||||
|
||||
|
||||
@@ -381,7 +381,7 @@ public class LodQuadTree extends QuadTree<LodRenderSection> implements AutoClose
|
||||
|
||||
// The minimum detail level is done to prevent single corner sections rendering 1 detail level lower than the others.
|
||||
// If not done corners may not be flush with the other LODs, which looks bad.
|
||||
byte minSectionDetailLevel = this.getDetailLevelFromDistance(this.blockRenderDistanceRadius); // get the minimum allowed detail level
|
||||
byte minSectionDetailLevel = this.getDetailLevelFromDistance(this.blockRenderDistanceDiameter); // get the minimum allowed detail level
|
||||
minSectionDetailLevel -= 1; // -1 so corners can't render lower than their adjacent neighbors. space
|
||||
minSectionDetailLevel = (byte) Math.min(minSectionDetailLevel, this.treeMinDetailLevel); // don't allow rendering lower detail sections than what the tree contains
|
||||
this.minRenderDetailLevel = (byte) Math.max(minSectionDetailLevel, this.maxRenderDetailLevel); // respect the user's selected max resolution if it is lower detail (IE they want 2x2 block, but minSectionDetailLevel is specifically for 1x1 block render resolution)
|
||||
|
||||
@@ -171,7 +171,20 @@ public class GLProxy
|
||||
long potentialLodBuilderGlContext = 0;
|
||||
GLCapabilities potentialLodBuilderGlCapabilities = null;
|
||||
|
||||
for (Pair<Integer, Integer> supportedGlVersion : SUPPORTED_GL_VERSIONS)
|
||||
int majorGlVersion = Config.Client.Advanced.Debugging.OpenGl.glContextMajorVersion.get();
|
||||
int minorGlVersion = Config.Client.Advanced.Debugging.OpenGl.glContextMinorVersion.get();
|
||||
|
||||
ArrayList<Pair<Integer, Integer>> glVersions = new ArrayList<>();
|
||||
if (majorGlVersion != 0)
|
||||
{
|
||||
glVersions.add(new Pair<>(majorGlVersion, minorGlVersion));
|
||||
}
|
||||
else
|
||||
{
|
||||
glVersions.addAll(SUPPORTED_GL_VERSIONS);
|
||||
}
|
||||
|
||||
for (Pair<Integer, Integer> supportedGlVersion : glVersions)
|
||||
{
|
||||
int glMajorVersion = supportedGlVersion.first;
|
||||
int glMinorVersion = supportedGlVersion.second;
|
||||
@@ -193,8 +206,8 @@ public class GLProxy
|
||||
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, glMajorVersion);
|
||||
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, glMinorVersion);
|
||||
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_DEBUG_CONTEXT, debugContextEnabled ? GLFW.GLFW_TRUE : GLFW.GLFW_FALSE);
|
||||
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_FORWARD_COMPAT, forwardCompatEnabled ? GLFW.GLFW_TRUE : GLFW.GLFW_FALSE);
|
||||
|
||||
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_FORWARD_COMPAT, forwardCompatEnabled ? GLFW.GLFW_TRUE : GLFW.GLFW_FALSE);
|
||||
int profileModeInt;
|
||||
EGlProfileMode profileModeEnum = Config.Client.Advanced.Debugging.OpenGl.glProfileMode.get();
|
||||
switch (profileModeEnum)
|
||||
@@ -215,15 +228,15 @@ public class GLProxy
|
||||
contextCreateErrorMessage =
|
||||
"Failed to create OpenGL GLFW context for OpenGL Version: [" + glMajorVersion + "." + glMinorVersion + "] \n" +
|
||||
"with Debugging: [" + (debugContextEnabled ? "Enabled" : "Disabled") + "], \n" +
|
||||
"Forward Compatibility: [" + (forwardCompatEnabled ? "Enabled" : "Disabled") + "], \n" +
|
||||
"Forward Compatibility: [" + (true ? "Enabled" : "Disabled") + "], \n" +
|
||||
"and Profile: [" + profileModeEnum.name() + "]. ";
|
||||
|
||||
|
||||
// try creating the Lod Builder context
|
||||
potentialLodBuilderGlContext = GLFW.glfwCreateWindow(1, 1, "LOD Builder Window", 0L, this.minecraftGlContext);
|
||||
potentialLodBuilderGlContext = GLFW.glfwCreateWindow(64, 64, "LOD Builder Window", 0L, this.minecraftGlContext);
|
||||
if (potentialLodBuilderGlContext == 0)
|
||||
{
|
||||
GL_LOGGER.debug(contextCreateErrorMessage);
|
||||
GL_LOGGER.info(contextCreateErrorMessage);
|
||||
GL_LOGGER.debug("Minecraft GL Capabilities:\n [\n" + ReflectionUtil.getAllFieldValuesAsString(this.minecraftGlCapabilities) + "\n]\n");
|
||||
|
||||
continue;
|
||||
|
||||
@@ -21,6 +21,7 @@ package com.seibel.distanthorizons.core.render.glObject;
|
||||
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
// TODO make this Closable or AutoClosable so it can be used with try-resource blocks
|
||||
public class GLState
|
||||
{
|
||||
private static final int FBO_MAX = 4;
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ public class LightmapTexture
|
||||
MC.sendChatMessage(same + " " + badIndex);
|
||||
*/
|
||||
// comment this line out to prevent uploading the new lightmap
|
||||
GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, GL32.GL_RGBA, lightMapWidth * lightMapHeight,
|
||||
GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, GL32.GL_RGBA8, lightMapWidth * lightMapHeight,
|
||||
1, 0, GL32.GL_RGBA, GL32.GL_UNSIGNED_BYTE, pixels);
|
||||
GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_WRAP_S, GL32.GL_CLAMP_TO_BORDER);
|
||||
GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_WRAP_T, GL32.GL_CLAMP_TO_BORDER);
|
||||
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.core.render.glObject.vertexAttribute;
|
||||
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
/**
|
||||
* Base for binding/unbinding Vertex Attribute objects (VAO's).
|
||||
*
|
||||
* @see VertexAttributePostGL43
|
||||
* @see VertexAttributePreGL43
|
||||
*/
|
||||
public abstract class AbstractVertexAttribute
|
||||
{
|
||||
/** Stores the handle of the AbstractVertexAttribute. */
|
||||
public final int id;
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// constructors //
|
||||
//==============//
|
||||
|
||||
// This will bind AbstractVertexAttribute
|
||||
protected AbstractVertexAttribute()
|
||||
{
|
||||
this.id = GL32.glGenVertexArrays();
|
||||
GL32.glBindVertexArray(this.id);
|
||||
}
|
||||
|
||||
public static AbstractVertexAttribute create()
|
||||
{
|
||||
if (GLProxy.getInstance().VertexAttributeBufferBindingSupported)
|
||||
{
|
||||
return new VertexAttributePostGL43();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new VertexAttributePreGL43();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// binding //
|
||||
//=========//
|
||||
|
||||
public void bind() { GL32.glBindVertexArray(this.id); }
|
||||
public void unbind() { GL32.glBindVertexArray(0); }
|
||||
|
||||
/** Always remember to always free your resources! */
|
||||
public void free() { GL32.glDeleteVertexArrays(this.id); }
|
||||
|
||||
|
||||
|
||||
//==================//
|
||||
// abstract methods //
|
||||
//==================//
|
||||
|
||||
/** Requires both AbstractVertexAttribute and VertexBuffer to be bound */
|
||||
public abstract void bindBufferToAllBindingPoints(int buffer);
|
||||
/** Requires both AbstractVertexAttribute and VertexBuffer to be bound */
|
||||
public abstract void bindBufferToBindingPoint(int buffer, int bindingPoint);
|
||||
/** Requires both AbstractVertexAttribute to be bound */
|
||||
public abstract void unbindBuffersFromAllBindingPoint();
|
||||
/** Requires both AbstractVertexAttribute to be bound */
|
||||
public abstract void unbindBuffersFromBindingPoint(int bindingPoint);
|
||||
/** Requires both AbstractVertexAttribute to be bound */
|
||||
public abstract void setVertexAttribute(int bindingPoint, int attributeIndex, VertexPointer attribute);
|
||||
/** Requires both AbstractVertexAttribute to be bound */
|
||||
public abstract void completeAndCheck(int expectedStrideSize);
|
||||
|
||||
}
|
||||
-158
@@ -1,158 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.core.render.glObject.vertexAttribute;
|
||||
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
|
||||
import com.seibel.distanthorizons.coreapi.util.MathUtil;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
public abstract class VertexAttribute
|
||||
{
|
||||
|
||||
public static final class VertexPointer
|
||||
{
|
||||
public final int elementCount;
|
||||
public final int glType;
|
||||
public final boolean normalized;
|
||||
public final int byteSize;
|
||||
public final boolean useInteger;
|
||||
public VertexPointer(int elementCount, int glType, boolean normalized, int byteSize, boolean useInteger)
|
||||
{
|
||||
this.elementCount = elementCount;
|
||||
this.glType = glType;
|
||||
this.normalized = normalized;
|
||||
this.byteSize = byteSize;
|
||||
this.useInteger = useInteger;
|
||||
}
|
||||
public VertexPointer(int elementCount, int glType, boolean normalized, int byteSize)
|
||||
{
|
||||
this(elementCount, glType, normalized, byteSize, false);
|
||||
}
|
||||
private static int _align(int bytes)
|
||||
{
|
||||
return MathUtil.ceilDiv(bytes, 4) * 4;
|
||||
}
|
||||
|
||||
public static VertexPointer addFloatPointer(boolean normalized)
|
||||
{
|
||||
return new VertexPointer(1, GL32.GL_FLOAT, normalized, 4);
|
||||
}
|
||||
public static VertexPointer addVec2Pointer(boolean normalized)
|
||||
{
|
||||
return new VertexPointer(2, GL32.GL_FLOAT, normalized, 8);
|
||||
}
|
||||
public static VertexPointer addVec3Pointer(boolean normalized)
|
||||
{
|
||||
return new VertexPointer(3, GL32.GL_FLOAT, normalized, 12);
|
||||
}
|
||||
public static VertexPointer addVec4Pointer(boolean normalized)
|
||||
{
|
||||
return new VertexPointer(4, GL32.GL_FLOAT, normalized, 16);
|
||||
}
|
||||
public static VertexPointer addUnsignedBytePointer(boolean normalized, boolean useInteger)
|
||||
{
|
||||
return new VertexPointer(1, GL32.GL_UNSIGNED_BYTE, normalized, 4, useInteger); // Always aligned to 4 bytes
|
||||
}
|
||||
public static VertexPointer addUnsignedBytesPointer(int elementCount, boolean normalized, boolean useInteger)
|
||||
{
|
||||
return new VertexPointer(elementCount, GL32.GL_UNSIGNED_BYTE, normalized, _align(elementCount), useInteger); // aligned to 4 bytes
|
||||
}
|
||||
public static VertexPointer addUnsignedShortsPointer(int elementCount, boolean normalized, boolean useInteger)
|
||||
{
|
||||
return new VertexPointer(elementCount, GL32.GL_UNSIGNED_SHORT, normalized, _align(elementCount * 2), useInteger);
|
||||
}
|
||||
public static VertexPointer addShortsPointer(int elementCount, boolean normalized, boolean useInteger)
|
||||
{
|
||||
return new VertexPointer(elementCount, GL32.GL_SHORT, normalized, _align(elementCount * 2), useInteger);
|
||||
}
|
||||
public static VertexPointer addIntPointer(boolean normalized, boolean useInteger)
|
||||
{
|
||||
return new VertexPointer(1, GL32.GL_INT, normalized, 4, useInteger);
|
||||
}
|
||||
public static VertexPointer addIvec2Pointer(boolean normalized, boolean useInteger)
|
||||
{
|
||||
return new VertexPointer(2, GL32.GL_INT, normalized, 8, useInteger);
|
||||
}
|
||||
public static VertexPointer addIvec3Pointer(boolean normalized, boolean useInteger)
|
||||
{
|
||||
return new VertexPointer(3, GL32.GL_INT, normalized, 12, useInteger);
|
||||
}
|
||||
public static VertexPointer addIvec4Pointer(boolean normalized, boolean useInteger)
|
||||
{
|
||||
return new VertexPointer(4, GL32.GL_INT, normalized, 16, useInteger);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** Stores the handle of the VertexAttribute. */
|
||||
public final int id;
|
||||
|
||||
// This will bind VertexAttribute
|
||||
protected VertexAttribute()
|
||||
{
|
||||
id = GL32.glGenVertexArrays();
|
||||
GL32.glBindVertexArray(id);
|
||||
}
|
||||
|
||||
public static VertexAttribute create()
|
||||
{
|
||||
if (GLProxy.getInstance().VertexAttributeBufferBindingSupported)
|
||||
{
|
||||
return new VertexAttributePostGL43();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new VertexAttributePreGL43();
|
||||
}
|
||||
}
|
||||
|
||||
// This will bind VertexAttribute
|
||||
public void bind()
|
||||
{
|
||||
GL32.glBindVertexArray(id);
|
||||
}
|
||||
|
||||
// This will unbind VertexAttribute
|
||||
public void unbind()
|
||||
{
|
||||
GL32.glBindVertexArray(0);
|
||||
}
|
||||
|
||||
// REMEMBER to always free the resource!
|
||||
public void free()
|
||||
{
|
||||
GL32.glDeleteVertexArrays(id);
|
||||
}
|
||||
|
||||
// Requires VertexAttribute binded, VertexBuffer binded
|
||||
public abstract void bindBufferToAllBindingPoint(int buffer);
|
||||
// Requires VertexAttribute binded, VertexBuffer binded
|
||||
public abstract void bindBufferToBindingPoint(int buffer, int bindingPoint);
|
||||
// Requires VertexAttribute binded
|
||||
public abstract void unbindBuffersFromAllBindingPoint();
|
||||
// Requires VertexAttribute binded
|
||||
public abstract void unbindBuffersFromBindingPoint(int bindingPoint);
|
||||
// Requires VertexAttribute binded
|
||||
public abstract void setVertexAttribute(int bindingPoint, int attributeIndex, VertexPointer attribute);
|
||||
// Requires VertexAttribute binded
|
||||
public abstract void completeAndCheck(int expectedStrideSize);
|
||||
|
||||
}
|
||||
+70
-31
@@ -22,87 +22,126 @@ package com.seibel.distanthorizons.core.render.glObject.vertexAttribute;
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
|
||||
import org.lwjgl.opengl.GL43;
|
||||
|
||||
// In OpenGL 4.3 and later, Vertex Attribute got a make-over.
|
||||
// Now it provides support for buffer binding points natively.
|
||||
// This means that setting up the VAO just use ONE native call when
|
||||
// binding to a buffer.
|
||||
//
|
||||
// Since I no longer needs to implement binding points, I also no
|
||||
// longer needs to keep track of Pointers.
|
||||
|
||||
public final class VertexAttributePostGL43 extends VertexAttribute
|
||||
/**
|
||||
* In OpenGL 4.3 and later, Vertex Attribute got a make-over.
|
||||
* Now it provides support for buffer binding points natively.
|
||||
* This means that setting up the VAO is just use ONE native call when
|
||||
* binding to a buffer. <br><br>
|
||||
*
|
||||
* Since I no longer need to implement binding points, I also no
|
||||
* longer needs to keep track of Pointers.
|
||||
*/
|
||||
public final class VertexAttributePostGL43 extends AbstractVertexAttribute
|
||||
{
|
||||
|
||||
int numberOfBindingPoints = 0;
|
||||
int strideSize = 0;
|
||||
|
||||
// This will bind VertexAttribute
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
/** This will bind the {@link AbstractVertexAttribute} */
|
||||
public VertexAttributePostGL43()
|
||||
{
|
||||
super(); // also bind VertexAttribute
|
||||
super(); // also bind AbstractVertexAttribute
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// binding //
|
||||
//=========//
|
||||
|
||||
/** Requires both AbstractVertexAttribute and VertexBuffer to be bound */
|
||||
@Override
|
||||
// Requires VertexAttribute binded, VertexBuffer binded
|
||||
public void bindBufferToAllBindingPoint(int buffer)
|
||||
public void bindBufferToAllBindingPoints(int buffer)
|
||||
{
|
||||
for (int i = 0; i < numberOfBindingPoints; i++)
|
||||
for (int i = 0; i < this.numberOfBindingPoints; i++)
|
||||
{
|
||||
GL43.glBindVertexBuffer(i, buffer, 0, strideSize);
|
||||
GL43.glBindVertexBuffer(i, buffer, 0, this.strideSize);
|
||||
}
|
||||
}
|
||||
|
||||
/** Requires both AbstractVertexAttribute and VertexBuffer to be bound */
|
||||
@Override
|
||||
// Requires VertexAttribute binded, VertexBuffer binded
|
||||
public void bindBufferToBindingPoint(int buffer, int bindingPoint)
|
||||
{
|
||||
GL43.glBindVertexBuffer(bindingPoint, buffer, 0, strideSize);
|
||||
GL43.glBindVertexBuffer(bindingPoint, buffer, 0, this.strideSize);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===========//
|
||||
// unbinding //
|
||||
//===========//
|
||||
|
||||
/** Requires AbstractVertexAttribute to be bound */
|
||||
@Override
|
||||
// Requires VertexAttribute binded
|
||||
public void unbindBuffersFromAllBindingPoint()
|
||||
{
|
||||
for (int i = 0; i < numberOfBindingPoints; i++)
|
||||
for (int i = 0; i < this.numberOfBindingPoints; i++)
|
||||
{
|
||||
GL43.glBindVertexBuffer(i, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/** Requires AbstractVertexAttribute to be bound */
|
||||
@Override
|
||||
// Requires VertexAttribute binded
|
||||
public void unbindBuffersFromBindingPoint(int bindingPoint)
|
||||
{
|
||||
GL43.glBindVertexBuffer(bindingPoint, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==========================//
|
||||
// manual attribute setting //
|
||||
//==========================//
|
||||
|
||||
/** Requires AbstractVertexAttribute to be bound */
|
||||
@Override
|
||||
// Requires VertexAttribute binded
|
||||
public void setVertexAttribute(int bindingPoint, int attributeIndex, VertexPointer attribute)
|
||||
{
|
||||
if (attribute.useInteger)
|
||||
GL43.glVertexAttribIFormat(attributeIndex, attribute.elementCount, attribute.glType, strideSize);
|
||||
{
|
||||
GL43.glVertexAttribIFormat(attributeIndex, attribute.elementCount, attribute.glType, this.strideSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL43.glVertexAttribFormat(attributeIndex, attribute.elementCount, attribute.glType,
|
||||
attribute.normalized, strideSize); // Here strideSize is new attrib offset
|
||||
strideSize += attribute.byteSize;
|
||||
if (numberOfBindingPoints <= bindingPoint) numberOfBindingPoints = bindingPoint + 1;
|
||||
attribute.normalized, this.strideSize); // Here strideSize is new attrib offset
|
||||
}
|
||||
|
||||
this.strideSize += attribute.byteSize;
|
||||
if (this.numberOfBindingPoints <= bindingPoint)
|
||||
{
|
||||
this.numberOfBindingPoints = bindingPoint + 1;
|
||||
}
|
||||
GL43.glVertexAttribBinding(attributeIndex, bindingPoint);
|
||||
GL43.glEnableVertexAttribArray(attributeIndex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//============//
|
||||
// validation //
|
||||
//============//
|
||||
|
||||
/** Requires AbstractVertexAttribute to be bound */
|
||||
@Override
|
||||
// Requires VertexAttribute binded
|
||||
public void completeAndCheck(int expectedStrideSize)
|
||||
{
|
||||
if (strideSize != expectedStrideSize)
|
||||
if (this.strideSize != expectedStrideSize)
|
||||
{
|
||||
GLProxy.GL_LOGGER.error("Vertex Attribute calculated stride size " + strideSize +
|
||||
GLProxy.GL_LOGGER.error("Vertex Attribute calculated stride size " + this.strideSize +
|
||||
" does not match the provided expected stride size " + expectedStrideSize + "!");
|
||||
throw new IllegalArgumentException("Vertex Attribute Incorrect Format");
|
||||
}
|
||||
GLProxy.GL_LOGGER.info("Vertex Attribute (GL43+) completed. It contains " + numberOfBindingPoints
|
||||
+ " binding points and a stride size of " + strideSize);
|
||||
|
||||
GLProxy.GL_LOGGER.info("Vertex Attribute (GL43+) completed. It contains " + this.numberOfBindingPoints
|
||||
+ " binding points and a stride size of " + this.strideSize);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+109
-59
@@ -28,11 +28,10 @@ import com.seibel.distanthorizons.core.render.glObject.GLProxy;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
|
||||
public final class VertexAttributePreGL43 extends VertexAttribute
|
||||
public final class VertexAttributePreGL43 extends AbstractVertexAttribute
|
||||
{
|
||||
|
||||
// I tried to use as much raw arrays as possible as those lookups
|
||||
// happens every frame, and the speed directly effects fps
|
||||
// I tried to use raw arrays as much as possible since those lookups
|
||||
// happen every frame, and the speed directly affects fps
|
||||
int strideSize = 0;
|
||||
int[][] bindingPointsToIndex;
|
||||
VertexPointer[] pointers;
|
||||
@@ -41,153 +40,204 @@ public final class VertexAttributePreGL43 extends VertexAttribute
|
||||
TreeMap<Integer, TreeSet<Integer>> bindingPointsToIndexBuilder;
|
||||
ArrayList<VertexPointer> pointersBuilder;
|
||||
|
||||
// This will bind VertexAttribute
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
/** This will bind the {@link AbstractVertexAttribute} */
|
||||
public VertexAttributePreGL43()
|
||||
{
|
||||
super(); // also bind VertexAttribute
|
||||
bindingPointsToIndexBuilder = new TreeMap<Integer, TreeSet<Integer>>();
|
||||
pointersBuilder = new ArrayList<VertexPointer>();
|
||||
super(); // also bind AbstractVertexAttribute
|
||||
this.bindingPointsToIndexBuilder = new TreeMap<>();
|
||||
this.pointersBuilder = new ArrayList<>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// binding //
|
||||
//=========//
|
||||
|
||||
/** Requires both AbstractVertexAttribute and VertexBuffer to be bound */
|
||||
@Override
|
||||
// Requires VertexAttribute binded, VertexBuffer binded
|
||||
public void bindBufferToAllBindingPoint(int buffer)
|
||||
public void bindBufferToAllBindingPoints(int buffer)
|
||||
{
|
||||
for (int i = 0; i < pointers.length; i++)
|
||||
for (int i = 0; i < this.pointers.length; i++)
|
||||
{
|
||||
GL32.glEnableVertexAttribArray(i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < pointers.length; i++)
|
||||
for (int i = 0; i < this.pointers.length; i++)
|
||||
{
|
||||
VertexPointer pointer = pointers[i];
|
||||
if (pointer == null) continue;
|
||||
VertexPointer pointer = this.pointers[i];
|
||||
if (pointer == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pointer.useInteger)
|
||||
{
|
||||
GL32.glVertexAttribIPointer(i, pointer.elementCount, pointer.glType,
|
||||
strideSize, pointersOffset[i]);
|
||||
else GL32.glVertexAttribPointer(i, pointer.elementCount, pointer.glType,
|
||||
pointer.normalized, strideSize, pointersOffset[i]);
|
||||
this.strideSize, this.pointersOffset[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL32.glVertexAttribPointer(i, pointer.elementCount, pointer.glType,
|
||||
pointer.normalized, this.strideSize, this.pointersOffset[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Requires both AbstractVertexAttribute and VertexBuffer to be bound */
|
||||
@Override
|
||||
// Requires VertexAttribute binded, VertexBuffer binded
|
||||
public void bindBufferToBindingPoint(int buffer, int bindingPoint)
|
||||
{
|
||||
int[] toBind = bindingPointsToIndex[bindingPoint];
|
||||
int[] bindingPointIndexes = this.bindingPointsToIndex[bindingPoint];
|
||||
|
||||
for (int k : toBind)
|
||||
for (int bindingPointIndex : bindingPointIndexes)
|
||||
{
|
||||
GL32.glEnableVertexAttribArray(k);
|
||||
GL32.glEnableVertexAttribArray(bindingPointIndex);
|
||||
}
|
||||
|
||||
for (int j : toBind)
|
||||
for (int bindingPointIndex : bindingPointIndexes)
|
||||
{
|
||||
VertexPointer pointer = pointers[j];
|
||||
VertexPointer pointer = this.pointers[bindingPointIndex];
|
||||
if (pointer == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pointer.useInteger)
|
||||
GL32.glVertexAttribIPointer(j, pointer.elementCount, pointer.glType,
|
||||
strideSize, pointersOffset[j]);
|
||||
else GL32.glVertexAttribPointer(j, pointer.elementCount, pointer.glType,
|
||||
pointer.normalized, strideSize, pointersOffset[j]);
|
||||
{
|
||||
GL32.glVertexAttribIPointer(bindingPointIndex, pointer.elementCount, pointer.glType,
|
||||
this.strideSize, this.pointersOffset[bindingPointIndex]);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL32.glVertexAttribPointer(bindingPointIndex, pointer.elementCount, pointer.glType,
|
||||
pointer.normalized, this.strideSize, this.pointersOffset[bindingPointIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===========//
|
||||
// unbinding //
|
||||
//===========//
|
||||
|
||||
/** Requires AbstractVertexAttribute to be bound */
|
||||
@Override
|
||||
// Requires VertexAttribute binded
|
||||
public void unbindBuffersFromAllBindingPoint()
|
||||
{
|
||||
for (int i = 0; i < pointers.length; i++)
|
||||
for (int i = 0; i < this.pointers.length; i++)
|
||||
{
|
||||
GL32.glDisableVertexAttribArray(i);
|
||||
}
|
||||
}
|
||||
|
||||
/** Requires AbstractVertexAttribute to be bound */
|
||||
@Override
|
||||
// Requires VertexAttribute binded
|
||||
public void unbindBuffersFromBindingPoint(int bindingPoint)
|
||||
{
|
||||
int[] toBind = bindingPointsToIndex[bindingPoint];
|
||||
|
||||
for (int j : toBind)
|
||||
int[] bindingPointIndexes = this.bindingPointsToIndex[bindingPoint];
|
||||
for (int bindingPointIndex : bindingPointIndexes)
|
||||
{
|
||||
GL32.glDisableVertexAttribArray(j);
|
||||
GL32.glDisableVertexAttribArray(bindingPointIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==========================//
|
||||
// manual attribute setting //
|
||||
//==========================//
|
||||
|
||||
/** Requires AbstractVertexAttribute to be bound */
|
||||
@Override
|
||||
// Requires VertexAttribute binded
|
||||
public void setVertexAttribute(int bindingPoint, int attributeIndex, VertexPointer attribute)
|
||||
{
|
||||
TreeSet<Integer> intArray = bindingPointsToIndexBuilder.computeIfAbsent(bindingPoint, k -> new TreeSet<Integer>());
|
||||
TreeSet<Integer> intArray = this.bindingPointsToIndexBuilder.computeIfAbsent(bindingPoint, k -> new TreeSet<>());
|
||||
intArray.add(attributeIndex);
|
||||
|
||||
while (pointersBuilder.size() <= attributeIndex)
|
||||
while (this.pointersBuilder.size() <= attributeIndex)
|
||||
{
|
||||
// This is dumb, but ArrayList doesn't have a resize, And this code
|
||||
// should only be ran when it's building the Vertex Attribute anyways.
|
||||
pointersBuilder.add(null);
|
||||
// should only be run when it's building the Vertex Attribute anyway.
|
||||
this.pointersBuilder.add(null);
|
||||
}
|
||||
pointersBuilder.set(attributeIndex, attribute);
|
||||
this.pointersBuilder.set(attributeIndex, attribute);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//============//
|
||||
// validation //
|
||||
//============//
|
||||
|
||||
/** Requires AbstractVertexAttribute to be bound */
|
||||
@Override
|
||||
// Requires VertexAttribute binded
|
||||
public void completeAndCheck(int expectedStrideSize)
|
||||
{
|
||||
int maxBindPointNumber = bindingPointsToIndexBuilder.lastKey();
|
||||
bindingPointsToIndex = new int[maxBindPointNumber + 1][];
|
||||
int maxBindPointNumber = this.bindingPointsToIndexBuilder.lastKey();
|
||||
this.bindingPointsToIndex = new int[maxBindPointNumber + 1][];
|
||||
|
||||
bindingPointsToIndexBuilder.forEach((Integer i, TreeSet<Integer> set) -> {
|
||||
bindingPointsToIndex[i] = new int[set.size()];
|
||||
this.bindingPointsToIndexBuilder.forEach((Integer i, TreeSet<Integer> set) ->
|
||||
{
|
||||
this.bindingPointsToIndex[i] = new int[set.size()];
|
||||
Iterator<Integer> iter = set.iterator();
|
||||
for (int j = 0; j < set.size(); j++)
|
||||
{
|
||||
bindingPointsToIndex[i][j] = iter.next();
|
||||
this.bindingPointsToIndex[i][j] = iter.next();
|
||||
}
|
||||
});
|
||||
|
||||
pointers = pointersBuilder.toArray(new VertexPointer[pointersBuilder.size()]);
|
||||
pointersOffset = new int[pointers.length];
|
||||
pointersBuilder = null; // Release the builder
|
||||
bindingPointsToIndexBuilder = null; // Release the builder
|
||||
this.pointers = this.pointersBuilder.toArray(new VertexPointer[this.pointersBuilder.size()]);
|
||||
this.pointersOffset = new int[this.pointers.length];
|
||||
this.pointersBuilder = null; // Release the builder
|
||||
this.bindingPointsToIndexBuilder = null; // Release the builder
|
||||
|
||||
// Check if all pointers are valid
|
||||
int currentOffset = 0;
|
||||
for (int i = 0; i < pointers.length; i++)
|
||||
for (int i = 0; i < this.pointers.length; i++)
|
||||
{
|
||||
VertexPointer pointer = pointers[i];
|
||||
VertexPointer pointer = this.pointers[i];
|
||||
if (pointer == null)
|
||||
{
|
||||
GLProxy.GL_LOGGER.warn("Vertex Attribute index " + i + " is not set! No index should be skipped normally!");
|
||||
continue;
|
||||
}
|
||||
pointersOffset[i] = currentOffset;
|
||||
this.pointersOffset[i] = currentOffset;
|
||||
currentOffset += pointer.byteSize;
|
||||
}
|
||||
|
||||
if (currentOffset != expectedStrideSize)
|
||||
{
|
||||
GLProxy.GL_LOGGER.error("Vertex Attribute calculated stride size " + currentOffset +
|
||||
" does not match the provided expected stride size " + expectedStrideSize + "!");
|
||||
throw new IllegalArgumentException("Vertex Attribute Incorrect Format");
|
||||
}
|
||||
strideSize = currentOffset;
|
||||
this.strideSize = currentOffset;
|
||||
GLProxy.GL_LOGGER.info("Vertex Attribute (pre GL43) completed.");
|
||||
|
||||
// Debug logging
|
||||
GLProxy.GL_LOGGER.debug("AttributeIndex: ElementCount, glType, normalized, strideSize, offset");
|
||||
|
||||
for (int i = 0; i < pointers.length; i++)
|
||||
for (int i = 0; i < this.pointers.length; i++)
|
||||
{
|
||||
VertexPointer pointer = pointers[i];
|
||||
VertexPointer pointer = this.pointers[i];
|
||||
if (pointer == null)
|
||||
{
|
||||
GLProxy.GL_LOGGER.debug(i + ": Null!!!!");
|
||||
continue;
|
||||
}
|
||||
GLProxy.GL_LOGGER.debug(i + ": " + pointer.elementCount + ", " +
|
||||
pointer.glType + ", " + pointer.normalized + ", " + strideSize + ", " + pointersOffset[i]);
|
||||
else
|
||||
{
|
||||
GLProxy.GL_LOGGER.debug(i + ": " + pointer.elementCount + ", " +
|
||||
pointer.glType + ", " + pointer.normalized + ", " + this.strideSize + ", " + this.pointersOffset[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.core.render.glObject.vertexAttribute;
|
||||
|
||||
import com.seibel.distanthorizons.coreapi.util.MathUtil;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
public final class VertexPointer
|
||||
{
|
||||
public final int elementCount;
|
||||
public final int glType;
|
||||
public final boolean normalized;
|
||||
public final int byteSize;
|
||||
public final boolean useInteger;
|
||||
|
||||
|
||||
|
||||
// basic constructors //
|
||||
|
||||
public VertexPointer(int elementCount, int glType, boolean normalized, int byteSize, boolean useInteger)
|
||||
{
|
||||
this.elementCount = elementCount;
|
||||
this.glType = glType;
|
||||
this.normalized = normalized;
|
||||
this.byteSize = byteSize;
|
||||
this.useInteger = useInteger;
|
||||
}
|
||||
public VertexPointer(int elementCount, int glType, boolean normalized, int byteSize)
|
||||
{
|
||||
this(elementCount, glType, normalized, byteSize, false);
|
||||
}
|
||||
private static int _align(int bytes) { return MathUtil.ceilDiv(bytes, 4) * 4; }
|
||||
|
||||
|
||||
|
||||
// named constructors //
|
||||
|
||||
public static VertexPointer addFloatPointer(boolean normalized) { return new VertexPointer(1, GL32.GL_FLOAT, normalized, Float.BYTES); }
|
||||
public static VertexPointer addVec2Pointer(boolean normalized) { return new VertexPointer(2, GL32.GL_FLOAT, normalized, Float.BYTES * 2); }
|
||||
public static VertexPointer addVec3Pointer(boolean normalized) { return new VertexPointer(3, GL32.GL_FLOAT, normalized, Float.BYTES * 3); }
|
||||
public static VertexPointer addVec4Pointer(boolean normalized) { return new VertexPointer(4, GL32.GL_FLOAT, normalized, Float.BYTES * 4); }
|
||||
/** Always aligned to 4 bytes */
|
||||
public static VertexPointer addUnsignedBytePointer(boolean normalized, boolean useInteger) { return new VertexPointer(1, GL32.GL_UNSIGNED_BYTE, normalized, 4, useInteger); }
|
||||
/** aligned to 4 bytes */
|
||||
public static VertexPointer addUnsignedBytesPointer(int elementCount, boolean normalized, boolean useInteger) { return new VertexPointer(elementCount, GL32.GL_UNSIGNED_BYTE, normalized, _align(elementCount), useInteger); }
|
||||
public static VertexPointer addUnsignedShortsPointer(int elementCount, boolean normalized, boolean useInteger) { return new VertexPointer(elementCount, GL32.GL_UNSIGNED_SHORT, normalized, _align(elementCount * 2), useInteger); }
|
||||
public static VertexPointer addShortsPointer(int elementCount, boolean normalized, boolean useInteger) { return new VertexPointer(elementCount, GL32.GL_SHORT, normalized, _align(elementCount * 2), useInteger); }
|
||||
public static VertexPointer addIntPointer(boolean normalized, boolean useInteger) { return new VertexPointer(1, GL32.GL_INT, normalized, 4, useInteger); }
|
||||
public static VertexPointer addIVec2Pointer(boolean normalized, boolean useInteger) { return new VertexPointer(2, GL32.GL_INT, normalized, 8, useInteger); }
|
||||
public static VertexPointer addIVec3Pointer(boolean normalized, boolean useInteger) { return new VertexPointer(3, GL32.GL_INT, normalized, 12, useInteger); }
|
||||
public static VertexPointer addIVec4Pointer(boolean normalized, boolean useInteger) { return new VertexPointer(4, GL32.GL_INT, normalized, 16, useInteger); }
|
||||
|
||||
}
|
||||
+6
-5
@@ -33,7 +33,8 @@ import com.seibel.distanthorizons.core.render.glObject.GLState;
|
||||
import com.seibel.distanthorizons.core.render.glObject.buffer.GLElementBuffer;
|
||||
import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer;
|
||||
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexAttribute;
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.AbstractVertexAttribute;
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexPointer;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3d;
|
||||
@@ -66,7 +67,7 @@ public class DebugRenderer
|
||||
private ShaderProgram basicShader;
|
||||
private GLVertexBuffer boxBuffer;
|
||||
private GLElementBuffer boxOutlineBuffer;
|
||||
private VertexAttribute va;
|
||||
private AbstractVertexAttribute va;
|
||||
private boolean init = false;
|
||||
|
||||
// used when rendering
|
||||
@@ -155,10 +156,10 @@ public class DebugRenderer
|
||||
}
|
||||
|
||||
this.init = true;
|
||||
this.va = VertexAttribute.create();
|
||||
this.va = AbstractVertexAttribute.create();
|
||||
this.va.bind();
|
||||
// Pos
|
||||
this.va.setVertexAttribute(0, 0, VertexAttribute.VertexPointer.addVec3Pointer(false));
|
||||
this.va.setVertexAttribute(0, 0, VertexPointer.addVec3Pointer(false));
|
||||
this.va.completeAndCheck(Float.BYTES * 3);
|
||||
this.basicShader = new ShaderProgram("shaders/debug/vert.vert", "shaders/debug/frag.frag",
|
||||
"fragColor", new String[]{"vPosition"});
|
||||
@@ -206,7 +207,7 @@ public class DebugRenderer
|
||||
|
||||
this.basicShader.bind();
|
||||
this.va.bind();
|
||||
this.va.bindBufferToAllBindingPoint(this.boxBuffer.getId());
|
||||
this.va.bindBufferToAllBindingPoints(this.boxBuffer.getId());
|
||||
|
||||
this.boxOutlineBuffer.bind();
|
||||
|
||||
|
||||
+9
-10
@@ -24,9 +24,10 @@ import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
|
||||
import com.seibel.distanthorizons.core.render.glObject.shader.Shader;
|
||||
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexAttribute;
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.AbstractVertexAttribute;
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexAttributePostGL43;
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexAttributePreGL43;
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexPointer;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.render.fog.LodFogConfig;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
@@ -40,7 +41,7 @@ public class LodRenderProgram extends ShaderProgram
|
||||
public static final String FRAGMENT_SHADER_PATH = "shaders/flat_shaded.frag";
|
||||
private static final IVersionConstants VERSION_CONSTANTS = SingletonInjector.INSTANCE.get(IVersionConstants.class);
|
||||
|
||||
public final VertexAttribute vao;
|
||||
public final AbstractVertexAttribute vao;
|
||||
|
||||
// Uniforms
|
||||
public final int combinedMatUniform;
|
||||
@@ -66,7 +67,7 @@ public class LodRenderProgram extends ShaderProgram
|
||||
|
||||
private final LodFogConfig fogConfig;
|
||||
|
||||
// This will bind VertexAttribute
|
||||
// This will bind AbstractVertexAttribute
|
||||
public LodRenderProgram(LodFogConfig fogConfig)
|
||||
{
|
||||
super(() -> Shader.loadFile(fogConfig.earthCurveRatio != 0 ? VERTEX_CURVE_SHADER_PATH : VERTEX_SHADER_PATH,
|
||||
@@ -97,15 +98,13 @@ public class LodRenderProgram extends ShaderProgram
|
||||
// TODO: Add better use of the LODFormat thing
|
||||
int vertexByteCount = LodUtil.LOD_VERTEX_FORMAT.getByteSize();
|
||||
if (GLProxy.getInstance().VertexAttributeBufferBindingSupported)
|
||||
vao = new VertexAttributePostGL43(); // also binds VertexAttribute
|
||||
vao = new VertexAttributePostGL43(); // also binds AbstractVertexAttribute
|
||||
else
|
||||
vao = new VertexAttributePreGL43(); // also binds VertexAttribute
|
||||
vao = new VertexAttributePreGL43(); // also binds AbstractVertexAttribute
|
||||
vao.bind();
|
||||
// Now a pos+light.
|
||||
vao.setVertexAttribute(0, 0, VertexAttribute.VertexPointer.addUnsignedShortsPointer(4, false, true)); // 2+2+2+2
|
||||
//vao.setVertexAttribute(0, posAttrib, VertexAttribute.VertexPointer.addVec3Pointer(false)); // 4+4+4
|
||||
vao.setVertexAttribute(0, 1, VertexAttribute.VertexPointer.addUnsignedBytesPointer(4, true, false)); // +4
|
||||
//vao.setVertexAttribute(0, lightAttrib, VertexAttribute.VertexPointer.addUnsignedBytesPointer(2, false)); // +4 due to how it aligns
|
||||
vao.setVertexAttribute(0, 0, VertexPointer.addUnsignedShortsPointer(4, false, true)); // 2+2+2+2
|
||||
vao.setVertexAttribute(0, 1, VertexPointer.addUnsignedBytesPointer(4, true, false)); // +4
|
||||
try
|
||||
{
|
||||
vao.completeAndCheck(vertexByteCount);
|
||||
@@ -159,7 +158,7 @@ public class LodRenderProgram extends ShaderProgram
|
||||
|
||||
public void bindVertexBuffer(int vbo)
|
||||
{
|
||||
vao.bindBufferToAllBindingPoint(vbo);
|
||||
vao.bindBufferToAllBindingPoints(vbo);
|
||||
}
|
||||
|
||||
public void unbindVertexBuffer()
|
||||
|
||||
+24
-4
@@ -46,6 +46,7 @@ import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3d;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3f;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
import java.awt.*;
|
||||
@@ -250,6 +251,12 @@ public class LodRenderer
|
||||
if (!this.isSetupComplete)
|
||||
{
|
||||
this.setup();
|
||||
|
||||
// shouldn't normally happen, but just in case
|
||||
if (!this.isSetupComplete)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -263,10 +270,10 @@ public class LodRenderer
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.colorTextureId);
|
||||
GL32.glTexImage2D(GL32.GL_TEXTURE_2D,
|
||||
0,
|
||||
GL32.GL_RGB,
|
||||
GL32.GL_RGBA8,
|
||||
MC_RENDER.getTargetFrameBufferViewportWidth(), MC_RENDER.getTargetFrameBufferViewportHeight(),
|
||||
0,
|
||||
GL32.GL_RGB,
|
||||
GL32.GL_RGBA,
|
||||
GL32.GL_UNSIGNED_BYTE,
|
||||
(ByteBuffer) null);
|
||||
GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MIN_FILTER, GL32.GL_LINEAR);
|
||||
@@ -404,7 +411,8 @@ public class LodRenderer
|
||||
profiler.popPush("LOD Transparent");
|
||||
|
||||
GL32.glEnable(GL32.GL_BLEND);
|
||||
GL32.glBlendFunc(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA);
|
||||
GL32.glBlendEquation(GL32.GL_FUNC_ADD);
|
||||
GL32.glBlendFunc(GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA);
|
||||
this.bufferHandler.renderTransparent(this);
|
||||
GL32.glDepthMask(true); // Apparently the depth mask state is stored in the FBO, so glState fails to restore it...
|
||||
|
||||
@@ -414,11 +422,21 @@ public class LodRenderer
|
||||
drawLagSpikeCatcher.end("LodDraw");
|
||||
|
||||
|
||||
|
||||
//=============================//
|
||||
// Apply to the MC FrameBuffer //
|
||||
//=============================//
|
||||
|
||||
profiler.popPush("LOD Apply");
|
||||
|
||||
GLState dhApplyGlState = new GLState();
|
||||
|
||||
// Copy the LOD framebuffer to Minecraft's framebuffer
|
||||
DhApplyShader.INSTANCE.render(partialTicks);
|
||||
|
||||
dhApplyGlState.restore();
|
||||
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
@@ -457,6 +475,7 @@ public class LodRenderer
|
||||
}
|
||||
}
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
|
||||
//=================//
|
||||
@@ -471,8 +490,9 @@ public class LodRenderer
|
||||
EVENT_LOGGER.warn("Renderer setup called but it has already completed setup!");
|
||||
return;
|
||||
}
|
||||
if (!GLProxy.hasInstance())
|
||||
if (GLProxy.getInstance() == null)
|
||||
{
|
||||
// shouldn't normally happen, but just in case
|
||||
EVENT_LOGGER.warn("Renderer setup called but GLProxy has not yet been setup!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -21,12 +21,17 @@ package com.seibel.distanthorizons.core.render.renderer;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.config.EGpuUploadMethod;
|
||||
import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer;
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexAttribute;
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.AbstractVertexAttribute;
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexPointer;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
/**
|
||||
* Renders a full-screen textured quad to the screen.
|
||||
* Used in composite / deferred rendering (IE fog).
|
||||
*/
|
||||
public class ScreenQuad
|
||||
{
|
||||
public static ScreenQuad INSTANCE = new ScreenQuad();
|
||||
@@ -41,7 +46,7 @@ public class ScreenQuad
|
||||
};
|
||||
|
||||
private GLVertexBuffer boxBuffer;
|
||||
private VertexAttribute va;
|
||||
private AbstractVertexAttribute va;
|
||||
private boolean init = false;
|
||||
|
||||
|
||||
@@ -56,11 +61,11 @@ public class ScreenQuad
|
||||
if (this.init) return;
|
||||
this.init = true;
|
||||
|
||||
this.va = VertexAttribute.create();
|
||||
this.va = AbstractVertexAttribute.create();
|
||||
this.va.bind();
|
||||
|
||||
// Pos
|
||||
this.va.setVertexAttribute(0, 0, VertexAttribute.VertexPointer.addVec2Pointer(false));
|
||||
this.va.setVertexAttribute(0, 0, VertexPointer.addVec2Pointer(false));
|
||||
this.va.completeAndCheck(Float.BYTES * 2);
|
||||
|
||||
// Framebuffer
|
||||
@@ -71,8 +76,10 @@ public class ScreenQuad
|
||||
{
|
||||
this.init();
|
||||
|
||||
this.boxBuffer.bind();
|
||||
|
||||
this.va.bind();
|
||||
this.va.bindBufferToAllBindingPoint(this.boxBuffer.getId());
|
||||
this.va.bindBufferToAllBindingPoints(this.boxBuffer.getId());
|
||||
|
||||
GL32.glDrawArrays(GL32.GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
@@ -88,4 +95,5 @@ public class ScreenQuad
|
||||
this.boxBuffer.bind();
|
||||
this.boxBuffer.uploadBuffer(buffer, box_vertices.length, EGpuUploadMethod.DATA, box_vertices.length * Float.BYTES);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+8
-7
@@ -28,7 +28,8 @@ import com.seibel.distanthorizons.core.render.glObject.GLProxy;
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLState;
|
||||
import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer;
|
||||
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexAttribute;
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.AbstractVertexAttribute;
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexPointer;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
@@ -52,7 +53,7 @@ public class TestRenderer
|
||||
ShaderProgram basicShader;
|
||||
GLVertexBuffer sameContextBuffer;
|
||||
GLVertexBuffer sharedContextBuffer;
|
||||
VertexAttribute va;
|
||||
AbstractVertexAttribute va;
|
||||
boolean init = false;
|
||||
|
||||
public void init()
|
||||
@@ -60,12 +61,12 @@ public class TestRenderer
|
||||
if (init) return;
|
||||
logger.info("init");
|
||||
init = true;
|
||||
va = VertexAttribute.create();
|
||||
va = AbstractVertexAttribute.create();
|
||||
va.bind();
|
||||
// Pos
|
||||
va.setVertexAttribute(0, 0, VertexAttribute.VertexPointer.addVec2Pointer(false));
|
||||
va.setVertexAttribute(0, 0, VertexPointer.addVec2Pointer(false));
|
||||
// Color
|
||||
va.setVertexAttribute(0, 1, VertexAttribute.VertexPointer.addVec4Pointer(false));
|
||||
va.setVertexAttribute(0, 1, VertexPointer.addVec4Pointer(false));
|
||||
va.completeAndCheck(Float.BYTES * 6);
|
||||
basicShader = new ShaderProgram("shaders/test/vert.vert", "shaders/test/frag.frag",
|
||||
"fragColor", new String[]{"vPosition", "color"});
|
||||
@@ -123,13 +124,13 @@ public class TestRenderer
|
||||
if (System.currentTimeMillis() % 2000 < 1000)
|
||||
{
|
||||
sameContextBuffer.bind();
|
||||
va.bindBufferToAllBindingPoint(sameContextBuffer.getId());
|
||||
va.bindBufferToAllBindingPoints(sameContextBuffer.getId());
|
||||
spamLogger.debug("same context buffer");
|
||||
}
|
||||
else
|
||||
{
|
||||
sameContextBuffer.bind();
|
||||
va.bindBufferToAllBindingPoint(sharedContextBuffer.getId());
|
||||
va.bindBufferToAllBindingPoints(sharedContextBuffer.getId());
|
||||
spamLogger.debug("shared context buffer");
|
||||
}
|
||||
// Render the square
|
||||
|
||||
+27
-11
@@ -21,10 +21,13 @@ package com.seibel.distanthorizons.core.render.renderer.shaders;
|
||||
|
||||
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
|
||||
import com.seibel.distanthorizons.core.render.renderer.LodRenderer;
|
||||
import com.seibel.distanthorizons.core.render.renderer.SSAORenderer;
|
||||
import com.seibel.distanthorizons.core.render.renderer.ScreenQuad;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* Copies {@link LodRenderer}'s currently active color and depth texture to Minecraft's framebuffer.
|
||||
*/
|
||||
@@ -32,10 +35,16 @@ public class DhApplyShader extends AbstractShaderRenderer
|
||||
{
|
||||
public static DhApplyShader INSTANCE = new DhApplyShader();
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
// uniforms
|
||||
public int gDhColorTextureUniform;
|
||||
public int gDepthMapUniform;
|
||||
|
||||
public int tempFramebufferId;
|
||||
public int tempColorTextureId;
|
||||
public int tempDepthTextureId;
|
||||
|
||||
|
||||
@Override
|
||||
public void onInit()
|
||||
@@ -49,18 +58,16 @@ public class DhApplyShader extends AbstractShaderRenderer
|
||||
// uniform setup
|
||||
this.gDhColorTextureUniform = this.shader.getUniformLocation("gDhColorTexture");
|
||||
this.gDepthMapUniform = this.shader.getUniformLocation("gDhDepthTexture");
|
||||
|
||||
this.tempFramebufferId = GL32.glGenFramebuffers();
|
||||
this.tempColorTextureId = GL32.glGenTextures();
|
||||
this.tempDepthTextureId = GL32.glGenTextures();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onApplyUniforms(float partialTicks)
|
||||
{
|
||||
GL32.glActiveTexture(GL32.GL_TEXTURE0);
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, LodRenderer.getActiveColorTextureId());
|
||||
GL32.glUniform1i(this.gDhColorTextureUniform, 0);
|
||||
|
||||
GL32.glActiveTexture(GL32.GL_TEXTURE1);
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, LodRenderer.getActiveDepthTextureId());
|
||||
GL32.glUniform1i(this.gDepthMapUniform, 1);
|
||||
|
||||
}
|
||||
|
||||
@@ -69,6 +76,8 @@ public class DhApplyShader extends AbstractShaderRenderer
|
||||
// render //
|
||||
//========//
|
||||
|
||||
private boolean texturesCreated = false;
|
||||
|
||||
@Override
|
||||
protected void onRender()
|
||||
{
|
||||
@@ -77,10 +86,17 @@ public class DhApplyShader extends AbstractShaderRenderer
|
||||
GL32.glEnable(GL32.GL_BLEND);
|
||||
GL32.glBlendEquation(GL32.GL_FUNC_ADD);
|
||||
GL32.glBlendFunc(GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
|
||||
GL32.glActiveTexture(GL32.GL_TEXTURE0);
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, LodRenderer.getActiveColorTextureId());
|
||||
GL32.glUniform1i(this.gDhColorTextureUniform, 0);
|
||||
|
||||
GL32.glActiveTexture(GL32.GL_TEXTURE1);
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, LodRenderer.getActiveDepthTextureId());
|
||||
GL32.glUniform1i(this.gDepthMapUniform, 1);
|
||||
|
||||
// Copy to MC's framebuffer
|
||||
GL32.glBindFramebuffer(GL32.GL_READ_FRAMEBUFFER, 0); // this framebuffer shouldn't be used since we are reading in from a texture instead
|
||||
GL32.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, MC_RENDER.getTargetFrameBuffer());
|
||||
GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, MC_RENDER.getTargetFrameBuffer());
|
||||
|
||||
ScreenQuad.INSTANCE.render();
|
||||
}
|
||||
|
||||
+3
-1
@@ -151,8 +151,10 @@ public class FogShader extends AbstractShaderRenderer
|
||||
|
||||
GL32.glDisable(GL32.GL_DEPTH_TEST);
|
||||
GL32.glDisable(GL32.GL_SCISSOR_TEST);
|
||||
|
||||
GL32.glEnable(GL32.GL_BLEND);
|
||||
GL32.glBlendFunc(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA);
|
||||
GL32.glBlendEquation(GL32.GL_FUNC_ADD);
|
||||
GL32.glBlendFuncSeparate(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA, GL32.GL_ONE, GL32.GL_ONE);
|
||||
|
||||
GL32.glActiveTexture(GL32.GL_TEXTURE0);
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, LodRenderer.getActiveColorTextureId());
|
||||
|
||||
@@ -235,7 +235,7 @@ public class RenderUtil
|
||||
}
|
||||
public static int getFarClipPlaneDistanceInBlocks()
|
||||
{
|
||||
int lodChunkDist = Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistance.get();
|
||||
int lodChunkDist = Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius.get();
|
||||
return lodChunkDist * LodUtil.CHUNK_WIDTH;
|
||||
}
|
||||
|
||||
|
||||
@@ -269,6 +269,11 @@ public final class GLMessage
|
||||
*/
|
||||
public GLMessage add(String str)
|
||||
{
|
||||
// TODO fix implementation for MC 1.20.2 and newer
|
||||
// please see the incomplete GLMessageTest for an example as to how the message formats differ
|
||||
if (true)
|
||||
return null;
|
||||
|
||||
str = str.trim();
|
||||
if (str.isEmpty())
|
||||
return null;
|
||||
|
||||
+10
-10
@@ -56,7 +56,7 @@ public class QuadTree<T>
|
||||
*/
|
||||
public final byte treeMaxDetailLevel;
|
||||
|
||||
private final int widthInBlocks; // diameterInBlocks
|
||||
private final int diameterInBlocks; // diameterInBlocks
|
||||
|
||||
/** contain the actual data in the quad tree structure */
|
||||
private final MovableGridRingList<QuadNode<T>> topRingList;
|
||||
@@ -68,18 +68,18 @@ public class QuadTree<T>
|
||||
/**
|
||||
* Constructor of the quadTree
|
||||
*
|
||||
* @param widthInBlocks equivalent to the distance between two opposing sides
|
||||
* @param diameterInBlocks equivalent to the distance between the two opposing sides
|
||||
*/
|
||||
public QuadTree(int widthInBlocks, DhBlockPos2D centerBlockPos, byte treeMaxDetailLevel)
|
||||
public QuadTree(int diameterInBlocks, DhBlockPos2D centerBlockPos, byte treeMaxDetailLevel)
|
||||
{
|
||||
this.centerBlockPos = centerBlockPos;
|
||||
this.widthInBlocks = widthInBlocks;
|
||||
this.diameterInBlocks = diameterInBlocks;
|
||||
|
||||
this.treeMaxDetailLevel = treeMaxDetailLevel;
|
||||
// the min detail level must be greater than 0 (to prevent divide by 0 errors) and greater than the maximum detail level
|
||||
this.treeMinDetailLevel = (byte) Math.max(Math.max(1, this.treeMaxDetailLevel), MathUtil.log2(widthInBlocks));
|
||||
this.treeMinDetailLevel = (byte) Math.max(Math.max(1, this.treeMaxDetailLevel), MathUtil.log2(diameterInBlocks));
|
||||
|
||||
int halfSizeInRootNodes = Math.floorDiv(this.widthInBlocks, 2) / BitShiftUtil.powerOfTwo(this.treeMinDetailLevel);
|
||||
int halfSizeInRootNodes = Math.floorDiv(this.diameterInBlocks, 2) / BitShiftUtil.powerOfTwo(this.treeMinDetailLevel);
|
||||
halfSizeInRootNodes = halfSizeInRootNodes + 1; // always add 1 so nodes will always have a parent, even if the tree's center is offset from the root node grid
|
||||
|
||||
Pos2D ringListCenterPos = new Pos2D(
|
||||
@@ -171,14 +171,14 @@ public class QuadTree<T>
|
||||
|
||||
|
||||
// check if the testPos is within the X,Z boundary of the tree
|
||||
DhBlockPos2D treeBlockCorner = this.centerBlockPos.add(new DhBlockPos2D(-this.widthInBlocks / 2, -this.widthInBlocks / 2));
|
||||
DhBlockPos2D treeBlockCorner = this.centerBlockPos.add(new DhBlockPos2D(-this.diameterInBlocks / 2, -this.diameterInBlocks / 2));
|
||||
DhLodPos treeCornerPos = new DhLodPos((byte) 0, treeBlockCorner.x, treeBlockCorner.z);
|
||||
|
||||
DhSectionPos inputSectionCorner = testPos.convertNewToDetailLevel((byte) 0);
|
||||
DhLodPos inputCornerPos = new DhLodPos((byte) 0, inputSectionCorner.getX(), inputSectionCorner.getZ());
|
||||
int inputBlockWidth = BitShiftUtil.powerOfTwo(testPos.getDetailLevel());
|
||||
|
||||
return DoSquaresOverlap(treeCornerPos, this.widthInBlocks, inputCornerPos, inputBlockWidth);
|
||||
return DoSquaresOverlap(treeCornerPos, this.diameterInBlocks, inputCornerPos, inputBlockWidth);
|
||||
}
|
||||
private static boolean DoSquaresOverlap(DhLodPos square1Min, int square1Width, DhLodPos square2Min, int square2Width)
|
||||
{
|
||||
@@ -368,7 +368,7 @@ public class QuadTree<T>
|
||||
// TODO comment, currently a tree will always have 9 root nodes, because the tree will grow all the way up to the top, if this is ever changed then these values must also change
|
||||
public int ringListWidth() { return 3; }
|
||||
public int ringListHalfWidth() { return 1; }
|
||||
public int diameterInBlocks() { return this.widthInBlocks; }
|
||||
public int diameterInBlocks() { return this.diameterInBlocks; }
|
||||
|
||||
// public String getDebugString()
|
||||
// {
|
||||
@@ -384,7 +384,7 @@ public class QuadTree<T>
|
||||
// }
|
||||
|
||||
@Override
|
||||
public String toString() { return "center block: " + this.centerBlockPos + ", block width: " + this.widthInBlocks + ", detail level range: [" + this.treeMaxDetailLevel + "-" + this.treeMinDetailLevel + "], leaf #: " + this.leafNodeCount(); }
|
||||
public String toString() { return "center block: " + this.centerBlockPos + ", block width: " + this.diameterInBlocks + ", detail level range: [" + this.treeMaxDetailLevel + "-" + this.treeMinDetailLevel + "], leaf #: " + this.leafNodeCount(); }
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -88,9 +88,9 @@
|
||||
"Max Horizontal Resolution",
|
||||
"distanthorizons.config.client.advanced.graphics.quality.maxHorizontalResolution.@tooltip":
|
||||
"The maximum detail LODs are rendered at.\n\n§6Fastest:§r Chunk\n§6Fanciest:§r Block",
|
||||
"distanthorizons.config.client.advanced.graphics.quality.lodChunkRenderDistance":
|
||||
"LOD Render Distance",
|
||||
"distanthorizons.config.client.advanced.graphics.quality.lodChunkRenderDistance.@tooltip":
|
||||
"distanthorizons.config.client.advanced.graphics.quality.lodChunkRenderDistanceRadius":
|
||||
"LOD Render Distance Radius",
|
||||
"distanthorizons.config.client.advanced.graphics.quality.lodChunkRenderDistanceRadius.@tooltip":
|
||||
"Distant Horizons' render distance, measured in chunks. \n\nNote: this is a best effort number. \nThe render distance may be above or below this number \ndepending on your other graphic settings.",
|
||||
"distanthorizons.config.client.advanced.graphics.quality.verticalQuality":
|
||||
"Vertical Quality",
|
||||
|
||||
Reference in New Issue
Block a user