Slowly implementing new render pipeline
This commit is contained in:
parent
c1f6c5ec10
commit
340d8ff463
14
build.gradle
14
build.gradle
@ -12,18 +12,6 @@ eclipse {
|
|||||||
classpath {
|
classpath {
|
||||||
downloadJavadoc = true
|
downloadJavadoc = true
|
||||||
downloadSources = true
|
downloadSources = true
|
||||||
file {
|
|
||||||
whenMerged { cp ->
|
|
||||||
cp.entries.forEach { entry ->
|
|
||||||
// Target the core LWJGL modules
|
|
||||||
if (entry.kind == 'lib' && entry.path.contains('org.lwjgl')) {
|
|
||||||
// Dynamically add a JPMS modular export rule to the Eclipse compiler
|
|
||||||
def rule = new org.gradle.plugins.ide.eclipse.model.AccessRule('accessible', 'org/lwjgl/system/**')
|
|
||||||
entry.accessRules.add(rule)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,8 +75,6 @@ jar {
|
|||||||
it.isDirectory() ? it : zipTree(it)
|
it.isDirectory() ? it : zipTree(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exclude('**/*.LIST')
|
|
||||||
exclude('**/module-info.class')
|
|
||||||
duplicatesStrategy = DuplicatesStrategy.INCLUDE
|
duplicatesStrategy = DuplicatesStrategy.INCLUDE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,18 +2,27 @@ package speiger.src.coreengine.graphics.api.buffer;
|
|||||||
|
|
||||||
import java.nio.Buffer;
|
import java.nio.Buffer;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import speiger.src.coreengine.graphics.api.core.GraphicsResource;
|
import speiger.src.collections.ints.misc.pairs.IntObjectPair;
|
||||||
|
import speiger.src.coreengine.graphics.api.buffer.states.BufferState;
|
||||||
|
import speiger.src.coreengine.graphics.api.buffer.states.BufferType;
|
||||||
|
import speiger.src.coreengine.graphics.api.utils.GraphicsResource;
|
||||||
|
|
||||||
public abstract class VertexBuffer implements GraphicsResource {
|
public abstract class VertexBuffer implements GraphicsResource {
|
||||||
|
protected final BufferType type;
|
||||||
protected final BufferState usage;
|
protected final BufferState usage;
|
||||||
protected int size;
|
protected int size;
|
||||||
|
|
||||||
public VertexBuffer(BufferState usage, int size) {
|
public VertexBuffer(BufferType type, BufferState usage) {
|
||||||
|
this.type = type;
|
||||||
this.usage = usage;
|
this.usage = usage;
|
||||||
this.size = size;
|
}
|
||||||
|
|
||||||
|
public BufferType type() {
|
||||||
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BufferState usage() {
|
public BufferState usage() {
|
||||||
@ -24,6 +33,9 @@ public abstract class VertexBuffer implements GraphicsResource {
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract VertexBuffer bind();
|
||||||
|
public abstract VertexBuffer unbind();
|
||||||
|
|
||||||
public abstract VertexBuffer allocate(int totalBytes);
|
public abstract VertexBuffer allocate(int totalBytes);
|
||||||
public abstract VertexBuffer set(long pointer, int totalBytes);
|
public abstract VertexBuffer set(long pointer, int totalBytes);
|
||||||
public VertexBuffer set(ByteBuffer buffer) {
|
public VertexBuffer set(ByteBuffer buffer) {
|
||||||
@ -35,10 +47,17 @@ public abstract class VertexBuffer implements GraphicsResource {
|
|||||||
return fill(MemoryUtil.memAddress(buffer), buffer.remaining(), offset);
|
return fill(MemoryUtil.memAddress(buffer), buffer.remaining(), offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract VertexBuffer read(long pointer, int totalbytes, int offset);
|
public abstract VertexBuffer read(long pointer, int totalBytes, int offset);
|
||||||
public VertexBuffer read(Buffer buffer, int totalBytes, int offset) {
|
public VertexBuffer read(Buffer buffer, int totalBytes, int offset) {
|
||||||
return read(MemoryUtil.memAddress(buffer), totalBytes, offset);
|
read(MemoryUtil.memAddress(buffer), totalBytes, offset);
|
||||||
|
buffer.flip();
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public VertexBuffer fill(List<IntObjectPair<byte[]>> data) { return fill(0, data); }
|
||||||
|
public abstract VertexBuffer fill(int offset, List<IntObjectPair<byte[]>> data);
|
||||||
|
|
||||||
|
public abstract VertexBuffer shrink(int newSize);
|
||||||
|
public abstract VertexBuffer grow(int newSize);
|
||||||
|
public abstract VertexBuffer shift(int source, int dest, int length);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
package speiger.src.coreengine.graphics.api.buffer;
|
package speiger.src.coreengine.graphics.api.buffer.states;
|
||||||
|
|
||||||
public enum BufferState {
|
public enum BufferState {
|
||||||
STATIC_DRAW,
|
STATIC_DRAW,
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package speiger.src.coreengine.graphics.api.buffer.states;
|
||||||
|
|
||||||
|
public enum BufferType {
|
||||||
|
ARRAY_BUFFER,
|
||||||
|
ELEMENT_BUFFER,
|
||||||
|
UNIFORM_BUFFER,
|
||||||
|
DRAW_INDIRECT_BUFFER,
|
||||||
|
TEXTURE_BUFFER,
|
||||||
|
PIXEL_PACK_BUFFER,
|
||||||
|
PIXEL_UNPACK_BUFFER,
|
||||||
|
TRANSFORM_FEEDBACK_BUFFER,
|
||||||
|
COPY_READ_BUFFER,
|
||||||
|
COPY_WRITE_BUFFER,
|
||||||
|
ATOMIC_COUNTER_BUFFER,
|
||||||
|
DISPATCH_INDIRECT_BUFFER,
|
||||||
|
SHADER_STORAGE_BUFFER;
|
||||||
|
}
|
||||||
@ -5,5 +5,6 @@ import speiger.src.coreengine.rendering.input.window.Window;
|
|||||||
public interface Graphics {
|
public interface Graphics {
|
||||||
public String getName();
|
public String getName();
|
||||||
|
|
||||||
|
public void setupWindowArguments();
|
||||||
public GraphicsDevice createDevice(Window window);
|
public GraphicsDevice createDevice(Window window);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,17 @@
|
|||||||
package speiger.src.coreengine.graphics.api.core;
|
package speiger.src.coreengine.graphics.api.core;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.graphics.api.texture.Texture;
|
||||||
|
import speiger.src.coreengine.graphics.api.utils.PushableResource;
|
||||||
|
import speiger.src.coreengine.math.vector.floats.Vec4f;
|
||||||
|
|
||||||
public interface GraphicsCommandQueue {
|
public interface GraphicsCommandQueue {
|
||||||
|
public static final int CLEAR_COLOR = 1;
|
||||||
|
public static final int CLEAR_DEPTH = 2;
|
||||||
|
public PushableResource pushClearColor(Vec4f color);
|
||||||
|
public PushableResource pushClearDepth(double value);
|
||||||
|
|
||||||
}
|
public void clearTexture(Texture texture, int clearParam);
|
||||||
|
public void clearTexture(Texture texture, int x, int y, int width, int height, int clearParam);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,12 +1,18 @@
|
|||||||
package speiger.src.coreengine.graphics.api.core;
|
package speiger.src.coreengine.graphics.api.core;
|
||||||
|
|
||||||
import speiger.src.coreengine.graphics.api.buffer.VertexBuffer;
|
import speiger.src.coreengine.graphics.api.buffer.VertexBuffer;
|
||||||
|
import speiger.src.coreengine.graphics.api.buffer.states.BufferState;
|
||||||
|
import speiger.src.coreengine.graphics.api.buffer.states.BufferType;
|
||||||
|
import speiger.src.coreengine.graphics.api.sampler.Sampler;
|
||||||
|
import speiger.src.coreengine.graphics.api.sampler.SamplerSettings;
|
||||||
import speiger.src.coreengine.graphics.api.texture.Texture;
|
import speiger.src.coreengine.graphics.api.texture.Texture;
|
||||||
import speiger.src.coreengine.rendering.input.window.Window;
|
import speiger.src.coreengine.graphics.api.texture.TextureSettings;
|
||||||
|
|
||||||
public interface GraphicsDevice {
|
public interface GraphicsDevice {
|
||||||
public GraphicsSurface createSurface(Window window);
|
public GraphicsSurface createSurface();
|
||||||
public GraphicsCommandQueue getQueue();
|
public GraphicsCommandQueue getQueue();
|
||||||
public VertexBuffer createBuffer();
|
public VertexBuffer createBuffer(BufferType type, BufferState state);
|
||||||
public Texture createTexture();
|
public VertexBuffer createBuffer(BufferType type, BufferState state, int allocatedBytes);
|
||||||
|
public Texture createTexture(TextureSettings data, int width, int height);
|
||||||
|
public Sampler createSampler(SamplerSettings settings);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,4 +2,6 @@ package speiger.src.coreengine.graphics.api.core;
|
|||||||
|
|
||||||
public interface GraphicsSurface {
|
public interface GraphicsSurface {
|
||||||
public void setVsync(boolean value);
|
public void setVsync(boolean value);
|
||||||
|
public void beginFrame();
|
||||||
|
public void finishFrame();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
package speiger.src.coreengine.graphics.api.sampler;
|
package speiger.src.coreengine.graphics.api.sampler;
|
||||||
|
|
||||||
public abstract class Sampler {
|
import speiger.src.coreengine.graphics.api.utils.GraphicsResource;
|
||||||
SamplerSettings settings;
|
|
||||||
|
public abstract class Sampler implements GraphicsResource {
|
||||||
|
protected SamplerSettings settings;
|
||||||
|
|
||||||
public Sampler(SamplerSettings settings) {
|
public Sampler(SamplerSettings settings) {
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
|
|||||||
@ -1,5 +1,60 @@
|
|||||||
package speiger.src.coreengine.graphics.api.sampler;
|
package speiger.src.coreengine.graphics.api.sampler;
|
||||||
|
|
||||||
public class SamplerSettings {
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.graphics.api.sampler.states.BorderMode;
|
||||||
|
import speiger.src.coreengine.graphics.api.sampler.states.SampleMode;
|
||||||
|
|
||||||
|
public record SamplerSettings(BorderMode wrapS, BorderMode wrapT, Optional<BorderMode> wrapR, SampleMode minSample, SampleMode magSample) {
|
||||||
|
|
||||||
|
public SamplerSettings {
|
||||||
|
Objects.requireNonNull(wrapS);
|
||||||
|
Objects.requireNonNull(wrapT);
|
||||||
|
Objects.requireNonNull(wrapR);
|
||||||
|
Objects.requireNonNull(minSample);
|
||||||
|
Objects.requireNonNull(magSample);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
BorderMode wrapS;
|
||||||
|
BorderMode wrapT;
|
||||||
|
BorderMode wrapR;
|
||||||
|
SampleMode minSample;
|
||||||
|
SampleMode magSample;
|
||||||
|
|
||||||
|
public Builder wrapS(BorderMode mode) {
|
||||||
|
wrapS = Objects.requireNonNull(mode);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder wrapT(BorderMode mode) {
|
||||||
|
wrapT = Objects.requireNonNull(mode);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder wrapR(BorderMode mode) {
|
||||||
|
wrapR = mode;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder minSample(SampleMode mode) {
|
||||||
|
minSample = Objects.requireNonNull(mode);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder magSample(SampleMode mode) {
|
||||||
|
if(mode != SampleMode.LINEAR && mode != SampleMode.NEAREST) throw new IllegalArgumentException("["+mode+"] is not supported in mag filter");
|
||||||
|
magSample = Objects.requireNonNull(mode);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SamplerSettings build() {
|
||||||
|
return new SamplerSettings(Objects.requireNonNull(wrapS, "X Wrap should be defined"),
|
||||||
|
Objects.requireNonNull(wrapT, "Y Wrap should be defined"),
|
||||||
|
Optional.ofNullable(wrapR),
|
||||||
|
Objects.requireNonNull(minSample, "Min Sample should be defined"),
|
||||||
|
Objects.requireNonNull(magSample, "Mag Sample should be defined"));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
package speiger.src.coreengine.graphics.api.sampler.states;
|
||||||
|
|
||||||
|
public enum BorderMode {
|
||||||
|
CLAMP_TO_EDGE,
|
||||||
|
CLAMP_TO_BORDER,
|
||||||
|
MIRRORED_REPEAT,
|
||||||
|
REPEAT,
|
||||||
|
MIRROR_CLAMP_TO_EDGE;
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
package speiger.src.coreengine.graphics.api.sampler.states;
|
||||||
|
|
||||||
|
public enum SampleMode {
|
||||||
|
NEAREST,
|
||||||
|
LINEAR,
|
||||||
|
NEAREST_MIPMAP_NEAREST,
|
||||||
|
LINEAR_MIPMAP_NEAREST,
|
||||||
|
NEAREST_MIPMAP_LINEAR,
|
||||||
|
LINEAR_MIPMAP_LINEAR;
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package speiger.src.coreengine.graphics.api.shader;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.states.GraphicsDataType;
|
||||||
|
|
||||||
|
public record BufferAttribute(int index, int size, GraphicsDataType type, boolean normal, int instancedAmount) {
|
||||||
|
public BufferAttribute(int index, int size) {
|
||||||
|
this(index, size, GraphicsDataType.FLOAT, false, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferAttribute(int index, int size, GraphicsDataType type) {
|
||||||
|
this(index, size, type, false, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferAttribute(int index, int size, GraphicsDataType type, boolean normal) {
|
||||||
|
this(index, size, type, normal, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferAttribute(int index, int size, GraphicsDataType type, int instancedAmount) {
|
||||||
|
this(index, size, type, false, instancedAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BufferAttribute[] array(int startIndex, int width, int size, GraphicsDataType type) { return array(startIndex, width, size, type, false, 0); }
|
||||||
|
public static BufferAttribute[] array(int startIndex, int width, int size, GraphicsDataType type, boolean normal) { return array(startIndex, width, size, type, normal, 0); }
|
||||||
|
public static BufferAttribute[] array(int startIndex, int width, int size, GraphicsDataType type, int instanceAmount) { return array(startIndex, width, size, type, false, instanceAmount); }
|
||||||
|
public static BufferAttribute[] array(int startIndex, int width, int size, GraphicsDataType type, boolean normal, int instancedAmount) {
|
||||||
|
BufferAttribute[] attributes = new BufferAttribute[width];
|
||||||
|
for(int i = 0;i < width;i++) {
|
||||||
|
attributes[i] = new BufferAttribute(startIndex + i, size, type, normal, instancedAmount);
|
||||||
|
}
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package speiger.src.coreengine.graphics.api.shader;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.states.BlendFunction;
|
||||||
|
|
||||||
|
public record ColorTarget(Optional<BlendFunction> blend, int writeMask) {
|
||||||
|
public static final int RED = 1;
|
||||||
|
public static final int GREEN = 2;
|
||||||
|
public static final int BLUE = 4;
|
||||||
|
public static final int ALPHA = 8;
|
||||||
|
public static final int ALL = 15;
|
||||||
|
public static final ColorTarget DEFAULT = new ColorTarget(null);
|
||||||
|
|
||||||
|
public ColorTarget {
|
||||||
|
Objects.requireNonNull(blend);
|
||||||
|
if(writeMask < 0 || writeMask > ALL) throw new IllegalArgumentException("WriteMask has to be within 0-15");
|
||||||
|
}
|
||||||
|
|
||||||
|
public ColorTarget(BlendFunction function) {
|
||||||
|
this(Optional.ofNullable(function), ALL);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
package speiger.src.coreengine.graphics.api.shader;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.graphics.api.utils.AlphaFunction;
|
||||||
|
|
||||||
|
public record DepthTarget(AlphaFunction function, boolean write) {
|
||||||
|
public static final DepthTarget DEFAULT = new DepthTarget(AlphaFunction.GEQUAL, true);
|
||||||
|
|
||||||
|
public DepthTarget {
|
||||||
|
Objects.requireNonNull(function);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,139 @@
|
|||||||
|
package speiger.src.coreengine.graphics.api.shader;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.EnumMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import speiger.src.collections.objects.lists.ImmutableObjectList;
|
||||||
|
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||||
|
import speiger.src.collections.objects.lists.ObjectList;
|
||||||
|
import speiger.src.collections.objects.sets.ObjectOpenHashSet;
|
||||||
|
import speiger.src.collections.objects.sets.ObjectSet;
|
||||||
|
import speiger.src.coreengine.assets.AssetLocation;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.states.DrawMode;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.states.PolygonMode;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.states.ShaderType;
|
||||||
|
|
||||||
|
public record ShaderPipeline(AssetLocation id, Map<ShaderType, AssetLocation> shaders, List<List<BufferAttribute>> attributes, List<String> attributeNames, Set<String> uniforms, Set<String> samplers, DrawMode mode, PolygonMode fillMode, boolean cullBack, ColorTarget colorTarget, DepthTarget depthTarget) {
|
||||||
|
|
||||||
|
public ShaderPipeline {
|
||||||
|
Objects.requireNonNull(id);
|
||||||
|
if(shaders.isEmpty()) throw new IllegalStateException("Shaders isn't allowed to be empty");
|
||||||
|
Objects.requireNonNull(uniforms);
|
||||||
|
Objects.requireNonNull(samplers);
|
||||||
|
Objects.requireNonNull(mode);
|
||||||
|
Objects.requireNonNull(fillMode);
|
||||||
|
Objects.requireNonNull(colorTarget);
|
||||||
|
Objects.requireNonNull(depthTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder builder(AssetLocation id) {
|
||||||
|
return new Builder(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder copy(AssetLocation id) {
|
||||||
|
return new Builder(id, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
AssetLocation id;
|
||||||
|
EnumMap<ShaderType, AssetLocation> shaders = new EnumMap<>(ShaderType.class);
|
||||||
|
ObjectList<String> attributeNames = new ObjectArrayList<>();
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
ObjectList<List<BufferAttribute>> attributes = ObjectArrayList.wrap(new List[8]);
|
||||||
|
ObjectSet<String> uniforms = new ObjectOpenHashSet<>();
|
||||||
|
ObjectSet<String> samplers = new ObjectOpenHashSet<>();
|
||||||
|
DrawMode drawMode;
|
||||||
|
PolygonMode fillMode = PolygonMode.FILL;
|
||||||
|
boolean cullBack = true;
|
||||||
|
ColorTarget colorTarget = ColorTarget.DEFAULT;
|
||||||
|
DepthTarget depthTarget = DepthTarget.DEFAULT;
|
||||||
|
|
||||||
|
private Builder(AssetLocation id) {
|
||||||
|
this.id = Objects.requireNonNull(id);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Builder(AssetLocation id, ShaderPipeline line) {
|
||||||
|
this(id);
|
||||||
|
shaders.putAll(line.shaders());
|
||||||
|
attributeNames.addAll(line.attributeNames());
|
||||||
|
for(int i = 0,m=line.attributes().size();i<m;i++) {
|
||||||
|
attributes.set(i, line.attributes().get(i));
|
||||||
|
}
|
||||||
|
uniforms.addAll(line.uniforms());
|
||||||
|
samplers.addAll(line.samplers());
|
||||||
|
drawMode = line.mode();
|
||||||
|
fillMode = line.fillMode();
|
||||||
|
cullBack = line.cullBack();
|
||||||
|
colorTarget = line.colorTarget();
|
||||||
|
depthTarget = line.depthTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withShader(ShaderType type, AssetLocation location) {
|
||||||
|
shaders.put(Objects.requireNonNull(type, "Shouldn't be null"), Objects.requireNonNull(location, "Resource shouldn't be null"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withUniform(String uniform) {
|
||||||
|
uniforms.add(Objects.requireNonNull(uniform));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withSampler(String sampler) {
|
||||||
|
samplers.add(Objects.requireNonNull(sampler));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withDrawMode(DrawMode mode) {
|
||||||
|
drawMode = Objects.requireNonNull(mode);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withFillMode(PolygonMode mode) {
|
||||||
|
this.fillMode = Objects.requireNonNull(mode);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withBackCulling(boolean cull) {
|
||||||
|
this.cullBack = cull;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withAttributeNames(String... names) {
|
||||||
|
this.attributeNames.clear();
|
||||||
|
this.attributeNames.addAll(names);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withBufferFormat(int index, BufferAttribute...attributes) {
|
||||||
|
if(index < 0 || index >= 8) throw new IndexOutOfBoundsException(index);
|
||||||
|
this.attributes.set(index, new ImmutableObjectList<>(attributes));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder clearBufferFormat(int index) {
|
||||||
|
if(index < 0 || index >= 8) throw new IndexOutOfBoundsException(index);
|
||||||
|
attributes.set(index, null);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withColorTarget(ColorTarget target) {
|
||||||
|
this.colorTarget = Objects.requireNonNull(target);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withDepthTarget(DepthTarget target) {
|
||||||
|
this.depthTarget = Objects.requireNonNull(target);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ShaderPipeline build() {
|
||||||
|
if(shaders.isEmpty()) throw new IllegalStateException("Shaders must be provided in a Shader Pipeline");
|
||||||
|
return new ShaderPipeline(id, Collections.unmodifiableMap(shaders), attributes.unmodifiable(), attributeNames.unmodifiable(), uniforms.unmodifiable(), samplers.unmodifiable(), Objects.requireNonNull(drawMode, "Draw Mode has to be defined"), fillMode, cullBack, colorTarget, depthTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
package speiger.src.coreengine.graphics.api.shader.states;
|
||||||
|
|
||||||
|
public enum BlendFactor {
|
||||||
|
ZERO,
|
||||||
|
ONE,
|
||||||
|
CONSTANT_COLOR,
|
||||||
|
CONSTANT_ALPHA,
|
||||||
|
SRC_COLOR,
|
||||||
|
SRC_ALPHA,
|
||||||
|
DST_COLOR,
|
||||||
|
DST_ALPHA,
|
||||||
|
ONE_MINUS_SRC_COLOR,
|
||||||
|
ONE_MINUS_SRC_ALPHA,
|
||||||
|
ONE_MINUS_DST_COLOR,
|
||||||
|
ONE_MINUS_DST_ALPHA,
|
||||||
|
ONE_MINUS_CONSTANT_COLOR,
|
||||||
|
ONE_MINUS_CONSTANT_ALPHA,
|
||||||
|
SRC_ALPHA_SATURATE;
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package speiger.src.coreengine.graphics.api.shader.states;
|
||||||
|
|
||||||
|
public record BlendFunction(BlendFactor colorSource, BlendFactor alphaSource, BlendFactor colorTarget, BlendFactor alphaTarget) {
|
||||||
|
public BlendFunction(BlendFactor source, BlendFactor target) {
|
||||||
|
this(source, BlendFactor.ONE, target, BlendFactor.ZERO);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
package speiger.src.coreengine.graphics.api.shader.states;
|
||||||
|
|
||||||
|
public enum DrawMode {
|
||||||
|
POINT(1),
|
||||||
|
LINES(2),
|
||||||
|
LINE_STRIP(2, true),
|
||||||
|
LINE_LOOP(2, true),
|
||||||
|
TRIANGLES(3),
|
||||||
|
TRIANGLE_STRIP(3, true),
|
||||||
|
TRIANGLE_FAN(3, true),
|
||||||
|
QUADS(4);
|
||||||
|
|
||||||
|
int length;
|
||||||
|
boolean isConnective;
|
||||||
|
|
||||||
|
private DrawMode(int length) {
|
||||||
|
this(length, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DrawMode(int length, boolean isConnective) {
|
||||||
|
this.length = length;
|
||||||
|
this.isConnective = isConnective;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int primitiveLength() { return length; }
|
||||||
|
public boolean isConnective() { return isConnective; }
|
||||||
|
public int indeciesCount(int vertecies) {
|
||||||
|
return switch(this) {
|
||||||
|
case POINT, LINE_STRIP, TRIANGLES, TRIANGLE_STRIP, TRIANGLE_FAN -> vertecies;
|
||||||
|
case LINES, QUADS -> vertecies / 4 * 6;
|
||||||
|
default -> 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,76 @@
|
|||||||
|
package speiger.src.coreengine.graphics.api.shader.states;
|
||||||
|
|
||||||
|
public enum GraphicsDataType {
|
||||||
|
BYTE("byte", 1, PrimitiveType.BYTE),
|
||||||
|
UNSIGNED_BYTE("u_byte", 1, PrimitiveType.BYTE, true, false),
|
||||||
|
SHORT("short", 2, PrimitiveType.SHORT),
|
||||||
|
UNSIGNED_SHORT("u_short", 2, PrimitiveType.SHORT, true, false),
|
||||||
|
INT("int", 4, PrimitiveType.INT),
|
||||||
|
UNSIGNED_INT("u_int", 4, PrimitiveType.INT, true, false),
|
||||||
|
FLOAT("float", 4, PrimitiveType.FLOAT),
|
||||||
|
DOUBLE("double", 8, PrimitiveType.DOUBLE),
|
||||||
|
|
||||||
|
//CompressedTypes
|
||||||
|
UNSIGNED_3_3_2("u_byte_3_3_2", 1, PrimitiveType.BYTE),
|
||||||
|
UNSIGNED_2_3_3_REV("u_byte_2_3_3_rev", 1, PrimitiveType.BYTE),
|
||||||
|
UNSIGNED_5_6_5("u_short_5_6_5", 2, PrimitiveType.SHORT),
|
||||||
|
UNSIGNED_5_6_5_REV("u_short_5_6_5_rev", 2, PrimitiveType.SHORT),
|
||||||
|
UNSIGNED_4_4_4_4("u_short_4_4_4_4", 2, PrimitiveType.SHORT),
|
||||||
|
UNSIGNED_4_4_4_4_REV("u_short_4_4_4_4_rev", 2, PrimitiveType.SHORT),
|
||||||
|
UNSIGNED_5_5_5_1("u_short_5_5_5_1", 2, PrimitiveType.SHORT),
|
||||||
|
UNSIGNED_1_5_5_5_REV("u_short_1_5_5_5_rev", 2, PrimitiveType.SHORT),
|
||||||
|
UNSIGNED_8_8_8_8("u_int_8_8_8_8", 4, PrimitiveType.INT),
|
||||||
|
UNSIGNED_8_8_8_8_REV("u_int_8_8_8_8_rev", 4, PrimitiveType.INT),
|
||||||
|
UNSIGNED_10_10_10_2("u_int_10_10_10_2", 4, PrimitiveType.INT),
|
||||||
|
UNSIGNED_2_10_10_10_REV("u_int_2_10_10_10_rev", 4, PrimitiveType.INT),
|
||||||
|
|
||||||
|
UNSIGNED_INT_10F_11F_11F_REV("u_int_10_11_11_rev", 4, PrimitiveType.INT),
|
||||||
|
UNSIGNED_INT_5_9_9_9_REV("u_int_5_9_9_9_rev", 4, PrimitiveType.INT);
|
||||||
|
|
||||||
|
String name;
|
||||||
|
int byteSize;
|
||||||
|
PrimitiveType type;
|
||||||
|
boolean supportsIBO;
|
||||||
|
boolean isCompound;
|
||||||
|
|
||||||
|
private GraphicsDataType(String name, int byteSize, PrimitiveType type, boolean supportsIBO, boolean isCompound) {
|
||||||
|
this.name = name;
|
||||||
|
this.byteSize = byteSize;
|
||||||
|
this.type = type;
|
||||||
|
this.supportsIBO = supportsIBO;
|
||||||
|
this.isCompound = isCompound;
|
||||||
|
}
|
||||||
|
|
||||||
|
private GraphicsDataType(String name, int byteSize, PrimitiveType type, boolean isCompound) {
|
||||||
|
this(name, byteSize, type, false, isCompound);
|
||||||
|
}
|
||||||
|
|
||||||
|
private GraphicsDataType(String name, int byteSize, PrimitiveType type) {
|
||||||
|
this(name, byteSize, type, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String idName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int byteSize() {
|
||||||
|
return byteSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PrimitiveType type() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsIBO() {
|
||||||
|
return supportsIBO;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCompound() {
|
||||||
|
return isCompound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size(int attributes) {
|
||||||
|
return isCompound ? byteSize : attributes * byteSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package speiger.src.coreengine.graphics.api.shader.states;
|
||||||
|
|
||||||
|
public enum PolygonMode {
|
||||||
|
POINT,
|
||||||
|
LINE,
|
||||||
|
FILL;
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
package speiger.src.coreengine.graphics.api.shader.states;
|
||||||
|
|
||||||
|
public enum PrimitiveType {
|
||||||
|
BYTE,
|
||||||
|
SHORT,
|
||||||
|
INT,
|
||||||
|
LONG,
|
||||||
|
FLOAT,
|
||||||
|
DOUBLE;
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package speiger.src.coreengine.graphics.api.shader.states;
|
||||||
|
|
||||||
|
public enum ShaderType {
|
||||||
|
VERTEX,
|
||||||
|
FRAGMENT,
|
||||||
|
GEOMETRY,
|
||||||
|
TESSELATION_CONTROL,
|
||||||
|
TESSELATION_EVALUATION;
|
||||||
|
}
|
||||||
@ -1,12 +1,24 @@
|
|||||||
package speiger.src.coreengine.graphics.api.texture;
|
package speiger.src.coreengine.graphics.api.texture;
|
||||||
|
|
||||||
import speiger.src.coreengine.graphics.api.core.GraphicsResource;
|
import speiger.src.coreengine.graphics.api.utils.GraphicsResource;
|
||||||
|
|
||||||
public abstract class Texture implements GraphicsResource {
|
public abstract class Texture implements GraphicsResource {
|
||||||
final TextureSettings settings;
|
final TextureSettings settings;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
|
||||||
public Texture(TextureSettings settings) {
|
public Texture(TextureSettings settings, int width, int height) {
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int width() {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int height() {
|
||||||
|
return height;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextureSettings settings() {
|
public TextureSettings settings() {
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
package speiger.src.coreengine.graphics.api.texture;
|
package speiger.src.coreengine.graphics.api.texture;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.OptionalInt;
|
import java.util.OptionalInt;
|
||||||
@ -11,7 +10,17 @@ import speiger.src.coreengine.graphics.api.texture.states.SwizzleMask;
|
|||||||
import speiger.src.coreengine.graphics.api.texture.states.TextureFormat;
|
import speiger.src.coreengine.graphics.api.texture.states.TextureFormat;
|
||||||
import speiger.src.coreengine.graphics.api.texture.states.TextureType;
|
import speiger.src.coreengine.graphics.api.texture.states.TextureType;
|
||||||
|
|
||||||
public record TextureSettings(TextureType type, TextureFormat internal, TextureFormat external, boolean generateMipmapping, OptionalInt baseLevel, OptionalInt maxLevel, List<Optional<SwizzleMask>> swizzle, Optional<StencilType> stencilType) {
|
public record TextureSettings(TextureType type, TextureFormat internal, TextureFormat external, boolean generateMipmapping, OptionalInt baseLevel, OptionalInt maxLevel, ImmutableObjectList<Optional<SwizzleMask>> swizzle, Optional<StencilType> stencilType) {
|
||||||
|
|
||||||
|
public TextureSettings {
|
||||||
|
Objects.requireNonNull(type, "Texture Type shouldn't be null");
|
||||||
|
Objects.requireNonNull(internal, "Internal Format shouldn't be null");
|
||||||
|
Objects.requireNonNull(external, "External Format shouldn't be null");
|
||||||
|
Objects.requireNonNull(baseLevel);
|
||||||
|
Objects.requireNonNull(maxLevel);
|
||||||
|
Objects.requireNonNull(swizzle);
|
||||||
|
Objects.requireNonNull(stencilType);
|
||||||
|
}
|
||||||
|
|
||||||
public Builder copy() { return new Builder(this); }
|
public Builder copy() { return new Builder(this); }
|
||||||
public static Builder builder() { return new Builder(); }
|
public static Builder builder() { return new Builder(); }
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
package speiger.src.coreengine.graphics.api.texture.states;
|
package speiger.src.coreengine.graphics.api.texture.states;
|
||||||
|
|
||||||
public enum StencilType {
|
public enum StencilType {
|
||||||
DEPTH_COMPONENT,
|
GL_COMPARE_REF_TO_TEXTURE,
|
||||||
STENCIL_INDEX
|
GL_NONE
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,12 @@
|
|||||||
|
package speiger.src.coreengine.graphics.api.utils;
|
||||||
|
|
||||||
|
public enum AlphaFunction {
|
||||||
|
NEVER,
|
||||||
|
LESS,
|
||||||
|
EQUAL,
|
||||||
|
LEQUAL,
|
||||||
|
GREATER,
|
||||||
|
NOTEQUAL,
|
||||||
|
GEQUAL,
|
||||||
|
ALWAYS;
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package speiger.src.coreengine.graphics.api.core;
|
package speiger.src.coreengine.graphics.api.utils;
|
||||||
|
|
||||||
public interface GraphicsResource extends AutoCloseable {
|
public interface GraphicsResource extends AutoCloseable {
|
||||||
public boolean isRemoved();
|
public boolean isRemoved();
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
package speiger.src.coreengine.graphics.api.utils;
|
||||||
|
|
||||||
|
public interface PushableResource extends AutoCloseable {
|
||||||
|
@Override
|
||||||
|
public void close();
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
package speiger.src.coreengine.graphics.api.vertex;
|
||||||
|
|
||||||
|
public record VertexElement(int size, Usage usage)
|
||||||
|
{
|
||||||
|
public static enum Usage {
|
||||||
|
POS,
|
||||||
|
UV,
|
||||||
|
COLOR,
|
||||||
|
NORMAL,
|
||||||
|
CUSTOM;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,78 @@
|
|||||||
|
package speiger.src.coreengine.graphics.api.vertex;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import speiger.src.collections.ints.lists.IntArrayList;
|
||||||
|
import speiger.src.collections.ints.lists.IntList;
|
||||||
|
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||||
|
import speiger.src.collections.objects.lists.ObjectList;
|
||||||
|
import speiger.src.collections.objects.maps.impl.hash.Object2ObjectLinkedOpenHashMap;
|
||||||
|
import speiger.src.collections.objects.maps.interfaces.Object2ObjectMap;
|
||||||
|
import speiger.src.collections.objects.maps.interfaces.Object2ObjectMap.Entry;
|
||||||
|
import speiger.src.collections.objects.utils.ObjectIterators;
|
||||||
|
import speiger.src.coreengine.graphics.api.vertex.VertexElement.Usage;
|
||||||
|
|
||||||
|
public class VertexFormat implements Iterable<VertexElement> {
|
||||||
|
Object2ObjectMap<String, VertexElement> mappedElements = new Object2ObjectLinkedOpenHashMap<>();
|
||||||
|
ObjectList<VertexElement> elements = new ObjectArrayList<>();
|
||||||
|
Set<Usage> types = EnumSet.noneOf(Usage.class);
|
||||||
|
IntList offsets = new IntArrayList();
|
||||||
|
int totalOffset;
|
||||||
|
|
||||||
|
private VertexFormat() {}
|
||||||
|
|
||||||
|
private VertexFormat(VertexFormat vertexList) {
|
||||||
|
elements.addAll(vertexList.elements);
|
||||||
|
offsets.addAll(vertexList.offsets);
|
||||||
|
totalOffset = vertexList.totalOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder builder(VertexFormat format) {
|
||||||
|
return new Builder(format);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void add(String name, VertexElement element) {
|
||||||
|
if(mappedElements.put(name, element) != null) throw new IllegalStateException("Duplicated Names are not allowed");
|
||||||
|
elements.add(element);
|
||||||
|
offsets.add(totalOffset);
|
||||||
|
totalOffset += element.size();
|
||||||
|
types.add(element.usage());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int totalOffset() { return totalOffset; }
|
||||||
|
public int size() { return elements.size(); }
|
||||||
|
public VertexElement get(int index) { return elements.get(index); }
|
||||||
|
public int offset(int index) { return offsets.getInt(index); }
|
||||||
|
public Iterable<Entry<String, VertexElement>> entrySet() { return mappedElements.object2ObjectEntrySet().unmodifiable(); }
|
||||||
|
@Override
|
||||||
|
public Iterator<VertexElement> iterator() { return ObjectIterators.unmodifiable(elements.iterator()); }
|
||||||
|
public boolean hasType(Usage type) { return types.contains(type); }
|
||||||
|
public boolean hasName(String name) { return mappedElements.containsKey(name); }
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
VertexFormat format;
|
||||||
|
|
||||||
|
public Builder() {
|
||||||
|
format = new VertexFormat();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder(VertexFormat prev) {
|
||||||
|
format = new VertexFormat(prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder add(String name, VertexElement element) {
|
||||||
|
format.add(name, element);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VertexFormat build() {
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,139 @@
|
|||||||
|
package speiger.src.coreengine.graphics.opengl.buffer;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL15;
|
||||||
|
import org.lwjgl.opengl.GL45;
|
||||||
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
|
import speiger.src.collections.ints.misc.pairs.IntObjectPair;
|
||||||
|
import speiger.src.coreengine.graphics.api.buffer.VertexBuffer;
|
||||||
|
import speiger.src.coreengine.graphics.api.buffer.states.BufferState;
|
||||||
|
import speiger.src.coreengine.graphics.api.buffer.states.BufferType;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.GLUtils;
|
||||||
|
import speiger.src.coreengine.rendering.utils.AllocationTracker;
|
||||||
|
import speiger.src.coreengine.utils.io.GameLog;
|
||||||
|
|
||||||
|
public class GLVertexBuffer extends VertexBuffer {
|
||||||
|
int id;
|
||||||
|
public GLVertexBuffer(BufferType type, BufferState usage) {
|
||||||
|
super(type, usage);
|
||||||
|
id = GL45.glCreateBuffers();
|
||||||
|
}
|
||||||
|
|
||||||
|
public GLVertexBuffer(BufferType type, BufferState usage, int totalBytes) {
|
||||||
|
super(type, usage);
|
||||||
|
id = GL45.glCreateBuffers();
|
||||||
|
bind().allocate(totalBytes).unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int id() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRemoved() {
|
||||||
|
return id == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
if(id == 0) return;
|
||||||
|
GL15.glDeleteBuffers(id);
|
||||||
|
id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GLVertexBuffer bind() {
|
||||||
|
GL15.glBindBuffer(GLUtils.toGL(type), id);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GLVertexBuffer unbind() {
|
||||||
|
GL15.glBindBuffer(GLUtils.toGL(type), 0);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GLVertexBuffer allocate(int totalBytes) {
|
||||||
|
this.size = totalBytes;
|
||||||
|
GL45.glNamedBufferData(id, totalBytes, GLUtils.toGL(usage));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GLVertexBuffer set(long pointer, int totalBytes) {
|
||||||
|
this.size = totalBytes;
|
||||||
|
GL45.nglNamedBufferData(id, totalBytes, pointer, GLUtils.toGL(usage));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GLVertexBuffer fill(long pointer, int totalBytes, int offset) {
|
||||||
|
GL45.nglNamedBufferSubData(id, offset, totalBytes, pointer);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GLVertexBuffer read(long pointer, int totalBytes, int offset) {
|
||||||
|
GL45.nglGetNamedBufferSubData(id, offset, totalBytes, pointer);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GLVertexBuffer fill(int offset, List<IntObjectPair<byte[]>> data) {
|
||||||
|
if(data.size() > 0) {
|
||||||
|
ByteBuffer buffer = GL45.glMapNamedBuffer(id, GL15.GL_WRITE_ONLY);
|
||||||
|
for(int i = 0,m = data.size();i < m;i++) {
|
||||||
|
IntObjectPair<byte[]> entry = data.get(i);
|
||||||
|
buffer.position(entry.getIntKey() + offset);
|
||||||
|
buffer.put(entry.getValue());
|
||||||
|
}
|
||||||
|
buffer.flip();
|
||||||
|
if(!GL45.glUnmapNamedBuffer(id)) GameLog.info("Memory Corruption?");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GLVertexBuffer shrink(int newSize) {
|
||||||
|
if(size <= newSize) throw new IllegalArgumentException("New Size ["+newSize+"] is bigger then the buffer ["+size+"]");
|
||||||
|
ByteBuffer buffer = GL45.glMapNamedBuffer(id, GL15.GL_READ_WRITE);
|
||||||
|
if(size != buffer.remaining()) throw new IllegalStateException("Grow Function found inconsisten data: Found=["+buffer.remaining()+"], Expected=["+size+"]");
|
||||||
|
ByteBuffer newBuff = MemoryUtil.memAlloc(newSize);
|
||||||
|
MemoryUtil.memCopy(MemoryUtil.memAddress(buffer), MemoryUtil.memAddress(newBuff), newSize);
|
||||||
|
newBuff.position(newSize).flip();
|
||||||
|
GL45.glUnmapNamedBuffer(id);
|
||||||
|
|
||||||
|
set(MemoryUtil.memAddress(newBuff), newSize);
|
||||||
|
MemoryUtil.memFree(newBuff);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GLVertexBuffer grow(int newSize) {
|
||||||
|
if(size >= newSize) throw new IllegalArgumentException("New Size ["+newSize+"] is smaller then the buffer ["+size+"]");
|
||||||
|
ByteBuffer buffer = GL45.glMapNamedBuffer(id, GL15.GL_READ_ONLY);
|
||||||
|
if(size != buffer.remaining()) throw new IllegalStateException("Grow Function found inconsisten data: Found=["+buffer.remaining()+"], Expected=["+size+"]");
|
||||||
|
ByteBuffer newBuff = MemoryUtil.memAlloc(newSize);
|
||||||
|
MemoryUtil.memCopy(MemoryUtil.memAddress(buffer), MemoryUtil.memAddress(newBuff), size);
|
||||||
|
newBuff.position(newSize).flip();
|
||||||
|
GL45.glUnmapNamedBuffer(id);
|
||||||
|
|
||||||
|
set(MemoryUtil.memAddress(newBuff), newSize);
|
||||||
|
MemoryUtil.memFree(newBuff);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GLVertexBuffer shift(int source, int dest, int length) {
|
||||||
|
if(source < 0 || source + length >= size) throw new ArrayIndexOutOfBoundsException();
|
||||||
|
if(dest < 0 || dest + length >= size) throw new ArrayIndexOutOfBoundsException();
|
||||||
|
GL45.glCopyNamedBufferSubData(id, id, source, dest, length);
|
||||||
|
AllocationTracker.INSTANCE.addGPUBytes(length*2);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package speiger.src.coreengine.graphics.opengl.core;
|
||||||
|
|
||||||
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.graphics.api.core.Graphics;
|
||||||
|
import speiger.src.coreengine.rendering.input.window.Window;
|
||||||
|
|
||||||
|
public class GLGraphics implements Graphics {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "OpenGL";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setupWindowArguments() {
|
||||||
|
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||||
|
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||||
|
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, GLFW.GLFW_OPENGL_CORE_PROFILE);
|
||||||
|
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_FORWARD_COMPAT, GLFW.GLFW_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GLGraphicsDevice createDevice(Window window) {
|
||||||
|
return new GLGraphicsDevice(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,79 @@
|
|||||||
|
package speiger.src.coreengine.graphics.opengl.core;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL12;
|
||||||
|
import org.lwjgl.opengl.GL33;
|
||||||
|
import org.lwjgl.opengl.GL43;
|
||||||
|
import org.lwjgl.opengl.GL45;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.graphics.api.buffer.states.BufferState;
|
||||||
|
import speiger.src.coreengine.graphics.api.buffer.states.BufferType;
|
||||||
|
import speiger.src.coreengine.graphics.api.core.GraphicsCommandQueue;
|
||||||
|
import speiger.src.coreengine.graphics.api.core.GraphicsDevice;
|
||||||
|
import speiger.src.coreengine.graphics.api.core.GraphicsSurface;
|
||||||
|
import speiger.src.coreengine.graphics.api.sampler.SamplerSettings;
|
||||||
|
import speiger.src.coreengine.graphics.api.texture.TextureSettings;
|
||||||
|
import speiger.src.coreengine.graphics.api.texture.states.SwizzleMask;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.buffer.GLVertexBuffer;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.sampler.GLSampler;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.texture.GLTexture;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.GLFunctions;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.GLUtils;
|
||||||
|
import speiger.src.coreengine.rendering.input.window.Window;
|
||||||
|
|
||||||
|
public class GLGraphicsDevice implements GraphicsDevice {
|
||||||
|
Window owner;
|
||||||
|
|
||||||
|
public GLGraphicsDevice(Window owner) {
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GraphicsSurface createSurface() {
|
||||||
|
return new GLSurface(owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GraphicsCommandQueue getQueue() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GLVertexBuffer createBuffer(BufferType type, BufferState state) {
|
||||||
|
return new GLVertexBuffer(Objects.requireNonNull(type), Objects.requireNonNull(state));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GLVertexBuffer createBuffer(BufferType type, BufferState state, int allocatedBytes) {
|
||||||
|
if(allocatedBytes <= 0) throw new IllegalArgumentException("Allocated bytes are invalid");
|
||||||
|
return new GLVertexBuffer(Objects.requireNonNull(type), Objects.requireNonNull(state), allocatedBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GLTexture createTexture(TextureSettings settings, int width, int height) {
|
||||||
|
if(width < 0) throw new IllegalArgumentException("Width ["+width+"] is invalid");
|
||||||
|
if(height < 0) throw new IllegalArgumentException("Height ["+height+"] is invalid");
|
||||||
|
int id = GLFunctions.createTexture(settings.type());
|
||||||
|
settings.stencilType().ifPresent(T -> GL45.glTextureParameteri(id, GL43.GL_DEPTH_STENCIL_TEXTURE_MODE, GLUtils.toGL(T)));
|
||||||
|
settings.baseLevel().ifPresent(T -> GL45.glTextureParameteri(id, GL12.GL_TEXTURE_BASE_LEVEL, T));
|
||||||
|
settings.maxLevel().ifPresent(T -> GL45.glTextureParameteri(id, GL12.GL_TEXTURE_MAX_LEVEL, T));
|
||||||
|
if(settings.hasSwizzle()) {
|
||||||
|
List<Optional<SwizzleMask>> masks = settings.swizzle();
|
||||||
|
GL45.glTextureParameterIiv(id, GL33.GL_TEXTURE_SWIZZLE_RGBA, new int[] {
|
||||||
|
GLUtils.toGL(masks.get(0).orElse(SwizzleMask.RED)),
|
||||||
|
GLUtils.toGL(masks.get(1).orElse(SwizzleMask.GREEN)),
|
||||||
|
GLUtils.toGL(masks.get(2).orElse(SwizzleMask.BLUE)),
|
||||||
|
GLUtils.toGL(masks.get(3).orElse(SwizzleMask.ALPHA)),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return new GLTexture(settings, id, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GLSampler createSampler(SamplerSettings settings) {
|
||||||
|
return new GLSampler(Objects.requireNonNull(settings));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
package speiger.src.coreengine.graphics.opengl.core;
|
||||||
|
|
||||||
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.graphics.api.core.GraphicsSurface;
|
||||||
|
import speiger.src.coreengine.rendering.input.window.Window;
|
||||||
|
|
||||||
|
public class GLSurface implements GraphicsSurface {
|
||||||
|
Window window;
|
||||||
|
|
||||||
|
public GLSurface(Window window) {
|
||||||
|
this.window = window;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setVsync(boolean value) {
|
||||||
|
window.vsync(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beginFrame() {
|
||||||
|
GLFW.glfwPollEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void finishFrame() {
|
||||||
|
window.handleInput();
|
||||||
|
window.finishFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
package speiger.src.coreengine.graphics.opengl.sampler;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
import org.lwjgl.opengl.GL12;
|
||||||
|
import org.lwjgl.opengl.GL33;
|
||||||
|
import org.lwjgl.opengl.GL45;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.graphics.api.sampler.Sampler;
|
||||||
|
import speiger.src.coreengine.graphics.api.sampler.SamplerSettings;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.GLUtils;
|
||||||
|
|
||||||
|
public class GLSampler extends Sampler {
|
||||||
|
int id;
|
||||||
|
|
||||||
|
public GLSampler(SamplerSettings settings) {
|
||||||
|
super(settings);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void init() {
|
||||||
|
this.id = GL45.glCreateSamplers();
|
||||||
|
GL45.glSamplerParameteri(id, GL11.GL_TEXTURE_WRAP_S, GLUtils.toGL(settings.wrapS()));
|
||||||
|
GL45.glSamplerParameteri(id, GL11.GL_TEXTURE_WRAP_T, GLUtils.toGL(settings.wrapT()));
|
||||||
|
settings.wrapR().ifPresent(T -> GL45.glSamplerParameteri(id, GL12.GL_TEXTURE_WRAP_R, GLUtils.toGL(T)));
|
||||||
|
GL45.glSamplerParameteri(id, GL11.GL_TEXTURE_WRAP_S, GLUtils.toGL(settings.wrapS()));
|
||||||
|
GL45.glSamplerParameteri(id, GL11.GL_TEXTURE_MIN_FILTER, GLUtils.toGL(settings.minSample()));
|
||||||
|
GL45.glSamplerParameteri(id, GL11.GL_TEXTURE_MAG_FILTER, GLUtils.toGL(settings.magSample()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRemoved() {
|
||||||
|
return id == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
if(id == 0) return;
|
||||||
|
GL33.glDeleteSamplers(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
package speiger.src.coreengine.graphics.opengl.texture;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.graphics.api.texture.Texture;
|
||||||
|
import speiger.src.coreengine.graphics.api.texture.TextureSettings;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.GLFunctions;
|
||||||
|
|
||||||
|
public class GLTexture extends Texture {
|
||||||
|
int id;
|
||||||
|
|
||||||
|
public GLTexture(TextureSettings settings, int id, int width, int height) {
|
||||||
|
super(settings, width, height);
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRemoved() {
|
||||||
|
return id == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
if(id == 0) return;
|
||||||
|
GLFunctions.deleteTextures(id);
|
||||||
|
id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package speiger.src.coreengine.graphics.opengl.utils;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
import org.lwjgl.opengl.GL45;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.graphics.api.texture.states.TextureType;
|
||||||
|
|
||||||
|
public class GLFunctions {
|
||||||
|
|
||||||
|
public static int createTexture(TextureType type) {
|
||||||
|
return GL45.glCreateTextures(GLUtils.toGL(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void deleteTextures(int... id) {
|
||||||
|
GL11.glDeleteTextures(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,129 @@
|
|||||||
|
package speiger.src.coreengine.graphics.opengl.utils;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
import org.lwjgl.opengl.GL12;
|
||||||
|
import org.lwjgl.opengl.GL13;
|
||||||
|
import org.lwjgl.opengl.GL14;
|
||||||
|
import org.lwjgl.opengl.GL15;
|
||||||
|
import org.lwjgl.opengl.GL21;
|
||||||
|
import org.lwjgl.opengl.GL30;
|
||||||
|
import org.lwjgl.opengl.GL31;
|
||||||
|
import org.lwjgl.opengl.GL32;
|
||||||
|
import org.lwjgl.opengl.GL40;
|
||||||
|
import org.lwjgl.opengl.GL42;
|
||||||
|
import org.lwjgl.opengl.GL43;
|
||||||
|
import org.lwjgl.opengl.GL44;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.graphics.api.buffer.states.BufferState;
|
||||||
|
import speiger.src.coreengine.graphics.api.buffer.states.BufferType;
|
||||||
|
import speiger.src.coreengine.graphics.api.sampler.states.BorderMode;
|
||||||
|
import speiger.src.coreengine.graphics.api.sampler.states.SampleMode;
|
||||||
|
import speiger.src.coreengine.graphics.api.texture.states.StencilType;
|
||||||
|
import speiger.src.coreengine.graphics.api.texture.states.SwizzleMask;
|
||||||
|
import speiger.src.coreengine.graphics.api.texture.states.TextureType;
|
||||||
|
import speiger.src.coreengine.graphics.api.utils.AlphaFunction;
|
||||||
|
|
||||||
|
public class GLUtils {
|
||||||
|
//Buffer Begin
|
||||||
|
|
||||||
|
public static int toGL(BufferType type) {
|
||||||
|
return switch(type) {
|
||||||
|
case ARRAY_BUFFER -> GL15.GL_ARRAY_BUFFER;
|
||||||
|
case ELEMENT_BUFFER -> GL15.GL_ELEMENT_ARRAY_BUFFER;
|
||||||
|
case UNIFORM_BUFFER -> GL31.GL_UNIFORM_BUFFER;
|
||||||
|
case DRAW_INDIRECT_BUFFER -> GL40.GL_DRAW_INDIRECT_BUFFER;
|
||||||
|
case TEXTURE_BUFFER -> GL31.GL_TEXTURE_BUFFER;
|
||||||
|
case PIXEL_PACK_BUFFER -> GL21.GL_PIXEL_PACK_BUFFER;
|
||||||
|
case PIXEL_UNPACK_BUFFER -> GL21.GL_PIXEL_UNPACK_BUFFER;
|
||||||
|
case TRANSFORM_FEEDBACK_BUFFER -> GL30.GL_TRANSFORM_FEEDBACK_BUFFER;
|
||||||
|
case COPY_READ_BUFFER -> GL31.GL_COPY_READ_BUFFER;
|
||||||
|
case COPY_WRITE_BUFFER -> GL31.GL_COPY_WRITE_BUFFER;
|
||||||
|
case ATOMIC_COUNTER_BUFFER -> GL42.GL_ATOMIC_COUNTER_BUFFER;
|
||||||
|
case DISPATCH_INDIRECT_BUFFER -> GL43.GL_DISPATCH_INDIRECT_BUFFER;
|
||||||
|
case SHADER_STORAGE_BUFFER -> GL43.GL_SHADER_STORAGE_BUFFER;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int toGL(BufferState state) {
|
||||||
|
return switch(state) {
|
||||||
|
case STATIC_DRAW -> GL15.GL_STATIC_DRAW;
|
||||||
|
case STATIC_READ -> GL15.GL_STATIC_READ;
|
||||||
|
case STATIC_COPY -> GL15.GL_STATIC_COPY;
|
||||||
|
case STREAM_DRAW -> GL15.GL_STREAM_DRAW;
|
||||||
|
case STREAM_READ -> GL15.GL_STREAM_READ;
|
||||||
|
case STREAM_COPY -> GL15.GL_STREAM_COPY;
|
||||||
|
case DYNAMIC_DRAW -> GL15.GL_DYNAMIC_DRAW;
|
||||||
|
case DYNAMIC_READ -> GL15.GL_DYNAMIC_READ;
|
||||||
|
case DYNAMIC_COPY -> GL15.GL_DYNAMIC_COPY;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//Texture Begin
|
||||||
|
|
||||||
|
public static int toGL(TextureType type) {
|
||||||
|
return switch(type) {
|
||||||
|
case TEXTURE_1D -> GL11.GL_TEXTURE_1D;
|
||||||
|
case TEXTURE_1D_ARRAY -> GL30.GL_TEXTURE_1D_ARRAY;
|
||||||
|
case TEXTURE_2D -> GL11.GL_TEXTURE_2D;
|
||||||
|
case TEXTURE_2D_ARRAY -> GL30.GL_TEXTURE_2D_ARRAY;
|
||||||
|
case TEXTURE_2D_MULTISAMPLE -> GL32.GL_TEXTURE_2D_MULTISAMPLE;
|
||||||
|
case TEXTURE_2D_MULTISAMPLE_ARRAY -> GL32.GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
|
||||||
|
case TEXTURE_3D -> GL12.GL_TEXTURE_3D;
|
||||||
|
case TEXTURE_CUBE_MAP -> GL32.GL_TEXTURE_CUBE_MAP;
|
||||||
|
case TEXTURE_CUBE_MAP_ARRAY -> GL40.GL_TEXTURE_CUBE_MAP_ARRAY;
|
||||||
|
case TEXTURE_RECTANGLE -> GL31.GL_TEXTURE_RECTANGLE;
|
||||||
|
case TEXTURE_BUFFER -> GL31.GL_TEXTURE_BUFFER;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int toGL(SwizzleMask mask) {
|
||||||
|
return switch(mask) {
|
||||||
|
case RED -> GL11.GL_RED;
|
||||||
|
case GREEN -> GL11.GL_GREEN;
|
||||||
|
case BLUE -> GL11.GL_BLUE;
|
||||||
|
case ALPHA -> GL11.GL_ALPHA;
|
||||||
|
case ZERO -> GL11.GL_ZERO;
|
||||||
|
case ONE -> GL11.GL_ONE;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int toGL(StencilType type) {
|
||||||
|
return type == StencilType.GL_COMPARE_REF_TO_TEXTURE ? GL30.GL_COMPARE_REF_TO_TEXTURE : GL11.GL_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Sampler begin
|
||||||
|
public static int toGL(BorderMode mode) {
|
||||||
|
return switch(mode) {
|
||||||
|
case CLAMP_TO_BORDER -> GL13.GL_CLAMP_TO_BORDER;
|
||||||
|
case CLAMP_TO_EDGE -> GL12.GL_CLAMP_TO_EDGE;
|
||||||
|
case MIRRORED_REPEAT -> GL14.GL_MIRRORED_REPEAT;
|
||||||
|
case MIRROR_CLAMP_TO_EDGE -> GL44.GL_MIRROR_CLAMP_TO_EDGE;
|
||||||
|
case REPEAT -> GL11.GL_REPEAT;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int toGL(SampleMode mode) {
|
||||||
|
return switch(mode) {
|
||||||
|
case LINEAR -> GL11.GL_LINEAR;
|
||||||
|
case LINEAR_MIPMAP_LINEAR -> GL11.GL_LINEAR_MIPMAP_LINEAR;
|
||||||
|
case LINEAR_MIPMAP_NEAREST -> GL11.GL_LINEAR_MIPMAP_NEAREST;
|
||||||
|
case NEAREST -> GL11.GL_NEAREST;
|
||||||
|
case NEAREST_MIPMAP_LINEAR -> GL11.GL_NEAREST_MIPMAP_LINEAR;
|
||||||
|
case NEAREST_MIPMAP_NEAREST -> GL11.GL_NEAREST_MIPMAP_NEAREST;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int toGL(AlphaFunction type) {
|
||||||
|
return switch(type) {
|
||||||
|
case ALWAYS -> GL11.GL_ALWAYS;
|
||||||
|
case EQUAL -> GL11.GL_EQUAL;
|
||||||
|
case GEQUAL -> GL11.GL_GEQUAL;
|
||||||
|
case GREATER -> GL11.GL_GREATER;
|
||||||
|
case LEQUAL -> GL11.GL_LEQUAL;
|
||||||
|
case LESS -> GL11.GL_LESS;
|
||||||
|
case NEVER -> GL11.GL_NEVER;
|
||||||
|
case NOTEQUAL -> GL11.GL_NOTEQUAL;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,54 +1,54 @@
|
|||||||
package speiger.src.coreengine.rendering.shader;
|
package speiger.src.coreengine.rendering.shader;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.attribute.FileTime;
|
import java.nio.file.attribute.FileTime;
|
||||||
|
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
public class ShaderCache {
|
public class ShaderCache {
|
||||||
public static final ShaderCache INSTANCE = new ShaderCache();
|
public static final ShaderCache INSTANCE = new ShaderCache();
|
||||||
private Path cache;
|
private Path cache;
|
||||||
|
|
||||||
public void init(Path cache) {
|
public void init(Path cache) {
|
||||||
this.cache = cache;
|
this.cache = cache;
|
||||||
if(Files.notExists(cache)) {
|
if(Files.notExists(cache)) {
|
||||||
try { Files.createDirectories(cache); }
|
try { Files.createDirectories(cache); }
|
||||||
catch(IOException e) {
|
catch(IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
this.cache = null;
|
this.cache = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasCache() {
|
public boolean hasCache() {
|
||||||
return cache != null;
|
return cache != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ByteBuffer readFromCache(String location, FileTime latestSource) {
|
public ByteBuffer readFromCache(String location, FileTime latestSource) {
|
||||||
try { return readFromCacheUnsafe(location, latestSource); }
|
try { return readFromCacheUnsafe(location, latestSource); }
|
||||||
catch(Exception e) { e.printStackTrace(); }
|
catch(Exception e) { e.printStackTrace(); }
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ByteBuffer readFromCacheUnsafe(String location, FileTime latestSource) throws IOException {
|
private ByteBuffer readFromCacheUnsafe(String location, FileTime latestSource) throws IOException {
|
||||||
if(cache == null) return null;
|
if(cache == null) return null;
|
||||||
Path path = cache.resolve(location+".bin");
|
Path path = cache.resolve(location+".bin");
|
||||||
if(Files.exists(path)) {
|
if(Files.exists(path)) {
|
||||||
if(Files.getLastModifiedTime(path).compareTo(latestSource) <= 0) return null;
|
if(Files.getLastModifiedTime(path).compareTo(latestSource) <= 0) return null;
|
||||||
byte[] data = Files.readAllBytes(path);
|
byte[] data = Files.readAllBytes(path);
|
||||||
return MemoryUtil.memAlloc(data.length).put(data).flip();
|
return MemoryUtil.memAlloc(data.length).put(data).flip();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void storeInCache(String location, byte[] data) {
|
public void storeInCache(String location, byte[] data) {
|
||||||
if(cache == null) return;
|
if(cache == null) return;
|
||||||
try { Files.write(cache.resolve(location+".bin"), data); }
|
try { Files.write(cache.resolve(location+".bin"), data); }
|
||||||
catch(Exception e) {
|
catch(Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user