├── lib ├── jinput-2.0.5.jar ├── jutils-1.0.0.jar ├── lwjgl-2.9.1.jar ├── slick-util.jar ├── natives │ ├── linux │ │ ├── liblwjgl.so │ │ ├── libopenal.so │ │ ├── liblwjgl64.so │ │ ├── libopenal64.so │ │ ├── libjinput-linux.so │ │ └── libjinput-linux64.so │ ├── windows │ │ ├── lwjgl.dll │ │ ├── OpenAL32.dll │ │ ├── OpenAL64.dll │ │ ├── lwjgl64.dll │ │ ├── jinput-dx8.dll │ │ ├── jinput-raw.dll │ │ ├── jinput-dx8_64.dll │ │ └── jinput-raw_64.dll │ ├── macosx │ │ ├── openal.dylib │ │ ├── liblwjgl.jnilib │ │ └── libjinput-osx.jnilib │ └── solaris │ │ ├── liblwjgl.so │ │ ├── libopenal.so │ │ ├── liblwjgl64.so │ │ └── libopenal64.so ├── lwjgl-platform-2.9.1-natives-osx.jar ├── jinput-platform-2.0.5-natives-osx.jar ├── lwjgl-platform-2.9.1-natives-linux.jar ├── jinput-platform-2.0.5-natives-linux.jar ├── jinput-platform-2.0.5-natives-windows.jar └── lwjgl-platform-2.9.1-natives-windows.jar ├── res ├── bitmaps │ ├── level1.png │ ├── level2.png │ ├── level3.png │ └── levelTest.png ├── textures │ ├── MEDIA0.png │ ├── PISFA0.png │ ├── PISGB0.png │ ├── SSWVA1.png │ ├── SSWVB1.png │ ├── SSWVC1.png │ ├── SSWVD1.png │ ├── SSWVE0.png │ ├── SSWVF0.png │ ├── SSWVG0.png │ ├── SSWVH0.png │ ├── SSWVI0.png │ ├── SSWVJ0.png │ ├── SSWVK0.png │ ├── SSWVL0.png │ ├── SSWVM0.png │ └── WolfCollection.png └── shaders │ ├── basicFragment120.fs │ ├── basicFragment.fs │ ├── basicVertex120.vs │ ├── basicVertex.vs │ ├── phongVertex.vs │ └── phongFragment.fs ├── src └── com │ └── base │ └── engine │ ├── Time.java │ ├── BaseLight.java │ ├── DirectionalLight.java │ ├── Attenuation.java │ ├── BasicShader.java │ ├── SpotLight.java │ ├── Game.java │ ├── Vertex.java │ ├── PointLight.java │ ├── RenderUtil.java │ ├── Window.java │ ├── Material.java │ ├── Bitmap.java │ ├── Quaternion.java │ ├── Vector2f.java │ ├── Util.java │ ├── Medkit.java │ ├── MainComponent.java │ ├── Texture.java │ ├── Transform.java │ ├── Vector3f.java │ ├── Camera.java │ ├── Shader.java │ ├── Door.java │ ├── Matrix4f.java │ ├── Mesh.java │ ├── PhongShader.java │ ├── Player.java │ ├── Input.java │ ├── Monster.java │ └── Level.java ├── .gitattributes └── .gitignore /lib/jinput-2.0.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/jinput-2.0.5.jar -------------------------------------------------------------------------------- /lib/jutils-1.0.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/jutils-1.0.0.jar -------------------------------------------------------------------------------- /lib/lwjgl-2.9.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/lwjgl-2.9.1.jar -------------------------------------------------------------------------------- /lib/slick-util.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/slick-util.jar -------------------------------------------------------------------------------- /res/bitmaps/level1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/res/bitmaps/level1.png -------------------------------------------------------------------------------- /res/bitmaps/level2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/res/bitmaps/level2.png -------------------------------------------------------------------------------- /res/bitmaps/level3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/res/bitmaps/level3.png -------------------------------------------------------------------------------- /res/bitmaps/levelTest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/res/bitmaps/levelTest.png -------------------------------------------------------------------------------- /res/textures/MEDIA0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/res/textures/MEDIA0.png -------------------------------------------------------------------------------- /res/textures/PISFA0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/res/textures/PISFA0.png -------------------------------------------------------------------------------- /res/textures/PISGB0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/res/textures/PISGB0.png -------------------------------------------------------------------------------- /res/textures/SSWVA1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/res/textures/SSWVA1.png -------------------------------------------------------------------------------- /res/textures/SSWVB1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/res/textures/SSWVB1.png -------------------------------------------------------------------------------- /res/textures/SSWVC1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/res/textures/SSWVC1.png -------------------------------------------------------------------------------- /res/textures/SSWVD1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/res/textures/SSWVD1.png -------------------------------------------------------------------------------- /res/textures/SSWVE0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/res/textures/SSWVE0.png -------------------------------------------------------------------------------- /res/textures/SSWVF0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/res/textures/SSWVF0.png -------------------------------------------------------------------------------- /res/textures/SSWVG0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/res/textures/SSWVG0.png -------------------------------------------------------------------------------- /res/textures/SSWVH0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/res/textures/SSWVH0.png -------------------------------------------------------------------------------- /res/textures/SSWVI0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/res/textures/SSWVI0.png -------------------------------------------------------------------------------- /res/textures/SSWVJ0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/res/textures/SSWVJ0.png -------------------------------------------------------------------------------- /res/textures/SSWVK0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/res/textures/SSWVK0.png -------------------------------------------------------------------------------- /res/textures/SSWVL0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/res/textures/SSWVL0.png -------------------------------------------------------------------------------- /res/textures/SSWVM0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/res/textures/SSWVM0.png -------------------------------------------------------------------------------- /lib/natives/linux/liblwjgl.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/natives/linux/liblwjgl.so -------------------------------------------------------------------------------- /lib/natives/linux/libopenal.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/natives/linux/libopenal.so -------------------------------------------------------------------------------- /lib/natives/windows/lwjgl.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/natives/windows/lwjgl.dll -------------------------------------------------------------------------------- /lib/natives/linux/liblwjgl64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/natives/linux/liblwjgl64.so -------------------------------------------------------------------------------- /lib/natives/linux/libopenal64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/natives/linux/libopenal64.so -------------------------------------------------------------------------------- /lib/natives/macosx/openal.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/natives/macosx/openal.dylib -------------------------------------------------------------------------------- /lib/natives/solaris/liblwjgl.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/natives/solaris/liblwjgl.so -------------------------------------------------------------------------------- /lib/natives/solaris/libopenal.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/natives/solaris/libopenal.so -------------------------------------------------------------------------------- /lib/natives/windows/OpenAL32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/natives/windows/OpenAL32.dll -------------------------------------------------------------------------------- /lib/natives/windows/OpenAL64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/natives/windows/OpenAL64.dll -------------------------------------------------------------------------------- /lib/natives/windows/lwjgl64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/natives/windows/lwjgl64.dll -------------------------------------------------------------------------------- /res/textures/WolfCollection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/res/textures/WolfCollection.png -------------------------------------------------------------------------------- /lib/natives/macosx/liblwjgl.jnilib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/natives/macosx/liblwjgl.jnilib -------------------------------------------------------------------------------- /lib/natives/solaris/liblwjgl64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/natives/solaris/liblwjgl64.so -------------------------------------------------------------------------------- /lib/natives/solaris/libopenal64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/natives/solaris/libopenal64.so -------------------------------------------------------------------------------- /lib/natives/windows/jinput-dx8.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/natives/windows/jinput-dx8.dll -------------------------------------------------------------------------------- /lib/natives/windows/jinput-raw.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/natives/windows/jinput-raw.dll -------------------------------------------------------------------------------- /lib/natives/linux/libjinput-linux.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/natives/linux/libjinput-linux.so -------------------------------------------------------------------------------- /lib/natives/windows/jinput-dx8_64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/natives/windows/jinput-dx8_64.dll -------------------------------------------------------------------------------- /lib/natives/windows/jinput-raw_64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/natives/windows/jinput-raw_64.dll -------------------------------------------------------------------------------- /lib/lwjgl-platform-2.9.1-natives-osx.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/lwjgl-platform-2.9.1-natives-osx.jar -------------------------------------------------------------------------------- /lib/natives/linux/libjinput-linux64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/natives/linux/libjinput-linux64.so -------------------------------------------------------------------------------- /lib/natives/macosx/libjinput-osx.jnilib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/natives/macosx/libjinput-osx.jnilib -------------------------------------------------------------------------------- /lib/jinput-platform-2.0.5-natives-osx.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/jinput-platform-2.0.5-natives-osx.jar -------------------------------------------------------------------------------- /lib/lwjgl-platform-2.9.1-natives-linux.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/lwjgl-platform-2.9.1-natives-linux.jar -------------------------------------------------------------------------------- /lib/jinput-platform-2.0.5-natives-linux.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/jinput-platform-2.0.5-natives-linux.jar -------------------------------------------------------------------------------- /lib/jinput-platform-2.0.5-natives-windows.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/jinput-platform-2.0.5-natives-windows.jar -------------------------------------------------------------------------------- /lib/lwjgl-platform-2.9.1-natives-windows.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BennyQBD/Wolfenstein3DClone/HEAD/lib/lwjgl-platform-2.9.1-natives-windows.jar -------------------------------------------------------------------------------- /res/shaders/basicFragment120.fs: -------------------------------------------------------------------------------- 1 | #version 120 2 | 3 | varying vec2 texCoord0; 4 | 5 | uniform vec3 color; 6 | uniform sampler2D sampler; 7 | 8 | void main() 9 | { 10 | gl_FragColor = texture2D(sampler, texCoord0.xy) * vec4(color, 1); 11 | } 12 | -------------------------------------------------------------------------------- /res/shaders/basicFragment.fs: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | in vec2 texCoord0; 4 | 5 | out vec4 fragColor; 6 | 7 | uniform vec3 color; 8 | uniform sampler2D sampler; 9 | 10 | void main() 11 | { 12 | fragColor = texture(sampler, texCoord0.xy) * vec4(color, 1); 13 | } -------------------------------------------------------------------------------- /res/shaders/basicVertex120.vs: -------------------------------------------------------------------------------- 1 | #version 120 2 | 3 | attribute vec3 position; 4 | attribute vec2 texCoord; 5 | 6 | varying vec2 texCoord0; 7 | 8 | uniform mat4 transform; 9 | 10 | void main() 11 | { 12 | gl_Position = transform * vec4(position, 1.0); 13 | texCoord0 = texCoord; 14 | } -------------------------------------------------------------------------------- /res/shaders/basicVertex.vs: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | layout (location = 0) in vec3 position; 4 | layout (location = 1) in vec2 texCoord; 5 | 6 | out vec2 texCoord0; 7 | 8 | uniform mat4 transform; 9 | 10 | void main() 11 | { 12 | gl_Position = transform * vec4(position, 1.0); 13 | texCoord0 = texCoord; 14 | } -------------------------------------------------------------------------------- /src/com/base/engine/Time.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | public class Time 4 | { 5 | public static final long SECOND = 1000000000L; 6 | 7 | private static double delta; 8 | 9 | public static long getTime() 10 | { 11 | return System.nanoTime(); 12 | } 13 | 14 | public static double getDelta() 15 | { 16 | return delta; 17 | } 18 | 19 | public static void setDelta(double delta) 20 | { 21 | Time.delta = delta; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /res/shaders/phongVertex.vs: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | layout (location = 0) in vec3 position; 4 | layout (location = 1) in vec2 texCoord; 5 | layout (location = 2) in vec3 normal; 6 | 7 | out vec2 texCoord0; 8 | out vec3 normal0; 9 | out vec3 worldPos0; 10 | 11 | uniform mat4 transform; 12 | uniform mat4 transformProjected; 13 | 14 | void main() 15 | { 16 | gl_Position = transformProjected * vec4(position, 1.0); 17 | texCoord0 = texCoord; 18 | normal0 = (transform * vec4(normal, 0.0)).xyz; 19 | worldPos0 = (transform * vec4(position, 1.0)).xyz; 20 | } -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /src/com/base/engine/BaseLight.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | public class BaseLight 4 | { 5 | private Vector3f color; 6 | private float intensity; 7 | 8 | public BaseLight(Vector3f color, float intensity) 9 | { 10 | this.color = color; 11 | this.intensity = intensity; 12 | } 13 | 14 | public Vector3f getColor() 15 | { 16 | return color; 17 | } 18 | 19 | public void setColor(Vector3f color) 20 | { 21 | this.color = color; 22 | } 23 | 24 | public float getIntensity() 25 | { 26 | return intensity; 27 | } 28 | 29 | public void setIntensity(float intensity) 30 | { 31 | this.intensity = intensity; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/com/base/engine/DirectionalLight.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | public class DirectionalLight 4 | { 5 | private BaseLight base; 6 | private Vector3f direction; 7 | 8 | public DirectionalLight(BaseLight base, Vector3f direction) 9 | { 10 | this.base = base; 11 | this.direction = direction.normalized(); 12 | } 13 | 14 | public BaseLight getBase() 15 | { 16 | return base; 17 | } 18 | 19 | public void setBase(BaseLight base) 20 | { 21 | this.base = base; 22 | } 23 | 24 | public Vector3f getDirection() 25 | { 26 | return direction; 27 | } 28 | 29 | public void setDirection(Vector3f direction) 30 | { 31 | this.direction = direction.normalized(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/com/base/engine/Attenuation.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | public class Attenuation 4 | { 5 | private float constant; 6 | private float linear; 7 | private float exponent; 8 | 9 | public Attenuation(float constant, float linear, float exponent) 10 | { 11 | this.constant = constant; 12 | this.linear = linear; 13 | this.exponent = exponent; 14 | } 15 | 16 | public float getConstant() 17 | { 18 | return constant; 19 | } 20 | public void setConstant(float constant) 21 | { 22 | this.constant = constant; 23 | } 24 | public float getLinear() 25 | { 26 | return linear; 27 | } 28 | public void setLinear(float linear) 29 | { 30 | this.linear = linear; 31 | } 32 | public float getExponent() 33 | { 34 | return exponent; 35 | } 36 | public void setExponent(float exponent) 37 | { 38 | this.exponent = exponent; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/com/base/engine/BasicShader.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | public class BasicShader extends Shader 4 | { 5 | private static final BasicShader instance = new BasicShader(); 6 | 7 | public static BasicShader getInstance() 8 | { 9 | return instance; 10 | } 11 | 12 | private BasicShader() 13 | { 14 | super(); 15 | 16 | addVertexShaderFromFile("basicVertex120.vs"); 17 | addFragmentShaderFromFile("basicFragment120.fs"); 18 | compileShader(); 19 | 20 | addUniform("transform"); 21 | addUniform("color"); 22 | } 23 | 24 | public void updateUniforms(Matrix4f worldMatrix, Matrix4f projectedMatrix, Material material) 25 | { 26 | if(material.getTexture() != null) 27 | material.getTexture().bind(); 28 | else 29 | RenderUtil.unbindTextures(); 30 | 31 | setUniform("transform", projectedMatrix); 32 | setUniform("color", material.getColor()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/com/base/engine/SpotLight.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | public class SpotLight 4 | { 5 | private PointLight pointLight; 6 | private Vector3f direction; 7 | private float cutoff; 8 | 9 | public SpotLight(PointLight pointLight, Vector3f direction, float cutoff) 10 | { 11 | this.pointLight = pointLight; 12 | this.direction = direction.normalized(); 13 | this.cutoff = cutoff; 14 | } 15 | 16 | public PointLight getPointLight() 17 | { 18 | return pointLight; 19 | } 20 | 21 | public void setPointLight(PointLight pointLight) 22 | { 23 | this.pointLight = pointLight; 24 | } 25 | 26 | public Vector3f getDirection() 27 | { 28 | return direction; 29 | } 30 | public void setDirection(Vector3f direction) 31 | { 32 | this.direction = direction.normalized(); 33 | } 34 | public float getCutoff() 35 | { 36 | return cutoff; 37 | } 38 | public void setCutoff(float cutoff) 39 | { 40 | this.cutoff = cutoff; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/com/base/engine/Game.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | public class Game 4 | { 5 | private static Level level; 6 | private static boolean isRunning; 7 | private static int levelNum = 0; 8 | 9 | public Game() 10 | { 11 | loadNextLevel(); 12 | } 13 | 14 | public void input() 15 | { 16 | level.input(); 17 | } 18 | 19 | public void update() 20 | { 21 | if(isRunning) 22 | level.update(); 23 | } 24 | 25 | public void render() 26 | { 27 | if(isRunning) 28 | level.render(); 29 | } 30 | 31 | public static void loadNextLevel() 32 | { 33 | levelNum++; 34 | level = new Level("level" + levelNum + ".png", "WolfCollection.png"); 35 | 36 | Transform.setProjection(70, Window.getWidth(), Window.getHeight(), 0.01f, 1000f); 37 | Transform.setCamera(level.getPlayer().getCamera()); 38 | isRunning = true; 39 | } 40 | 41 | public static Level getLevel() 42 | { 43 | return level; 44 | } 45 | 46 | public static void setIsRunning(boolean value) 47 | { 48 | isRunning = value; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/com/base/engine/Vertex.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | public class Vertex 4 | { 5 | public static final int SIZE = 8; 6 | 7 | private Vector3f pos; 8 | private Vector2f texCoord; 9 | private Vector3f normal; 10 | 11 | public Vertex(Vector3f pos) 12 | { 13 | this(pos, new Vector2f(0,0)); 14 | } 15 | 16 | public Vertex(Vector3f pos, Vector2f texCoord) 17 | { 18 | this(pos, texCoord, new Vector3f(0,0,0)); 19 | } 20 | 21 | public Vertex(Vector3f pos, Vector2f texCoord, Vector3f normal) 22 | { 23 | this.pos = pos; 24 | this.texCoord = texCoord; 25 | this.normal = normal; 26 | } 27 | 28 | public Vector3f getPos() 29 | { 30 | return pos; 31 | } 32 | 33 | public void setPos(Vector3f pos) 34 | { 35 | this.pos = pos; 36 | } 37 | 38 | public Vector2f getTexCoord() 39 | { 40 | return texCoord; 41 | } 42 | 43 | public void setTexCoord(Vector2f texCoord) 44 | { 45 | this.texCoord = texCoord; 46 | } 47 | 48 | public Vector3f getNormal() 49 | { 50 | return normal; 51 | } 52 | 53 | public void setNormal(Vector3f normal) 54 | { 55 | this.normal = normal; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/com/base/engine/PointLight.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | public class PointLight 4 | { 5 | private BaseLight baseLight; 6 | private Attenuation atten; 7 | private Vector3f position; 8 | private float range; 9 | 10 | public PointLight(BaseLight baseLight, Attenuation atten, Vector3f position, float range) 11 | { 12 | this.baseLight = baseLight; 13 | this.atten = atten; 14 | this.position = position; 15 | this.range = range; 16 | } 17 | 18 | public BaseLight getBaseLight() 19 | { 20 | return baseLight; 21 | } 22 | public void setBaseLight(BaseLight baseLight) 23 | { 24 | this.baseLight = baseLight; 25 | } 26 | public Attenuation getAtten() 27 | { 28 | return atten; 29 | } 30 | public void setAtten(Attenuation atten) 31 | { 32 | this.atten = atten; 33 | } 34 | public Vector3f getPosition() 35 | { 36 | return position; 37 | } 38 | public void setPosition(Vector3f position) 39 | { 40 | this.position = position; 41 | } 42 | 43 | public float getRange() 44 | { 45 | return range; 46 | } 47 | 48 | public void setRange(float range) 49 | { 50 | this.range = range; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/com/base/engine/RenderUtil.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | import static org.lwjgl.opengl.GL11.*; 4 | import static org.lwjgl.opengl.GL32.GL_DEPTH_CLAMP; 5 | 6 | public class RenderUtil 7 | { 8 | public static void clearScreen() 9 | { 10 | //TODO: Stencil Buffer 11 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 12 | } 13 | 14 | public static void setTextures(boolean enabled) 15 | { 16 | if(enabled) 17 | glEnable(GL_TEXTURE_2D); 18 | else 19 | glDisable(GL_TEXTURE_2D); 20 | } 21 | 22 | public static void unbindTextures() 23 | { 24 | glBindTexture(GL_TEXTURE_2D, 0); 25 | } 26 | 27 | public static void setClearColor(Vector3f color) 28 | { 29 | glClearColor(color.getX(), color.getY(), color.getZ(), 1.0f); 30 | } 31 | 32 | public static void initGraphics() 33 | { 34 | glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 35 | 36 | glFrontFace(GL_CW); 37 | glCullFace(GL_BACK); 38 | glEnable(GL_CULL_FACE); 39 | glEnable(GL_DEPTH_TEST); 40 | 41 | glEnable (GL_BLEND); 42 | glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 43 | 44 | glEnable(GL_DEPTH_CLAMP); 45 | 46 | glEnable(GL_TEXTURE_2D); 47 | } 48 | 49 | public static String getOpenGLVersion() 50 | { 51 | return glGetString(GL_VERSION); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/com/base/engine/Window.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | import org.lwjgl.LWJGLException; 4 | import org.lwjgl.input.Keyboard; 5 | import org.lwjgl.input.Mouse; 6 | import org.lwjgl.opengl.Display; 7 | import org.lwjgl.opengl.DisplayMode; 8 | 9 | public class Window 10 | { 11 | public static void createWindow(int width, int height, String title) 12 | { 13 | Display.setTitle(title); 14 | try 15 | { 16 | Display.setDisplayMode(new DisplayMode(width, height)); 17 | Display.create(); 18 | Keyboard.create(); 19 | Mouse.create(); 20 | } 21 | catch (LWJGLException e) 22 | { 23 | e.printStackTrace(); 24 | } 25 | } 26 | 27 | public static void render() 28 | { 29 | Display.update(); 30 | } 31 | 32 | public static void dispose() 33 | { 34 | Display.destroy(); 35 | Keyboard.destroy(); 36 | Mouse.destroy(); 37 | } 38 | 39 | public static boolean isCloseRequested() 40 | { 41 | return Display.isCloseRequested(); 42 | } 43 | 44 | public static int getWidth() 45 | { 46 | return Display.getDisplayMode().getWidth(); 47 | } 48 | 49 | public static int getHeight() 50 | { 51 | return Display.getDisplayMode().getHeight(); 52 | } 53 | 54 | public static String getTitle() 55 | { 56 | return Display.getTitle(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/com/base/engine/Material.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | public class Material 4 | { 5 | private Texture texture; 6 | private Vector3f color; 7 | private float specularIntensity; 8 | private float specularPower; 9 | 10 | public Material(Texture texture) 11 | { 12 | this(texture, new Vector3f(1,1,1)); 13 | } 14 | 15 | public Material(Texture texture, Vector3f color) 16 | { 17 | this(texture, color, 2, 32); 18 | } 19 | 20 | public Material(Texture texture, Vector3f color, float specularIntensity, float specularPower) 21 | { 22 | this.texture = texture; 23 | this.color = color; 24 | this.specularIntensity = specularIntensity; 25 | this.specularPower = specularPower; 26 | } 27 | 28 | public Texture getTexture() 29 | { 30 | return texture; 31 | } 32 | 33 | public void setTexture(Texture texture) 34 | { 35 | this.texture = texture; 36 | } 37 | 38 | public Vector3f getColor() 39 | { 40 | return color; 41 | } 42 | 43 | public void setColor(Vector3f color) 44 | { 45 | this.color = color; 46 | } 47 | 48 | public float getSpecularIntensity() 49 | { 50 | return specularIntensity; 51 | } 52 | 53 | public void setSpecularIntensity(float specularIntensity) 54 | { 55 | this.specularIntensity = specularIntensity; 56 | } 57 | 58 | public float getSpecularPower() 59 | { 60 | return specularPower; 61 | } 62 | 63 | public void setSpecularPower(float specularPower) 64 | { 65 | this.specularPower = specularPower; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/com/base/engine/Bitmap.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | import java.awt.image.BufferedImage; 4 | import java.io.File; 5 | import java.io.IOException; 6 | 7 | import javax.imageio.ImageIO; 8 | 9 | public class Bitmap 10 | { 11 | private int width; 12 | private int height; 13 | private int[] pixels; 14 | 15 | public Bitmap(String fileName) 16 | { 17 | try 18 | { 19 | BufferedImage image = ImageIO.read(new File("./res/bitmaps/" + fileName)); 20 | 21 | width = image.getWidth(); 22 | height = image.getHeight(); 23 | 24 | pixels = new int[width * height]; 25 | image.getRGB(0, 0, width, height, pixels, 0, width); 26 | } 27 | catch(IOException e) 28 | { 29 | // TODO Auto-generated catch block 30 | e.printStackTrace(); 31 | } 32 | } 33 | 34 | public Bitmap(int width, int height) 35 | { 36 | this.width = width; 37 | this.height = height; 38 | this.pixels = new int[width * height]; 39 | } 40 | 41 | public Bitmap flipX() 42 | { 43 | int[] temp = new int[pixels.length]; 44 | 45 | for(int i = 0; i < width; i++) 46 | for(int j = 0; j < height; j++) 47 | temp[i + j * width] = pixels[(width - i - 1) + j * width]; 48 | 49 | pixels = temp; 50 | 51 | return this; 52 | } 53 | 54 | public Bitmap flipY() 55 | { 56 | int[] temp = new int[pixels.length]; 57 | 58 | for(int i = 0; i < width; i++) 59 | for(int j = 0; j < height; j++) 60 | temp[i + j * width] = pixels[i + (height - j - 1) * width]; 61 | 62 | pixels = temp; 63 | 64 | return this; 65 | } 66 | 67 | public int getWidth() 68 | { 69 | return width; 70 | } 71 | 72 | public int getHeight() 73 | { 74 | return height; 75 | } 76 | 77 | public int[] getPixels() 78 | { 79 | return pixels; 80 | } 81 | 82 | public int getPixel(int x, int y) 83 | { 84 | return pixels[x + y * width]; 85 | } 86 | 87 | public void setPixel(int x, int y, int value) 88 | { 89 | pixels[x + y * width] = value; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/com/base/engine/Quaternion.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | public class Quaternion 4 | { 5 | private float x; 6 | private float y; 7 | private float z; 8 | private float w; 9 | 10 | public Quaternion(float x, float y, float z, float w) 11 | { 12 | this.x = x; 13 | this.y = y; 14 | this.z = z; 15 | this.w = w; 16 | } 17 | 18 | public float length() 19 | { 20 | return (float)Math.sqrt(x * x + y * y + z * z + w * w); 21 | } 22 | 23 | public Quaternion normalize() 24 | { 25 | float length = length(); 26 | 27 | return new Quaternion(x / length, y / length, z / length, w / length); 28 | } 29 | 30 | public Quaternion conjugate() 31 | { 32 | return new Quaternion(-x, -y, -z, w); 33 | } 34 | 35 | public Quaternion mul(Quaternion r) 36 | { 37 | float w_ = w * r.getW() - x * r.getX() - y * r.getY() - z * r.getZ(); 38 | float x_ = x * r.getW() + w * r.getX() + y * r.getZ() - z * r.getY(); 39 | float y_ = y * r.getW() + w * r.getY() + z * r.getX() - x * r.getZ(); 40 | float z_ = z * r.getW() + w * r.getZ() + x * r.getY() - y * r.getX(); 41 | 42 | return new Quaternion(x_, y_, z_, w_); 43 | } 44 | 45 | public Quaternion mul(Vector3f r) 46 | { 47 | float w_ = -x * r.getX() - y * r.getY() - z * r.getZ(); 48 | float x_ = w * r.getX() + y * r.getZ() - z * r.getY(); 49 | float y_ = w * r.getY() + z * r.getX() - x * r.getZ(); 50 | float z_ = w * r.getZ() + x * r.getY() - y * r.getX(); 51 | 52 | return new Quaternion(x_, y_, z_, w_); 53 | } 54 | 55 | public float getX() 56 | { 57 | return x; 58 | } 59 | 60 | public void setX(float x) 61 | { 62 | this.x = x; 63 | } 64 | 65 | public float getY() 66 | { 67 | return y; 68 | } 69 | 70 | public void setY(float y) 71 | { 72 | this.y = y; 73 | } 74 | 75 | public float getZ() 76 | { 77 | return z; 78 | } 79 | 80 | public void setZ(float z) 81 | { 82 | this.z = z; 83 | } 84 | 85 | public float getW() 86 | { 87 | return w; 88 | } 89 | 90 | public void setW(float w) 91 | { 92 | this.w = w; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/com/base/engine/Vector2f.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | public class Vector2f 4 | { 5 | private float x; 6 | private float y; 7 | 8 | public Vector2f(float x, float y) 9 | { 10 | this.x = x; 11 | this.y = y; 12 | } 13 | 14 | public float length() 15 | { 16 | return (float)Math.sqrt(x * x + y * y); 17 | } 18 | 19 | public float dot(Vector2f r) 20 | { 21 | return x * r.getX() + y * r.getY(); 22 | } 23 | 24 | public Vector2f normalized() 25 | { 26 | float length = length(); 27 | 28 | return new Vector2f(x / length, y / length); 29 | } 30 | 31 | public Vector2f rotate(float angle) 32 | { 33 | double rad = Math.toRadians(angle); 34 | double cos = Math.cos(rad); 35 | double sin = Math.sin(rad); 36 | 37 | return new Vector2f((float)(x * cos - y * sin),(float)(x * sin + y * cos)); 38 | } 39 | 40 | public Vector2f add(Vector2f r) 41 | { 42 | return new Vector2f(x + r.getX(), y + r.getY()); 43 | } 44 | 45 | public Vector2f add(float r) 46 | { 47 | return new Vector2f(x + r, y + r); 48 | } 49 | 50 | public Vector2f sub(Vector2f r) 51 | { 52 | return new Vector2f(x - r.getX(), y - r.getY()); 53 | } 54 | 55 | public Vector2f sub(float r) 56 | { 57 | return new Vector2f(x - r, y - r); 58 | } 59 | 60 | public Vector2f mul(Vector2f r) 61 | { 62 | return new Vector2f(x * r.getX(), y * r.getY()); 63 | } 64 | 65 | public Vector2f mul(float r) 66 | { 67 | return new Vector2f(x * r, y * r); 68 | } 69 | 70 | public Vector2f div(Vector2f r) 71 | { 72 | return new Vector2f(x / r.getX(), y / r.getY()); 73 | } 74 | 75 | public Vector2f div(float r) 76 | { 77 | return new Vector2f(x / r, y / r); 78 | } 79 | 80 | public Vector2f abs() 81 | { 82 | return new Vector2f(Math.abs(x), Math.abs(y)); 83 | } 84 | 85 | public String toString() 86 | { 87 | return "(" + x + " " + y + ")"; 88 | } 89 | 90 | public float getX() 91 | { 92 | return x; 93 | } 94 | 95 | public void setX(float x) 96 | { 97 | this.x = x; 98 | } 99 | 100 | public float getY() 101 | { 102 | return y; 103 | } 104 | 105 | public void setY(float y) 106 | { 107 | this.y = y; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/com/base/engine/Util.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | import java.nio.ByteBuffer; 4 | import java.nio.FloatBuffer; 5 | import java.nio.IntBuffer; 6 | import java.util.ArrayList; 7 | 8 | import org.lwjgl.BufferUtils; 9 | 10 | public class Util 11 | { 12 | public static FloatBuffer createFloatBuffer(int size) 13 | { 14 | return BufferUtils.createFloatBuffer(size); 15 | } 16 | 17 | public static IntBuffer createIntBuffer(int size) 18 | { 19 | return BufferUtils.createIntBuffer(size); 20 | } 21 | 22 | public static ByteBuffer createByteBuffer(int size) 23 | { 24 | return BufferUtils.createByteBuffer(size); 25 | } 26 | 27 | public static IntBuffer createFlippedBuffer(int... values) 28 | { 29 | IntBuffer buffer = createIntBuffer(values.length); 30 | buffer.put(values); 31 | buffer.flip(); 32 | 33 | return buffer; 34 | } 35 | 36 | public static FloatBuffer createFlippedBuffer(Vertex[] vertices) 37 | { 38 | FloatBuffer buffer = createFloatBuffer(vertices.length * Vertex.SIZE); 39 | 40 | for(int i = 0; i < vertices.length; i++) 41 | { 42 | buffer.put(vertices[i].getPos().getX()); 43 | buffer.put(vertices[i].getPos().getY()); 44 | buffer.put(vertices[i].getPos().getZ()); 45 | buffer.put(vertices[i].getTexCoord().getX()); 46 | buffer.put(vertices[i].getTexCoord().getY()); 47 | buffer.put(vertices[i].getNormal().getX()); 48 | buffer.put(vertices[i].getNormal().getY()); 49 | buffer.put(vertices[i].getNormal().getZ()); 50 | } 51 | 52 | buffer.flip(); 53 | 54 | return buffer; 55 | } 56 | 57 | public static FloatBuffer createFlippedBuffer(Matrix4f value) 58 | { 59 | FloatBuffer buffer = createFloatBuffer(4 * 4); 60 | 61 | for(int i = 0; i < 4; i++) 62 | for(int j = 0; j < 4; j++) 63 | buffer.put(value.get(i, j)); 64 | 65 | buffer.flip(); 66 | 67 | return buffer; 68 | } 69 | 70 | public static String[] removeEmptyStrings(String[] data) 71 | { 72 | ArrayList result = new ArrayList(); 73 | 74 | for(int i = 0; i < data.length; i++) 75 | if(!data[i].equals("")) 76 | result.add(data[i]); 77 | 78 | String[] res = new String[result.size()]; 79 | result.toArray(res); 80 | 81 | return res; 82 | } 83 | 84 | public static int[] toIntArray(Integer[] data) 85 | { 86 | int[] result = new int[data.length]; 87 | 88 | for(int i = 0; i < data.length; i++) 89 | result[i] = data[i].intValue(); 90 | 91 | return result; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/com/base/engine/Medkit.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | public class Medkit 4 | { 5 | public static final float PICKUP_DISTANCE = 0.75f; 6 | public static final int HEAL_AMOUNT = 25; 7 | 8 | public static final float SCALE = 0.25f; 9 | public static final float SIZEY = SCALE; 10 | public static final float SIZEX = (float)((double)SIZEY / (0.67857142857142857142857142857143 * 2.5)); 11 | public static final float START = 0; 12 | 13 | public static final float OFFSET_X = 0.0f; //0.05f 14 | public static final float OFFSET_Y = 0.0f; //0.01f 15 | 16 | public static final float TEX_MIN_X = -OFFSET_X; 17 | public static final float TEX_MAX_X = -1 - OFFSET_X; 18 | public static final float TEX_MIN_Y = -OFFSET_Y; 19 | public static final float TEX_MAX_Y = 1 - OFFSET_Y; 20 | 21 | private static Mesh mesh; 22 | private static Material material; 23 | 24 | private Transform transform; 25 | 26 | public Medkit(Vector3f position) 27 | { 28 | if(mesh == null) 29 | { 30 | Vertex[] vertices = new Vertex[]{new Vertex(new Vector3f(-SIZEX,START,START), new Vector2f(TEX_MAX_X,TEX_MAX_Y)), 31 | new Vertex(new Vector3f(-SIZEX,SIZEY,START), new Vector2f(TEX_MAX_X,TEX_MIN_Y)), 32 | new Vertex(new Vector3f(SIZEX,SIZEY,START), new Vector2f(TEX_MIN_X,TEX_MIN_Y)), 33 | new Vertex(new Vector3f(SIZEX,START,START), new Vector2f(TEX_MIN_X,TEX_MAX_Y))}; 34 | 35 | int[] indices = new int[]{0,1,2, 36 | 0,2,3}; 37 | 38 | mesh = new Mesh(vertices, indices); 39 | } 40 | 41 | if(material == null) 42 | { 43 | material = new Material(new Texture("MEDIA0.png")); 44 | } 45 | 46 | transform = new Transform(); 47 | transform.setTranslation(position); 48 | } 49 | 50 | public void update() 51 | { 52 | Vector3f directionToCamera = Transform.getCamera().getPos().sub(transform.getTranslation()); 53 | 54 | float angleToFaceTheCamera = (float)Math.toDegrees(Math.atan(directionToCamera.getZ() / directionToCamera.getX())); 55 | 56 | if(directionToCamera.getX() < 0) 57 | angleToFaceTheCamera += 180; 58 | 59 | transform.getRotation().setY(angleToFaceTheCamera + 90); 60 | 61 | if(directionToCamera.length() < PICKUP_DISTANCE) 62 | { 63 | Player player = Game.getLevel().getPlayer(); 64 | 65 | if(player.getHealth() < player.getMaxHealth()) 66 | { 67 | Game.getLevel().removeMedkit(this); 68 | player.damage(-HEAL_AMOUNT); 69 | } 70 | } 71 | } 72 | 73 | public void render() 74 | { 75 | Shader shader = Game.getLevel().getShader(); 76 | shader.updateUniforms(transform.getTransformation(), transform.getProjectedTransformation(), material); 77 | mesh.draw(); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/com/base/engine/MainComponent.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | public class MainComponent 4 | { 5 | public static final int WIDTH = 800; 6 | public static final int HEIGHT = 600; 7 | public static final String TITLE = "3D Engine"; 8 | public static final double FRAME_CAP = 250.0; 9 | 10 | private boolean isRunning; 11 | private Game game; 12 | 13 | public MainComponent() 14 | { 15 | System.out.println(RenderUtil.getOpenGLVersion()); 16 | RenderUtil.initGraphics(); 17 | isRunning = false; 18 | game = new Game(); 19 | } 20 | 21 | public void start() 22 | { 23 | if(isRunning) 24 | return; 25 | 26 | run(); 27 | } 28 | 29 | public void stop() 30 | { 31 | if(!isRunning) 32 | return; 33 | 34 | isRunning = false; 35 | } 36 | 37 | private void run() 38 | { 39 | isRunning = true; 40 | 41 | int frames = 0; 42 | long frameCounter = 0; 43 | 44 | final double frameTime = 1.0 / FRAME_CAP; 45 | 46 | long lastTime = Time.getTime(); 47 | double unprocessedTime = 0; 48 | 49 | while(isRunning) 50 | { 51 | boolean render = false; 52 | 53 | long startTime = Time.getTime(); 54 | long passedTime = startTime - lastTime; 55 | lastTime = startTime; 56 | 57 | unprocessedTime += passedTime / (double)Time.SECOND; 58 | frameCounter += passedTime; 59 | 60 | while(unprocessedTime > frameTime) 61 | { 62 | render = true; 63 | 64 | unprocessedTime -= frameTime; 65 | 66 | if(Window.isCloseRequested()) 67 | stop(); 68 | 69 | Time.setDelta(frameTime); 70 | 71 | game.input(); 72 | Input.update(); 73 | 74 | game.update(); 75 | 76 | if(frameCounter >= Time.SECOND) 77 | { 78 | //System.out.println(frames); 79 | frames = 0; 80 | frameCounter = 0; 81 | } 82 | } 83 | if(render) 84 | { 85 | render(); 86 | frames++; 87 | } 88 | else 89 | { 90 | try 91 | { 92 | Thread.sleep(1); 93 | } 94 | catch (InterruptedException e) 95 | { 96 | e.printStackTrace(); 97 | } 98 | } 99 | } 100 | 101 | cleanUp(); 102 | } 103 | 104 | private void render() 105 | { 106 | RenderUtil.clearScreen(); 107 | game.render(); 108 | Window.render(); 109 | } 110 | 111 | private void cleanUp() 112 | { 113 | Window.dispose(); 114 | } 115 | 116 | public static void main(String[] args) 117 | { 118 | Window.createWindow(WIDTH, HEIGHT, TITLE); 119 | 120 | MainComponent game = new MainComponent(); 121 | 122 | game.start(); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/com/base/engine/Texture.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | import static org.lwjgl.opengl.GL11.*; 4 | import static org.lwjgl.opengl.GL11.glTexImage2D; 5 | 6 | import java.awt.image.BufferedImage; 7 | import java.io.File; 8 | import java.nio.ByteBuffer; 9 | 10 | import javax.imageio.ImageIO; 11 | 12 | public class Texture 13 | { 14 | private int id; 15 | 16 | public Texture(String fileName) 17 | { 18 | this(loadTexture(fileName)); 19 | } 20 | 21 | public Texture(int id) 22 | { 23 | this.id = id; 24 | } 25 | 26 | public void bind() 27 | { 28 | glBindTexture(GL_TEXTURE_2D, id); 29 | } 30 | 31 | public int getID() 32 | { 33 | return id; 34 | } 35 | 36 | private static int loadTexture(String fileName) 37 | { 38 | String[] splitArray = fileName.split("\\."); 39 | String ext = splitArray[splitArray.length - 1]; 40 | 41 | try 42 | { 43 | BufferedImage image = ImageIO.read(new File("./res/textures/" + fileName)); 44 | 45 | boolean hasAlpha = image.getColorModel().hasAlpha(); 46 | 47 | int[] pixels = image.getRGB(0, 0, image.getWidth(), 48 | image.getHeight(), null, 0, image.getWidth()); 49 | 50 | ByteBuffer buffer = Util.createByteBuffer(image.getWidth() * image.getHeight() * 4); 51 | 52 | for (int y = 0; y < image.getHeight(); y++) 53 | { 54 | for (int x = 0; x < image.getWidth(); x++) 55 | { 56 | int pixel = pixels[y * image.getWidth() + x]; 57 | 58 | buffer.put((byte) ((pixel >> 16) & 0xFF)); 59 | buffer.put((byte) ((pixel >> 8) & 0xFF)); 60 | buffer.put((byte) ((pixel >> 0) & 0xFF)); 61 | if (hasAlpha) 62 | buffer.put((byte) ((pixel >> 24) & 0xFF)); 63 | else 64 | buffer.put((byte) (0xFF)); 65 | } 66 | } 67 | 68 | buffer.flip(); 69 | 70 | // this.width = image.getWidth(); 71 | // this.height = image.getHeight(); 72 | // this.id = Engine.getRenderer().createTexture(width, height, buffer, true, true); 73 | // this.frameBuffer = 0; 74 | // this.pixels = null; 75 | 76 | int texture = glGenTextures(); 77 | glBindTexture(GL_TEXTURE_2D, texture); 78 | 79 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 80 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 81 | 82 | glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 83 | glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 84 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); 85 | 86 | return texture; 87 | } 88 | catch(Exception e) 89 | { 90 | e.printStackTrace(); 91 | System.exit(1); 92 | } 93 | 94 | return 0; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/com/base/engine/Transform.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | public class Transform 4 | { 5 | private static Camera camera; 6 | 7 | private static float zNear; 8 | private static float zFar; 9 | private static float width; 10 | private static float height; 11 | private static float fov; 12 | 13 | private Vector3f translation; 14 | private Vector3f rotation; 15 | private Vector3f scale; 16 | 17 | public Transform() 18 | { 19 | translation = new Vector3f(0,0,0); 20 | rotation = new Vector3f(0,0,0); 21 | scale = new Vector3f(1,1,1); 22 | } 23 | 24 | public Matrix4f getTransformation() 25 | { 26 | Matrix4f translationMatrix = new Matrix4f().initTranslation(translation.getX(), translation.getY(), translation.getZ()); 27 | Matrix4f rotationMatrix = new Matrix4f().initRotation(rotation.getX(), rotation.getY(), rotation.getZ()); 28 | Matrix4f scaleMatrix = new Matrix4f().initScale(scale.getX(), scale.getY(), scale.getZ()); 29 | 30 | return translationMatrix.mul(rotationMatrix.mul(scaleMatrix)); 31 | } 32 | 33 | public Matrix4f getProjectedTransformation() 34 | { 35 | Matrix4f transformationMatrix = getTransformation(); 36 | Matrix4f projectionMatrix = new Matrix4f().initProjection(fov, width, height, zNear, zFar); 37 | Matrix4f cameraRotation = new Matrix4f().initCamera(camera.getForward(), camera.getUp()); 38 | Matrix4f cameraTranslation = new Matrix4f().initTranslation(-camera.getPos().getX(), -camera.getPos().getY(), -camera.getPos().getZ()); 39 | 40 | return projectionMatrix.mul(cameraRotation.mul(cameraTranslation.mul(transformationMatrix))); 41 | } 42 | 43 | public Vector3f getTranslation() 44 | { 45 | return translation; 46 | } 47 | 48 | public static void setProjection(float fov, float width, float height, float zNear, float zFar) 49 | { 50 | Transform.fov = fov; 51 | Transform.width = width; 52 | Transform.height = height; 53 | Transform.zNear = zNear; 54 | Transform.zFar = zFar; 55 | } 56 | 57 | public void setTranslation(Vector3f translation) 58 | { 59 | this.translation = translation; 60 | } 61 | 62 | public void setTranslation(float x, float y, float z) 63 | { 64 | this.translation = new Vector3f(x, y, z); 65 | } 66 | 67 | public Vector3f getRotation() 68 | { 69 | return rotation; 70 | } 71 | 72 | public void setRotation(Vector3f rotation) 73 | { 74 | this.rotation = rotation; 75 | } 76 | 77 | public void setRotation(float x, float y, float z) 78 | { 79 | this.rotation = new Vector3f(x, y, z); 80 | } 81 | 82 | public Vector3f getScale() 83 | { 84 | return scale; 85 | } 86 | 87 | public void setScale(Vector3f scale) 88 | { 89 | this.scale = scale; 90 | } 91 | 92 | public void setScale(float x, float y, float z) 93 | { 94 | this.scale = new Vector3f(x, y, z); 95 | } 96 | 97 | public static Camera getCamera() 98 | { 99 | return camera; 100 | } 101 | 102 | public static void setCamera(Camera camera) 103 | { 104 | Transform.camera = camera; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/com/base/engine/Vector3f.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | public class Vector3f 4 | { 5 | private float x; 6 | private float y; 7 | private float z; 8 | 9 | public Vector3f(float x, float y, float z) 10 | { 11 | this.x = x; 12 | this.y = y; 13 | this.z = z; 14 | } 15 | 16 | public float length() 17 | { 18 | return (float)Math.sqrt(x * x + y * y + z * z); 19 | } 20 | 21 | public float dot(Vector3f r) 22 | { 23 | return x * r.getX() + y * r.getY() + z * r.getZ(); 24 | } 25 | 26 | public Vector3f cross(Vector3f r) 27 | { 28 | float x_ = y * r.getZ() - z * r.getY(); 29 | float y_ = z * r.getX() - x * r.getZ(); 30 | float z_ = x * r.getY() - y * r.getX(); 31 | 32 | return new Vector3f(x_, y_, z_); 33 | } 34 | 35 | public Vector3f normalized() 36 | { 37 | float length = length(); 38 | 39 | return new Vector3f(x / length, y / length, z / length); 40 | } 41 | 42 | public Vector3f rotate(float angle, Vector3f axis) 43 | { 44 | float sinHalfAngle = (float)Math.sin(Math.toRadians(angle / 2)); 45 | float cosHalfAngle = (float)Math.cos(Math.toRadians(angle / 2)); 46 | 47 | float rX = axis.getX() * sinHalfAngle; 48 | float rY = axis.getY() * sinHalfAngle; 49 | float rZ = axis.getZ() * sinHalfAngle; 50 | float rW = cosHalfAngle; 51 | 52 | Quaternion rotation = new Quaternion(rX, rY, rZ, rW); 53 | Quaternion conjugate = rotation.conjugate(); 54 | 55 | Quaternion w = rotation.mul(this).mul(conjugate); 56 | 57 | return new Vector3f(w.getX(), w.getY(), w.getZ()); 58 | } 59 | 60 | public Vector3f add(Vector3f r) 61 | { 62 | return new Vector3f(x + r.getX(), y + r.getY(), z + r.getZ()); 63 | } 64 | 65 | public Vector3f add(float r) 66 | { 67 | return new Vector3f(x + r, y + r, z + r); 68 | } 69 | 70 | public Vector3f sub(Vector3f r) 71 | { 72 | return new Vector3f(x - r.getX(), y - r.getY(), z - r.getZ()); 73 | } 74 | 75 | public Vector3f sub(float r) 76 | { 77 | return new Vector3f(x - r, y - r, z - r); 78 | } 79 | 80 | public Vector3f mul(Vector3f r) 81 | { 82 | return new Vector3f(x * r.getX(), y * r.getY(), z * r.getZ()); 83 | } 84 | 85 | public Vector3f mul(float r) 86 | { 87 | return new Vector3f(x * r, y * r, z * r); 88 | } 89 | 90 | public Vector3f div(Vector3f r) 91 | { 92 | return new Vector3f(x / r.getX(), y / r.getY(), z / r.getZ()); 93 | } 94 | 95 | public Vector3f div(float r) 96 | { 97 | return new Vector3f(x / r, y / r, z / r); 98 | } 99 | 100 | public Vector3f abs() 101 | { 102 | return new Vector3f(Math.abs(x), Math.abs(y), Math.abs(z)); 103 | } 104 | 105 | public String toString() 106 | { 107 | return "(" + x + " " + y + " " + z + ")"; 108 | } 109 | 110 | public float getX() 111 | { 112 | return x; 113 | } 114 | 115 | public void setX(float x) 116 | { 117 | this.x = x; 118 | } 119 | 120 | public float getY() 121 | { 122 | return y; 123 | } 124 | 125 | public void setY(float y) 126 | { 127 | this.y = y; 128 | } 129 | 130 | public float getZ() 131 | { 132 | return z; 133 | } 134 | 135 | public void setZ(float z) 136 | { 137 | this.z = z; 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/com/base/engine/Camera.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | public class Camera 4 | { 5 | public static final Vector3f yAxis = new Vector3f(0,1,0); 6 | 7 | private Vector3f pos; 8 | private Vector3f forward; 9 | private Vector3f up; 10 | 11 | public Camera() 12 | { 13 | this(new Vector3f(0,0,0), new Vector3f(0,0,1), new Vector3f(0,1,0)); 14 | } 15 | 16 | public Camera(Vector3f pos, Vector3f forward, Vector3f up) 17 | { 18 | this.pos = pos; 19 | this.forward = forward.normalized(); 20 | this.up = up.normalized(); 21 | } 22 | 23 | boolean mouseLocked = false; 24 | Vector2f centerPosition = new Vector2f(Window.getWidth()/2, Window.getHeight()/2); 25 | 26 | public void input() 27 | { 28 | float sensitivity = 0.5f; 29 | float movAmt = (float)(10 * Time.getDelta()); 30 | // float rotAmt = (float)(100 * Time.getDelta()); 31 | 32 | if(Input.getKey(Input.KEY_ESCAPE)) 33 | { 34 | Input.setCursor(true); 35 | mouseLocked = false; 36 | } 37 | if(Input.getMouseDown(0)) 38 | { 39 | Input.setMousePosition(centerPosition); 40 | Input.setCursor(false); 41 | mouseLocked = true; 42 | } 43 | 44 | if(Input.getKey(Input.KEY_W)) 45 | move(getForward(), movAmt); 46 | if(Input.getKey(Input.KEY_S)) 47 | move(getForward(), -movAmt); 48 | if(Input.getKey(Input.KEY_A)) 49 | move(getLeft(), movAmt); 50 | if(Input.getKey(Input.KEY_D)) 51 | move(getRight(), movAmt); 52 | 53 | if(mouseLocked) 54 | { 55 | Vector2f deltaPos = Input.getMousePosition().sub(centerPosition); 56 | 57 | boolean rotY = deltaPos.getX() != 0; 58 | boolean rotX = deltaPos.getY() != 0; 59 | 60 | if(rotY) 61 | rotateY(deltaPos.getX() * sensitivity); 62 | if(rotX) 63 | rotateX(-deltaPos.getY() * sensitivity); 64 | 65 | if(rotY || rotX) 66 | Input.setMousePosition(new Vector2f(Window.getWidth()/2, Window.getHeight()/2)); 67 | } 68 | 69 | // if(Input.getKey(Input.KEY_UP)) 70 | // rotateX(-rotAmt); 71 | // if(Input.getKey(Input.KEY_DOWN)) 72 | // rotateX(rotAmt); 73 | // if(Input.getKey(Input.KEY_LEFT)) 74 | // rotateY(-rotAmt); 75 | // if(Input.getKey(Input.KEY_RIGHT)) 76 | // rotateY(rotAmt); 77 | } 78 | 79 | public void move(Vector3f dir, float amt) 80 | { 81 | pos = pos.add(dir.mul(amt)); 82 | } 83 | 84 | public void rotateY(float angle) 85 | { 86 | Vector3f Haxis = yAxis.cross(forward).normalized(); 87 | 88 | forward = forward.rotate(angle, yAxis).normalized(); 89 | 90 | up = forward.cross(Haxis).normalized(); 91 | } 92 | 93 | public void rotateX(float angle) 94 | { 95 | Vector3f Haxis = yAxis.cross(forward).normalized(); 96 | 97 | forward = forward.rotate(angle, Haxis).normalized(); 98 | 99 | up = forward.cross(Haxis).normalized(); 100 | } 101 | 102 | public Vector3f getLeft() 103 | { 104 | return forward.cross(up).normalized(); 105 | } 106 | 107 | public Vector3f getRight() 108 | { 109 | return up.cross(forward).normalized(); 110 | } 111 | 112 | public Vector3f getPos() 113 | { 114 | return pos; 115 | } 116 | 117 | public void setPos(Vector3f pos) 118 | { 119 | this.pos = pos; 120 | } 121 | 122 | public Vector3f getForward() 123 | { 124 | return forward; 125 | } 126 | 127 | public void setForward(Vector3f forward) 128 | { 129 | this.forward = forward; 130 | } 131 | 132 | public Vector3f getUp() 133 | { 134 | return up; 135 | } 136 | 137 | public void setUp(Vector3f up) 138 | { 139 | this.up = up; 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.Publish.xml 129 | *.pubxml 130 | 131 | # NuGet Packages Directory 132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 133 | #packages/ 134 | 135 | # Windows Azure Build Output 136 | csx 137 | *.build.csdef 138 | 139 | # Windows Store app package directory 140 | AppPackages/ 141 | 142 | # Others 143 | sql/ 144 | *.Cache 145 | ClientBin/ 146 | [Ss]tyle[Cc]op.* 147 | ~$* 148 | *~ 149 | *.dbmdl 150 | *.[Pp]ublish.xml 151 | *.pfx 152 | *.publishsettings 153 | 154 | # RIA/Silverlight projects 155 | Generated_Code/ 156 | 157 | # Backup & report files from converting an old project file to a newer 158 | # Visual Studio version. Backup files are not needed, because we have git ;-) 159 | _UpgradeReport_Files/ 160 | Backup*/ 161 | UpgradeLog*.XML 162 | UpgradeLog*.htm 163 | 164 | # SQL Server files 165 | App_Data/*.mdf 166 | App_Data/*.ldf 167 | 168 | ############# 169 | ## Windows detritus 170 | ############# 171 | 172 | # Windows image file caches 173 | Thumbs.db 174 | ehthumbs.db 175 | 176 | # Folder config file 177 | Desktop.ini 178 | 179 | # Recycle Bin used on file shares 180 | $RECYCLE.BIN/ 181 | 182 | # Mac crap 183 | .DS_Store 184 | 185 | 186 | ############# 187 | ## Python 188 | ############# 189 | 190 | *.py[co] 191 | 192 | # Packages 193 | *.egg 194 | *.egg-info 195 | dist/ 196 | build/ 197 | eggs/ 198 | parts/ 199 | var/ 200 | sdist/ 201 | develop-eggs/ 202 | .installed.cfg 203 | 204 | # Installer logs 205 | pip-log.txt 206 | 207 | # Unit test / coverage reports 208 | .coverage 209 | .tox 210 | 211 | #Translations 212 | *.mo 213 | 214 | #Mr Developer 215 | .mr.developer.cfg 216 | -------------------------------------------------------------------------------- /res/shaders/phongFragment.fs: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | const int MAX_POINT_LIGHTS = 4; 4 | const int MAX_SPOT_LIGHTS = 4; 5 | 6 | in vec2 texCoord0; 7 | in vec3 normal0; 8 | in vec3 worldPos0; 9 | 10 | out vec4 fragColor; 11 | 12 | struct BaseLight 13 | { 14 | vec3 color; 15 | float intensity; 16 | }; 17 | 18 | struct DirectionalLight 19 | { 20 | BaseLight base; 21 | vec3 direction; 22 | }; 23 | 24 | struct Attenuation 25 | { 26 | float constant; 27 | float linear; 28 | float exponent; 29 | }; 30 | 31 | struct PointLight 32 | { 33 | BaseLight base; 34 | Attenuation atten; 35 | vec3 position; 36 | float range; 37 | }; 38 | 39 | struct SpotLight 40 | { 41 | PointLight pointLight; 42 | vec3 direction; 43 | float cutoff; 44 | }; 45 | 46 | uniform vec3 baseColor; 47 | uniform vec3 eyePos; 48 | uniform vec3 ambientLight; 49 | uniform sampler2D sampler; 50 | 51 | uniform float specularIntensity; 52 | uniform float specularPower; 53 | 54 | uniform DirectionalLight directionalLight; 55 | uniform PointLight pointLights[MAX_POINT_LIGHTS]; 56 | uniform SpotLight spotLights[MAX_SPOT_LIGHTS]; 57 | 58 | vec4 calcLight(BaseLight base, vec3 direction, vec3 normal) 59 | { 60 | float diffuseFactor = dot(normal, -direction); 61 | 62 | vec4 diffuseColor = vec4(0,0,0,0); 63 | vec4 specularColor = vec4(0,0,0,0); 64 | 65 | if(diffuseFactor > 0) 66 | { 67 | diffuseColor = vec4(base.color, 1.0) * base.intensity * diffuseFactor; 68 | 69 | vec3 directionToEye = normalize(eyePos - worldPos0); 70 | vec3 reflectDirection = normalize(reflect(direction, normal)); 71 | 72 | float specularFactor = dot(directionToEye, reflectDirection); 73 | specularFactor = pow(specularFactor, specularPower); 74 | 75 | if(specularFactor > 0) 76 | { 77 | specularColor = vec4(base.color, 1.0) * specularIntensity * specularFactor; 78 | } 79 | } 80 | 81 | return diffuseColor + specularColor; 82 | } 83 | 84 | vec4 calcDirectionalLight(DirectionalLight directionalLight, vec3 normal) 85 | { 86 | return calcLight(directionalLight.base, -directionalLight.direction, normal); 87 | } 88 | 89 | vec4 calcPointLight(PointLight pointLight, vec3 normal) 90 | { 91 | vec3 lightDirection = worldPos0 - pointLight.position; 92 | float distanceToPoint = length(lightDirection); 93 | 94 | if(distanceToPoint > pointLight.range) 95 | return vec4(0,0,0,0); 96 | 97 | lightDirection = normalize(lightDirection); 98 | 99 | vec4 color = calcLight(pointLight.base, lightDirection, normal); 100 | 101 | float attenuation = pointLight.atten.constant + 102 | pointLight.atten.linear * distanceToPoint + 103 | pointLight.atten.exponent * distanceToPoint * distanceToPoint + 104 | 0.0001; 105 | 106 | return color / attenuation; 107 | } 108 | 109 | vec4 calcSpotLight(SpotLight spotLight, vec3 normal) 110 | { 111 | vec3 lightDirection = normalize(worldPos0 - spotLight.pointLight.position); 112 | float spotFactor = dot(lightDirection, spotLight.direction); 113 | 114 | vec4 color = vec4(0,0,0,0); 115 | 116 | if(spotFactor > spotLight.cutoff) 117 | { 118 | color = calcPointLight(spotLight.pointLight, normal) * 119 | (1.0 - (1.0 - spotFactor)/(1.0 - spotLight.cutoff)); 120 | } 121 | 122 | return color; 123 | } 124 | 125 | void main() 126 | { 127 | vec4 totalLight = vec4(ambientLight,1); 128 | vec4 color = vec4(baseColor, 1); 129 | vec4 textureColor = texture(sampler, texCoord0.xy); 130 | 131 | if(textureColor != vec4(0,0,0,0)) 132 | color *= textureColor; 133 | 134 | vec3 normal = normalize(normal0); 135 | 136 | totalLight += calcDirectionalLight(directionalLight, normal); 137 | 138 | for(int i = 0; i < MAX_POINT_LIGHTS; i++) 139 | if(pointLights[i].base.intensity > 0) 140 | totalLight += calcPointLight(pointLights[i], normal); 141 | 142 | for(int i = 0; i < MAX_SPOT_LIGHTS; i++) 143 | if(spotLights[i].pointLight.base.intensity > 0) 144 | totalLight += calcSpotLight(spotLights[i], normal); 145 | 146 | fragColor = color * totalLight; 147 | } -------------------------------------------------------------------------------- /src/com/base/engine/Shader.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | import static org.lwjgl.opengl.GL20.*; 4 | import static org.lwjgl.opengl.GL32.*; 5 | 6 | import java.io.BufferedReader; 7 | import java.io.FileReader; 8 | import java.util.HashMap; 9 | 10 | public class Shader 11 | { 12 | private int program; 13 | private HashMap uniforms; 14 | 15 | public Shader() 16 | { 17 | program = glCreateProgram(); 18 | uniforms = new HashMap(); 19 | 20 | if(program == 0) 21 | { 22 | System.err.println("Shader creation failed: Could not find valid memory location in constructor"); 23 | System.exit(1); 24 | } 25 | } 26 | 27 | public void bind() 28 | { 29 | glUseProgram(program); 30 | } 31 | 32 | public void updateUniforms(Matrix4f worldMatrix, Matrix4f projectedMatrix, Material material) 33 | { 34 | 35 | } 36 | 37 | public void addUniform(String uniform) 38 | { 39 | int uniformLocation = glGetUniformLocation(program, uniform); 40 | 41 | if(uniformLocation == 0xFFFFFFFF) 42 | { 43 | System.err.println("Error: Could not find uniform: " + uniform); 44 | new Exception().printStackTrace(); 45 | System.exit(1); 46 | } 47 | 48 | uniforms.put(uniform, uniformLocation); 49 | } 50 | 51 | public void addVertexShaderFromFile(String text) 52 | { 53 | addProgram(loadShader(text), GL_VERTEX_SHADER); 54 | } 55 | 56 | public void addGeometryShaderFromFile(String text) 57 | { 58 | addProgram(loadShader(text), GL_GEOMETRY_SHADER); 59 | } 60 | 61 | public void addFragmentShaderFromFile(String text) 62 | { 63 | addProgram(loadShader(text), GL_FRAGMENT_SHADER); 64 | } 65 | 66 | public void addVertexShader(String text) 67 | { 68 | addProgram(text, GL_VERTEX_SHADER); 69 | } 70 | 71 | public void addGeometryShader(String text) 72 | { 73 | addProgram(text, GL_GEOMETRY_SHADER); 74 | } 75 | 76 | public void addFragmentShader(String text) 77 | { 78 | addProgram(text, GL_FRAGMENT_SHADER); 79 | } 80 | 81 | public void compileShader() 82 | { 83 | glLinkProgram(program); 84 | 85 | if(glGetProgram(program, GL_LINK_STATUS) == 0) 86 | { 87 | System.err.println(glGetProgramInfoLog(program, 1024)); 88 | System.exit(1); 89 | } 90 | 91 | glValidateProgram(program); 92 | 93 | if(glGetProgram(program, GL_VALIDATE_STATUS) == 0) 94 | { 95 | System.err.println(glGetProgramInfoLog(program, 1024)); 96 | System.exit(1); 97 | } 98 | } 99 | 100 | private void addProgram(String text, int type) 101 | { 102 | int shader = glCreateShader(type); 103 | 104 | if(shader == 0) 105 | { 106 | System.err.println("Shader creation failed: Could not find valid memory location when adding shader"); 107 | System.exit(1); 108 | } 109 | 110 | glShaderSource(shader, text); 111 | glCompileShader(shader); 112 | 113 | if(glGetShader(shader, GL_COMPILE_STATUS) == 0) 114 | { 115 | System.err.println(glGetShaderInfoLog(shader, 1024)); 116 | System.exit(1); 117 | } 118 | 119 | glAttachShader(program, shader); 120 | } 121 | 122 | private static String loadShader(String fileName) 123 | { 124 | StringBuilder shaderSource = new StringBuilder(); 125 | BufferedReader shaderReader = null; 126 | 127 | try 128 | { 129 | shaderReader = new BufferedReader(new FileReader("./res/shaders/" + fileName)); 130 | String line; 131 | 132 | while((line = shaderReader.readLine()) != null) 133 | { 134 | shaderSource.append(line).append("\n"); 135 | } 136 | 137 | shaderReader.close(); 138 | } 139 | catch(Exception e) 140 | { 141 | e.printStackTrace(); 142 | System.exit(1); 143 | } 144 | 145 | 146 | return shaderSource.toString(); 147 | } 148 | 149 | public void setUniformi(String uniformName, int value) 150 | { 151 | glUniform1i(uniforms.get(uniformName), value); 152 | } 153 | 154 | public void setUniformf(String uniformName, float value) 155 | { 156 | glUniform1f(uniforms.get(uniformName), value); 157 | } 158 | 159 | public void setUniform(String uniformName, Vector3f value) 160 | { 161 | glUniform3f(uniforms.get(uniformName), value.getX(), value.getY(), value.getZ()); 162 | } 163 | 164 | public void setUniform(String uniformName, Matrix4f value) 165 | { 166 | glUniformMatrix4(uniforms.get(uniformName), true, Util.createFlippedBuffer(value)); 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/com/base/engine/Door.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | public class Door 4 | { 5 | //NOTE: You may need to add top/bottom face depending on how you set these variables 6 | public static final float LENGTH = 1; 7 | public static final float HEIGHT = 1; 8 | public static final float WIDTH = 0.125f; 9 | public static final float START = 0; 10 | public static final double TIME_TO_OPEN = 0.25; 11 | public static final double CLOSE_DELAY = 2.0; 12 | 13 | private static Mesh mesh; 14 | private Material material; 15 | private Transform transform; 16 | 17 | private Vector3f openPosition; 18 | private Vector3f closePosition; 19 | 20 | private boolean isOpening; 21 | private double openingStartTime; 22 | private double openTime; 23 | private double closingStartTime; 24 | private double closeTime; 25 | 26 | public Door(Transform transform, Material material, Vector3f openPosition) 27 | { 28 | this.transform = transform; 29 | this.material = material; 30 | this.isOpening = false; 31 | this.closePosition = transform.getTranslation().mul(1); 32 | this.openPosition = openPosition; 33 | 34 | if(mesh == null) 35 | { 36 | Vertex[] vertices = new Vertex[]{new Vertex(new Vector3f(START,START,START), new Vector2f(0.5f,1)), 37 | new Vertex(new Vector3f(START,HEIGHT,START), new Vector2f(0.5f,0.75f)), 38 | new Vertex(new Vector3f(LENGTH,HEIGHT,START), new Vector2f(0.75f,0.75f)), 39 | new Vertex(new Vector3f(LENGTH,START,START), new Vector2f(0.75f,1)), 40 | 41 | new Vertex(new Vector3f(START,START,START), new Vector2f(0.73f,1)), 42 | new Vertex(new Vector3f(START,HEIGHT,START), new Vector2f(0.73f,0.75f)), 43 | new Vertex(new Vector3f(START,HEIGHT,WIDTH), new Vector2f(0.75f,0.75f)), 44 | new Vertex(new Vector3f(START,START,WIDTH), new Vector2f(0.75f,1)), 45 | 46 | new Vertex(new Vector3f(START,START,WIDTH), new Vector2f(0.5f,1)), 47 | new Vertex(new Vector3f(START,HEIGHT,WIDTH), new Vector2f(0.5f,0.75f)), 48 | new Vertex(new Vector3f(LENGTH,HEIGHT,WIDTH), new Vector2f(0.75f,0.75f)), 49 | new Vertex(new Vector3f(LENGTH,START,WIDTH), new Vector2f(0.75f,1)), 50 | 51 | new Vertex(new Vector3f(LENGTH,START,START), new Vector2f(0.73f,1)), 52 | new Vertex(new Vector3f(LENGTH,HEIGHT,START), new Vector2f(0.73f,0.75f)), 53 | new Vertex(new Vector3f(LENGTH,HEIGHT,WIDTH), new Vector2f(0.75f,0.75f)), 54 | new Vertex(new Vector3f(LENGTH,START,WIDTH), new Vector2f(0.75f,1))}; 55 | 56 | int[] indices = new int[]{0,1,2, 57 | 0,2,3, 58 | 59 | 6,5,4, 60 | 7,6,4, 61 | 62 | 10,9,8, 63 | 11,10,8, 64 | 65 | 12,13,14, 66 | 12,14,15}; 67 | 68 | mesh = new Mesh(vertices, indices); 69 | } 70 | } 71 | 72 | public void open() 73 | { 74 | if(isOpening) 75 | return; 76 | 77 | openingStartTime = (double)Time.getTime()/(double)Time.SECOND; 78 | openTime = openingStartTime + TIME_TO_OPEN; 79 | closingStartTime = openTime + CLOSE_DELAY; 80 | closeTime = closingStartTime + TIME_TO_OPEN; 81 | 82 | isOpening = true; 83 | } 84 | 85 | private Vector3f VectorLerp(Vector3f startPos, Vector3f endPos, float lerpFactor) 86 | { 87 | return startPos.add(endPos.sub(startPos).mul(lerpFactor)); 88 | } 89 | 90 | public void update() 91 | { 92 | if(isOpening) 93 | { 94 | double time = (double)Time.getTime()/(double)Time.SECOND; 95 | 96 | if(time < openTime) 97 | { 98 | getTransform().setTranslation(VectorLerp(closePosition, openPosition, 99 | (float)((time - openingStartTime) / TIME_TO_OPEN))); 100 | } 101 | else if(time < closingStartTime) 102 | { 103 | getTransform().setTranslation(openPosition); 104 | } 105 | else if(time < closeTime) 106 | { 107 | getTransform().setTranslation(VectorLerp(openPosition, closePosition, 108 | (float)((time - closingStartTime) / TIME_TO_OPEN))); 109 | } 110 | else 111 | { 112 | getTransform().setTranslation(closePosition); 113 | isOpening = false; 114 | } 115 | } 116 | } 117 | 118 | public void render() 119 | { 120 | Shader shader = Game.getLevel().getShader(); 121 | shader.updateUniforms(transform.getTransformation(), transform.getProjectedTransformation(), material); 122 | mesh.draw(); 123 | } 124 | 125 | public Vector2f getDoorSize() 126 | { 127 | if(getTransform().getRotation().getY() == 90) 128 | return new Vector2f(Door.WIDTH, Door.LENGTH); 129 | else 130 | return new Vector2f(Door.LENGTH, Door.WIDTH); 131 | } 132 | 133 | public Transform getTransform() 134 | { 135 | return transform; 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /src/com/base/engine/Matrix4f.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | public class Matrix4f 4 | { 5 | private float[][] m; 6 | 7 | public Matrix4f() 8 | { 9 | m = new float[4][4]; 10 | } 11 | 12 | public Matrix4f initIdentity() 13 | { 14 | m[0][0] = 1; m[0][1] = 0; m[0][2] = 0; m[0][3] = 0; 15 | m[1][0] = 0; m[1][1] = 1; m[1][2] = 0; m[1][3] = 0; 16 | m[2][0] = 0; m[2][1] = 0; m[2][2] = 1; m[2][3] = 0; 17 | m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1; 18 | 19 | return this; 20 | } 21 | 22 | public Matrix4f initTranslation(float x, float y, float z) 23 | { 24 | m[0][0] = 1; m[0][1] = 0; m[0][2] = 0; m[0][3] = x; 25 | m[1][0] = 0; m[1][1] = 1; m[1][2] = 0; m[1][3] = y; 26 | m[2][0] = 0; m[2][1] = 0; m[2][2] = 1; m[2][3] = z; 27 | m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1; 28 | 29 | return this; 30 | } 31 | 32 | public Matrix4f initRotation(float x, float y, float z) 33 | { 34 | Matrix4f rx = new Matrix4f(); 35 | Matrix4f ry = new Matrix4f(); 36 | Matrix4f rz = new Matrix4f(); 37 | 38 | x = (float)Math.toRadians(x); 39 | y = (float)Math.toRadians(y); 40 | z = (float)Math.toRadians(z); 41 | 42 | rz.m[0][0] = (float)Math.cos(z);rz.m[0][1] = -(float)Math.sin(z);rz.m[0][2] = 0; rz.m[0][3] = 0; 43 | rz.m[1][0] = (float)Math.sin(z);rz.m[1][1] = (float)Math.cos(z);rz.m[1][2] = 0; rz.m[1][3] = 0; 44 | rz.m[2][0] = 0; rz.m[2][1] = 0; rz.m[2][2] = 1; rz.m[2][3] = 0; 45 | rz.m[3][0] = 0; rz.m[3][1] = 0; rz.m[3][2] = 0; rz.m[3][3] = 1; 46 | 47 | rx.m[0][0] = 1; rx.m[0][1] = 0; rx.m[0][2] = 0; rx.m[0][3] = 0; 48 | rx.m[1][0] = 0; rx.m[1][1] = (float)Math.cos(x);rx.m[1][2] = -(float)Math.sin(x);rx.m[1][3] = 0; 49 | rx.m[2][0] = 0; rx.m[2][1] = (float)Math.sin(x);rx.m[2][2] = (float)Math.cos(x);rx.m[2][3] = 0; 50 | rx.m[3][0] = 0; rx.m[3][1] = 0; rx.m[3][2] = 0; rx.m[3][3] = 1; 51 | 52 | ry.m[0][0] = (float)Math.cos(y);ry.m[0][1] = 0; ry.m[0][2] = -(float)Math.sin(y);ry.m[0][3] = 0; 53 | ry.m[1][0] = 0; ry.m[1][1] = 1; ry.m[1][2] = 0; ry.m[1][3] = 0; 54 | ry.m[2][0] = (float)Math.sin(y);ry.m[2][1] = 0; ry.m[2][2] = (float)Math.cos(y);ry.m[2][3] = 0; 55 | ry.m[3][0] = 0; ry.m[3][1] = 0; ry.m[3][2] = 0; ry.m[3][3] = 1; 56 | 57 | m = rz.mul(ry.mul(rx)).getM(); 58 | 59 | return this; 60 | } 61 | 62 | public Matrix4f initScale(float x, float y, float z) 63 | { 64 | m[0][0] = x; m[0][1] = 0; m[0][2] = 0; m[0][3] = 0; 65 | m[1][0] = 0; m[1][1] = y; m[1][2] = 0; m[1][3] = 0; 66 | m[2][0] = 0; m[2][1] = 0; m[2][2] = z; m[2][3] = 0; 67 | m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1; 68 | 69 | return this; 70 | } 71 | 72 | public Matrix4f initProjection(float fov, float width, float height, float zNear, float zFar) 73 | { 74 | float ar = width/height; 75 | float tanHalfFOV = (float)Math.tan(Math.toRadians(fov / 2)); 76 | float zRange = zNear - zFar; 77 | 78 | m[0][0] = 1.0f / (tanHalfFOV * ar); m[0][1] = 0; m[0][2] = 0; m[0][3] = 0; 79 | m[1][0] = 0; m[1][1] = 1.0f / tanHalfFOV; m[1][2] = 0; m[1][3] = 0; 80 | m[2][0] = 0; m[2][1] = 0; m[2][2] = (-zNear -zFar)/zRange; m[2][3] = 2 * zFar * zNear / zRange; 81 | m[3][0] = 0; m[3][1] = 0; m[3][2] = 1; m[3][3] = 0; 82 | 83 | 84 | return this; 85 | } 86 | 87 | public Matrix4f initCamera(Vector3f forward, Vector3f up) 88 | { 89 | Vector3f f = forward.normalized(); 90 | 91 | Vector3f r = up.normalized(); 92 | r = r.cross(f); 93 | 94 | Vector3f u = f.cross(r); 95 | 96 | m[0][0] = r.getX(); m[0][1] = r.getY(); m[0][2] = r.getZ(); m[0][3] = 0; 97 | m[1][0] = u.getX(); m[1][1] = u.getY(); m[1][2] = u.getZ(); m[1][3] = 0; 98 | m[2][0] = f.getX(); m[2][1] = f.getY(); m[2][2] = f.getZ(); m[2][3] = 0; 99 | m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1; 100 | 101 | return this; 102 | } 103 | 104 | public Matrix4f mul(Matrix4f r) 105 | { 106 | Matrix4f res = new Matrix4f(); 107 | 108 | for(int i = 0; i < 4; i++) 109 | { 110 | for(int j = 0; j < 4; j++) 111 | { 112 | res.set(i, j, m[i][0] * r.get(0, j) + 113 | m[i][1] * r.get(1, j) + 114 | m[i][2] * r.get(2, j) + 115 | m[i][3] * r.get(3, j)); 116 | } 117 | } 118 | 119 | return res; 120 | } 121 | 122 | public float[][] getM() 123 | { 124 | float[][] res = new float[4][4]; 125 | 126 | for(int i = 0; i < 4; i++) 127 | for(int j = 0; j < 4; j++) 128 | res[i][j] = m[i][j]; 129 | 130 | return res; 131 | } 132 | 133 | public float get(int x, int y) 134 | { 135 | return m[x][y]; 136 | } 137 | 138 | public void setM(float[][] m) 139 | { 140 | this.m = m; 141 | } 142 | 143 | public void set(int x, int y, float value) 144 | { 145 | m[x][y] = value; 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/com/base/engine/Mesh.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | import static org.lwjgl.opengl.GL11.*; 4 | import static org.lwjgl.opengl.GL15.*; 5 | import static org.lwjgl.opengl.GL20.*; 6 | 7 | import java.io.BufferedReader; 8 | import java.io.FileReader; 9 | import java.util.ArrayList; 10 | 11 | public class Mesh 12 | { 13 | private int vbo; 14 | private int ibo; 15 | private int size; 16 | 17 | public Mesh(String fileName) 18 | { 19 | initMeshData(); 20 | loadMesh(fileName); 21 | } 22 | 23 | public Mesh(Vertex[] vertices, int[] indices) 24 | { 25 | this(vertices, indices, false); 26 | } 27 | 28 | public Mesh(Vertex[] vertices, int[] indices, boolean calcNormals) 29 | { 30 | initMeshData(); 31 | addVertices(vertices, indices, calcNormals); 32 | } 33 | 34 | private void initMeshData() 35 | { 36 | vbo = glGenBuffers(); 37 | ibo = glGenBuffers(); 38 | size = 0; 39 | } 40 | 41 | private void addVertices(Vertex[] vertices, int[] indices, boolean calcNormals) 42 | { 43 | if(calcNormals) 44 | { 45 | calcNormals(vertices, indices); 46 | } 47 | 48 | size = indices.length; 49 | 50 | glBindBuffer(GL_ARRAY_BUFFER, vbo); 51 | glBufferData(GL_ARRAY_BUFFER, Util.createFlippedBuffer(vertices), GL_STATIC_DRAW); 52 | 53 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); 54 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, Util.createFlippedBuffer(indices), GL_STATIC_DRAW); 55 | } 56 | 57 | public void draw() 58 | { 59 | glEnableVertexAttribArray(0); 60 | glEnableVertexAttribArray(1); 61 | glEnableVertexAttribArray(2); 62 | 63 | glBindBuffer(GL_ARRAY_BUFFER, vbo); 64 | glVertexAttribPointer(0, 3, GL_FLOAT, false, Vertex.SIZE * 4, 0); 65 | glVertexAttribPointer(1, 2, GL_FLOAT, false, Vertex.SIZE * 4, 12); 66 | glVertexAttribPointer(2, 3, GL_FLOAT, false, Vertex.SIZE * 4, 20); 67 | 68 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); 69 | glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0); 70 | 71 | glDisableVertexAttribArray(0); 72 | glDisableVertexAttribArray(1); 73 | glDisableVertexAttribArray(2); 74 | } 75 | 76 | private void calcNormals(Vertex[] vertices, int[] indices) 77 | { 78 | for(int i = 0; i < indices.length; i += 3) 79 | { 80 | int i0 = indices[i]; 81 | int i1 = indices[i + 1]; 82 | int i2 = indices[i + 2]; 83 | 84 | Vector3f v1 = vertices[i1].getPos().sub(vertices[i0].getPos()); 85 | Vector3f v2 = vertices[i2].getPos().sub(vertices[i0].getPos()); 86 | 87 | Vector3f normal = v1.cross(v2).normalized(); 88 | 89 | vertices[i0].setNormal(vertices[i0].getNormal().add(normal)); 90 | vertices[i1].setNormal(vertices[i1].getNormal().add(normal)); 91 | vertices[i2].setNormal(vertices[i2].getNormal().add(normal)); 92 | } 93 | 94 | for(int i = 0; i < vertices.length; i++) 95 | vertices[i].setNormal(vertices[i].getNormal().normalized()); 96 | } 97 | 98 | private Mesh loadMesh(String fileName) 99 | { 100 | String[] splitArray = fileName.split("\\."); 101 | String ext = splitArray[splitArray.length - 1]; 102 | 103 | if(!ext.equals("obj")) 104 | { 105 | System.err.println("Error: File format not supported for mesh data: " + ext); 106 | new Exception().printStackTrace(); 107 | System.exit(1); 108 | } 109 | 110 | ArrayList vertices = new ArrayList(); 111 | ArrayList indices = new ArrayList(); 112 | 113 | BufferedReader meshReader = null; 114 | 115 | try 116 | { 117 | meshReader = new BufferedReader(new FileReader("./res/models/" + fileName)); 118 | String line; 119 | 120 | while((line = meshReader.readLine()) != null) 121 | { 122 | String[] tokens = line.split(" "); 123 | tokens = Util.removeEmptyStrings(tokens); 124 | 125 | if(tokens.length == 0 || tokens[0].equals("#")) 126 | continue; 127 | else if(tokens[0].equals("v")) 128 | { 129 | vertices.add(new Vertex(new Vector3f(Float.valueOf(tokens[1]), 130 | Float.valueOf(tokens[2]), 131 | Float.valueOf(tokens[3])))); 132 | } 133 | else if(tokens[0].equals("f")) 134 | { 135 | indices.add(Integer.parseInt(tokens[1].split("/")[0]) - 1); 136 | indices.add(Integer.parseInt(tokens[2].split("/")[0]) - 1); 137 | indices.add(Integer.parseInt(tokens[3].split("/")[0]) - 1); 138 | 139 | if(tokens.length > 4) 140 | { 141 | indices.add(Integer.parseInt(tokens[1].split("/")[0]) - 1); 142 | indices.add(Integer.parseInt(tokens[3].split("/")[0]) - 1); 143 | indices.add(Integer.parseInt(tokens[4].split("/")[0]) - 1); 144 | } 145 | } 146 | } 147 | 148 | meshReader.close(); 149 | 150 | Vertex[] vertexData = new Vertex[vertices.size()]; 151 | vertices.toArray(vertexData); 152 | 153 | Integer[] indexData = new Integer[indices.size()]; 154 | indices.toArray(indexData); 155 | 156 | addVertices(vertexData, Util.toIntArray(indexData), true); 157 | } 158 | catch(Exception e) 159 | { 160 | e.printStackTrace(); 161 | System.exit(1); 162 | } 163 | 164 | return null; 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /src/com/base/engine/PhongShader.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | public class PhongShader extends Shader 4 | { 5 | private static final int MAX_POINT_LIGHTS = 4; 6 | private static final int MAX_SPOT_LIGHTS = 4; 7 | 8 | private static final PhongShader instance = new PhongShader(); 9 | 10 | public static PhongShader getInstance() 11 | { 12 | return instance; 13 | } 14 | 15 | private static Vector3f ambientLight = new Vector3f(0.1f,0.1f,0.1f); 16 | private static DirectionalLight directionalLight = new DirectionalLight(new BaseLight(new Vector3f(0,0,0), 0), new Vector3f(0,0,0)); 17 | private static PointLight[] pointLights = new PointLight[] {}; 18 | private static SpotLight[] spotLights = new SpotLight[] {}; 19 | 20 | private PhongShader() 21 | { 22 | super(); 23 | 24 | addVertexShaderFromFile("phongVertex.vs"); 25 | addFragmentShaderFromFile("phongFragment.fs"); 26 | compileShader(); 27 | 28 | addUniform("transform"); 29 | addUniform("transformProjected"); 30 | addUniform("baseColor"); 31 | addUniform("ambientLight"); 32 | 33 | addUniform("specularIntensity"); 34 | addUniform("specularPower"); 35 | addUniform("eyePos"); 36 | 37 | addUniform("directionalLight.base.color"); 38 | addUniform("directionalLight.base.intensity"); 39 | addUniform("directionalLight.direction"); 40 | 41 | for(int i = 0; i < MAX_POINT_LIGHTS; i++) 42 | { 43 | addUniform("pointLights[" + i + "].base.color"); 44 | addUniform("pointLights[" + i + "].base.intensity"); 45 | addUniform("pointLights[" + i + "].atten.constant"); 46 | addUniform("pointLights[" + i + "].atten.linear"); 47 | addUniform("pointLights[" + i + "].atten.exponent"); 48 | addUniform("pointLights[" + i + "].position"); 49 | addUniform("pointLights[" + i + "].range"); 50 | } 51 | 52 | for(int i = 0; i < MAX_SPOT_LIGHTS; i++) 53 | { 54 | addUniform("spotLights[" + i + "].pointLight.base.color"); 55 | addUniform("spotLights[" + i + "].pointLight.base.intensity"); 56 | addUniform("spotLights[" + i + "].pointLight.atten.constant"); 57 | addUniform("spotLights[" + i + "].pointLight.atten.linear"); 58 | addUniform("spotLights[" + i + "].pointLight.atten.exponent"); 59 | addUniform("spotLights[" + i + "].pointLight.position"); 60 | addUniform("spotLights[" + i + "].pointLight.range"); 61 | addUniform("spotLights[" + i + "].direction"); 62 | addUniform("spotLights[" + i + "].cutoff"); 63 | } 64 | } 65 | 66 | public void updateUniforms(Matrix4f worldMatrix, Matrix4f projectedMatrix, Material material) 67 | { 68 | if(material.getTexture() != null) 69 | material.getTexture().bind(); 70 | else 71 | RenderUtil.unbindTextures(); 72 | 73 | setUniform("transformProjected", projectedMatrix); 74 | setUniform("transform", worldMatrix); 75 | setUniform("baseColor", material.getColor()); 76 | 77 | setUniform("ambientLight", ambientLight); 78 | setUniform("directionalLight", directionalLight); 79 | 80 | for(int i = 0; i < pointLights.length; i++) 81 | setUniform("pointLights[" + i + "]", pointLights[i]); 82 | 83 | for(int i = 0; i < spotLights.length; i++) 84 | setUniform("spotLights[" + i + "]", spotLights[i]); 85 | 86 | setUniformf("specularIntensity", material.getSpecularIntensity()); 87 | setUniformf("specularPower", material.getSpecularPower()); 88 | 89 | setUniform("eyePos", Transform.getCamera().getPos()); 90 | } 91 | 92 | public static Vector3f getAmbientLight() 93 | { 94 | return ambientLight; 95 | } 96 | 97 | public static void setAmbientLight(Vector3f ambientLight) 98 | { 99 | PhongShader.ambientLight = ambientLight; 100 | } 101 | 102 | public static void setDirectionalLight(DirectionalLight directionalLight) 103 | { 104 | PhongShader.directionalLight = directionalLight; 105 | } 106 | 107 | public static void setPointLight(PointLight[] pointLights) 108 | { 109 | if(pointLights.length > MAX_POINT_LIGHTS) 110 | { 111 | System.err.println("Error: You passed in too many point lights. Max allowed is " + MAX_POINT_LIGHTS + ", you passed in " + pointLights.length); 112 | new Exception().printStackTrace(); 113 | System.exit(1); 114 | } 115 | 116 | PhongShader.pointLights = pointLights; 117 | } 118 | 119 | public static void setSpotLights(SpotLight[] spotLights) 120 | { 121 | if(spotLights.length > MAX_SPOT_LIGHTS) 122 | { 123 | System.err.println("Error: You passed in too many spot lights. Max allowed is " + MAX_SPOT_LIGHTS + ", you passed in " + spotLights.length); 124 | new Exception().printStackTrace(); 125 | System.exit(1); 126 | } 127 | 128 | PhongShader.spotLights = spotLights; 129 | } 130 | 131 | public void setUniform(String uniformName, BaseLight baseLight) 132 | { 133 | setUniform(uniformName + ".color", baseLight.getColor()); 134 | setUniformf(uniformName + ".intensity", baseLight.getIntensity()); 135 | } 136 | 137 | public void setUniform(String uniformName, DirectionalLight directionalLight) 138 | { 139 | setUniform(uniformName + ".base", directionalLight.getBase()); 140 | setUniform(uniformName + ".direction", directionalLight.getDirection()); 141 | } 142 | 143 | public void setUniform(String uniformName, PointLight pointLight) 144 | { 145 | setUniform(uniformName + ".base", pointLight.getBaseLight()); 146 | setUniformf(uniformName + ".atten.constant", pointLight.getAtten().getConstant()); 147 | setUniformf(uniformName + ".atten.linear", pointLight.getAtten().getLinear()); 148 | setUniformf(uniformName + ".atten.exponent", pointLight.getAtten().getExponent()); 149 | setUniform(uniformName + ".position", pointLight.getPosition()); 150 | setUniformf(uniformName + ".range", pointLight.getRange()); 151 | } 152 | 153 | public void setUniform(String uniformName, SpotLight spotLight) 154 | { 155 | setUniform(uniformName + ".pointLight", spotLight.getPointLight()); 156 | setUniform(uniformName + ".direction", spotLight.getDirection()); 157 | setUniformf(uniformName + ".cutoff", spotLight.getCutoff()); 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /src/com/base/engine/Player.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | import java.util.Random; 4 | 5 | public class Player 6 | { 7 | public static final float GUN_OFFSET = -0.0875f; 8 | 9 | public static final float SCALE = 0.0625f; 10 | public static final float SIZEY = SCALE; 11 | public static final float SIZEX = (float)((double)SIZEY / (1.0379746835443037974683544303797 * 2.0)); 12 | public static final float START = 0; 13 | 14 | public static final float OFFSET_X = 0.0f; //0.05f 15 | public static final float OFFSET_Y = 0.0f; //0.01f 16 | 17 | public static final float TEX_MIN_X = -OFFSET_X; 18 | public static final float TEX_MAX_X = -1 - OFFSET_X; 19 | public static final float TEX_MIN_Y = -OFFSET_Y; 20 | public static final float TEX_MAX_Y = 1 - OFFSET_Y; 21 | 22 | private static final float MOUSE_SENSITIVITY = 0.33f; 23 | private static final float MOVE_SPEED = 5f; 24 | public static final float PLAYER_SIZE = 0.2f; 25 | public static final float SHOOT_DISTANCE = 1000.0f; 26 | private static final Vector3f zeroVector = new Vector3f(0,0,0); 27 | public static final int DAMAGE_MIN = 20; 28 | public static final int DAMAGE_MAX = 60; 29 | public static final int MAX_HEALTH = 100; 30 | 31 | private static Mesh mesh; 32 | private static Material gunMaterial; 33 | 34 | private Transform gunTransform; 35 | private Camera camera; 36 | private Random rand; 37 | private int health; 38 | 39 | private static boolean mouseLocked = false; 40 | private Vector2f centerPosition = new Vector2f(Window.getWidth()/2, Window.getHeight()/2); 41 | private Vector3f movementVector; 42 | 43 | public Player(Vector3f position) 44 | { 45 | if(mesh == null) 46 | { 47 | Vertex[] vertices = new Vertex[]{new Vertex(new Vector3f(-SIZEX,START,START), new Vector2f(TEX_MAX_X,TEX_MAX_Y)), 48 | new Vertex(new Vector3f(-SIZEX,SIZEY,START), new Vector2f(TEX_MAX_X,TEX_MIN_Y)), 49 | new Vertex(new Vector3f(SIZEX,SIZEY,START), new Vector2f(TEX_MIN_X,TEX_MIN_Y)), 50 | new Vertex(new Vector3f(SIZEX,START,START), new Vector2f(TEX_MIN_X,TEX_MAX_Y))}; 51 | 52 | int[] indices = new int[]{0,1,2, 53 | 0,2,3}; 54 | 55 | mesh = new Mesh(vertices, indices); 56 | } 57 | 58 | if(gunMaterial == null) 59 | { 60 | gunMaterial = new Material(new Texture("PISGB0.png")); 61 | } 62 | 63 | camera = new Camera(position, new Vector3f(0,0,-1), new Vector3f(0,1,0)); 64 | rand = new Random(); 65 | health = MAX_HEALTH; 66 | gunTransform = new Transform(); 67 | gunTransform.setTranslation(new Vector3f(7,0,7)); 68 | movementVector = zeroVector; 69 | } 70 | 71 | public void damage(int amt) 72 | { 73 | health -= amt; 74 | 75 | if(health > MAX_HEALTH) 76 | health = MAX_HEALTH; 77 | 78 | System.out.println(health); 79 | 80 | if(health <= 0) 81 | { 82 | Game.setIsRunning(false); 83 | System.out.println("You just died! GAME OVER!"); 84 | } 85 | } 86 | 87 | public int getDamage() 88 | { 89 | return rand.nextInt(DAMAGE_MAX - DAMAGE_MIN) + DAMAGE_MIN; 90 | } 91 | 92 | public int getHealth() 93 | { 94 | return health; 95 | } 96 | 97 | public int getMaxHealth() 98 | { 99 | return MAX_HEALTH; 100 | } 101 | 102 | public void input() 103 | { 104 | if(Input.getKeyDown(Input.KEY_E)) 105 | { 106 | Game.getLevel().openDoors(camera.getPos(), true); 107 | } 108 | 109 | if(Input.getKey(Input.KEY_ESCAPE)) 110 | { 111 | Input.setCursor(true); 112 | mouseLocked = false; 113 | } 114 | if(Input.getMouseDown(0)) 115 | { 116 | if(!mouseLocked) 117 | { 118 | Input.setMousePosition(centerPosition); 119 | Input.setCursor(false); 120 | mouseLocked = true; 121 | } 122 | else 123 | { 124 | Vector2f lineStart = new Vector2f(camera.getPos().getX(), camera.getPos().getZ()); 125 | Vector2f castDirection = new Vector2f(camera.getForward().getX(), camera.getForward().getZ()).normalized(); 126 | Vector2f lineEnd = lineStart.add(castDirection.mul(SHOOT_DISTANCE)); 127 | 128 | Game.getLevel().checkIntersections(lineStart, lineEnd, true); 129 | } 130 | } 131 | 132 | movementVector = zeroVector; 133 | 134 | if(Input.getKey(Input.KEY_W)) 135 | movementVector = movementVector.add(camera.getForward());//camera.move(camera.getForward(), movAmt); 136 | if(Input.getKey(Input.KEY_S)) 137 | movementVector = movementVector.sub(camera.getForward());//camera.move(camera.getForward(), -movAmt); 138 | if(Input.getKey(Input.KEY_A)) 139 | movementVector = movementVector.add(camera.getLeft());//camera.move(camera.getLeft(), movAmt); 140 | if(Input.getKey(Input.KEY_D)) 141 | movementVector = movementVector.add(camera.getRight());//camera.move(camera.getRight(), movAmt); 142 | 143 | if(mouseLocked) 144 | { 145 | Vector2f deltaPos = Input.getMousePosition().sub(centerPosition); 146 | 147 | boolean rotY = deltaPos.getX() != 0; 148 | boolean rotX = deltaPos.getY() != 0; 149 | 150 | if(rotY) 151 | camera.rotateY(deltaPos.getX() * MOUSE_SENSITIVITY); 152 | if(rotX) 153 | camera.rotateX(-deltaPos.getY() * MOUSE_SENSITIVITY); 154 | 155 | if(rotY || rotX) 156 | Input.setMousePosition(centerPosition); 157 | } 158 | } 159 | 160 | public void update() 161 | { 162 | float movAmt = (float)(MOVE_SPEED * Time.getDelta()); 163 | 164 | movementVector.setY(0); 165 | 166 | if(movementVector.length() > 0) 167 | movementVector = movementVector.normalized(); 168 | 169 | Vector3f oldPos = camera.getPos(); 170 | Vector3f newPos = oldPos.add(movementVector.mul(movAmt)); 171 | 172 | Vector3f collisionVector = Game.getLevel().checkCollision(oldPos, newPos, PLAYER_SIZE, PLAYER_SIZE); 173 | movementVector = movementVector.mul(collisionVector); 174 | 175 | if(movementVector.length() > 0) 176 | camera.move(movementVector, movAmt); 177 | 178 | //Gun movement 179 | gunTransform.setTranslation(camera.getPos().add(camera.getForward().normalized().mul(0.105f))); 180 | gunTransform.getTranslation().setY(gunTransform.getTranslation().getY() + GUN_OFFSET); 181 | 182 | Vector3f directionToCamera = Transform.getCamera().getPos().sub(gunTransform.getTranslation()); 183 | 184 | float angleToFaceTheCamera = (float)Math.toDegrees(Math.atan(directionToCamera.getZ() / directionToCamera.getX())); 185 | 186 | if(directionToCamera.getX() < 0) 187 | angleToFaceTheCamera += 180; 188 | 189 | gunTransform.getRotation().setY(angleToFaceTheCamera + 90); 190 | } 191 | 192 | public void render() 193 | { 194 | Shader shader = Game.getLevel().getShader(); 195 | shader.updateUniforms(gunTransform.getTransformation(), gunTransform.getProjectedTransformation(), gunMaterial); 196 | mesh.draw(); 197 | } 198 | 199 | public Camera getCamera() 200 | { 201 | return camera; 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /src/com/base/engine/Input.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.lwjgl.input.Keyboard; 6 | import org.lwjgl.input.Mouse; 7 | 8 | public class Input 9 | { 10 | public static final int NUM_KEYCODES = 256; 11 | public static final int NUM_MOUSEBUTTONS = 5; 12 | 13 | //All these constants come from LWJGL's Keyboard class 14 | public static final int KEY_NONE = 0x00; 15 | public static final int KEY_ESCAPE = 0x01; 16 | public static final int KEY_1 = 0x02; 17 | public static final int KEY_2 = 0x03; 18 | public static final int KEY_3 = 0x04; 19 | public static final int KEY_4 = 0x05; 20 | public static final int KEY_5 = 0x06; 21 | public static final int KEY_6 = 0x07; 22 | public static final int KEY_7 = 0x08; 23 | public static final int KEY_8 = 0x09; 24 | public static final int KEY_9 = 0x0A; 25 | public static final int KEY_0 = 0x0B; 26 | public static final int KEY_MINUS = 0x0C; /* - on main keyboard */ 27 | public static final int KEY_EQUALS = 0x0D; 28 | public static final int KEY_BACK = 0x0E; /* backspace */ 29 | public static final int KEY_TAB = 0x0F; 30 | public static final int KEY_Q = 0x10; 31 | public static final int KEY_W = 0x11; 32 | public static final int KEY_E = 0x12; 33 | public static final int KEY_R = 0x13; 34 | public static final int KEY_T = 0x14; 35 | public static final int KEY_Y = 0x15; 36 | public static final int KEY_U = 0x16; 37 | public static final int KEY_I = 0x17; 38 | public static final int KEY_O = 0x18; 39 | public static final int KEY_P = 0x19; 40 | public static final int KEY_LBRACKET = 0x1A; 41 | public static final int KEY_RBRACKET = 0x1B; 42 | public static final int KEY_RETURN = 0x1C; /* Enter on main keyboard */ 43 | public static final int KEY_LCONTROL = 0x1D; 44 | public static final int KEY_A = 0x1E; 45 | public static final int KEY_S = 0x1F; 46 | public static final int KEY_D = 0x20; 47 | public static final int KEY_F = 0x21; 48 | public static final int KEY_G = 0x22; 49 | public static final int KEY_H = 0x23; 50 | public static final int KEY_J = 0x24; 51 | public static final int KEY_K = 0x25; 52 | public static final int KEY_L = 0x26; 53 | public static final int KEY_SEMICOLON = 0x27; 54 | public static final int KEY_APOSTROPHE = 0x28; 55 | public static final int KEY_GRAVE = 0x29; /* accent grave */ 56 | public static final int KEY_LSHIFT = 0x2A; 57 | public static final int KEY_BACKSLASH = 0x2B; 58 | public static final int KEY_Z = 0x2C; 59 | public static final int KEY_X = 0x2D; 60 | public static final int KEY_C = 0x2E; 61 | public static final int KEY_V = 0x2F; 62 | public static final int KEY_B = 0x30; 63 | public static final int KEY_N = 0x31; 64 | public static final int KEY_M = 0x32; 65 | public static final int KEY_COMMA = 0x33; 66 | public static final int KEY_PERIOD = 0x34; /* . on main keyboard */ 67 | public static final int KEY_SLASH = 0x35; /* / on main keyboard */ 68 | public static final int KEY_RSHIFT = 0x36; 69 | public static final int KEY_MULTIPLY = 0x37; /* * on numeric keypad */ 70 | public static final int KEY_LMENU = 0x38; /* left Alt */ 71 | public static final int KEY_LALT = KEY_LMENU; /* left Alt */ 72 | public static final int KEY_SPACE = 0x39; 73 | public static final int KEY_CAPITAL = 0x3A; 74 | public static final int KEY_F1 = 0x3B; 75 | public static final int KEY_F2 = 0x3C; 76 | public static final int KEY_F3 = 0x3D; 77 | public static final int KEY_F4 = 0x3E; 78 | public static final int KEY_F5 = 0x3F; 79 | public static final int KEY_F6 = 0x40; 80 | public static final int KEY_F7 = 0x41; 81 | public static final int KEY_F8 = 0x42; 82 | public static final int KEY_F9 = 0x43; 83 | public static final int KEY_F10 = 0x44; 84 | public static final int KEY_NUMLOCK = 0x45; 85 | public static final int KEY_SCROLL = 0x46; /* Scroll Lock */ 86 | public static final int KEY_NUMPAD7 = 0x47; 87 | public static final int KEY_NUMPAD8 = 0x48; 88 | public static final int KEY_NUMPAD9 = 0x49; 89 | public static final int KEY_SUBTRACT = 0x4A; /* - on numeric keypad */ 90 | public static final int KEY_NUMPAD4 = 0x4B; 91 | public static final int KEY_NUMPAD5 = 0x4C; 92 | public static final int KEY_NUMPAD6 = 0x4D; 93 | public static final int KEY_ADD = 0x4E; /* + on numeric keypad */ 94 | public static final int KEY_NUMPAD1 = 0x4F; 95 | public static final int KEY_NUMPAD2 = 0x50; 96 | public static final int KEY_NUMPAD3 = 0x51; 97 | public static final int KEY_NUMPAD0 = 0x52; 98 | public static final int KEY_DECIMAL = 0x53; /* . on numeric keypad */ 99 | public static final int KEY_F11 = 0x57; 100 | public static final int KEY_F12 = 0x58; 101 | public static final int KEY_F13 = 0x64; /* (NEC PC98) */ 102 | public static final int KEY_F14 = 0x65; /* (NEC PC98) */ 103 | public static final int KEY_F15 = 0x66; /* (NEC PC98) */ 104 | public static final int KEY_KANA = 0x70; /* (Japanese keyboard) */ 105 | public static final int KEY_CONVERT = 0x79; /* (Japanese keyboard) */ 106 | public static final int KEY_NOCONVERT = 0x7B; /* (Japanese keyboard) */ 107 | public static final int KEY_YEN = 0x7D; /* (Japanese keyboard) */ 108 | public static final int KEY_NUMPADEQUALS = 0x8D; /* = on numeric keypad (NEC PC98) */ 109 | public static final int KEY_CIRCUMFLEX = 0x90; /* (Japanese keyboard) */ 110 | public static final int KEY_AT = 0x91; /* (NEC PC98) */ 111 | public static final int KEY_COLON = 0x92; /* (NEC PC98) */ 112 | public static final int KEY_UNDERLINE = 0x93; /* (NEC PC98) */ 113 | public static final int KEY_KANJI = 0x94; /* (Japanese keyboard) */ 114 | public static final int KEY_STOP = 0x95; /* (NEC PC98) */ 115 | public static final int KEY_AX = 0x96; /* (Japan AX) */ 116 | public static final int KEY_UNLABELED = 0x97; /* (J3100) */ 117 | public static final int KEY_NUMPADENTER = 0x9C; /* Enter on numeric keypad */ 118 | public static final int KEY_RCONTROL = 0x9D; 119 | public static final int KEY_NUMPADCOMMA = 0xB3; /* , on numeric keypad (NEC PC98) */ 120 | public static final int KEY_DIVIDE = 0xB5; /* / on numeric keypad */ 121 | public static final int KEY_SYSRQ = 0xB7; 122 | public static final int KEY_RMENU = 0xB8; /* right Alt */ 123 | public static final int KEY_RALT = KEY_RMENU; /* right Alt */ 124 | public static final int KEY_PAUSE = 0xC5; /* Pause */ 125 | public static final int KEY_HOME = 0xC7; /* Home on arrow keypad */ 126 | public static final int KEY_UP = 0xC8; /* UpArrow on arrow keypad */ 127 | public static final int KEY_PRIOR = 0xC9; /* PgUp on arrow keypad */ 128 | public static final int KEY_LEFT = 0xCB; /* LeftArrow on arrow keypad */ 129 | public static final int KEY_RIGHT = 0xCD; /* RightArrow on arrow keypad */ 130 | public static final int KEY_END = 0xCF; /* End on arrow keypad */ 131 | public static final int KEY_DOWN = 0xD0; /* DownArrow on arrow keypad */ 132 | public static final int KEY_NEXT = 0xD1; /* PgDn on arrow keypad */ 133 | public static final int KEY_INSERT = 0xD2; /* Insert on arrow keypad */ 134 | public static final int KEY_DELETE = 0xD3; /* Delete on arrow keypad */ 135 | public static final int KEY_LMETA = 0xDB; /* Left Windows/Option key */ 136 | public static final int KEY_LWIN = KEY_LMETA; /* Left Windows key */ 137 | public static final int KEY_RMETA = 0xDC; /* Right Windows/Option key */ 138 | public static final int KEY_RWIN = KEY_RMETA; /* Right Windows key */ 139 | public static final int KEY_APPS = 0xDD; /* AppMenu key */ 140 | public static final int KEY_POWER = 0xDE; 141 | public static final int KEY_SLEEP = 0xDF; 142 | 143 | private static boolean[] lastKeys = new boolean[NUM_KEYCODES]; 144 | private static boolean[] lastMouse = new boolean[NUM_MOUSEBUTTONS]; 145 | 146 | public static void update() 147 | { 148 | for(int i = 0; i < NUM_KEYCODES; i++) 149 | lastKeys[i] = getKey(i); 150 | 151 | for(int i = 0; i < NUM_MOUSEBUTTONS; i++) 152 | lastMouse[i] = getMouse(i); 153 | } 154 | 155 | public static boolean getKey(int keyCode) 156 | { 157 | return Keyboard.isKeyDown(keyCode); 158 | } 159 | 160 | public static boolean getKeyDown(int keyCode) 161 | { 162 | return getKey(keyCode) && !lastKeys[keyCode]; 163 | } 164 | 165 | public static boolean getKeyUp(int keyCode) 166 | { 167 | return !getKey(keyCode) && lastKeys[keyCode]; 168 | } 169 | 170 | public static boolean getMouse(int mouseButton) 171 | { 172 | return Mouse.isButtonDown(mouseButton); 173 | } 174 | 175 | public static boolean getMouseDown(int mouseButton) 176 | { 177 | return getMouse(mouseButton) && !lastMouse[mouseButton]; 178 | } 179 | 180 | public static boolean getMouseUp(int mouseButton) 181 | { 182 | return !getMouse(mouseButton) && lastMouse[mouseButton]; 183 | } 184 | 185 | public static Vector2f getMousePosition() 186 | { 187 | return new Vector2f(Mouse.getX(), Mouse.getY()); 188 | } 189 | 190 | public static void setMousePosition(Vector2f pos) 191 | { 192 | Mouse.setCursorPosition((int)pos.getX(), (int)pos.getY()); 193 | } 194 | 195 | public static void setCursor(boolean enabled) 196 | { 197 | Mouse.setGrabbed(!enabled); 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /src/com/base/engine/Monster.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Random; 5 | 6 | public class Monster 7 | { 8 | public static final float SCALE = 0.7f; 9 | public static final float SIZEY = SCALE; 10 | public static final float SIZEX = (float)((double)SIZEY / (1.9310344827586206896551724137931 * 2.0)); 11 | public static final float START = 0; 12 | 13 | public static final float OFFSET_X = 0.0f; //0.05f 14 | public static final float OFFSET_Y = 0.0f; //0.01f 15 | public static final float OFFSET_FROM_GROUND = 0.0f; //-0.075f 16 | 17 | public static final float TEX_MIN_X = -OFFSET_X; 18 | public static final float TEX_MAX_X = -1 - OFFSET_X; 19 | public static final float TEX_MIN_Y = -OFFSET_Y; 20 | public static final float TEX_MAX_Y = 1 - OFFSET_Y; 21 | 22 | public static final int STATE_IDLE = 0; 23 | public static final int STATE_CHASE = 1; 24 | public static final int STATE_ATTACK = 2; 25 | public static final int STATE_DYING = 3; 26 | public static final int STATE_DEAD = 4; 27 | 28 | public static final float MOVE_SPEED = 1.0f; 29 | public static final float MOVEMENT_STOP_DISTANCE = 1.5f; 30 | public static final float MONSTER_WIDTH = 0.2f; 31 | public static final float MONSTER_LENGTH = 0.2f; 32 | 33 | public static final float SHOOT_DISTANCE = 1000.0f; 34 | public static final float SHOT_ANGLE = 10.0f; 35 | public static final float ATTACK_CHANCE = 0.5f; 36 | public static final int MAX_HEALTH = 100; 37 | public static final int DAMAGE_MIN = 5; 38 | public static final int DAMAGE_MAX = 30; 39 | 40 | private static Mesh mesh; 41 | private static ArrayList animations; 42 | 43 | private Material material; 44 | private Transform transform; 45 | private Random rand; 46 | private int state; 47 | private int health; 48 | private boolean canLook; 49 | private boolean canAttack; 50 | private double deathTime; 51 | 52 | public Monster(Transform transform) 53 | { 54 | if(animations == null) 55 | { 56 | animations = new ArrayList(); 57 | 58 | animations.add(new Texture("SSWVA1.png")); 59 | animations.add(new Texture("SSWVB1.png")); 60 | animations.add(new Texture("SSWVC1.png")); 61 | animations.add(new Texture("SSWVD1.png")); 62 | 63 | animations.add(new Texture("SSWVE0.png")); 64 | animations.add(new Texture("SSWVF0.png")); 65 | animations.add(new Texture("SSWVG0.png")); 66 | 67 | animations.add(new Texture("SSWVH0.png")); 68 | 69 | animations.add(new Texture("SSWVI0.png")); 70 | animations.add(new Texture("SSWVJ0.png")); 71 | animations.add(new Texture("SSWVK0.png")); 72 | animations.add(new Texture("SSWVL0.png")); 73 | 74 | animations.add(new Texture("SSWVM0.png")); 75 | } 76 | 77 | if(mesh == null) 78 | { 79 | Vertex[] vertices = new Vertex[]{new Vertex(new Vector3f(-SIZEX,START,START), new Vector2f(TEX_MAX_X,TEX_MAX_Y)), 80 | new Vertex(new Vector3f(-SIZEX,SIZEY,START), new Vector2f(TEX_MAX_X,TEX_MIN_Y)), 81 | new Vertex(new Vector3f(SIZEX,SIZEY,START), new Vector2f(TEX_MIN_X,TEX_MIN_Y)), 82 | new Vertex(new Vector3f(SIZEX,START,START), new Vector2f(TEX_MIN_X,TEX_MAX_Y))}; 83 | 84 | int[] indices = new int[]{0,1,2, 85 | 0,2,3}; 86 | 87 | mesh = new Mesh(vertices, indices); 88 | } 89 | 90 | this.transform = transform; 91 | this.state = STATE_IDLE; 92 | this.canAttack = false; 93 | this.canLook = false; 94 | this.health = MAX_HEALTH; 95 | this.rand = new Random(); 96 | this.material = new Material(animations.get(0)); 97 | this.deathTime = 0; 98 | } 99 | 100 | public Transform getTransform() 101 | { 102 | return transform; 103 | } 104 | 105 | public Vector2f getSize() 106 | { 107 | return new Vector2f(MONSTER_WIDTH, MONSTER_LENGTH); 108 | } 109 | 110 | public void damage(int amt) 111 | { 112 | if(state == STATE_IDLE) 113 | state = STATE_CHASE; 114 | 115 | health -= amt; 116 | 117 | if(health <= 0) 118 | state = STATE_DYING; 119 | } 120 | 121 | private void idleUpdate(Vector3f orientation, float distance) 122 | { 123 | double time = ((double)Time.getTime())/((double)Time.SECOND); 124 | double timeDecimals = time - (double)((int)time); 125 | 126 | if(timeDecimals < 0.5) 127 | { 128 | canLook = true; 129 | material.setTexture(animations.get(0)); 130 | } 131 | else 132 | { 133 | material.setTexture(animations.get(1)); 134 | 135 | if(canLook) 136 | { 137 | Vector2f lineStart = new Vector2f(transform.getTranslation().getX(), transform.getTranslation().getZ()); 138 | Vector2f castDirection = new Vector2f(orientation.getX(), orientation.getZ()); 139 | Vector2f lineEnd = lineStart.add(castDirection.mul(SHOOT_DISTANCE)); 140 | 141 | Vector2f collisionVector = Game.getLevel().checkIntersections(lineStart, lineEnd, false); 142 | 143 | Vector2f playerIntersectVector = new Vector2f(Transform.getCamera().getPos().getX(), Transform.getCamera().getPos().getZ()); 144 | 145 | if(collisionVector == null || 146 | playerIntersectVector.sub(lineStart).length() < collisionVector.sub(lineStart).length()) 147 | { 148 | state = STATE_CHASE; 149 | } 150 | 151 | canLook = false; 152 | } 153 | } 154 | } 155 | 156 | private void chaseUpdate(Vector3f orientation, float distance) 157 | { 158 | double time = ((double)Time.getTime())/((double)Time.SECOND); 159 | double timeDecimals = time - (double)((int)time); 160 | 161 | if(timeDecimals < 0.25) 162 | material.setTexture(animations.get(0)); 163 | else if(timeDecimals < 0.5) 164 | material.setTexture(animations.get(1)); 165 | else if(timeDecimals < 0.75) 166 | material.setTexture(animations.get(2)); 167 | else 168 | material.setTexture(animations.get(3)); 169 | 170 | if(rand.nextDouble() < ATTACK_CHANCE * Time.getDelta()) 171 | state = STATE_ATTACK; 172 | 173 | if(distance > MOVEMENT_STOP_DISTANCE) 174 | { 175 | float moveAmount = MOVE_SPEED * (float) Time.getDelta(); 176 | 177 | Vector3f oldPos = transform.getTranslation(); 178 | Vector3f newPos = transform.getTranslation().add(orientation.mul(moveAmount)); 179 | 180 | Vector3f collisionVector = Game.getLevel().checkCollision(oldPos, newPos, MONSTER_WIDTH, MONSTER_LENGTH); 181 | 182 | Vector3f movementVector = collisionVector.mul(orientation); 183 | 184 | if(movementVector.length() > 0) 185 | transform.setTranslation(transform.getTranslation().add(movementVector.mul(moveAmount))); 186 | 187 | if(movementVector.sub(orientation).length() != 0) 188 | Game.getLevel().openDoors(transform.getTranslation(), false); 189 | } 190 | else 191 | state = STATE_ATTACK; 192 | } 193 | 194 | private void attackUpdate(Vector3f orientation, float distance) 195 | { 196 | double time = ((double)Time.getTime())/((double)Time.SECOND); 197 | double timeDecimals = time - (double)((int)time); 198 | 199 | if(timeDecimals < 0.25) 200 | material.setTexture(animations.get(4)); 201 | else if(timeDecimals < 0.5) 202 | material.setTexture(animations.get(5)); 203 | else if(timeDecimals < 0.75) 204 | { 205 | material.setTexture(animations.get(6)); 206 | if(canAttack) 207 | { 208 | Vector2f lineStart = new Vector2f(transform.getTranslation().getX(), transform.getTranslation().getZ()); 209 | Vector2f castDirection = new Vector2f(orientation.getX(), orientation.getZ()).rotate((rand.nextFloat() - 0.5f) * SHOT_ANGLE); 210 | Vector2f lineEnd = lineStart.add(castDirection.mul(SHOOT_DISTANCE)); 211 | 212 | Vector2f collisionVector = Game.getLevel().checkIntersections(lineStart, lineEnd, false); 213 | 214 | Vector2f playerIntersectVector = Game.getLevel().lineIntersectRect(lineStart, lineEnd, 215 | new Vector2f(Transform.getCamera().getPos().getX(), Transform.getCamera().getPos().getZ()), 216 | new Vector2f(Player.PLAYER_SIZE, Player.PLAYER_SIZE)); 217 | 218 | if(playerIntersectVector != null && (collisionVector == null || 219 | playerIntersectVector.sub(lineStart).length() < collisionVector.sub(lineStart).length())) 220 | { 221 | Game.getLevel().damagePlayer(rand.nextInt(DAMAGE_MAX - DAMAGE_MIN) + DAMAGE_MIN); 222 | } 223 | 224 | canAttack = false; 225 | } 226 | } 227 | else 228 | { 229 | material.setTexture(animations.get(5)); 230 | state = STATE_CHASE; 231 | canAttack = true; 232 | } 233 | 234 | } 235 | 236 | private void dyingUpdate(Vector3f orientation, float distance) 237 | { 238 | double time = ((double)Time.getTime())/((double)Time.SECOND); 239 | double timeDecimals = time - (double)((int)time); 240 | 241 | if(deathTime == 0) 242 | deathTime = time; 243 | 244 | final float time1 = 0.1f; 245 | final float time2 = 0.3f; 246 | final float time3 = 0.45f; 247 | final float time4 = 0.6f; 248 | 249 | if(time < deathTime + time1) 250 | { 251 | material.setTexture(animations.get(8)); 252 | transform.setScale(1,0.96428571428571428571428571428571f,1); 253 | } 254 | else if(time < deathTime + time2) 255 | { 256 | material.setTexture(animations.get(9)); 257 | transform.setScale(1.7f,0.9f,1); 258 | } 259 | else if(time < deathTime + time3) 260 | { 261 | material.setTexture(animations.get(10)); 262 | transform.setScale(1.7f,0.9f,1); 263 | } 264 | else if(time < deathTime + time4) 265 | { 266 | material.setTexture(animations.get(11)); 267 | transform.setScale(1.7f,0.5f,1); 268 | } 269 | else 270 | { 271 | state = STATE_DEAD; 272 | } 273 | } 274 | 275 | private void deadUpdate(Vector3f orientation, float distance) 276 | { 277 | material.setTexture(animations.get(12)); 278 | transform.setScale(1.7586206896551724137931034482759f,0.28571428571428571428571428571429f,1); 279 | } 280 | 281 | private void alignWithGround() 282 | { 283 | transform.getTranslation().setY(OFFSET_FROM_GROUND); 284 | } 285 | 286 | private void faceCamera(Vector3f directionToCamera) 287 | { 288 | float angleToFaceTheCamera = (float)Math.toDegrees(Math.atan(directionToCamera.getZ() / directionToCamera.getX())); 289 | 290 | if(directionToCamera.getX() < 0) 291 | angleToFaceTheCamera += 180; 292 | 293 | transform.getRotation().setY(angleToFaceTheCamera + 90); 294 | } 295 | 296 | public void update() 297 | { 298 | Vector3f directionToCamera = Transform.getCamera().getPos().sub(transform.getTranslation()); 299 | 300 | float distance = directionToCamera.length(); 301 | Vector3f orientation = directionToCamera.div(distance); 302 | 303 | alignWithGround(); 304 | faceCamera(orientation); 305 | 306 | switch(state) 307 | { 308 | case STATE_IDLE: idleUpdate(orientation, distance); break; 309 | case STATE_CHASE: chaseUpdate(orientation, distance); break; 310 | case STATE_ATTACK: attackUpdate(orientation, distance); break; 311 | case STATE_DYING: dyingUpdate(orientation, distance); break; 312 | case STATE_DEAD: deadUpdate(orientation, distance); break; 313 | } 314 | } 315 | 316 | public void render() 317 | { 318 | Shader shader = Game.getLevel().getShader(); 319 | shader.updateUniforms(transform.getTransformation(), transform.getProjectedTransformation(), material); 320 | mesh.draw(); 321 | } 322 | } 323 | -------------------------------------------------------------------------------- /src/com/base/engine/Level.java: -------------------------------------------------------------------------------- 1 | package com.base.engine; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class Level 6 | { 7 | private static final float SPOT_WIDTH = 1; 8 | private static final float SPOT_LENGTH = 1; 9 | private static final float SPOT_HEIGHT = 1; 10 | 11 | private static final int NUM_TEX_EXP = 4; 12 | private static final int NUM_TEXTURES = (int)Math.pow(2, NUM_TEX_EXP); 13 | private static final float OPEN_DISTANCE = 1.0f; 14 | private static final float DOOR_OPEN_MOVEMENT_AMOUNT = 0.9f; 15 | 16 | private Mesh mesh; 17 | private Bitmap level; 18 | private Shader shader; 19 | private Material material; 20 | private Transform transform; 21 | private Player player; 22 | private ArrayList doors; 23 | private ArrayList monsters; 24 | private ArrayList medkits; 25 | private ArrayList exitPoints; 26 | 27 | private ArrayList medkitsToRemove; 28 | 29 | private ArrayList collisionPosStart; 30 | private ArrayList collisionPosEnd; 31 | 32 | //WARNING: TEMP VARIABLE! 33 | //private Monster monster; 34 | 35 | public Player getPlayer() 36 | { 37 | return player; 38 | } 39 | 40 | public Level(String levelName, String textureName) 41 | { 42 | //this.player = player; 43 | medkitsToRemove = new ArrayList(); 44 | level = new Bitmap(levelName).flipY(); 45 | material = new Material(new Texture(textureName)); 46 | transform = new Transform(); 47 | 48 | shader = BasicShader.getInstance(); 49 | 50 | exitPoints = new ArrayList(); 51 | 52 | generateLevel(); 53 | // Transform tempTransform = new Transform(); 54 | // tempTransform.setTranslation(new Vector3f(12,0,12)); 55 | 56 | //monsters.add(new Monster(tempTransform)); 57 | //door = new Door(tempTransform, material); 58 | } 59 | 60 | public void openDoors(Vector3f position, boolean tryExitLevel) 61 | { 62 | for(Door door : doors) 63 | { 64 | if(door.getTransform().getTranslation().sub(position).length() < OPEN_DISTANCE) 65 | { 66 | door.open(); 67 | } 68 | } 69 | 70 | if(tryExitLevel) 71 | { 72 | for(Vector3f exitPoint : exitPoints) 73 | if(exitPoint.sub(position).length() < OPEN_DISTANCE) 74 | Game.loadNextLevel(); 75 | } 76 | } 77 | 78 | public void damagePlayer(int amt) 79 | { 80 | player.damage(amt); 81 | } 82 | 83 | public void input() 84 | { 85 | player.input(); 86 | } 87 | 88 | public void update() 89 | { 90 | for(Door door : doors) 91 | door.update(); 92 | 93 | player.update(); 94 | 95 | for(Medkit medkit : medkits) 96 | medkit.update(); 97 | 98 | for(Monster monster : monsters) 99 | monster.update(); 100 | 101 | for(Medkit medkit : medkitsToRemove) 102 | medkits.remove(medkit); 103 | } 104 | 105 | public void render() 106 | { 107 | shader.bind(); 108 | shader.updateUniforms(transform.getTransformation(), transform.getProjectedTransformation(), material); 109 | mesh.draw(); 110 | for(Door door : doors) 111 | door.render(); 112 | 113 | for(Monster monster : monsters) 114 | monster.render(); 115 | 116 | for(Medkit medkit : medkits) 117 | medkit.render(); 118 | 119 | player.render(); 120 | } 121 | 122 | public Vector3f checkCollision(Vector3f oldPos, Vector3f newPos, float objectWidth, float objectLength) 123 | { 124 | Vector2f collisionVector = new Vector2f(1,1); 125 | Vector3f movementVector = newPos.sub(oldPos); 126 | 127 | if(movementVector.length() > 0) 128 | { 129 | Vector2f blockSize = new Vector2f(SPOT_WIDTH, SPOT_LENGTH); 130 | Vector2f objectSize = new Vector2f(objectWidth, objectLength); 131 | 132 | Vector2f oldPos2 = new Vector2f(oldPos.getX(), oldPos.getZ()); 133 | Vector2f newPos2 = new Vector2f(newPos.getX(), newPos.getZ()); 134 | 135 | for(int i = 0; i < level.getWidth(); i++) 136 | for(int j = 0; j < level.getHeight(); j++) 137 | if((level.getPixel(i,j) & 0xFFFFFF) == 0) 138 | collisionVector = collisionVector.mul(rectCollide(oldPos2, newPos2, objectSize, blockSize.mul(new Vector2f(i,j)), blockSize)); 139 | 140 | 141 | for(Door door : doors) 142 | { 143 | Vector2f doorSize = door.getDoorSize(); 144 | Vector3f doorPos3f = door.getTransform().getTranslation(); 145 | Vector2f doorPos2f = new Vector2f(doorPos3f.getX(), doorPos3f.getZ()); 146 | collisionVector = collisionVector.mul(rectCollide(oldPos2, newPos2, objectSize, doorPos2f, doorSize)); 147 | } 148 | } 149 | 150 | return new Vector3f(collisionVector.getX(), 0, collisionVector.getY()); 151 | } 152 | 153 | public Vector2f checkIntersections(Vector2f lineStart, Vector2f lineEnd, boolean hurtMonsters) 154 | { 155 | Vector2f nearestIntersection = null; 156 | 157 | for(int i = 0; i < collisionPosStart.size(); i++) 158 | { 159 | Vector2f collisionVector = lineIntersect(lineStart, lineEnd, collisionPosStart.get(i), collisionPosEnd.get(i)); 160 | nearestIntersection = findNearestVector2f(nearestIntersection, collisionVector, lineStart); 161 | } 162 | 163 | for(Door door : doors) 164 | { 165 | Vector2f doorSize = door.getDoorSize(); 166 | Vector3f doorPos3f = door.getTransform().getTranslation(); 167 | Vector2f doorPos2f = new Vector2f(doorPos3f.getX(), doorPos3f.getZ()); 168 | Vector2f collisionVector = lineIntersectRect(lineStart, lineEnd, doorPos2f, doorSize); 169 | 170 | nearestIntersection = findNearestVector2f(nearestIntersection, collisionVector, lineStart); 171 | } 172 | 173 | if(hurtMonsters) 174 | { 175 | Vector2f nearestMonsterIntersect = null; 176 | Monster nearestMonster = null; 177 | 178 | for(Monster monster : monsters) 179 | { 180 | Vector2f monsterSize = monster.getSize(); 181 | Vector3f monsterPos3f = monster.getTransform().getTranslation(); 182 | Vector2f monsterPos2f = new Vector2f(monsterPos3f.getX(), monsterPos3f.getZ()); 183 | Vector2f collisionVector = lineIntersectRect(lineStart, lineEnd, monsterPos2f, monsterSize); 184 | 185 | nearestMonsterIntersect = findNearestVector2f(nearestMonsterIntersect, collisionVector, lineStart); 186 | 187 | if(nearestMonsterIntersect == collisionVector) 188 | nearestMonster = monster; 189 | } 190 | 191 | if(nearestMonsterIntersect != null && (nearestIntersection == null || 192 | nearestMonsterIntersect.sub(lineStart).length() < nearestIntersection.sub(lineStart).length())) 193 | { 194 | if(nearestMonster != null) 195 | nearestMonster.damage(player.getDamage()); 196 | } 197 | } 198 | 199 | return nearestIntersection; 200 | } 201 | 202 | private Vector2f findNearestVector2f(Vector2f a, Vector2f b, Vector2f positionRelativeTo) 203 | { 204 | if(b != null && (a == null || 205 | a.sub(positionRelativeTo).length() > b.sub(positionRelativeTo).length())) 206 | return b; 207 | 208 | return a; 209 | } 210 | 211 | public Vector2f lineIntersectRect(Vector2f lineStart, Vector2f lineEnd, Vector2f rectPos, Vector2f rectSize) 212 | { 213 | Vector2f result = null; 214 | 215 | Vector2f collisionVector = lineIntersect(lineStart, lineEnd, rectPos, new Vector2f(rectPos.getX() + rectSize.getX(), rectPos.getY())); 216 | result = findNearestVector2f(result, collisionVector, lineStart); 217 | 218 | collisionVector = lineIntersect(lineStart, lineEnd, rectPos, new Vector2f(rectPos.getX(), rectPos.getY() + rectSize.getY())); 219 | result = findNearestVector2f(result, collisionVector, lineStart); 220 | 221 | collisionVector = lineIntersect(lineStart, lineEnd, new Vector2f(rectPos.getX(), rectPos.getY() + rectSize.getY()), rectPos.add(rectSize)); 222 | result = findNearestVector2f(result, collisionVector, lineStart); 223 | 224 | collisionVector = lineIntersect(lineStart, lineEnd, new Vector2f(rectPos.getX() + rectSize.getX(), rectPos.getY()), rectPos.add(rectSize)); 225 | result = findNearestVector2f(result, collisionVector, lineStart); 226 | 227 | return result; 228 | } 229 | 230 | private float Vector2fCross(Vector2f a, Vector2f b) 231 | { 232 | return a.getX() * b.getY() - a.getY() * b.getX(); 233 | } 234 | 235 | //http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect 236 | private Vector2f lineIntersect(Vector2f lineStart1, Vector2f lineEnd1, Vector2f lineStart2, Vector2f lineEnd2) 237 | { 238 | Vector2f line1 = lineEnd1.sub(lineStart1); 239 | Vector2f line2 = lineEnd2.sub(lineStart2); 240 | 241 | //lineStart1 + line1 * a == lineStart2 + line2 * b 242 | 243 | float cross = Vector2fCross(line1, line2); 244 | 245 | if(cross == 0) 246 | return null; 247 | 248 | Vector2f distanceBetweenLineStarts = lineStart2.sub(lineStart1); 249 | 250 | float a = Vector2fCross(distanceBetweenLineStarts, line2) / cross; 251 | float b = Vector2fCross(distanceBetweenLineStarts, line1) / cross; 252 | 253 | if(0.0f < a && a < 1.0f && 0.0f < b && b < 1.0f) 254 | return lineStart1.add(line1.mul(a)); 255 | 256 | return null; 257 | } 258 | 259 | private Vector2f rectCollide(Vector2f oldPos, Vector2f newPos, Vector2f size1, Vector2f pos2, Vector2f size2) 260 | { 261 | Vector2f result = new Vector2f(0,0); 262 | 263 | if(newPos.getX() + size1.getX() < pos2.getX() || 264 | newPos.getX() - size1.getX() > pos2.getX() + size2.getX() * size2.getX() || 265 | oldPos.getY() + size1.getY() < pos2.getY() || 266 | oldPos.getY() - size1.getY() > pos2.getY() + size2.getY() * size2.getY()) 267 | result.setX(1); 268 | 269 | if(oldPos.getX() + size1.getX() < pos2.getX() || 270 | oldPos.getX() - size1.getX() > pos2.getX() + size2.getX() * size2.getX() || 271 | newPos.getY() + size1.getY() < pos2.getY() || 272 | newPos.getY() - size1.getY() > pos2.getY() + size2.getY() * size2.getY()) 273 | result.setY(1); 274 | 275 | return result; 276 | } 277 | 278 | private void addFace(ArrayList indices, int startLocation, boolean direction) 279 | { 280 | if(direction) 281 | { 282 | indices.add(startLocation + 2); 283 | indices.add(startLocation + 1); 284 | indices.add(startLocation + 0); 285 | indices.add(startLocation + 3); 286 | indices.add(startLocation + 2); 287 | indices.add(startLocation + 0); 288 | } 289 | else 290 | { 291 | indices.add(startLocation + 0); 292 | indices.add(startLocation + 1); 293 | indices.add(startLocation + 2); 294 | indices.add(startLocation + 0); 295 | indices.add(startLocation + 2); 296 | indices.add(startLocation + 3); 297 | } 298 | } 299 | 300 | private float[] calcTexCoords(int value) 301 | { 302 | int texX = value / NUM_TEXTURES; 303 | int texY = texX % NUM_TEX_EXP; 304 | texX /= NUM_TEX_EXP; 305 | 306 | float[] result = new float[4]; 307 | 308 | result[0] = 1f - (float)texX/(float)NUM_TEX_EXP; 309 | result[1] = result[0] - 1f/(float)NUM_TEX_EXP; 310 | result[3] = 1f - (float)texY/(float)NUM_TEX_EXP; 311 | result[2] = result[3] - 1f/(float)NUM_TEX_EXP; 312 | 313 | return result; 314 | } 315 | 316 | private void addVertices(ArrayList vertices, int i, int j, float offset, boolean x, boolean y, boolean z, float[] texCoords) 317 | { 318 | if(x && z) 319 | { 320 | vertices.add(new Vertex(new Vector3f(i * SPOT_WIDTH, offset * SPOT_HEIGHT, j * SPOT_LENGTH), new Vector2f(texCoords[1],texCoords[3]))); 321 | vertices.add(new Vertex(new Vector3f((i + 1) * SPOT_WIDTH, offset * SPOT_HEIGHT, j * SPOT_LENGTH), new Vector2f(texCoords[0],texCoords[3]))); 322 | vertices.add(new Vertex(new Vector3f((i + 1) * SPOT_WIDTH, offset * SPOT_HEIGHT, (j + 1) * SPOT_LENGTH), new Vector2f(texCoords[0],texCoords[2]))); 323 | vertices.add(new Vertex(new Vector3f(i * SPOT_WIDTH, offset * SPOT_HEIGHT, (j + 1) * SPOT_LENGTH), new Vector2f(texCoords[1],texCoords[2]))); 324 | } 325 | else if(x && y) 326 | { 327 | vertices.add(new Vertex(new Vector3f(i * SPOT_WIDTH, j * SPOT_HEIGHT, offset * SPOT_LENGTH), new Vector2f(texCoords[1],texCoords[3]))); 328 | vertices.add(new Vertex(new Vector3f((i + 1) * SPOT_WIDTH, j * SPOT_HEIGHT, offset * SPOT_LENGTH), new Vector2f(texCoords[0],texCoords[3]))); 329 | vertices.add(new Vertex(new Vector3f((i + 1) * SPOT_WIDTH, (j + 1) * SPOT_HEIGHT, offset * SPOT_LENGTH), new Vector2f(texCoords[0],texCoords[2]))); 330 | vertices.add(new Vertex(new Vector3f(i * SPOT_WIDTH, (j + 1) * SPOT_HEIGHT, offset * SPOT_LENGTH), new Vector2f(texCoords[1],texCoords[2]))); 331 | } 332 | else if(y && z) 333 | { 334 | vertices.add(new Vertex(new Vector3f(offset * SPOT_WIDTH, i * SPOT_HEIGHT, j * SPOT_LENGTH), new Vector2f(texCoords[1],texCoords[3]))); 335 | vertices.add(new Vertex(new Vector3f(offset * SPOT_WIDTH, i * SPOT_HEIGHT, (j + 1) * SPOT_LENGTH), new Vector2f(texCoords[0],texCoords[3]))); 336 | vertices.add(new Vertex(new Vector3f(offset * SPOT_WIDTH, (i + 1) * SPOT_HEIGHT, (j + 1) * SPOT_LENGTH), new Vector2f(texCoords[0],texCoords[2]))); 337 | vertices.add(new Vertex(new Vector3f(offset * SPOT_WIDTH, (i + 1) * SPOT_HEIGHT, j * SPOT_LENGTH), new Vector2f(texCoords[1],texCoords[2]))); 338 | } 339 | else 340 | { 341 | System.err.println("Invalid plane used in level generator"); 342 | new Exception().printStackTrace(); 343 | System.exit(1); 344 | } 345 | } 346 | 347 | private void addDoor(int x, int y) 348 | { 349 | Transform doorTransform = new Transform(); 350 | 351 | boolean xDoor = (level.getPixel(x, y - 1) & 0xFFFFFF) == 0 && (level.getPixel(x, y + 1) & 0xFFFFFF) == 0; 352 | boolean yDoor = (level.getPixel(x - 1, y) & 0xFFFFFF) == 0 && (level.getPixel(x + 1, y) & 0xFFFFFF) == 0; 353 | 354 | if(!(xDoor ^ yDoor)) 355 | { 356 | System.err.println("Level Generation has failed! :( You placed a door in an invalid location at " + x + ", " + y); 357 | new Exception().printStackTrace(); 358 | System.exit(1); 359 | } 360 | 361 | Vector3f openPosition = null; 362 | 363 | if(yDoor) 364 | { 365 | doorTransform.setTranslation(x, 0, y + SPOT_LENGTH / 2); 366 | openPosition = doorTransform.getTranslation().sub(new Vector3f(DOOR_OPEN_MOVEMENT_AMOUNT, 0.0f, 0.0f)); 367 | } 368 | 369 | if(xDoor) 370 | { 371 | doorTransform.setTranslation(x + SPOT_WIDTH / 2, 0, y); 372 | doorTransform.setRotation(0, 90, 0); 373 | openPosition = doorTransform.getTranslation().sub(new Vector3f(0.0f, 0.0f, DOOR_OPEN_MOVEMENT_AMOUNT)); 374 | } 375 | 376 | doors.add(new Door(doorTransform, material, openPosition)); 377 | } 378 | 379 | private void addSpecial(int blueValue, int x, int y) 380 | { 381 | if(blueValue == 16) 382 | addDoor(x, y); 383 | if(blueValue == 1) 384 | player = new Player(new Vector3f((x + 0.5f) * SPOT_WIDTH, 0.4375f, (y + 0.5f) * SPOT_LENGTH)); 385 | if(blueValue == 128) 386 | { 387 | Transform monsterTransform = new Transform(); 388 | monsterTransform.setTranslation(new Vector3f((x + 0.5f) * SPOT_WIDTH, 0, (y + 0.5f) * SPOT_LENGTH)); 389 | monsters.add(new Monster(monsterTransform)); 390 | } 391 | if(blueValue == 192) 392 | medkits.add(new Medkit(new Vector3f((x + 0.5f) * SPOT_WIDTH, 0, (y + 0.5f) * SPOT_LENGTH))); 393 | if(blueValue == 97) 394 | exitPoints.add(new Vector3f((x + 0.5f) * SPOT_WIDTH, 0, (y + 0.5f) * SPOT_LENGTH)); 395 | } 396 | 397 | private void generateLevel() 398 | { 399 | doors = new ArrayList(); 400 | monsters = new ArrayList(); 401 | medkits = new ArrayList(); 402 | collisionPosStart = new ArrayList(); 403 | collisionPosEnd = new ArrayList(); 404 | 405 | ArrayList vertices = new ArrayList(); 406 | ArrayList indices = new ArrayList(); 407 | 408 | for(int i = 0; i < level.getWidth(); i++) 409 | { 410 | for(int j = 0; j < level.getHeight(); j++) 411 | { 412 | if((level.getPixel(i,j) & 0xFFFFFF) == 0) 413 | continue; 414 | 415 | float[] texCoords = calcTexCoords((level.getPixel(i,j) & 0x00FF00) >> 8); 416 | 417 | addSpecial((level.getPixel(i,j) & 0x0000FF), i , j); 418 | 419 | //Generate Floor 420 | addFace(indices, vertices.size(), true); 421 | addVertices(vertices, i, j, 0, true, false, true, texCoords); 422 | 423 | //Generate Ceiling 424 | addFace(indices, vertices.size(), false); 425 | addVertices(vertices, i, j, 1, true, false, true, texCoords); 426 | 427 | //Generate Walls 428 | texCoords = calcTexCoords((level.getPixel(i,j) & 0xFF0000) >> 16); 429 | 430 | if((level.getPixel(i,j - 1) & 0xFFFFFF) == 0) 431 | { 432 | collisionPosStart.add(new Vector2f(i * SPOT_WIDTH, j * SPOT_LENGTH)); 433 | collisionPosEnd.add(new Vector2f((i + 1) * SPOT_WIDTH, j * SPOT_LENGTH)); 434 | addFace(indices, vertices.size(), false); 435 | addVertices(vertices, i, 0, j, true, true, false, texCoords); 436 | } 437 | if((level.getPixel(i,j + 1) & 0xFFFFFF) == 0) 438 | { 439 | collisionPosStart.add(new Vector2f(i * SPOT_WIDTH, (j + 1) * SPOT_LENGTH)); 440 | collisionPosEnd.add(new Vector2f((i + 1) * SPOT_WIDTH, (j + 1) * SPOT_LENGTH)); 441 | addFace(indices, vertices.size(), true); 442 | addVertices(vertices, i, 0, (j + 1), true, true, false, texCoords); 443 | } 444 | if((level.getPixel(i - 1,j) & 0xFFFFFF) == 0) 445 | { 446 | collisionPosStart.add(new Vector2f(i * SPOT_WIDTH, j * SPOT_LENGTH)); 447 | collisionPosEnd.add(new Vector2f(i * SPOT_WIDTH, (j + 1) * SPOT_LENGTH)); 448 | addFace(indices, vertices.size(), true); 449 | addVertices(vertices, 0, j, i, false, true, true, texCoords); 450 | } 451 | if((level.getPixel(i + 1,j) & 0xFFFFFF) == 0) 452 | { 453 | collisionPosStart.add(new Vector2f((i + 1) * SPOT_WIDTH, j * SPOT_LENGTH)); 454 | collisionPosEnd.add(new Vector2f((i + 1) * SPOT_WIDTH, (j + 1) * SPOT_LENGTH)); 455 | addFace(indices, vertices.size(), false); 456 | addVertices(vertices, 0, j, (i + 1), false, true, true, texCoords); 457 | } 458 | } 459 | } 460 | 461 | //WARNING: DEBUG CODE! 462 | 463 | // vertices.clear(); 464 | // indices.clear(); 465 | // 466 | // for(int i = 0; i < collisionPosStart.size(); i++) 467 | // { 468 | // Vector2f lineStart = collisionPosStart.get(i); 469 | // Vector2f lineEnd = collisionPosEnd.get(i); 470 | // 471 | // indices.add(vertices.size() + 0); 472 | // indices.add(vertices.size() + 1); 473 | // indices.add(vertices.size() + 2); 474 | // indices.add(vertices.size() + 0); 475 | // indices.add(vertices.size() + 2); 476 | // indices.add(vertices.size() + 3); 477 | // 478 | // indices.add(vertices.size() + 2); 479 | // indices.add(vertices.size() + 1); 480 | // indices.add(vertices.size() + 0); 481 | // indices.add(vertices.size() + 3); 482 | // indices.add(vertices.size() + 2); 483 | // indices.add(vertices.size() + 0); 484 | // 485 | // vertices.add(new Vertex(new Vector3f(lineStart.getX(), 0, lineStart.getY()), new Vector2f(0, 0))); 486 | // vertices.add(new Vertex(new Vector3f(lineStart.getX(), 1, lineStart.getY()), new Vector2f(0, 1))); 487 | // vertices.add(new Vertex(new Vector3f(lineEnd.getX(), 1, lineEnd.getY()), new Vector2f(1, 1))); 488 | // vertices.add(new Vertex(new Vector3f(lineEnd.getX(), 0, lineEnd.getY()), new Vector2f(1, 0))); 489 | // } 490 | 491 | //END DEBUG CODE! 492 | 493 | Vertex[] vertArray = new Vertex[vertices.size()]; 494 | Integer[] intArray = new Integer[indices.size()]; 495 | 496 | vertices.toArray(vertArray); 497 | indices.toArray(intArray); 498 | 499 | mesh = new Mesh(vertArray, Util.toIntArray(intArray)); 500 | } 501 | 502 | public void removeMedkit(Medkit medkit) 503 | { 504 | medkitsToRemove.add(medkit); 505 | } 506 | 507 | public Shader getShader() 508 | { 509 | return shader; 510 | } 511 | } 512 | --------------------------------------------------------------------------------