package gay.pizza.CavesOfJolk import com.badlogic.gdx.ApplicationAdapter import com.badlogic.gdx.Gdx import com.badlogic.gdx.graphics.* import com.badlogic.gdx.graphics.g2d.BitmapFont import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g3d.* import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute import com.badlogic.gdx.graphics.g3d.attributes.FloatAttribute import com.badlogic.gdx.graphics.g3d.attributes.IntAttribute import com.badlogic.gdx.graphics.g3d.attributes.TextureAttribute import com.badlogic.gdx.graphics.g3d.environment.DirectionalLight import com.badlogic.gdx.graphics.g3d.model.data.* import com.badlogic.gdx.graphics.g3d.shaders.DefaultShader import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder import com.badlogic.gdx.graphics.g3d.utils.TextureDescriptor import com.badlogic.gdx.graphics.g3d.utils.TextureProvider import com.badlogic.gdx.math.* import com.badlogic.gdx.utils.Array import com.badlogic.gdx.utils.ScreenUtils import gay.pizza.CavesOfJolk.Resources.Companion.assetManager class Game: ApplicationAdapter() { private lateinit var texJolk: Texture private lateinit var fntComic: BitmapFont private lateinit var cube: Model private lateinit var floor: Model private lateinit var spriteBatch: SpriteBatch private lateinit var modelBatch: ModelBatch private lateinit var env: Environment private lateinit var colin: Colin private var jolkRot = 0.0f private lateinit var cubeInstance: ModelInstance private lateinit var floorInstance: ModelInstance private lateinit var suzanneInstance: ModelInstance private fun makeCube(texture: Texture): Model { val modelBuilder = ModelBuilder() val size = 2.0f val material = Material( ColorAttribute.createDiffuse(XnaColor.White), TextureAttribute(TextureAttribute.Diffuse, TextureDescriptor(texture, Texture.TextureFilter.Linear, Texture.TextureFilter.Linear, Texture.TextureWrap.ClampToEdge, Texture.TextureWrap.ClampToEdge)), ColorAttribute.createSpecular(XnaColor.Gray), FloatAttribute.createShininess(20.0f)) val attribs = VertexAttributes.Usage.Position or VertexAttributes.Usage.TextureCoordinates or VertexAttributes.Usage.Normal return modelBuilder.createBox(size, size, size, material, attribs.toLong()) } private fun makeFloor(): Model { val model = ModelData() val mesh = ModelMesh() mesh.id = "floormodel" mesh.attributes = arrayOf( VertexAttribute.Position(), VertexAttribute.Normal(), VertexAttribute.Tangent(), VertexAttribute.Binormal(), VertexAttribute.TexCoords(0)) val normal = Vector3(0.0f, 1.0f, 0.0f) val tangent = Vector3(1.0f, 0.0f, 0.0f) val bitangent = Vector3(0.0f, 0.0f, -1.0f) val vertex = { pos: Vector3, tex: Vector2, norm: Vector3, tan: Vector3, bitan: Vector3 -> floatArrayOf( pos.x, pos.y, pos.z, norm.x, norm.y, norm.z, tan.x, tan.y, tan.z, bitan.x, bitan.y, bitan.z, tex.x, tex.y )} val size = 16.0f val texs = 4.0f mesh.vertices = vertex(Vector3(0.0f, 0.0f, 0.0f), Vector2(0.0f, texs), normal, tangent, bitangent) + vertex(Vector3(size, 0.0f, 0.0f), Vector2(texs, texs), normal, tangent, bitangent) + vertex(Vector3(0.0f, 0.0f, -size), Vector2(0.0f, 0.0f), normal, tangent, bitangent) + vertex(Vector3(size, 0.0f, -size), Vector2(texs, 0.0f), normal, tangent, bitangent) val part = ModelMeshPart() part.id = "floormesh" part.primitiveType = GL20.GL_TRIANGLES part.indices = shortArrayOf( 0, 1, 2, 3, 2, 1) mesh.parts = arrayOf(part) model.addMesh(mesh) val material = ModelMaterial() material.id = "floormat" material.diffuse = XnaColor.White material.specular = XnaColor.BlanchedAlmond.mix(XnaColor.Black, 0.4f) material.shininess = 65.0f val diffuse = ModelTexture() diffuse.usage = ModelTexture.USAGE_DIFFUSE diffuse.fileName = "cobblestone.png" val normalMap = ModelTexture() normalMap.usage = ModelTexture.USAGE_NORMAL normalMap.fileName = "cobblestone_normal.png" material.textures = Array() material.textures.add(diffuse, normalMap) model.materials.add(material) val node = ModelNode() node.id = "floornode" node.scale = Vector3(1.0f, 1.0f, 1.0f) node.rotation = Quaternion() val nodePart = ModelNodePart() nodePart.meshPartId = "floormesh" nodePart.materialId = "floormat" node.parts = arrayOf(nodePart) model.nodes.add(node) return Model(model, TextureProvider.FileTextureProvider( Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest, Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat, false)) } override fun create() { Resources.instance.loadAssets() assetManager.finishLoading() texJolk = assetManager.get("jolkmeup.jpg") fntComic = assetManager.get("Comic Sans MS.ttf") val suzanne = assetManager.get("suzanne.g3db", Model::class.java) // Override ridiculous shininess because i cbf to fix the model for (i in suzanne.materials) i.set(FloatAttribute.createShininess(30.0f)) cube = makeCube(texJolk) floor = makeFloor() spriteBatch = SpriteBatch() env = Environment() env.set( IntAttribute.createCullFace(GL20.GL_BACK), ColorAttribute.createAmbientLight(XnaColor.DarkSlateGray.lighten(-0.6)), ColorAttribute.createFog(XnaColor.CornflowerBlue)) env.set( CustomIntAttribute.createFogMode(CustomIntAttribute.FogModes.Depth), CustomIntAttribute.createFogType(CustomIntAttribute.FogTypes.Smooth), CustomFloatAttribute.createFogNear(0.75f), CustomFloatAttribute.createFogFar(20.5f)) /* env.set( CustomIntAttribute.createFogMode(CustomIntAttribute.FogModes.Distance), CustomIntAttribute.createFogType(CustomIntAttribute.FogTypes.Exp2), CustomFloatAttribute.createFogDensity(0.1f)) */ env.add(DirectionalLight().set( XnaColor.BlanchedAlmond.lighten(0.01), Vector3(1.0f, -1.0f, -1.0f).nor())) val shaderConfig = DefaultShader.Config() shaderConfig.numDirectionalLights = 1 shaderConfig.numPointLights = 0 shaderConfig.numBones = 0 modelBatch = ModelBatch(CustomDefaultShaderProvider(shaderConfig)) colin = Colin() cubeInstance = ModelInstance(cube) floorInstance = ModelInstance(floor) suzanneInstance = ModelInstance(suzanne) suzanneInstance.transform = Matrix4().translate(3.0f, 1.0f, -3.5f) } override fun resize(width: Int, height: Int) { colin.resize(width, height) spriteBatch.projectionMatrix.setToOrtho2D(0.0f, 0.0f, Gdx.graphics.getWidth().toFloat(), Gdx.graphics.getHeight().toFloat()); } private fun update(deltaTime: Float) { colin.update(deltaTime) jolkRot += 15.0f * deltaTime } override fun render() { val deltaTime = Gdx.graphics.deltaTime update(deltaTime) ScreenUtils.clear(XnaColor.CornflowerBlue, true) val jolkPos = Vector3(0.0f, 1.0f + MathUtils.sin(jolkRot * 0.25f) * 0.25f, -4.0f) val world = Matrix4() .setTranslation(jolkPos) .rotateRad(1.0f, 0.0f, 0.0f, jolkRot * 0.25f) .rotate(0.0f, 1.0f, 0.0f, jolkRot) .scale(0.25f, 0.25f, 0.25f) cubeInstance.transform = world modelBatch.begin(colin.camera) modelBatch.render(floorInstance, env) modelBatch.render(cubeInstance, env) modelBatch.render(suzanneInstance, env) modelBatch.end() spriteBatch.begin() colin.draw(spriteBatch) val textPos = colin.camera.project(jolkPos) if (textPos.z < 1.0) fntComic.draw(spriteBatch, "I am filled with jolk", textPos.x, textPos.y) fntComic.draw(spriteBatch, "${colin.position.x}\n${colin.position.y}", 10.0f, Gdx.graphics.height - 10.0f) spriteBatch.end() } override fun dispose() { floor.dispose() cube.dispose() modelBatch.dispose() spriteBatch.dispose() assetManager.dispose() } }