Entire project
8
.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
bin/
|
||||||
|
.settings/
|
||||||
|
*.jar
|
||||||
|
*.zip
|
||||||
|
*.bat
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
*.txt
|
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
Mit License
|
||||||
|
|
||||||
|
Copyright (c) 2018 Gnarly Narwhal
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
22
README.md
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# Ludum Dare 40
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
Must have [Java](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) installed
|
||||||
|
* NOTE: I run Java 9 so I cannot guarantee that it will work on earlier version, but I don't believe I've used anything preventing it from running on some older versions. Click [here](http://www.oracle.com/technetwork/java/javase/downloads/jdk9-downloads-3848520.html) to download Java 9.
|
||||||
|
|
||||||
|
Graphics driver must have support for OpenGL 3.3 Core or later
|
||||||
|
|
||||||
|
### What's this all about?
|
||||||
|
This project is my game for Ludum Dare 40. If you don't know what [Ludum Dare](https://ldjam.com/about) is and you're into making games then definitely check it out [here](https://ldjam.com/about).
|
||||||
|
|
||||||
|
### So what's the game?
|
||||||
|
The game is a snake inspired game in which you control a snake and navigate though levels to reach the end.
|
||||||
|
|
||||||
|
### Can I play it?
|
||||||
|
Of course! Here's how:
|
||||||
|
|
||||||
|
Click [here](https://drive.google.com/drive/folders/1CPgHTXhfeaYPd9OUWtnpnup5hiO7CTq2?usp=sharing) to download the game. Once you've downloaded it extract the zip file and run the jar file.
|
||||||
|
|
||||||
|
Of course you can always download the source and compile it yourself. You are going to need [LWJGL 3](https://www.lwjgl.org/download). Make sure to include JOML under **Addons**
|
BIN
res/audio/chiptune1.wav
Normal file
BIN
res/audio/chiptune2.wav
Normal file
BIN
res/audio/fretnoise.wav
Normal file
BIN
res/audio/medieval.wav
Normal file
BIN
res/audio/medievalharp.wav
Normal file
BIN
res/audio/medievalsynth.wav
Normal file
BIN
res/audio/menu.wav
Normal file
1
res/audio/samples.ceol
Normal file
BIN
res/img/fruit.png
Normal file
After Width: | Height: | Size: 217 B |
BIN
res/img/letters/a.png
Normal file
After Width: | Height: | Size: 247 B |
BIN
res/img/letters/b.png
Normal file
After Width: | Height: | Size: 244 B |
BIN
res/img/letters/c.png
Normal file
After Width: | Height: | Size: 243 B |
BIN
res/img/letters/d.png
Normal file
After Width: | Height: | Size: 257 B |
BIN
res/img/letters/e.png
Normal file
After Width: | Height: | Size: 243 B |
BIN
res/img/letters/f.png
Normal file
After Width: | Height: | Size: 229 B |
BIN
res/img/letters/g.png
Normal file
After Width: | Height: | Size: 248 B |
BIN
res/img/letters/h.png
Normal file
After Width: | Height: | Size: 260 B |
BIN
res/img/letters/i.png
Normal file
After Width: | Height: | Size: 234 B |
BIN
res/img/letters/j.png
Normal file
After Width: | Height: | Size: 252 B |
BIN
res/img/letters/k.png
Normal file
After Width: | Height: | Size: 259 B |
BIN
res/img/letters/l.png
Normal file
After Width: | Height: | Size: 236 B |
BIN
res/img/letters/m.png
Normal file
After Width: | Height: | Size: 249 B |
BIN
res/img/letters/n.png
Normal file
After Width: | Height: | Size: 252 B |
BIN
res/img/letters/o.png
Normal file
After Width: | Height: | Size: 244 B |
BIN
res/img/letters/q.png
Normal file
After Width: | Height: | Size: 249 B |
BIN
res/img/letters/r.png
Normal file
After Width: | Height: | Size: 253 B |
BIN
res/img/letters/s.png
Normal file
After Width: | Height: | Size: 239 B |
BIN
res/img/letters/t.png
Normal file
After Width: | Height: | Size: 220 B |
BIN
res/img/letters/v.png
Normal file
After Width: | Height: | Size: 264 B |
BIN
res/img/letters/w.png
Normal file
After Width: | Height: | Size: 250 B |
BIN
res/img/letters/x.png
Normal file
After Width: | Height: | Size: 258 B |
BIN
res/img/letters/y.png
Normal file
After Width: | Height: | Size: 247 B |
BIN
res/img/letters/z.png
Normal file
After Width: | Height: | Size: 249 B |
BIN
res/img/toxin.png
Normal file
After Width: | Height: | Size: 525 B |
19
res/levels/all/countdown.fx
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
3
|
||||||
|
|
||||||
|
1 false true 1 1
|
||||||
|
0 1 1 1
|
||||||
|
0 1 0.3 1
|
||||||
|
0 1 1 0.25
|
||||||
|
0 0 0 0.25
|
||||||
|
|
||||||
|
1 false true 1 1
|
||||||
|
60 1 1 1
|
||||||
|
0 0 0 1
|
||||||
|
60 1 1 0.25
|
||||||
|
0 0 0 0.25
|
||||||
|
|
||||||
|
1 false true 1 1
|
||||||
|
120 1 1 1
|
||||||
|
0 0 0 1
|
||||||
|
120 1 1 0.25
|
||||||
|
0 0 0 0.25
|
7
res/levels/all/defeat.fx
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
1
|
||||||
|
|
||||||
|
3 true true 2 0.5
|
||||||
|
0.7 0 0 1
|
||||||
|
0.3 0 0 1
|
||||||
|
0.7 0 0 1
|
||||||
|
0.3 0 0 1
|
BIN
res/levels/all/length.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
7
res/levels/all/next/hovered.fx
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
1
|
||||||
|
|
||||||
|
3 true true 2 0.5
|
||||||
|
0 1 0 1
|
||||||
|
0 0.5 0 1
|
||||||
|
0 1 0 1
|
||||||
|
0 0.5 0 1
|
BIN
res/levels/all/next/next.png
Normal file
After Width: | Height: | Size: 434 B |
7
res/levels/all/next/pressed.fx
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
1
|
||||||
|
|
||||||
|
3 true true 2 0.5
|
||||||
|
0 0.4 0 1
|
||||||
|
0 0.2 0 1
|
||||||
|
0 0.4 0 1
|
||||||
|
0 0.2 0 1
|
BIN
res/levels/all/next/space.png
Normal file
After Width: | Height: | Size: 451 B |
7
res/levels/all/next/unpressed.fx
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
1
|
||||||
|
|
||||||
|
3 true true 2 0.5
|
||||||
|
0.8 0.8 0.8 1
|
||||||
|
0.5 1 0.5 1
|
||||||
|
0.8 0.8 0.8 1
|
||||||
|
0.5 1 0.5 1
|
BIN
res/levels/all/one.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
7
res/levels/all/retry/hovered.fx
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
1
|
||||||
|
|
||||||
|
3 true true 2 0.5
|
||||||
|
1 0 0 1
|
||||||
|
0.5 0 0 1
|
||||||
|
1 0 0 1
|
||||||
|
0.5 0 0 1
|
7
res/levels/all/retry/pressed.fx
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
1
|
||||||
|
|
||||||
|
3 true true 2 0.5
|
||||||
|
0.4 0 0 1
|
||||||
|
0.2 0 0 1
|
||||||
|
0.4 0 0 1
|
||||||
|
0.2 0 0 1
|
BIN
res/levels/all/retry/retry.png
Normal file
After Width: | Height: | Size: 370 B |
BIN
res/levels/all/retry/space.png
Normal file
After Width: | Height: | Size: 440 B |
7
res/levels/all/retry/unpressed.fx
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
1
|
||||||
|
|
||||||
|
3 true true 2 0.5
|
||||||
|
0.8 0.8 0.8 1
|
||||||
|
1 0.5 0.5 1
|
||||||
|
0.8 0.8 0.8 1
|
||||||
|
1 0.5 0.5 1
|
BIN
res/levels/all/speed.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
res/levels/all/three.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
res/levels/all/two.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
13
res/levels/all/victory.fx
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
2
|
||||||
|
|
||||||
|
0.75 false false 0 1
|
||||||
|
60 1 1 1
|
||||||
|
60 1 1 1
|
||||||
|
72 1 0.5 1
|
||||||
|
36 1 0.5 1
|
||||||
|
|
||||||
|
0.25 false false 0 1
|
||||||
|
72 1 0.5 1
|
||||||
|
36 1 0.5 1
|
||||||
|
60 1 1 1
|
||||||
|
60 1 1 1
|
2
res/levels/level1/data.prop
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
8
|
||||||
|
5
|
7
res/levels/level1/effect.fx
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
1
|
||||||
|
|
||||||
|
2 true true 0.5 2
|
||||||
|
0 1 1 1
|
||||||
|
1 0 0 1
|
||||||
|
0 1 1 1
|
||||||
|
1 0 0 1
|
BIN
res/levels/level1/level.png
Normal file
After Width: | Height: | Size: 978 B |
BIN
res/levels/level1/music.wav
Normal file
2
res/levels/level2/data.prop
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
8
|
||||||
|
20
|
7
res/levels/level2/effect.fx
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
1
|
||||||
|
|
||||||
|
2 true true 0.5 2
|
||||||
|
0.6666 0 1 1
|
||||||
|
1 0.5 0 1
|
||||||
|
0.6666 0 1 1
|
||||||
|
1 0.5 0 1
|
BIN
res/levels/level2/level.png
Normal file
After Width: | Height: | Size: 726 B |
BIN
res/levels/level2/music.wav
Normal file
2
res/levels/level3/data.prop
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
8
|
||||||
|
10
|
7
res/levels/level3/effect.fx
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
1
|
||||||
|
|
||||||
|
10 false false 0 1
|
||||||
|
0 0.75 0.5 1
|
||||||
|
0 0.75 0.5 1
|
||||||
|
360 0.75 0.5 1
|
||||||
|
360 0.75 0.5 1
|
BIN
res/levels/level3/level.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
res/levels/level3/music.wav
Normal file
2
res/levels/level4/data.prop
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
5
|
||||||
|
10
|
7
res/levels/level4/effect.fx
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
1
|
||||||
|
|
||||||
|
4 false false 1 1
|
||||||
|
0 1 1 1
|
||||||
|
360 1 1 1
|
||||||
|
0 1 1 1
|
||||||
|
360 1 1 1
|
BIN
res/levels/level4/level.png
Normal file
After Width: | Height: | Size: 592 B |
BIN
res/levels/level4/music.wav
Normal file
2
res/menu/data.prop
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
6
|
||||||
|
5
|
7
res/menu/effect.fx
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
1
|
||||||
|
|
||||||
|
4 false false 1 1
|
||||||
|
0 0.5 0.1 1
|
||||||
|
360 0.5 0.1 1
|
||||||
|
0 0.5 0.1 1
|
||||||
|
360 0.5 0.1 1
|
7
res/menu/hovered.fx
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
1
|
||||||
|
|
||||||
|
2 false true -1 1
|
||||||
|
40 1 1 1
|
||||||
|
0 1 1 1
|
||||||
|
40 1 1 1
|
||||||
|
0 1 1 1
|
BIN
res/menu/level.png
Normal file
After Width: | Height: | Size: 668 B |
7
res/menu/logo.fx
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
1
|
||||||
|
|
||||||
|
3 false true 1 1
|
||||||
|
130 1 0.75 1
|
||||||
|
170 1 0.15 1
|
||||||
|
130 1 0.75 1
|
||||||
|
170 1 0.15 1
|
BIN
res/menu/logo.png
Normal file
After Width: | Height: | Size: 645 B |
BIN
res/menu/music.wav
Normal file
BIN
res/menu/play.png
Normal file
After Width: | Height: | Size: 349 B |
7
res/menu/pressed.fx
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
1
|
||||||
|
|
||||||
|
2 false true -1 1
|
||||||
|
40 1 0.25 1
|
||||||
|
0 1 0.25 1
|
||||||
|
40 1 0.25 1
|
||||||
|
0 1 0.25 1
|
13
res/shaders/s2a/frag.gls
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
uniform sampler2D sampler;
|
||||||
|
|
||||||
|
in vec2 texCoords;
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
color = texture(sampler, texCoords);
|
||||||
|
if(color.a == 0)
|
||||||
|
discard;
|
||||||
|
}
|
15
res/shaders/s2a/vert.gls
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
uniform mat4 mvp;
|
||||||
|
|
||||||
|
uniform vec2 animProps; // Loc 0 - Frame Width, Loc 1 - Offset
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 vertices;
|
||||||
|
layout (location = 1) in vec2 iTexCoords;
|
||||||
|
|
||||||
|
out vec2 texCoords;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
texCoords = vec2(((iTexCoords.x * animProps.x) + animProps.y), iTexCoords.y);
|
||||||
|
gl_Position = mvp * vec4(vertices, 1.0);
|
||||||
|
}
|
9
res/shaders/s2c/frag.gls
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
uniform vec4 iColor = vec4(0, 0.6, 0.9, 1);
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
color = iColor;
|
||||||
|
}
|
9
res/shaders/s2c/vert.gls
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
uniform mat4 mvp;
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 vertices;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = mvp * vec4(vertices, 1);
|
||||||
|
}
|
46
res/shaders/s2le/frag.gls
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
uniform sampler2D sampler;
|
||||||
|
|
||||||
|
uniform vec4 color1 = vec4(0, 1, 1, 1);
|
||||||
|
uniform vec4 color2 = vec4(0, 0, 1, 1);
|
||||||
|
uniform float time = 0, freq = 1;
|
||||||
|
uniform bool rgb = true, loop = false, textured = false;
|
||||||
|
|
||||||
|
in vec2 iTexCoords;
|
||||||
|
in float percent;
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
vec4 hsvToRgb(vec4 hsva);
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 tcolor;
|
||||||
|
if(textured)
|
||||||
|
tcolor = texture(sampler, iTexCoords);
|
||||||
|
if(!textured || tcolor.xyz == vec3(1, 1, 1)) {
|
||||||
|
float finalPercent = mod((percent + time) * freq, 1);
|
||||||
|
if(loop) {
|
||||||
|
if(finalPercent > 0.5)
|
||||||
|
finalPercent = 1 - finalPercent;
|
||||||
|
finalPercent *= 2;
|
||||||
|
}
|
||||||
|
vec4 interpolated = color1 + (color2 - color1) * finalPercent;
|
||||||
|
if(rgb)
|
||||||
|
color = interpolated;
|
||||||
|
else
|
||||||
|
color = hsvToRgb(interpolated);
|
||||||
|
if(textured)
|
||||||
|
color.w = texture(sampler, iTexCoords).w;
|
||||||
|
}
|
||||||
|
else if(tcolor.w != 0)
|
||||||
|
color = tcolor;
|
||||||
|
else
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 hsvToRgb(vec4 c) {
|
||||||
|
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||||
|
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||||
|
return vec4(c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y), c.w);
|
||||||
|
}
|
16
res/shaders/s2le/vert.gls
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
uniform mat4 mvp;
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 vertices;
|
||||||
|
layout (location = 1) in vec2 texCoords;
|
||||||
|
|
||||||
|
out vec2 iTexCoords;
|
||||||
|
out float percent;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
iTexCoords = texCoords;
|
||||||
|
vec4 position = mvp * vec4(vertices, 1);
|
||||||
|
percent = (position.x + 1) / 4 - (position.y - 1) / 4;
|
||||||
|
gl_Position = position;
|
||||||
|
}
|
11
res/shaders/s2t/frag.gls
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
uniform sampler2D sampler;
|
||||||
|
|
||||||
|
in vec2 texCoords;
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
color = texture(sampler, texCoords);
|
||||||
|
}
|
13
res/shaders/s2t/vert.gls
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
uniform mat4 mvp;
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 vertices;
|
||||||
|
layout (location = 1) in vec2 itexCoords;
|
||||||
|
|
||||||
|
out vec2 texCoords;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
texCoords = itexCoords;
|
||||||
|
gl_Position = mvp * vec4(vertices, 1);
|
||||||
|
}
|
15
res/shaders/s2x/frag.gls
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
uniform vec4 iColor;
|
||||||
|
|
||||||
|
uniform sampler2D sampler;
|
||||||
|
|
||||||
|
in vec2 texCoords;
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
color = iColor * texture(sampler, texCoords);
|
||||||
|
if(color.a == 0)
|
||||||
|
discard;
|
||||||
|
}
|
15
res/shaders/s2x/vert.gls
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
uniform mat4 mvp;
|
||||||
|
|
||||||
|
uniform vec2 character;
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 vertices;
|
||||||
|
layout (location = 1) in vec2 iTexCoords;
|
||||||
|
|
||||||
|
out vec2 texCoords;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
texCoords = iTexCoords + character;
|
||||||
|
gl_Position = mvp * vec4(vertices, 1.0);
|
||||||
|
}
|
39
src/com/gnarly/engine/audio/ALManagement.java
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
package com.gnarly.engine.audio;
|
||||||
|
|
||||||
|
import static org.lwjgl.openal.ALC10.alcCreateContext;
|
||||||
|
import static org.lwjgl.openal.ALC10.alcMakeContextCurrent;
|
||||||
|
import static org.lwjgl.openal.ALC10.alcOpenDevice;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
|
||||||
|
import org.lwjgl.openal.AL;
|
||||||
|
import org.lwjgl.openal.ALC;
|
||||||
|
import org.lwjgl.openal.ALC10;
|
||||||
|
import org.lwjgl.openal.ALCCapabilities;
|
||||||
|
|
||||||
|
public class ALManagement {
|
||||||
|
|
||||||
|
private long device, context;
|
||||||
|
private ALCCapabilities deviceCaps;
|
||||||
|
|
||||||
|
public ALManagement() {
|
||||||
|
device = alcOpenDevice((ByteBuffer) null);
|
||||||
|
if (device == 0)
|
||||||
|
throw new IllegalStateException("Failed to open the default device.");
|
||||||
|
|
||||||
|
deviceCaps = ALC.createCapabilities(device);
|
||||||
|
|
||||||
|
context = alcCreateContext(device, (IntBuffer) null);
|
||||||
|
if (context == 0)
|
||||||
|
throw new IllegalStateException("Failed to create an OpenAL context.");
|
||||||
|
|
||||||
|
alcMakeContextCurrent(context);
|
||||||
|
AL.createCapabilities(deviceCaps);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroy() {
|
||||||
|
ALC10.alcDestroyContext(context);
|
||||||
|
ALC10.alcCloseDevice(device);
|
||||||
|
}
|
||||||
|
}
|
38
src/com/gnarly/engine/audio/Sound.java
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
package com.gnarly.engine.audio;
|
||||||
|
|
||||||
|
import org.lwjgl.openal.AL10;
|
||||||
|
|
||||||
|
public class Sound {
|
||||||
|
|
||||||
|
private int buffer;
|
||||||
|
private int sourceId;
|
||||||
|
|
||||||
|
public Sound(String path) {
|
||||||
|
sourceId = AL10.alGenSources();
|
||||||
|
buffer = AL10.alGenBuffers();
|
||||||
|
WaveData waveData = WaveData.create(path);
|
||||||
|
AL10.alBufferData(buffer, waveData.format, waveData.data, waveData.samplerate);
|
||||||
|
AL10.alSourcei(sourceId, AL10.AL_BUFFER, buffer);
|
||||||
|
AL10.alSourcef(sourceId, AL10.AL_GAIN, 1);
|
||||||
|
AL10.alSourcef(sourceId, AL10.AL_PITCH, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void play(boolean loop) {
|
||||||
|
AL10.alSourcei(sourceId, AL10.AL_LOOPING, loop ? 1 : 0);
|
||||||
|
AL10.alSource3f(sourceId, AL10.AL_POSITION, 0, 0, 0);
|
||||||
|
AL10.alSourcePlay(sourceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
AL10.alSourceStop(sourceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVolume(float volume) {
|
||||||
|
AL10.alSourcef(sourceId, AL10.AL_GAIN, volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroy() {
|
||||||
|
AL10.alDeleteBuffers(buffer);
|
||||||
|
AL10.alDeleteSources(sourceId);
|
||||||
|
}
|
||||||
|
}
|
88
src/com/gnarly/engine/audio/WaveData.java
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
package com.gnarly.engine.audio;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import javax.sound.sampled.AudioFormat;
|
||||||
|
import javax.sound.sampled.AudioInputStream;
|
||||||
|
import javax.sound.sampled.AudioSystem;
|
||||||
|
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||||
|
|
||||||
|
import org.lwjgl.BufferUtils;
|
||||||
|
import org.lwjgl.openal.AL10;
|
||||||
|
|
||||||
|
public class WaveData {
|
||||||
|
|
||||||
|
final int format;
|
||||||
|
final int samplerate;
|
||||||
|
final int totalBytes;
|
||||||
|
final int bytesPerFrame;
|
||||||
|
final ByteBuffer data;
|
||||||
|
|
||||||
|
private final AudioInputStream audioStream;
|
||||||
|
private final byte[] dataArray;
|
||||||
|
|
||||||
|
private WaveData(AudioInputStream stream) {
|
||||||
|
this.audioStream = stream;
|
||||||
|
AudioFormat audioFormat = stream.getFormat();
|
||||||
|
format = getOpenAlFormat(audioFormat.getChannels(), audioFormat.getSampleSizeInBits());
|
||||||
|
this.samplerate = (int) audioFormat.getSampleRate();
|
||||||
|
this.bytesPerFrame = audioFormat.getFrameSize();
|
||||||
|
this.totalBytes = (int) (stream.getFrameLength() * bytesPerFrame);
|
||||||
|
this.data = BufferUtils.createByteBuffer(totalBytes);
|
||||||
|
this.dataArray = new byte[totalBytes];
|
||||||
|
loadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void dispose() {
|
||||||
|
try {
|
||||||
|
audioStream.close();
|
||||||
|
data.clear();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ByteBuffer loadData() {
|
||||||
|
try {
|
||||||
|
int bytesRead = audioStream.read(dataArray, 0, totalBytes);
|
||||||
|
data.clear();
|
||||||
|
data.put(dataArray, 0, bytesRead);
|
||||||
|
data.flip();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.err.println("Couldn't read bytes from audio stream!");
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static WaveData create(String file) {
|
||||||
|
WaveData wavStream = null;
|
||||||
|
try {
|
||||||
|
InputStream stream = new FileInputStream(new File(file));
|
||||||
|
InputStream bufferedInput = new BufferedInputStream(stream);
|
||||||
|
AudioInputStream audioStream = null;
|
||||||
|
audioStream = AudioSystem.getAudioInputStream(bufferedInput);
|
||||||
|
wavStream = new WaveData(audioStream);
|
||||||
|
} catch (UnsupportedAudioFileException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return wavStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static int getOpenAlFormat(int channels, int bitsPerSample) {
|
||||||
|
if (channels == 1) {
|
||||||
|
return bitsPerSample == 8 ? AL10.AL_FORMAT_MONO8 : AL10.AL_FORMAT_MONO16;
|
||||||
|
} else {
|
||||||
|
return bitsPerSample == 8 ? AL10.AL_FORMAT_STEREO8 : AL10.AL_FORMAT_STEREO16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
101
src/com/gnarly/engine/display/Camera.java
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
package com.gnarly.engine.display;
|
||||||
|
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
|
public class Camera {
|
||||||
|
|
||||||
|
private Matrix4f projection, projView;
|
||||||
|
|
||||||
|
private float width, height;
|
||||||
|
private Vector3f position;
|
||||||
|
private float rotation;
|
||||||
|
|
||||||
|
public Camera(float width, float height) {
|
||||||
|
setDims(width, height);
|
||||||
|
position = new Vector3f();
|
||||||
|
rotation = 0;
|
||||||
|
projView = new Matrix4f();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDims(float width, float height) {
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
projection = new Matrix4f().setOrtho(0, width, height, 0, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
projection.translate(position.negate(new Vector3f()), projView);
|
||||||
|
projView.rotateZ(-rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Matrix4f getProjection() {
|
||||||
|
return new Matrix4f(projection);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Matrix4f getMatrix() {
|
||||||
|
return new Matrix4f(projView);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getX() {
|
||||||
|
return position.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getY() {
|
||||||
|
return position.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3f getPosition() {
|
||||||
|
return new Vector3f(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getWidth() {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getHeight() {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(float x) {
|
||||||
|
position.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setY(float y) {
|
||||||
|
position.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPosition(float x, float y) {
|
||||||
|
position.set(x, y, position.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPosition(Vector3f position) {
|
||||||
|
this.position.x = position.x;
|
||||||
|
this.position.y = position.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCenter(float x, float y) {
|
||||||
|
position.set(x - width / 2, y - height / 2, position.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCenter(Vector3f position) {
|
||||||
|
this.position.x = position.x - width / 2;
|
||||||
|
this.position.y = position.y - height / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void translate(float x, float y, float z) {
|
||||||
|
position.add(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void translate(Vector3f transform) {
|
||||||
|
position.add(transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRotation(float angle) {
|
||||||
|
rotation = angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rotate(float angle) {
|
||||||
|
rotation += angle;
|
||||||
|
}
|
||||||
|
}
|
211
src/com/gnarly/engine/display/Window.java
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
package com.gnarly.engine.display;
|
||||||
|
|
||||||
|
import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MAJOR;
|
||||||
|
import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MINOR;
|
||||||
|
import static org.lwjgl.glfw.GLFW.GLFW_DECORATED;
|
||||||
|
import static org.lwjgl.glfw.GLFW.GLFW_FALSE;
|
||||||
|
import static org.lwjgl.glfw.GLFW.GLFW_KEY_LAST;
|
||||||
|
import static org.lwjgl.glfw.GLFW.GLFW_MAXIMIZED;
|
||||||
|
import static org.lwjgl.glfw.GLFW.GLFW_MOUSE_BUTTON_LAST;
|
||||||
|
import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_CORE_PROFILE;
|
||||||
|
import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_FORWARD_COMPAT;
|
||||||
|
import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_PROFILE;
|
||||||
|
import static org.lwjgl.glfw.GLFW.GLFW_RESIZABLE;
|
||||||
|
import static org.lwjgl.glfw.GLFW.GLFW_SAMPLES;
|
||||||
|
import static org.lwjgl.glfw.GLFW.GLFW_TRUE;
|
||||||
|
import static org.lwjgl.glfw.GLFW.glfwCreateWindow;
|
||||||
|
import static org.lwjgl.glfw.GLFW.glfwGetCursorPos;
|
||||||
|
import static org.lwjgl.glfw.GLFW.glfwGetPrimaryMonitor;
|
||||||
|
import static org.lwjgl.glfw.GLFW.glfwGetVideoMode;
|
||||||
|
import static org.lwjgl.glfw.GLFW.glfwGetWindowSize;
|
||||||
|
import static org.lwjgl.glfw.GLFW.glfwInit;
|
||||||
|
import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent;
|
||||||
|
import static org.lwjgl.glfw.GLFW.glfwPollEvents;
|
||||||
|
import static org.lwjgl.glfw.GLFW.glfwSetErrorCallback;
|
||||||
|
import static org.lwjgl.glfw.GLFW.glfwSetKeyCallback;
|
||||||
|
import static org.lwjgl.glfw.GLFW.glfwSetMouseButtonCallback;
|
||||||
|
import static org.lwjgl.glfw.GLFW.glfwSetWindowShouldClose;
|
||||||
|
import static org.lwjgl.glfw.GLFW.glfwSetWindowSizeCallback;
|
||||||
|
import static org.lwjgl.glfw.GLFW.glfwSwapBuffers;
|
||||||
|
import static org.lwjgl.glfw.GLFW.glfwSwapInterval;
|
||||||
|
import static org.lwjgl.glfw.GLFW.glfwTerminate;
|
||||||
|
import static org.lwjgl.glfw.GLFW.glfwWindowHint;
|
||||||
|
import static org.lwjgl.glfw.GLFW.glfwWindowShouldClose;
|
||||||
|
import static org.lwjgl.opengl.GL.createCapabilities;
|
||||||
|
import static org.lwjgl.opengl.GL11.GL_BLEND;
|
||||||
|
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
|
||||||
|
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
|
||||||
|
import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST;
|
||||||
|
import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA;
|
||||||
|
import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA;
|
||||||
|
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||||
|
import static org.lwjgl.opengl.GL11.GL_TRUE;
|
||||||
|
import static org.lwjgl.opengl.GL11.glBlendFunc;
|
||||||
|
import static org.lwjgl.opengl.GL11.glClear;
|
||||||
|
import static org.lwjgl.opengl.GL11.glClearColor;
|
||||||
|
import static org.lwjgl.opengl.GL11.glEnable;
|
||||||
|
import static org.lwjgl.opengl.GL11.glViewport;
|
||||||
|
import static org.lwjgl.opengl.GL13.GL_MULTISAMPLE;
|
||||||
|
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
import org.lwjgl.glfw.GLFWErrorCallback;
|
||||||
|
import org.lwjgl.glfw.GLFWVidMode;
|
||||||
|
|
||||||
|
public class Window {
|
||||||
|
|
||||||
|
public static int
|
||||||
|
SCREEN_WIDTH,
|
||||||
|
SCREEN_HEIGHT;
|
||||||
|
|
||||||
|
public static float SCALE;
|
||||||
|
|
||||||
|
private long window;
|
||||||
|
private int width, height;
|
||||||
|
private boolean resized;
|
||||||
|
|
||||||
|
private int[] mouseButtons = new int[GLFW_MOUSE_BUTTON_LAST + 1];
|
||||||
|
private int[] keys = new int[GLFW_KEY_LAST + 1];
|
||||||
|
|
||||||
|
public Window(String title, boolean vSync) {
|
||||||
|
init(0, 0, title, vSync, false, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Window(String title, boolean vSync, boolean resizable, boolean decorated) {
|
||||||
|
init(800, 500, title, vSync, resizable, decorated, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Window(int width, int height, String title, boolean vSync, boolean resizable, boolean decorated) {
|
||||||
|
init(width, height, title, vSync, resizable, decorated, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(int lwidth, int lheight, String title, boolean vSync, boolean resizable, boolean decorated, boolean maximized) {
|
||||||
|
glfwSetErrorCallback(GLFWErrorCallback.createPrint(System.err));
|
||||||
|
|
||||||
|
for (int i = 0; i < mouseButtons.length; i++)
|
||||||
|
mouseButtons[i] = 0;
|
||||||
|
|
||||||
|
if(!glfwInit()) {
|
||||||
|
System.err.println("GLFW failed to initialize!");
|
||||||
|
System.exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||||
|
|
||||||
|
glfwWindowHint(GLFW_SAMPLES, 8);
|
||||||
|
glfwWindowHint(GLFW_RESIZABLE, resizable ? GLFW_TRUE : GLFW_FALSE);
|
||||||
|
glfwWindowHint(GLFW_DECORATED, decorated ? GLFW_TRUE : GLFW_FALSE);
|
||||||
|
glfwWindowHint(GLFW_MAXIMIZED, maximized ? GLFW_TRUE : GLFW_FALSE);
|
||||||
|
|
||||||
|
GLFWVidMode vidMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
|
||||||
|
SCREEN_WIDTH = vidMode.width();
|
||||||
|
SCREEN_HEIGHT = vidMode.height();
|
||||||
|
SCALE = SCREEN_HEIGHT / 1080f;
|
||||||
|
if(lwidth == 0 || lheight == 0) {
|
||||||
|
width = vidMode.width();
|
||||||
|
height = vidMode.height();
|
||||||
|
window = glfwCreateWindow(width, height, title, glfwGetPrimaryMonitor(), 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.width = lwidth;
|
||||||
|
this.height = lheight;
|
||||||
|
window = glfwCreateWindow(width, height, title, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwMakeContextCurrent(window);
|
||||||
|
createCapabilities();
|
||||||
|
|
||||||
|
glfwSwapInterval(vSync ? 1 : 0);
|
||||||
|
|
||||||
|
glfwSetWindowSizeCallback(window, (long window, int w, int h) -> {
|
||||||
|
width = w;
|
||||||
|
height = h;
|
||||||
|
resized = true;
|
||||||
|
glViewport(0, 0, width, height);
|
||||||
|
});
|
||||||
|
|
||||||
|
glfwSetMouseButtonCallback(window, (long window, int button, int action, int mods) -> {
|
||||||
|
mouseButtons[button] = action;
|
||||||
|
});
|
||||||
|
|
||||||
|
glfwSetKeyCallback(window, (long window, int key, int scancode, int action, int mods) -> {
|
||||||
|
keys[key] = action;
|
||||||
|
});
|
||||||
|
|
||||||
|
glClearColor(0, 0, 0, 1);
|
||||||
|
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
glEnable(GL_MULTISAMPLE);
|
||||||
|
|
||||||
|
int[] awidth = new int[1], aheight = new int[1];
|
||||||
|
glfwGetWindowSize(window, awidth, aheight);
|
||||||
|
width = awidth[0];
|
||||||
|
height = aheight[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
for (int i = 0; i < mouseButtons.length; i++)
|
||||||
|
if (mouseButtons[i] == 1)
|
||||||
|
++mouseButtons[i];
|
||||||
|
for (int i = 0; i < keys.length; i++)
|
||||||
|
if (keys[i] == 1)
|
||||||
|
++keys[i];
|
||||||
|
resized = false;
|
||||||
|
glfwPollEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWidth() {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeight() {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void swap() {
|
||||||
|
glfwSwapBuffers(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
glfwSetWindowShouldClose(window, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void terminate() {
|
||||||
|
glfwTerminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean shouldClose() {
|
||||||
|
return glfwWindowShouldClose(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int keyPressed(int keyCode) {
|
||||||
|
return keys[keyCode];
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3f getMouseCoords(Camera camera) {
|
||||||
|
double[] x = new double[1], y = new double[1];
|
||||||
|
glfwGetCursorPos(window, x, y);
|
||||||
|
Vector3f ret = new Vector3f((float) x[0], (float) y[0], 0);
|
||||||
|
return ret.mul(camera.getWidth() / this.width, camera.getHeight() / this.height, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int mousePressed(int button) {
|
||||||
|
return mouseButtons[button];
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean wasResized() {
|
||||||
|
return resized;
|
||||||
|
}
|
||||||
|
}
|
121
src/com/gnarly/engine/model/Circle.java
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
package com.gnarly.engine.model;
|
||||||
|
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
|
import com.gnarly.engine.display.Camera;
|
||||||
|
import com.gnarly.engine.shaders.Shader;
|
||||||
|
import com.gnarly.engine.shaders.Shader2c;
|
||||||
|
|
||||||
|
public class Circle {
|
||||||
|
|
||||||
|
private static Vao vao;
|
||||||
|
|
||||||
|
private Camera camera;
|
||||||
|
private Shader2c shader;
|
||||||
|
private Vector3f position;
|
||||||
|
private float radius;
|
||||||
|
private float r, g, b, a;
|
||||||
|
|
||||||
|
public Circle(Camera camera, float x, float y, float z, float radius) {
|
||||||
|
this.camera = camera;
|
||||||
|
position = new Vector3f(x, y, z);
|
||||||
|
this.radius = radius;
|
||||||
|
shader = Shader.SHADER2C;
|
||||||
|
r = 1;
|
||||||
|
g = 0;
|
||||||
|
b = 0;
|
||||||
|
a = 1;
|
||||||
|
if(vao == null)
|
||||||
|
initVao();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initVao() {
|
||||||
|
final int NUM_POINTS = 30;
|
||||||
|
float[] cVertices = new float[NUM_POINTS * 3];
|
||||||
|
int[] cIndices = new int[(NUM_POINTS - 2) * 3];
|
||||||
|
for (int i = 0; i < cVertices.length; i += 3) {
|
||||||
|
double angle = Math.PI * 2 * i / (NUM_POINTS * 3);
|
||||||
|
cVertices[i ] = (float) Math.cos(angle);
|
||||||
|
cVertices[i + 1] = (float) Math.sin(angle);
|
||||||
|
cVertices[i + 2] = 0;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < cIndices.length; i += 3) {
|
||||||
|
cIndices[i ] = 0;
|
||||||
|
cIndices[i + 1] = i / 3 + 1;
|
||||||
|
cIndices[i + 2] = i / 3 + 2;
|
||||||
|
}
|
||||||
|
vao = new Vao(cVertices, cIndices);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void render() {
|
||||||
|
shader.enable();
|
||||||
|
shader.setMVP(camera.getMatrix().translate(position).scale(radius));
|
||||||
|
shader.setColor(r, g, b, a);
|
||||||
|
vao.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3f getPosition() {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(float x) {
|
||||||
|
position.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setY(float y) {
|
||||||
|
position.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setZ(float z) {
|
||||||
|
position.z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPosition(float x, float y) {
|
||||||
|
position.x = x;
|
||||||
|
position.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPosition(float x, float y, float z) {
|
||||||
|
position.x = x;
|
||||||
|
position.y = y;
|
||||||
|
position.z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPosition(Vector3f position) {
|
||||||
|
this.position.set(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void translate(float x, float y) {
|
||||||
|
position.x += x;
|
||||||
|
position.y += y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void translate(float x, float y, float z) {
|
||||||
|
position.x += x;
|
||||||
|
position.y += y;
|
||||||
|
position.z += z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void translate(Vector3f position) {
|
||||||
|
this.position.add(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRadius(float radius) {
|
||||||
|
this.radius = radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDiameter(float diameter) {
|
||||||
|
this.radius = diameter / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColor(float r, float g, float b, float a) {
|
||||||
|
this.r = r;
|
||||||
|
this.g = g;
|
||||||
|
this.b = b;
|
||||||
|
this.a = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(Vector3f vector) {
|
||||||
|
return (position.sub(vector, new Vector3f()).lengthSquared() < radius * radius);
|
||||||
|
}
|
||||||
|
}
|
37
src/com/gnarly/engine/model/ColRect.java
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
package com.gnarly.engine.model;
|
||||||
|
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
|
import com.gnarly.engine.display.Camera;
|
||||||
|
import com.gnarly.engine.shaders.Shader;
|
||||||
|
import com.gnarly.engine.shaders.Shader2c;
|
||||||
|
|
||||||
|
public class ColRect extends Rect {
|
||||||
|
|
||||||
|
private Shader2c shader;
|
||||||
|
|
||||||
|
private float r, g, b, a;
|
||||||
|
|
||||||
|
public ColRect(Camera camera, float x, float y, float z, float width, float height, float r, float g, float b, float a, boolean gui) {
|
||||||
|
super(camera, x, y, z, width, height, 0, gui);
|
||||||
|
shader = Shader.SHADER2C;
|
||||||
|
this.r = r;
|
||||||
|
this.g = g;
|
||||||
|
this.b = b;
|
||||||
|
this.a = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void render() {
|
||||||
|
shader.enable();
|
||||||
|
shader.setColor(r, g, b, a);
|
||||||
|
Matrix4f cmat = gui ? camera.getProjection() : camera.getMatrix();
|
||||||
|
shader.setMVP(cmat.translate(position.add(width * scale / 2, height * scale / 2, 0, new Vector3f())).rotateZ(rotation * 3.1415927f / 180).scale(width * scale, height * scale, 1).translate(-0.5f, -0.5f, 0));
|
||||||
|
vao.render();
|
||||||
|
shader.disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOpacity(float opacity) {
|
||||||
|
a = opacity;
|
||||||
|
}
|
||||||
|
}
|
54
src/com/gnarly/engine/model/EffectRect.java
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
package com.gnarly.engine.model;
|
||||||
|
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
|
import com.gnarly.engine.display.Camera;
|
||||||
|
import com.gnarly.engine.shaders.LevelEffect;
|
||||||
|
import com.gnarly.engine.shaders.Shader;
|
||||||
|
import com.gnarly.engine.shaders.Shader2le;
|
||||||
|
import com.gnarly.engine.texture.Texture;
|
||||||
|
import com.gnarly.game.Main;
|
||||||
|
|
||||||
|
public class EffectRect extends Rect {
|
||||||
|
|
||||||
|
private Shader2le shader = Shader.SHADER2LE;
|
||||||
|
|
||||||
|
private Texture texture;
|
||||||
|
|
||||||
|
private LevelEffect effect;
|
||||||
|
|
||||||
|
public EffectRect(Camera camera, String path, float x, float y, float z, float width, float height, boolean gui) {
|
||||||
|
super(camera, x, y, z, width, height, 0, gui);
|
||||||
|
effect = new LevelEffect(path);
|
||||||
|
texture = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EffectRect(Camera camera, String effect, String texture, float x, float y, float z, float width, float height, boolean gui) {
|
||||||
|
super(camera, x, y, z, width, height, 0, gui);
|
||||||
|
this.effect = new LevelEffect(effect);
|
||||||
|
this.texture = new Texture(texture);
|
||||||
|
this.gui = gui;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void render() {
|
||||||
|
if(texture != null)
|
||||||
|
texture.bind();
|
||||||
|
shader.enable();
|
||||||
|
shader.setEffect(effect.getPayload(Main.ttime), texture != null);
|
||||||
|
Matrix4f cmat = gui ? camera.getProjection() : camera.getMatrix();
|
||||||
|
shader.setMVP(cmat.translate(position.add(width * scale / 2, height * scale / 2, 0, new Vector3f())).rotateZ(rotation * 3.1415927f / 180).scale(width * scale, height * scale, 1).translate(-0.5f, -0.5f, 0));
|
||||||
|
vao.render();
|
||||||
|
shader.disable();
|
||||||
|
if(texture != null)
|
||||||
|
texture.unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEffect(String path) {
|
||||||
|
effect = new LevelEffect(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTexture(String path) {
|
||||||
|
texture = new Texture(path);
|
||||||
|
}
|
||||||
|
}
|
118
src/com/gnarly/engine/model/Line.java
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
package com.gnarly.engine.model;
|
||||||
|
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
|
import com.gnarly.engine.display.Camera;
|
||||||
|
import com.gnarly.engine.shaders.Shader;
|
||||||
|
import com.gnarly.engine.shaders.Shader2c;
|
||||||
|
|
||||||
|
public class Line {
|
||||||
|
|
||||||
|
private static Vao cap, rect;
|
||||||
|
|
||||||
|
private Camera camera;
|
||||||
|
private Shader2c shader;
|
||||||
|
|
||||||
|
private Vector3f position;
|
||||||
|
private float angle, length, thickness;
|
||||||
|
private float r, g, b, a;
|
||||||
|
|
||||||
|
public Line(Camera camera, float x1, float y1, float x2, float y2, float depth, float thickness) {
|
||||||
|
this.camera = camera;
|
||||||
|
shader = Shader.SHADER2C;
|
||||||
|
if(cap == null)
|
||||||
|
initVaos();
|
||||||
|
this.thickness = thickness;
|
||||||
|
position = new Vector3f(x1, y1, depth);
|
||||||
|
setPoints(x1, y1, x2, y2);
|
||||||
|
r = 1;
|
||||||
|
g = 1;
|
||||||
|
b = 1;
|
||||||
|
a = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initVaos() {
|
||||||
|
float[] rVertices = {
|
||||||
|
0, 0.5f, 0,
|
||||||
|
0, -0.5f, 0,
|
||||||
|
1, -0.5f, 0,
|
||||||
|
1, 0.5f, 0
|
||||||
|
};
|
||||||
|
int rIndices[] = {
|
||||||
|
0, 1, 3,
|
||||||
|
1, 2, 3
|
||||||
|
};
|
||||||
|
rect = new Vao(rVertices, rIndices);
|
||||||
|
final int NUM_POINTS = 10;
|
||||||
|
float[] cVertices = new float[NUM_POINTS * 3];
|
||||||
|
int[] cIndices = new int[(NUM_POINTS - 2) * 3];
|
||||||
|
for (int i = 0; i < cVertices.length; i += 3) {
|
||||||
|
double angle = Math.PI * i / (NUM_POINTS * 3 - 3) + Math.PI / 2;
|
||||||
|
cVertices[i ] = (float) Math.cos(angle) / 2;
|
||||||
|
cVertices[i + 1] = (float) Math.sin(angle) / 2;
|
||||||
|
cVertices[i + 2] = 0;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < cIndices.length; i += 3) {
|
||||||
|
cIndices[i ] = 0;
|
||||||
|
cIndices[i + 1] = i / 3 + 1;
|
||||||
|
cIndices[i + 2] = i / 3 + 2;
|
||||||
|
}
|
||||||
|
cap = new Vao(cVertices, cIndices);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void render() {
|
||||||
|
shader.enable();
|
||||||
|
shader.setColor(r, g, b, a);
|
||||||
|
shader.setMVP(camera.getMatrix().translate(position).rotateZ(angle).scale(thickness));
|
||||||
|
cap.render();
|
||||||
|
shader.setMVP(camera.getMatrix().translate(position).rotateZ(angle).scale(length, thickness, 1));
|
||||||
|
rect.render();
|
||||||
|
shader.setMVP(camera.getMatrix().translate(position.add((float) (Math.cos(angle) * length), (float) (-Math.sin(Math.PI + angle) * length), 0, new Vector3f())).rotateZ((float) Math.PI).rotateZ(angle).scale(thickness));
|
||||||
|
cap.render();
|
||||||
|
shader.disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAngle(float x, float y, float angle, float length) {
|
||||||
|
position.x = x;
|
||||||
|
position.y = y;
|
||||||
|
this.angle = angle;
|
||||||
|
this.length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPoints(float x1, float y1, float x2, float y2) {
|
||||||
|
float xl = x2 - x1;
|
||||||
|
float yl = y2 - y1;
|
||||||
|
length = (float) Math.sqrt(xl * xl + yl * yl);
|
||||||
|
if(x1 != x2) {
|
||||||
|
angle = (float) Math.atan(yl / xl);
|
||||||
|
if(xl < 0)
|
||||||
|
angle += Math.PI;
|
||||||
|
setAngle(x1, y1, angle, length);
|
||||||
|
}
|
||||||
|
else if(y1 > y2)
|
||||||
|
setAngle(x1, y1, (float) Math.PI * 1.5f, length);
|
||||||
|
else if(y1 < y2)
|
||||||
|
setAngle(x1, y1, (float) Math.PI * 0.5f, length);
|
||||||
|
else
|
||||||
|
setAngle(x1, y1, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPoints(Vector3f p1, Vector3f p2) {
|
||||||
|
setPoints(p1.x, p1.y, p2.x, p2.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setThickness(float thickness) {
|
||||||
|
this.thickness = thickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDepth(float z) {
|
||||||
|
position.z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColor(float r, float g, float b, float a) {
|
||||||
|
this.r = r;
|
||||||
|
this.g = g;
|
||||||
|
this.b = b;
|
||||||
|
this.a = a;
|
||||||
|
}
|
||||||
|
}
|
104
src/com/gnarly/engine/model/Rect.java
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
package com.gnarly.engine.model;
|
||||||
|
|
||||||
|
import org.joml.Vector2f;
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
|
import com.gnarly.engine.display.Camera;
|
||||||
|
|
||||||
|
public class Rect {
|
||||||
|
|
||||||
|
protected static Vao vao;
|
||||||
|
|
||||||
|
protected Camera camera;
|
||||||
|
|
||||||
|
protected float width, height;
|
||||||
|
protected Vector3f position;
|
||||||
|
protected float rotation, scale;
|
||||||
|
protected boolean gui;
|
||||||
|
|
||||||
|
protected Rect(Camera camera, float x, float y, float z, float width, float height, float rotation, boolean gui) {
|
||||||
|
this.camera = camera;
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
position = new Vector3f(x, y, z);
|
||||||
|
scale = 1;
|
||||||
|
this.rotation = rotation;
|
||||||
|
this.gui = gui;
|
||||||
|
if(vao == null) {
|
||||||
|
float vertices[] = {
|
||||||
|
1, 0, 0, // Top left
|
||||||
|
1, 1, 0, // Bottom left
|
||||||
|
0, 1, 0, // Bottom right
|
||||||
|
0, 0, 0 // Top right
|
||||||
|
};
|
||||||
|
int indices[] = {
|
||||||
|
0, 1, 3,
|
||||||
|
1, 2, 3
|
||||||
|
};
|
||||||
|
float[] texCoords = {
|
||||||
|
1, 0,
|
||||||
|
1, 1,
|
||||||
|
0, 1,
|
||||||
|
0, 0
|
||||||
|
};
|
||||||
|
vao = new Vao(vertices, indices);
|
||||||
|
vao.addAttrib(texCoords, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getX() {
|
||||||
|
return position.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getY() {
|
||||||
|
return position.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getWidth() {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getHeight() {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(float x, float y, float width, float height) {
|
||||||
|
position.x = x;
|
||||||
|
position.y = y;
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWidth(float width) {
|
||||||
|
this.width = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeight(float height) {
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPosition(float x, float y, float z) {
|
||||||
|
position.set(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPosition(Vector2f position) {
|
||||||
|
this.position.x = position.x;
|
||||||
|
this.position.y = position.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void translate(float x, float y, float z) {
|
||||||
|
position.add(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRotation(float angle) {
|
||||||
|
rotation = angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rotate(float angle) {
|
||||||
|
rotation += angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScale(float scale) {
|
||||||
|
this.scale = scale;
|
||||||
|
}
|
||||||
|
}
|