Convert DataSource ID from an int to a string

Since everything will be stored in a database binary space constraints aren't as big of a concern
This commit is contained in:
James Seibel
2023-10-07 16:07:15 -05:00
parent e0d25fdd88
commit 444090ed39
14 changed files with 48 additions and 152 deletions
@@ -33,14 +33,12 @@ import java.util.concurrent.locks.ReentrantLock;
public abstract class AbstractFullDataSourceLoader
{
public static final HashMultimap<Class<? extends IFullDataSource>, AbstractFullDataSourceLoader> LOADER_REGISTRY = HashMultimap.create();
public static final HashMap<Long, Class<? extends IFullDataSource>> DATATYPE_ID_REGISTRY = new HashMap<>();
private static final int AVAILABLE_PROCESSOR_COUNT = Runtime.getRuntime().availableProcessors();
public static final HashMap<String, Class<? extends IFullDataSource>> DATATYPE_REGISTRY = new HashMap<>();
public final Class<? extends IFullDataSource> fullDataSourceClass;
public final long datatypeId;
public final String datatype;
public final byte[] loaderSupportedVersions;
/** used when pooling data sources */
@@ -53,35 +51,38 @@ public abstract class AbstractFullDataSourceLoader
// constructor //
//=============//
public AbstractFullDataSourceLoader(Class<? extends IFullDataSource> fullDataSourceClass, long datatypeId, byte[] loaderSupportedVersions)
public AbstractFullDataSourceLoader(Class<? extends IFullDataSource> fullDataSourceClass, String datatype, byte[] loaderSupportedVersions)
{
this.datatypeId = datatypeId;
this.datatype = datatype;
this.loaderSupportedVersions = loaderSupportedVersions;
Arrays.sort(loaderSupportedVersions); // sort to allow fast access
this.fullDataSourceClass = fullDataSourceClass;
if (DATATYPE_ID_REGISTRY.containsKey(datatypeId) && DATATYPE_ID_REGISTRY.get(datatypeId) != fullDataSourceClass)
if (DATATYPE_REGISTRY.containsKey(datatype) && DATATYPE_REGISTRY.get(datatype) != fullDataSourceClass)
{
throw new IllegalArgumentException("Loader for datatypeId " + datatypeId + " already registered with different class: "
+ DATATYPE_ID_REGISTRY.get(datatypeId) + " != " + fullDataSourceClass);
throw new IllegalArgumentException("Loader for datatype: [" + datatype + "] already registered with different class: "
+ DATATYPE_REGISTRY.get(datatype) + " != " + fullDataSourceClass);
}
Set<AbstractFullDataSourceLoader> loaders = LOADER_REGISTRY.get(fullDataSourceClass);
if (loaders.stream().anyMatch(other ->
{
// see if any loaderSupportsVersion conflicts with this one
for (byte otherVer : other.loaderSupportedVersions)
{
if (Arrays.binarySearch(loaderSupportedVersions, otherVer) >= 0)
// see if any loaderSupportsVersion conflicts with this one
for (byte otherVer : other.loaderSupportedVersions)
{
return true;
if (Arrays.binarySearch(loaderSupportedVersions, otherVer) >= 0)
{
return true;
}
}
}
return false;
}))
return false;
}))
{
throw new IllegalArgumentException("Loader for class " + fullDataSourceClass + " that supports one of the version in "
+ Arrays.toString(loaderSupportedVersions) + " already registered!");
}
DATATYPE_ID_REGISTRY.put(datatypeId, fullDataSourceClass);
DATATYPE_REGISTRY.put(datatype, fullDataSourceClass);
LOADER_REGISTRY.put(fullDataSourceClass, this);
}
@@ -91,9 +92,9 @@ public abstract class AbstractFullDataSourceLoader
// loader getters //
//================//
public static AbstractFullDataSourceLoader getLoader(long dataTypeId, byte dataVersion)
public static AbstractFullDataSourceLoader getLoader(String dataType, byte dataVersion)
{
return LOADER_REGISTRY.get(DATATYPE_ID_REGISTRY.get(dataTypeId)).stream()
return LOADER_REGISTRY.get(DATATYPE_REGISTRY.get(dataType)).stream()
.filter(loader -> Arrays.binarySearch(loader.loaderSupportedVersions, dataVersion) >= 0)
.findFirst().orElse(null);
}
@@ -20,17 +20,12 @@
package com.seibel.distanthorizons.core.dataObjects.fullData.loader;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.interfaces.IFullDataSource;
import com.seibel.distanthorizons.core.file.fullDatafile.FullDataMetaFile;
import com.seibel.distanthorizons.core.level.IDhLevel;
import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.util.objects.dataStreams.DhDataInputStream;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.CompleteFullDataSource;
import java.io.IOException;
public class CompleteFullDataSourceLoader extends AbstractFullDataSourceLoader
{
public CompleteFullDataSourceLoader() { super(CompleteFullDataSource.class, CompleteFullDataSource.TYPE_ID, new byte[]{CompleteFullDataSource.DATA_FORMAT_VERSION}); }
public CompleteFullDataSourceLoader() { super(CompleteFullDataSource.class, CompleteFullDataSource.DATA_SOURCE_TYPE, new byte[]{CompleteFullDataSource.DATA_FORMAT_VERSION}); }
@Override
protected IFullDataSource createEmptyDataSource(DhSectionPos pos) { return CompleteFullDataSource.createEmpty(pos); }
@@ -19,19 +19,13 @@
package com.seibel.distanthorizons.core.dataObjects.fullData.loader;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.CompleteFullDataSource;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.interfaces.IFullDataSource;
import com.seibel.distanthorizons.core.file.fullDatafile.FullDataMetaFile;
import com.seibel.distanthorizons.core.level.IDhLevel;
import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.util.objects.dataStreams.DhDataInputStream;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.HighDetailIncompleteFullDataSource;
import java.io.IOException;
public class HighDetailIncompleteFullDataSourceLoader extends AbstractFullDataSourceLoader
{
public HighDetailIncompleteFullDataSourceLoader() { super(HighDetailIncompleteFullDataSource.class, HighDetailIncompleteFullDataSource.TYPE_ID, new byte[]{HighDetailIncompleteFullDataSource.DATA_FORMAT_VERSION}); }
public HighDetailIncompleteFullDataSourceLoader() { super(HighDetailIncompleteFullDataSource.class, HighDetailIncompleteFullDataSource.DATA_SOURCE_TYPE, new byte[]{HighDetailIncompleteFullDataSource.DATA_FORMAT_VERSION}); }
@Override
protected IFullDataSource createEmptyDataSource(DhSectionPos pos) { return HighDetailIncompleteFullDataSource.createEmpty(pos); }
@@ -19,19 +19,13 @@
package com.seibel.distanthorizons.core.dataObjects.fullData.loader;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.CompleteFullDataSource;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.interfaces.IFullDataSource;
import com.seibel.distanthorizons.core.file.fullDatafile.FullDataMetaFile;
import com.seibel.distanthorizons.core.level.IDhLevel;
import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.util.objects.dataStreams.DhDataInputStream;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.LowDetailIncompleteFullDataSource;
import java.io.IOException;
public class LowDetailIncompleteFullDataSourceLoader extends AbstractFullDataSourceLoader
{
public LowDetailIncompleteFullDataSourceLoader() { super(LowDetailIncompleteFullDataSource.class, LowDetailIncompleteFullDataSource.TYPE_ID, new byte[]{LowDetailIncompleteFullDataSource.DATA_FORMAT_VERSION}); }
public LowDetailIncompleteFullDataSourceLoader() { super(LowDetailIncompleteFullDataSource.class, LowDetailIncompleteFullDataSource.DATA_SOURCE_TYPE, new byte[]{LowDetailIncompleteFullDataSource.DATA_FORMAT_VERSION}); }
@Override
protected IFullDataSource createEmptyDataSource(DhSectionPos pos) { return LowDetailIncompleteFullDataSource.createEmpty(pos); }
@@ -59,8 +59,7 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu
public static final int WIDTH = BitShiftUtil.powerOfTwo(SECTION_SIZE_OFFSET);
public static final byte DATA_FORMAT_VERSION = 3;
/** written to the binary file to mark what {@link IFullDataSource} the binary file corresponds to */
public static final long TYPE_ID = "CompleteFullDataSource".hashCode();
public static final String DATA_SOURCE_TYPE = "CompleteFullDataSource";
private DhSectionPos sectionPos;
private boolean isEmpty = true;
@@ -72,8 +72,7 @@ public class HighDetailIncompleteFullDataSource implements IIncompleteFullDataSo
public static final byte MAX_SECTION_DETAIL = SECTION_SIZE_OFFSET + SPARSE_UNIT_DETAIL;
public static final byte DATA_FORMAT_VERSION = 3;
/** written to the binary file to mark what {@link IFullDataSource} the binary file corresponds to */
public static final long TYPE_ID = "HighDetailIncompleteFullDataSource".hashCode();
public static final String DATA_SOURCE_TYPE = "HighDetailIncompleteFullDataSource";
protected final FullDataPointIdMap mapping;
@@ -63,8 +63,7 @@ public class LowDetailIncompleteFullDataSource extends FullDataArrayAccessor imp
public static final int WIDTH = BitShiftUtil.powerOfTwo(SECTION_SIZE_OFFSET);
public static final byte DATA_FORMAT_VERSION = 3;
/** written to the binary file to mark what {@link IFullDataSource} the binary file corresponds to */
public static final long TYPE_ID = "LowDetailIncompleteFullDataSource".hashCode();
public static final String DATA_SOURCE_TYPE = "LowDetailIncompleteFullDataSource";
private DhSectionPos sectionPos;
@@ -56,7 +56,7 @@ public class ColumnRenderSource
public static final int SECTION_SIZE = BitShiftUtil.powerOfTwo(SECTION_SIZE_OFFSET);
public static final byte DATA_FORMAT_VERSION = 1;
public static final long TYPE_ID = "ColumnRenderSource".hashCode();
public static final String DATA_NAME = "ColumnRenderSource";
/**
* This is the byte put between different sections in the binary save file.
@@ -430,7 +430,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider
else
{
// shouldn't normally happen, but sometimes does
dataSourceLoader = AbstractFullDataSourceLoader.getLoader(existingFile.baseMetaData.dataTypeId, existingFile.baseMetaData.binaryDataFormatVersion);
dataSourceLoader = AbstractFullDataSourceLoader.getLoader(existingFile.baseMetaData.dataType, existingFile.baseMetaData.binaryDataFormatVersion);
}
dataSourceLoader.returnPooledDataSource(existingFullDataSource);
@@ -127,7 +127,7 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile implements I
public static FullDataMetaFile createFromExistingDto(IFullDataSourceProvider fullDataSourceProvider, IDhLevel level, MetaDataDto metaDataDto) throws IOException { return new FullDataMetaFile(fullDataSourceProvider, level, metaDataDto); }
private FullDataMetaFile(IFullDataSourceProvider fullDataSourceProvider, IDhLevel level, MetaDataDto metaDataDto) throws IOException
{
super(metaDataDto.dataArray);
super(metaDataDto.baseMetaData);
checkAndLogPhantomDataSourceLifeCycles();
this.fullDataSourceProvider = fullDataSourceProvider;
@@ -135,11 +135,10 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile implements I
LodUtil.assertTrue(this.baseMetaData != null);
this.doesDtoExist = true;
this.fullDataSourceLoader = AbstractFullDataSourceLoader.getLoader(this.baseMetaData.dataTypeId, this.baseMetaData.binaryDataFormatVersion);
this.fullDataSourceLoader = AbstractFullDataSourceLoader.getLoader(this.baseMetaData.dataType, this.baseMetaData.binaryDataFormatVersion);
if (this.fullDataSourceLoader == null)
{
// TODO add a hard coded dictionary of known ID name combos so we can easily see in the log if the ID is valid or if the data was corrupted/old
throw new IOException("Invalid file: Data type loader not found: " + this.baseMetaData.dataTypeId + "(v" + this.baseMetaData.binaryDataFormatVersion + ")");
throw new IOException("Invalid file: Data type loader not found: " + this.baseMetaData.dataType + "(v" + this.baseMetaData.binaryDataFormatVersion + ")");
}
this.fullDataSourceClass = this.fullDataSourceLoader.fullDataSourceClass;
@@ -224,7 +223,7 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile implements I
this.baseMetaData = new BaseMetaData(
fullDataSource.getSectionPos(), -1,
fullDataSource.getDataDetailLevel(), fullDataSource.getWorldGenStep(),
(dataSourceLoader == null ? 0 : dataSourceLoader.datatypeId), fullDataSource.getBinaryDataFormatVersion(), Long.MAX_VALUE);
(dataSourceLoader == null ? null : dataSourceLoader.datatype), fullDataSource.getBinaryDataFormatVersion(), Long.MAX_VALUE);
return fullDataSource;
})
@@ -524,25 +523,7 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile implements I
private InputStream getInputStream() throws IOException
{
MetaDataDto dto = this.fullDataSourceProvider.getRepo().getByPrimaryKey(this.pos.serialize());
ByteArrayInputStream inputStream = new ByteArrayInputStream(dto.dataArray);
// skip the meta-data bytes
int bytesToSkip = AbstractMetaDataContainerFile.METADATA_SIZE_IN_BYTES;
while (bytesToSkip > 0)
{
long skippedByteCount = inputStream.skip(bytesToSkip);
if (skippedByteCount == 0)
{
throw new IOException("Invalid file: Failed to skip metadata.");
}
bytesToSkip -= skippedByteCount;
}
if (bytesToSkip != 0)
{
throw new IOException("File IO Error: Failed to skip metadata.");
}
return inputStream;
return new ByteArrayInputStream(dto.dataArray);
}
/**
@@ -705,7 +686,7 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile implements I
LodUtil.assertTrue(this.fullDataSourceLoader != null, "No loader for " + fullDataSource.getClass() + " (v" + fullDataSource.getBinaryDataFormatVersion() + ")");
this.fullDataSourceClass = fullDataSource.getClass();
this.baseMetaData.dataTypeId = (this.fullDataSourceLoader == null) ? 0 : this.fullDataSourceLoader.datatypeId;
this.baseMetaData.dataType = (this.fullDataSourceLoader == null) ? null : this.fullDataSourceLoader.datatype;
this.baseMetaData.binaryDataFormatVersion = fullDataSource.getBinaryDataFormatVersion();
@@ -714,7 +695,7 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile implements I
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
super.writeData((bufferedOutputStream) -> fullDataSource.writeToStream((bufferedOutputStream), this.level), byteArrayOutputStream);
MetaDataDto dto = new MetaDataDto(this.pos, byteArrayOutputStream.toByteArray());
MetaDataDto dto = new MetaDataDto(this.baseMetaData, byteArrayOutputStream.toByteArray());
this.fullDataSourceProvider.getRepo().save(dto);
this.doesDtoExist = true;
}
@@ -64,12 +64,6 @@ public abstract class AbstractMetaDataContainerFile
{
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
public static final int METADATA_SIZE_IN_BYTES = 64;
// public static final int BUFFER_SIZE = 8192;
public static final int METADATA_RESERVED_SIZE = 24;
/** equivalent to "DHv0" */
public static final int METADATA_IDENTITY_BYTES = 0x44_48_76_30;
/**
* Will be null if no file exists for this object. <br>
@@ -99,42 +93,11 @@ public abstract class AbstractMetaDataContainerFile
* @throws IOException if the file was formatted incorrectly
* @throws FileNotFoundException if no file exists for the given path
*/
protected AbstractMetaDataContainerFile(byte[] byteArray) throws IOException
protected AbstractMetaDataContainerFile(BaseMetaData baseMetaData) throws IOException
{
this.baseMetaData = readMetaDataFromByteArray(byteArray);
this.baseMetaData = baseMetaData;
this.pos = this.baseMetaData.pos;
}
/**
* Attempts to create a new {@link AbstractMetaDataContainerFile} from the given file.
*
* @throws IOException if the file was formatted incorrectly
*/
private static BaseMetaData readMetaDataFromByteArray(byte[] byteArray) throws IOException
{
ByteBuffer byteBuffer = ByteBuffer.wrap(byteArray);
int idBytes = byteBuffer.getInt();
if (idBytes != METADATA_IDENTITY_BYTES)
{
throw new IOException("Invalid file format: Metadata Identity byte check failed. Expected: [" + METADATA_IDENTITY_BYTES + "], Actual: [" + idBytes + "].");
}
int x = byteBuffer.getInt();
int y = byteBuffer.getInt(); // Unused
int z = byteBuffer.getInt();
int checksum = byteBuffer.getInt();
byte detailLevel = byteBuffer.get();
byte dataLevel = byteBuffer.get();
byte loaderVersion = byteBuffer.get();
EDhApiWorldGenerationStep worldGenStep = EDhApiWorldGenerationStep.fromValue(byteBuffer.get());
long dataTypeId = byteBuffer.getLong();
long dataVersion = byteBuffer.getLong(); // data versioning
//LodUtil.assertTrue(byteBuffer.remaining() == METADATA_RESERVED_SIZE);
DhSectionPos dataPos = new DhSectionPos(detailLevel, x, z);
return new BaseMetaData(dataPos, checksum, dataLevel, worldGenStep, dataTypeId, loaderVersion, dataVersion);
}
//==============//
@@ -147,11 +110,8 @@ public abstract class AbstractMetaDataContainerFile
try
{
// the staging stream is so we can process the compressed data before the metadata, while still writing it after the meta data
ByteArrayOutputStream compressedDataStagingOutputStream = new ByteArrayOutputStream();
// the order of these streams is important, otherwise the checksum won't be calculated
CheckedOutputStream checkedOut = new CheckedOutputStream(compressedDataStagingOutputStream, new Adler32());
CheckedOutputStream checkedOut = new CheckedOutputStream(outputStream, new Adler32());
// normally a DhStream should be the topmost stream to prevent closing the stream accidentally, but since this stream will be closed immediately after writing anyway, it won't be an issue
DhDataOutputStream compressedOut = new DhDataOutputStream(checkedOut);
@@ -162,33 +122,8 @@ public abstract class AbstractMetaDataContainerFile
this.baseMetaData.checksum = (int) checkedOut.getChecksum().getValue();
// generate the meta data
ByteBuffer buffer = ByteBuffer.allocate(METADATA_SIZE_IN_BYTES);
buffer.putInt(METADATA_IDENTITY_BYTES);
buffer.putInt(this.pos.getX());
buffer.putInt(Integer.MIN_VALUE); // Unused - y pos
buffer.putInt(this.pos.getZ());
buffer.putInt(0); //FIXME this.baseMetaData.checksum);
buffer.put(this.pos.getDetailLevel());
buffer.put(this.baseMetaData.dataDetailLevel);
buffer.put(this.baseMetaData.binaryDataFormatVersion);
buffer.put(this.baseMetaData.worldGenStep != null ? this.baseMetaData.worldGenStep.value : EDhApiWorldGenerationStep.EMPTY.value); // TODO this null check shouldn't be necessary
buffer.putLong(this.baseMetaData.dataTypeId);
buffer.putLong(this.baseMetaData.dataVersion.get()); // for types that doesn't need data versioning, this will be Long.MAX_VALUE
// confirm we haven't gone outside the metadata reserved space
LodUtil.assertTrue(buffer.remaining() == METADATA_RESERVED_SIZE);
// write all data to the output
outputStream.write(buffer.array());
outputStream.write(compressedDataStagingOutputStream.toByteArray());
outputStream.close();
}
catch (NoSuchFileException e)
{
// can be thrown by the "Files.move" method if the system tries writing to an unloaded level
}
catch (ClosedChannelException e) // includes ClosedByInterruptException
{
// expected if the file handler is shut down, the exception can be ignored
@@ -40,13 +40,13 @@ public class BaseMetaData
public EDhApiWorldGenerationStep worldGenStep;
// Loader stuff //
/** indicates what data is held in this file, this is generally a hash of the data's name */
public long dataTypeId;
/** indicates what data is held in this file, this is generally the data's name */
public String dataType;
public byte binaryDataFormatVersion;
public BaseMetaData(DhSectionPos pos, int checksum, byte dataDetailLevel, EDhApiWorldGenerationStep worldGenStep, long dataTypeId, byte binaryDataFormatVersion, long dataVersion)
public BaseMetaData(DhSectionPos pos, int checksum, byte dataDetailLevel, EDhApiWorldGenerationStep worldGenStep, String dataType, byte binaryDataFormatVersion, long dataVersion)
{
this.pos = pos;
this.checksum = checksum;
@@ -54,7 +54,7 @@ public class BaseMetaData
this.dataDetailLevel = dataDetailLevel;
this.worldGenStep = worldGenStep;
this.dataTypeId = dataTypeId;
this.dataType = dataType;
this.binaryDataFormatVersion = binaryDataFormatVersion;
}
@@ -54,9 +54,8 @@ public class RenderDataMetaFile extends AbstractMetaDataContainerFile implements
{
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
public static final String FILE_SUFFIX = ".rlod";
public static final boolean ALWAYS_INVALIDATE_CACHE = false;
public static final long RENDER_SOURCE_TYPE_ID = ColumnRenderSource.TYPE_ID;
public static final String RENDER_SOURCE_TYPE = ColumnRenderSource.DATA_NAME;
/**
@@ -103,7 +102,7 @@ public class RenderDataMetaFile extends AbstractMetaDataContainerFile implements
public static RenderDataMetaFile createFromExistingFile(IFullDataSourceProvider fullDataSourceProvider, IRenderSourceProvider renderDataSourceProvider, IDhClientLevel clientLevel, MetaDataDto metaDataDto) throws IOException { return new RenderDataMetaFile(fullDataSourceProvider, renderDataSourceProvider, clientLevel, metaDataDto); }
private RenderDataMetaFile(IFullDataSourceProvider fullDataSourceProvider, IRenderSourceProvider renderDataSourceProvider, IDhClientLevel clientLevel, MetaDataDto metaDataDto) throws IOException
{
super(metaDataDto.dataArray);
super(metaDataDto.baseMetaData);
this.fullDataSourceProvider = fullDataSourceProvider;
this.renderDataSourceProvider = renderDataSourceProvider;
this.clientLevel = clientLevel;
@@ -196,7 +195,7 @@ public class RenderDataMetaFile extends AbstractMetaDataContainerFile implements
this.baseMetaData = new BaseMetaData(
newColumnRenderSource.getSectionPos(), -1, newColumnRenderSource.getDataDetailLevel(),
newColumnRenderSource.worldGenStep, RENDER_SOURCE_TYPE_ID,
newColumnRenderSource.worldGenStep, RENDER_SOURCE_TYPE,
newColumnRenderSource.getRenderDataFormatVersion(), Long.MAX_VALUE);
this.updateRenderCacheAsync(newColumnRenderSource).whenComplete((voidObj, ex) ->
@@ -353,7 +352,7 @@ public class RenderDataMetaFile extends AbstractMetaDataContainerFile implements
// update the meta data
this.baseMetaData.dataVersion.set(renderDataVersionRef.value);
this.baseMetaData.dataDetailLevel = renderSource.getDataDetailLevel();
this.baseMetaData.dataTypeId = RENDER_SOURCE_TYPE_ID;
this.baseMetaData.dataType = RENDER_SOURCE_TYPE;
this.baseMetaData.binaryDataFormatVersion = renderSource.getRenderDataFormatVersion();
// save to file
@@ -166,7 +166,7 @@ public class GLProxy
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 2);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_DEBUG_CONTEXT, GLFW.GLFW_TRUE);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_FORWARD_COMPAT, GLFW.GLFW_TRUE);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, GLFW.GLFW_OPENGL_CORE_PROFILE);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, GLFW.GLFW_OPENGL_ANY_PROFILE);
// create the Lod Builder context
this.lodBuilderGlContext = GLFW.glfwCreateWindow(64, 48, "LOD Builder Window", 0L, this.minecraftGlContext);