diff --git a/assets/Shaders/entities/clouds/clouds.fs b/assets/Shaders/entities/clouds/clouds.fs new file mode 100644 index 00000000..1c133d5e --- /dev/null +++ b/assets/Shaders/entities/clouds/clouds.fs @@ -0,0 +1,102 @@ +#version 450 core + +//macros +#extension GL_ARB_explicit_uniform_location : enable + +//output +out vec4 fragColor; + +//input +in vec3 FragPos; +in vec3 Normal; +in vec2 TexCoord; +in vec4 projCoord; +in vec4 modelCoord; + +//uniforms +uniform float time; +uniform mat4 model; +uniform vec3 viewPos; + +const float CONTACT_TEST_MARGIN = -0.001; + +/* +Main method +*/ +void main(){ + + float timeS = time * 0.01; + + // Normalized pixel coordinates (from 0 to 1) + vec3 projCoordNorm = projCoord.xyz / projCoord.w / 2.0 + 0.5; + //make vec2 + vec2 finalProd = projCoordNorm.xy; + + //get vector that describes the movement through the cube + vec3 viewDir = normalize(viewPos - FragPos); + //need to transform to model space + //get inverse of model transform + mat4 inverseModel = inverse(model); + //apply to view dir + vec4 modelViewDir = normalize(inverseModel * vec4(viewDir,1.0)); + + //where the vector first hits the cube + vec4 contactPoint = modelCoord; + + + float red = 1.0; + float green = 1.0; + float blue = 1.0; + + red = modelViewDir.x; + green = modelViewDir.y; + blue = modelViewDir.z; + + + //need to calculate exit point + //if we hit one of the X edges + vec4 backPoint = vec4(1.0); + if(abs(contactPoint.x)-1.0>CONTACT_TEST_MARGIN){ + red = 1.0; + //discard if backface + if(sign(contactPoint.x)!=sign(modelViewDir.x)){ + discard; + } + //calculate distance to nearest face + float distX = 2.0; + //this is some really weird logic that I believe works to calculate distance to nearest face + float distY = abs(sign(modelViewDir.y) - contactPoint.y); + float distZ = abs(sign(modelViewDir.z) - contactPoint.z); + //calculate number of times to add viewDir to get dist + float scaleX = distX / modelViewDir.x; + float scaleY = distY / modelViewDir.y; + float scaleZ = distZ / modelViewDir.z; + //this is the smallest distance of all of them + float minScale = min(scaleX,min(scaleY,scaleZ)); + backPoint = contactPoint + (modelViewDir * minScale); + float dist = length(abs(vec3(contactPoint) - vec3(backPoint)))/1.0; + red = green = blue = dist; + } else if(abs(contactPoint.y)-1.0>CONTACT_TEST_MARGIN){ + green = 1.0; + //discard if backface + if(sign(contactPoint.y)!=sign(modelViewDir.y)){ + discard; + } + } else if(abs(contactPoint.z)-1.0>CONTACT_TEST_MARGIN){ + blue = 1.0; + //discard if backface + if(sign(contactPoint.z)!=sign(modelViewDir.z)){ + discard; + } + } + + + vec4 color = vec4( + red, + green, + blue, + 0.3 + ); + + fragColor = color; +} diff --git a/assets/Shaders/entities/clouds/clouds.vs b/assets/Shaders/entities/clouds/clouds.vs new file mode 100644 index 00000000..a9c23396 --- /dev/null +++ b/assets/Shaders/entities/clouds/clouds.vs @@ -0,0 +1,43 @@ +#version 450 core + + + +//input buffers +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec3 aNormal; +layout (location = 4) in vec2 aTex; + + +//coordinate space transformation matrices +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; +uniform float time; + + + +//output buffers +out vec3 FragPos; +out vec3 Normal; +out vec2 TexCoord; +out vec4 projCoord; +out vec4 modelCoord; + + + +void main() { + //normalize posiiton and normal + vec4 FinalVertex = vec4(aPos, 1.0); + vec4 FinalNormal = vec4(aNormal, 1.0); + + + //push frag, normal, and texture positions to fragment shader + FragPos = vec3(model * FinalVertex); + Normal = mat3(transpose(inverse(model))) * aNormal; + TexCoord = aTex; + projCoord = projection * view * model * FinalVertex; + modelCoord = FinalVertex; + + //set final position with opengl space + gl_Position = projection * view * model * FinalVertex; +} diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index d249ca18..7f93ea52 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1156,6 +1156,11 @@ Convert PhysicsEntityUtils to use generic interface to load tri geom rigid bodie Fix winding order on block meshes Add texture atlasing to blocks +(!1/25/2024) +Remove unused import +Geometry mesh generation class +Cloud shader + # TODO diff --git a/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java b/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java index 807f63ba..24722051 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java +++ b/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java @@ -19,6 +19,7 @@ import electrosphere.client.ui.menu.mainmenu.MenuCharacterCreation; import electrosphere.controls.ControlHandler; import electrosphere.engine.Globals; import electrosphere.engine.assetmanager.AssetDataStrings; +import electrosphere.engine.assetmanager.queue.QueuedModel; import electrosphere.engine.signal.Signal.SignalType; import electrosphere.engine.threads.LabeledThread.ThreadLabel; import electrosphere.entity.DrawableUtils; @@ -30,6 +31,10 @@ import electrosphere.net.NetUtils; import electrosphere.net.client.ClientNetworking; import electrosphere.renderer.actor.Actor; import electrosphere.renderer.actor.ActorTextureMask; +import electrosphere.renderer.meshgen.GeometryMeshGen; +import electrosphere.renderer.model.Mesh; +import electrosphere.renderer.model.Model; +import electrosphere.renderer.shader.VisualShader; public class ClientLoading { @@ -272,6 +277,22 @@ public class ClientLoading { cursorActor.addTextureMask(new ActorTextureMask("sphere", Arrays.asList(new String[]{"Textures/transparent_red.png"}))); DrawableUtils.makeEntityTransparent(Globals.playerCursor); EntityUtils.getScale(Globals.playerCursor).set(0.2f); + + //cloud object + // Entity cloudEnt = EntityCreationUtils.createClientSpatialEntity(); + // EntityCreationUtils.makeEntityDrawablePreexistingModel(cloudEnt, Globals.assetManager.queuedAsset(new QueuedModel(() -> { + // Model rVal = new Model(); + + // Mesh m = GeometryMeshGen.genBox(1, 1, 1); + + // //shader logic + // m.setShader(VisualShader.loadSpecificShader("Shaders/entities/clouds/clouds.vs", "Shaders/entities/clouds/clouds.fs")); + // m.setParent(rVal); + + // rVal.getMeshes().add(m); + // rVal.setBoundingSphere(0,0,0,2); + // return rVal; + // }))); } static final int MAX_DRAW_CELL_WAIT = 1000; diff --git a/src/main/java/electrosphere/renderer/meshgen/GeometryMeshGen.java b/src/main/java/electrosphere/renderer/meshgen/GeometryMeshGen.java new file mode 100644 index 00000000..c3ac6c27 --- /dev/null +++ b/src/main/java/electrosphere/renderer/meshgen/GeometryMeshGen.java @@ -0,0 +1,277 @@ +package electrosphere.renderer.meshgen; + +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.util.LinkedList; +import java.util.List; + +import org.joml.Vector2f; +import org.joml.Vector3f; +import org.lwjgl.BufferUtils; + +import electrosphere.renderer.model.Mesh; + +public class GeometryMeshGen { + + /** + * Meshes a box + * @param verts The list of verts to store into + * @param normals The list of normals to store into + * @param uvs The list of uvs to store into + * @param indices The list of indices to store into + * @param width The width of the box + * @param height The height of the box + * @param depth THe depth of the box + */ + public static Mesh genBox(float width, float height, float depth){ + Mesh mesh = new Mesh("box"); + mesh.generateVAO(); + List verts = new LinkedList(); + List normals = new LinkedList(); + List uvs = new LinkedList(); + List indices = new LinkedList(); + // + //face 1 + // + + //verts + verts.add(new Vector3f(0, 0, 0)); + verts.add(new Vector3f(0 + width, 0, 0)); + verts.add(new Vector3f(0, 0 + height, 0)); + verts.add(new Vector3f(0 + width, 0 + height, 0)); + //indices + indices.add(0); + indices.add(2); + indices.add(3); + indices.add(0); + indices.add(3); + indices.add(1); + //normals + normals.add(new Vector3f(0,0,-1)); + normals.add(new Vector3f(0,0,-1)); + normals.add(new Vector3f(0,0,-1)); + normals.add(new Vector3f(0,0,-1)); + //uvs + uvs.add(new Vector2f( 0, 0)); + uvs.add(new Vector2f(width, 0)); + uvs.add(new Vector2f( 0, height)); + uvs.add(new Vector2f(width, height)); + + // + //face 2 + // + + //verts + verts.add(new Vector3f(0, 0, 0 )); + verts.add(new Vector3f(0, 0, 0 + depth)); + verts.add(new Vector3f(0, 0 + height, 0 )); + verts.add(new Vector3f(0, 0 + height, 0 + depth)); + //indices + indices.add(4); + indices.add(7); + indices.add(6); + indices.add(4); + indices.add(5); + indices.add(7); + //normals + normals.add(new Vector3f(-1,0,0)); + normals.add(new Vector3f(-1,0,0)); + normals.add(new Vector3f(-1,0,0)); + normals.add(new Vector3f(-1,0,0)); + //uvs + uvs.add(new Vector2f( 0, 0)); + uvs.add(new Vector2f(depth, 0)); + uvs.add(new Vector2f( 0, height)); + uvs.add(new Vector2f(depth, height)); + + // + //face 3 + // + + //verts + verts.add(new Vector3f(0, 0, 0 )); + verts.add(new Vector3f(0, 0, 0 + depth)); + verts.add(new Vector3f(0 + width, 0, 0 )); + verts.add(new Vector3f(0 + width, 0, 0 + depth)); + //indices + indices.add( 8); + indices.add(10); + indices.add(11); + indices.add( 9); + indices.add( 8); + indices.add(11); + //normals + normals.add(new Vector3f(0,-1,0)); + normals.add(new Vector3f(0,-1,0)); + normals.add(new Vector3f(0,-1,0)); + normals.add(new Vector3f(0,-1,0)); + //uvs + uvs.add(new Vector2f( 0, 0)); + uvs.add(new Vector2f(depth, 0)); + uvs.add(new Vector2f( 0, width)); + uvs.add(new Vector2f(depth, width)); + + // + //face 4 + // + + //verts + verts.add(new Vector3f(0, 0, 0 + depth)); + verts.add(new Vector3f(0 + width, 0, 0 + depth)); + verts.add(new Vector3f(0, 0 + height, 0 + depth)); + verts.add(new Vector3f(0 + width, 0 + height, 0 + depth)); + //indices + indices.add(12); + indices.add(15); + indices.add(14); + indices.add(12); + indices.add(13); + indices.add(15); + //normals + normals.add(new Vector3f(0,0,1)); + normals.add(new Vector3f(0,0,1)); + normals.add(new Vector3f(0,0,1)); + normals.add(new Vector3f(0,0,1)); + //uvs + uvs.add(new Vector2f( 0, 0)); + uvs.add(new Vector2f(width, 0)); + uvs.add(new Vector2f( 0, height)); + uvs.add(new Vector2f(width, height)); + + + // + //face 5 + // + + //verts + verts.add(new Vector3f(0 + width, 0, 0 )); + verts.add(new Vector3f(0 + width, 0, 0 + depth)); + verts.add(new Vector3f(0 + width, 0 + height, 0 )); + verts.add(new Vector3f(0 + width, 0 + height, 0 + depth)); + //indices + indices.add(16); + indices.add(18); + indices.add(19); + indices.add(16); + indices.add(19); + indices.add(17); + //normals + normals.add(new Vector3f(1,0,0)); + normals.add(new Vector3f(1,0,0)); + normals.add(new Vector3f(1,0,0)); + normals.add(new Vector3f(1,0,0)); + //uvs + uvs.add(new Vector2f( 0, 0)); + uvs.add(new Vector2f(depth, 0)); + uvs.add(new Vector2f( 0, height)); + uvs.add(new Vector2f(depth, height)); + + + // + //face 6 + // + + //verts + verts.add(new Vector3f(0, 0 + height, 0 )); + verts.add(new Vector3f(0, 0 + height, 0 + depth)); + verts.add(new Vector3f(0 + width, 0 + height, 0 )); + verts.add(new Vector3f(0 + width, 0 + height, 0 + depth)); + //indices + indices.add(20); + indices.add(23); + indices.add(22); + indices.add(20); + indices.add(21); + indices.add(23); + //normals + normals.add(new Vector3f(0,1,0)); + normals.add(new Vector3f(0,1,0)); + normals.add(new Vector3f(0,1,0)); + normals.add(new Vector3f(0,1,0)); + //uvs + uvs.add(new Vector2f( 0, 0)); + uvs.add(new Vector2f(depth, 0)); + uvs.add(new Vector2f( 0, width)); + uvs.add(new Vector2f(depth, width)); + + + + //store into arrays + FloatBuffer vertBuffer; + FloatBuffer normalBuffer; + FloatBuffer uvBuffer; + IntBuffer faceBuffer; + //verts + float[] vertices = new float[verts.size() * 3]; + for(int i = 0; i < verts.size(); i++){ + Vector3f currentVert = verts.get(i); + vertices[3 * i + 0] = currentVert.x; + vertices[3 * i + 1] = currentVert.y; + vertices[3 * i + 2] = currentVert.z; + } + vertBuffer = BufferUtils.createFloatBuffer(vertices.length); + vertBuffer.put(vertices); + + //faces + int[] faceElements = new int[indices.size()]; + for(int i = 0; i < indices.size(); i++){ + faceElements[i] = indices.get(i); + } + faceBuffer = BufferUtils.createIntBuffer(faceElements.length); + faceBuffer.put(faceElements); + + //normals + float[] normalsArr = new float[normals.size() * 3]; + for(int i = 0; i < normals.size(); i++){ + Vector3f currentNormal = normals.get(i); + normalsArr[3 * i + 0] = currentNormal.x; + normalsArr[3 * i + 1] = currentNormal.y; + normalsArr[3 * i + 2] = currentNormal.z; + } + normalBuffer = BufferUtils.createFloatBuffer(normalsArr.length); + normalBuffer.put(normalsArr); + + //uvs + float[] uvsArr = new float[uvs.size() * 2]; + for(int i = 0; i < uvs.size(); i++){ + Vector2f currentUV = uvs.get(i); + uvsArr[2 * i + 0] = currentUV.x; + uvsArr[2 * i + 1] = currentUV.y; + } + uvBuffer = BufferUtils.createFloatBuffer(uvsArr.length); + uvBuffer.put(uvsArr); + + + + + //actually store in mesh + int elementCount = faceElements.length; + try { + //actually buffer vertices + if(vertBuffer.position() > 0){ + vertBuffer.flip(); + mesh.bufferVertices(vertBuffer, 3); + } + //actually buffer normals + if(normalBuffer != null && normalBuffer.position() > 0){ + normalBuffer.flip(); + mesh.bufferNormals(normalBuffer, 3); + } + //actually buffer UVs + if(uvBuffer != null && uvBuffer.position() > 0){ + uvBuffer.flip(); + mesh.bufferTextureCoords(uvBuffer, 2); + } + //buffer element indices + if(faceBuffer.position() > 0){ + faceBuffer.flip(); + mesh.bufferFaces(faceBuffer, elementCount); + } + } catch (NullPointerException ex){ + ex.printStackTrace(); + } + + return mesh; + } + +} diff --git a/src/main/java/electrosphere/renderer/model/Model.java b/src/main/java/electrosphere/renderer/model/Model.java index 446b1f6f..8f571067 100644 --- a/src/main/java/electrosphere/renderer/model/Model.java +++ b/src/main/java/electrosphere/renderer/model/Model.java @@ -608,6 +608,17 @@ public class Model { this.boundingSphere = boundingSphere; } + /** + * Sets the bounding sphere + * @param x The x position + * @param y The y position + * @param z The z position + * @param r The radius of the sphere + */ + public void setBoundingSphere(double x, double y, double z, double r){ + this.boundingSphere = new Sphered(x,y,z,r); + } + /** * Gets the list of all animations * @return The list of all animations diff --git a/src/main/java/electrosphere/renderer/ui/font/FontManager.java b/src/main/java/electrosphere/renderer/ui/font/FontManager.java index 816538d6..69f0cbb4 100644 --- a/src/main/java/electrosphere/renderer/ui/font/FontManager.java +++ b/src/main/java/electrosphere/renderer/ui/font/FontManager.java @@ -1,13 +1,9 @@ package electrosphere.renderer.ui.font; -import java.awt.FontFormatException; -import java.io.IOException; import java.util.HashMap; import java.util.Map; import electrosphere.engine.Globals; -import electrosphere.logger.LoggerInterface; -import electrosphere.util.FileUtils; /** * Manages all fonts loaded into the engine diff --git a/src/main/java/electrosphere/server/block/manager/ServerBlockChunkGenerationThread.java b/src/main/java/electrosphere/server/block/manager/ServerBlockChunkGenerationThread.java index e0901e5a..83eb7088 100644 --- a/src/main/java/electrosphere/server/block/manager/ServerBlockChunkGenerationThread.java +++ b/src/main/java/electrosphere/server/block/manager/ServerBlockChunkGenerationThread.java @@ -105,16 +105,16 @@ public class ServerBlockChunkGenerationThread implements Runnable { //TODO: generate from macro-level data chunk = BlockChunkData.allocate(); chunk.setHomogenousValue(0); - if(worldX == 0 && worldY == 0 && worldZ == 0){ - chunk.setHomogenousValue(BlockChunkData.NOT_HOMOGENOUS); - for(int x = 0; x < 16; x++){ - for(int y = 0; y < 16; y++){ - for(int z = 0; z < 16; z++){ - chunk.setType(x, y, z, 1); - } - } - } - } + // if(worldX == 0 && worldY == 0 && worldZ == 0){ + // chunk.setHomogenousValue(BlockChunkData.NOT_HOMOGENOUS); + // for(int x = 0; x < 16; x++){ + // for(int y = 0; y < 16; y++){ + // for(int z = 0; z < 16; z++){ + // chunk.setType(x, y, z, 1); + // } + // } + // } + // } } if(chunk != null){ chunkCache.add(worldX, worldY, worldZ, stride, chunk); diff --git a/src/main/java/electrosphere/server/block/manager/ServerBlockManager.java b/src/main/java/electrosphere/server/block/manager/ServerBlockManager.java index 084e1551..fb800134 100644 --- a/src/main/java/electrosphere/server/block/manager/ServerBlockManager.java +++ b/src/main/java/electrosphere/server/block/manager/ServerBlockManager.java @@ -121,16 +121,16 @@ public class ServerBlockManager { returnedChunk.setWorldY(worldY); returnedChunk.setWorldZ(worldZ); returnedChunk.setHomogenousValue(0); - if(worldX == 0 && worldY == 0 && worldZ == 0){ - returnedChunk.setHomogenousValue(BlockChunkData.NOT_HOMOGENOUS); - for(int x = 3; x < 16; x++){ - for(int y = 8; y < 16; y++){ - for(int z = 3; z < 16; z++){ - returnedChunk.setType(x, y, z, 1); - } - } - } - } + // if(worldX == 0 && worldY == 0 && worldZ == 0){ + // returnedChunk.setHomogenousValue(BlockChunkData.NOT_HOMOGENOUS); + // for(int x = 3; x < 16; x++){ + // for(int y = 8; y < 16; y++){ + // for(int z = 3; z < 16; z++){ + // returnedChunk.setType(x, y, z, 1); + // } + // } + // } + // } } this.chunkCache.add(worldX, worldY, worldZ, BlockChunkData.LOD_FULL_RES, returnedChunk); }