diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index eef89763..b13f63e9 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1905,6 +1905,7 @@ Ambient light sent in dedicated variable to shader Major lighting shader organization rework Material albedo work Editor entities don't use charges on placing blocks +Overhaul material loading - uses queued textures now diff --git a/src/main/java/electrosphere/client/terrain/foliage/FoliageModel.java b/src/main/java/electrosphere/client/terrain/foliage/FoliageModel.java index 16b439f0..f9893cdf 100644 --- a/src/main/java/electrosphere/client/terrain/foliage/FoliageModel.java +++ b/src/main/java/electrosphere/client/terrain/foliage/FoliageModel.java @@ -16,7 +16,6 @@ import electrosphere.client.terrain.cache.ChunkData; import electrosphere.data.entity.foliage.FoliageType; import electrosphere.engine.Globals; import electrosphere.engine.assetmanager.queue.QueuedTexture; -import electrosphere.engine.assetmanager.queue.QueuedTexture.QueuedTextureType; import electrosphere.engine.threads.ThreadCounts; import electrosphere.entity.ClientEntityUtils; import electrosphere.entity.Entity; @@ -249,7 +248,7 @@ public class FoliageModel { int textureWidth = (1 + (drawCount / MAX_TEXTURE_HEIGHT)) * (SINGLE_FOLIAGE_DATA_SIZE_BYTES / 4); //construct data texture - QueuedTexture queuedAsset = new QueuedTexture(QueuedTextureType.DATA_BUFF,buffer,textureWidth,textureHeight); + QueuedTexture queuedAsset = QueuedTexture.createFromBuffer(buffer,textureWidth,textureHeight); Globals.assetManager.queuedAsset(queuedAsset); TextureInstancedActor actor = TextureInstancedActor.attachTextureInstancedActor(rVal, foliageType.getGraphicsTemplate().getModel().getPath(), vertexPath, fragmentPath, queuedAsset, drawCount, textureWidth / NUM_PER_INSTANCE_VARS); diff --git a/src/main/java/electrosphere/engine/assetmanager/queue/QueuedTexture.java b/src/main/java/electrosphere/engine/assetmanager/queue/QueuedTexture.java index c323015d..ad6d2883 100644 --- a/src/main/java/electrosphere/engine/assetmanager/queue/QueuedTexture.java +++ b/src/main/java/electrosphere/engine/assetmanager/queue/QueuedTexture.java @@ -31,52 +31,57 @@ public class QueuedTexture implements QueuedAsset { /** * The type of queued texture */ - QueuedTextureType type; + private QueuedTextureType type; /** * True if loaded */ - boolean hasLoaded = false; + private boolean hasLoaded = false; /** * The resuling texture object */ - Texture texture = null; + private Texture texture = null; /** * The data to be loaded */ - BufferedImage data; + private BufferedImage data; /** * The byte buffer */ - ByteBuffer buffer; + private ByteBuffer buffer; /** * Width of the image */ - int width = -1; + private int width = -1; /** * Height of the image */ - int height = -1; + private int height = -1; /** * The path the asset manager promises this texture will be stored at */ - String promisedPath; + private String promisedPath; /** * true if the path to register this asset was supplied while it was being queued, false if the promised path should be generated when it is placed in queue */ - boolean suppliedPath = false; + private boolean suppliedPath = false; /** * The runnable to invoke to actually load the model */ - Consumer loadFunc; + private Consumer loadFunc; + + /** + * Constructor + */ + private QueuedTexture(){ } /** * Creates the queued texture object @@ -84,13 +89,29 @@ public class QueuedTexture implements QueuedAsset { * @param width The width of the buffer * @param height The height of the buffer */ - public QueuedTexture(QueuedTextureType type, ByteBuffer buffer, int width, int height){ + private QueuedTexture(QueuedTextureType type, ByteBuffer buffer, int width, int height){ this.type = type; this.buffer = buffer; this.width = width; this.height = height; } + /** + * Creates a queued texture from a buffer + * @param buffer The buffer + * @param width The width of the buffer + * @param height The height of the buffer + * @return The queued texture + */ + public static QueuedTexture createFromBuffer(ByteBuffer buffer, int width, int height){ + QueuedTexture rVal = new QueuedTexture(); + rVal.type = QueuedTextureType.DATA_BUFF; + rVal.buffer = buffer; + rVal.width = width; + rVal.height = height; + return rVal; + } + /** * Creates the queued texture object * @param image the image to load to gpu @@ -175,6 +196,20 @@ public class QueuedTexture implements QueuedAsset { return rVal; } + /** + * Creates the queued texture object + * @param path The path to the texture file + * @param loadFunc The function to invoke when the texture loads + */ + public static QueuedTexture createFromPath(String path, Consumer loadFunc){ + QueuedTexture rVal = new QueuedTexture(); + rVal.type = QueuedTextureType.IMG_BUFF; + rVal.promisedPath = path; + rVal.loadFunc = loadFunc; + rVal.suppliedPath = true; + return rVal; + } + @Override public void load() { switch(this.type){ @@ -183,7 +218,11 @@ public class QueuedTexture implements QueuedAsset { this.buffer = null; } break; case IMG_BUFF: { - texture = new Texture(Globals.renderingEngine.getOpenGLState(), data, buffer); + if(data != null){ + texture = new Texture(Globals.renderingEngine.getOpenGLState(), data, buffer); + } else if(promisedPath != null){ + texture = new Texture(Globals.renderingEngine.getOpenGLState(), promisedPath); + } } break; } if(this.loadFunc != null){ diff --git a/src/main/java/electrosphere/renderer/RenderUtils.java b/src/main/java/electrosphere/renderer/RenderUtils.java index 0ac7f048..d7352653 100644 --- a/src/main/java/electrosphere/renderer/RenderUtils.java +++ b/src/main/java/electrosphere/renderer/RenderUtils.java @@ -220,7 +220,7 @@ public class RenderUtils { - particleMesh.setMaterial(new Material(AssetDataStrings.TEXTURE_PARTICLE)); + particleMesh.setMaterial(Material.createExisting(AssetDataStrings.TEXTURE_PARTICLE)); @@ -391,8 +391,7 @@ public class RenderUtils { //setup extra structures - Material mat = new Material(); - mat.setDiffuse(AssetDataStrings.TEXTURE_TEAL_TRANSPARENT); + Material mat = Material.createExisting(AssetDataStrings.TEXTURE_TEAL_TRANSPARENT); sphereMesh.setMaterial(mat); sphereMesh.setShader(VisualShader.smartAssembleShader()); openGLState.glBindVertexArray(0); @@ -447,8 +446,7 @@ public class RenderUtils { } //setup extra structures - Material mat = new Material(); - mat.setDiffuse(AssetDataStrings.TEXTURE_TEAL_TRANSPARENT); + Material mat = Material.createExisting(AssetDataStrings.TEXTURE_TEAL_TRANSPARENT); sphereMesh.setMaterial(mat); sphereMesh.setShader(VisualShader.smartAssembleShader()); openGLState.glBindVertexArray(0); @@ -535,8 +533,7 @@ public class RenderUtils { sphereMesh.bufferTextureCoords(texCoords, 2); //setup extra structures - Material mat = new Material(); - mat.setDiffuse(AssetDataStrings.TEXTURE_TEAL_TRANSPARENT); + Material mat = Material.createExisting(AssetDataStrings.TEXTURE_TEAL_TRANSPARENT); sphereMesh.setMaterial(mat); sphereMesh.setShader(VisualShader.smartAssembleShader()); openGLState.glBindVertexArray(0); @@ -623,8 +620,7 @@ public class RenderUtils { cubeMesh.bufferTextureCoords(texCoords, 2); //setup extra structures - Material mat = new Material(); - mat.setDiffuse(AssetDataStrings.TEXTURE_BLOCK_ATLAS); + Material mat = Material.createExisting(AssetDataStrings.TEXTURE_BLOCK_ATLAS); cubeMesh.setMaterial(mat); cubeMesh.setShader(VisualShader.loadSpecificShader(AssetDataStrings.SHADER_BLOCK_SINGLE_VERT, AssetDataStrings.SHADER_BLOCK_SINGLE_FRAG)); openGLState.glBindVertexArray(0); @@ -714,10 +710,7 @@ public class RenderUtils { openGLState.glBindVertexArray(0); m.setParent(rVal); - Material uiMat = new Material(); - Globals.assetManager.addTexturePathtoQueue("/Textures/Fonts/myfont1-harsher.png"); - uiMat.setDiffuse("/Textures/Fonts/myfont1-harsher.png"); - uiMat.setSpecular("/Textures/Fonts/myfont1-harsher.png"); + Material uiMat = Material.create("/Textures/Fonts/myfont1-harsher.png"); m.setMaterial(uiMat); rVal.getMaterials().add(uiMat); @@ -1067,10 +1060,7 @@ public class RenderUtils { openGLState.glBindVertexArray(0); m.setParent(rVal); - Material groundMat = new Material(); - Globals.assetManager.addTexturePathtoQueue("/Textures/Ground/Dirt1.png"); - groundMat.setDiffuse("/Textures/Ground/Dirt1.png"); - groundMat.setSpecular("/Textures/Ground/Dirt1.png"); + Material groundMat = Material.create("/Textures/Ground/Dirt1.png"); m.setMaterial(groundMat); rVal.getMeshes().add(m); @@ -1624,10 +1614,7 @@ public class RenderUtils { openGLState.glBindVertexArray(0); m.setParent(rVal); - Material groundMat = new Material(); - Globals.assetManager.addTexturePathtoQueue("/Textures/Ground/Dirt1.png"); - groundMat.setDiffuse("/Textures/Ground/Dirt1.png"); - groundMat.setSpecular("/Textures/Ground/Dirt1.png"); + Material groundMat = Material.create("/Textures/Ground/Dirt1.png"); m.setMaterial(groundMat); rVal.getMeshes().add(m); diff --git a/src/main/java/electrosphere/renderer/RenderingEngine.java b/src/main/java/electrosphere/renderer/RenderingEngine.java index 84ea2699..26615e35 100644 --- a/src/main/java/electrosphere/renderer/RenderingEngine.java +++ b/src/main/java/electrosphere/renderer/RenderingEngine.java @@ -190,7 +190,7 @@ public class RenderingEngine { /** * The default material */ - private Material materialDefault = new Material(AssetDataStrings.TEXTURE_DEFAULT); + private Material materialDefault = Material.createExisting(AssetDataStrings.TEXTURE_DEFAULT); /** * the current state of the rendering pipeline diff --git a/src/main/java/electrosphere/renderer/actor/instance/TextureInstancedActor.java b/src/main/java/electrosphere/renderer/actor/instance/TextureInstancedActor.java index d7935572..de625621 100644 --- a/src/main/java/electrosphere/renderer/actor/instance/TextureInstancedActor.java +++ b/src/main/java/electrosphere/renderer/actor/instance/TextureInstancedActor.java @@ -69,7 +69,7 @@ public class TextureInstancedActor { protected TextureInstancedActor(String modelPath, String vertexShaderPath, String fragmentShaderPath, Texture dataTexture, int drawCount){ this.modelPath = modelPath; this.material = new Material(); - this.material.setTexturePointer(dataTexture.getTexturePointer()); + this.material.setDiffuse(dataTexture); this.drawCount = drawCount; this.vertexShaderPath = vertexShaderPath; this.fragmentShaderPath = fragmentShaderPath; @@ -126,7 +126,7 @@ public class TextureInstancedActor { Model model = Globals.assetManager.fetchModel(modelPath); VisualShader shader = Globals.assetManager.fetchShader(vertexShaderPath, fragmentShaderPath); if(queuedTexture != null && !setQueuedTexturePointer && queuedTexture.getTexture() != null){ - this.material.setTexturePointer(queuedTexture.getTexture().getTexturePointer()); + this.material.setDiffuse(queuedTexture.getTexture()); setQueuedTexturePointer = true; } if( diff --git a/src/main/java/electrosphere/renderer/loading/ModelLoader.java b/src/main/java/electrosphere/renderer/loading/ModelLoader.java index aa03fce4..f6e0b2ee 100644 --- a/src/main/java/electrosphere/renderer/loading/ModelLoader.java +++ b/src/main/java/electrosphere/renderer/loading/ModelLoader.java @@ -101,7 +101,7 @@ public class ModelLoader { } } } else { - LoggerInterface.loggerRenderer.WARNING("Trying to get textures for model that doesn't have local or global texture map entries! " + path); + // LoggerInterface.loggerRenderer.WARNING("Trying to get textures for model that doesn't have local or global texture map entries! " + path); } } @@ -116,24 +116,16 @@ public class ModelLoader { //set diffuse String diffusePath = meshTextureData.getDiffuse(); LoggerInterface.loggerRenderer.DEBUG(mesh.getMeshName() + "->" + diffusePath); - if(diffusePath != null){ - LoggerInterface.loggerRenderer.DEBUG(diffusePath); - Globals.assetManager.addTexturePathtoQueue(diffusePath); - finalMat.setDiffuse(diffusePath); - LoggerInterface.loggerRenderer.DEBUG(diffusePath); - } else { - finalMat.setDiffuse(AssetDataStrings.TEXTURE_DEFAULT); + if(diffusePath == null){ + diffusePath = AssetDataStrings.TEXTURE_DEFAULT; } //set specular String specularPath = meshTextureData.getSpecular(); - if(specularPath != null){ - Globals.assetManager.addTexturePathtoQueue(specularPath); - finalMat.setSpecular(specularPath); - LoggerInterface.loggerRenderer.DEBUG(specularPath); - } else { - finalMat.setSpecular(AssetDataStrings.TEXTURE_DEFAULT); + if(specularPath == null){ + specularPath = AssetDataStrings.TEXTURE_DEFAULT; } + finalMat = Material.create(diffusePath, specularPath); //once we've either added default textures or actual textures, //set the current mesh's material to this new one mesh.setMaterial(finalMat); diff --git a/src/main/java/electrosphere/renderer/meshgen/BlockMeshgen.java b/src/main/java/electrosphere/renderer/meshgen/BlockMeshgen.java index 372b8f96..2d0d7421 100644 --- a/src/main/java/electrosphere/renderer/meshgen/BlockMeshgen.java +++ b/src/main/java/electrosphere/renderer/meshgen/BlockMeshgen.java @@ -580,9 +580,7 @@ public class BlockMeshgen { Mesh m = BlockMeshgen.generateBlockMesh(Globals.renderingEngine.getOpenGLState(), meshData); //construct the material for the chunk - Material groundMat = new Material(); - groundMat.setTexturePointer(Globals.blockTextureAtlas.getSpecular().getTexturePointer()); - groundMat.setNormalTexturePointer(Globals.blockTextureAtlas.getNormal().getTexturePointer()); + Material groundMat = Material.create(Globals.blockTextureAtlas.getSpecular(), Globals.blockTextureAtlas.getNormal()); m.setMaterial(groundMat); //shader logic diff --git a/src/main/java/electrosphere/renderer/meshgen/FluidChunkModelGeneration.java b/src/main/java/electrosphere/renderer/meshgen/FluidChunkModelGeneration.java index ade05ca6..00fd49c8 100644 --- a/src/main/java/electrosphere/renderer/meshgen/FluidChunkModelGeneration.java +++ b/src/main/java/electrosphere/renderer/meshgen/FluidChunkModelGeneration.java @@ -791,10 +791,7 @@ public class FluidChunkModelGeneration { Mesh m = generateFluidMesh(Globals.renderingEngine.getOpenGLState(),data); - Material groundMat = new Material(); - groundMat.setDiffuse("/Textures/Ground/Dirt1.png"); - groundMat.setSpecular("/Textures/Ground/Dirt1.png"); - Globals.assetManager.addTexturePathtoQueue("/Textures/Ground/Dirt1.png"); + Material groundMat = Material.create("/Textures/Ground/Dirt1.png"); m.setMaterial(groundMat); m.setShader(FluidChunkModelGeneration.fluidChunkShaderProgram); diff --git a/src/main/java/electrosphere/renderer/meshgen/TerrainChunkModelGeneration.java b/src/main/java/electrosphere/renderer/meshgen/TerrainChunkModelGeneration.java index 70cf5931..ad09c4ab 100644 --- a/src/main/java/electrosphere/renderer/meshgen/TerrainChunkModelGeneration.java +++ b/src/main/java/electrosphere/renderer/meshgen/TerrainChunkModelGeneration.java @@ -886,9 +886,7 @@ public class TerrainChunkModelGeneration { Mesh m = TerrainChunkModelGeneration.generateTerrainMesh(Globals.renderingEngine.getOpenGLState(), data); //construct the material for the chunk - Material groundMat = new Material(); - groundMat.setTexturePointer(atlas.getSpecular().getTexturePointer()); - groundMat.setNormalTexturePointer(atlas.getNormal().getTexturePointer()); + Material groundMat = Material.create(atlas.getSpecular(), atlas.getNormal()); m.setMaterial(groundMat); //shader logic diff --git a/src/main/java/electrosphere/renderer/meshgen/TransvoxelModelGeneration.java b/src/main/java/electrosphere/renderer/meshgen/TransvoxelModelGeneration.java index 87bac672..3a6138fd 100644 --- a/src/main/java/electrosphere/renderer/meshgen/TransvoxelModelGeneration.java +++ b/src/main/java/electrosphere/renderer/meshgen/TransvoxelModelGeneration.java @@ -2296,9 +2296,7 @@ public class TransvoxelModelGeneration { Mesh m = TransvoxelModelGeneration.generateTerrainMesh(Globals.renderingEngine.getOpenGLState(), data); //construct the material for the chunk - Material groundMat = new Material(); - groundMat.setTexturePointer(atlas.getSpecular().getTexturePointer()); - groundMat.setNormalTexturePointer(atlas.getNormal().getTexturePointer()); + Material groundMat = Material.create(atlas.getSpecular(), atlas.getNormal()); m.setMaterial(groundMat); //shader logic diff --git a/src/main/java/electrosphere/renderer/model/Material.java b/src/main/java/electrosphere/renderer/model/Material.java index 8900a8b8..045b0267 100644 --- a/src/main/java/electrosphere/renderer/model/Material.java +++ b/src/main/java/electrosphere/renderer/model/Material.java @@ -1,6 +1,7 @@ package electrosphere.renderer.model; import electrosphere.engine.Globals; +import electrosphere.engine.assetmanager.queue.QueuedTexture; import electrosphere.logger.LoggerInterface; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.texture.Texture; @@ -40,35 +41,19 @@ public class Material { /** - * The path of the diffuse texture when using texture lookups + * The diffuse texture */ - private String diffuse; + private Texture diffuse; /** - * The path of the specular texture when using texture lookups + * The specular texture */ - private String specular; + private Texture specular; /** - * Tracks whether this material has transparency or not + * used to continuously poll for an existing texture (that maybe is still being loaded in) to assign to this material */ - public boolean hasTransparency = false; - - /** - * Sets whether this material should get its texture pointers from the assetManager by looking up diffuse and specular paths - * or whether it should have a manually set texturePointer and not look up while binding - */ - private boolean usesFetch = true; - - /** - * texture pointer for the specular - */ - private int texturePointer; - - /** - * texture pointer for the normal - */ - private int normalPointer; + private String existingPath = null; /** * The shininess value @@ -92,11 +77,84 @@ public class Material { } /** - * Creates a material with a diffuse texture - * @param diffuse The path to the diffuse texture + * Creates a material with a supplied diffuse path + * @param diffuse The diffuse path + * @return The material */ - public Material(String diffuse){ - this.diffuse = diffuse; + public static Material create(String diffuse){ + if(diffuse == null){ + throw new Error("Diffuse undefined"); + } + Material rVal = new Material(); + Globals.assetManager.queuedAsset(QueuedTexture.createFromPath(diffuse, (Texture tex) -> { + if(tex == null){ + throw new Error("Failed to load " + diffuse); + } + rVal.diffuse = tex; + })); + return rVal; + } + + /** + * Creates a material with a supplied diffuse path + * @param diffuse The diffuse path + * @return The material + */ + public static Material createExisting(String diffuse){ + if(diffuse == null){ + throw new Error("Diffuse undefined"); + } + Material rVal = new Material(); + rVal.existingPath = diffuse; + return rVal; + } + + /** + * Creates a material with a supplied diffuse and specular path + * @param diffuse The diffuse path + * @param specular The specular path + * @return The material + */ + public static Material create(String diffuse, String specular){ + if(diffuse == null){ + throw new Error("Diffuse undefined"); + } + if(specular == null){ + throw new Error("Diffuse undefined"); + } + Material rVal = new Material(); + Globals.assetManager.queuedAsset(QueuedTexture.createFromPath(diffuse, (Texture tex) -> { + if(tex == null){ + throw new Error("Failed to load " + diffuse); + } + rVal.diffuse = tex; + })); + Globals.assetManager.queuedAsset(QueuedTexture.createFromPath(specular, (Texture tex) -> { + if(tex == null){ + throw new Error("Failed to load " + specular); + } + rVal.specular = tex; + })); + return rVal; + } + + /** + * Creates a material with a supplied diffuse and specular path + * @param diffuse The diffuse path + * @param specular The specular path + * @return The material + */ + public static Material create(Texture diffuse, Texture specular){ + if(diffuse == null){ + throw new Error("Diffuse undefined"); + } + if(specular == null){ + throw new Error("Diffuse undefined"); + } + Material rVal = new Material(); + rVal.diffuse = diffuse; + rVal.specular = specular; + return rVal; } /** @@ -126,12 +184,47 @@ public class Material { texPaths[i] = tex.mFilename().dataString(); } //discover diffuse + boolean discovered = Material.tryDiscoverDiffuse(path,scene,input,texPaths,aiPathString,Assimp.aiTextureType_DIFFUSE,rVal); + if(!discovered){ + discovered = Material.tryDiscoverDiffuse(path,scene,input,texPaths,aiPathString,Assimp.aiTextureType_BASE_COLOR,rVal); + } + if(!discovered){ + discovered = Material.tryDiscoverDiffuse(path,scene,input,texPaths,aiPathString,Assimp.aiTextureType_EMISSIVE,rVal); + } + if(!discovered){ + discovered = Material.tryDiscoverDiffuse(path,scene,input,texPaths,aiPathString,Assimp.aiTextureType_AMBIENT,rVal); + } + if(!discovered){ + discovered = Material.tryDiscoverDiffuse(path,scene,input,texPaths,aiPathString,Assimp.aiTextureType_EMISSION_COLOR,rVal); + } + + if(!discovered){ + LoggerInterface.loggerRenderer.DEBUG("Failed to find diffuse path for mesh in " + path); + } + + //free mem + aiPathString.free(); + + return rVal; + } + + /** + * Tries to discover a material at a given texture type + * @param path The path to the model + * @param scene The scene of the model + * @param input The input material + * @param texPaths The texture paths + * @param aiPathString The ai string buffer + * @param mat The material object + * @return true if a diffuse was found, false otherwise + */ + private static boolean tryDiscoverDiffuse(String path, AIScene scene, AIMaterial input, String[] texPaths, AIString aiPathString, int texType, Material mat){ boolean foundDiffuse = false; - int textureCount = Assimp.aiGetMaterialTextureCount(input, Assimp.aiTextureType_DIFFUSE); + int textureCount = Assimp.aiGetMaterialTextureCount(input, texType); if(textureCount > 0){ //for the time being, only load the first diffuse int textureIndex = 0; - int retCode = Assimp.aiGetMaterialTexture(input, Assimp.aiTextureType_DIFFUSE, textureIndex, aiPathString, (IntBuffer)null, null, null, null, null, null); + int retCode = Assimp.aiGetMaterialTexture(input, texType, textureIndex, aiPathString, (IntBuffer)null, null, null, null, null, null); if(retCode != Assimp.aiReturn_SUCCESS){ throw new Error("Failed to read diffuse! " + textureCount + " " + Assimp.aiGetErrorString()); } @@ -148,64 +241,28 @@ public class Material { } String resolved = Material.resolveTexturePath(path, texPaths[indexInLoadedTexturePaths]); if(resolved != null && resolved.length() > 0){ - rVal.usesFetch = true; - rVal.diffuse = resolved; - Globals.assetManager.addTexturePathtoQueue(rVal.diffuse); + Globals.assetManager.queuedAsset(QueuedTexture.createFromPath(resolved, (Texture tex) -> { + if(tex == null){ + throw new Error("Failed to load " + resolved); + } + mat.diffuse = tex; + })); foundDiffuse = true; } } else { String resolved = Material.resolveTexturePath(path, texturePath); if(resolved != null && resolved.length() > 0){ - rVal.usesFetch = true; - rVal.diffuse = resolved; - Globals.assetManager.addTexturePathtoQueue(rVal.diffuse); + Globals.assetManager.queuedAsset(QueuedTexture.createFromPath(resolved, (Texture tex) -> { + if(tex == null){ + throw new Error("Failed to load " + resolved); + } + mat.diffuse = tex; + })); foundDiffuse = true; } } } - if(!foundDiffuse){ - textureCount = Assimp.aiGetMaterialTextureCount(input, Assimp.aiTextureType_BASE_COLOR); - if(textureCount > 0){ - //for the time being, only load the first diffuse - int textureIndex = 0; - int retCode = Assimp.aiGetMaterialTexture(input, Assimp.aiTextureType_BASE_COLOR, textureIndex, aiPathString, (IntBuffer)null, null, null, null, null, null); - if(retCode != Assimp.aiReturn_SUCCESS){ - throw new Error("Failed to read diffuse! " + textureCount + " " + Assimp.aiGetErrorString()); - } - String texturePath = aiPathString.dataString(); - if(texturePath == null || texturePath.length() <= 0){ - throw new Error("Texture path is empty " + texturePath); - } - if(texturePath.length() == 2 && texturePath.startsWith("*")){ - //older versions of Assimp require you to read the INDEX of the texture from the material, then look up that texture in the scene itself - //format looks like "*" ie "*0" - int indexInLoadedTexturePaths = Integer.parseInt(texturePath.substring(1)); - if(indexInLoadedTexturePaths >= texPaths.length){ - throw new Error("Index discovered is outside the array's length " + indexInLoadedTexturePaths + " " + texPaths.length); - } - String resolved = Material.resolveTexturePath(path, texPaths[indexInLoadedTexturePaths]); - if(resolved != null && resolved.length() > 0){ - rVal.usesFetch = true; - rVal.diffuse = resolved; - Globals.assetManager.addTexturePathtoQueue(rVal.diffuse); - foundDiffuse = true; - } - } else { - String resolved = Material.resolveTexturePath(path, texturePath); - if(resolved != null && resolved.length() > 0){ - rVal.usesFetch = true; - rVal.diffuse = resolved; - Globals.assetManager.addTexturePathtoQueue(rVal.diffuse); - foundDiffuse = true; - } - } - } - } - - //free mem - aiPathString.free(); - - return rVal; + return foundDiffuse; } /** @@ -259,7 +316,7 @@ public class Material { * Gets the path for the diffuse of the material * @return The path for the diffuse texture */ - public String getDiffuse(){ + public Texture getDiffuse(){ return diffuse; } @@ -267,7 +324,7 @@ public class Material { * Gets the path for the specular of the material * @return The path for the specular texture */ - public String getSpecular(){ + public Texture getSpecular(){ return specular; } @@ -275,7 +332,7 @@ public class Material { * Sets the diffuse texture * @param t The texture path */ - public void setDiffuse(String t){ + public void setDiffuse(Texture t){ diffuse = t; } @@ -283,7 +340,7 @@ public class Material { * Sets the specular texture path * @param t The specular texture path */ - public void setSpecular(String t){ + public void setSpecular(Texture t){ specular = t; } @@ -302,24 +359,6 @@ public class Material { public Vector3f getAlbedo(){ return this.albedo; } - - /** - * Sets the texture pointer - * @param pointer The texture pointer - */ - public void setTexturePointer(int pointer){ - texturePointer = pointer; - usesFetch = false; - } - - /** - * Sets the in-material pointer for the normal - * @param pointer the normal texture - */ - public void setNormalTexturePointer(int pointer){ - normalPointer = pointer; - usesFetch = false; - } /** * Reads a float property from a material @@ -347,28 +386,24 @@ public class Material { * Applies the material */ public void applyMaterial(OpenGLState openGLState){ + if(this.existingPath != null){ + Texture tex = Globals.assetManager.fetchTexture(existingPath); + if(tex != null){ + this.diffuse = tex; + this.existingPath = null; + } + } //Controls whether the texturePointer should be resolved by looking up the diffuse in asset manager or using the texture pointer already set in this material - if(usesFetch){ - if(diffuse != null){ - Texture diffuseTexture = Globals.assetManager.fetchTexture(diffuse); - if(diffuseTexture != null){ - diffuseTexture.bind(openGLState,0); - Globals.renderingEngine.checkError(); - openGLState.getActiveShader().setUniform(openGLState, "material.diffuse", 0); - Globals.renderingEngine.checkError(); - } - } - if(specular != null){ - Texture specularTexture = Globals.assetManager.fetchTexture(specular); - if(specularTexture != null){ - specularTexture.bind(openGLState,1); - Globals.renderingEngine.checkError(); - openGLState.getActiveShader().setUniform(openGLState, "material.specular", 1); - Globals.renderingEngine.checkError(); - } - } - } else { - openGLState.glBindTextureUnit(GL45.GL_TEXTURE0, texturePointer, GL45.GL_TEXTURE_2D); + if(diffuse != null){ + diffuse.bind(openGLState,0); + Globals.renderingEngine.checkError(); + openGLState.getActiveShader().setUniform(openGLState, "material.diffuse", 0); + Globals.renderingEngine.checkError(); + } + if(specular != null){ + specular.bind(openGLState,1); + Globals.renderingEngine.checkError(); + openGLState.getActiveShader().setUniform(openGLState, "material.specular", 1); Globals.renderingEngine.checkError(); } //send physical properties @@ -379,31 +414,16 @@ public class Material { openGLState.getActiveShader().setUniform(openGLState, "material.albedo", this.albedo); Globals.renderingEngine.checkError(); } - - /** - * Checks if this material has transparency - * @return true if there is transparency, false otherwise - */ - public boolean isTransparent(){ - boolean rVal = false; - Texture diffuseTexture = Globals.assetManager.fetchTexture(diffuse); - if(diffuseTexture != null && diffuseTexture.isTransparent()){ - rVal = true; - } - Texture specularTexture = Globals.assetManager.fetchTexture(specular); - if(specularTexture != null && specularTexture.isTransparent()){ - rVal = true; - } - return rVal; - } /** * Frees the material */ public void free(){ - GL45.glDeleteTextures(new int[]{ - this.texturePointer, - this.normalPointer, - }); + if(this.diffuse != null){ + GL45.glDeleteTextures(this.diffuse.getTexturePointer()); + } + if(this.specular != null){ + GL45.glDeleteTextures(this.specular.getTexturePointer()); + } } } diff --git a/src/main/java/electrosphere/renderer/model/Model.java b/src/main/java/electrosphere/renderer/model/Model.java index a66cf821..de3638d0 100644 --- a/src/main/java/electrosphere/renderer/model/Model.java +++ b/src/main/java/electrosphere/renderer/model/Model.java @@ -180,11 +180,7 @@ public class Model { //conditionally add material int materialIndex = aiMesh.mMaterialIndex(); if(materialIndex < rVal.materials.size()){ - Material mat = rVal.materials.get(materialIndex); - //only assign if the diffuse is actually set (ie we've actually loaded it properly) - if(mat.getDiffuse() != null){ - currentMesh.setMaterial(rVal.materials.get(materialIndex)); - } + currentMesh.setMaterial(rVal.materials.get(materialIndex)); } } diff --git a/src/main/java/electrosphere/renderer/pipelines/debug/DebugBonesPipeline.java b/src/main/java/electrosphere/renderer/pipelines/debug/DebugBonesPipeline.java index 089d5c53..02ee15cc 100644 --- a/src/main/java/electrosphere/renderer/pipelines/debug/DebugBonesPipeline.java +++ b/src/main/java/electrosphere/renderer/pipelines/debug/DebugBonesPipeline.java @@ -69,7 +69,7 @@ public class DebugBonesPipeline implements RenderPipeline { // Actor targetActor = EntityUtils.getActor(targetEntity); Model boneModel = Globals.assetManager.fetchModel(AssetDataStrings.UNITCYLINDER); - boneModel.getMaterials().get(0).setDiffuse(AssetDataStrings.TEXTURE_DEFAULT); + boneModel.getMaterials().get(0).setDiffuse(Globals.assetManager.fetchTexture(AssetDataStrings.TEXTURE_DEFAULT)); for(Bone bone : targetActor.getBoneValues()){ Vector3d bonePos = MathBones.getBoneWorldPosition(targetEntity, bone.boneID); Quaterniond boneRot = MathBones.getBoneWorldRotation(targetEntity, bone.boneID); diff --git a/src/main/java/electrosphere/renderer/ui/UIUtils.java b/src/main/java/electrosphere/renderer/ui/UIUtils.java index 53459ce4..38a85dc4 100644 --- a/src/main/java/electrosphere/renderer/ui/UIUtils.java +++ b/src/main/java/electrosphere/renderer/ui/UIUtils.java @@ -19,7 +19,7 @@ import electrosphere.renderer.ui.elementtypes.Element; public class UIUtils { //the material that links the texture to draw - static Material customMat = new Material("Textures/ui/uiOutline1.png"); + static Material customMat = Material.createExisting("Textures/ui/uiOutline1.png"); /** * Renders the outline of the provided element and all child elements of the rootEl diff --git a/src/main/java/electrosphere/renderer/ui/elements/BufferedStandardDrawableContainerElement.java b/src/main/java/electrosphere/renderer/ui/elements/BufferedStandardDrawableContainerElement.java index 161b5ff9..fb9555f7 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/BufferedStandardDrawableContainerElement.java +++ b/src/main/java/electrosphere/renderer/ui/elements/BufferedStandardDrawableContainerElement.java @@ -107,7 +107,7 @@ public class BufferedStandardDrawableContainerElement extends StandardDrawableC planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); planeModel.pushUniformToMesh("plane", "tPosition", texPosition); planeModel.pushUniformToMesh("plane", "tDimension", texScale); - elementMat.setTexturePointer(windowFrame.getTexturePointer()); + elementMat.setDiffuse(windowFrame); planeModel.getMeshes().get(0).setMaterial(elementMat); planeModel.drawUI(); } @@ -117,7 +117,7 @@ public class BufferedStandardDrawableContainerElement extends StandardDrawableC planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); planeModel.pushUniformToMesh("plane", "tPosition", texPosition); planeModel.pushUniformToMesh("plane", "tDimension", texScale); - elementMat.setTexturePointer(elementBuffer.getTexture().getTexturePointer()); + elementMat.setDiffuse(elementBuffer.getTexture()); planeModel.getMeshes().get(0).setMaterial(elementMat); planeModel.drawUI(); } else { @@ -148,7 +148,7 @@ public class BufferedStandardDrawableContainerElement extends StandardDrawableC } catch(Exception e){ LoggerInterface.loggerRenderer.ERROR(e); } - elementMat.setTexturePointer(elementBuffer.getTexture().getTexturePointer()); + elementMat.setDiffuse(elementBuffer.getTexture()); } diff --git a/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java b/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java index d2cfffe4..d947e102 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java +++ b/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java @@ -76,10 +76,10 @@ public class ImagePanel extends StandardElement implements DrawableElement, Drag texture = Globals.assetManager.fetchTexture(this.texturePath); } if(texture != null){ - customMat.setTexturePointer(texture.getTexturePointer()); + customMat.setDiffuse(texture); hasLoadedTexture = true; } else if(Globals.assetManager.fetchTexture(AssetDataStrings.TEXTURE_BLACK) != null) { - customMat.setTexturePointer(Globals.assetManager.fetchTexture(AssetDataStrings.TEXTURE_BLACK).getTexturePointer()); + customMat.setDiffuse(Globals.assetManager.fetchTexture(AssetDataStrings.TEXTURE_BLACK)); } } @@ -106,7 +106,7 @@ public class ImagePanel extends StandardElement implements DrawableElement, Drag * @param texture The texture to use */ public void setTexture(Texture texture){ - customMat.setTexturePointer(texture.getTexturePointer()); + customMat.setDiffuse(texture); } /** @@ -137,7 +137,7 @@ public class ImagePanel extends StandardElement implements DrawableElement, Drag Model planeModel = Globals.assetManager.fetchModel(imagePanelModelPath); if(texture != null){ - customMat.setTexturePointer(texture.getTexturePointer()); + customMat.setDiffuse(texture); } else if(this.texturePath != null){ texture = Globals.assetManager.fetchTexture(this.texturePath); } diff --git a/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java b/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java index 685b2eab..df614933 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java +++ b/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java @@ -186,7 +186,7 @@ public class ScrollableContainer extends BufferedStandardDrawableContainerElemen planeModel.pushUniformToMesh("plane", "tPosition", texPosition); planeModel.pushUniformToMesh("plane", "tDimension", texScale); planeModel.pushUniformToMesh(planeModel.getMeshes().get(0).getMeshName(), "color", color); - elementMat.setTexturePointer(elementBuffer.getTexture().getTexturePointer()); + elementMat.setDiffuse(elementBuffer.getTexture()); planeModel.getMeshes().get(0).setMaterial(elementMat); planeModel.drawUI(); } else { diff --git a/src/main/java/electrosphere/renderer/ui/elements/Slider.java b/src/main/java/electrosphere/renderer/ui/elements/Slider.java index 4a5b50e2..bf4bc6fd 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Slider.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Slider.java @@ -87,9 +87,7 @@ public class Slider extends StandardDrawableElement implements ClickableElement, private Slider(){ super(); if(mat == null){ - mat = new Material(); - mat.setDiffuse("Textures/ui/square.png"); - mat.setSpecular("Textures/ui/square.png"); + mat = Material.create("Textures/ui/square.png"); } setWidth(DEFAULT_WIDTH); setHeight(DEFAULT_HEIGHT); @@ -99,9 +97,7 @@ public class Slider extends StandardDrawableElement implements ClickableElement, public Slider(int positionX, int positionY, int width, int height, Vector4f colorBackground, Vector4f colorForeground){ super(); if(mat == null){ - mat = new Material(); - mat.setDiffuse("Textures/ui/square.png"); - mat.setSpecular("Textures/ui/square.png"); + mat = Material.create("Textures/ui/square.png"); } setPositionX(positionX); setPositionY(positionY); diff --git a/src/main/java/electrosphere/renderer/ui/elements/ToggleInput.java b/src/main/java/electrosphere/renderer/ui/elements/ToggleInput.java index f9ab77be..93f0915d 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/ToggleInput.java +++ b/src/main/java/electrosphere/renderer/ui/elements/ToggleInput.java @@ -96,14 +96,10 @@ public class ToggleInput extends StandardDrawableElement implements ClickableEle private ToggleInput(){ //material work if(circleMat == null){ - circleMat = new Material(); - circleMat.setDiffuse("Textures/ui/circle.png"); - circleMat.setSpecular("Textures/ui/circle.png"); + circleMat = Material.create("Textures/ui/circle.png"); } if(barMat == null){ - barMat = new Material(); - barMat.setDiffuse("Textures/ui/square.png"); - barMat.setSpecular("Textures/ui/square.png"); + barMat = Material.create("Textures/ui/square.png"); } this.setWidth(TOGGLE_PIXEL_WIDTH_DEFAULT); diff --git a/src/main/java/electrosphere/renderer/ui/elements/Tooltip.java b/src/main/java/electrosphere/renderer/ui/elements/Tooltip.java index 5232c7b8..a942e9e3 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Tooltip.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Tooltip.java @@ -128,7 +128,7 @@ public class Tooltip extends StandardDrawableContainerElement { planeModel.pushUniformToMesh("plane", "tPosition", texPosition); planeModel.pushUniformToMesh("plane", "tDimension", texScale); planeModel.pushUniformToMesh(planeModel.getMeshes().get(0).getMeshName(), "color", backgroundColor); - customMat.setTexturePointer(windowFrame.getTexturePointer()); + customMat.setDiffuse(windowFrame); planeModel.getMeshes().get(0).setMaterial(customMat); planeModel.drawUI(); } diff --git a/src/main/java/electrosphere/renderer/ui/elements/Window.java b/src/main/java/electrosphere/renderer/ui/elements/Window.java index 44a6eedd..7da0f348 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Window.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Window.java @@ -263,7 +263,7 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme planeModel.pushUniformToMesh("plane", "tPosition", texPosition); planeModel.pushUniformToMesh("plane", "tDimension", texScale); planeModel.pushUniformToMesh(planeModel.getMeshes().get(0).getMeshName(), "color", new Vector4f(1.0f)); - customMat.setTexturePointer(widgetBuffer.getTexture().getTexturePointer()); + customMat.setDiffuse(widgetBuffer.getTexture()); planeModel.getMeshes().get(0).setMaterial(customMat); planeModel.drawUI(); } @@ -315,7 +315,7 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme } catch(Exception e){ LoggerInterface.loggerRenderer.ERROR(e); } - customMat.setTexturePointer(widgetBuffer.getTexture().getTexturePointer()); + customMat.setDiffuse(widgetBuffer.getTexture()); } @Override diff --git a/src/main/java/electrosphere/renderer/ui/font/FontUtils.java b/src/main/java/electrosphere/renderer/ui/font/FontUtils.java index 5ef91203..0ce92bcd 100644 --- a/src/main/java/electrosphere/renderer/ui/font/FontUtils.java +++ b/src/main/java/electrosphere/renderer/ui/font/FontUtils.java @@ -186,7 +186,7 @@ public class FontUtils { //create material with new font image Material uiMat = new Material(); Globals.assetManager.queuedAsset(QueuedTexture.createFromImage(image, (Texture tex) -> { - uiMat.setTexturePointer(tex.getTexturePointer()); + uiMat.setDiffuse(tex); })); @@ -271,7 +271,7 @@ public class FontUtils { //create the bitmap image off of the raw texture data Texture texture = Texture.createBitmap(openGLState, bakedTextureData, TTF_BITMAP_WIDTH, TTF_BITMAP_HEIGHT); - uiMat.setTexturePointer(texture.getTexturePointer()); + uiMat.setDiffuse(texture); //parse the glyphs try(MemoryStack stack = MemoryStack.stackPush()){ diff --git a/src/main/java/electrosphere/renderer/ui/frame/UIFrameUtils.java b/src/main/java/electrosphere/renderer/ui/frame/UIFrameUtils.java index 7a0ab071..82c8981f 100644 --- a/src/main/java/electrosphere/renderer/ui/frame/UIFrameUtils.java +++ b/src/main/java/electrosphere/renderer/ui/frame/UIFrameUtils.java @@ -69,7 +69,7 @@ public class UIFrameUtils { //render background of window if(planeModel != null && windowFrame != null){ //set materials + uniforms - customMat.setTexturePointer(windowFrame.getTexturePointer()); + customMat.setDiffuse(windowFrame); planeModel.getMeshes().get(0).setMaterial(customMat); planeModel.pushUniformToMesh(planeModel.getMeshes().get(0).getMeshName(), "color", color);