diff --git a/assets/shaders/confictura/depth-screenspace.frag b/assets/shaders/confictura/depth-screenspace.frag new file mode 100644 index 0000000..c012128 --- /dev/null +++ b/assets/shaders/confictura/depth-screenspace.frag @@ -0,0 +1,13 @@ +#define HIGHP + +in vec2 v_texCoords; + +out vec4 fragColor; + +uniform sampler2D u_color; +uniform sampler2D u_depth; + +void main(){ + fragColor = texture(u_color, v_texCoords); + gl_FragDepth = texture(u_depth, v_texCoords).r; +} diff --git a/assets/shaders/confictura/depth-screenspace.vert b/assets/shaders/confictura/depth-screenspace.vert new file mode 100644 index 0000000..2a53f08 --- /dev/null +++ b/assets/shaders/confictura/depth-screenspace.vert @@ -0,0 +1,11 @@ +#define HIGHP + +in vec4 a_position; +in vec2 a_texCoord0; + +out vec2 v_texCoords; + +void main(){ + v_texCoords = a_texCoord0; + gl_Position = a_position; +} diff --git a/src/confictura/ConficturaMod.java b/src/confictura/ConficturaMod.java index d0ca3d0..644dd5a 100644 --- a/src/confictura/ConficturaMod.java +++ b/src/confictura/ConficturaMod.java @@ -51,6 +51,7 @@ public class ConficturaMod extends Mod{ // <--- Modules only present in clients, typically rendering or auxiliary input utilities. ---> public static RenderContext renderContext; public static ModelPropDrawer modelPropDrawer; + public static SizedGraphics sizedGraphics; // <--- Map-editor extension modules. ---> public static CinematicEditor cinematicEditor; @@ -188,6 +189,7 @@ public String getName(){ inputAggregator = new InputAggregator(); renderContext = new RenderContext(); modelPropDrawer = new ModelPropDrawer(CShaders.modelProp, 8192, 16384); + sizedGraphics = new SizedGraphics(); }); } }); diff --git a/src/confictura/content/CPlanets.java b/src/confictura/content/CPlanets.java index 31c4842..05771d1 100644 --- a/src/confictura/content/CPlanets.java +++ b/src/confictura/content/CPlanets.java @@ -39,9 +39,9 @@ public static void load(){ }}; for(int i = 0; i < 3; i++){ - new Planet("test" + i, blackHole, 1f){{ + new AtmospherePlanet("test" + i, blackHole, 1f){{ generator = new SerpuloPlanetGenerator(); - meshLoader = () -> new HexMesh(this, 6); + meshLoader = () -> new AtmosphereHexMesh(generator, 6); cloudMeshLoader = () -> new MultiMesh( new HexSkyMesh(this, 11, 0.15f, 0.13f, 5, new Color().set(Pal.spore).mul(0.9f).a(0.75f), 2, 0.45f, 0.9f, 0.38f), new HexSkyMesh(this, 1, 0.6f, 0.16f, 5, Color.white.cpy().lerp(Pal.spore, 0.55f).a(0.75f), 2, 0.45f, 1f, 0.41f) diff --git a/src/confictura/graphics/CShaders.java b/src/confictura/graphics/CShaders.java index 2677f09..7dd5a45 100644 --- a/src/confictura/graphics/CShaders.java +++ b/src/confictura/graphics/CShaders.java @@ -12,6 +12,7 @@ * @author GlFolker */ public final class CShaders{ + public static DepthScreenspaceShader depthScreenspace; public static DepthShader depth; public static DepthAtmosphereShader depthAtmosphere; public static PortalForcefieldShader portalForcefield; @@ -30,6 +31,7 @@ public static void load(){ String prevVert = Shader.prependVertexCode, prevFrag = Shader.prependFragmentCode; Shader.prependVertexCode = Shader.prependFragmentCode = ""; + depthScreenspace = new DepthScreenspaceShader(); depth = new DepthShader(); depthAtmosphere = new DepthAtmosphereShader(); portalForcefield = new PortalForcefieldShader(); diff --git a/src/confictura/graphics/SizedGraphics.java b/src/confictura/graphics/SizedGraphics.java new file mode 100644 index 0000000..c931279 --- /dev/null +++ b/src/confictura/graphics/SizedGraphics.java @@ -0,0 +1,212 @@ +package confictura.graphics; + +import arc.*; +import arc.Graphics.Cursor.*; +import arc.graphics.*; +import arc.graphics.gl.*; + +import java.lang.reflect.*; + +import static arc.Core.*; + +public class SizedGraphics extends Graphics{ + private static final Method setCursor, setSystemCursor; + + protected boolean overriding; + protected int overrideWidth, overrideHeight; + + static{ + try{ + setCursor = Graphics.class.getDeclaredMethod("setCursor", Cursor.class); + setSystemCursor = Graphics.class.getDeclaredMethod("setSystemCursor", SystemCursor.class); + + setCursor.setAccessible(true); + setSystemCursor.setAccessible(true); + }catch(NoSuchMethodException e){ + throw new RuntimeException(e); + } + } + + public void override(int dimension, Runnable run){ + override(dimension, dimension, run); + } + + public void override(int width, int height, Runnable run){ + overriding = true; + overrideWidth = width; + overrideHeight = height; + + var prev = graphics; + graphics = this; + + try{ + run.run(); + }finally{ + overriding = false; + graphics = prev; + } + } + + @Override + public int getWidth(){ + return overriding ? overrideWidth : graphics.getWidth(); + } + + @Override + public int getHeight(){ + return overriding ? overrideHeight : graphics.getHeight(); + } + + @Override + public GL20 getGL20(){ + return graphics.getGL20(); + } + + @Override + public void setGL20(GL20 gl20){ + graphics.setGL20(gl20); + } + + @Override + public GL30 getGL30(){ + return graphics.getGL30(); + } + + @Override + public void setGL30(GL30 gl30){ + graphics.setGL30(gl30); + } + + @Override + public int getBackBufferWidth(){ + return graphics.getBackBufferWidth(); + } + + @Override + public int getBackBufferHeight(){ + return graphics.getBackBufferHeight(); + } + + @Override + public long getFrameId(){ + return graphics.getFrameId(); + } + + @Override + public float getDeltaTime(){ + return graphics.getDeltaTime(); + } + + @Override + public int getFramesPerSecond(){ + return graphics.getFramesPerSecond(); + } + + @Override + public GLVersion getGLVersion(){ + return graphics.getGLVersion(); + } + + @Override + public float getPpiX(){ + return graphics.getPpiX(); + } + + @Override + public float getPpiY(){ + return graphics.getPpiY(); + } + + @Override + public float getPpcX(){ + return graphics.getPpcX(); + } + + @Override + public float getPpcY(){ + return graphics.getPpcY(); + } + + @Override + public float getDensity(){ + return graphics.getDensity(); + } + + @Override + public boolean setWindowedMode(int width, int height){ + return graphics.setWindowedMode(width, height); + } + + @Override + public void setTitle(String title){ + graphics.setTitle(title); + } + + @Override + public void setBorderless(boolean undecorated){ + graphics.setBorderless(undecorated); + } + + @Override + public void setResizable(boolean resizable){ + graphics.setResizable(resizable); + } + + @Override + public void setVSync(boolean vsync){ + graphics.setVSync(vsync); + } + + @Override + public BufferFormat getBufferFormat(){ + return graphics.getBufferFormat(); + } + + @Override + public boolean supportsExtension(String extension){ + return graphics.supportsExtension(extension); + } + + @Override + public boolean isContinuousRendering(){ + return graphics.isContinuousRendering(); + } + + @Override + public void setContinuousRendering(boolean isContinuous){ + graphics.setContinuousRendering(isContinuous); + } + + @Override + public void requestRendering(){ + graphics.requestRendering(); + } + + @Override + public boolean isFullscreen(){ + return graphics.isFullscreen(); + } + + @Override + public Cursor newCursor(Pixmap pixmap, int xHotspot, int yHotspot){ + return graphics.newCursor(pixmap, xHotspot, yHotspot); + } + + @Override + protected void setCursor(Cursor cursor){ + try{ + setCursor.invoke(graphics, cursor); + }catch(InvocationTargetException | IllegalAccessException e){ + throw new RuntimeException(e); + } + } + + @Override + protected void setSystemCursor(SystemCursor systemCursor){ + try{ + setSystemCursor.invoke(graphics, systemCursor); + }catch(InvocationTargetException | IllegalAccessException e){ + throw new RuntimeException(e); + } + } +} diff --git a/src/confictura/graphics/gl/CFrameBuffer.java b/src/confictura/graphics/gl/CFrameBuffer.java index 9616064..da0a24b 100644 --- a/src/confictura/graphics/gl/CFrameBuffer.java +++ b/src/confictura/graphics/gl/CFrameBuffer.java @@ -102,6 +102,7 @@ public void resize(int width, int height){ public void begin(Color clearColor){ begin(); Gl.clearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a); + Gl.clearDepthf(1f); Gl.clear(Gl.colorBufferBit | (hasDepth ? Gl.depthBufferBit : 0) | (hasStencil ? Gl.stencilBufferBit : 0)); } } diff --git a/src/confictura/graphics/shaders/DepthScreenspaceShader.java b/src/confictura/graphics/shaders/DepthScreenspaceShader.java new file mode 100644 index 0000000..b3658c5 --- /dev/null +++ b/src/confictura/graphics/shaders/DepthScreenspaceShader.java @@ -0,0 +1,22 @@ +package confictura.graphics.shaders; + +import confictura.graphics.gl.*; + +import static confictura.graphics.CShaders.*; + +public class DepthScreenspaceShader extends Gl30Shader{ + public CFrameBuffer buffer; + + public DepthScreenspaceShader(){ + super(file("depth-screenspace.vert"), file("depth-screenspace.frag")); + } + + @Override + public void apply(){ + buffer.getTexture().bind(1); + buffer.getDepthTexture().bind(0); + + setUniformi("u_color", 1); + setUniformi("u_depth", 0); + } +} diff --git a/src/confictura/world/celestial/AtmospherePlanet.java b/src/confictura/world/celestial/AtmospherePlanet.java index 98779e5..a852900 100644 --- a/src/confictura/world/celestial/AtmospherePlanet.java +++ b/src/confictura/world/celestial/AtmospherePlanet.java @@ -2,11 +2,13 @@ import arc.graphics.*; import arc.graphics.Texture.*; +import arc.graphics.g2d.*; import arc.graphics.g3d.*; import arc.graphics.gl.*; import arc.math.geom.*; import arc.util.*; import confictura.graphics.*; +import confictura.graphics.gl.*; import mindustry.graphics.*; import mindustry.graphics.g3d.*; import mindustry.type.*; @@ -20,6 +22,7 @@ */ public class AtmospherePlanet extends Planet{ public @Nullable FrameBuffer depthBuffer; + public @Nullable CFrameBuffer buffer; public AtmospherePlanet(String name, Planet parent, float radius){ super(name, parent, radius); @@ -32,10 +35,15 @@ public AtmospherePlanet(String name, Planet parent, float radius, int sectorSize @Override public void load(){ super.load(); - if(!headless){ + if(depthBuffer == null){ depthBuffer = new FrameBuffer(graphics.getWidth(), graphics.getHeight(), true); depthBuffer.getTexture().setFilter(TextureFilter.nearest); } + + if(buffer == null){ + buffer = new CFrameBuffer(2, 2, true); + buffer.getTexture().setFilter(TextureFilter.nearest); + } } @Override @@ -67,6 +75,25 @@ public AtmosphereHexMesh(int divisions){ @Override public void render(PlanetParams params, Mat3D projection, Mat3D transform){ + /*buffer.resize(graphics.getWidth(), graphics.getHeight()); + buffer.begin(Color.clear); + + var shader = Shaders.planet; + shader.planet = AtmospherePlanet.this; + shader.lightDir.set(solarSystem.position).sub(position).rotate(Vec3.Y, getRotation()).nor(); + shader.ambientColor.set(solarSystem.lightColor); + shader.bind(); + shader.setUniformMatrix4("u_proj", renderer.planets.cam.combined.val); + shader.setUniformMatrix4("u_trans", transform.val); + shader.apply(); + mesh.render(shader, Gl.triangles); + + buffer.end(); + + var blit = CShaders.depthScreenspace; + blit.buffer = buffer; + Draw.blit(blit);*/ + if(params.alwaysDrawAtmosphere || settings.getBool("atmosphere")){ var depth = CShaders.depth; depthBuffer.resize(graphics.getWidth(), graphics.getHeight()); @@ -75,7 +102,7 @@ public void render(PlanetParams params, Mat3D projection, Mat3D transform){ depth.camera = renderer.planets.cam; depth.bind(); - depth.setUniformMatrix4("u_proj", projection.val); + depth.setUniformMatrix4("u_proj", renderer.planets.cam.combined.val); depth.setUniformMatrix4("u_trans", transform.val); depth.apply(); mesh.render(depth, Gl.triangles); @@ -89,7 +116,7 @@ public void render(PlanetParams params, Mat3D projection, Mat3D transform){ shader.lightDir.set(solarSystem.position).sub(position).rotate(Vec3.Y, getRotation()).nor(); shader.ambientColor.set(solarSystem.lightColor); shader.bind(); - shader.setUniformMatrix4("u_proj", projection.val); + shader.setUniformMatrix4("u_proj", renderer.planets.cam.combined.val); shader.setUniformMatrix4("u_trans", transform.val); shader.apply(); mesh.render(shader, Gl.triangles); diff --git a/src/confictura/world/celestial/BlackHole.java b/src/confictura/world/celestial/BlackHole.java index c211320..a2ce315 100644 --- a/src/confictura/world/celestial/BlackHole.java +++ b/src/confictura/world/celestial/BlackHole.java @@ -17,6 +17,7 @@ import mindustry.type.*; import static arc.Core.*; +import static confictura.ConficturaMod.*; import static mindustry.Vars.*; /** @@ -102,100 +103,102 @@ public void draw(PlanetParams params, Mat3D projection, Mat3D transform){ children = stash; drawing = true; - - int dim = Math.max(graphics.getWidth(), graphics.getHeight()); var cam = renderer.planets.cam; float fov = cam.fov, w = cam.width, h = cam.height; var up = v1.set(cam.up); var dir = v2.set(cam.direction); - cam.fov = 90f; - cam.width = cam.height = dim; - - frustum.position.set(position); - frustum.fov = 30f; - frustum.width = frustum.height = 1f; - frustum.lookAt(cam.position); - frustum.update(); - - requests.clear(); - visit(this, requests::add); - - orbit.resize(dim, dim); - orbitRef.resize(dim, dim); var shader = CShaders.blackHole; - pov.resize(dim, dim); - pov.begin(); - pov.eachSide(side -> { - Gl.clearColor(0f, 0f, 0f, 0f); - Gl.clear(Gl.colorBufferBit | Gl.depthBufferBit); - - side.getUp(cam.up); - side.getDirection(cam.direction); - - if(params.drawSkybox){ - var lastPos = v3.set(cam.position); - cam.position.setZero(); - cam.update(); - - Gl.depthMask(false); - renderer.planets.skybox.render(cam.combined); - Gl.depthMask(true); - - cam.position.set(lastPos); - } - - cam.update(); - shader.cubemapView[side.index].set(cam.view); - - for(var p : requests){ - if(!p.visible()) continue; - if(cam.frustum.containsSphere(p.position, p.clipRadius) && !frustum.frustum.containsSphere(p.position, p.clipRadius)){ - p.draw(params, cam.combined, p.getTransform(mat)); + sizedGraphics.override(Math.max(graphics.getWidth(), graphics.getHeight()), () -> { + cam.fov = 90f; + cam.width = graphics.getWidth(); + cam.height = graphics.getHeight(); + + frustum.position.set(position); + frustum.fov = 30f; + frustum.width = frustum.height = 1f; + frustum.lookAt(cam.position); + frustum.update(); + + requests.clear(); + visit(this, requests::add); + + orbit.resize(graphics.getWidth(), graphics.getHeight()); + orbitRef.resize(graphics.getWidth(), graphics.getHeight()); + + pov.resize(graphics.getWidth(), graphics.getHeight()); + pov.begin(); + pov.eachSide(side -> { + Gl.clearColor(0f, 0f, 0f, 0f); + Gl.clear(Gl.colorBufferBit | Gl.depthBufferBit); + + side.getUp(cam.up); + side.getDirection(cam.direction); + + if(params.drawSkybox){ + var lastPos = v3.set(cam.position); + cam.position.setZero(); + cam.update(); + + Gl.depthMask(false); + renderer.planets.skybox.render(cam.combined); + Gl.depthMask(true); + + cam.position.set(lastPos); } - } - for(var p : requests){ - if(!p.visible()) continue; - if(!frustum.frustum.containsSphere(p.position, p.clipRadius)){ - p.drawClouds(params, cam.combined, p.getTransform(mat)); - if(p.hasGrid() && p == params.planet && params.drawUi){ - renderer.planets.renderSectors(p, params); + cam.update(); + shader.cubemapView[side.index].set(cam.view); + + for(var p : requests){ + if(!p.visible()) continue; + if(cam.frustum.containsSphere(p.position, p.clipRadius) && !frustum.frustum.containsSphere(p.position, p.clipRadius)){ + p.draw(params, cam.combined, p.getTransform(mat)); } + } - if(cam.frustum.containsSphere(p.position, p.clipRadius) && p.parent != null && p.hasAtmosphere && (params.alwaysDrawAtmosphere || Core.settings.getBool("atmosphere"))){ - p.drawAtmosphere(renderer.planets.atmosphere, cam); + for(var p : requests){ + if(!p.visible()) continue; + if(!frustum.frustum.containsSphere(p.position, p.clipRadius)){ + p.drawClouds(params, cam.combined, p.getTransform(mat)); + if(p.hasGrid() && p == params.planet && params.drawUi){ + renderer.planets.renderSectors(p, params); + } + + if(cam.frustum.containsSphere(p.position, p.clipRadius) && p.parent != null && p.hasAtmosphere && (params.alwaysDrawAtmosphere || Core.settings.getBool("atmosphere"))){ + p.drawAtmosphere(renderer.planets.atmosphere, cam); + } } } - } - orbitRef.begin(Color.clear); + orbitRef.begin(Color.clear); - var unlit = Shaders.unlit; - unlit.bind(); - unlit.setUniformMatrix4("u_proj", cam.combined.val); - unlit.setUniformMatrix4("u_trans", getTransform(mat).val); - unlit.apply(); + var unlit = Shaders.unlit; + unlit.bind(); + unlit.setUniformMatrix4("u_proj", cam.combined.val); + unlit.setUniformMatrix4("u_trans", getTransform(mat).val); + unlit.apply(); - mesh.render(unlit, Gl.triangles); - orbitRef.end(); + mesh.render(unlit, Gl.triangles); + orbitRef.end(); - orbit.begin(Color.clear); - for(var p : requests){ - if(!p.visible()) continue; - if(params.drawUi){ - renderer.planets.batch.proj(cam.combined); - renderer.planets.renderOrbit(p, params); + orbit.begin(Color.clear); + for(var p : requests){ + if(!p.visible()) continue; + if(params.drawUi){ + renderer.planets.batch.proj(cam.combined); + renderer.planets.renderOrbit(p, params); + } } - } - orbit.end(); - - var stencil = CShaders.blackHoleStencil; - stencil.src = orbit; - stencil.ref = orbitRef; - Draw.blit(stencil); + orbit.end(); + + var stencil = CShaders.blackHoleStencil; + stencil.src = orbit; + stencil.ref = orbitRef; + Draw.blit(stencil); + }); + pov.end(); }); - pov.end(); cam.up.set(up); cam.direction.set(dir);