Next Milestone reached.
This commit is contained in:
@@ -5,7 +5,7 @@ connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
|
|||||||
connection.project.dir=
|
connection.project.dir=
|
||||||
eclipse.preferences.version=1
|
eclipse.preferences.version=1
|
||||||
gradle.user.home=
|
gradle.user.home=
|
||||||
java.home=C\:/Program Files/Eclipse Adoptium/jdk25
|
java.home=C\:/Program Files/Java/jdk25
|
||||||
jvm.arguments=
|
jvm.arguments=
|
||||||
offline.mode=false
|
offline.mode=false
|
||||||
override.workspace.settings=true
|
override.workspace.settings=true
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
org.gradle.jvmargs=-Xmx2G
|
org.gradle.jvmargs=-Xmx2G
|
||||||
|
|
||||||
lwjglVersion = 3.3.4
|
lwjglVersion = 3.4.2
|
||||||
lwjglNatives = natives-windows
|
lwjglNatives = natives-windows
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package speiger.src.coreengine.assets.api;
|
package speiger.src.coreengine.assets.api;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.file.FileSystem;
|
||||||
|
import java.nio.file.FileSystems;
|
||||||
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.BasicFileAttributes;
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
@@ -12,7 +14,9 @@ import java.util.function.Consumer;
|
|||||||
import org.jspecify.annotations.NullMarked;
|
import org.jspecify.annotations.NullMarked;
|
||||||
import org.jspecify.annotations.Nullable;
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.assets.impl.FolderAssetPackage;
|
||||||
import speiger.src.coreengine.assets.impl.FolderWatcher.ChangeType;
|
import speiger.src.coreengine.assets.impl.FolderWatcher.ChangeType;
|
||||||
|
import speiger.src.coreengine.assets.impl.ZipAssetPackage;
|
||||||
|
|
||||||
@NullMarked
|
@NullMarked
|
||||||
public interface IAssetPackage extends AutoCloseable {
|
public interface IAssetPackage extends AutoCloseable {
|
||||||
@@ -23,6 +27,23 @@ public interface IAssetPackage extends AutoCloseable {
|
|||||||
IAsset get(ID location);
|
IAsset get(ID location);
|
||||||
void getAll(ID folder, BiConsumer<ID, IAsset> assets);
|
void getAll(ID folder, BiConsumer<ID, IAsset> assets);
|
||||||
|
|
||||||
|
public static IAssetPackage asset(Path path) {
|
||||||
|
return create(path, "assets");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IAssetPackage create(Path path, String baseFolder) {
|
||||||
|
if(Files.exists(path)) {
|
||||||
|
if(Files.isDirectory(path)) return new FolderAssetPackage(path.resolve(baseFolder));
|
||||||
|
if(isZip(path)) return new ZipAssetPackage(path, baseFolder);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isZip(Path path) {
|
||||||
|
try(FileSystem system = FileSystems.newFileSystem(path)) { return "jar".equals(system.provider().getScheme()); }
|
||||||
|
catch(Exception _) { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
public record AssetIdentity(long size, FileTime lastModified) {
|
public record AssetIdentity(long size, FileTime lastModified) {
|
||||||
|
|
||||||
public AssetIdentity(Path path) throws IOException {
|
public AssetIdentity(Path path) throws IOException {
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ public record ID(String domain, String path) implements Comparable<ID> {
|
|||||||
public static final ID of(String location) {
|
public static final ID of(String location) {
|
||||||
Objects.requireNonNull(location);
|
Objects.requireNonNull(location);
|
||||||
int index = location.indexOf(":");
|
int index = location.indexOf(":");
|
||||||
String domain = location.substring(0, index);
|
String domain = index == -1 ? "base" : location.substring(0, index);
|
||||||
String path = location.substring(index + 1);
|
String path = index == -1 ? location : location.substring(index + 1);
|
||||||
if(!isValidDomain(domain)) throw new IllegalArgumentException("Non [a-zA-Z0-9_.-] Character found in domain of location ["+domain+":"+path+"]");
|
if(!isValidDomain(domain)) throw new IllegalArgumentException("Non [a-zA-Z0-9_.-] Character found in domain of location ["+domain+":"+path+"]");
|
||||||
if(!isValidPath(path)) throw new IllegalArgumentException("Non [a-zA-Z0-9/_.-] Character found in path of location ["+domain+":"+path+"]");
|
if(!isValidPath(path)) throw new IllegalArgumentException("Non [a-zA-Z0-9/_.-] Character found in path of location ["+domain+":"+path+"]");
|
||||||
return new ID(domain, path);
|
return new ID(domain, path);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public class Checksums {
|
|||||||
public static class CRC implements IAssetParser<String> {
|
public static class CRC implements IAssetParser<String> {
|
||||||
@Override
|
@Override
|
||||||
public String parse(Path path) throws IOException {
|
public String parse(Path path) throws IOException {
|
||||||
Map<String, Object> files = Files.readAttributes(path, "crc");
|
Map<String, Object> files = Files.readAttributes(path, "*");
|
||||||
if(files.containsKey("crc")) return Long.toHexString(((Long)files.get("crc")) & 0xFFFFFFFFL);
|
if(files.containsKey("crc")) return Long.toHexString(((Long)files.get("crc")) & 0xFFFFFFFFL);
|
||||||
CRC32C crc = new CRC32C();
|
CRC32C crc = new CRC32C();
|
||||||
crc.update(Files.readAllBytes(path));
|
crc.update(Files.readAllBytes(path));
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import java.nio.file.Path;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
@@ -27,6 +28,7 @@ public class AssetManager {
|
|||||||
List<IAssetPackage> packages;
|
List<IAssetPackage> packages;
|
||||||
ReloadTracker tracker = new ReloadTracker();
|
ReloadTracker tracker = new ReloadTracker();
|
||||||
ReloadManager manager;
|
ReloadManager manager;
|
||||||
|
AtomicInteger InUse = new AtomicInteger();
|
||||||
|
|
||||||
public AssetManager(BaseProvider provider) {
|
public AssetManager(BaseProvider provider) {
|
||||||
setPackages(provider);
|
setPackages(provider);
|
||||||
@@ -89,21 +91,29 @@ public class AssetManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public IAssetProvider get() {
|
public IAssetProvider get() {
|
||||||
return new WrappedProvider(provider);
|
InUse.incrementAndGet();
|
||||||
|
return new WrappedProvider(provider, this::manageClose);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void manageClose() throws Exception {
|
||||||
|
if(InUse.decrementAndGet() > 0) return;
|
||||||
|
provider.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class WrappedProvider implements IAssetProvider {
|
public final class WrappedProvider implements IAssetProvider {
|
||||||
BaseProvider provider;
|
BaseProvider provider;
|
||||||
|
AutoCloseable closer;
|
||||||
|
|
||||||
public WrappedProvider(BaseProvider provider) {
|
public WrappedProvider(BaseProvider provider, AutoCloseable closer) {
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
|
this.closer = closer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws Exception {
|
public void close() throws Exception {
|
||||||
BaseProvider provider = this.provider;
|
if(provider == null) return;
|
||||||
this.provider = null;
|
this.provider = null;
|
||||||
provider.close();
|
closer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -5,6 +5,6 @@ import java.util.List;
|
|||||||
import speiger.src.coreengine.assets.api.IAssetPackage;
|
import speiger.src.coreengine.assets.api.IAssetPackage;
|
||||||
import speiger.src.coreengine.assets.api.IAssetProvider;
|
import speiger.src.coreengine.assets.api.IAssetProvider;
|
||||||
|
|
||||||
public interface BaseProvider extends IAssetProvider, AutoCloseable {
|
public interface BaseProvider extends IAssetProvider {
|
||||||
List<IAssetPackage> packages();
|
List<IAssetPackage> packages();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,13 +38,21 @@ public abstract class VertexBuffer implements GraphicsResource {
|
|||||||
|
|
||||||
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) { return set(MemoryUtil.memAddress(buffer), buffer.remaining()); }
|
||||||
return set(MemoryUtil.memAddress(buffer), buffer.remaining());
|
public VertexBuffer set(byte[] data) {
|
||||||
|
ByteBuffer buffer = MemoryUtil.memAlloc(data.length).put(data).flip();
|
||||||
|
set(buffer);
|
||||||
|
MemoryUtil.memFree(buffer);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract VertexBuffer fill(long pointer, int totalBytes, int offset);
|
public abstract VertexBuffer fill(long pointer, int totalBytes, int offset);
|
||||||
public VertexBuffer fill(int offset, ByteBuffer buffer) {
|
public VertexBuffer fill(int offset, ByteBuffer buffer) { return fill(MemoryUtil.memAddress(buffer), buffer.remaining(), offset); }
|
||||||
return fill(MemoryUtil.memAddress(buffer), buffer.remaining(), offset);
|
public VertexBuffer fill(int offset, byte[] data) {
|
||||||
|
ByteBuffer buffer = MemoryUtil.memAlloc(data.length).put(data).flip();
|
||||||
|
fill(offset, buffer);
|
||||||
|
MemoryUtil.memFree(buffer);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract VertexBuffer read(long pointer, int totalBytes, int offset);
|
public abstract VertexBuffer read(long pointer, int totalBytes, int offset);
|
||||||
|
|||||||
+6
-3
@@ -13,10 +13,13 @@ public interface GraphicsCommandBuffer extends GraphicsResource {
|
|||||||
|
|
||||||
GraphicsCommandBuffer pipeline(ShaderPipeline pipeline);
|
GraphicsCommandBuffer pipeline(ShaderPipeline pipeline);
|
||||||
GraphicsCommandBuffer mesh(Mesh mesh);
|
GraphicsCommandBuffer mesh(Mesh mesh);
|
||||||
GraphicsCommandBuffer texture(int set, int binding, Texture texture, Sampler sampler);
|
GraphicsCommandBuffer texture(int binding, Texture texture, Sampler sampler);
|
||||||
GraphicsCommandBuffer uniform(int set, int binding, VertexBuffer buffer);
|
|
||||||
|
|
||||||
GraphicsCommandBuffer drawIndexed(int start, int count);
|
GraphicsCommandBuffer uniform(int binding, VertexBuffer buffer);
|
||||||
|
GraphicsCommandBuffer uniform(int binding, VertexBuffer buffer, long offset, long size);
|
||||||
|
|
||||||
|
GraphicsCommandBuffer drawArrays(int offset, int count);
|
||||||
|
GraphicsCommandBuffer drawElements(int offset, int count);
|
||||||
|
|
||||||
GraphicsCommandBuffer pushScissors(int x, int y, int width, int height);
|
GraphicsCommandBuffer pushScissors(int x, int y, int width, int height);
|
||||||
GraphicsCommandBuffer popScissors();
|
GraphicsCommandBuffer popScissors();
|
||||||
|
|||||||
+9
-12
@@ -1,34 +1,31 @@
|
|||||||
package speiger.src.coreengine.graphics.api.core;
|
package speiger.src.coreengine.graphics.api.core;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.states.GraphicsDataType;
|
||||||
import speiger.src.coreengine.graphics.api.target.RenderTarget;
|
import speiger.src.coreengine.graphics.api.target.RenderTarget;
|
||||||
import speiger.src.coreengine.graphics.api.texture.Texture;
|
import speiger.src.coreengine.graphics.api.texture.Texture;
|
||||||
|
import speiger.src.coreengine.graphics.api.texture.states.TextureFormat;
|
||||||
import speiger.src.coreengine.graphics.api.utils.PushableResource;
|
import speiger.src.coreengine.graphics.api.utils.PushableResource;
|
||||||
import speiger.src.coreengine.math.vector.floats.Vec4f;
|
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_COLOR = 1;
|
||||||
public static final int CLEAR_DEPTH = 2;
|
public static final int CLEAR_DEPTH = 2;
|
||||||
|
public static final int CLEAR_BOTH = 3;
|
||||||
public PushableResource putClearColor(Vec4f color);
|
public PushableResource putClearColor(Vec4f color);
|
||||||
public PushableResource putClearDepth(double value);
|
public PushableResource putClearDepth(double value);
|
||||||
public PushableResource putRenderTarget(RenderTarget target);
|
public PushableResource putRenderTarget(RenderTarget target);
|
||||||
|
public PushableResource pushViewPort(int x, int y, int width, int height);
|
||||||
|
|
||||||
public void clearTexture(int clearParam);
|
public void clearTexture(int clearParam);
|
||||||
public void clearTexture(int x, int y, int width, int height, int clearParam);
|
public void clearTexture(int x, int y, int width, int height, int clearParam);
|
||||||
public void clearTexture(Texture texture, int clearParam);
|
public void clearTexture(Texture texture, int clearParam);
|
||||||
public void clearTexture(Texture texture, int x, int y, int width, int height, int clearParam);
|
public void clearTexture(Texture texture, int x, int y, int width, int height, int clearParam);
|
||||||
|
|
||||||
public void writeToTexture(Texture target, int x, int y, int width, int height, long source);
|
public void writeToTexture(Texture target, TextureFormat format, GraphicsDataType dataType, long source);
|
||||||
public void readFromTexture(Texture source, int x, int y, int width, int height, long target);
|
public default void writeToTexture(Texture target, int x, int y, int width, int height, TextureFormat format, GraphicsDataType dataType, long source) {
|
||||||
|
writeToTexture(target, 0, 0, x, y, width, height, format, dataType, source);
|
||||||
|
}
|
||||||
|
public void writeToTexture(Texture target, int sourceX, int sourceY, int targetX, int targetY, int width, int height, TextureFormat format, GraphicsDataType dataType, long source);
|
||||||
|
|
||||||
public void submitCommands(GraphicsCommandBuffer buffer);
|
public void submitCommands(GraphicsCommandBuffer buffer);
|
||||||
|
|
||||||
public record DrawArea(int x, int y, int width, int height) {
|
|
||||||
public boolean fits(int x, int y, int width, int height) {
|
|
||||||
return x >= x() && y >= y() && x + width < width() && y + height < height();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean fills(int width, int height) {
|
|
||||||
return x == 0 && y == 0 && width == width() && height == height();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,24 +1,28 @@
|
|||||||
package speiger.src.coreengine.graphics.api.core;
|
package speiger.src.coreengine.graphics.api.core;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
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.BufferState;
|
||||||
import speiger.src.coreengine.graphics.api.buffer.states.BufferType;
|
import speiger.src.coreengine.graphics.api.buffer.states.BufferType;
|
||||||
import speiger.src.coreengine.graphics.api.mesh.Mesh;
|
import speiger.src.coreengine.graphics.api.mesh.Mesh;
|
||||||
import speiger.src.coreengine.graphics.api.sampler.Sampler;
|
import speiger.src.coreengine.graphics.api.sampler.Sampler;
|
||||||
import speiger.src.coreengine.graphics.api.sampler.SamplerSettings;
|
import speiger.src.coreengine.graphics.api.sampler.SamplerSettings;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.ShaderPipeline;
|
||||||
import speiger.src.coreengine.graphics.api.texture.Texture;
|
import speiger.src.coreengine.graphics.api.texture.Texture;
|
||||||
import speiger.src.coreengine.graphics.api.texture.TextureSettings;
|
import speiger.src.coreengine.graphics.api.texture.TextureSettings;
|
||||||
import speiger.src.coreengine.graphics.api.utils.ExecutionType;
|
import speiger.src.coreengine.graphics.api.utils.ExecutionType;
|
||||||
import speiger.src.coreengine.rendering.input.window.Window;
|
import speiger.src.coreengine.rendering.input.window.Window;
|
||||||
|
|
||||||
public interface GraphicsDevice {
|
public interface GraphicsDevice {
|
||||||
public Window getWindow();
|
Window window();
|
||||||
public GraphicsSurface createSurface();
|
GraphicsSurface createSurface();
|
||||||
public GraphicsCommandBuffer createCommandBuffer(ExecutionType type);
|
GraphicsCommandBuffer createCommandBuffer(ExecutionType type);
|
||||||
public GraphicsCommandQueue getQueue();
|
GraphicsCommandQueue queue();
|
||||||
public VertexBuffer createBuffer(BufferType type, BufferState state);
|
VertexBuffer createBuffer(BufferType type, BufferState state);
|
||||||
public VertexBuffer createBuffer(BufferType type, BufferState state, int allocatedBytes);
|
VertexBuffer createBuffer(BufferType type, BufferState state, int allocatedBytes);
|
||||||
public Texture createTexture(TextureSettings data, int width, int height);
|
Texture createTexture(TextureSettings data, int width, int height);
|
||||||
public Sampler createSampler(SamplerSettings settings);
|
Sampler createSampler(SamplerSettings settings);
|
||||||
public Mesh createMesh(Mesh.Builder builder);
|
Mesh createMesh(Mesh.Builder builder);
|
||||||
|
void preloadPipelines(List<ShaderPipeline> pipelines);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ public record SamplerSettings(BorderMode wrapS, BorderMode wrapT, Optional<Borde
|
|||||||
Objects.requireNonNull(magSample);
|
Objects.requireNonNull(magSample);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
BorderMode wrapS;
|
BorderMode wrapS;
|
||||||
BorderMode wrapT;
|
BorderMode wrapT;
|
||||||
@@ -23,6 +27,19 @@ public record SamplerSettings(BorderMode wrapS, BorderMode wrapT, Optional<Borde
|
|||||||
SampleMode minSample;
|
SampleMode minSample;
|
||||||
SampleMode magSample;
|
SampleMode magSample;
|
||||||
|
|
||||||
|
public Builder wrap(BorderMode mode) {
|
||||||
|
return wrap(mode, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder wrap(BorderMode mode, boolean includeR) {
|
||||||
|
wrapS = Objects.requireNonNull(mode);
|
||||||
|
wrapT = Objects.requireNonNull(mode);
|
||||||
|
if(includeR) {
|
||||||
|
wrapR = Objects.requireNonNull(mode);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder wrapS(BorderMode mode) {
|
public Builder wrapS(BorderMode mode) {
|
||||||
wrapS = Objects.requireNonNull(mode);
|
wrapS = Objects.requireNonNull(mode);
|
||||||
return this;
|
return this;
|
||||||
@@ -38,6 +55,13 @@ public record SamplerSettings(BorderMode wrapS, BorderMode wrapT, Optional<Borde
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder sampler(SampleMode mode) {
|
||||||
|
minSample = Objects.requireNonNull(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 Builder minSample(SampleMode mode) {
|
public Builder minSample(SampleMode mode) {
|
||||||
minSample = Objects.requireNonNull(mode);
|
minSample = Objects.requireNonNull(mode);
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import java.util.Objects;
|
|||||||
|
|
||||||
import speiger.src.coreengine.graphics.api.utils.AlphaFunction;
|
import speiger.src.coreengine.graphics.api.utils.AlphaFunction;
|
||||||
|
|
||||||
public record DepthTarget(AlphaFunction function, boolean write) {
|
public record DepthTarget(boolean enabled, AlphaFunction function, boolean write) {
|
||||||
public static final DepthTarget DEFAULT = new DepthTarget(AlphaFunction.GEQUAL, true);
|
public static final DepthTarget DEFAULT = new DepthTarget(true, AlphaFunction.GEQUAL, true);
|
||||||
|
|
||||||
public DepthTarget {
|
public DepthTarget {
|
||||||
Objects.requireNonNull(function);
|
Objects.requireNonNull(function);
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
package speiger.src.coreengine.graphics.api.shader;
|
|
||||||
|
|
||||||
import speiger.src.coreengine.graphics.api.buffer.VertexBuffer;
|
|
||||||
import speiger.src.coreengine.graphics.api.buffer.states.IndeciesType;
|
|
||||||
import speiger.src.coreengine.graphics.api.core.GraphicsCommandQueue.DrawArea;
|
|
||||||
import speiger.src.coreengine.graphics.api.sampler.Sampler;
|
|
||||||
import speiger.src.coreengine.graphics.api.texture.Texture;
|
|
||||||
import speiger.src.coreengine.graphics.api.utils.ScissorsManager;
|
|
||||||
|
|
||||||
public abstract class RenderPass implements AutoCloseable {
|
|
||||||
protected final DrawArea area;
|
|
||||||
protected final boolean hasColor;
|
|
||||||
protected final boolean hasDepth;
|
|
||||||
protected final ScissorsManager scissors = new ScissorsManager(16);
|
|
||||||
|
|
||||||
public RenderPass(DrawArea area, boolean hasColor, boolean hasDepth) {
|
|
||||||
this.area = area;
|
|
||||||
this.hasColor = hasColor;
|
|
||||||
this.hasDepth = hasDepth;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void pushScissors(int x, int y, int width, int height) {
|
|
||||||
if(area != null && area.fits(x, y, width, height)) {
|
|
||||||
//TODO implement logging
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
scissors.push(x, y, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void popScissors() {
|
|
||||||
scissors.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void setShader(ShaderPipeline pipeline);
|
|
||||||
public abstract void setTexture(String name, Texture texture, Sampler sampler);
|
|
||||||
public abstract void clearTextures();
|
|
||||||
public abstract void removeTexture(String name);
|
|
||||||
public abstract void setUniform(String name, VertexBuffer buffer);
|
|
||||||
public abstract void setIndecies(VertexBuffer buffer, IndeciesType type);
|
|
||||||
public abstract void clearIndecies();
|
|
||||||
public abstract void setVertexBuffer(int index, VertexBuffer buffer);
|
|
||||||
|
|
||||||
public DrawArea area() { return area; }
|
|
||||||
public boolean hasDepth() { return hasDepth; }
|
|
||||||
public boolean hasColor() { return hasColor; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract void close();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -69,13 +69,13 @@ public record ShaderPipeline(ID id, Map<ShaderType, ID> shaders, List<VertexBind
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder withUniform(String name, int binding, int set, int bytes) {
|
public Builder withUniform(String name, int binding, int slot, int bytes) {
|
||||||
uniforms.add(new UniformBinding(name, binding, set, bytes));
|
uniforms.add(new UniformBinding(name, binding, slot, bytes));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder withTexture(String name, int binding, int set, TextureType type) {
|
public Builder withTexture(String name, int binding, int slot, TextureType type) {
|
||||||
textures.add(new TextureBinding(name, binding, set, type));
|
textures.add(new TextureBinding(name, binding, slot, type));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ import java.util.Objects;
|
|||||||
import speiger.src.coreengine.graphics.api.texture.states.TextureType;
|
import speiger.src.coreengine.graphics.api.texture.states.TextureType;
|
||||||
|
|
||||||
public class Bindings {
|
public class Bindings {
|
||||||
public record UniformBinding(String name, int binding, int set, int bytes) {
|
public record UniformBinding(String name, int binding, int slot, int bytes) {
|
||||||
public UniformBinding {
|
public UniformBinding {
|
||||||
Objects.requireNonNull(name, "A name has to be provided");
|
Objects.requireNonNull(name, "A name has to be provided");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public record TextureBinding(String name, int binding, int set, TextureType type) {
|
public record TextureBinding(String name, int binding, int slot, TextureType type) {
|
||||||
public TextureBinding {
|
public TextureBinding {
|
||||||
Objects.requireNonNull(name, "A name has to be provided");
|
Objects.requireNonNull(name, "A name has to be provided");
|
||||||
Objects.requireNonNull(type, "A TextureType has to be provided");
|
Objects.requireNonNull(type, "A TextureType has to be provided");
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package speiger.src.coreengine.graphics.api.shader.states;
|
package speiger.src.coreengine.graphics.api.shader.states;
|
||||||
|
|
||||||
public record BlendFunction(BlendFactor colorSource, BlendFactor alphaSource, BlendFactor colorTarget, BlendFactor alphaTarget) {
|
public record BlendFunction(BlendFactor colorSource, BlendFactor alphaSource, BlendFactor colorTarget, BlendFactor alphaTarget) {
|
||||||
|
public static final BlendFunction DEFAULT = new BlendFunction(BlendFactor.ONE, BlendFactor.ZERO);
|
||||||
public BlendFunction(BlendFactor source, BlendFactor target) {
|
public BlendFunction(BlendFactor source, BlendFactor target) {
|
||||||
this(source, BlendFactor.ONE, target, BlendFactor.ZERO);
|
this(source, BlendFactor.ONE, target, BlendFactor.ZERO);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package speiger.src.coreengine.graphics.api.target;
|
package speiger.src.coreengine.graphics.api.target;
|
||||||
|
|
||||||
import speiger.src.coreengine.assets.AssetLocation;
|
import speiger.src.coreengine.assets.api.ID;
|
||||||
import speiger.src.coreengine.graphics.api.texture.Texture;
|
import speiger.src.coreengine.graphics.api.texture.Texture;
|
||||||
import speiger.src.coreengine.graphics.api.texture.states.TextureType;
|
import speiger.src.coreengine.graphics.api.texture.states.TextureType;
|
||||||
|
|
||||||
public record TextureTarget(AssetLocation id, Texture color, Texture depth) implements RenderTarget {
|
public record TextureTarget(ID id, Texture color, Texture depth) implements RenderTarget {
|
||||||
public TextureTarget {
|
public TextureTarget {
|
||||||
if(color == null && depth == null) throw new IllegalArgumentException("At least either texture has to be nonNull");
|
if(color == null && depth == null) throw new IllegalArgumentException("At least either texture has to be nonNull");
|
||||||
if(color != null && depth != null) {
|
if(color != null && depth != null) {
|
||||||
|
|||||||
@@ -10,12 +10,11 @@ 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, ImmutableObjectList<Optional<SwizzleMask>> swizzle, Optional<StencilType> stencilType) {
|
public record TextureSettings(TextureType type, TextureFormat internal, boolean generateMipmapping, OptionalInt baseLevel, OptionalInt maxLevel, ImmutableObjectList<Optional<SwizzleMask>> swizzle, Optional<StencilType> stencilType) {
|
||||||
|
|
||||||
public TextureSettings {
|
public TextureSettings {
|
||||||
Objects.requireNonNull(type, "Texture Type shouldn't be null");
|
Objects.requireNonNull(type, "Texture Type shouldn't be null");
|
||||||
Objects.requireNonNull(internal, "Internal Format 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(baseLevel);
|
||||||
Objects.requireNonNull(maxLevel);
|
Objects.requireNonNull(maxLevel);
|
||||||
Objects.requireNonNull(swizzle);
|
Objects.requireNonNull(swizzle);
|
||||||
@@ -33,9 +32,8 @@ public record TextureSettings(TextureType type, TextureFormat internal, TextureF
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
TextureFormat internalFormat;
|
TextureFormat internalFormat = TextureFormat.RGBA;
|
||||||
TextureFormat externalFormat;
|
TextureType type = TextureType.TEXTURE_2D;
|
||||||
TextureType type;
|
|
||||||
boolean generateMipmapping = false;
|
boolean generateMipmapping = false;
|
||||||
OptionalInt baseLevel = OptionalInt.empty();
|
OptionalInt baseLevel = OptionalInt.empty();
|
||||||
OptionalInt maxLevel = OptionalInt.empty();
|
OptionalInt maxLevel = OptionalInt.empty();
|
||||||
@@ -47,7 +45,6 @@ public record TextureSettings(TextureType type, TextureFormat internal, TextureF
|
|||||||
private Builder(TextureSettings settings) {
|
private Builder(TextureSettings settings) {
|
||||||
type = settings.type;
|
type = settings.type;
|
||||||
internalFormat = settings.internal;
|
internalFormat = settings.internal;
|
||||||
externalFormat = settings.external;
|
|
||||||
generateMipmapping = settings.generateMipmapping;
|
generateMipmapping = settings.generateMipmapping;
|
||||||
baseLevel = settings.baseLevel;
|
baseLevel = settings.baseLevel;
|
||||||
maxLevel = settings.maxLevel;
|
maxLevel = settings.maxLevel;
|
||||||
@@ -59,7 +56,6 @@ public record TextureSettings(TextureType type, TextureFormat internal, TextureF
|
|||||||
return new TextureSettings(
|
return new TextureSettings(
|
||||||
Objects.requireNonNull(type, "Texture Type shouldn't be null"),
|
Objects.requireNonNull(type, "Texture Type shouldn't be null"),
|
||||||
Objects.requireNonNull(internalFormat, "Internal Format shouldn't be null"),
|
Objects.requireNonNull(internalFormat, "Internal Format shouldn't be null"),
|
||||||
Objects.requireNonNull(externalFormat, "External Format shouldn't be null"),
|
|
||||||
generateMipmapping, baseLevel, maxLevel, new ImmutableObjectList<>(swizzle), stencilType);
|
generateMipmapping, baseLevel, maxLevel, new ImmutableObjectList<>(swizzle), stencilType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +66,6 @@ public record TextureSettings(TextureType type, TextureFormat internal, TextureF
|
|||||||
|
|
||||||
public Builder format(TextureFormat format) {
|
public Builder format(TextureFormat format) {
|
||||||
this.internalFormat = format;
|
this.internalFormat = format;
|
||||||
this.externalFormat = format;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,11 +74,6 @@ public record TextureSettings(TextureType type, TextureFormat internal, TextureF
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder external(TextureFormat format) {
|
|
||||||
this.externalFormat = format;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder swizzle(SwizzleMask red, SwizzleMask green, SwizzleMask blue, SwizzleMask alpha) {
|
public Builder swizzle(SwizzleMask red, SwizzleMask green, SwizzleMask blue, SwizzleMask alpha) {
|
||||||
swizzle[0] = Optional.ofNullable(red);
|
swizzle[0] = Optional.ofNullable(red);
|
||||||
swizzle[1] = Optional.ofNullable(green);
|
swizzle[1] = Optional.ofNullable(green);
|
||||||
|
|||||||
+18
-7
@@ -1,11 +1,22 @@
|
|||||||
package speiger.src.coreengine.graphics.api.texture.states;
|
package speiger.src.coreengine.graphics.api.texture.states;
|
||||||
|
|
||||||
public enum TextureFormat {
|
public enum TextureFormat {
|
||||||
R,
|
R(1),
|
||||||
RGB,
|
RG(2),
|
||||||
RGBA,
|
RGB(3),
|
||||||
DEPTH,
|
RGBA(4),
|
||||||
DEPTH_STENCIL,
|
DEPTH(1),
|
||||||
LUMINANCE,
|
DEPTH_STENCIL(2),
|
||||||
LUMINANCE_ALPHA
|
LUMINANCE(1),
|
||||||
|
LUMINANCE_ALPHA(2);
|
||||||
|
|
||||||
|
int components;
|
||||||
|
|
||||||
|
private TextureFormat(int components) {
|
||||||
|
this.components = components;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int components() {
|
||||||
|
return components;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,29 @@
|
|||||||
package speiger.src.coreengine.graphics.api.utils;
|
package speiger.src.coreengine.graphics.api.utils;
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL11;
|
import java.util.Objects;
|
||||||
|
|
||||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||||
import speiger.src.collections.utils.Stack;
|
import speiger.src.collections.utils.Stack;
|
||||||
import speiger.src.coreengine.math.vector.ints.Vec4i;
|
import speiger.src.coreengine.math.vector.ints.Vec4i;
|
||||||
|
|
||||||
public class ScissorsManager {
|
public class ScissorsManager {
|
||||||
|
IScissorsHandler handler;
|
||||||
Stack<Vec4i> stack = new ObjectArrayList<>();
|
Stack<Vec4i> stack = new ObjectArrayList<>();
|
||||||
|
boolean withRoot = false;
|
||||||
int limit;
|
int limit;
|
||||||
|
|
||||||
public ScissorsManager(int limit) {
|
public ScissorsManager(int limit, IScissorsHandler handler) {
|
||||||
if(limit <= 0) throw new IllegalStateException("Limit is negative");
|
if(limit <= 0) throw new IllegalStateException("Limit is negative");
|
||||||
this.limit = limit;
|
this.limit = limit;
|
||||||
|
this.handler = Objects.requireNonNull(handler, "Handler is required");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRoot(int x, int y, int width, int height) {
|
||||||
|
if(stack.size() > 0) throw new IllegalStateException("A Root can't be set if the Stack is already in use or the root is already set");
|
||||||
|
withRoot = true;
|
||||||
|
stack.push(Vec4i.of(x, y, x + width, y + height));
|
||||||
|
handler.enable();
|
||||||
|
handler.apply(x, y, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void push(int x, int y, int width, int height) {
|
public void push(int x, int y, int width, int height) {
|
||||||
@@ -22,12 +33,18 @@ public class ScissorsManager {
|
|||||||
}
|
}
|
||||||
if(stack.isEmpty()) {
|
if(stack.isEmpty()) {
|
||||||
stack.push(Vec4i.of(x, y, x + width, y + height));
|
stack.push(Vec4i.of(x, y, x + width, y + height));
|
||||||
GL11.glEnable(GL11.GL_SCISSOR_TEST);
|
handler.enable();
|
||||||
GL11.glScissor(x, y, width, height);
|
handler.apply(x, y, width, height);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Vec4i top = stack.top();
|
Vec4i top = stack.top();
|
||||||
stack.push(Vec4i.of(Math.max(x, top.x()), Math.max(y, top.y()), Math.min(x + width, top.z()), Math.min(y + height, top.w())));
|
Vec4i result = Vec4i.of(Math.max(x, top.x()), Math.max(y, top.y()), Math.min(x + width, top.z()), Math.min(y + height, top.w()));
|
||||||
|
stack.push(result);
|
||||||
|
handler.apply(result.x(), result.y(), result.z() - result.x(), result.w() - result.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec4i top() {
|
||||||
|
return stack.isEmpty() ? Vec4i.MINUS_ONE : stack.top();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean contains(int x, int y, int width, int height) {
|
public boolean contains(int x, int y, int width, int height) {
|
||||||
@@ -39,14 +56,39 @@ public class ScissorsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void pop() {
|
public void pop() {
|
||||||
if(stack.isEmpty()) {
|
if(stack.size() <= (withRoot ? 1 : 0)) {
|
||||||
//TODO implement logging
|
//TODO implement logging
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
stack.pop();
|
stack.pop();
|
||||||
|
if(stack.isEmpty()) {
|
||||||
|
handler.disable();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Vec4i result = stack.top();
|
||||||
|
handler.apply(result.x(), result.y(), result.z() - result.x(), result.w() - result.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
stack.clear();
|
stack.clear();
|
||||||
|
withRoot = false;
|
||||||
|
handler.disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static interface IScissorsHandler {
|
||||||
|
public void enable();
|
||||||
|
public void disable();
|
||||||
|
public void apply(int x, int y, int width, int height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class NoOp implements IScissorsHandler {
|
||||||
|
public static final IScissorsHandler INSTANCE = new NoOp();
|
||||||
|
@Override
|
||||||
|
public void enable() {}
|
||||||
|
@Override
|
||||||
|
public void disable() {}
|
||||||
|
@Override
|
||||||
|
public void apply(int x, int y, int width, int height) {}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class VertexLayout implements ObjectIterable<Element> {
|
|||||||
private void add(Element element) {
|
private void add(Element element) {
|
||||||
if(mapped.put(element.name(), element) != null) throw new IllegalStateException("Duplicated Names are not allowed");
|
if(mapped.put(element.name(), element) != null) throw new IllegalStateException("Duplicated Names are not allowed");
|
||||||
elements.add(element);
|
elements.add(element);
|
||||||
offsets.add(stride);
|
offsets.add(bytes);
|
||||||
int size = element.size();
|
int size = element.size();
|
||||||
stride += size;
|
stride += size;
|
||||||
bytes += element.type().size(size);
|
bytes += element.type().size(size);
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ public class GLVertexBuffer extends VertexBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int id() {
|
public int id() {
|
||||||
|
if(id == 0) throw new IllegalStateException("Buffer is already removed");
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,17 +7,24 @@ import org.lwjgl.opengl.GL11;
|
|||||||
import org.lwjgl.opengl.GL30;
|
import org.lwjgl.opengl.GL30;
|
||||||
import org.lwjgl.opengl.GL45;
|
import org.lwjgl.opengl.GL45;
|
||||||
|
|
||||||
import speiger.src.coreengine.assets.AssetLocation;
|
import speiger.src.coreengine.assets.api.ID;
|
||||||
import speiger.src.coreengine.graphics.api.core.GraphicsCommandBuffer;
|
import speiger.src.coreengine.graphics.api.core.GraphicsCommandBuffer;
|
||||||
import speiger.src.coreengine.graphics.api.core.GraphicsCommandQueue;
|
import speiger.src.coreengine.graphics.api.core.GraphicsCommandQueue;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.states.GraphicsDataType;
|
||||||
import speiger.src.coreengine.graphics.api.target.RenderTarget;
|
import speiger.src.coreengine.graphics.api.target.RenderTarget;
|
||||||
import speiger.src.coreengine.graphics.api.target.ScreenTarget;
|
import speiger.src.coreengine.graphics.api.target.ScreenTarget;
|
||||||
import speiger.src.coreengine.graphics.api.target.TextureTarget;
|
import speiger.src.coreengine.graphics.api.target.TextureTarget;
|
||||||
import speiger.src.coreengine.graphics.api.texture.Texture;
|
import speiger.src.coreengine.graphics.api.texture.Texture;
|
||||||
|
import speiger.src.coreengine.graphics.api.texture.states.TextureFormat;
|
||||||
import speiger.src.coreengine.graphics.api.utils.PushableResource;
|
import speiger.src.coreengine.graphics.api.utils.PushableResource;
|
||||||
import speiger.src.coreengine.graphics.opengl.texture.FrameBufferCache;
|
import speiger.src.coreengine.graphics.opengl.texture.FrameBufferCache;
|
||||||
import speiger.src.coreengine.graphics.opengl.texture.GLTexture;
|
import speiger.src.coreengine.graphics.opengl.texture.GLTexture;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.GLStates;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.GLUtils;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.ViewPortStack;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.states.ScissorState;
|
||||||
import speiger.src.coreengine.math.vector.floats.Vec4f;
|
import speiger.src.coreengine.math.vector.floats.Vec4f;
|
||||||
|
import speiger.src.coreengine.math.vector.ints.Vec4i;
|
||||||
import speiger.src.coreengine.rendering.input.window.Window;
|
import speiger.src.coreengine.rendering.input.window.Window;
|
||||||
|
|
||||||
public class GLCommandQueue implements GraphicsCommandQueue {
|
public class GLCommandQueue implements GraphicsCommandQueue {
|
||||||
@@ -25,12 +32,14 @@ public class GLCommandQueue implements GraphicsCommandQueue {
|
|||||||
FrameBufferCache fboCache = new FrameBufferCache();
|
FrameBufferCache fboCache = new FrameBufferCache();
|
||||||
RenderTarget renderTarget = ScreenTarget.INSTANCE;
|
RenderTarget renderTarget = ScreenTarget.INSTANCE;
|
||||||
ScreenBuffer targetFBO;
|
ScreenBuffer targetFBO;
|
||||||
|
int tempWriteFBO;
|
||||||
Vec4f clearColor = Vec4f.mutable(0F, 0F, 0F, 1F);
|
Vec4f clearColor = Vec4f.mutable(0F, 0F, 0F, 1F);
|
||||||
double clearDepth = 0D;
|
double clearDepth = 0D;
|
||||||
|
|
||||||
public GLCommandQueue(GLGraphicsDevice device) {
|
public GLCommandQueue(GLGraphicsDevice device) {
|
||||||
this.device = device;
|
this.device = device;
|
||||||
this.targetFBO = new ScreenBuffer(0, device.getWindow().width(), device.getWindow().height());
|
this.targetFBO = new ScreenBuffer(0, device.window().width(), device.window().height());
|
||||||
|
tempWriteFBO = GL45.glCreateFramebuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -48,6 +57,22 @@ public class GLCommandQueue implements GraphicsCommandQueue {
|
|||||||
return new PushableObject<>(renderTarget, setRenderTarget(target), () -> renderTarget, this::setRenderTarget);
|
return new PushableObject<>(renderTarget, setRenderTarget(target), () -> renderTarget, this::setRenderTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PushableResource pushViewPort(int x, int y, int width, int height) {
|
||||||
|
ViewPortStack stack = device.states.viewPort;
|
||||||
|
Vec4i top = stack.top();
|
||||||
|
Vec4i bounds = Vec4i.of(x, y, height, width);
|
||||||
|
stack.push(x, y, width, height);
|
||||||
|
return new PushableObject<>(top, bounds, stack::top, _ -> stack.pop());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void submitCommands(GraphicsCommandBuffer buffer) {
|
||||||
|
if(buffer instanceof GLRecordingCommandBuffer recorder) {
|
||||||
|
recorder.execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Vec4f setClearColor(Vec4f value) {
|
private Vec4f setClearColor(Vec4f value) {
|
||||||
if(clearColor.equals(value)) return value;
|
if(clearColor.equals(value)) return value;
|
||||||
clearColor.set(value);
|
clearColor.set(value);
|
||||||
@@ -67,10 +92,10 @@ public class GLCommandQueue implements GraphicsCommandQueue {
|
|||||||
this.renderTarget = target;
|
this.renderTarget = target;
|
||||||
targetFBO = switch(target) {
|
targetFBO = switch(target) {
|
||||||
case ScreenTarget _ -> {
|
case ScreenTarget _ -> {
|
||||||
Window window = device.getWindow();
|
Window window = device.window();
|
||||||
yield new ScreenBuffer(0, window.width(), window.height());
|
yield new ScreenBuffer(0, window.width(), window.height());
|
||||||
}
|
}
|
||||||
case TextureTarget(AssetLocation id, Texture color, Texture depth) -> {
|
case TextureTarget(ID id, Texture color, Texture depth) -> {
|
||||||
int fbo = fboCache.getOrCreateFBO(id);
|
int fbo = fboCache.getOrCreateFBO(id);
|
||||||
if(color != null) {
|
if(color != null) {
|
||||||
GL45.glNamedFramebufferTexture(fbo, GL30.GL_COLOR_ATTACHMENT0, ((GLTexture)color).id(), 0);
|
GL45.glNamedFramebufferTexture(fbo, GL30.GL_COLOR_ATTACHMENT0, ((GLTexture)color).id(), 0);
|
||||||
@@ -90,26 +115,61 @@ public class GLCommandQueue implements GraphicsCommandQueue {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearTexture(int clearParam) {
|
public void clearTexture(int clearParam) {
|
||||||
|
GL11.glClear(((clearParam & CLEAR_COLOR) != 0 ? GL11.GL_COLOR_BUFFER_BIT : 0) | ((clearParam & CLEAR_DEPTH) != 0 ? GL11.GL_DEPTH_BUFFER_BIT : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearTexture(int x, int y, int width, int height, int clearParam) {
|
public void clearTexture(int x, int y, int width, int height, int clearParam) {
|
||||||
|
ScissorState state = device.states.scissors;
|
||||||
|
state.backup();
|
||||||
|
try(PushableResource _ = pushViewPort(0, 0, targetFBO.width(), targetFBO.height())) {
|
||||||
|
state.set(Vec4i.of(x, y, x + width, y + height));
|
||||||
|
clearTexture(clearParam);
|
||||||
|
}
|
||||||
|
state.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearTexture(Texture texture, int clearParam) {
|
public void clearTexture(Texture texture, int clearParam) {
|
||||||
|
if((clearParam & CLEAR_BOTH) == CLEAR_BOTH) {
|
||||||
|
//TODO implement Logging
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, tempWriteFBO);
|
||||||
|
GL45.glNamedFramebufferTexture(tempWriteFBO, GL30.GL_COLOR_ATTACHMENT0, ((GLTexture)texture).id(), 0);
|
||||||
|
clearTexture(clearParam);
|
||||||
|
GL45.glNamedFramebufferTexture(tempWriteFBO, GL30.GL_COLOR_ATTACHMENT0, 0, 0);
|
||||||
|
GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, targetFBO.fbo());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearTexture(Texture texture, int x, int y, int width, int height, int clearParam) {
|
public void clearTexture(Texture texture, int x, int y, int width, int height, int clearParam) {
|
||||||
|
ScissorState state = device.states.scissors;
|
||||||
|
state.backup();
|
||||||
|
try(PushableResource _ = pushViewPort(x, y, texture.width(), texture.height())) {
|
||||||
|
state.set(Vec4i.of(x, y, x + width, y + height));
|
||||||
|
clearTexture(texture, clearParam);
|
||||||
|
}
|
||||||
|
state.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeToTexture(Texture target, int x, int y, int width, int height, long source) {
|
public void writeToTexture(Texture target, TextureFormat format, GraphicsDataType dataType, long source) {
|
||||||
|
GL45.glTextureSubImage2D(((GLTexture)target).id(), 0, 0, 0, target.width(), target.height(), GLUtils.toGLExternal(format), GLUtils.toGL(dataType), source);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readFromTexture(Texture source, int x, int y, int width, int height, long target) {
|
public void writeToTexture(Texture target, int sourceX, int sourceY, int targetX, int targetY, int width, int height, TextureFormat format, GraphicsDataType dataType, long source) {
|
||||||
|
GLStates states = device.states;
|
||||||
|
states.unpack_alignment.set(target.settings().internal().components());
|
||||||
|
states.unpack_row_length.set(target.width());
|
||||||
|
states.unpack_skip_pixel.set(sourceX);
|
||||||
|
states.unpack_skip_rows.set(sourceY);
|
||||||
|
GL45.glTextureSubImage2D(((GLTexture)target).id(), 0, targetX, targetY, width, height, GLUtils.toGLExternal(format), GLUtils.toGL(dataType), source);
|
||||||
|
states.unpack_alignment.setDefault();
|
||||||
|
states.unpack_row_length.setDefault();
|
||||||
|
states.unpack_skip_pixel.setDefault();
|
||||||
|
states.unpack_skip_rows.setDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
private record PushableObject<T>(T original, T applying, Supplier<T> current, Consumer<T> apply) implements PushableResource {
|
private record PushableObject<T>(T original, T applying, Supplier<T> current, Consumer<T> apply) implements PushableResource {
|
||||||
@@ -122,9 +182,4 @@ public class GLCommandQueue implements GraphicsCommandQueue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private record ScreenBuffer(int fbo, int width, int height) {}
|
private record ScreenBuffer(int fbo, int width, int height) {}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void submitCommands(GraphicsCommandBuffer buffer) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
package speiger.src.coreengine.graphics.opengl.core;
|
package speiger.src.coreengine.graphics.opengl.core;
|
||||||
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
import org.lwjgl.opengl.GL;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.assets.manager.AssetManager;
|
||||||
import speiger.src.coreengine.graphics.api.core.Graphics;
|
import speiger.src.coreengine.graphics.api.core.Graphics;
|
||||||
import speiger.src.coreengine.rendering.input.window.Window;
|
import speiger.src.coreengine.rendering.input.window.Window;
|
||||||
|
|
||||||
public class GLGraphics implements Graphics {
|
public class GLGraphics implements Graphics {
|
||||||
|
AssetManager manager;
|
||||||
|
|
||||||
|
public GLGraphics(AssetManager manager) {
|
||||||
|
this.manager = manager;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@@ -14,6 +21,9 @@ public class GLGraphics implements Graphics {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setupWindowArguments() {
|
public void setupWindowArguments() {
|
||||||
|
GLFW.glfwDefaultWindowHints();
|
||||||
|
GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE);
|
||||||
|
|
||||||
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 4);
|
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||||
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 0);
|
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||||
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, GLFW.GLFW_OPENGL_CORE_PROFILE);
|
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, GLFW.GLFW_OPENGL_CORE_PROFILE);
|
||||||
@@ -22,7 +32,7 @@ public class GLGraphics implements Graphics {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GLGraphicsDevice createDevice(Window window) {
|
public GLGraphicsDevice createDevice(Window window) {
|
||||||
return new GLGraphicsDevice(window);
|
return new GLGraphicsDevice(window, manager, GL.createCapabilities());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+204
-5
@@ -1,19 +1,41 @@
|
|||||||
package speiger.src.coreengine.graphics.opengl.core;
|
package speiger.src.coreengine.graphics.opengl.core;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.OptionalInt;
|
import java.util.OptionalInt;
|
||||||
|
import java.util.function.IntPredicate;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
import org.lwjgl.opengl.GL12;
|
import org.lwjgl.opengl.GL12;
|
||||||
|
import org.lwjgl.opengl.GL20;
|
||||||
|
import org.lwjgl.opengl.GL31;
|
||||||
import org.lwjgl.opengl.GL33;
|
import org.lwjgl.opengl.GL33;
|
||||||
|
import org.lwjgl.opengl.GL41;
|
||||||
import org.lwjgl.opengl.GL43;
|
import org.lwjgl.opengl.GL43;
|
||||||
import org.lwjgl.opengl.GL45;
|
import org.lwjgl.opengl.GL45;
|
||||||
|
import org.lwjgl.opengl.GL46;
|
||||||
|
import org.lwjgl.opengl.GLCapabilities;
|
||||||
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
|
import speiger.src.collections.ints.lists.IntArrayList;
|
||||||
|
import speiger.src.collections.ints.lists.IntList;
|
||||||
import speiger.src.collections.ints.maps.impl.hash.Int2ObjectLinkedOpenHashMap;
|
import speiger.src.collections.ints.maps.impl.hash.Int2ObjectLinkedOpenHashMap;
|
||||||
import speiger.src.collections.ints.maps.impl.hash.Int2ObjectOpenHashMap;
|
import speiger.src.collections.ints.maps.impl.hash.Int2ObjectOpenHashMap;
|
||||||
import speiger.src.collections.ints.maps.interfaces.Int2ObjectMap;
|
import speiger.src.collections.ints.maps.interfaces.Int2ObjectMap;
|
||||||
|
import speiger.src.collections.objects.maps.impl.hash.Object2IntOpenHashMap;
|
||||||
|
import speiger.src.collections.objects.maps.impl.hash.Object2ObjectOpenHashMap;
|
||||||
|
import speiger.src.collections.objects.maps.interfaces.Object2IntMap;
|
||||||
|
import speiger.src.collections.objects.maps.interfaces.Object2ObjectMap;
|
||||||
|
import speiger.src.collections.objects.utils.ObjectIterables;
|
||||||
|
import speiger.src.coreengine.assets.api.IAsset;
|
||||||
import speiger.src.coreengine.assets.api.IAssetProvider;
|
import speiger.src.coreengine.assets.api.IAssetProvider;
|
||||||
|
import speiger.src.coreengine.assets.api.ID;
|
||||||
|
import speiger.src.coreengine.assets.api.MultiAsset;
|
||||||
|
import speiger.src.coreengine.assets.manager.AssetManager;
|
||||||
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.BufferState;
|
||||||
import speiger.src.coreengine.graphics.api.buffer.states.BufferType;
|
import speiger.src.coreengine.graphics.api.buffer.states.BufferType;
|
||||||
@@ -22,30 +44,50 @@ import speiger.src.coreengine.graphics.api.core.GraphicsDevice;
|
|||||||
import speiger.src.coreengine.graphics.api.mesh.Mesh;
|
import speiger.src.coreengine.graphics.api.mesh.Mesh;
|
||||||
import speiger.src.coreengine.graphics.api.mesh.Mesh.LayoutInfo;
|
import speiger.src.coreengine.graphics.api.mesh.Mesh.LayoutInfo;
|
||||||
import speiger.src.coreengine.graphics.api.sampler.SamplerSettings;
|
import speiger.src.coreengine.graphics.api.sampler.SamplerSettings;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.BufferAttribute;
|
||||||
import speiger.src.coreengine.graphics.api.shader.ShaderPipeline;
|
import speiger.src.coreengine.graphics.api.shader.ShaderPipeline;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.VertexBinding;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.states.Bindings.TextureBinding;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.states.Bindings.UniformBinding;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.states.ShaderType;
|
||||||
import speiger.src.coreengine.graphics.api.texture.TextureSettings;
|
import speiger.src.coreengine.graphics.api.texture.TextureSettings;
|
||||||
import speiger.src.coreengine.graphics.api.texture.states.SwizzleMask;
|
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.ExecutionType;
|
import speiger.src.coreengine.graphics.api.utils.ExecutionType;
|
||||||
import speiger.src.coreengine.graphics.opengl.buffer.GLVertexBuffer;
|
import speiger.src.coreengine.graphics.opengl.buffer.GLVertexBuffer;
|
||||||
import speiger.src.coreengine.graphics.opengl.mesh.GLMesh;
|
import speiger.src.coreengine.graphics.opengl.mesh.GLMesh;
|
||||||
import speiger.src.coreengine.graphics.opengl.sampler.GLSampler;
|
import speiger.src.coreengine.graphics.opengl.sampler.GLSampler;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.shader.ShaderCache;
|
||||||
import speiger.src.coreengine.graphics.opengl.shader.ShaderInstance;
|
import speiger.src.coreengine.graphics.opengl.shader.ShaderInstance;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.shader.ShaderInstance.SamplerObject;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.shader.ShaderInstance.ShaderStorage;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.shader.ShaderInstance.UniformObject;
|
||||||
import speiger.src.coreengine.graphics.opengl.texture.GLTexture;
|
import speiger.src.coreengine.graphics.opengl.texture.GLTexture;
|
||||||
import speiger.src.coreengine.graphics.opengl.utils.GLFunctions;
|
import speiger.src.coreengine.graphics.opengl.utils.GLFunctions;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.GLStates;
|
||||||
import speiger.src.coreengine.graphics.opengl.utils.GLUtils;
|
import speiger.src.coreengine.graphics.opengl.utils.GLUtils;
|
||||||
import speiger.src.coreengine.rendering.input.window.Window;
|
import speiger.src.coreengine.rendering.input.window.Window;
|
||||||
|
|
||||||
public class GLGraphicsDevice implements GraphicsDevice {
|
public class GLGraphicsDevice implements GraphicsDevice {
|
||||||
|
static final Map<ID, String> IMPORTS = Object2ObjectMap.builder().<ID, String>map().synchronize();
|
||||||
|
Object2IntMap<ID> shaderCache = new Object2IntOpenHashMap<>();
|
||||||
|
Object2ObjectMap<ID, ShaderInstance> programCache = new Object2ObjectOpenHashMap<>();
|
||||||
|
AssetManager manager;
|
||||||
|
GLCapabilities capabilities;
|
||||||
|
GLStates states = new GLStates();
|
||||||
|
ShaderCache cache = new ShaderCache();
|
||||||
GLCommandQueue queue;
|
GLCommandQueue queue;
|
||||||
Window owner;
|
Window owner;
|
||||||
|
|
||||||
public GLGraphicsDevice(Window owner) {
|
public GLGraphicsDevice(Window owner, AssetManager manager, GLCapabilities capbilities) {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
|
this.manager = manager;
|
||||||
|
this.capabilities = capbilities;
|
||||||
this.queue = new GLCommandQueue(this);
|
this.queue = new GLCommandQueue(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Window getWindow() {
|
public Window window() {
|
||||||
return owner;
|
return owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,11 +98,11 @@ public class GLGraphicsDevice implements GraphicsDevice {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GraphicsCommandBuffer createCommandBuffer(ExecutionType type) {
|
public GraphicsCommandBuffer createCommandBuffer(ExecutionType type) {
|
||||||
return null;
|
return type == ExecutionType.IMMEDIATE ? new GLImmidateCommandBuffer(this) : new GLRecordingCommandBuffer(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GLCommandQueue getQueue() {
|
public GLCommandQueue queue() {
|
||||||
return queue;
|
return queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,6 +121,7 @@ public class GLGraphicsDevice implements GraphicsDevice {
|
|||||||
public GLTexture createTexture(TextureSettings settings, int width, int height) {
|
public GLTexture createTexture(TextureSettings settings, int width, int height) {
|
||||||
if(width < 0) throw new IllegalArgumentException("Width ["+width+"] is invalid");
|
if(width < 0) throw new IllegalArgumentException("Width ["+width+"] is invalid");
|
||||||
if(height < 0) throw new IllegalArgumentException("Height ["+height+"] is invalid");
|
if(height < 0) throw new IllegalArgumentException("Height ["+height+"] is invalid");
|
||||||
|
if(settings.type() != TextureType.TEXTURE_2D) throw new IllegalStateException("Currently only 2D textures are supported");
|
||||||
int id = GLFunctions.createTexture(settings.type());
|
int id = GLFunctions.createTexture(settings.type());
|
||||||
settings.stencilType().ifPresent(T -> GL45.glTextureParameteri(id, GL43.GL_DEPTH_STENCIL_TEXTURE_MODE, GLUtils.toGL(T)));
|
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.baseLevel().ifPresent(T -> GL45.glTextureParameteri(id, GL12.GL_TEXTURE_BASE_LEVEL, T));
|
||||||
@@ -92,6 +135,7 @@ public class GLGraphicsDevice implements GraphicsDevice {
|
|||||||
GLUtils.toGL(masks.get(3).orElse(SwizzleMask.ALPHA)),
|
GLUtils.toGL(masks.get(3).orElse(SwizzleMask.ALPHA)),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
GL45.glTextureStorage2D(id, 1, GLUtils.toGLInternal(settings.internal()), width, height);
|
||||||
return new GLTexture(settings, id, width, height);
|
return new GLTexture(settings, id, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +160,162 @@ public class GLGraphicsDevice implements GraphicsDevice {
|
|||||||
return new GLMesh(builder.info(), new Int2ObjectOpenHashMap<>(), null, null, false);
|
return new GLMesh(builder.info(), new Int2ObjectOpenHashMap<>(), null, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShaderInstance createShader(ShaderPipeline line, IAssetProvider provider) {
|
@Override
|
||||||
|
public void preloadPipelines(List<ShaderPipeline> pipelines) {
|
||||||
|
try(IAssetProvider provider = manager.get()) {
|
||||||
|
for(ShaderPipeline pipeline : pipelines) {
|
||||||
|
computeShaderProgram(pipeline, provider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ShaderInstance getShader(ShaderPipeline pipeline) {
|
||||||
|
return programCache.supplyIfAbsent(pipeline.id(), () -> computeShaderProgram(pipeline));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ShaderInstance computeShaderProgram(ShaderPipeline pipeline) {
|
||||||
|
try(IAssetProvider provider = manager.get()) {
|
||||||
|
return computeShaderProgram(pipeline, provider);
|
||||||
|
}
|
||||||
|
catch(Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ShaderInstance computeShaderProgram(ShaderPipeline pipeline, IAssetProvider provider) {
|
||||||
|
MultiAsset assets = MultiAsset.combineNonNull(provider, pipeline.shaders().values().toArray(ID[]::new));
|
||||||
|
if(assets == null) {
|
||||||
|
//TODO log stuff
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int program = loadOrCreateProgram(pipeline, assets, T -> {
|
||||||
|
Map<ID, IAsset> map = Object2ObjectMap.builder().map();
|
||||||
|
assets.forEach(map, (K, V) -> K.put(V.location(), V));
|
||||||
|
IntList shaders = new IntArrayList();
|
||||||
|
for(Entry<ShaderType, ID> entry : pipeline.shaders().entrySet()) {
|
||||||
|
ShaderType type = entry.getKey();
|
||||||
|
IAsset asset = map.get(entry.getValue());
|
||||||
|
int id = shaderCache.computeIfAbsent(entry.getValue(), E -> computeShader(E, asset, type, provider));
|
||||||
|
if(id == -1) {
|
||||||
|
System.out.println("Couldn't create a shader. Type["+type+"], of Id["+asset.location()+"]");
|
||||||
|
//TODO implement logging.
|
||||||
|
//Failed to compile shader
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
GL20.glAttachShader(T, id);
|
||||||
|
}
|
||||||
|
for(BufferAttribute attribute : ObjectIterables.flatMap(pipeline.attributes(), VertexBinding::attributes)) {
|
||||||
|
GL20.glBindAttribLocation(T, attribute.index(), attribute.name());
|
||||||
|
}
|
||||||
|
GL20.glLinkProgram(T);
|
||||||
|
for(int i = 0,m=shaders.size();i<m;i++) {
|
||||||
|
GL20.glDetachShader(T, shaders.getInt(i));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
if(program == 0) return null;
|
||||||
|
ShaderStorage<UniformObject> uniforms = new ShaderStorage<>();
|
||||||
|
ShaderStorage<SamplerObject> samplers = new ShaderStorage<>();
|
||||||
|
for(TextureBinding binding : pipeline.textures()) {
|
||||||
|
int location = GL20.glGetUniformLocation(program, binding.name());
|
||||||
|
if(location == -1) {
|
||||||
|
System.out.println("Couldn't find Location ["+binding.name()+"] in Program ["+program+"]");
|
||||||
|
//TODO Warn that location wasn't found
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
samplers.add(binding.name(), binding.slot(), new SamplerObject(binding.slot()));
|
||||||
|
}
|
||||||
|
for(UniformBinding binding : pipeline.uniforms()) {
|
||||||
|
int location = GL31.glGetUniformBlockIndex(program, binding.name());
|
||||||
|
if(location == GL31.GL_INVALID_INDEX) {
|
||||||
|
System.out.println("Couldn't find Location ["+binding.name()+"] in Program ["+program+"]");
|
||||||
|
|
||||||
|
//TODO Warn that location wasn't found
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
uniforms.add(binding.name(), binding.slot(), new UniformObject(binding.slot()));
|
||||||
|
}
|
||||||
|
ShaderInstance instance = new ShaderInstance(program, uniforms, samplers);
|
||||||
|
states.shaders.register(instance);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int computeShader(ID id, IAsset asset, ShaderType type, IAssetProvider provider) {
|
||||||
|
StringBuilder builder = new StringBuilder(2048);
|
||||||
|
try {
|
||||||
|
for(String line : asset.lines()) {
|
||||||
|
if(line.startsWith("//")) continue;
|
||||||
|
if(line.startsWith("#import<") && line.endsWith(">")) builder.append(importLines(provider, ID.of(line.substring(8, line.length()-1))));
|
||||||
|
else builder.append(line);
|
||||||
|
builder.append("\n");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch(Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int shader = GL20.glCreateShader(GLUtils.toGL(type));
|
||||||
|
GL20.glShaderSource(shader, builder);
|
||||||
|
GL20.glCompileShader(shader);
|
||||||
|
if(GL20.glGetShaderi(shader, GL20.GL_COMPILE_STATUS) == 0) {
|
||||||
|
//TODO improve logging
|
||||||
|
System.out.println(GL20.glGetShaderInfoLog(shader, GL20.glGetShaderi(shader, GL20.GL_INFO_LOG_LENGTH)));
|
||||||
|
GL20.glDeleteShader(shader);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int loadOrCreateProgram(ShaderPipeline pipeline, MultiAsset assets, IntPredicate callback) {
|
||||||
|
int id = GL20.glCreateProgram();
|
||||||
|
boolean fail = true;
|
||||||
|
if((fail = !loadFromCache(id, pipeline, assets) && callback.test(id))) {
|
||||||
|
if(GL20.glGetProgrami(id, GL20.GL_LINK_STATUS) == GL11.GL_TRUE) {
|
||||||
|
cache.store(pipeline.id(), assets.crc(), getProgramBytes(id));
|
||||||
|
fail = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(fail) {
|
||||||
|
GL20.glDeleteProgram(id);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
String error = GL20.glGetProgramInfoLog(id);
|
||||||
|
if(!error.isBlank()) {
|
||||||
|
System.out.println("Error: "+error);
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] getProgramBytes(int programId) {
|
||||||
|
ByteBuffer buffer = MemoryUtil.memAlloc(GL20.glGetProgrami(programId, GL41.GL_PROGRAM_BINARY_LENGTH) + 4);
|
||||||
|
int[] format = new int[1];
|
||||||
|
GL41.glGetProgramBinary(programId, null, format, buffer.position(4));
|
||||||
|
buffer.putInt(0, format[0]).flip();
|
||||||
|
byte[] data = new byte[buffer.remaining()];
|
||||||
|
buffer.get(data);
|
||||||
|
MemoryUtil.memFree(buffer);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean loadFromCache(int programId, ShaderPipeline pipeline, MultiAsset asset) {
|
||||||
|
ByteBuffer data = cache.get(pipeline.id(), asset::crc);
|
||||||
|
if(data == null) return false;
|
||||||
|
GL41.glProgramBinary(programId, data.getInt(), data);
|
||||||
|
MemoryUtil.memFree(data);
|
||||||
|
return GL46.glGetProgrami(programId, GL46.GL_LINK_STATUS) == GL46.GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String importLines(IAssetProvider provider, ID location) {
|
||||||
|
return IMPORTS.computeIfAbsent(location, T -> {
|
||||||
|
try { return ObjectIterables.filter(provider.get(T).lines(), E -> !E.startsWith("//")).reduce(new StringBuilder(), (K, V) -> K.append(V).append("\n")).toString(); }
|
||||||
|
catch(Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+132
-11
@@ -1,85 +1,206 @@
|
|||||||
package speiger.src.coreengine.graphics.opengl.core;
|
package speiger.src.coreengine.graphics.opengl.core;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
import org.lwjgl.opengl.GL30;
|
||||||
|
import org.lwjgl.opengl.GL31;
|
||||||
|
import org.lwjgl.opengl.GL33;
|
||||||
|
import org.lwjgl.opengl.GL45;
|
||||||
|
|
||||||
import speiger.src.coreengine.graphics.api.buffer.VertexBuffer;
|
import speiger.src.coreengine.graphics.api.buffer.VertexBuffer;
|
||||||
import speiger.src.coreengine.graphics.api.core.GraphicsCommandBuffer;
|
import speiger.src.coreengine.graphics.api.core.GraphicsCommandBuffer;
|
||||||
import speiger.src.coreengine.graphics.api.mesh.Mesh;
|
import speiger.src.coreengine.graphics.api.mesh.Mesh;
|
||||||
import speiger.src.coreengine.graphics.api.sampler.Sampler;
|
import speiger.src.coreengine.graphics.api.sampler.Sampler;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.ColorTarget;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.DepthTarget;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.RasterizerState;
|
||||||
import speiger.src.coreengine.graphics.api.shader.ShaderPipeline;
|
import speiger.src.coreengine.graphics.api.shader.ShaderPipeline;
|
||||||
import speiger.src.coreengine.graphics.api.texture.Texture;
|
import speiger.src.coreengine.graphics.api.texture.Texture;
|
||||||
|
import speiger.src.coreengine.graphics.api.utils.ScissorsManager;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.buffer.GLVertexBuffer;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.mesh.GLMesh;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.sampler.GLSampler;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.shader.ShaderInstance;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.texture.GLTexture;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.GLScissorsHandler;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.GLStates;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.GLUtils;
|
||||||
|
|
||||||
public class GLImmidateCommandBuffer implements GraphicsCommandBuffer {
|
public class GLImmidateCommandBuffer implements GraphicsCommandBuffer {
|
||||||
|
GLGraphicsDevice device;
|
||||||
|
boolean removed = false;
|
||||||
boolean recording = false;
|
boolean recording = false;
|
||||||
ShaderPipeline pipeline;
|
|
||||||
Mesh mesh;
|
|
||||||
int recorded = 0;
|
int recorded = 0;
|
||||||
|
|
||||||
|
ScissorsManager scissors;
|
||||||
|
ShaderPipeline pipeline;
|
||||||
|
ShaderInstance shader;
|
||||||
|
GLMesh mesh;
|
||||||
|
|
||||||
|
public GLImmidateCommandBuffer(GLGraphicsDevice device) {
|
||||||
|
this.device = device;
|
||||||
|
this.scissors = new ScissorsManager(8, new GLScissorsHandler(device.states));
|
||||||
|
}
|
||||||
|
|
||||||
protected void ensureDrawing() {
|
protected void ensureDrawing() {
|
||||||
|
if(removed) throw new IllegalStateException("CommandBuffer is removed");
|
||||||
if(!recording) throw new IllegalStateException("CommandBuffer isn't recording");
|
if(!recording) throw new IllegalStateException("CommandBuffer isn't recording");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRemoved() { return false; }
|
public boolean isRemoved() { return removed; }
|
||||||
@Override
|
@Override
|
||||||
public void remove() {}
|
public void remove() {
|
||||||
|
clear();
|
||||||
|
device = null;
|
||||||
|
removed = true;
|
||||||
|
recorded = 0;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GraphicsCommandBuffer begin() {
|
public GraphicsCommandBuffer begin() {
|
||||||
|
if(removed) throw new IllegalStateException("CommandBuffer is removed");
|
||||||
if(recording) throw new IllegalStateException("CommandBuffer already recording");
|
if(recording) throw new IllegalStateException("CommandBuffer already recording");
|
||||||
recording = true;
|
recording = true;
|
||||||
|
recorded = 0;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GraphicsCommandBuffer setScissors(int x, int y, int width, int height) {
|
public GraphicsCommandBuffer setScissors(int x, int y, int width, int height) {
|
||||||
|
ensureDrawing();
|
||||||
|
scissors.setRoot(x, y, width, height);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GraphicsCommandBuffer pipeline(ShaderPipeline pipeline) {
|
public GraphicsCommandBuffer pipeline(ShaderPipeline pipeline) {
|
||||||
|
Objects.requireNonNull(pipeline);
|
||||||
|
ensureDrawing();
|
||||||
|
if(this.pipeline == pipeline) return this;
|
||||||
this.pipeline = pipeline;
|
this.pipeline = pipeline;
|
||||||
|
shader = device.getShader(pipeline);
|
||||||
|
if(shader == null) {
|
||||||
|
//TODO implement logging
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
GLStates states = device.states;
|
||||||
|
states.shaders.bind(shader);
|
||||||
|
RasterizerState rasterization = pipeline.rasterizer();
|
||||||
|
states.polygon.set(rasterization.fillMode());
|
||||||
|
states.backCulling.set(rasterization.cullBack());
|
||||||
|
DepthTarget depth = pipeline.depthTarget();
|
||||||
|
if(depth.enabled()) {
|
||||||
|
states.depth.enable();
|
||||||
|
states.setDepthMask(depth.write());
|
||||||
|
states.setDepthFunction(depth.function());
|
||||||
|
}
|
||||||
|
else states.depth.disable();
|
||||||
|
ColorTarget color = pipeline.colorTarget();
|
||||||
|
color.blend().ifPresentOrElse(states.blend::enableSet, states.blend::disable);
|
||||||
|
states.setColorMask(color.writeMask());
|
||||||
|
recorded++;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GraphicsCommandBuffer mesh(Mesh mesh) {
|
public GraphicsCommandBuffer mesh(Mesh mesh) {
|
||||||
this.mesh = mesh;
|
Objects.requireNonNull(mesh);
|
||||||
|
ensureDrawing();
|
||||||
|
if(this.mesh == mesh) return this;
|
||||||
|
this.mesh = (GLMesh)mesh;
|
||||||
|
this.mesh.bind();
|
||||||
|
// GL30.glBindVertexArray(this.mesh.id());
|
||||||
|
recorded++;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GraphicsCommandBuffer texture(int set, int binding, Texture texture, Sampler sampler) {
|
public GraphicsCommandBuffer texture(int binding, Texture texture, Sampler sampler) {
|
||||||
|
Objects.requireNonNull(texture);
|
||||||
|
Objects.requireNonNull(sampler);
|
||||||
|
ensureDrawing();
|
||||||
|
Objects.requireNonNull(shader, "No Pipeline found");
|
||||||
|
Objects.requireNonNull(shader.samplers().byIndex(binding), "Texture["+binding+"] binding not found");
|
||||||
|
// GLStates states = device.states;
|
||||||
|
GL45.glBindTextureUnit(binding, ((GLTexture)texture).id());
|
||||||
|
GL33.glBindSampler(binding, ((GLSampler)sampler).id());
|
||||||
|
// states.textures.bind(binding, ((GLTexture)texture).id());
|
||||||
|
// states.samplers.bind(binding, ((GLSampler)sampler).id());
|
||||||
|
recorded++;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GraphicsCommandBuffer uniform(int set, int binding, VertexBuffer buffer) {
|
public GraphicsCommandBuffer uniform(int binding, VertexBuffer buffer) {
|
||||||
|
Objects.requireNonNull(buffer);
|
||||||
|
ensureDrawing();
|
||||||
|
Objects.requireNonNull(shader, "No Pipeline found");
|
||||||
|
Objects.requireNonNull(shader.uniforms().byIndex(binding), "Uniform for binding ["+binding+"] doesn't exist");
|
||||||
|
GL30.glBindBufferBase(GL31.GL_UNIFORM_BUFFER, binding, ((GLVertexBuffer)buffer).id());
|
||||||
|
recorded++;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GraphicsCommandBuffer drawIndexed(int start, int count) {
|
public GraphicsCommandBuffer uniform(int binding, VertexBuffer buffer, long offset, long size) {
|
||||||
|
Objects.requireNonNull(buffer);
|
||||||
|
ensureDrawing();
|
||||||
|
Objects.requireNonNull(shader, "No Pipeline found");
|
||||||
|
Objects.requireNonNull(shader.uniforms().byIndex(binding), "Uniform for binding ["+binding+"] doesn't exist");
|
||||||
|
GL30.glBindBufferRange(GL31.GL_UNIFORM_BUFFER, binding, ((GLVertexBuffer)buffer).id(), offset, size);
|
||||||
|
recorded++;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GraphicsCommandBuffer drawArrays(int offset, int count) {
|
||||||
|
ensureDrawing();
|
||||||
|
Objects.requireNonNull(shader, "No Pipeline found");
|
||||||
|
GL11.glDrawArrays(GLUtils.toGL(pipeline.rasterizer().mode()), offset, count);
|
||||||
|
recorded++;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GraphicsCommandBuffer drawElements(int offset, int count) {
|
||||||
|
ensureDrawing();
|
||||||
|
Objects.requireNonNull(shader, "No Pipeline found");
|
||||||
|
GL11.nglDrawElements(GLUtils.toGL(pipeline.rasterizer().mode()), count, GLUtils.toGL(mesh.indeciesType()), offset);
|
||||||
|
recorded++;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GraphicsCommandBuffer pushScissors(int x, int y, int width, int height) {
|
public GraphicsCommandBuffer pushScissors(int x, int y, int width, int height) {
|
||||||
|
ensureDrawing();
|
||||||
|
scissors.push(x, y, width, height);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GraphicsCommandBuffer popScissors() {
|
public GraphicsCommandBuffer popScissors() {
|
||||||
|
ensureDrawing();
|
||||||
|
scissors.pop();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GraphicsCommandBuffer end() {
|
public GraphicsCommandBuffer end() {
|
||||||
if(!recording) throw new IllegalStateException("Already Stopped Recording");
|
if(!recording) throw new IllegalStateException("Already Stopped Recording");
|
||||||
pipeline = null;
|
clear();
|
||||||
mesh = null;
|
|
||||||
recording = false;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void clear() {
|
||||||
|
recording = false;
|
||||||
|
pipeline = null;
|
||||||
|
shader = null;
|
||||||
|
mesh = null;
|
||||||
|
scissors.clear();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int commandCount() { return recorded; }
|
public int commandCount() { return recorded; }
|
||||||
}
|
}
|
||||||
|
|||||||
+239
@@ -0,0 +1,239 @@
|
|||||||
|
package speiger.src.coreengine.graphics.opengl.core;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
import org.lwjgl.opengl.GL30;
|
||||||
|
import org.lwjgl.opengl.GL31;
|
||||||
|
|
||||||
|
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||||
|
import speiger.src.coreengine.graphics.api.buffer.VertexBuffer;
|
||||||
|
import speiger.src.coreengine.graphics.api.buffer.states.IndeciesType;
|
||||||
|
import speiger.src.coreengine.graphics.api.core.GraphicsCommandBuffer;
|
||||||
|
import speiger.src.coreengine.graphics.api.mesh.Mesh;
|
||||||
|
import speiger.src.coreengine.graphics.api.sampler.Sampler;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.ColorTarget;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.DepthTarget;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.RasterizerState;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.ShaderPipeline;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.states.DrawMode;
|
||||||
|
import speiger.src.coreengine.graphics.api.texture.Texture;
|
||||||
|
import speiger.src.coreengine.graphics.api.utils.ScissorsManager;
|
||||||
|
import speiger.src.coreengine.graphics.api.utils.ScissorsManager.NoOp;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.buffer.GLVertexBuffer;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.mesh.GLMesh;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.sampler.GLSampler;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.shader.ShaderInstance;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.texture.GLTexture;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.GLStates;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.GLUtils;
|
||||||
|
import speiger.src.coreengine.math.vector.ints.Vec4i;
|
||||||
|
|
||||||
|
public class GLRecordingCommandBuffer implements GraphicsCommandBuffer {
|
||||||
|
List<Runnable> tasks = new ObjectArrayList<>();
|
||||||
|
boolean recording = false;
|
||||||
|
boolean removed = false;
|
||||||
|
GLGraphicsDevice device;
|
||||||
|
|
||||||
|
ScissorsManager scissors = new ScissorsManager(8, NoOp.INSTANCE);
|
||||||
|
ShaderPipeline pipeline;
|
||||||
|
ShaderInstance shader;
|
||||||
|
GLMesh mesh;
|
||||||
|
|
||||||
|
|
||||||
|
public GLRecordingCommandBuffer(GLGraphicsDevice device) {
|
||||||
|
this.device = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void ensureDrawing() {
|
||||||
|
if(removed) throw new IllegalStateException("CommandBuffer is removed");
|
||||||
|
if(!recording) throw new IllegalStateException("CommandBuffer isn't recording");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRemoved() {
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
removed = true;
|
||||||
|
clear();
|
||||||
|
recording = false;
|
||||||
|
tasks.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GraphicsCommandBuffer begin() {
|
||||||
|
if(removed) throw new IllegalStateException("CommandBuffer is removed");
|
||||||
|
if(recording) throw new IllegalStateException("CommandBuffer already recording");
|
||||||
|
recording = true;
|
||||||
|
tasks.clear();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GraphicsCommandBuffer setScissors(int x, int y, int width, int height) {
|
||||||
|
ensureDrawing();
|
||||||
|
scissors.setRoot(x, y, width, height);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GraphicsCommandBuffer pipeline(ShaderPipeline pipeline) {
|
||||||
|
Objects.requireNonNull(pipeline);
|
||||||
|
ensureDrawing();
|
||||||
|
if(this.pipeline == pipeline) return this;
|
||||||
|
this.pipeline = pipeline;
|
||||||
|
shader = device.getShader(pipeline);
|
||||||
|
tasks.add(new SetPipeline(pipeline, shader, device.states));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GraphicsCommandBuffer mesh(Mesh mesh) {
|
||||||
|
Objects.requireNonNull(mesh);
|
||||||
|
ensureDrawing();
|
||||||
|
if(this.mesh == mesh) return this;
|
||||||
|
this.mesh = (GLMesh)mesh;
|
||||||
|
this.tasks.add(new SetMesh(this.mesh));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GraphicsCommandBuffer texture(int binding, Texture texture, Sampler sampler) {
|
||||||
|
Objects.requireNonNull(texture);
|
||||||
|
Objects.requireNonNull(sampler);
|
||||||
|
ensureDrawing();
|
||||||
|
Objects.requireNonNull(shader, "No Pipeline found");
|
||||||
|
Objects.requireNonNull(shader.samplers().byIndex(binding), "Texture["+binding+"] binding not found");
|
||||||
|
tasks.add(new SetTexture(binding, (GLTexture)texture, (GLSampler)sampler, device.states));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GraphicsCommandBuffer uniform(int binding, VertexBuffer buffer) {
|
||||||
|
Objects.requireNonNull(buffer);
|
||||||
|
ensureDrawing();
|
||||||
|
Objects.requireNonNull(shader, "No Pipeline found");
|
||||||
|
Objects.requireNonNull(shader.uniforms().byIndex(binding), "Uniform for binding ["+binding+"] doesn't exist");
|
||||||
|
tasks.add(new SetUniform(binding, (GLVertexBuffer)buffer, -1, -1));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GraphicsCommandBuffer uniform(int binding, VertexBuffer buffer, long offset, long size) {
|
||||||
|
Objects.requireNonNull(buffer);
|
||||||
|
ensureDrawing();
|
||||||
|
Objects.requireNonNull(shader, "No Pipeline found");
|
||||||
|
Objects.requireNonNull(shader.uniforms().byIndex(binding), "Uniform for binding ["+binding+"] doesn't exist");
|
||||||
|
tasks.add(new SetUniform(binding, (GLVertexBuffer)buffer, offset, size));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GraphicsCommandBuffer drawArrays(int offset, int count) {
|
||||||
|
ensureDrawing();
|
||||||
|
Objects.requireNonNull(shader, "No Pipeline found");
|
||||||
|
DrawMode mode = pipeline.rasterizer().mode();
|
||||||
|
tasks.add(() -> GL11.glDrawArrays(GLUtils.toGL(mode), offset, count));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GraphicsCommandBuffer drawElements(int offset, int count) {
|
||||||
|
ensureDrawing();
|
||||||
|
Objects.requireNonNull(shader, "No Pipeline found");
|
||||||
|
DrawMode mode = pipeline.rasterizer().mode();
|
||||||
|
IndeciesType type = mesh.indeciesType();
|
||||||
|
tasks.add(() -> GL11.nglDrawElements(GLUtils.toGL(mode), count, GLUtils.toGL(type), offset));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GraphicsCommandBuffer pushScissors(int x, int y, int width, int height) {
|
||||||
|
ensureDrawing();
|
||||||
|
scissors.push(x, y, width, height);
|
||||||
|
tasks.add(new SetScissors(scissors.top(), device.states));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GraphicsCommandBuffer popScissors() {
|
||||||
|
ensureDrawing();
|
||||||
|
scissors.pop();
|
||||||
|
tasks.add(new SetScissors(scissors.top(), device.states));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GraphicsCommandBuffer end() {
|
||||||
|
if(!recording) throw new IllegalStateException("Already Stopped Recording");
|
||||||
|
clear();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int commandCount() {
|
||||||
|
return tasks.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void execute() {
|
||||||
|
tasks.forEach(Runnable::run);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clear() {
|
||||||
|
recording = false;
|
||||||
|
pipeline = null;
|
||||||
|
shader = null;
|
||||||
|
mesh = null;
|
||||||
|
scissors.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public record SetScissors(Vec4i area, GLStates states) implements Runnable {
|
||||||
|
@Override
|
||||||
|
public void run() { states.scissors.set(area); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public record SetPipeline(ShaderPipeline pipeline, ShaderInstance instance, GLStates states) implements Runnable {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
states.shaders.bind(instance);
|
||||||
|
RasterizerState rasterization = pipeline.rasterizer();
|
||||||
|
states.polygon.set(rasterization.fillMode());
|
||||||
|
states.backCulling.set(rasterization.cullBack());
|
||||||
|
DepthTarget depth = pipeline.depthTarget();
|
||||||
|
if(depth.enabled()) {
|
||||||
|
states.depth.enable();
|
||||||
|
states.setDepthMask(depth.write());
|
||||||
|
states.setDepthFunction(depth.function());
|
||||||
|
}
|
||||||
|
else states.depth.disable();
|
||||||
|
ColorTarget color = pipeline.colorTarget();
|
||||||
|
color.blend().ifPresentOrElse(states.blend::enableSet, states.blend::disable);
|
||||||
|
states.setColorMask(color.writeMask());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record SetMesh(GLMesh mesh) implements Runnable {
|
||||||
|
@Override
|
||||||
|
public void run() { GL30.glBindVertexArray(mesh.id()); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public record SetTexture(int binding, GLTexture texture, GLSampler sampler, GLStates states) implements Runnable {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
states.textures.bind(binding, texture.id());
|
||||||
|
states.samplers.bind(binding, sampler.id());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record SetUniform(int binding, GLVertexBuffer buffer, long offset, long size) implements Runnable {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if(size < 0 || offset < 0) GL30.glBindBufferBase(GL31.GL_UNIFORM_BUFFER, binding, buffer.id());
|
||||||
|
else GL30.glBindBufferRange(GL31.GL_UNIFORM_BUFFER, binding, buffer.id(), offset, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package speiger.src.coreengine.graphics.opengl.core;
|
package speiger.src.coreengine.graphics.opengl.core;
|
||||||
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
import speiger.src.coreengine.graphics.api.core.GraphicsSurface;
|
import speiger.src.coreengine.graphics.api.core.GraphicsSurface;
|
||||||
import speiger.src.coreengine.rendering.input.window.Window;
|
import speiger.src.coreengine.rendering.input.window.Window;
|
||||||
@@ -19,6 +20,9 @@ public class GLSurface implements GraphicsSurface {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beginFrame() {
|
public void beginFrame() {
|
||||||
|
GL11.glClearColor(0.2F, 0.55F, 0.66F, 1F);
|
||||||
|
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
|
||||||
|
window.beginFrame();
|
||||||
GLFW.glfwPollEvents();
|
GLFW.glfwPollEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package speiger.src.coreengine.graphics.opengl.mesh;
|
package speiger.src.coreengine.graphics.opengl.mesh;
|
||||||
|
|
||||||
import org.jspecify.annotations.Nullable;
|
import org.jspecify.annotations.Nullable;
|
||||||
|
import org.lwjgl.opengl.GL30;
|
||||||
import org.lwjgl.opengl.GL45;
|
import org.lwjgl.opengl.GL45;
|
||||||
|
|
||||||
import speiger.src.collections.ints.collections.IntIterator;
|
import speiger.src.collections.ints.collections.IntIterator;
|
||||||
@@ -29,6 +30,22 @@ public class GLMesh extends Mesh {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int id() {
|
||||||
|
return vao;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bind() {
|
||||||
|
GL30.glBindVertexArray(vao);
|
||||||
|
for(Element element : layouts.values().map(LayoutInfo::layout).flatMap(VertexLayout::elements)) {
|
||||||
|
GL45.glEnableVertexArrayAttrib(vao, element.index());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return obj instanceof GLMesh mesh && mesh.vao == vao;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRemoved() { return vao == 0; }
|
public boolean isRemoved() { return vao == 0; }
|
||||||
|
|
||||||
@@ -47,6 +64,7 @@ public class GLMesh extends Mesh {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void bindElement() {
|
private void bindElement() {
|
||||||
|
indeciesBuffer.bind();
|
||||||
GL45.glVertexArrayElementBuffer(vao, ((GLVertexBuffer)indeciesBuffer).id());
|
GL45.glVertexArrayElementBuffer(vao, ((GLVertexBuffer)indeciesBuffer).id());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,6 +72,7 @@ public class GLMesh extends Mesh {
|
|||||||
LayoutInfo info = layouts.get(binding);
|
LayoutInfo info = layouts.get(binding);
|
||||||
VertexLayout layout = info.layout();
|
VertexLayout layout = info.layout();
|
||||||
GLVertexBuffer buffer = (GLVertexBuffer)buffers.get(binding);
|
GLVertexBuffer buffer = (GLVertexBuffer)buffers.get(binding);
|
||||||
|
buffer.bind();
|
||||||
GL45.glVertexArrayVertexBuffer(vao, binding, buffer.id(), 0, layout.bytes());
|
GL45.glVertexArrayVertexBuffer(vao, binding, buffer.id(), 0, layout.bytes());
|
||||||
if(info.instanceCount() > 0) GL45.glVertexArrayBindingDivisor(vao, binding, info.instanceCount());
|
if(info.instanceCount() > 0) GL45.glVertexArrayBindingDivisor(vao, binding, info.instanceCount());
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|||||||
@@ -27,6 +27,10 @@ public class GLSampler extends Sampler {
|
|||||||
GL45.glSamplerParameteri(id, GL11.GL_TEXTURE_MAG_FILTER, GLUtils.toGL(settings.magSample()));
|
GL45.glSamplerParameteri(id, GL11.GL_TEXTURE_MAG_FILTER, GLUtils.toGL(settings.magSample()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int id() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRemoved() {
|
public boolean isRemoved() {
|
||||||
return id == 0;
|
return id == 0;
|
||||||
|
|||||||
@@ -2,10 +2,14 @@ package speiger.src.coreengine.graphics.opengl.shader;
|
|||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
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.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
@@ -62,12 +66,16 @@ public class ShaderCache {
|
|||||||
catch(Exception e) { e.printStackTrace(); }
|
catch(Exception e) { e.printStackTrace(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] get(ID shaderId, String fileHash) {
|
public ByteBuffer get(ID shaderId, Supplier<String> fileHash) {
|
||||||
|
if(cache == null) return null;
|
||||||
String known = hashCache.get(shaderId);
|
String known = hashCache.get(shaderId);
|
||||||
if(!Objects.equals(known, fileHash)) return null;
|
if(known == null || !Objects.equals(known, fileHash.get())) return null;
|
||||||
Path path = toFile(shaderId);
|
Path path = toFile(shaderId);
|
||||||
if(Files.notExists(path)) return null;
|
if(Files.notExists(path)) return null;
|
||||||
try { return Files.readAllBytes(path); }
|
try {
|
||||||
|
byte[] data = Files.readAllBytes(path);
|
||||||
|
return MemoryUtil.memAlloc(data.length).put(data).flip();
|
||||||
|
}
|
||||||
catch(Exception e) { e.printStackTrace(); }
|
catch(Exception e) { e.printStackTrace(); }
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -76,6 +84,7 @@ public class ShaderCache {
|
|||||||
Objects.requireNonNull(shaderId);
|
Objects.requireNonNull(shaderId);
|
||||||
Objects.requireNonNull(fileHash);
|
Objects.requireNonNull(fileHash);
|
||||||
Objects.requireNonNull(shader);
|
Objects.requireNonNull(shader);
|
||||||
|
if(cache == null) return;
|
||||||
hashCache.put(shaderId, fileHash);
|
hashCache.put(shaderId, fileHash);
|
||||||
try {
|
try {
|
||||||
Path file = toFile(shaderId);
|
Path file = toFile(shaderId);
|
||||||
@@ -89,6 +98,7 @@ public class ShaderCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void delete(ID shaderId) {
|
public void delete(ID shaderId) {
|
||||||
|
if(cache == null) return;
|
||||||
if(hashCache.remove(shaderId) == null) return;
|
if(hashCache.remove(shaderId) == null) return;
|
||||||
try { Files.deleteIfExists(toFile(shaderId)); }
|
try { Files.deleteIfExists(toFile(shaderId)); }
|
||||||
catch(Exception e) { e.printStackTrace(); }
|
catch(Exception e) { e.printStackTrace(); }
|
||||||
|
|||||||
+22
-1
@@ -2,8 +2,29 @@ package speiger.src.coreengine.graphics.opengl.shader;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public record ShaderInstance(int programId, Map<String, UniformObject> uniforms, Map<String, SamplerObject> samplers) {
|
import speiger.src.collections.ints.maps.impl.hash.Int2ObjectOpenHashMap;
|
||||||
|
import speiger.src.collections.ints.maps.interfaces.Int2ObjectMap;
|
||||||
|
import speiger.src.collections.objects.maps.impl.hash.Object2ObjectOpenHashMap;
|
||||||
|
|
||||||
|
public record ShaderInstance(int programId, ShaderStorage<UniformObject> uniforms, ShaderStorage<SamplerObject> samplers) {
|
||||||
public record UniformObject(int slot) {}
|
public record UniformObject(int slot) {}
|
||||||
public record SamplerObject(int unit) {}
|
public record SamplerObject(int unit) {}
|
||||||
|
|
||||||
|
public static class ShaderStorage<T> {
|
||||||
|
Map<String, T> byName = new Object2ObjectOpenHashMap<>();
|
||||||
|
Int2ObjectMap<T> byIndex = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
|
public void add(String name, int index, T value) {
|
||||||
|
byName.put(name, value);
|
||||||
|
byIndex.put(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T byName(String name) {
|
||||||
|
return byName.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T byIndex(int index) {
|
||||||
|
return byIndex.get(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package speiger.src.coreengine.graphics.opengl.shader;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL20;
|
||||||
|
|
||||||
|
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||||
|
import speiger.src.collections.objects.lists.ObjectList;
|
||||||
|
|
||||||
|
public class ShaderTracker {
|
||||||
|
ObjectList<ShaderInstance> knownShaders = new ObjectArrayList<ShaderInstance>();
|
||||||
|
int boundShader;
|
||||||
|
|
||||||
|
public void register(ShaderInstance instance) {
|
||||||
|
knownShaders.add(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(ShaderInstance instance) {
|
||||||
|
knownShaders.remove(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bind(ShaderInstance instance) {
|
||||||
|
int id = instance.programId();
|
||||||
|
if(id == boundShader) return;
|
||||||
|
boundShader = id;
|
||||||
|
GL20.glUseProgram(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-4
@@ -4,16 +4,16 @@ import org.lwjgl.opengl.GL45;
|
|||||||
|
|
||||||
import speiger.src.collections.objects.maps.impl.hash.Object2IntOpenHashMap;
|
import speiger.src.collections.objects.maps.impl.hash.Object2IntOpenHashMap;
|
||||||
import speiger.src.collections.objects.maps.interfaces.Object2IntMap;
|
import speiger.src.collections.objects.maps.interfaces.Object2IntMap;
|
||||||
import speiger.src.coreengine.assets.AssetLocation;
|
import speiger.src.coreengine.assets.api.ID;
|
||||||
|
|
||||||
public class FrameBufferCache {
|
public class FrameBufferCache {
|
||||||
Object2IntMap<AssetLocation> fboCache = new Object2IntOpenHashMap<>();
|
Object2IntMap<ID> fboCache = new Object2IntOpenHashMap<>();
|
||||||
|
|
||||||
public int getOrCreateFBO(AssetLocation id) {
|
public int getOrCreateFBO(ID id) {
|
||||||
return fboCache.supplyIntIfAbsent(id, GL45::glCreateFramebuffers);
|
return fboCache.supplyIntIfAbsent(id, GL45::glCreateFramebuffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteFBO(AssetLocation id) {
|
public void deleteFBO(ID id) {
|
||||||
int fbo = fboCache.rem(id);
|
int fbo = fboCache.rem(id);
|
||||||
if(fbo == -1) return;
|
if(fbo == -1) return;
|
||||||
GL45.glDeleteFramebuffers(fbo);
|
GL45.glDeleteFramebuffers(fbo);
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package speiger.src.coreengine.graphics.opengl.utils;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.graphics.api.utils.ScissorsManager.IScissorsHandler;
|
||||||
|
import speiger.src.coreengine.math.vector.ints.Vec4i;
|
||||||
|
|
||||||
|
public record GLScissorsHandler(GLStates states) implements IScissorsHandler {
|
||||||
|
@Override
|
||||||
|
public void enable() { states.scissors.enable(); }
|
||||||
|
@Override
|
||||||
|
public void disable() { states.scissors.disable(); }
|
||||||
|
@Override
|
||||||
|
public void apply(int x, int y, int width, int height) { states.scissors.set(Vec4i.of(x, y, x + width, y + height)); }
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package speiger.src.coreengine.graphics.opengl.utils;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
import org.lwjgl.opengl.GL13;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.ColorTarget;
|
||||||
|
import speiger.src.coreengine.graphics.api.utils.AlphaFunction;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.shader.ShaderTracker;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.states.BlendState;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.states.CullState;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.states.FloatState;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.states.GLPolygon;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.states.GLState;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.states.PixelState;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.states.SamplerState;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.states.ScissorState;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.states.TextureState;
|
||||||
|
|
||||||
|
public final class GLStates {
|
||||||
|
public final GLState multiSampling = new GLState(GL13.GL_MULTISAMPLE);
|
||||||
|
public final GLState depth = new GLState(GL11.GL_DEPTH_TEST);
|
||||||
|
public final GLPolygon polygon = new GLPolygon();
|
||||||
|
public final GLState backCulling = new CullState();
|
||||||
|
public final FloatState pointSize = new FloatState(1F, GL11::glPointSize);
|
||||||
|
public final FloatState lineSize = new FloatState(1F, GL11::glLineWidth);
|
||||||
|
public final TextureState textures = new TextureState();
|
||||||
|
public final SamplerState samplers = new SamplerState();
|
||||||
|
public final BlendState blend = new BlendState();
|
||||||
|
public final ScissorState scissors = new ScissorState();
|
||||||
|
public final ViewPortStack viewPort = new ViewPortStack();
|
||||||
|
|
||||||
|
//Texture States
|
||||||
|
public final PixelState unpack_alignment = new PixelState(GL11.GL_UNPACK_ALIGNMENT, 4);
|
||||||
|
public final PixelState unpack_skip_pixel = new PixelState(GL11.GL_UNPACK_SKIP_PIXELS, 0);
|
||||||
|
public final PixelState unpack_skip_rows = new PixelState(GL11.GL_UNPACK_SKIP_ROWS, 0);
|
||||||
|
public final PixelState unpack_row_length = new PixelState(GL11.GL_UNPACK_ROW_LENGTH, 0);
|
||||||
|
|
||||||
|
public final ShaderTracker shaders = new ShaderTracker();
|
||||||
|
|
||||||
|
|
||||||
|
int colorMask = ColorTarget.ALL;
|
||||||
|
boolean depthMask = true;
|
||||||
|
AlphaFunction depthFunction = AlphaFunction.GEQUAL;
|
||||||
|
int activeVAO = 0;
|
||||||
|
int activeShader = 0;
|
||||||
|
|
||||||
|
public void setColorMask(int mask) {
|
||||||
|
if(colorMask == mask) return;
|
||||||
|
colorMask = mask;
|
||||||
|
GL11.glColorMask((mask & ColorTarget.RED) != 0, (mask & ColorTarget.GREEN) != 0, (mask & ColorTarget.BLUE) != 0, (mask & ColorTarget.ALPHA) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDepthMask(boolean depth) {
|
||||||
|
if(depthMask == depth) return;
|
||||||
|
depthMask = depth;
|
||||||
|
GL11.glDepthMask(depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDepthFunction(AlphaFunction function) {
|
||||||
|
if(depthFunction == function) return;
|
||||||
|
depthFunction = function;
|
||||||
|
GL11.glDepthFunc(GLUtils.toGL(function));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import org.lwjgl.opengl.GL12;
|
|||||||
import org.lwjgl.opengl.GL13;
|
import org.lwjgl.opengl.GL13;
|
||||||
import org.lwjgl.opengl.GL14;
|
import org.lwjgl.opengl.GL14;
|
||||||
import org.lwjgl.opengl.GL15;
|
import org.lwjgl.opengl.GL15;
|
||||||
|
import org.lwjgl.opengl.GL20;
|
||||||
import org.lwjgl.opengl.GL21;
|
import org.lwjgl.opengl.GL21;
|
||||||
import org.lwjgl.opengl.GL30;
|
import org.lwjgl.opengl.GL30;
|
||||||
import org.lwjgl.opengl.GL31;
|
import org.lwjgl.opengl.GL31;
|
||||||
@@ -16,17 +17,21 @@ import org.lwjgl.opengl.GL44;
|
|||||||
|
|
||||||
import speiger.src.coreengine.graphics.api.buffer.states.BufferState;
|
import speiger.src.coreengine.graphics.api.buffer.states.BufferState;
|
||||||
import speiger.src.coreengine.graphics.api.buffer.states.BufferType;
|
import speiger.src.coreengine.graphics.api.buffer.states.BufferType;
|
||||||
|
import speiger.src.coreengine.graphics.api.buffer.states.IndeciesType;
|
||||||
import speiger.src.coreengine.graphics.api.sampler.states.BorderMode;
|
import speiger.src.coreengine.graphics.api.sampler.states.BorderMode;
|
||||||
import speiger.src.coreengine.graphics.api.sampler.states.SampleMode;
|
import speiger.src.coreengine.graphics.api.sampler.states.SampleMode;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.states.BlendFactor;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.states.DrawMode;
|
||||||
import speiger.src.coreengine.graphics.api.shader.states.GraphicsDataType;
|
import speiger.src.coreengine.graphics.api.shader.states.GraphicsDataType;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.states.PolygonMode;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.states.ShaderType;
|
||||||
import speiger.src.coreengine.graphics.api.texture.states.StencilType;
|
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.SwizzleMask;
|
||||||
|
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;
|
||||||
import speiger.src.coreengine.graphics.api.utils.AlphaFunction;
|
import speiger.src.coreengine.graphics.api.utils.AlphaFunction;
|
||||||
|
|
||||||
public class GLUtils {
|
public class GLUtils {
|
||||||
//Buffer Begin
|
|
||||||
|
|
||||||
public static int toGL(BufferType type) {
|
public static int toGL(BufferType type) {
|
||||||
return switch(type) {
|
return switch(type) {
|
||||||
case ARRAY_BUFFER -> GL15.GL_ARRAY_BUFFER;
|
case ARRAY_BUFFER -> GL15.GL_ARRAY_BUFFER;
|
||||||
@@ -59,8 +64,6 @@ public class GLUtils {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
//Texture Begin
|
|
||||||
|
|
||||||
public static int toGL(TextureType type) {
|
public static int toGL(TextureType type) {
|
||||||
return switch(type) {
|
return switch(type) {
|
||||||
case TEXTURE_1D -> GL11.GL_TEXTURE_1D;
|
case TEXTURE_1D -> GL11.GL_TEXTURE_1D;
|
||||||
@@ -77,6 +80,45 @@ public class GLUtils {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int toGLInternal(TextureFormat format) {
|
||||||
|
return switch(format) {
|
||||||
|
case R -> GL11.GL_RED;
|
||||||
|
case RG -> GL30.GL_RG;
|
||||||
|
case RGB -> GL11.GL_RGB;
|
||||||
|
case RGBA -> GL11.GL_RGBA8;
|
||||||
|
case DEPTH -> GL11.GL_DEPTH_COMPONENT;
|
||||||
|
case DEPTH_STENCIL -> GL30.GL_DEPTH_STENCIL;
|
||||||
|
case LUMINANCE -> GL30.GL_R8;
|
||||||
|
case LUMINANCE_ALPHA -> GL11.GL_LUMINANCE8_ALPHA8;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int toGLExternal(TextureFormat format) {
|
||||||
|
return switch(format) {
|
||||||
|
case R -> GL11.GL_RED;
|
||||||
|
case RG -> GL30.GL_RG;
|
||||||
|
case RGB -> GL11.GL_RGB;
|
||||||
|
case RGBA -> GL11.GL_RGBA;
|
||||||
|
case DEPTH -> GL11.GL_DEPTH_COMPONENT;
|
||||||
|
case DEPTH_STENCIL -> GL30.GL_DEPTH_STENCIL;
|
||||||
|
case LUMINANCE -> GL30.GL_R8;
|
||||||
|
case LUMINANCE_ALPHA -> GL11.GL_LUMINANCE8_ALPHA8;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int components(TextureFormat format) {
|
||||||
|
return switch(format) {
|
||||||
|
case R -> 1;
|
||||||
|
case RG -> 2;
|
||||||
|
case RGB -> 3;
|
||||||
|
case RGBA -> 4;
|
||||||
|
case DEPTH -> 1;
|
||||||
|
case DEPTH_STENCIL -> 2;
|
||||||
|
case LUMINANCE -> 1;
|
||||||
|
case LUMINANCE_ALPHA -> 2;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public static int toGL(SwizzleMask mask) {
|
public static int toGL(SwizzleMask mask) {
|
||||||
return switch(mask) {
|
return switch(mask) {
|
||||||
case RED -> GL11.GL_RED;
|
case RED -> GL11.GL_RED;
|
||||||
@@ -154,4 +196,64 @@ public class GLUtils {
|
|||||||
case UNSIGNED_INT_5_9_9_9_REV -> GL30.GL_UNSIGNED_INT_5_9_9_9_REV;
|
case UNSIGNED_INT_5_9_9_9_REV -> GL30.GL_UNSIGNED_INT_5_9_9_9_REV;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int toGL(BlendFactor type) {
|
||||||
|
return switch(type) {
|
||||||
|
case ZERO -> GL11.GL_ZERO;
|
||||||
|
case ONE -> GL11.GL_ONE;
|
||||||
|
case CONSTANT_COLOR -> GL15.GL_CONSTANT_COLOR;
|
||||||
|
case CONSTANT_ALPHA -> GL15.GL_CONSTANT_ALPHA;
|
||||||
|
case SRC_COLOR -> GL11.GL_SRC_COLOR;
|
||||||
|
case SRC_ALPHA -> GL11.GL_SRC_ALPHA;
|
||||||
|
case DST_COLOR -> GL11.GL_DST_COLOR;
|
||||||
|
case DST_ALPHA -> GL11.GL_DST_ALPHA;
|
||||||
|
case ONE_MINUS_SRC_COLOR -> GL11.GL_ONE_MINUS_SRC_COLOR;
|
||||||
|
case ONE_MINUS_SRC_ALPHA -> GL11.GL_ONE_MINUS_SRC_ALPHA;
|
||||||
|
case ONE_MINUS_DST_COLOR -> GL11.GL_ONE_MINUS_DST_COLOR;
|
||||||
|
case ONE_MINUS_DST_ALPHA -> GL11.GL_ONE_MINUS_DST_ALPHA;
|
||||||
|
case ONE_MINUS_CONSTANT_COLOR -> GL15.GL_ONE_MINUS_CONSTANT_COLOR;
|
||||||
|
case ONE_MINUS_CONSTANT_ALPHA -> GL15.GL_ONE_MINUS_CONSTANT_ALPHA;
|
||||||
|
case SRC_ALPHA_SATURATE -> GL11.GL_SRC_ALPHA_SATURATE;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int toGL(PolygonMode state) {
|
||||||
|
return switch(state) {
|
||||||
|
case FILL -> GL11.GL_FILL;
|
||||||
|
case LINE -> GL11.GL_LINE;
|
||||||
|
case POINT -> GL11.GL_POINT;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int toGL(ShaderType type) {
|
||||||
|
return switch(type) {
|
||||||
|
case VERTEX -> GL20.GL_VERTEX_SHADER;
|
||||||
|
case FRAGMENT -> GL20.GL_FRAGMENT_SHADER;
|
||||||
|
case GEOMETRY -> GL32.GL_GEOMETRY_SHADER;
|
||||||
|
case TESSELATION_CONTROL -> GL40.GL_TESS_CONTROL_SHADER;
|
||||||
|
case TESSELATION_EVALUATION -> GL40.GL_TESS_EVALUATION_SHADER;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int toGL(DrawMode mode) {
|
||||||
|
return switch(mode) {
|
||||||
|
case POINT -> GL11.GL_POINT;
|
||||||
|
case LINES -> GL11.GL_LINES;
|
||||||
|
case LINE_LOOP -> GL11.GL_LINE_LOOP;
|
||||||
|
case LINE_STRIP -> GL11.GL_LINE_STRIP;
|
||||||
|
case TRIANGLES -> GL11.GL_TRIANGLES;
|
||||||
|
case TRIANGLE_FAN -> GL11.GL_TRIANGLE_FAN;
|
||||||
|
case TRIANGLE_STRIP -> GL11.GL_TRIANGLE_STRIP;
|
||||||
|
case QUADS -> GL11.GL_QUADS;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int toGL(IndeciesType type) {
|
||||||
|
return switch(type) {
|
||||||
|
case BYTE -> GL11.GL_UNSIGNED_BYTE;
|
||||||
|
case SHORT -> GL11.GL_UNSIGNED_SHORT;
|
||||||
|
case INT -> GL11.GL_UNSIGNED_INT;
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package speiger.src.coreengine.graphics.opengl.utils;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
|
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||||
|
import speiger.src.collections.utils.Stack;
|
||||||
|
import speiger.src.coreengine.math.vector.ints.Vec4i;
|
||||||
|
|
||||||
|
public class ViewPortStack {
|
||||||
|
Stack<Vec4i> stack = new ObjectArrayList<>();
|
||||||
|
Vec4i defaultPort = Vec4i.ZERO;
|
||||||
|
|
||||||
|
public void setDefault(int x, int y, int w, int h) {
|
||||||
|
if(defaultPort.x() == x && defaultPort.y() == y && defaultPort.z() == w && defaultPort.w() == h) return;
|
||||||
|
defaultPort.set(x, y, w, h);
|
||||||
|
if(stack.isEmpty()) GL11.glViewport(x, y, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void push(int x, int y, int w, int h) {
|
||||||
|
Vec4i current = top();
|
||||||
|
if(current.x() == x && current.y() == y && current.z() == w && current.w() == h) return;
|
||||||
|
stack.push(Vec4i.of(x, y, w, h));
|
||||||
|
GL11.glViewport(x, y, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pop() {
|
||||||
|
if(stack.isEmpty()) return;
|
||||||
|
stack.pop();
|
||||||
|
Vec4i current = top();
|
||||||
|
GL11.glViewport(current.x(), current.y(), current.z(), current.w());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec4i top() {
|
||||||
|
return stack.isEmpty() ? defaultPort : stack.top();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package speiger.src.coreengine.graphics.opengl.utils.states;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
import org.lwjgl.opengl.GL15;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.states.BlendFunction;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.GLUtils;
|
||||||
|
|
||||||
|
public class BlendState extends GLState {
|
||||||
|
BlendFunction function = BlendFunction.DEFAULT;
|
||||||
|
|
||||||
|
public BlendState() {
|
||||||
|
super(GL11.GL_BLEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlendState enableSet(BlendFunction function) {
|
||||||
|
enable();
|
||||||
|
return set(function);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlendState set(BlendFunction function) {
|
||||||
|
if(this.function.equals(function)) return this;
|
||||||
|
this.function = function;
|
||||||
|
GL15.glBlendFuncSeparate(GLUtils.toGL(function.colorSource()), GLUtils.toGL(function.colorTarget()), GLUtils.toGL(function.alphaSource()), GLUtils.toGL(function.alphaTarget()));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reapply() {
|
||||||
|
super.reapply();
|
||||||
|
GL15.glBlendFuncSeparate(GLUtils.toGL(function.colorSource()), GLUtils.toGL(function.colorTarget()), GLUtils.toGL(function.alphaSource()), GLUtils.toGL(function.alphaTarget()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDefault() {
|
||||||
|
super.setDefault();
|
||||||
|
set(BlendFunction.DEFAULT);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package speiger.src.coreengine.graphics.opengl.utils.states;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
|
public class CullState extends GLState {
|
||||||
|
|
||||||
|
public CullState() {
|
||||||
|
super(GL11.GL_CULL_FACE, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GLState enable() {
|
||||||
|
super.enable();
|
||||||
|
GL11.glCullFace(GL11.GL_BACK);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reapply() {
|
||||||
|
super.reapply();
|
||||||
|
GL11.glCullFace(GL11.GL_BACK);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package speiger.src.coreengine.graphics.opengl.utils.states;
|
||||||
|
|
||||||
|
import speiger.src.collections.floats.functions.FloatConsumer;
|
||||||
|
|
||||||
|
public class FloatState implements IGLState {
|
||||||
|
protected final float defaultValue;
|
||||||
|
protected float value;
|
||||||
|
FloatConsumer setter;
|
||||||
|
|
||||||
|
public FloatState(float defaultValue, FloatConsumer setter) {
|
||||||
|
this.defaultValue = this.value = defaultValue;
|
||||||
|
this.setter = setter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FloatState set(float value) {
|
||||||
|
if(equalsNot(this.value, value)) {
|
||||||
|
this.value = value;
|
||||||
|
setter.accept(value);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float get() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDefault() {
|
||||||
|
set(defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reapply() {
|
||||||
|
setter.accept(defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean equalsNot(float key, float value) {
|
||||||
|
return Float.floatToIntBits(key) != Float.floatToIntBits(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package speiger.src.coreengine.graphics.opengl.utils.states;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.states.PolygonMode;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.utils.GLUtils;
|
||||||
|
|
||||||
|
|
||||||
|
public class GLPolygon implements IGLState
|
||||||
|
{
|
||||||
|
PolygonMode defaultState = PolygonMode.FILL;
|
||||||
|
PolygonMode state = PolygonMode.FILL;
|
||||||
|
|
||||||
|
public GLPolygon set(PolygonMode state) {
|
||||||
|
if(this.state == state) return this;
|
||||||
|
this.state = state;
|
||||||
|
GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GLUtils.toGL(state));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDefault() {
|
||||||
|
set(defaultState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reapply() {
|
||||||
|
GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GLUtils.toGL(state));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package speiger.src.coreengine.graphics.opengl.utils.states;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
|
public class GLState implements IGLState {
|
||||||
|
final int id;
|
||||||
|
final boolean defaultValue;
|
||||||
|
boolean value;
|
||||||
|
|
||||||
|
public GLState(int id) {
|
||||||
|
this(id, GL11.glGetBoolean(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public GLState(int id, boolean defaultValue) {
|
||||||
|
this.id = id;
|
||||||
|
this.defaultValue = this.value = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GLState enable() {
|
||||||
|
return set(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GLState disable() {
|
||||||
|
return set(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GLState set(boolean value) {
|
||||||
|
if(this.value != value) {
|
||||||
|
this.value = value;
|
||||||
|
setValue(value);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean enabled() { return value; }
|
||||||
|
|
||||||
|
protected void setValue(boolean value) {
|
||||||
|
if(value) GL11.glEnable(id);
|
||||||
|
else GL11.glDisable(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reapply() {
|
||||||
|
setValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDefault() {
|
||||||
|
set(defaultValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package speiger.src.coreengine.graphics.opengl.utils.states;
|
||||||
|
|
||||||
|
public interface IGLState
|
||||||
|
{
|
||||||
|
public void setDefault();
|
||||||
|
public void reapply();
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package speiger.src.coreengine.graphics.opengl.utils.states;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
|
public class PixelState implements IGLState {
|
||||||
|
final int id;
|
||||||
|
final int defaultValue;
|
||||||
|
int value;
|
||||||
|
|
||||||
|
public PixelState(int id, int defaultValue) {
|
||||||
|
this.id = id;
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
this.value = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PixelState set(int value) {
|
||||||
|
if(this.value != value) {
|
||||||
|
this.value = value;
|
||||||
|
setValue(value);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setValue(int value) {
|
||||||
|
GL11.glPixelStorei(id, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int get() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDefault() {
|
||||||
|
set(defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reapply() {
|
||||||
|
setValue(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
+51
@@ -0,0 +1,51 @@
|
|||||||
|
package speiger.src.coreengine.graphics.opengl.utils.states;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL20;
|
||||||
|
import org.lwjgl.opengl.GL33;
|
||||||
|
import org.lwjgl.opengl.GL44;
|
||||||
|
|
||||||
|
public class SamplerState implements IGLState {
|
||||||
|
int[] samplers = new int[GL20.GL_TEXTURE31 - GL20.GL_TEXTURE0];
|
||||||
|
|
||||||
|
public SamplerState bind(int sampler) {
|
||||||
|
return bind(0, sampler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SamplerState bind(int unit, int sampler) {
|
||||||
|
if(samplers[unit] != sampler) {
|
||||||
|
this.samplers[unit] = sampler;
|
||||||
|
GL33.glBindSampler(unit, sampler);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SamplerState unbind(int unit) {
|
||||||
|
if(samplers[unit] != 0) {
|
||||||
|
samplers[unit] = 0;
|
||||||
|
GL33.glBindSampler(unit, 0);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SamplerState unbindAll() {
|
||||||
|
setDefault();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSamplerId(int unit) {
|
||||||
|
return samplers[unit];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDefault() {
|
||||||
|
GL44.nglBindSamplers(0, samplers.length, 0);
|
||||||
|
Arrays.fill(samplers, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reapply() {
|
||||||
|
GL44.glBindSamplers(0, samplers);
|
||||||
|
}
|
||||||
|
}
|
||||||
+52
@@ -0,0 +1,52 @@
|
|||||||
|
package speiger.src.coreengine.graphics.opengl.utils.states;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.math.vector.ints.Vec4i;
|
||||||
|
|
||||||
|
public class ScissorState extends GLState {
|
||||||
|
Vec4i current = Vec4i.MINUS_ONE;
|
||||||
|
Vec4i backup = null;
|
||||||
|
|
||||||
|
public ScissorState() {
|
||||||
|
super(GL11.GL_SCISSOR_TEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScissorState set(Vec4i bounds) {
|
||||||
|
if(current.equals(bounds)) return this;
|
||||||
|
current = bounds.asImmutable();
|
||||||
|
if(Vec4i.MINUS_ONE.equals(bounds)) {
|
||||||
|
disable();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
enable();
|
||||||
|
GL11.glScissor(bounds.x(), bounds.y(), bounds.z() - bounds.x(), bounds.w() - bounds.y());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void backup() {
|
||||||
|
backup = current;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void restore() {
|
||||||
|
if(backup == null) return;
|
||||||
|
set(backup);
|
||||||
|
backup = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec4i current() {
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDefault() {
|
||||||
|
super.setDefault();
|
||||||
|
current = Vec4i.MINUS_ONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reapply() {
|
||||||
|
super.reapply();
|
||||||
|
GL11.glScissor(current.x(), current.y(), current.z() - current.x(), current.w() - current.y());
|
||||||
|
}
|
||||||
|
}
|
||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
package speiger.src.coreengine.graphics.opengl.utils.states;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL20;
|
||||||
|
import org.lwjgl.opengl.GL45;
|
||||||
|
|
||||||
|
public class TextureState implements IGLState {
|
||||||
|
int[] textures = new int[GL20.GL_TEXTURE31 - GL20.GL_TEXTURE0];
|
||||||
|
|
||||||
|
public TextureState bind(int texture) {
|
||||||
|
return bind(0, texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextureState bind(int unit, int texture) {
|
||||||
|
if(textures[unit] != texture) {
|
||||||
|
this.textures[unit] = texture;
|
||||||
|
GL45.glBindTextureUnit(unit, texture);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextureState unbind(int unit) {
|
||||||
|
if(textures[unit] != 0) {
|
||||||
|
textures[unit] = 0;
|
||||||
|
GL45.glBindTextureUnit(unit, 0);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextureState unbindAll() {
|
||||||
|
setDefault();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTextureId(int unit) {
|
||||||
|
return textures[unit];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDefault() {
|
||||||
|
GL45.nglBindTextures(0, textures.length, 0);
|
||||||
|
Arrays.fill(textures, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reapply() {
|
||||||
|
GL45.glBindTextures(0, textures);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -76,8 +76,8 @@ public class NewInputTest {
|
|||||||
Joystick.INSTANCE.init(manager, bus);
|
Joystick.INSTANCE.init(manager, bus);
|
||||||
FileDrop.INSTANCE.init(bus);
|
FileDrop.INSTANCE.init(bus);
|
||||||
manager.addDevices(Mouse.INSTANCE, Keyboard.INSTANCE, Joystick.INSTANCE, FileDrop.INSTANCE);
|
manager.addDevices(Mouse.INSTANCE, Keyboard.INSTANCE, Joystick.INSTANCE, FileDrop.INSTANCE);
|
||||||
Window window = manager.builder().title("Testing Engine").width(800).height(600).antialis(0).build();
|
Window window = manager.builder().title("Testing Engine").width(800).height(600).antialis(0).build(null);
|
||||||
Window secondWindow = manager.builder().title("Second Window Engine").width(800).height(600).antialis(0).build();
|
Window secondWindow = manager.builder().title("Second Window Engine").width(800).height(600).antialis(0).build(null);
|
||||||
Thread.ofPlatform().start(() -> drawSecondScreen(secondWindow));
|
Thread.ofPlatform().start(() -> drawSecondScreen(secondWindow));
|
||||||
window.setupContext();
|
window.setupContext();
|
||||||
shaderTest.register();
|
shaderTest.register();
|
||||||
|
|||||||
@@ -0,0 +1,154 @@
|
|||||||
|
package speiger.src.coreengine;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
import org.lwjgl.system.Configuration;
|
||||||
|
import org.lwjgl.util.freetype.FreeType;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.assets.api.IAssetPackage;
|
||||||
|
import speiger.src.coreengine.assets.api.ID;
|
||||||
|
import speiger.src.coreengine.assets.manager.AssetManager;
|
||||||
|
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.core.Graphics;
|
||||||
|
import speiger.src.coreengine.graphics.api.core.GraphicsCommandBuffer;
|
||||||
|
import speiger.src.coreengine.graphics.api.core.GraphicsDevice;
|
||||||
|
import speiger.src.coreengine.graphics.api.core.GraphicsSurface;
|
||||||
|
import speiger.src.coreengine.graphics.api.mesh.Mesh;
|
||||||
|
import speiger.src.coreengine.graphics.api.sampler.Sampler;
|
||||||
|
import speiger.src.coreengine.graphics.api.sampler.SamplerSettings;
|
||||||
|
import speiger.src.coreengine.graphics.api.sampler.states.BorderMode;
|
||||||
|
import speiger.src.coreengine.graphics.api.sampler.states.SampleMode;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.ShaderPipeline;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.states.GraphicsDataType;
|
||||||
|
import speiger.src.coreengine.graphics.api.shader.states.ShaderType;
|
||||||
|
import speiger.src.coreengine.graphics.api.texture.Texture;
|
||||||
|
import speiger.src.coreengine.graphics.api.texture.TextureSettings;
|
||||||
|
import speiger.src.coreengine.graphics.api.texture.states.TextureFormat;
|
||||||
|
import speiger.src.coreengine.graphics.api.texture.states.TextureType;
|
||||||
|
import speiger.src.coreengine.graphics.api.utils.ExecutionType;
|
||||||
|
import speiger.src.coreengine.graphics.api.vertex.VertexLayout;
|
||||||
|
import speiger.src.coreengine.graphics.api.vertex.VertexLayout.Usage;
|
||||||
|
import speiger.src.coreengine.graphics.opengl.core.GLGraphics;
|
||||||
|
import speiger.src.coreengine.math.vector.matrix.Matrix4f;
|
||||||
|
import speiger.src.coreengine.rendering.input.devices.FileDrop;
|
||||||
|
import speiger.src.coreengine.rendering.input.devices.Joystick;
|
||||||
|
import speiger.src.coreengine.rendering.input.devices.Keyboard;
|
||||||
|
import speiger.src.coreengine.rendering.input.devices.Mouse;
|
||||||
|
import speiger.src.coreengine.rendering.input.window.Window;
|
||||||
|
import speiger.src.coreengine.rendering.input.window.WindowManager;
|
||||||
|
import speiger.src.coreengine.rendering.tesselation.buffer.VertexBuilder;
|
||||||
|
import speiger.src.coreengine.rendering.tesselation.format.VertexTypes;
|
||||||
|
import speiger.src.coreengine.rendering.textures.custom.Drawable;
|
||||||
|
import speiger.src.coreengine.rendering.utils.values.textures.GLTextureFormat;
|
||||||
|
import speiger.src.coreengine.utils.eventbus.EventBus;
|
||||||
|
import speiger.src.coreengine.utils.helpers.IOUtils;
|
||||||
|
|
||||||
|
public class NewRenderEngineTest {
|
||||||
|
EventBus bus = new EventBus();
|
||||||
|
WindowManager manager = new WindowManager();
|
||||||
|
AssetManager assets = AssetManager.single(IAssetPackage.asset(IOUtils.getBaseLocation()));
|
||||||
|
|
||||||
|
public static void main(String... args) {
|
||||||
|
new NewRenderEngineTest().run();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
Configuration.HARFBUZZ_LIBRARY_NAME.set(FreeType.getLibrary());
|
||||||
|
GLFW.glfwInit();
|
||||||
|
manager.initialize();
|
||||||
|
Mouse.INSTANCE.init(bus);
|
||||||
|
Keyboard.INSTANCE.init(bus);
|
||||||
|
Joystick.INSTANCE.init(manager, bus);
|
||||||
|
FileDrop.INSTANCE.init(bus);
|
||||||
|
manager.addDevices(Mouse.INSTANCE, Keyboard.INSTANCE, Joystick.INSTANCE, FileDrop.INSTANCE);
|
||||||
|
Graphics graphics = new GLGraphics(assets);
|
||||||
|
Window window = manager.builder().title("Testing Engine").width(800).height(600).antialis(0).build(graphics);
|
||||||
|
GraphicsDevice device = graphics.createDevice(window);
|
||||||
|
window.setupContext();
|
||||||
|
|
||||||
|
GraphicsSurface surface = device.createSurface();
|
||||||
|
int size = 512;
|
||||||
|
int half = size >> 1;
|
||||||
|
int base = size >> 3;
|
||||||
|
Drawable drawer = new Drawable(GLTextureFormat.RGBA, size, size);
|
||||||
|
drawer.fill(0, 0, size, size, -1);
|
||||||
|
drawer.fill(0, 0, half, half, 255, 0, 0, 255);
|
||||||
|
drawer.fill(half, 0, half, half, 0, 255, 0, 255);
|
||||||
|
drawer.fill(half, half, half, half, 255, 0, 0, 255);
|
||||||
|
drawer.fill(0, half, half, half, 0, 0, 255, 255);
|
||||||
|
|
||||||
|
VertexBuilder builder = new VertexBuilder(255);
|
||||||
|
builder.start(null, VertexTypes.TESTING);
|
||||||
|
builder.pos(-0.5F, -0.5F, 0).tex(0F, 1F).rgba(-1).endVertex();
|
||||||
|
builder.pos(0.5F, -0.5F, 0).tex(1F, 1F).rgba(-1).endVertex();
|
||||||
|
builder.pos(0.5F, 0.5F, 0).tex(1F, 0F).rgba(-1).endVertex();
|
||||||
|
builder.pos(0.5F, 0.5F, 0).tex(1F, 0F).rgba(-1).endVertex();
|
||||||
|
builder.pos(-0.5F, 0.5F, 0).tex(0F, 0F).rgba(-1).endVertex();
|
||||||
|
builder.pos(-0.5F, -0.5F, 0).tex(0F, 1F).rgba(-1).endVertex();
|
||||||
|
|
||||||
|
Texture texture = device.createTexture(TextureSettings.builder().build(), size, size);
|
||||||
|
device.queue().writeToTexture(texture, TextureFormat.RGBA, GraphicsDataType.UNSIGNED_BYTE, drawer.pixels());
|
||||||
|
drawer.close();
|
||||||
|
|
||||||
|
VertexLayout layout = VertexLayout.builder()
|
||||||
|
.element("pos", 0, 3, Usage.POS)
|
||||||
|
.element("tex", 1, 2, Usage.UV)
|
||||||
|
.element("color", 2, 4, Usage.COLOR, GraphicsDataType.UNSIGNED_BYTE, true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Mesh mesh = device.createMesh(Mesh.builder().layout(layout));
|
||||||
|
mesh.buffer(0, device.createBuffer(BufferType.ARRAY_BUFFER, BufferState.STATIC_DRAW).bind().set(builder.getBytes()).unbind());
|
||||||
|
|
||||||
|
Sampler sampler = device.createSampler(SamplerSettings.builder().sampler(SampleMode.NEAREST).wrap(BorderMode.CLAMP_TO_EDGE).build());
|
||||||
|
VertexBuffer buffer = device.createBuffer(BufferType.UNIFORM_BUFFER, BufferState.STATIC_DRAW);
|
||||||
|
ByteBuffer mat = ByteBuffer.allocate(64);
|
||||||
|
int scale = 0;
|
||||||
|
new Matrix4f().ortho(0, 0, window.width() >> scale, window.height() >> scale, 1000, -1000).store(mat);
|
||||||
|
buffer.bind().set(mat.flip().array()).unbind();
|
||||||
|
|
||||||
|
|
||||||
|
ShaderPipeline pipeline = ShaderPipeline.builder(ID.of("gui"))
|
||||||
|
.withStage(ShaderType.VERTEX, ID.of("shader/testGui/vertex.vs"))
|
||||||
|
.withStage(ShaderType.FRAGMENT, ID.of("shader/testGui/fragment.fs"))
|
||||||
|
.withTexture("texture", 0, 0, TextureType.TEXTURE_2D)
|
||||||
|
.withUniform("Camera", 0, 0, 64)
|
||||||
|
.withFormat()
|
||||||
|
.attribute("in_position", 0, 3)
|
||||||
|
.attribute("in_tex", 1, 2)
|
||||||
|
.attribute("in_color", 2, 4, GraphicsDataType.UNSIGNED_BYTE, true)
|
||||||
|
.endFormat()
|
||||||
|
.build();
|
||||||
|
window.visible(true);
|
||||||
|
GraphicsCommandBuffer queue = device.createCommandBuffer(ExecutionType.IMMEDIATE);
|
||||||
|
|
||||||
|
while(!window.shouldClose()) {
|
||||||
|
surface.beginFrame();
|
||||||
|
if(window.changed()) {
|
||||||
|
window.updateViewport();
|
||||||
|
new Matrix4f().ortho(0, 0, window.width() >> scale, window.height() >> scale, 1000, -1000).store(mat);
|
||||||
|
buffer.bind().set(mat.flip().array()).unbind();
|
||||||
|
}
|
||||||
|
queue.begin();
|
||||||
|
queue.pipeline(pipeline)
|
||||||
|
.mesh(mesh)
|
||||||
|
.texture(0, texture, sampler)
|
||||||
|
.uniform(0, buffer)
|
||||||
|
.drawArrays(0, 6)
|
||||||
|
.drawArrays(0, 6);
|
||||||
|
|
||||||
|
queue.end();
|
||||||
|
|
||||||
|
surface.finishFrame();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(1);
|
||||||
|
}
|
||||||
|
catch(Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,12 +8,12 @@ import org.lwjgl.opengl.GLCapabilities;
|
|||||||
import org.lwjgl.system.CallbackI;
|
import org.lwjgl.system.CallbackI;
|
||||||
|
|
||||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||||
|
import speiger.src.coreengine.graphics.api.core.Graphics;
|
||||||
import speiger.src.coreengine.math.BitUtil;
|
import speiger.src.coreengine.math.BitUtil;
|
||||||
import speiger.src.coreengine.math.vector.ints.Vec4i;
|
import speiger.src.coreengine.math.vector.ints.Vec4i;
|
||||||
import speiger.src.coreengine.rendering.input.window.IWindowListener.Reason;
|
import speiger.src.coreengine.rendering.input.window.IWindowListener.Reason;
|
||||||
import speiger.src.coreengine.rendering.input.window.WindowCallback.ReloadFunction;
|
import speiger.src.coreengine.rendering.input.window.WindowCallback.ReloadFunction;
|
||||||
import speiger.src.coreengine.rendering.input.window.WindowManager.WindowBuilder;
|
import speiger.src.coreengine.rendering.input.window.WindowManager.WindowBuilder;
|
||||||
import speiger.src.coreengine.rendering.utils.GLStateTracker;
|
|
||||||
import speiger.src.coreengine.utils.collections.FlagHolder;
|
import speiger.src.coreengine.utils.collections.FlagHolder;
|
||||||
|
|
||||||
public class Window {
|
public class Window {
|
||||||
@@ -49,7 +49,7 @@ public class Window {
|
|||||||
List<IWindowListener> listeners = new ObjectArrayList<>();
|
List<IWindowListener> listeners = new ObjectArrayList<>();
|
||||||
GLCapabilities capabilities;
|
GLCapabilities capabilities;
|
||||||
|
|
||||||
protected Window(WindowBuilder builder) {
|
protected Window(WindowBuilder builder, Graphics graphics) {
|
||||||
manager = builder.manager;
|
manager = builder.manager;
|
||||||
title = builder.title;
|
title = builder.title;
|
||||||
frameWidth = width = builder.width;
|
frameWidth = width = builder.width;
|
||||||
@@ -62,7 +62,8 @@ public class Window {
|
|||||||
flags.setFlag(RESIZABLE, builder.resizable);
|
flags.setFlag(RESIZABLE, builder.resizable);
|
||||||
flags.setFlag(VSYNC, builder.vsync);
|
flags.setFlag(VSYNC, builder.vsync);
|
||||||
flags.setFlag(CPU_FPS_CAP, builder.fpsCap);
|
flags.setFlag(CPU_FPS_CAP, builder.fpsCap);
|
||||||
createDefaultWindowHints();
|
if(graphics != null) graphics.setupWindowArguments();
|
||||||
|
else createDefaultWindowHints();
|
||||||
for(int i = 0,m=builder.windowHints.size();i<m;i++) {
|
for(int i = 0,m=builder.windowHints.size();i<m;i++) {
|
||||||
long value = builder.windowHints.getLong(i);
|
long value = builder.windowHints.getLong(i);
|
||||||
GLFW.glfwWindowHint(BitUtil.intKey(value), BitUtil.intValue(value));
|
GLFW.glfwWindowHint(BitUtil.intKey(value), BitUtil.intValue(value));
|
||||||
@@ -81,7 +82,7 @@ public class Window {
|
|||||||
manager.addWindow(this);
|
manager.addWindow(this);
|
||||||
createWindowListeners();
|
createWindowListeners();
|
||||||
GLFW.glfwMakeContextCurrent(id);
|
GLFW.glfwMakeContextCurrent(id);
|
||||||
capabilities = GL.createCapabilities(true);
|
if(graphics == null) capabilities = GL.createCapabilities(true);
|
||||||
x = monitor.xOffset() + (builder.center ? (mode.width() / 2) - (width / 2) : 0);
|
x = monitor.xOffset() + (builder.center ? (mode.width() / 2) - (width / 2) : 0);
|
||||||
y = monitor.yOffset() + (builder.center ? (mode.height() / 2) - (height / 2) : 0);
|
y = monitor.yOffset() + (builder.center ? (mode.height() / 2) - (height / 2) : 0);
|
||||||
if(!fullscreen) GLFW.glfwSetWindowPos(id, x, y);
|
if(!fullscreen) GLFW.glfwSetWindowPos(id, x, y);
|
||||||
@@ -138,14 +139,14 @@ public class Window {
|
|||||||
|
|
||||||
public void updateViewport() {
|
public void updateViewport() {
|
||||||
flags.clearFlag(WINDOW_CHANGE);
|
flags.clearFlag(WINDOW_CHANGE);
|
||||||
GLStateTracker.instance().viewPort.setDefault(0, 0, frameWidth, frameHeight);
|
// GLStateTracker.instance().viewPort.setDefault(0, 0, frameWidth, frameHeight);
|
||||||
for(int i = 0,m=listeners.size();i<m;i++) {
|
for(int i = 0,m=listeners.size();i<m;i++) {
|
||||||
listeners.get(i).onChanged(this, Reason.CHANGE);
|
listeners.get(i).onChanged(this, Reason.CHANGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setupContext() {
|
public void setupContext() {
|
||||||
GL.setCapabilities(capabilities);
|
if(capabilities != null) GL.setCapabilities(capabilities);
|
||||||
GLFW.glfwMakeContextCurrent(id);
|
GLFW.glfwMakeContextCurrent(id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import speiger.src.collections.longs.lists.LongList;
|
|||||||
import speiger.src.collections.longs.maps.impl.concurrent.Long2ObjectConcurrentOpenHashMap;
|
import speiger.src.collections.longs.maps.impl.concurrent.Long2ObjectConcurrentOpenHashMap;
|
||||||
import speiger.src.collections.longs.maps.interfaces.Long2ObjectMap;
|
import speiger.src.collections.longs.maps.interfaces.Long2ObjectMap;
|
||||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
import speiger.src.collections.objects.lists.ObjectArrayList;
|
||||||
|
import speiger.src.coreengine.graphics.api.core.Graphics;
|
||||||
import speiger.src.coreengine.math.BitUtil;
|
import speiger.src.coreengine.math.BitUtil;
|
||||||
import speiger.src.coreengine.rendering.input.devices.InputDevice;
|
import speiger.src.coreengine.rendering.input.devices.InputDevice;
|
||||||
import speiger.src.coreengine.rendering.input.window.WindowCallback.SimpleReloadFunction;
|
import speiger.src.coreengine.rendering.input.window.WindowCallback.SimpleReloadFunction;
|
||||||
@@ -39,7 +40,7 @@ public class WindowManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public WindowBuilder builder() { return new WindowBuilder(this); }
|
public WindowBuilder builder() { return new WindowBuilder(this); }
|
||||||
private Window create(WindowBuilder builder) { return new Window(builder); }
|
private Window create(WindowBuilder builder, Graphics graphics) { return new Window(builder, graphics); }
|
||||||
|
|
||||||
public void addDevices(InputDevice...devices) {
|
public void addDevices(InputDevice...devices) {
|
||||||
for(InputDevice device : devices) addDevice(device);
|
for(InputDevice device : devices) addDevice(device);
|
||||||
@@ -258,8 +259,8 @@ public class WindowManager {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Window build() {
|
public Window build(Graphics graphics) {
|
||||||
return manager.create(this);
|
return manager.create(this, graphics);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
#version 330
|
#version 420
|
||||||
|
|
||||||
in vec4 pass_color;
|
in vec4 pass_color;
|
||||||
in vec2 pass_tex;
|
in vec2 pass_tex;
|
||||||
|
|
||||||
out vec4 frag_color;
|
out vec4 frag_color;
|
||||||
|
|
||||||
uniform sampler2D texture;
|
layout(binding = 0) uniform sampler2D texture;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#version 330
|
#version 420
|
||||||
|
|
||||||
layout(location = 0) in vec3 in_position;
|
layout(location = 0) in vec3 in_position;
|
||||||
layout(location = 1) in vec2 in_tex;
|
layout(location = 1) in vec2 in_tex;
|
||||||
@@ -7,11 +7,13 @@ layout(location = 2) in vec4 in_color;
|
|||||||
out vec4 pass_color;
|
out vec4 pass_color;
|
||||||
out vec2 pass_tex;
|
out vec2 pass_tex;
|
||||||
|
|
||||||
uniform mat4 proViewMatrix;
|
layout(binding = 0) uniform Camera {
|
||||||
|
mat4 proViewMatrix;
|
||||||
|
} camera;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = proViewMatrix * vec4(in_position, 1.0);
|
gl_Position = camera.proViewMatrix * vec4(in_position, 1.0);
|
||||||
pass_color = in_color;
|
pass_color = in_color;
|
||||||
pass_tex = in_tex;
|
pass_tex = in_tex;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user