diff --git a/pom.xml b/pom.xml index 4235934..02069ba 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.opengame engine - 0.0.1-SNAPSHOT + 0.0.2-SNAPSHOT 11 diff --git a/src/main/java/org/opengame/engine/Engine.java b/src/main/java/org/opengame/engine/Engine.java index c355455..02678ff 100644 --- a/src/main/java/org/opengame/engine/Engine.java +++ b/src/main/java/org/opengame/engine/Engine.java @@ -8,6 +8,7 @@ import org.joml.Vector2f; import org.lwjgl.PointerBuffer; import org.lwjgl.bgfx.BGFXInit; +import org.lwjgl.bgfx.BGFXResolution; import org.lwjgl.glfw.GLFWErrorCallback; import org.lwjgl.glfw.GLFWNativeCocoa; import org.lwjgl.glfw.GLFWNativeWin32; @@ -42,7 +43,7 @@ public class Engine { private Scene currentScene; private float tickTime = 1000; - private int msPerUpdate = 1000 / 20; + private int msPerUpdate; /** * Init Vulkan context and window @@ -52,6 +53,7 @@ public void Init(AppConfig config) { log.info("Working directory: " + config.getWorkingDirectory()); instance = this; this.config = config; + msPerUpdate = 1000 / config.getUps(); initWindow(config); } @@ -66,7 +68,7 @@ private void initWindow(AppConfig config) { glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); windowHandle = glfwCreateWindow(config.getWindowWidth(), config.getWindowHeight(), - config.getAppName(), NULL, NULL); + config.getAppName(), config.isFullScreenMode() ? glfwGetPrimaryMonitor() : NULL, NULL); setupInputCallbacks(); @@ -107,7 +109,7 @@ private void initWindow(AppConfig config) { log.info("bgfx renderer: " + bgfx_get_renderer_name(bgfx_get_renderer_type())); bgfx_set_debug(BGFX_DEBUG_TEXT); - bgfx_set_view_clear(0, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x303030ff, 1.0f, 0); + bgfx_set_view_clear(0, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x0, 1.0f, 0); } private void logAvailableRenderers() { @@ -171,7 +173,7 @@ public void startLoop() { var frameMs = (float) toMs * frameTime; if (currentScene != null) { if (tickTime >= msPerUpdate) { - currentScene.update(); + currentScene.update((float) time, msPerUpdate); tickTime = 0; } tickTime += frameMs; @@ -209,4 +211,8 @@ public static int getScreenWidth() { public static int getScreenHeight() { return instance.getConfig().getWindowHeight(); } + + public static AppConfig getAppConfig() { + return instance.config; + } } diff --git a/src/main/java/org/opengame/engine/app/AppConfig.java b/src/main/java/org/opengame/engine/app/AppConfig.java index 4c96aa4..2468d20 100644 --- a/src/main/java/org/opengame/engine/app/AppConfig.java +++ b/src/main/java/org/opengame/engine/app/AppConfig.java @@ -26,6 +26,11 @@ public class AppConfig { private int windowWidth = 800; private int windowHeight = 600; + private boolean fullScreenMode = false; + + // private int fpsLimit = -1; + private int ups = 40; + private String workingDirectory; public String getWorkingDirectory() { @@ -36,10 +41,7 @@ public String getWorkingDirectory() { return workingDirectory; } - public void setWorkingDirectory(String relativePath) throws URISyntaxException, UnsupportedEncodingException { - var jarPath = new File(AppConfig.class.getProtectionDomain().getCodeSource().getLocation() - .toURI()).getPath(); - var jarUtfPath = URLDecoder.decode(jarPath, StandardCharsets.UTF_8); - workingDirectory = jarUtfPath.substring(0, jarUtfPath.lastIndexOf("/") + 1) + relativePath + "/"; + public void setWorkingDirectory(String fullPath) { + workingDirectory = fullPath; } } diff --git a/src/main/java/org/opengame/engine/camera/Camera.java b/src/main/java/org/opengame/engine/camera/Camera.java index 158da77..6558a99 100644 --- a/src/main/java/org/opengame/engine/camera/Camera.java +++ b/src/main/java/org/opengame/engine/camera/Camera.java @@ -1,11 +1,15 @@ package org.opengame.engine.camera; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.java.Log; import org.joml.Matrix4f; import org.joml.Matrix4x3f; import org.joml.Vector3f; +import org.joml.Vector4f; import org.lwjgl.system.MemoryUtil; import org.opengame.engine.Engine; -import org.opengame.engine.object.SceneObject; +import org.opengame.engine.object.MaterialObject; import org.opengame.engine.render.CameraUtils; import java.nio.FloatBuffer; @@ -15,55 +19,117 @@ /** * Base camera class */ -public class Camera extends SceneObject { +@Log +public class Camera extends MaterialObject { private final Matrix4x3f view = new Matrix4x3f(); private final FloatBuffer viewBuffer; private final Matrix4f projection = new Matrix4f(); private final FloatBuffer projectionBuffer; - protected Vector3f position; - protected Vector3f rotation; protected Vector3f direction; protected Vector3f right; protected Vector3f left; protected Vector3f up; + private float nearPlane = 0.1f; + private float farPlane = 100f; + + @Setter + @Getter + private boolean debugMode = false; + public Camera() { viewBuffer = MemoryUtil.memAllocFloat(16); projectionBuffer = MemoryUtil.memAllocFloat(16); - position = new Vector3f(); - rotation = new Vector3f(); direction = new Vector3f(0, 0, -1); right = new Vector3f(1, 0, 0); left = new Vector3f(1, 0, 0); up = new Vector3f(0, 1, 0); - CameraUtils.perspective(35, Engine.getScreenWidth(), Engine.getScreenHeight(), - 0.1f, 100.0f, projection); + setPerspective(35, Engine.getScreenWidth(), Engine.getScreenHeight(), + nearPlane, nearPlane); + } + + public void setPerspective(float fov, int screenWidth, int screenHeight, float nearPlane, float farPlane) { + CameraUtils.perspective(fov, screenWidth, screenHeight, nearPlane, farPlane, projection); + setViewProjection(); } public void setViewProjection() { view.identity(); - var eye = new Vector3f(position); + var eye = new Vector3f(getPosition()); eye.add(direction); - CameraUtils.lookAt(position, eye, view); + CameraUtils.lookAt(getPosition(), eye, view); bgfx_set_view_transform(0, view.get4x4(viewBuffer), projection.get(projectionBuffer)); + + if (debugMode) { + log.info("Current pos: " + getPosition()); + log.info("Current rotation: " + getRotation()); + } + } + + @Override + public void setPosition(Vector3f position) { + super.setPosition(position); + + setViewProjection(); + } + + @Override + public void setRotation(Vector3f rotation) { + super.setRotation(rotation); + + rotateLeftRight(rotation.x); + rotateUpDown(rotation.y); + + setViewProjection(); + } + + + protected void rotateUpDown(float delta) { + var normalizedDirection = direction.normalize(); + var directionNoY = new Vector3f(normalizedDirection.x, 0, normalizedDirection.z).normalize(); + + var currentAngleDegrees = Math.toDegrees(Math.acos(directionNoY.dot(direction))); + if (normalizedDirection.y < 0.0f) { + currentAngleDegrees = -currentAngleDegrees; + } + + var newAngleDegrees = currentAngleDegrees + delta; + + if (newAngleDegrees < -85.0f || newAngleDegrees > 85.0f) return; + + var rotationAxis = new Vector3f(normalizedDirection).cross(up).normalize(); + var rotationMatrix = new Matrix4f().rotate((float) Math.toRadians(delta), rotationAxis); + + var rotatedDirection = new Vector4f(normalizedDirection, 0).mul(rotationMatrix).normalize(); + direction = new Vector3f(rotatedDirection.x, rotatedDirection.y, rotatedDirection.z); + } + + protected void rotateLeftRight(float delta) { + var normalizedDirection = direction.normalize(); + var rotationMatrix = new Matrix4f().rotate((float) Math.toRadians(delta), up); + var rotatedDirection = new Vector4f(normalizedDirection, 0).mul(rotationMatrix); + direction = new Vector3f(rotatedDirection.x, rotatedDirection.y, rotatedDirection.z); + + var rotatedRight = new Vector4f(right.normalize(), 0).mul(rotationMatrix); + right = new Vector3f(rotatedRight.x, rotatedRight.y, rotatedRight.z); } public void moveForward(float offset) { - position.add(direction.x * offset, direction.y * offset, direction.z * offset); + getPosition().add(direction.x * offset, direction.y * offset, direction.z * offset); setViewProjection(); } public void moveRight(float offset) { - position.add(right.x * offset, right.y * offset, right.z * offset); + getPosition().add(right.x * offset, right.y * offset, right.z * offset); setViewProjection(); } public void moveUp(float offset) { - position.add(up.x * offset, up.y * offset, up.z * offset); + getPosition().add(up.x * offset, up.y * offset, up.z * offset); setViewProjection(); } diff --git a/src/main/java/org/opengame/engine/camera/FlyingCamera.java b/src/main/java/org/opengame/engine/camera/FlyingCamera.java index f7eef64..4a820b4 100644 --- a/src/main/java/org/opengame/engine/camera/FlyingCamera.java +++ b/src/main/java/org/opengame/engine/camera/FlyingCamera.java @@ -32,6 +32,8 @@ public class FlyingCamera extends Camera { private float currentForwardSpeed = 0; private float currentUpSpeed = 0; + private float boostMultiplier = 10f; + private float startTime; private float mouseSensitivity = 0.15f; @@ -66,10 +68,14 @@ private void processMouseMovedEvent(MouseEventData eventData) { var deltaY = lastMouseY - eventData.getYPos(); if (deltaX != 0) { - rotateLeftRight((float) deltaX * mouseSensitivity); + var angle = (float) deltaX * mouseSensitivity; + rotateLeftRight(angle); + getRotation().add(angle, 0, 0); } if (deltaY != 0) { + var angle = (float) deltaY * mouseSensitivity; rotateUpDown((float) deltaY * mouseSensitivity); + getRotation().add(0, angle, 0); } setViewProjection(); @@ -79,36 +85,6 @@ private void processMouseMovedEvent(MouseEventData eventData) { //Engine.setCursorPos(windowCenterPos); } - private void rotateUpDown(float delta) { - var normalizedDirection = direction.normalize(); - var directionNoY = new Vector3f(normalizedDirection.x, 0, normalizedDirection.z).normalize(); - - var currentAngleDegrees = Math.toDegrees(Math.acos(directionNoY.dot(direction))); - if (normalizedDirection.y < 0.0f) { - currentAngleDegrees = -currentAngleDegrees; - } - - var newAngleDegrees = currentAngleDegrees + delta; - - if (newAngleDegrees < -85.0f || newAngleDegrees > 85.0f) return; - - var rotationAxis = new Vector3f(normalizedDirection).cross(up).normalize(); - var rotationMatrix = new Matrix4f().rotate((float) Math.toRadians(delta), rotationAxis); - - var rotatedDirection = new Vector4f(normalizedDirection, 0).mul(rotationMatrix).normalize(); - direction = new Vector3f(rotatedDirection.x, rotatedDirection.y, rotatedDirection.z); - } - - private void rotateLeftRight(float delta) { - var normalizedDirection = direction.normalize(); - var rotationMatrix = new Matrix4f().rotate((float) Math.toRadians(delta), up); - var rotatedDirection = new Vector4f(normalizedDirection, 0).mul(rotationMatrix); - direction = new Vector3f(rotatedDirection.x, rotatedDirection.y, rotatedDirection.z); - - var rotatedRight = new Vector4f(right.normalize(), 0).mul(rotationMatrix); - right = new Vector3f(rotatedRight.x, rotatedRight.y, rotatedRight.z); - } - private void processKeyPressedEvent(KeyEventData eventData) { var key = eventData.getKeyCode(); @@ -129,6 +105,11 @@ private void processKeyPressedEvent(KeyEventData eventData) { if (key == GLFW_KEY_SPACE) { currentUpSpeed += flySpeed * isPressedMultiplier; } + if (key == GLFW_KEY_LEFT_SHIFT) { + currentUpSpeed = eventData.isPressed() ? currentUpSpeed * boostMultiplier : currentUpSpeed / boostMultiplier; + currentStrafeSpeed = eventData.isPressed() ? currentStrafeSpeed * boostMultiplier : currentStrafeSpeed / boostMultiplier; + currentForwardSpeed = eventData.isPressed() ? currentForwardSpeed * boostMultiplier : currentForwardSpeed / boostMultiplier; + } if (key == GLFW_MOUSE_BUTTON_RIGHT) { isChangingDirection = eventData.isPressed(); @@ -145,7 +126,7 @@ private void processMousePressedEvent(KeyEventData eventData) { } @Override - public void update() { + public void update(float time, float tickTime) { if (currentStrafeSpeed != 0) { moveRight(currentStrafeSpeed); } diff --git a/src/main/java/org/opengame/engine/event/EventBus.java b/src/main/java/org/opengame/engine/event/EventBus.java index 9d2f622..9433f72 100644 --- a/src/main/java/org/opengame/engine/event/EventBus.java +++ b/src/main/java/org/opengame/engine/event/EventBus.java @@ -2,10 +2,7 @@ import lombok.extern.java.Log; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.function.Consumer; /** @@ -15,13 +12,13 @@ public enum EventBus { INSTANCE; - private final Map>> eventListeners; + private final Map>> eventListeners; EventBus() { eventListeners = new HashMap<>(); } - public static void subscribeToEvent(EventType eventType, Consumer consumer) { + public static void subscribeToEvent(EventType eventType, Consumer consumer) { log.info("Subscribed to " + eventType); if (!INSTANCE.eventListeners.containsKey(eventType)) { @@ -31,7 +28,7 @@ public static void subscribeToEvent(EventType eventType, Consumer con INSTANCE.eventListeners.get(eventType).add(consumer); } - public static void broadcastEvent(EventType eventType, EventData data) { + public static void broadcastEvent(EventType eventType, Object data) { //log.warning("Event broadcast " + eventType); if (!INSTANCE.eventListeners.containsKey(eventType)) return; diff --git a/src/main/java/org/opengame/engine/event/EventData.java b/src/main/java/org/opengame/engine/event/EventData.java deleted file mode 100644 index 54fd1ea..0000000 --- a/src/main/java/org/opengame/engine/event/EventData.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.opengame.engine.event; - -public class EventData { -} diff --git a/src/main/java/org/opengame/engine/event/EventType.java b/src/main/java/org/opengame/engine/event/EventType.java index 8f1f94e..b155e27 100644 --- a/src/main/java/org/opengame/engine/event/EventType.java +++ b/src/main/java/org/opengame/engine/event/EventType.java @@ -1,14 +1,19 @@ package org.opengame.engine.event; +import org.opengame.engine.object.SceneObject; + public enum EventType { KEY_PRESSED(KeyEventData.class), KEY_RELEASED(KeyEventData.class), MOUSE_BUTTON_EVENT(KeyEventData.class), - MOUSE_MOVED(MouseEventData.class); + MOUSE_MOVED(MouseEventData.class), + + // Scene + OBJECT_ADDED_TO_SCENE(SceneObject .class); - private final Class eventDataClass; + private final Class eventDataClass; - EventType(Class eventDataClass) { + EventType(Class eventDataClass) { this.eventDataClass = eventDataClass; } } \ No newline at end of file diff --git a/src/main/java/org/opengame/engine/event/KeyEventData.java b/src/main/java/org/opengame/engine/event/KeyEventData.java index b86e06d..557d2c2 100644 --- a/src/main/java/org/opengame/engine/event/KeyEventData.java +++ b/src/main/java/org/opengame/engine/event/KeyEventData.java @@ -8,7 +8,7 @@ */ @RequiredArgsConstructor @Getter -public class KeyEventData extends EventData { +public class KeyEventData { private final int keyCode; private final boolean isPressed; } \ No newline at end of file diff --git a/src/main/java/org/opengame/engine/event/MouseEventData.java b/src/main/java/org/opengame/engine/event/MouseEventData.java index 762c28e..07f1b35 100644 --- a/src/main/java/org/opengame/engine/event/MouseEventData.java +++ b/src/main/java/org/opengame/engine/event/MouseEventData.java @@ -5,7 +5,7 @@ @RequiredArgsConstructor @Getter -public class MouseEventData extends EventData { +public class MouseEventData { private final double xPos; private final double yPos; } \ No newline at end of file diff --git a/src/main/java/org/opengame/engine/object/DynamicObject.java b/src/main/java/org/opengame/engine/object/DynamicObject.java index 6e11bf0..042e3b3 100644 --- a/src/main/java/org/opengame/engine/object/DynamicObject.java +++ b/src/main/java/org/opengame/engine/object/DynamicObject.java @@ -4,5 +4,5 @@ * Something that can be updated in some way */ public interface DynamicObject { - void update(); + void update(float time, float tickTimeMs); } diff --git a/src/main/java/org/opengame/engine/object/Line.java b/src/main/java/org/opengame/engine/object/Line.java new file mode 100644 index 0000000..cfb492f --- /dev/null +++ b/src/main/java/org/opengame/engine/object/Line.java @@ -0,0 +1,31 @@ +package org.opengame.engine.object; + +import lombok.Getter; +import lombok.Setter; +import org.joml.Vector3f; +import org.opengame.engine.scene.Mesh; +import org.opengame.engine.scene.MeshInfo; + +import java.awt.*; +import java.io.IOException; +import java.util.Arrays; + +/** + * Simple line with color that can be rendered + */ +@Getter +@Setter +public class Line extends LineStrip { + private Vector3f startPoint; + private Vector3f endPoint; + + private Color color; + + public Line(Vector3f startPoint, Vector3f endPoint, Color color) throws IOException { + super(Arrays.asList(startPoint, endPoint), color, 1); + + this.startPoint = startPoint; + this.endPoint = endPoint; + this.color = color; + } +} diff --git a/src/main/java/org/opengame/engine/object/LineStrip.java b/src/main/java/org/opengame/engine/object/LineStrip.java new file mode 100644 index 0000000..9556ca5 --- /dev/null +++ b/src/main/java/org/opengame/engine/object/LineStrip.java @@ -0,0 +1,86 @@ +package org.opengame.engine.object; + +import lombok.Getter; +import lombok.Setter; +import org.joml.Vector3f; +import org.opengame.engine.Engine; +import org.opengame.engine.scene.Mesh; +import org.opengame.engine.scene.MeshInfo; +import org.opengame.engine.scene.MeshLoader; +import org.opengame.engine.scene.Model; + +import java.awt.*; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Vector; + +import static org.lwjgl.bgfx.BGFX.BGFX_STATE_PT_LINES; + +/** + * Simple line with color that can be rendered + */ +@Getter +@Setter +public class LineStrip extends Model { + protected List points; + + private Color color; + private float width; + + public LineStrip(List points, Color color, float width) throws IOException { + super(createMeshes(points, color, width)); + + this.points = points; + this.color = color; + this.width = width; + } + + private static List createMeshes(List points, Color color, float width) throws IOException { + var meshes = new ArrayList(points.size() - 1); + for (int i = 0; i < points.size(); i++) { + var point = points.get(i); + var second = points.size() > i + 1 ? points.get(i+1) : null; + + meshes.add(createMesh(point, second, color, width)); + } + + return meshes; + } + + private static Mesh createMesh(Vector3f point, Vector3f second, Color color, float width) throws IOException { + var info = MeshInfo.builder().useTexture(false).color(color).build(); + var mesh = MeshLoader.loadMeshes("models/cylinder.obj", info).get(0); + + mesh.setPosition(point); + if (second != null) { + mesh.setScale(new Vector3f( + Math.max(Math.abs(second.x - point.x), width), + Math.max(Math.abs(second.y - point.y), width), + Math.max(Math.abs(second.z - point.z), width))); + } + + return mesh; + } + + public void addPoint(Vector3f point) throws IOException { + var lastMesh = getMeshes().get(getMeshes().size() - 1); + var lastPoint = lastMesh.getPosition(); + var mesh = createMesh(point, null, color, width); + getMeshes().add(mesh); + getPoints().add(point); + + lastMesh.lookAt(mesh.getPosition()); + //mesh.lookAt(lastMesh.getPosition()); + + lastMesh.setScale(new Vector3f(width, width * 2, width)); + + if (points.size() > 100) { + points.remove(0); + Engine.getCurrentScene().remove(getMeshes().get(0)); + getMeshes().remove(0); + } + + Engine.getCurrentScene().add(mesh); + } +} diff --git a/src/main/java/org/opengame/engine/object/MaterialObject.java b/src/main/java/org/opengame/engine/object/MaterialObject.java new file mode 100644 index 0000000..7446f98 --- /dev/null +++ b/src/main/java/org/opengame/engine/object/MaterialObject.java @@ -0,0 +1,16 @@ +package org.opengame.engine.object; + +import lombok.Getter; +import lombok.Setter; +import org.joml.Quaternionf; +import org.joml.Vector3f; + +@Getter +@Setter +public class MaterialObject extends SceneObject { + private Vector3f position = new Vector3f(); + // TODO delete (replace by orientation) + private Vector3f rotation = new Vector3f(); + private Quaternionf orientation = new Quaternionf(); + private Vector3f scale = new Vector3f(1, 1, 1); +} diff --git a/src/main/java/org/opengame/engine/object/SceneObject.java b/src/main/java/org/opengame/engine/object/SceneObject.java index 6d98d0d..137f8c1 100644 --- a/src/main/java/org/opengame/engine/object/SceneObject.java +++ b/src/main/java/org/opengame/engine/object/SceneObject.java @@ -13,7 +13,7 @@ public void frame(float time, float frameTimeMs) { } @Override - public void update() { + public void update(float time, float tickTimeMs) { // override in children } } diff --git a/src/main/java/org/opengame/engine/render/Material.java b/src/main/java/org/opengame/engine/render/Material.java new file mode 100644 index 0000000..5e023bf --- /dev/null +++ b/src/main/java/org/opengame/engine/render/Material.java @@ -0,0 +1,44 @@ +package org.opengame.engine.render; + +import lombok.Data; +import org.joml.Vector3f; +import org.lwjgl.assimp.AIColor4D; +import org.lwjgl.assimp.AIMaterial; + +import static org.lwjgl.assimp.Assimp.*; + +/** + * Representing material + */ +@Data +public class Material { + private float[] ambienceColor; + private float[] diffuseColor; + private float[] specularColor; + + public static Material from(AIMaterial aiMaterial) { + var material = new Material(); + + var mAmbienceColor = AIColor4D.create(); + if (aiGetMaterialColor(aiMaterial, AI_MATKEY_COLOR_AMBIENT, + aiTextureType_NONE, 0, mAmbienceColor) != 0) { + throw new IllegalStateException(aiGetErrorString()); + } + var mDiffuseColor = AIColor4D.create(); + if (aiGetMaterialColor(aiMaterial, AI_MATKEY_COLOR_DIFFUSE, + aiTextureType_NONE, 0, mDiffuseColor) != 0) { + throw new IllegalStateException(aiGetErrorString()); + } + var mSpecularColor = AIColor4D.create(); + if (aiGetMaterialColor(aiMaterial, AI_MATKEY_COLOR_SPECULAR, + aiTextureType_NONE, 0, mSpecularColor) != 0) { + throw new IllegalStateException(aiGetErrorString()); + } + + material.ambienceColor = new float[] { mAmbienceColor.r(), mAmbienceColor.g(), mAmbienceColor.b(), mAmbienceColor.a()}; + material.diffuseColor = new float[] { mDiffuseColor.r(), mDiffuseColor.g(), mDiffuseColor.b(), mDiffuseColor.a()}; + material.specularColor = new float[] { mSpecularColor.r(), mSpecularColor.g(), mSpecularColor.b(), mSpecularColor.a()}; + + return material; + } +} diff --git a/src/main/java/org/opengame/engine/render/TestCube.java b/src/main/java/org/opengame/engine/render/TestCube.java index eaf599e..3f1d359 100644 --- a/src/main/java/org/opengame/engine/render/TestCube.java +++ b/src/main/java/org/opengame/engine/render/TestCube.java @@ -2,6 +2,7 @@ import lombok.Getter; import org.opengame.engine.scene.Mesh; +import org.opengame.engine.scene.MeshInfo; import java.io.IOException; @@ -12,7 +13,7 @@ public class TestCube extends Mesh { public TestCube() throws IOException { - super(getTestVertices(), getTestIndices(), "vs_cube", "fs_cube", null); + super(MeshInfo.builder().vertexData(getTestVertices()).indexData(getTestIndices()).build()); } private static Object[][] getTestVertices() { diff --git a/src/main/java/org/opengame/engine/scene/Mesh.java b/src/main/java/org/opengame/engine/scene/Mesh.java index f6274c3..ac0a9b6 100644 --- a/src/main/java/org/opengame/engine/scene/Mesh.java +++ b/src/main/java/org/opengame/engine/scene/Mesh.java @@ -3,24 +3,28 @@ import lombok.Getter; import lombok.Setter; import lombok.extern.java.Log; -import lombok.extern.log4j.Log4j2; -import org.joml.Matrix4x3f; -import org.joml.Vector3f; +import org.joml.*; import org.lwjgl.bgfx.BGFXMemory; import org.lwjgl.bgfx.BGFXReleaseFunctionCallback; import org.lwjgl.bgfx.BGFXVertexLayout; import org.lwjgl.system.MemoryUtil; import org.opengame.engine.Engine; -import org.opengame.engine.object.SceneObject; +import org.opengame.engine.camera.Camera; +import org.opengame.engine.object.MaterialObject; +import org.opengame.engine.render.Material; +import java.awt.*; import java.io.BufferedInputStream; import java.io.File; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.FloatBuffer; +import java.nio.IntBuffer; import java.util.Arrays; import java.util.Objects; +import java.util.Vector; +import static org.joml.Math.*; import static org.lwjgl.bgfx.BGFX.*; import static org.lwjgl.system.MemoryUtil.*; @@ -28,65 +32,100 @@ * Base class for all meshes */ @Log -public class Mesh extends SceneObject { - private static final int VERTEX_SIZE = (5 * 4); +public class Mesh extends MaterialObject { private static BGFXReleaseFunctionCallback releaseMemoryCb = BGFXReleaseFunctionCallback.create((_ptr, _userData) -> nmemFree(_ptr)); - private static final String TEST_TEXTURE = "test.dds"; + private static final String TEST_TEXTURE = "textures/test.dds"; - private final ByteBuffer vertices; - private final ByteBuffer indices; + @Getter + @Setter + private ByteBuffer vertices; + @Getter + @Setter + private ByteBuffer indices; + + @Getter + @Setter + private Material[] materials; @Getter - private final int vertexCount; + @Setter + private int vertexCount; @Getter - private final int indexCount; + @Setter + private int indexCount; private final short vertexBuffer; private final short indexBuffer; private final BGFXVertexLayout layout; private final short program; + + private short textureUniform = -1; + private short colorUniform = -1; + private short camPosUniform = -1; + private short ambienceColorUniform = -1; + private short diffuseColorUniform = -1; + private short specColorUniform = -1; + private short specCoeffUniform = -1; private short texture; - private short textureUniform; + + private float[] colorBuf; + private long drawType; + + private int vertexSize; private final Matrix4x3f model = new Matrix4x3f(); - private final FloatBuffer modelBuffer; - @Getter - @Setter - private Vector3f position; - @Getter - @Setter - private Vector3f rotation; - - public Mesh(Object[][] vertexData, int[] indexData, String vertexShaderName, - String fragmentShaderName, String textureFileName) throws IOException { - position = new Vector3f(); - rotation = new Vector3f(); - - layout = createVertexLayout(false, false, true); - vertexCount = vertexData.length; - vertices = memAlloc(vertexData.length * VERTEX_SIZE); - vertexBuffer = createVertexBuffer(vertices, layout, vertexData); - indexCount = indexData.length; - indices = memAlloc(indexData.length * 2); - indexBuffer = createIndexBuffer(indices, indexData); - texture = loadTexture(textureFileName == null ? TEST_TEXTURE : textureFileName); - textureUniform = bgfx_create_uniform("s_texColor", BGFX_UNIFORM_TYPE_VEC4, 1); + private final FloatBuffer modelBuffer; - if (vertexShaderName != null && fragmentShaderName != null) { - short vertexShader = loadShader(vertexShaderName); - short fragmentShader = loadShader(fragmentShaderName); + public Mesh(MeshInfo info) throws IOException { + this.materials = info.getMaterials(); - this.program = bgfx_create_program(vertexShader, fragmentShader, true); + this.vertexSize = info.isVertexWithColor() ? 4 * 4 : info.isUseTexture() ? 4 * 5 : 4 * 3; + if (info.isUseNormals()) { + vertexSize += 3 * 4; + } + this.drawType = info.getDrawType(); + + layout = createVertexLayout(info.isUseNormals(), info.isVertexWithColor(), info.isUseTexture()); + vertexCount = info.getVertexData().length; + vertices = memAlloc(info.getVertexData().length * vertexSize); + vertexBuffer = createVertexBuffer(vertices, layout, info.getVertexData()); + indexCount = info.getIndexData().length; + indices = memAlloc(info.getIndexData().length * 2); + indexBuffer = createIndexBuffer(indices, info.getIndexData()); + + if (info.getTextureFileName() != null) { + texture = loadTexture(info.getTextureFileName()); + textureUniform = bgfx_create_uniform("s_texColor", BGFX_UNIFORM_TYPE_VEC4, 1); } else { - // default shader - this.program = 0; + texture = -1; + textureUniform = -1; } + if (info.getColor() != null) { + colorBuf = createBufferForColor(info.getColor()); + colorUniform = bgfx_create_uniform("u_color", BGFX_UNIFORM_TYPE_VEC4, 1); + } + if (info.isUseNormals()) { + diffuseColorUniform = bgfx_create_uniform("u_diffuseColor", BGFX_UNIFORM_TYPE_VEC4, 1); + specColorUniform = bgfx_create_uniform("u_specColor", BGFX_UNIFORM_TYPE_VEC4, 1); + ambienceColorUniform = bgfx_create_uniform("u_ambienceColor", BGFX_UNIFORM_TYPE_VEC4, 1); + } + + camPosUniform = bgfx_create_uniform("u_camPos", BGFX_UNIFORM_TYPE_VEC4, 1); + + program = loadShaderProgram(info); modelBuffer = MemoryUtil.memAllocFloat(16); } + private float[] createBufferForColor(Color color) { + var components = color.getRGBColorComponents(new float[4]); + components[3] = color.getAlpha() * 1.0f / 255f; + + return components; + } + /** * Create vertex layout for mesh * @param withNormals use normals @@ -100,15 +139,15 @@ protected BGFXVertexLayout createVertexLayout(boolean withNormals, boolean withC bgfx_vertex_layout_begin(layout, Engine.getRenderer()); bgfx_vertex_layout_add(layout, BGFX_ATTRIB_POSITION, 3, BGFX_ATTRIB_TYPE_FLOAT, false, false); - if (withNormals) { - bgfx_vertex_layout_add(layout, BGFX_ATTRIB_NORMAL, 3, BGFX_ATTRIB_TYPE_FLOAT, false, false); - } if (withColor) { bgfx_vertex_layout_add(layout, BGFX_ATTRIB_COLOR0, 4, BGFX_ATTRIB_TYPE_UINT8, true, false); } if (withTexture) { bgfx_vertex_layout_add(layout, BGFX_ATTRIB_TEXCOORD0, 2, BGFX_ATTRIB_TYPE_FLOAT, true, true); } + if (withNormals) { + bgfx_vertex_layout_add(layout, BGFX_ATTRIB_NORMAL, 3, BGFX_ATTRIB_TYPE_FLOAT, false, false); + } bgfx_vertex_layout_end(layout); @@ -143,6 +182,18 @@ protected short createIndexBuffer(ByteBuffer buffer, int[] indices) { return bgfx_create_index_buffer(Objects.requireNonNull(bgfx_make_ref(buffer)), BGFX_BUFFER_NONE); } + private short loadShaderProgram(MeshInfo info) throws IOException { + if (info.getVertexShaderName() != null && info.getFragmentShaderName() != null) { + short vertexShader = loadShader(info.getVertexShaderName()); + short fragmentShader = loadShader(info.getFragmentShaderName()); + + return bgfx_create_program(vertexShader, fragmentShader, true); + } else { + // default shader + return 0; + } + } + private short loadShader(String shaderName) throws IOException { String resourcePath = Engine.getWorkingDirectory() + "shaders/"; @@ -176,7 +227,7 @@ private short loadShader(String shaderName) throws IOException { } private short loadTexture(String fileName) throws IOException { - var textureDirPath = Engine.getWorkingDirectory() + "textures/"; + var textureDirPath = Engine.getWorkingDirectory(); ByteBuffer textureData = loadResource(textureDirPath + fileName); BGFXMemory textureMemory = bgfx_make_ref_release(textureData, releaseMemoryCb, NULL); @@ -213,33 +264,61 @@ private ByteBuffer loadResource(String resourcePath) throws IOException { } public void setTexture(String textureName) throws IOException { - bgfx_destroy_texture(texture); - bgfx_destroy_uniform(textureUniform); + if (texture != -1) { + bgfx_destroy_texture(texture); + bgfx_destroy_uniform(textureUniform); + } texture = loadTexture(textureName); textureUniform = bgfx_create_uniform("s_texColor", BGFX_UNIFORM_TYPE_VEC4, 1); } + public void lookAt(Vector3f lookAt) { + var targetDir = new Vector3f(lookAt.x - getPosition().x, + lookAt.y - getPosition().y, + lookAt.z - getPosition().z).normalize(); + var currentDir = new Vector3f(0, 1, 0).rotate(getOrientation()); + + getOrientation().rotationTo(currentDir, targetDir); + } + @Override public void frame(float time, float frameTime) { bgfx_dbg_text_printf(0, 2, 0x6f, "OpenGameEngine 0.0.1-SNAPSHOT"); bgfx_dbg_text_printf(0, 3, 0x0f, String.format("Frame: %7.3f[ms]", frameTime)); long encoder = bgfx_encoder_begin(false); + bgfx_encoder_set_transform(encoder, - model.translation(position) - .rotateXYZ(rotation) - .get4x4(modelBuffer)); + model.translation(getPosition()) + .rotate(getOrientation()) + .scale(getScale()) + .get4x4(modelBuffer)); bgfx_encoder_set_vertex_buffer(encoder, 0, vertexBuffer, 0, vertexCount); bgfx_encoder_set_index_buffer(encoder, indexBuffer, 0, indexCount); - bgfx_encoder_set_texture(encoder, 0, textureUniform, texture, 0xffffffff); + if (texture != -1) { + bgfx_encoder_set_texture(encoder, 0, textureUniform, texture, 0xffffffff); + } + if (colorUniform != -1) { + bgfx_encoder_set_uniform(encoder, colorUniform, colorBuf,1); + } + if (camPosUniform != -1) { + var cameraPos = Engine.getCurrentScene().getCamera().getPosition(); + bgfx_encoder_set_uniform(encoder, camPosUniform, new float[] {cameraPos.x, cameraPos.y, cameraPos.z, 1.0f}, 1); + } + if (ambienceColorUniform != -1) { + bgfx_encoder_set_uniform(encoder, ambienceColorUniform, materials[0].getAmbienceColor(), 1); + bgfx_encoder_set_uniform(encoder, diffuseColorUniform, materials[0].getDiffuseColor(), 1); + bgfx_encoder_set_uniform(encoder, specColorUniform, materials[0].getSpecularColor(), 1); + } bgfx_encoder_set_state(encoder, BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A | BGFX_STATE_WRITE_Z | BGFX_STATE_DEPTH_TEST_LESS + | drawType | BGFX_STATE_MSAA, 0); bgfx_encoder_submit(encoder, 0, program, 0, 0); @@ -250,11 +329,17 @@ public void dispose() { MemoryUtil.memFree(modelBuffer); bgfx_destroy_program(program); - bgfx_destroy_texture(texture); - bgfx_destroy_uniform(textureUniform); + + if (textureUniform != -1) { + bgfx_destroy_texture(texture); + bgfx_destroy_uniform(textureUniform); + } + if (colorUniform != -1) { + bgfx_destroy_uniform(colorUniform); + } bgfx_destroy_index_buffer(indexBuffer); + bgfx_destroy_vertex_buffer(vertexBuffer); MemoryUtil.memFree(indices); } - } diff --git a/src/main/java/org/opengame/engine/scene/MeshInfo.java b/src/main/java/org/opengame/engine/scene/MeshInfo.java new file mode 100644 index 0000000..6566384 --- /dev/null +++ b/src/main/java/org/opengame/engine/scene/MeshInfo.java @@ -0,0 +1,30 @@ +package org.opengame.engine.scene; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import org.opengame.engine.render.Material; + +import java.awt.*; + +import static org.lwjgl.bgfx.BGFX.BGFX_STATE_PT_TRISTRIP; + +/** + * All required stuff to render something using backend + */ +@Builder +@Getter +@Setter +public class MeshInfo { + private Object[][] vertexData; + private int[] indexData; + private String vertexShaderName; + private String fragmentShaderName; + private String textureFileName; + private Color color; + private boolean vertexWithColor = false; + private boolean useTexture = true; + private boolean useNormals = false; + private long drawType = BGFX_STATE_PT_TRISTRIP; + private Material[] materials; +} diff --git a/src/main/java/org/opengame/engine/scene/MeshLoader.java b/src/main/java/org/opengame/engine/scene/MeshLoader.java index 6069f43..47bf719 100644 --- a/src/main/java/org/opengame/engine/scene/MeshLoader.java +++ b/src/main/java/org/opengame/engine/scene/MeshLoader.java @@ -1,11 +1,15 @@ package org.opengame.engine.scene; import lombok.extern.java.Log; +import org.lwjgl.PointerBuffer; +import org.lwjgl.assimp.AIMaterial; import org.lwjgl.assimp.AIMesh; import org.lwjgl.assimp.AIScene; +import org.opengame.engine.render.Material; import java.io.IOException; import java.util.ArrayList; +import java.util.List; import static org.lwjgl.assimp.Assimp.aiImportFile; import static org.lwjgl.assimp.Assimp.aiProcess_OptimizeMeshes; @@ -15,7 +19,17 @@ */ @Log public class MeshLoader { - public static Model loadModel(String modelPath) throws IOException { + public static List loadMeshes(String modelPath) throws IOException { + var defaultMeshInfo = MeshInfo.builder() + .useTexture(true) + .useNormals(true) + .vertexShaderName("vs_textured") + .fragmentShaderName("fs_textured").build(); + + return loadMeshes(modelPath, defaultMeshInfo); + } + + public static List loadMeshes(String modelPath, MeshInfo meshInfo) throws IOException { AIScene scene = aiImportFile(modelPath, aiProcess_OptimizeMeshes); if (scene == null) { @@ -29,22 +43,54 @@ public static Model loadModel(String modelPath) throws IOException { var meshesBuffer = scene.mMeshes(); var meshes = new ArrayList(); for (int i = 0; i < scene.mNumMeshes(); i++) { - meshes.add(createMesh(AIMesh.create(meshesBuffer.get(i)))); + meshes.add(createMesh(AIMesh.create(meshesBuffer.get(i)), meshInfo, scene.mMaterials())); } - return new Model(meshes); + return meshes; + } + + public static Model loadModel(String modelPath) throws IOException { + return new Model(loadMeshes(modelPath)); + } + + public static Model loadModel(String modelPath, MeshInfo info) throws IOException { + return new Model(loadMeshes(modelPath, info)); } - private static Mesh createMesh(AIMesh aiMesh) throws IOException { + private static Mesh createMesh(AIMesh aiMesh, MeshInfo meshInfo, PointerBuffer materials) throws IOException { var vertices = aiMesh.mVertices(); var texCoords = aiMesh.mTextureCoords(0); + var normals = aiMesh.mNormals(); assert texCoords != null; - var meshVertices = new Object[aiMesh.mNumVertices()][5]; - for (int i = 0; i < meshVertices.length; i++) { + int size = 3; + if (meshInfo.isUseTexture()) { + size += 2; + } + if (meshInfo.isUseNormals()) { + size += 3; + } + var meshVertices = new Object[aiMesh.mNumVertices()][size];; + for (int i = 0; i < aiMesh.mNumVertices(); i++) { var vert = vertices.get(i); - meshVertices[i] = new Object[]{ vert.x(), vert.y(), vert.z(), texCoords.get(i).x(), texCoords.get(i).y()}; + if (meshInfo.isUseTexture()) { + if (meshInfo.isUseNormals()) { + meshVertices[i] = new Object[]{ vert.x(), vert.y(), vert.z(), + texCoords.get(i).x(), texCoords.get(i).y(), + normals.get(i).x(), normals.get(i).y(), normals.get(i).z()}; + } else { + meshVertices[i] = new Object[]{ vert.x(), vert.y(), vert.z(), + texCoords.get(i).x(), texCoords.get(i).y()}; + } + } else { + if (meshInfo.isUseNormals()) { + meshVertices[i] = new Object[]{ vert.x(), vert.y(), vert.z(), + normals.get(i).x(), normals.get(i).y(), normals.get(i).z()}; + } else { + meshVertices[i] = new Object[]{ vert.x(), vert.y(), vert.z() }; + } + } } var faces = aiMesh.mFaces(); @@ -56,7 +102,16 @@ private static Mesh createMesh(AIMesh aiMesh) throws IOException { meshIndices[i * 3 + 2] = face.mIndices().get(2); } - return new Mesh(meshVertices, meshIndices, - "vs_simple_textured", "fs_simple_textured", null); + var material = Material.from(AIMaterial.create(materials.get(aiMesh.mMaterialIndex()))); + + return new Mesh(MeshInfo.builder() + .vertexData(meshVertices) + .indexData(meshIndices) + .useNormals(meshInfo.isUseNormals()) + .useTexture(meshInfo.isUseTexture()) + .materials(new Material[] { material }) + .vertexShaderName(meshInfo.getVertexShaderName()) + .fragmentShaderName(meshInfo.getFragmentShaderName()) + .color(meshInfo.getColor()).build()); } } diff --git a/src/main/java/org/opengame/engine/scene/Model.java b/src/main/java/org/opengame/engine/scene/Model.java index e6b5617..88bc551 100644 --- a/src/main/java/org/opengame/engine/scene/Model.java +++ b/src/main/java/org/opengame/engine/scene/Model.java @@ -1,25 +1,41 @@ package org.opengame.engine.scene; import lombok.Getter; +import org.joml.Quaternionf; import org.joml.Vector3f; +import org.opengame.engine.object.MaterialObject; import org.opengame.engine.object.Renderable; import java.io.IOException; import java.util.List; -public class Model implements Renderable { +public class Model extends MaterialObject { + private boolean shadingEnabled = true; + private String model; @Getter private List meshes; + private Vector3f scale = new Vector3f(1, 1, 1); + public Model(List meshes) { this.meshes = meshes; } + @Override public void setRotation(Vector3f setRotation) { + super.setRotation(setRotation); meshes.forEach((mesh) -> mesh.setRotation(setRotation)); } + + @Override + public void setOrientation(Quaternionf orientation) { + super.setOrientation(orientation); + meshes.forEach((mesh) -> mesh.setOrientation(orientation)); + } + public void setPosition(Vector3f position) { + super.setPosition(position); meshes.forEach((mesh) -> mesh.setPosition(position)); } @@ -32,6 +48,13 @@ public void setTexture(String textureName) { } }); } + + public void setScale(Vector3f scale) { + super.setScale(scale); + this.scale = scale; + meshes.forEach(mesh -> mesh.setScale(scale)); + } + @Override public void frame(float time, float frameTimeMs) { meshes.forEach((mesh) -> mesh.frame(time, frameTimeMs)); diff --git a/src/main/java/org/opengame/engine/scene/Scene.java b/src/main/java/org/opengame/engine/scene/Scene.java index 8223f83..81e5fa9 100644 --- a/src/main/java/org/opengame/engine/scene/Scene.java +++ b/src/main/java/org/opengame/engine/scene/Scene.java @@ -5,8 +5,11 @@ import lombok.extern.java.Log; import org.opengame.engine.camera.Camera; import org.opengame.engine.camera.FlyingCamera; +import org.opengame.engine.event.EventBus; +import org.opengame.engine.event.EventType; import org.opengame.engine.object.SceneObject; +import java.awt.*; import java.util.Vector; /** @@ -18,10 +21,15 @@ public class Scene { private String name; private final Vector objects; + private final Vector objectsToAdd; + private final Vector objectsToRemove; private Camera camera; + private Color skyboxColor; public Scene() { objects = new Vector<>(); + objectsToAdd = new Vector<>(); + objectsToRemove = new Vector<>(); setCamera(FlyingCamera.createDefault()); name = "TestScene"; @@ -29,18 +37,28 @@ public Scene() { } public void add(SceneObject mesh) { - objects.add(mesh); + objectsToAdd.add(mesh); + EventBus.broadcastEvent(EventType.OBJECT_ADDED_TO_SCENE, mesh); } public void add(Model model) { - objects.addAll(model.getMeshes()); + objectsToAdd.add(model); + EventBus.broadcastEvent(EventType.OBJECT_ADDED_TO_SCENE, model); + } + + public void remove(SceneObject object) { + objectsToRemove.add(object); } public void render(float time, float frameTime) { objects.forEach((mesh) -> mesh.frame(time, frameTime)); } - public void update() { - objects.forEach(SceneObject::update); + public void update(float time, float tickTime) { + objects.removeAll(objectsToRemove); + objects.addAll(objectsToAdd); + objectsToAdd.clear(); + objectsToRemove.clear(); + objects.forEach((obj) -> obj.update(time, tickTime)); } public void setCamera(Camera camera) { @@ -48,7 +66,9 @@ public void setCamera(Camera camera) { objects.remove(camera); } this.camera = camera; - objects.add(camera); + camera.setViewProjection(); + EventBus.broadcastEvent(EventType.OBJECT_ADDED_TO_SCENE, camera); + objectsToAdd.add(camera); } public String getStats() { @@ -68,4 +88,8 @@ public String getStats() { }).sum(); return "[meshes: " + objects.size() + "; vertices: " + vertexCount + "; indices: " + indexCount + "]"; } + + public Color getSkyboxColor() { + return skyboxColor; + } } diff --git a/src/main/resources/models/cylinder.mtl b/src/main/resources/models/cylinder.mtl new file mode 100644 index 0000000..f231bdf --- /dev/null +++ b/src/main/resources/models/cylinder.mtl @@ -0,0 +1,10 @@ +# Blender MTL File: 'None' +# Material Count: 1 + +newmtl None +Ns 500 +Ka 0.8 0.8 0.8 +Kd 0.8 0.8 0.8 +Ks 0.8 0.8 0.8 +d 1 +illum 2 diff --git a/src/main/resources/models/cylinder.obj b/src/main/resources/models/cylinder.obj new file mode 100644 index 0000000..905b5a6 --- /dev/null +++ b/src/main/resources/models/cylinder.obj @@ -0,0 +1,358 @@ +# Blender v2.82 (sub 7) OBJ File: '' +# www.blender.org +mtllib cylinder.mtl +o Cylinder +v 0.000000 -1.000000 -1.000000 +v 0.000000 1.000000 -1.000000 +v 0.195090 -1.000000 -0.980785 +v 0.195090 1.000000 -0.980785 +v 0.382683 -1.000000 -0.923880 +v 0.382683 1.000000 -0.923880 +v 0.555570 -1.000000 -0.831470 +v 0.555570 1.000000 -0.831470 +v 0.707107 -1.000000 -0.707107 +v 0.707107 1.000000 -0.707107 +v 0.831470 -1.000000 -0.555570 +v 0.831470 1.000000 -0.555570 +v 0.923880 -1.000000 -0.382683 +v 0.923880 1.000000 -0.382683 +v 0.980785 -1.000000 -0.195090 +v 0.980785 1.000000 -0.195090 +v 1.000000 -1.000000 -0.000000 +v 1.000000 1.000000 -0.000000 +v 0.980785 -1.000000 0.195090 +v 0.980785 1.000000 0.195090 +v 0.923880 -1.000000 0.382683 +v 0.923880 1.000000 0.382683 +v 0.831470 -1.000000 0.555570 +v 0.831470 1.000000 0.555570 +v 0.707107 -1.000000 0.707107 +v 0.707107 1.000000 0.707107 +v 0.555570 -1.000000 0.831470 +v 0.555570 1.000000 0.831470 +v 0.382683 -1.000000 0.923880 +v 0.382683 1.000000 0.923880 +v 0.195090 -1.000000 0.980785 +v 0.195090 1.000000 0.980785 +v -0.000000 -1.000000 1.000000 +v -0.000000 1.000000 1.000000 +v -0.195091 -1.000000 0.980785 +v -0.195091 1.000000 0.980785 +v -0.382684 -1.000000 0.923879 +v -0.382684 1.000000 0.923879 +v -0.555571 -1.000000 0.831469 +v -0.555571 1.000000 0.831469 +v -0.707107 -1.000000 0.707106 +v -0.707107 1.000000 0.707106 +v -0.831470 -1.000000 0.555570 +v -0.831470 1.000000 0.555570 +v -0.923880 -1.000000 0.382683 +v -0.923880 1.000000 0.382683 +v -0.980785 -1.000000 0.195089 +v -0.980785 1.000000 0.195089 +v -1.000000 -1.000000 -0.000001 +v -1.000000 1.000000 -0.000001 +v -0.980785 -1.000000 -0.195091 +v -0.980785 1.000000 -0.195091 +v -0.923879 -1.000000 -0.382684 +v -0.923879 1.000000 -0.382684 +v -0.831469 -1.000000 -0.555571 +v -0.831469 1.000000 -0.555571 +v -0.707106 -1.000000 -0.707108 +v -0.707106 1.000000 -0.707108 +v -0.555569 -1.000000 -0.831470 +v -0.555569 1.000000 -0.831470 +v -0.382682 -1.000000 -0.923880 +v -0.382682 1.000000 -0.923880 +v -0.195089 -1.000000 -0.980786 +v -0.195089 1.000000 -0.980786 +vt 1.000000 1.000000 +vt 0.968750 0.500000 +vt 1.000000 0.500000 +vt 0.968750 1.000000 +vt 0.937500 0.500000 +vt 0.937500 1.000000 +vt 0.906250 0.500000 +vt 0.906250 1.000000 +vt 0.875000 0.500000 +vt 0.875000 1.000000 +vt 0.843750 0.500000 +vt 0.843750 1.000000 +vt 0.812500 0.500000 +vt 0.812500 1.000000 +vt 0.781250 0.500000 +vt 0.781250 1.000000 +vt 0.750000 0.500000 +vt 0.750000 1.000000 +vt 0.718750 0.500000 +vt 0.718750 1.000000 +vt 0.687500 0.500000 +vt 0.687500 1.000000 +vt 0.656250 0.500000 +vt 0.656250 1.000000 +vt 0.625000 0.500000 +vt 0.625000 1.000000 +vt 0.593750 0.500000 +vt 0.593750 1.000000 +vt 0.562500 0.500000 +vt 0.562500 1.000000 +vt 0.531250 0.500000 +vt 0.531250 1.000000 +vt 0.500000 0.500000 +vt 0.500000 1.000000 +vt 0.468750 0.500000 +vt 0.468750 1.000000 +vt 0.437500 0.500000 +vt 0.437500 1.000000 +vt 0.406250 0.500000 +vt 0.406250 1.000000 +vt 0.375000 0.500000 +vt 0.375000 1.000000 +vt 0.343750 0.500000 +vt 0.343750 1.000000 +vt 0.312500 0.500000 +vt 0.312500 1.000000 +vt 0.281250 0.500000 +vt 0.281250 1.000000 +vt 0.250000 0.500000 +vt 0.250000 1.000000 +vt 0.218750 0.500000 +vt 0.218750 1.000000 +vt 0.187500 0.500000 +vt 0.187500 1.000000 +vt 0.156250 0.500000 +vt 0.156250 1.000000 +vt 0.125000 0.500000 +vt 0.125000 1.000000 +vt 0.093750 0.500000 +vt 0.093750 1.000000 +vt 0.062500 0.500000 +vt 0.028269 0.341844 +vt 0.158156 0.028269 +vt 0.471731 0.158156 +vt 0.062500 1.000000 +vt 0.031250 0.500000 +vt 0.031250 1.000000 +vt 0.000000 0.500000 +vt 0.985388 0.296822 +vt 0.796822 0.014612 +vt 0.514611 0.203179 +vt 0.341844 0.471731 +vt 0.296822 0.485388 +vt 0.250000 0.490000 +vt 0.203179 0.485389 +vt 0.158156 0.471731 +vt 0.116663 0.449553 +vt 0.080295 0.419706 +vt 0.050447 0.383337 +vt 0.014612 0.296822 +vt 0.010000 0.250000 +vt 0.014611 0.203179 +vt 0.028269 0.158156 +vt 0.050447 0.116663 +vt 0.080294 0.080294 +vt 0.116663 0.050447 +vt 0.203178 0.014612 +vt 0.250000 0.010000 +vt 0.296822 0.014612 +vt 0.341844 0.028269 +vt 0.383337 0.050447 +vt 0.419706 0.080294 +vt 0.449553 0.116663 +vt 0.485388 0.203178 +vt 0.490000 0.250000 +vt 0.485388 0.296822 +vt 0.471731 0.341844 +vt 0.449553 0.383337 +vt 0.419706 0.419706 +vt 0.383337 0.449553 +vt 0.000000 1.000000 +vt 0.703179 0.485389 +vt 0.750000 0.490000 +vt 0.796822 0.485388 +vt 0.841844 0.471731 +vt 0.883337 0.449553 +vt 0.919706 0.419706 +vt 0.949553 0.383337 +vt 0.971731 0.341844 +vt 0.990000 0.250000 +vt 0.985388 0.203178 +vt 0.971731 0.158156 +vt 0.949553 0.116663 +vt 0.919706 0.080294 +vt 0.883337 0.050447 +vt 0.841844 0.028269 +vt 0.750000 0.010000 +vt 0.703178 0.014612 +vt 0.658156 0.028269 +vt 0.616663 0.050447 +vt 0.580294 0.080294 +vt 0.550447 0.116663 +vt 0.528269 0.158156 +vt 0.510000 0.250000 +vt 0.514612 0.296822 +vt 0.528269 0.341844 +vt 0.550447 0.383337 +vt 0.580295 0.419706 +vt 0.616663 0.449553 +vt 0.658156 0.471731 +vn 0.0980 0.0000 -0.9952 +vn 0.2903 0.0000 -0.9569 +vn 0.4714 0.0000 -0.8819 +vn 0.6344 0.0000 -0.7730 +vn 0.7730 0.0000 -0.6344 +vn 0.8819 0.0000 -0.4714 +vn 0.9569 0.0000 -0.2903 +vn 0.9952 0.0000 -0.0980 +vn 0.9952 0.0000 0.0980 +vn 0.9569 0.0000 0.2903 +vn 0.8819 0.0000 0.4714 +vn 0.7730 0.0000 0.6344 +vn 0.6344 0.0000 0.7730 +vn 0.4714 0.0000 0.8819 +vn 0.2903 0.0000 0.9569 +vn 0.0980 0.0000 0.9952 +vn -0.0980 0.0000 0.9952 +vn -0.2903 0.0000 0.9569 +vn -0.4714 0.0000 0.8819 +vn -0.6344 0.0000 0.7730 +vn -0.7730 0.0000 0.6344 +vn -0.8819 0.0000 0.4714 +vn -0.9569 0.0000 0.2903 +vn -0.9952 0.0000 0.0980 +vn -0.9952 0.0000 -0.0980 +vn -0.9569 0.0000 -0.2903 +vn -0.8819 0.0000 -0.4714 +vn -0.7730 0.0000 -0.6344 +vn -0.6344 0.0000 -0.7730 +vn -0.4714 0.0000 -0.8819 +vn 0.0000 1.0000 0.0000 +vn -0.2903 0.0000 -0.9569 +vn -0.0980 0.0000 -0.9952 +vn 0.0000 -1.0000 0.0000 +usemtl None +s off +f 2/1/1 3/2/1 1/3/1 +f 4/4/2 5/5/2 3/2/2 +f 6/6/3 7/7/3 5/5/3 +f 8/8/4 9/9/4 7/7/4 +f 10/10/5 11/11/5 9/9/5 +f 12/12/6 13/13/6 11/11/6 +f 14/14/7 15/15/7 13/13/7 +f 16/16/8 17/17/8 15/15/8 +f 18/18/9 19/19/9 17/17/9 +f 20/20/10 21/21/10 19/19/10 +f 22/22/11 23/23/11 21/21/11 +f 24/24/12 25/25/12 23/23/12 +f 26/26/13 27/27/13 25/25/13 +f 28/28/14 29/29/14 27/27/14 +f 30/30/15 31/31/15 29/29/15 +f 32/32/16 33/33/16 31/31/16 +f 34/34/17 35/35/17 33/33/17 +f 36/36/18 37/37/18 35/35/18 +f 38/38/19 39/39/19 37/37/19 +f 40/40/20 41/41/20 39/39/20 +f 42/42/21 43/43/21 41/41/21 +f 44/44/22 45/45/22 43/43/22 +f 46/46/23 47/47/23 45/45/23 +f 48/48/24 49/49/24 47/47/24 +f 50/50/25 51/51/25 49/49/25 +f 52/52/26 53/53/26 51/51/26 +f 54/54/27 55/55/27 53/53/27 +f 56/56/28 57/57/28 55/55/28 +f 58/58/29 59/59/29 57/57/29 +f 60/60/30 61/61/30 59/59/30 +f 54/62/31 38/63/31 22/64/31 +f 62/65/32 63/66/32 61/61/32 +f 64/67/33 1/68/33 63/66/33 +f 15/69/34 31/70/34 47/71/34 +f 2/1/1 4/4/1 3/2/1 +f 4/4/2 6/6/2 5/5/2 +f 6/6/3 8/8/3 7/7/3 +f 8/8/4 10/10/4 9/9/4 +f 10/10/5 12/12/5 11/11/5 +f 12/12/6 14/14/6 13/13/6 +f 14/14/7 16/16/7 15/15/7 +f 16/16/8 18/18/8 17/17/8 +f 18/18/9 20/20/9 19/19/9 +f 20/20/10 22/22/10 21/21/10 +f 22/22/11 24/24/11 23/23/11 +f 24/24/12 26/26/12 25/25/12 +f 26/26/13 28/28/13 27/27/13 +f 28/28/14 30/30/14 29/29/14 +f 30/30/15 32/32/15 31/31/15 +f 32/32/16 34/34/16 33/33/16 +f 34/34/17 36/36/17 35/35/17 +f 36/36/18 38/38/18 37/37/18 +f 38/38/19 40/40/19 39/39/19 +f 40/40/20 42/42/20 41/41/20 +f 42/42/21 44/44/21 43/43/21 +f 44/44/22 46/46/22 45/45/22 +f 46/46/23 48/48/23 47/47/23 +f 48/48/24 50/50/24 49/49/24 +f 50/50/25 52/52/25 51/51/25 +f 52/52/26 54/54/26 53/53/26 +f 54/54/27 56/56/27 55/55/27 +f 56/56/28 58/58/28 57/57/28 +f 58/58/29 60/60/29 59/59/29 +f 60/60/30 62/65/30 61/61/30 +f 6/72/31 4/73/31 2/74/31 +f 2/74/31 64/75/31 6/72/31 +f 64/75/31 62/76/31 6/72/31 +f 62/76/31 60/77/31 58/78/31 +f 58/78/31 56/79/31 54/62/31 +f 54/62/31 52/80/31 50/81/31 +f 50/81/31 48/82/31 54/62/31 +f 48/82/31 46/83/31 54/62/31 +f 46/83/31 44/84/31 42/85/31 +f 42/85/31 40/86/31 38/63/31 +f 38/63/31 36/87/31 34/88/31 +f 34/88/31 32/89/31 30/90/31 +f 30/90/31 28/91/31 26/92/31 +f 26/92/31 24/93/31 22/64/31 +f 22/64/31 20/94/31 18/95/31 +f 18/95/31 16/96/31 22/64/31 +f 16/96/31 14/97/31 22/64/31 +f 14/97/31 12/98/31 10/99/31 +f 10/99/31 8/100/31 6/72/31 +f 62/76/31 58/78/31 6/72/31 +f 58/78/31 54/62/31 6/72/31 +f 46/83/31 42/85/31 38/63/31 +f 38/63/31 34/88/31 22/64/31 +f 34/88/31 30/90/31 22/64/31 +f 30/90/31 26/92/31 22/64/31 +f 14/97/31 10/99/31 22/64/31 +f 10/99/31 6/72/31 22/64/31 +f 54/62/31 46/83/31 38/63/31 +f 6/72/31 54/62/31 22/64/31 +f 62/65/32 64/67/32 63/66/32 +f 64/67/33 2/101/33 1/68/33 +f 63/102/34 1/103/34 3/104/34 +f 3/104/34 5/105/34 7/106/34 +f 7/106/34 9/107/34 11/108/34 +f 11/108/34 13/109/34 7/106/34 +f 13/109/34 15/69/34 7/106/34 +f 15/69/34 17/110/34 19/111/34 +f 19/111/34 21/112/34 15/69/34 +f 21/112/34 23/113/34 15/69/34 +f 23/113/34 25/114/34 31/70/34 +f 25/114/34 27/115/34 31/70/34 +f 27/115/34 29/116/34 31/70/34 +f 31/70/34 33/117/34 35/118/34 +f 35/118/34 37/119/34 39/120/34 +f 39/120/34 41/121/34 47/71/34 +f 41/121/34 43/122/34 47/71/34 +f 43/122/34 45/123/34 47/71/34 +f 47/71/34 49/124/34 51/125/34 +f 51/125/34 53/126/34 55/127/34 +f 55/127/34 57/128/34 59/129/34 +f 59/129/34 61/130/34 63/102/34 +f 63/102/34 3/104/34 7/106/34 +f 31/70/34 35/118/34 47/71/34 +f 35/118/34 39/120/34 47/71/34 +f 47/71/34 51/125/34 63/102/34 +f 51/125/34 55/127/34 63/102/34 +f 55/127/34 59/129/34 63/102/34 +f 63/102/34 7/106/34 15/69/34 +f 15/69/34 23/113/34 31/70/34 +f 63/102/34 15/69/34 47/71/34 diff --git a/src/main/resources/shaders/common/bgfx_shader.sh b/src/main/resources/shaders/common/bgfx_shader.sh new file mode 100644 index 0000000..5002c07 --- /dev/null +++ b/src/main/resources/shaders/common/bgfx_shader.sh @@ -0,0 +1,529 @@ +/* + * Copyright 2011-2018 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#ifndef BGFX_SHADER_H_HEADER_GUARD +#define BGFX_SHADER_H_HEADER_GUARD + +#if !defined(BGFX_CONFIG_MAX_BONES) +# define BGFX_CONFIG_MAX_BONES 32 +#endif // !defined(BGFX_CONFIG_MAX_BONES) + +#ifndef __cplusplus + +#if BGFX_SHADER_LANGUAGE_HLSL > 3 +# define BRANCH [branch] +# define LOOP [loop] +# define UNROLL [unroll] +#else +# define BRANCH +# define LOOP +# define UNROLL +#endif // BGFX_SHADER_LANGUAGE_HLSL > 3 + +#if BGFX_SHADER_LANGUAGE_HLSL > 3 && BGFX_SHADER_TYPE_FRAGMENT +# define EARLY_DEPTH_STENCIL [earlydepthstencil] +#else +# define EARLY_DEPTH_STENCIL +#endif // BGFX_SHADER_LANGUAGE_HLSL > 3 && BGFX_SHADER_TYPE_FRAGMENT + +#if BGFX_SHADER_LANGUAGE_GLSL +# define ARRAY_BEGIN(_type, _name, _count) _type _name[_count] = _type[]( +# define ARRAY_END() ) +#else +# define ARRAY_BEGIN(_type, _name, _count) _type _name[_count] = { +# define ARRAY_END() } +#endif // BGFX_SHADER_LANGUAGE_GLSL + +#if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_SPIRV +# define CONST(_x) static const _x +# define dFdx(_x) ddx(_x) +# define dFdy(_y) ddy(-_y) +# define inversesqrt(_x) rsqrt(_x) +# define fract(_x) frac(_x) + +# define bvec2 bool2 +# define bvec3 bool3 +# define bvec4 bool4 + +# if BGFX_SHADER_LANGUAGE_HLSL > 4 +# define REGISTER(_type, _reg) register(_type[_reg]) +# else +# define REGISTER(_type, _reg) register(_type ## _reg) +# endif // BGFX_SHADER_LANGUAGE_HLSL + +# if BGFX_SHADER_LANGUAGE_HLSL > 3 || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_SPIRV +# if BGFX_SHADER_LANGUAGE_HLSL > 4 || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_SPIRV +# define dFdxCoarse(_x) ddx_coarse(_x) +# define dFdxFine(_x) ddx_fine(_x) +# define dFdyCoarse(_y) ddy_coarse(-_y) +# define dFdyFine(_y) ddy_fine(-_y) +# endif // BGFX_SHADER_LANGUAGE_HLSL > 4 + +# if BGFX_SHADER_LANGUAGE_HLSL +float intBitsToFloat(int _x) { return asfloat(_x); } +vec2 intBitsToFloat(uint2 _x) { return asfloat(_x); } +vec3 intBitsToFloat(uint3 _x) { return asfloat(_x); } +vec4 intBitsToFloat(uint4 _x) { return asfloat(_x); } +# endif // BGFX_SHADER_LANGUAGE_HLSL + +float uintBitsToFloat(uint _x) { return asfloat(_x); } +vec2 uintBitsToFloat(uint2 _x) { return asfloat(_x); } +vec3 uintBitsToFloat(uint3 _x) { return asfloat(_x); } +vec4 uintBitsToFloat(uint4 _x) { return asfloat(_x); } + +uint floatBitsToUint(float _x) { return asuint(_x); } +uvec2 floatBitsToUint(vec2 _x) { return asuint(_x); } +uvec3 floatBitsToUint(vec3 _x) { return asuint(_x); } +uvec4 floatBitsToUint(vec4 _x) { return asuint(_x); } + +int floatBitsToInt(float _x) { return asint(_x); } +ivec2 floatBitsToInt(vec2 _x) { return asint(_x); } +ivec3 floatBitsToInt(vec3 _x) { return asint(_x); } +ivec4 floatBitsToInt(vec4 _x) { return asint(_x); } + +uint bitfieldReverse(uint _x) { return reversebits(_x); } +uint2 bitfieldReverse(uint2 _x) { return reversebits(_x); } +uint3 bitfieldReverse(uint3 _x) { return reversebits(_x); } +uint4 bitfieldReverse(uint4 _x) { return reversebits(_x); } + +# if !BGFX_SHADER_LANGUAGE_SPIRV +uint packHalf2x16(vec2 _x) +{ + return (f32tof16(_x.y)<<16) | f32tof16(_x.x); +} + +vec2 unpackHalf2x16(uint _x) +{ + return vec2(f16tof32(_x & 0xffff), f16tof32(_x >> 16) ); +} +# endif // !BGFX_SHADER_LANGUAGE_SPIRV + +struct BgfxSampler2D +{ + SamplerState m_sampler; + Texture2D m_texture; +}; + +struct BgfxISampler2D +{ + Texture2D m_texture; +}; + +struct BgfxUSampler2D +{ + Texture2D m_texture; +}; + +struct BgfxSampler2DArray +{ + SamplerState m_sampler; + Texture2DArray m_texture; +}; + +struct BgfxSampler2DShadow +{ + SamplerComparisonState m_sampler; + Texture2D m_texture; +}; + +struct BgfxSampler3D +{ + SamplerState m_sampler; + Texture3D m_texture; +}; + +struct BgfxISampler3D +{ + Texture3D m_texture; +}; + +struct BgfxUSampler3D +{ + Texture3D m_texture; +}; + +struct BgfxSamplerCube +{ + SamplerState m_sampler; + TextureCube m_texture; +}; + +struct BgfxSampler2DMS +{ + Texture2DMS m_texture; +}; + +vec4 bgfxTexture2D(BgfxSampler2D _sampler, vec2 _coord) +{ + return _sampler.m_texture.Sample(_sampler.m_sampler, _coord); +} + +vec4 bgfxTexture2DLod(BgfxSampler2D _sampler, vec2 _coord, float _level) +{ + return _sampler.m_texture.SampleLevel(_sampler.m_sampler, _coord, _level); +} + +vec4 bgfxTexture2DProj(BgfxSampler2D _sampler, vec3 _coord) +{ + vec2 coord = _coord.xy * rcp(_coord.z); + return _sampler.m_texture.Sample(_sampler.m_sampler, coord); +} + +vec4 bgfxTexture2DProj(BgfxSampler2D _sampler, vec4 _coord) +{ + vec2 coord = _coord.xy * rcp(_coord.w); + return _sampler.m_texture.Sample(_sampler.m_sampler, coord); +} + +vec4 bgfxTexture2DGrad(BgfxSampler2D _sampler, vec2 _coord, vec2 _dPdx, vec2 _dPdy) +{ + return _sampler.m_texture.SampleGrad(_sampler.m_sampler, _coord, _dPdx, _dPdy); +} + +vec4 bgfxTexture2DArray(BgfxSampler2DArray _sampler, vec3 _coord) +{ + return _sampler.m_texture.Sample(_sampler.m_sampler, _coord); +} + +vec4 bgfxTexture2DArrayLod(BgfxSampler2DArray _sampler, vec3 _coord, float _lod) +{ + return _sampler.m_texture.SampleLevel(_sampler.m_sampler, _coord, _lod); +} + +float bgfxShadow2D(BgfxSampler2DShadow _sampler, vec3 _coord) +{ + return _sampler.m_texture.SampleCmpLevelZero(_sampler.m_sampler, _coord.xy, _coord.z); +} + +float bgfxShadow2DProj(BgfxSampler2DShadow _sampler, vec4 _coord) +{ + vec3 coord = _coord.xyz * rcp(_coord.w); + return _sampler.m_texture.SampleCmpLevelZero(_sampler.m_sampler, coord.xy, coord.z); +} + +vec4 bgfxTexture3D(BgfxSampler3D _sampler, vec3 _coord) +{ + return _sampler.m_texture.Sample(_sampler.m_sampler, _coord); +} + +vec4 bgfxTexture3DLod(BgfxSampler3D _sampler, vec3 _coord, float _level) +{ + return _sampler.m_texture.SampleLevel(_sampler.m_sampler, _coord, _level); +} + +ivec4 bgfxTexture3D(BgfxISampler3D _sampler, vec3 _coord) +{ + uvec3 size; + _sampler.m_texture.GetDimensions(size.x, size.y, size.z); + return _sampler.m_texture.Load(ivec4(_coord * size, 0) ); +} + +uvec4 bgfxTexture3D(BgfxUSampler3D _sampler, vec3 _coord) +{ + uvec3 size; + _sampler.m_texture.GetDimensions(size.x, size.y, size.z); + return _sampler.m_texture.Load(ivec4(_coord * size, 0) ); +} + +vec4 bgfxTextureCube(BgfxSamplerCube _sampler, vec3 _coord) +{ + return _sampler.m_texture.Sample(_sampler.m_sampler, _coord); +} + +vec4 bgfxTextureCubeLod(BgfxSamplerCube _sampler, vec3 _coord, float _level) +{ + return _sampler.m_texture.SampleLevel(_sampler.m_sampler, _coord, _level); +} + +vec4 bgfxTexelFetch(BgfxSampler2D _sampler, ivec2 _coord, int _lod) +{ + return _sampler.m_texture.Load(ivec3(_coord, _lod) ); +} + +vec2 bgfxTextureSize(BgfxSampler2D _sampler, int _lod) +{ + vec2 result; + _sampler.m_texture.GetDimensions(result.x, result.y); + return result; +} + +ivec4 bgfxTexelFetch(BgfxISampler2D _sampler, ivec2 _coord, int _lod) +{ + return _sampler.m_texture.Load(ivec3(_coord, _lod) ); +} + +uvec4 bgfxTexelFetch(BgfxUSampler2D _sampler, ivec2 _coord, int _lod) +{ + return _sampler.m_texture.Load(ivec3(_coord, _lod) ); +} + +vec4 bgfxTexelFetch(BgfxSampler2DMS _sampler, ivec2 _coord, int _sampleIdx) +{ + return _sampler.m_texture.Load(_coord, _sampleIdx); +} + +vec4 bgfxTexelFetch(BgfxSampler3D _sampler, ivec3 _coord, int _lod) +{ + return _sampler.m_texture.Load(ivec4(_coord, _lod) ); +} + +vec3 bgfxTextureSize(BgfxSampler3D _sampler, int _lod) +{ + vec3 result; + _sampler.m_texture.GetDimensions(result.x, result.y, result.z); + return result; +} + +# define SAMPLER2D(_name, _reg) \ + uniform SamplerState _name ## Sampler : REGISTER(s, _reg); \ + uniform Texture2D _name ## Texture : REGISTER(t, _reg); \ + static BgfxSampler2D _name = { _name ## Sampler, _name ## Texture } +# define ISAMPLER2D(_name, _reg) \ + uniform Texture2D _name ## Texture : REGISTER(t, _reg); \ + static BgfxISampler2D _name = { _name ## Texture } +# define USAMPLER2D(_name, _reg) \ + uniform Texture2D _name ## Texture : REGISTER(t, _reg); \ + static BgfxUSampler2D _name = { _name ## Texture } +# define sampler2D BgfxSampler2D +# define texture2D(_sampler, _coord) bgfxTexture2D(_sampler, _coord) +# define texture2DLod(_sampler, _coord, _level) bgfxTexture2DLod(_sampler, _coord, _level) +# define texture2DProj(_sampler, _coord) bgfxTexture2DProj(_sampler, _coord) +# define texture2DGrad(_sampler, _coord, _dPdx, _dPdy) bgfxTexture2DGrad(_sampler, _coord, _dPdx, _dPdy) + +# define SAMPLER2DARRAY(_name, _reg) \ + uniform SamplerState _name ## Sampler : REGISTER(s, _reg); \ + uniform Texture2DArray _name ## Texture : REGISTER(t, _reg); \ + static BgfxSampler2DArray _name = { _name ## Sampler, _name ## Texture } +# define sampler2DArray BgfxSampler2DArray +# define texture2DArray(_sampler, _coord) bgfxTexture2DArray(_sampler, _coord) +# define texture2DArrayLod(_sampler, _coord, _lod) bgfxTexture2DArrayLod(_sampler, _coord, _lod) + +# define SAMPLER2DMS(_name, _reg) \ + uniform Texture2DMS _name ## Texture : REGISTER(t, _reg); \ + static BgfxSampler2DMS _name = { _name ## Texture } +# define sampler2DMS BgfxSampler2DMS + +# define SAMPLER2DSHADOW(_name, _reg) \ + uniform SamplerComparisonState _name ## SamplerComparison : REGISTER(s, _reg); \ + uniform Texture2D _name ## Texture : REGISTER(t, _reg); \ + static BgfxSampler2DShadow _name = { _name ## SamplerComparison, _name ## Texture } +# define sampler2DShadow BgfxSampler2DShadow +# define shadow2D(_sampler, _coord) bgfxShadow2D(_sampler, _coord) +# define shadow2DProj(_sampler, _coord) bgfxShadow2DProj(_sampler, _coord) + +# define SAMPLER3D(_name, _reg) \ + uniform SamplerState _name ## Sampler : REGISTER(s, _reg); \ + uniform Texture3D _name ## Texture : REGISTER(t, _reg); \ + static BgfxSampler3D _name = { _name ## Sampler, _name ## Texture } +# define ISAMPLER3D(_name, _reg) \ + uniform Texture3D _name ## Texture : REGISTER(t, _reg); \ + static BgfxISampler3D _name = { _name ## Texture } +# define USAMPLER3D(_name, _reg) \ + uniform Texture3D _name ## Texture : REGISTER(t, _reg); \ + static BgfxUSampler3D _name = { _name ## Texture } +# define sampler3D BgfxSampler3D +# define texture3D(_sampler, _coord) bgfxTexture3D(_sampler, _coord) +# define texture3DLod(_sampler, _coord, _level) bgfxTexture3DLod(_sampler, _coord, _level) + +# define SAMPLERCUBE(_name, _reg) \ + uniform SamplerState _name ## Sampler : REGISTER(s, _reg); \ + uniform TextureCube _name ## Texture : REGISTER(t, _reg); \ + static BgfxSamplerCube _name = { _name ## Sampler, _name ## Texture } +# define samplerCube BgfxSamplerCube +# define textureCube(_sampler, _coord) bgfxTextureCube(_sampler, _coord) +# define textureCubeLod(_sampler, _coord, _level) bgfxTextureCubeLod(_sampler, _coord, _level) + +# define texelFetch(_sampler, _coord, _lod) bgfxTexelFetch(_sampler, _coord, _lod) +# define textureSize(_sampler, _lod) bgfxTextureSize(_sampler, _lod) +# else + +# define sampler2DShadow sampler2D + +vec4 bgfxTexture2DProj(sampler2D _sampler, vec3 _coord) +{ + return tex2Dproj(_sampler, vec4(_coord.xy, 0.0, _coord.z) ); +} + +vec4 bgfxTexture2DProj(sampler2D _sampler, vec4 _coord) +{ + return tex2Dproj(_sampler, _coord); +} + +float bgfxShadow2D(sampler2DShadow _sampler, vec3 _coord) +{ +#if 0 + float occluder = tex2D(_sampler, _coord.xy).x; + return step(_coord.z, occluder); +#else + return tex2Dproj(_sampler, vec4(_coord.xy, _coord.z, 1.0) ).x; +#endif // 0 +} + +float bgfxShadow2DProj(sampler2DShadow _sampler, vec4 _coord) +{ +#if 0 + vec3 coord = _coord.xyz * rcp(_coord.w); + float occluder = tex2D(_sampler, coord.xy).x; + return step(coord.z, occluder); +#else + return tex2Dproj(_sampler, _coord).x; +#endif // 0 +} + +# define SAMPLER2D(_name, _reg) uniform sampler2D _name : REGISTER(s, _reg) +# define SAMPLER2DMS(_name, _reg) uniform sampler2DMS _name : REGISTER(s, _reg) +# define texture2D(_sampler, _coord) tex2D(_sampler, _coord) +# define texture2DProj(_sampler, _coord) bgfxTexture2DProj(_sampler, _coord) + +# define SAMPLER2DARRAY(_name, _reg) SAMPLER2D(_name, _reg) +# define texture2DArray(_sampler, _coord) texture2D(_sampler, (_coord).xy) +# define texture2DArrayLod(_sampler, _coord, _lod) texture2DLod(_sampler, _coord, _lod) + +# define SAMPLER2DSHADOW(_name, _reg) uniform sampler2DShadow _name : REGISTER(s, _reg) +# define shadow2D(_sampler, _coord) bgfxShadow2D(_sampler, _coord) +# define shadow2DProj(_sampler, _coord) bgfxShadow2DProj(_sampler, _coord) + +# define SAMPLER3D(_name, _reg) uniform sampler3D _name : REGISTER(s, _reg) +# define texture3D(_sampler, _coord) tex3D(_sampler, _coord) + +# define SAMPLERCUBE(_name, _reg) uniform samplerCUBE _name : REGISTER(s, _reg) +# define textureCube(_sampler, _coord) texCUBE(_sampler, _coord) + +# if BGFX_SHADER_LANGUAGE_HLSL == 2 +# define texture2DLod(_sampler, _coord, _level) tex2D(_sampler, (_coord).xy) +# define texture2DGrad(_sampler, _coord, _dPdx, _dPdy) tex2D(_sampler, _coord) +# define texture3DLod(_sampler, _coord, _level) tex3D(_sampler, (_coord).xyz) +# define textureCubeLod(_sampler, _coord, _level) texCUBE(_sampler, (_coord).xyz) +# else +# define texture2DLod(_sampler, _coord, _level) tex2Dlod(_sampler, vec4( (_coord).xy, 0.0, _level) ) +# define texture2DGrad(_sampler, _coord, _dPdx, _dPdy) tex2Dgrad(_sampler, _coord, _dPdx, _dPdy) +# define texture3DLod(_sampler, _coord, _level) tex3Dlod(_sampler, vec4( (_coord).xyz, _level) ) +# define textureCubeLod(_sampler, _coord, _level) texCUBElod(_sampler, vec4( (_coord).xyz, _level) ) +# endif // BGFX_SHADER_LANGUAGE_HLSL == 2 + +# endif // BGFX_SHADER_LANGUAGE_HLSL > 3 + +vec3 instMul(vec3 _vec, mat3 _mtx) { return mul(_mtx, _vec); } +vec3 instMul(mat3 _mtx, vec3 _vec) { return mul(_vec, _mtx); } +vec4 instMul(vec4 _vec, mat4 _mtx) { return mul(_mtx, _vec); } +vec4 instMul(mat4 _mtx, vec4 _vec) { return mul(_vec, _mtx); } + +bvec2 lessThan(vec2 _a, vec2 _b) { return _a < _b; } +bvec3 lessThan(vec3 _a, vec3 _b) { return _a < _b; } +bvec4 lessThan(vec4 _a, vec4 _b) { return _a < _b; } + +bvec2 lessThanEqual(vec2 _a, vec2 _b) { return _a <= _b; } +bvec3 lessThanEqual(vec3 _a, vec3 _b) { return _a <= _b; } +bvec4 lessThanEqual(vec4 _a, vec4 _b) { return _a <= _b; } + +bvec2 greaterThan(vec2 _a, vec2 _b) { return _a > _b; } +bvec3 greaterThan(vec3 _a, vec3 _b) { return _a > _b; } +bvec4 greaterThan(vec4 _a, vec4 _b) { return _a > _b; } + +bvec2 greaterThanEqual(vec2 _a, vec2 _b) { return _a >= _b; } +bvec3 greaterThanEqual(vec3 _a, vec3 _b) { return _a >= _b; } +bvec4 greaterThanEqual(vec4 _a, vec4 _b) { return _a >= _b; } + +bvec2 notEqual(vec2 _a, vec2 _b) { return _a != _b; } +bvec3 notEqual(vec3 _a, vec3 _b) { return _a != _b; } +bvec4 notEqual(vec4 _a, vec4 _b) { return _a != _b; } + +bvec2 equal(vec2 _a, vec2 _b) { return _a == _b; } +bvec3 equal(vec3 _a, vec3 _b) { return _a == _b; } +bvec4 equal(vec4 _a, vec4 _b) { return _a == _b; } + +float mix(float _a, float _b, float _t) { return lerp(_a, _b, _t); } +vec2 mix(vec2 _a, vec2 _b, vec2 _t) { return lerp(_a, _b, _t); } +vec3 mix(vec3 _a, vec3 _b, vec3 _t) { return lerp(_a, _b, _t); } +vec4 mix(vec4 _a, vec4 _b, vec4 _t) { return lerp(_a, _b, _t); } + +float mod(float _a, float _b) { return _a - _b * floor(_a / _b); } +vec2 mod(vec2 _a, vec2 _b) { return _a - _b * floor(_a / _b); } +vec3 mod(vec3 _a, vec3 _b) { return _a - _b * floor(_a / _b); } +vec4 mod(vec4 _a, vec4 _b) { return _a - _b * floor(_a / _b); } + +#else +# define CONST(_x) const _x +# define atan2(_x, _y) atan(_x, _y) +# define mul(_a, _b) ( (_a) * (_b) ) +# define saturate(_x) clamp(_x, 0.0, 1.0) +# define SAMPLER2D(_name, _reg) uniform sampler2D _name +# define SAMPLER2DMS(_name, _reg) uniform sampler2DMS _name +# define SAMPLER3D(_name, _reg) uniform sampler3D _name +# define SAMPLERCUBE(_name, _reg) uniform samplerCube _name +# define SAMPLER2DSHADOW(_name, _reg) uniform sampler2DShadow _name + +# define SAMPLER2DARRAY(_name, _reg) uniform sampler2DArray _name +# define SAMPLER2DMSARRAY(_name, _reg) uniform sampler2DMSArray _name +# define SAMPLERCUBEARRAY(_name, _reg) uniform samplerCubeArray _name +# define SAMPLER2DARRAYSHADOW(_name, _reg) uniform sampler2DArrayShadow _name + +# if BGFX_SHADER_LANGUAGE_GLSL >= 130 +# define ISAMPLER2D(_name, _reg) uniform isampler2D _name +# define USAMPLER2D(_name, _reg) uniform usampler2D _name +# define ISAMPLER3D(_name, _reg) uniform isampler3D _name +# define USAMPLER3D(_name, _reg) uniform usampler3D _name + +# define texture2D(_sampler, _coord) texture(_sampler, _coord) +# define texture2DArray(_sampler, _coord) texture(_sampler, _coord) +# define texture3D(_sampler, _coord) texture(_sampler, _coord) +# endif // BGFX_SHADER_LANGUAGE_GLSL >= 130 + +vec3 instMul(vec3 _vec, mat3 _mtx) { return mul(_vec, _mtx); } +vec3 instMul(mat3 _mtx, vec3 _vec) { return mul(_mtx, _vec); } +vec4 instMul(vec4 _vec, mat4 _mtx) { return mul(_vec, _mtx); } +vec4 instMul(mat4 _mtx, vec4 _vec) { return mul(_mtx, _vec); } + +float rcp(float _a) { return 1.0/_a; } +vec2 rcp(vec2 _a) { return vec2(1.0)/_a; } +vec3 rcp(vec3 _a) { return vec3(1.0)/_a; } +vec4 rcp(vec4 _a) { return vec4(1.0)/_a; } +#endif // BGFX_SHADER_LANGUAGE_* + +vec2 vec2_splat(float _x) { return vec2(_x, _x); } +vec3 vec3_splat(float _x) { return vec3(_x, _x, _x); } +vec4 vec4_splat(float _x) { return vec4(_x, _x, _x, _x); } + +#if BGFX_SHADER_LANGUAGE_GLSL >= 130 || BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_SPIRV +uvec2 uvec2_splat(uint _x) { return uvec2(_x, _x); } +uvec3 uvec3_splat(uint _x) { return uvec3(_x, _x, _x); } +uvec4 uvec4_splat(uint _x) { return uvec4(_x, _x, _x, _x); } +#endif // BGFX_SHADER_LANGUAGE_GLSL >= 130 || BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_SPIRV + +mat4 mtxFromRows(vec4 _0, vec4 _1, vec4 _2, vec4 _3) +{ +#if BGFX_SHADER_LANGUAGE_GLSL + return transpose(mat4(_0, _1, _2, _3) ); +#else + return mat4(_0, _1, _2, _3); +#endif // BGFX_SHADER_LANGUAGE_GLSL +} + +mat4 mtxFromCols(vec4 _0, vec4 _1, vec4 _2, vec4 _3) +{ +#if BGFX_SHADER_LANGUAGE_GLSL + return mat4(_0, _1, _2, _3); +#else + return transpose(mat4(_0, _1, _2, _3) ); +#endif // BGFX_SHADER_LANGUAGE_GLSL +} + +uniform vec4 u_viewRect; +uniform vec4 u_viewTexel; +uniform mat4 u_view; +uniform mat4 u_invView; +uniform mat4 u_proj; +uniform mat4 u_invProj; +uniform mat4 u_viewProj; +uniform mat4 u_invViewProj; +uniform mat4 u_model[BGFX_CONFIG_MAX_BONES]; +uniform mat4 u_modelView; +uniform mat4 u_modelViewProj; +uniform vec4 u_alphaRef4; +#define u_alphaRef u_alphaRef4.x + +#endif // __cplusplus + +#endif // BGFX_SHADER_H_HEADER_GUARD diff --git a/src/main/resources/shaders/common/common.sh b/src/main/resources/shaders/common/common.sh new file mode 100644 index 0000000..238ee49 --- /dev/null +++ b/src/main/resources/shaders/common/common.sh @@ -0,0 +1,7 @@ +/* + * Copyright 2011-2018 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "bgfx_shader.sh" +#include "shaderlib.sh" diff --git a/src/main/resources/shaders/common/shaderlib.sh b/src/main/resources/shaders/common/shaderlib.sh new file mode 100644 index 0000000..2bcd43d --- /dev/null +++ b/src/main/resources/shaders/common/shaderlib.sh @@ -0,0 +1,395 @@ +/* + * Copyright 2011-2018 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#ifndef __SHADERLIB_SH__ +#define __SHADERLIB_SH__ + +vec4 encodeRE8(float _r) +{ + float exponent = ceil(log2(_r) ); + return vec4(_r / exp2(exponent) + , 0.0 + , 0.0 + , (exponent + 128.0) / 255.0 + ); +} + +float decodeRE8(vec4 _re8) +{ + float exponent = _re8.w * 255.0 - 128.0; + return _re8.x * exp2(exponent); +} + +vec4 encodeRGBE8(vec3 _rgb) +{ + vec4 rgbe8; + float maxComponent = max(max(_rgb.x, _rgb.y), _rgb.z); + float exponent = ceil(log2(maxComponent) ); + rgbe8.xyz = _rgb / exp2(exponent); + rgbe8.w = (exponent + 128.0) / 255.0; + return rgbe8; +} + +vec3 decodeRGBE8(vec4 _rgbe8) +{ + float exponent = _rgbe8.w * 255.0 - 128.0; + vec3 rgb = _rgbe8.xyz * exp2(exponent); + return rgb; +} + +vec3 encodeNormalUint(vec3 _normal) +{ + return _normal * 0.5 + 0.5; +} + +vec3 decodeNormalUint(vec3 _encodedNormal) +{ + return _encodedNormal * 2.0 - 1.0; +} + +vec2 encodeNormalSphereMap(vec3 _normal) +{ + return normalize(_normal.xy) * sqrt(_normal.z * 0.5 + 0.5); +} + +vec3 decodeNormalSphereMap(vec2 _encodedNormal) +{ + float zz = dot(_encodedNormal, _encodedNormal) * 2.0 - 1.0; + return vec3(normalize(_encodedNormal.xy) * sqrt(1.0 - zz*zz), zz); +} + +vec2 octahedronWrap(vec2 _val) +{ + // Reference: + // Octahedron normal vector encoding + // http://kriscg.blogspot.com/2014/04/octahedron-normal-vector-encoding.html + return (1.0 - abs(_val.yx) ) + * mix(vec2_splat(-1.0), vec2_splat(1.0), vec2(greaterThanEqual(_val.xy, vec2_splat(0.0) ) ) ); +} + +vec2 encodeNormalOctahedron(vec3 _normal) +{ + _normal /= abs(_normal.x) + abs(_normal.y) + abs(_normal.z); + _normal.xy = _normal.z >= 0.0 ? _normal.xy : octahedronWrap(_normal.xy); + _normal.xy = _normal.xy * 0.5 + 0.5; + return _normal.xy; +} + +vec3 decodeNormalOctahedron(vec2 _encodedNormal) +{ + _encodedNormal = _encodedNormal * 2.0 - 1.0; + + vec3 normal; + normal.z = 1.0 - abs(_encodedNormal.x) - abs(_encodedNormal.y); + normal.xy = normal.z >= 0.0 ? _encodedNormal.xy : octahedronWrap(_encodedNormal.xy); + return normalize(normal); +} + +vec3 convertRGB2XYZ(vec3 _rgb) +{ + // Reference: + // RGB/XYZ Matrices + // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html + vec3 xyz; + xyz.x = dot(vec3(0.4124564, 0.3575761, 0.1804375), _rgb); + xyz.y = dot(vec3(0.2126729, 0.7151522, 0.0721750), _rgb); + xyz.z = dot(vec3(0.0193339, 0.1191920, 0.9503041), _rgb); + return xyz; +} + +vec3 convertXYZ2RGB(vec3 _xyz) +{ + vec3 rgb; + rgb.x = dot(vec3( 3.2404542, -1.5371385, -0.4985314), _xyz); + rgb.y = dot(vec3(-0.9692660, 1.8760108, 0.0415560), _xyz); + rgb.z = dot(vec3( 0.0556434, -0.2040259, 1.0572252), _xyz); + return rgb; +} + +vec3 convertXYZ2Yxy(vec3 _xyz) +{ + // Reference: + // http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_xyY.html + float inv = 1.0/dot(_xyz, vec3(1.0, 1.0, 1.0) ); + return vec3(_xyz.y, _xyz.x*inv, _xyz.y*inv); +} + +vec3 convertYxy2XYZ(vec3 _Yxy) +{ + // Reference: + // http://www.brucelindbloom.com/index.html?Eqn_xyY_to_XYZ.html + vec3 xyz; + xyz.x = _Yxy.x*_Yxy.y/_Yxy.z; + xyz.y = _Yxy.x; + xyz.z = _Yxy.x*(1.0 - _Yxy.y - _Yxy.z)/_Yxy.z; + return xyz; +} + +vec3 convertRGB2Yxy(vec3 _rgb) +{ + return convertXYZ2Yxy(convertRGB2XYZ(_rgb) ); +} + +vec3 convertYxy2RGB(vec3 _Yxy) +{ + return convertXYZ2RGB(convertYxy2XYZ(_Yxy) ); +} + +vec3 convertRGB2Yuv(vec3 _rgb) +{ + vec3 yuv; + yuv.x = dot(_rgb, vec3(0.299, 0.587, 0.114) ); + yuv.y = (_rgb.x - yuv.x)*0.713 + 0.5; + yuv.z = (_rgb.z - yuv.x)*0.564 + 0.5; + return yuv; +} + +vec3 convertYuv2RGB(vec3 _yuv) +{ + vec3 rgb; + rgb.x = _yuv.x + 1.403*(_yuv.y-0.5); + rgb.y = _yuv.x - 0.344*(_yuv.y-0.5) - 0.714*(_yuv.z-0.5); + rgb.z = _yuv.x + 1.773*(_yuv.z-0.5); + return rgb; +} + +vec3 convertRGB2YIQ(vec3 _rgb) +{ + vec3 yiq; + yiq.x = dot(vec3(0.299, 0.587, 0.114 ), _rgb); + yiq.y = dot(vec3(0.595716, -0.274453, -0.321263), _rgb); + yiq.z = dot(vec3(0.211456, -0.522591, 0.311135), _rgb); + return yiq; +} + +vec3 convertYIQ2RGB(vec3 _yiq) +{ + vec3 rgb; + rgb.x = dot(vec3(1.0, 0.9563, 0.6210), _yiq); + rgb.y = dot(vec3(1.0, -0.2721, -0.6474), _yiq); + rgb.z = dot(vec3(1.0, -1.1070, 1.7046), _yiq); + return rgb; +} + +vec3 toLinear(vec3 _rgb) +{ + return pow(abs(_rgb), vec3_splat(2.2) ); +} + +vec4 toLinear(vec4 _rgba) +{ + return vec4(toLinear(_rgba.xyz), _rgba.w); +} + +vec3 toLinearAccurate(vec3 _rgb) +{ + vec3 lo = _rgb / 12.92; + vec3 hi = pow( (_rgb + 0.055) / 1.055, vec3_splat(2.4) ); + vec3 rgb = mix(hi, lo, vec3(lessThanEqual(_rgb, vec3_splat(0.04045) ) ) ); + return rgb; +} + +vec4 toLinearAccurate(vec4 _rgba) +{ + return vec4(toLinearAccurate(_rgba.xyz), _rgba.w); +} + +float toGamma(float _r) +{ + return pow(abs(_r), 1.0/2.2); +} + +vec3 toGamma(vec3 _rgb) +{ + return pow(abs(_rgb), vec3_splat(1.0/2.2) ); +} + +vec4 toGamma(vec4 _rgba) +{ + return vec4(toGamma(_rgba.xyz), _rgba.w); +} + +vec3 toGammaAccurate(vec3 _rgb) +{ + vec3 lo = _rgb * 12.92; + vec3 hi = pow(abs(_rgb), vec3_splat(1.0/2.4) ) * 1.055 - 0.055; + vec3 rgb = mix(hi, lo, vec3(lessThanEqual(_rgb, vec3_splat(0.0031308) ) ) ); + return rgb; +} + +vec4 toGammaAccurate(vec4 _rgba) +{ + return vec4(toGammaAccurate(_rgba.xyz), _rgba.w); +} + +vec3 toReinhard(vec3 _rgb) +{ + return toGamma(_rgb/(_rgb+vec3_splat(1.0) ) ); +} + +vec4 toReinhard(vec4 _rgba) +{ + return vec4(toReinhard(_rgba.xyz), _rgba.w); +} + +vec3 toFilmic(vec3 _rgb) +{ + _rgb = max(vec3_splat(0.0), _rgb - 0.004); + _rgb = (_rgb*(6.2*_rgb + 0.5) ) / (_rgb*(6.2*_rgb + 1.7) + 0.06); + return _rgb; +} + +vec4 toFilmic(vec4 _rgba) +{ + return vec4(toFilmic(_rgba.xyz), _rgba.w); +} + +vec3 toAcesFilmic(vec3 _rgb) +{ + // Reference: + // ACES Filmic Tone Mapping Curve + // https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ + float aa = 2.51f; + float bb = 0.03f; + float cc = 2.43f; + float dd = 0.59f; + float ee = 0.14f; + return saturate( (_rgb*(aa*_rgb + bb) )/(_rgb*(cc*_rgb + dd) + ee) ); +} + +vec4 toAcesFilmic(vec4 _rgba) +{ + return vec4(toAcesFilmic(_rgba.xyz), _rgba.w); +} + +vec3 luma(vec3 _rgb) +{ + float yy = dot(vec3(0.2126729, 0.7151522, 0.0721750), _rgb); + return vec3_splat(yy); +} + +vec4 luma(vec4 _rgba) +{ + return vec4(luma(_rgba.xyz), _rgba.w); +} + +vec3 conSatBri(vec3 _rgb, vec3 _csb) +{ + vec3 rgb = _rgb * _csb.z; + rgb = mix(luma(rgb), rgb, _csb.y); + rgb = mix(vec3_splat(0.5), rgb, _csb.x); + return rgb; +} + +vec4 conSatBri(vec4 _rgba, vec3 _csb) +{ + return vec4(conSatBri(_rgba.xyz, _csb), _rgba.w); +} + +vec3 posterize(vec3 _rgb, float _numColors) +{ + return floor(_rgb*_numColors) / _numColors; +} + +vec4 posterize(vec4 _rgba, float _numColors) +{ + return vec4(posterize(_rgba.xyz, _numColors), _rgba.w); +} + +vec3 sepia(vec3 _rgb) +{ + vec3 color; + color.x = dot(_rgb, vec3(0.393, 0.769, 0.189) ); + color.y = dot(_rgb, vec3(0.349, 0.686, 0.168) ); + color.z = dot(_rgb, vec3(0.272, 0.534, 0.131) ); + return color; +} + +vec4 sepia(vec4 _rgba) +{ + return vec4(sepia(_rgba.xyz), _rgba.w); +} + +vec3 blendOverlay(vec3 _base, vec3 _blend) +{ + vec3 lt = 2.0 * _base * _blend; + vec3 gte = 1.0 - 2.0 * (1.0 - _base) * (1.0 - _blend); + return mix(lt, gte, step(vec3_splat(0.5), _base) ); +} + +vec4 blendOverlay(vec4 _base, vec4 _blend) +{ + return vec4(blendOverlay(_base.xyz, _blend.xyz), _base.w); +} + +vec3 adjustHue(vec3 _rgb, float _hue) +{ + vec3 yiq = convertRGB2YIQ(_rgb); + float angle = _hue + atan2(yiq.z, yiq.y); + float len = length(yiq.yz); + return convertYIQ2RGB(vec3(yiq.x, len*cos(angle), len*sin(angle) ) ); +} + +vec4 packFloatToRgba(float _value) +{ + const vec4 shift = vec4(256 * 256 * 256, 256 * 256, 256, 1.0); + const vec4 mask = vec4(0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0); + vec4 comp = fract(_value * shift); + comp -= comp.xxyz * mask; + return comp; +} + +float unpackRgbaToFloat(vec4 _rgba) +{ + const vec4 shift = vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0); + return dot(_rgba, shift); +} + +vec2 packHalfFloat(float _value) +{ + const vec2 shift = vec2(256, 1.0); + const vec2 mask = vec2(0, 1.0 / 256.0); + vec2 comp = fract(_value * shift); + comp -= comp.xx * mask; + return comp; +} + +float unpackHalfFloat(vec2 _rg) +{ + const vec2 shift = vec2(1.0 / 256.0, 1.0); + return dot(_rg, shift); +} + +float random(vec2 _uv) +{ + return fract(sin(dot(_uv.xy, vec2(12.9898, 78.233) ) ) * 43758.5453); +} + +vec3 fixCubeLookup(vec3 _v, float _lod, float _topLevelCubeSize) +{ + // Reference: + // Seamless cube-map filtering + // http://the-witness.net/news/2012/02/seamless-cube-map-filtering/ + float ax = abs(_v.x); + float ay = abs(_v.y); + float az = abs(_v.z); + float vmax = max(max(ax, ay), az); + float scale = 1.0 - exp2(_lod) / _topLevelCubeSize; + if (ax != vmax) { _v.x *= scale; } + if (ay != vmax) { _v.y *= scale; } + if (az != vmax) { _v.z *= scale; } + return _v; +} + +vec2 texture2DBc5(sampler2D _sampler, vec2 _uv) +{ +#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 3 + return texture2D(_sampler, _uv).yx; +#else + return texture2D(_sampler, _uv).xy; +#endif +} + +#endif // __SHADERLIB_SH__ diff --git a/src/main/resources/shaders/glsl/fs_coloured.sh b/src/main/resources/shaders/glsl/fs_coloured.sh new file mode 100644 index 0000000..c6b2ce4 --- /dev/null +++ b/src/main/resources/shaders/glsl/fs_coloured.sh @@ -0,0 +1,25 @@ +$input v_normal, v_position + +#include "../common/common.sh" + +uniform vec4 u_color; +uniform vec4 u_camPos; +uniform vec4 u_diffuseColor; +uniform vec4 u_specColor; +uniform vec4 u_ambienceColor; + +void main() +{ + vec3 normal = normalize(v_normal); + vec3 lightPos = vec3(1.0, 0.0, 0.0); + vec3 lightDirection = normalize(lightPos - v_position); + vec4 lightColor = vec4(1.0, 1.0, 1.0, 1.0); + + float diffuse = max(dot(normal, lightDirection), 0); + + vec3 viewDir = normalize(v_position - u_camPos.xyz); + vec3 reflectionDir = reflect(lightDirection, normal); + float specAmount = pow(max(dot(viewDir, reflectionDir), 0), 8); + + gl_FragColor = u_color * (diffuse * u_diffuseColor + specAmount * u_specColor + u_ambienceColor); +} \ No newline at end of file diff --git a/src/main/resources/shaders/glsl/fs_cube_good.bin b/src/main/resources/shaders/glsl/fs_cube_good.bin new file mode 100644 index 0000000..db3e507 Binary files /dev/null and b/src/main/resources/shaders/glsl/fs_cube_good.bin differ diff --git a/src/main/resources/shaders/glsl/fs_cubes.bin b/src/main/resources/shaders/glsl/fs_cubes.bin new file mode 100644 index 0000000..5265e3b Binary files /dev/null and b/src/main/resources/shaders/glsl/fs_cubes.bin differ diff --git a/src/main/resources/shaders/glsl/fs_simple_color.bin b/src/main/resources/shaders/glsl/fs_simple_color.bin new file mode 100644 index 0000000..c3b4dfa Binary files /dev/null and b/src/main/resources/shaders/glsl/fs_simple_color.bin differ diff --git a/src/main/resources/shaders/glsl/fs_simple_color.sh b/src/main/resources/shaders/glsl/fs_simple_color.sh new file mode 100644 index 0000000..c516116 --- /dev/null +++ b/src/main/resources/shaders/glsl/fs_simple_color.sh @@ -0,0 +1,8 @@ +#include "../common/common.sh" + +uniform vec4 s_color; + +void main() +{ + gl_FragColor = vec4(0.4, 0.4, 0.4, 0.5); +} \ No newline at end of file diff --git a/src/main/resources/shaders/glsl/fs_simple_textured.bin b/src/main/resources/shaders/glsl/fs_simple_textured.bin new file mode 100644 index 0000000..d66b26a Binary files /dev/null and b/src/main/resources/shaders/glsl/fs_simple_textured.bin differ diff --git a/src/main/resources/shaders/glsl/fs_test.bin b/src/main/resources/shaders/glsl/fs_test.bin new file mode 100644 index 0000000..f427907 Binary files /dev/null and b/src/main/resources/shaders/glsl/fs_test.bin differ diff --git a/src/main/resources/shaders/glsl/fs_textured.sh b/src/main/resources/shaders/glsl/fs_textured.sh new file mode 100644 index 0000000..e76d067 --- /dev/null +++ b/src/main/resources/shaders/glsl/fs_textured.sh @@ -0,0 +1,26 @@ +$input v_normal, v_texcoord0, v_position + +#include "../common/common.sh" + +SAMPLER2D(s_texColor, 0); +uniform vec4 u_camPos; + +void main() +{ + vec3 normal = normalize(v_normal); + vec3 lightPos = vec3(1.0, 0.0, 0.0); + vec3 lightDirection = normalize(lightPos - v_position); + vec4 lightColor = vec4(1.0, 1.0, 1.0, 1.0); + + float diffuse = max(dot(normal, lightDirection), 0); + + float specIntensity = 0.5f; + vec3 viewDir = normalize(v_position - u_camPos.xyz); + vec3 reflectionDir = reflect(lightDirection, normal); + float specAmount = pow(max(dot(viewDir, reflectionDir), 0), 8); + float specular = specAmount * specIntensity; + + vec4 color = toLinear(texture2D(s_texColor, v_texcoord0)); + + gl_FragColor = color * mul(lightColor, diffuse + 0.2 + specular); +} \ No newline at end of file diff --git a/src/main/resources/shaders/glsl/fs_textured_back.sh b/src/main/resources/shaders/glsl/fs_textured_back.sh new file mode 100644 index 0000000..a30c607 --- /dev/null +++ b/src/main/resources/shaders/glsl/fs_textured_back.sh @@ -0,0 +1,15 @@ +$input v_normal, v_texcoord0 + +#include "../common/common.sh" + +SAMPLER2D(s_texColor, 0); + +void main() +{ + vec3 lightDir = vec3(0.0, 0.0, -1.0); + float ndotl = dot(normalize(v_normal), lightDir); + float spec = pow(ndotl, 30.0); + + vec4 color = toLinear(texture2D(s_texColor, v_texcoord0) ); + gl_FragColor = vec4(pow(pow(color.xyz, vec3_splat(2.2)) * ndotl + spec, vec3_splat(1.0 / 2.2)), 1.0); +} \ No newline at end of file diff --git a/src/main/resources/shaders/glsl/varying.def.sc b/src/main/resources/shaders/glsl/varying.def.sc index 75bbd39..674b25d 100644 --- a/src/main/resources/shaders/glsl/varying.def.sc +++ b/src/main/resources/shaders/glsl/varying.def.sc @@ -1,6 +1,9 @@ vec4 v_color0 : COLOR0 = vec4(1.0, 1.0, 0.0, 1.0); vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0); +vec3 v_normal : NORMAL = vec3(0.0, 1.0, 1.0); +vec3 v_position : POSITION = vec3(0.0, 0.0, 0.0); vec3 a_position : POSITION; vec4 a_color0 : COLOR0; vec2 a_texcoord0 : TEXCOORD0; +vec3 a_normal : NORMAL; \ No newline at end of file diff --git a/src/main/resources/shaders/glsl/vs_coloured.sh b/src/main/resources/shaders/glsl/vs_coloured.sh new file mode 100644 index 0000000..1d696a7 --- /dev/null +++ b/src/main/resources/shaders/glsl/vs_coloured.sh @@ -0,0 +1,11 @@ +$input a_position, a_normal +$output v_normal, v_position + +#include "../common/common.sh" + +void main() { + v_position = mul(u_model[0], vec4(a_position, 1.0)).xyz; + v_normal = normalize(mul(u_model[0], vec4(a_normal, 0.0) ).xyz); + + gl_Position = mul(u_modelViewProj, vec4(a_position, 1)); +} \ No newline at end of file diff --git a/src/main/resources/shaders/glsl/vs_cube_good.bin b/src/main/resources/shaders/glsl/vs_cube_good.bin new file mode 100644 index 0000000..fd7adfc Binary files /dev/null and b/src/main/resources/shaders/glsl/vs_cube_good.bin differ diff --git a/src/main/resources/shaders/glsl/vs_cubes.bin b/src/main/resources/shaders/glsl/vs_cubes.bin new file mode 100644 index 0000000..fd7adfc Binary files /dev/null and b/src/main/resources/shaders/glsl/vs_cubes.bin differ diff --git a/src/main/resources/shaders/glsl/vs_simple_color.bin b/src/main/resources/shaders/glsl/vs_simple_color.bin new file mode 100644 index 0000000..cb4153a Binary files /dev/null and b/src/main/resources/shaders/glsl/vs_simple_color.bin differ diff --git a/src/main/resources/shaders/glsl/vs_simple_color.sh b/src/main/resources/shaders/glsl/vs_simple_color.sh new file mode 100644 index 0000000..ab294ec --- /dev/null +++ b/src/main/resources/shaders/glsl/vs_simple_color.sh @@ -0,0 +1,7 @@ +$input a_position + +#include "../common/common.sh" + +void main() { + gl_Position = mul(u_modelViewProj, vec4(a_position, 1)); +} \ No newline at end of file diff --git a/src/main/resources/shaders/glsl/vs_simple_textured.bin b/src/main/resources/shaders/glsl/vs_simple_textured.bin new file mode 100644 index 0000000..3eda012 Binary files /dev/null and b/src/main/resources/shaders/glsl/vs_simple_textured.bin differ diff --git a/src/main/resources/shaders/glsl/vs_textured.sh b/src/main/resources/shaders/glsl/vs_textured.sh new file mode 100644 index 0000000..1d696a7 --- /dev/null +++ b/src/main/resources/shaders/glsl/vs_textured.sh @@ -0,0 +1,11 @@ +$input a_position, a_normal +$output v_normal, v_position + +#include "../common/common.sh" + +void main() { + v_position = mul(u_model[0], vec4(a_position, 1.0)).xyz; + v_normal = normalize(mul(u_model[0], vec4(a_normal, 0.0) ).xyz); + + gl_Position = mul(u_modelViewProj, vec4(a_position, 1)); +} \ No newline at end of file diff --git a/src/main/resources/shaders/glsl/vs_textured_back.sh b/src/main/resources/shaders/glsl/vs_textured_back.sh new file mode 100644 index 0000000..8a48330 --- /dev/null +++ b/src/main/resources/shaders/glsl/vs_textured_back.sh @@ -0,0 +1,10 @@ +$input a_position, a_normal, a_texcoord0 +$output v_normal, v_texcoord0 + +#include "../common/common.sh" + +void main() { + gl_Position = mul(u_modelViewProj, vec4(a_position, 1)); + v_normal = mul(u_model[0], vec4(a_normal, 0.0)).xyz; + v_texcoord0 = a_texcoord0; +} \ No newline at end of file diff --git a/src/main/resources/shaders/vulkan/fs_cubes.bin b/src/main/resources/shaders/vulkan/fs_simple_color.bin similarity index 100% rename from src/main/resources/shaders/vulkan/fs_cubes.bin rename to src/main/resources/shaders/vulkan/fs_simple_color.bin diff --git a/src/main/resources/shaders/vulkan/vs_cubes.bin b/src/main/resources/shaders/vulkan/vs_simple_color.bin similarity index 100% rename from src/main/resources/shaders/vulkan/vs_cubes.bin rename to src/main/resources/shaders/vulkan/vs_simple_color.bin diff --git a/src/main/resources/textures/cat.dds b/src/main/resources/textures/cat.dds new file mode 100644 index 0000000..fb9fbb3 Binary files /dev/null and b/src/main/resources/textures/cat.dds differ diff --git a/src/main/resources/textures/flowers_cloth.dds b/src/main/resources/textures/flowers_cloth.dds new file mode 100644 index 0000000..a86de50 Binary files /dev/null and b/src/main/resources/textures/flowers_cloth.dds differ diff --git a/tools/compile_shaders.sh b/tools/compile_shaders.sh new file mode 100755 index 0000000..bf8b7c8 --- /dev/null +++ b/tools/compile_shaders.sh @@ -0,0 +1,4 @@ +./shaderc -f ../src/main/resources/shaders/glsl/vs_coloured.sh -o ../src/main/resources/shaders/glsl/vs_coloured.bin --type vertex --platform linux -p 120 +./shaderc -f ../src/main/resources/shaders/glsl/fs_coloured.sh -o ../src/main/resources/shaders/glsl/fs_coloured.bin --type fragment --platform linux -p 120 +./shaderc -f ../src/main/resources/shaders/glsl/vs_textured.sh -o ../src/main/resources/shaders/glsl/vs_textured.bin --type vertex --platform linux -p 120 +./shaderc -f ../src/main/resources/shaders/glsl/fs_textured.sh -o ../src/main/resources/shaders/glsl/fs_textured.bin --type fragment --platform linux -p 120