Merge branch 'master' into 'Gameplay'
# Conflicts: # .gitignore
This commit is contained in:
commit
ccf004ee0a
4
.gitignore
vendored
4
.gitignore
vendored
@ -1 +1,5 @@
|
||||
/.idea/
|
||||
/.gitignore
|
||||
/jeu-de-combat.iml
|
||||
/target/
|
||||
/bin/
|
||||
|
9
.idea/jeu-de-combat.iml
generated
Normal file
9
.idea/jeu-de-combat.iml
generated
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/jeu-de-combat.iml" filepath="$PROJECT_DIR$/jeu-de-combat.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
19
README.md
19
README.md
@ -2,11 +2,18 @@
|
||||
|
||||
Jeu de combat inspiré de Street Fighter III: Third Strike, réalisé dans le cadre du projet de fin d'année de L3 Info de l'ISTIC (2020/2021).
|
||||
|
||||
## Technologies employées
|
||||
|
||||
* Java
|
||||
* OpenGL via [lwjgl](https://www.lwjgl.org/)
|
||||
* OpenAL via [lwjgl](https://www.lwjgl.org/)
|
||||
* [JavaFX](https://openjfx.io)
|
||||
|
||||
## Contributeurs
|
||||
|
||||
* François AUTIN
|
||||
* Victor AZRA
|
||||
* Indy BOYEAU
|
||||
* Antoine DUPUIS
|
||||
* Léo NOLIÈRE
|
||||
* Rémi RATIVEL
|
||||
* [François AUTIN](https://gitlab.istic.univ-rennes1.fr/fautin)
|
||||
* [Victor AZRA](https://gitlab.istic.univ-rennes1.fr/vazra)
|
||||
* [Indy BOYEAU](https://gitlab.istic.univ-rennes1.fr/iboyeau)
|
||||
* [Antoine DUPUIS](https://gitlab.istic.univ-rennes1.fr/18002392)
|
||||
* [Léo NOLIÈRE](https://gitlab.istic.univ-rennes1.fr/lnoliere)
|
||||
* [Rémi RATIVEL](https://gitlab.istic.univ-rennes1.fr/rrativel)
|
||||
|
BIN
docs/Architecture_Moteur_V1.pdf
Normal file
BIN
docs/Architecture_Moteur_V1.pdf
Normal file
Binary file not shown.
84
docs/grammaire.txt
Normal file
84
docs/grammaire.txt
Normal file
@ -0,0 +1,84 @@
|
||||
Version modifiable:
|
||||
|
||||
|
||||
Alphabet {ε , arène[1 à n], perso[1 à n], perso[1 à n] (bot), joueur 1, joueur 2, bot,
|
||||
j1, j2, ordi, a, b, x, y, l1, r1, haut, bas, droite, gauche, egalite, vrai, faux, n, s,
|
||||
|
||||
}
|
||||
|
||||
|
||||
JEU -> PARTIE | QUITTER
|
||||
QUITTER -> ε
|
||||
PARTIE -> ARENE PERSO JOUEUR, PERSO JOUEUR, ROUND1 | QUITTER
|
||||
ARENE -> arene1 | arene2 | ... | arene n
|
||||
PERSO -> perso1 | perso2| ....| perso n | BOT
|
||||
BOT -> perso1 (bot) | perso2 (bot) | ....| perso n (bot)
|
||||
ROUND1 -> ROUND, VAINQUEUR ,ROUND2
|
||||
ROUND2 -> ROUND, VAINQUEUR ,ROUND3 | ROUND, VAINQUEUR, JOUEUR, QUITTER
|
||||
ROUND3 -> ROUND,VAINQUEUR, JOUEUR, QUITTER
|
||||
ROUND -> JOUEUR ACTION JOUEUR ACTION
|
||||
ACTION -> ATTAQUE | DEPLACEMENT | DEFENSE | FIN DE TIMER | GAGNE | (+ cas ou le joueur ne bouge pas)
|
||||
ATTAQUE -> n,NORMAL | s,SPECIAL
|
||||
SPECIAL -> a SUCCES ACTION | b SUCCES ACTION | x SUCCES ACTION | y SUCCES ACTION | (+combinaison de touche)SUCCES ACTION
|
||||
NORAML -> a SUCCES ACTION | b SUCCES ACTION | x SUCCES ACTION | y SUCCES ACTION | (+combinaison de touche)SUCCES ACTION
|
||||
SUCCES -> vrai | faux
|
||||
DEPLACEMENT -> haut ACTION | bas ACTION | droite ACTION | gauche ACTION |(+combinaison de touche)ACTION
|
||||
DEFENSE -> l1 ACTION | r1 ACTION
|
||||
FIN DE TIMER -> egalite
|
||||
GAGNE -> vrai | faux
|
||||
VAINQUEUR -> joueur 1 | joueur 2 | bot | egalite
|
||||
JOUEUR -> j1 | j2 | ordi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extension a inserer de dans la grammaire
|
||||
|
||||
action (+ cas ou le joueur ne bouge pas)
|
||||
|
||||
attaque/deplacement (combinaison de touche)ACTION
|
||||
|
||||
est ce que toute les commandes ne devriat pas être directement dans action?
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ex: arène2 Perso3 j1 Perso1 j2 (liste des actions1) joueur2 (liste des actions2)joueur1 (liste des actions3)joueur1 j1 ε
|
||||
|
||||
"lsite des actions" correspond a action durant un ROUND (expliqué plus bas)
|
||||
|
||||
signifie que dans la partie, l'arène 2 a été selectionné, le joueur 1 a pris le personnage 3 le joueur 2 le personnage 1,
|
||||
les joueurs ont effectué une liste d'action qui ont fait que le joueur2 gagne la première manche, les joueurs ont effectué une
|
||||
liste d'action qui ont fait que le joueur1 la seconde, les joueurs ont effectué une
|
||||
liste d'action qui ont fait que le joueur 1 la troisième, le joueur 1
|
||||
gagne donc la partie, la partie prends fin
|
||||
|
||||
ex:
|
||||
liste de actions1: j1 gauche n a vrai s b faux n x vrai s l1 vrai droite....faux faux j2 droite n b vrai n b vrai s a faux ....true true
|
||||
|
||||
le joueur 1 a d'abord effectué (dans l'ordre) un deplacement à "gauche", puis une attaque "n" normal correspondant a la touche "a"
|
||||
qui a aboutit "vrai", puis il a lancé une attaque spécial "s" en appuyant sur "b" mais elle n'a pas aboutit.... il n'a pas
|
||||
gagné ce round, ("faux" avant le j2), le joueur 2 a appuyé (dans l'ordre) sur les touches "droite", "b", "b", "a".... et a remporté ce round.
|
||||
|
||||
|
||||
|
||||
ex2: arène1 Perso1 j1 Perso1(bot) ordi (liste des actions1) egalite (liste des actions2) bot (liste des actions3) bot ordi ε
|
||||
|
||||
signifie que, l'arène 1 a été selectionné, le joueur1 a pris le perso1 , il a joué contre un ordi qui a pris le joueur1,
|
||||
le premier round n'a pas donné de vaiqueur (a cause du timer), le bot gagne le second round, le bot gagne le troisième
|
||||
round, l'ordi gagne donc la partie, la partie prends fin
|
||||
|
||||
ex:
|
||||
liste de actions1: j1 gauche n a faux s b faux n x faux l1 s y vrai.... egalite ordi droite n b vrai n b vrai s a faux.... egalite
|
||||
|
||||
signifie que le joueur 1 a appuyé (dans l'ordre) sur les touches "gauche", "a", "b", "x", "l1",... le timer a été
|
||||
écoulé il y a une égalité, le bot a appuyé (dans l'ordre) sur les touches "droite", "b", "b", "a"....le timer a été
|
||||
écoulé il y a une égalité
|
||||
|
27
docs/syntaxe.txt
Normal file
27
docs/syntaxe.txt
Normal file
@ -0,0 +1,27 @@
|
||||
|
||||
(interface graphique)
|
||||
|
||||
Launcher -> fct Start qui permet de lancer le menu afin de configurer la partie, elle ne prends aucun paramêtre
|
||||
|
||||
Menu -> fct Selection qui permet de choisir une arene et un joueur
|
||||
|
||||
|
||||
(moteur du jeu)
|
||||
|
||||
Engine -> fct game qui lance le moteur du jeu avec les configuration correspondant a "Config" (ex:arène et skin perso)
|
||||
|
||||
(gameplay)
|
||||
|
||||
->fct _ qui lance la boucle du jeu (cf gameplay_loop2.drawio)
|
||||
|
||||
|
||||
element moteur du jeu (https://docs.google.com/document/d/1eCxAiBJTWdCK0AfzmLIlXzun_GEAG0jeMs8qg8kWJqs/edit)
|
||||
|
||||
|
||||
|
||||
Config -> toute les config selectionné dans le menu (arene, nb_joueur, perso)
|
||||
Config est un tableau (d'entier?)
|
||||
|
||||
|
||||
|
||||
|
11
pom.xml
11
pom.xml
@ -21,6 +21,7 @@
|
||||
<properties>
|
||||
<lwjgl.version>3.2.3</lwjgl.version>
|
||||
<lwjgl.natives>natives-windows</lwjgl.natives>
|
||||
<javafx.version>11</javafx.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
@ -90,6 +91,16 @@
|
||||
<artifactId>lwjgl-stb</artifactId>
|
||||
<classifier>${lwjgl.natives}</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-controls</artifactId>
|
||||
<version>${javafx.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-fxml</artifactId>
|
||||
<version>${javafx.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<url>https://gitlab.istic.univ-rennes1.fr/fautin/jeu-de-combat</url>
|
||||
|
10
shaders/ObjectGl/frag.glsl
Normal file
10
shaders/ObjectGl/frag.glsl
Normal file
@ -0,0 +1,10 @@
|
||||
#version 330 core
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform float time;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
12
shaders/ObjectGl/vert.glsl
Normal file
12
shaders/ObjectGl/vert.glsl
Normal file
@ -0,0 +1,12 @@
|
||||
#version 330 core
|
||||
|
||||
layout (location = 0) in vec3 aPos;
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 view;
|
||||
uniform mat4 transform;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = projection * view * transform * vec4(aPos, 1.0);
|
||||
}
|
12
shaders/ObjectGlColor/frag.glsl
Normal file
12
shaders/ObjectGlColor/frag.glsl
Normal file
@ -0,0 +1,12 @@
|
||||
#version 330 core
|
||||
|
||||
in vec3 color;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform float time;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(color, 1.0f);
|
||||
}
|
16
shaders/ObjectGlColor/vert.glsl
Normal file
16
shaders/ObjectGlColor/vert.glsl
Normal file
@ -0,0 +1,16 @@
|
||||
#version 330 core
|
||||
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aColor;
|
||||
|
||||
out vec3 color;
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 view;
|
||||
uniform mat4 transform;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = projection * view * transform * vec4(aPos, 1.0);
|
||||
color = aColor;
|
||||
}
|
13
shaders/ObjectGlTex/frag.glsl
Normal file
13
shaders/ObjectGlTex/frag.glsl
Normal file
@ -0,0 +1,13 @@
|
||||
#version 410 core
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
uniform sampler2D texture1;
|
||||
uniform float time;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = texture(texture1, texCoord);
|
||||
}
|
16
shaders/ObjectGlTex/vert.glsl
Normal file
16
shaders/ObjectGlTex/vert.glsl
Normal file
@ -0,0 +1,16 @@
|
||||
#version 410 core
|
||||
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 2) in vec2 aTexCoord;
|
||||
|
||||
out vec2 texCoord;
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 view;
|
||||
uniform mat4 transform;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = projection * view * transform * vec4(aPos, 1.0);
|
||||
texCoord = aTexCoord;
|
||||
}
|
19
shaders/ObjectGlTexColor/frag.glsl
Normal file
19
shaders/ObjectGlTexColor/frag.glsl
Normal file
@ -0,0 +1,19 @@
|
||||
#version 410 core
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec4 color;
|
||||
in vec2 texCoord;
|
||||
|
||||
uniform sampler2D texture1;
|
||||
uniform float time;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 tex = texture(texture1, texCoord);
|
||||
if (tex.a == 0.0){
|
||||
FragColor = tex;
|
||||
} else{
|
||||
FragColor = mix(tex, color, 0.5);
|
||||
}
|
||||
}
|
19
shaders/ObjectGlTexColor/vert.glsl
Normal file
19
shaders/ObjectGlTexColor/vert.glsl
Normal file
@ -0,0 +1,19 @@
|
||||
#version 410 core
|
||||
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aColor;
|
||||
layout (location = 2) in vec2 aTexCoord;
|
||||
|
||||
out vec2 texCoord;
|
||||
out vec4 color;
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 view;
|
||||
uniform mat4 transform;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = projection * view * transform * vec4(aPos, 1.0);
|
||||
color = vec4(aColor, 1.0f);
|
||||
texCoord = aTexCoord;
|
||||
}
|
21
shaders/StylishShaders/BasicVert.glsl
Normal file
21
shaders/StylishShaders/BasicVert.glsl
Normal file
@ -0,0 +1,21 @@
|
||||
#version 410 core
|
||||
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aColor;
|
||||
layout (location = 2) in vec2 aTexCoord;
|
||||
|
||||
out vec2 fragCoord;
|
||||
out vec2 texCoord;
|
||||
out vec4 color;
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 view;
|
||||
uniform mat4 transform;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = projection * view * transform * vec4(aPos, 1.0);
|
||||
color = vec4(aColor, 1.0f);
|
||||
texCoord = aTexCoord;
|
||||
fragCoord = aPos.xy;
|
||||
}
|
21
shaders/StylishShaders/EnergyWave.glsl
Normal file
21
shaders/StylishShaders/EnergyWave.glsl
Normal file
@ -0,0 +1,21 @@
|
||||
#version 410
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec4 color;
|
||||
in vec2 fragCoord;
|
||||
in vec2 texCoord;
|
||||
|
||||
uniform sampler2D texture1;
|
||||
uniform float time;
|
||||
|
||||
void main()
|
||||
{ // Pas fini c'est moche
|
||||
vec4 colorPoweredUp = abs(vec4(color.xyz * sin(fragCoord.y + time*20), 1.0));
|
||||
vec4 tex = texture(texture1, texCoord);
|
||||
if (tex.a == 0.0){
|
||||
FragColor = tex;
|
||||
} else{
|
||||
FragColor = mix(tex, colorPoweredUp, 0.5);
|
||||
}
|
||||
}
|
@ -7,27 +7,17 @@
|
||||
*
|
||||
*/
|
||||
|
||||
import launcher.Launcher;
|
||||
import engine.Engine;
|
||||
import launcher.Launcher;
|
||||
import javafx.application.Application;
|
||||
|
||||
public class Main {
|
||||
|
||||
// Interface de configuration et lancement
|
||||
static Launcher launcher = new Launcher();
|
||||
|
||||
// Moteur de jeu
|
||||
static Engine game = new Engine();
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
|
||||
// Lancement de l'interface de configuration du Jeu
|
||||
try {
|
||||
launcher.launch();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Application.launch(Launcher.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
165
src/configuration/Config.java
Normal file
165
src/configuration/Config.java
Normal file
@ -0,0 +1,165 @@
|
||||
package configuration;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class Config {
|
||||
|
||||
// tester a la main (okay normalement mais ajouter des test)
|
||||
public static void main(String[] args) {
|
||||
int[] tempfortest = { 0, 2, 1, 1 }; // {arene/nb_joueur/perso1/perso2} 0=alatoire
|
||||
config(tempfortest);
|
||||
}
|
||||
|
||||
// les variable a configurer
|
||||
// sel1 pour savoir si on a deja selectionner le joueur 1
|
||||
|
||||
public static String arene, perso1, perso2;
|
||||
public static int nb_joueur;
|
||||
private static boolean sel1 = false;
|
||||
|
||||
/*
|
||||
* fonction config qui prend en entre un tableau d'entier chaque case
|
||||
* correspondant a une variable, et ne retourne rien mais modifie la valeur des
|
||||
* variables par des fonctions annexes
|
||||
*/
|
||||
|
||||
private static void config(int[] tab) {
|
||||
int i = 0;
|
||||
while (i < tab.length) {
|
||||
|
||||
switch (i) {
|
||||
case 0:
|
||||
SelArene(tab[i]);
|
||||
i++;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
NbJoueur(tab[i]);
|
||||
i++;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
SelPerso(tab[i]);
|
||||
i++;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
SelPerso(tab[i]);
|
||||
i++;
|
||||
break;
|
||||
/*
|
||||
* case 4: ?
|
||||
*/
|
||||
|
||||
default:
|
||||
System.out.println("ERROR OUT OF BOUNDS CONFIG ARRAY");
|
||||
i = tab.length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
System.out.println(arene + " " + nb_joueur + " " + perso1 + " " + perso2 + " " + sel1);
|
||||
}
|
||||
|
||||
/*
|
||||
* fonction SelArene prend un entier en parametre et permet de choisir l'arene
|
||||
* du jeu
|
||||
*/
|
||||
|
||||
private static void SelArene(int s) {
|
||||
switch (s) {
|
||||
case 0:
|
||||
SelArene(random(1, 2));
|
||||
break;
|
||||
case 1:
|
||||
arene = "arene1.png";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
arene = "arene2.png";
|
||||
break;
|
||||
|
||||
default:
|
||||
System.out.println("ERROR ARENE INEXISTANTE");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* fonction NbJoueur prend un entier en parametre et permet de determiner si un
|
||||
* bot sera necessaire
|
||||
*/
|
||||
|
||||
private static void NbJoueur(int s) {
|
||||
switch (s) {
|
||||
case 1:
|
||||
nb_joueur = 1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
nb_joueur = 2;
|
||||
break;
|
||||
default:
|
||||
System.out.println("ERROR NUMBER OF PLAYER");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* fonction SelArene prend un entier en parametre et permet de choisir le
|
||||
* personnage en fonction du joueur
|
||||
*/
|
||||
|
||||
private static void SelPerso(int s) {
|
||||
if (sel1 == false) {
|
||||
switch (s) {
|
||||
case 0:
|
||||
SelPerso(random(1, 2));
|
||||
break;
|
||||
case 1:
|
||||
perso1 = "perso1.png";
|
||||
sel1 = true;
|
||||
break;
|
||||
case 2:
|
||||
perso1 = "perso2.png";
|
||||
sel1 = true;
|
||||
break;
|
||||
default:
|
||||
System.out.println("ERROR PERSO INEXISTANT");
|
||||
}
|
||||
} else if (sel1 == true) {
|
||||
|
||||
switch (s) {
|
||||
case 0:
|
||||
SelPerso(random(1, 2));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
perso2 = "perso1.png";
|
||||
sel1 = false;
|
||||
if (perso1 == perso2) {
|
||||
perso2 = "perso1_swapcolor.png";
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
perso2 = "perso2.png";
|
||||
sel1 = false;
|
||||
if (perso1 == perso2) {
|
||||
perso2 = "perso2_swapcolor.png";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
System.out.println("ERROR PERSO INEXISTANT");
|
||||
}
|
||||
} else {
|
||||
System.out.println("ERROR SELECTION PLAYER");
|
||||
}
|
||||
}
|
||||
|
||||
// fonction nombre aleatoire entre deux borne
|
||||
private static int random(int min, int max) {
|
||||
Random random = new Random();
|
||||
int value = random.nextInt(max - 1 + min) + min;
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
@ -1,14 +1,305 @@
|
||||
/**
|
||||
* CLASS ENGINE
|
||||
*
|
||||
* Classe principale du moteur de jeu
|
||||
*
|
||||
* @author François Autin
|
||||
*
|
||||
*/
|
||||
|
||||
package engine;
|
||||
|
||||
import engine.math.*;
|
||||
import engine.object.*;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.glfw.GLFWFramebufferSizeCallback;
|
||||
import org.lwjgl.glfw.GLFWVidMode;
|
||||
import org.lwjgl.opengl.GL;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.*;
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
import static org.lwjgl.system.MemoryUtil.NULL;
|
||||
|
||||
public class Engine {
|
||||
|
||||
private static long window;
|
||||
|
||||
private final List<ObjectGl> objectsGl;
|
||||
|
||||
private static boolean present = glfwJoystickPresent(GLFW_JOYSTICK_1);
|
||||
|
||||
private boolean running;
|
||||
|
||||
/**
|
||||
* Create the engine and initial attributes use .init() to start the engine
|
||||
*/
|
||||
public Engine() {
|
||||
this.running = false;
|
||||
this.objectsGl = new ArrayList<>();
|
||||
float width = 1280.0f;
|
||||
ObjectGl.projection = Matrix4f.orthographic(-width, width, -width * 9.0f / 16.0f, width * 9.0f / 16.0f, 0.1f, 100.0f);
|
||||
ObjectGl.view = Matrix4f.translate(new Vector3f(0.0f,0.0f,1.0f));
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the engine
|
||||
* Create the window
|
||||
* Set the color of the background
|
||||
*/
|
||||
public void init() {
|
||||
glfwInit();
|
||||
|
||||
this.running = true;
|
||||
|
||||
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); //On utilise la version 3.3 d'openGL
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); //Compatible MAC
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //Le core profile est l'interface 'avancé' d'openGL
|
||||
|
||||
int width = 1280;
|
||||
int height = 720;
|
||||
this.setWindow(glfwCreateWindow(width, height, "Boulevard Combattant", NULL, NULL));
|
||||
assert getWindow() != NULL;
|
||||
|
||||
|
||||
System.out.println(present);
|
||||
|
||||
// On récupère les informations du moniteur principal
|
||||
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
|
||||
assert vidmode != null;
|
||||
|
||||
// On met la fenêtre au centre de l'écran principale
|
||||
glfwSetWindowPos(getWindow(), (vidmode.width() - width)/2, (vidmode.height() - height)/2);
|
||||
|
||||
glfwSetKeyCallback(getWindow(), new Input());
|
||||
glfwSetInputMode(getWindow(), GLFW_STICKY_KEYS, GLFW_TRUE);
|
||||
|
||||
// Contexte = zone cible des rendus
|
||||
glfwMakeContextCurrent(getWindow());
|
||||
glfwShowWindow(getWindow());
|
||||
GL.createCapabilities();
|
||||
|
||||
glfwSetFramebufferSizeCallback(getWindow(), resizeWindow);
|
||||
|
||||
glEnable(GL_DEPTH_TEST); // Z-Buffer plus z est grand plus l'objet est proche de la camera limite à 100.0f au dela l'objet disparait
|
||||
|
||||
glEnable(GL_BLEND); // Transparence
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||||
System.out.println("OpenGL: " + glGetString(GL_VERSION));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void update(){
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void render(){
|
||||
|
||||
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
objectsGl.sort(new SortZ());
|
||||
for (ObjectGl objectGl : objectsGl) {
|
||||
objectGl.render();
|
||||
}
|
||||
|
||||
int error = glGetError();
|
||||
if (error != GL_NO_ERROR) System.out.println(error);
|
||||
glfwSwapBuffers(getWindow()); //Envoie le buffer vers le moniteur
|
||||
}
|
||||
|
||||
/**
|
||||
* Add obj to the render queue
|
||||
* @param obj
|
||||
*/
|
||||
public void add_objectGl(ObjectGl obj){
|
||||
objectsGl.add(obj);
|
||||
}
|
||||
|
||||
public void remove_objectGl(ObjectGl obj){
|
||||
objectsGl.remove(obj);
|
||||
}
|
||||
|
||||
public boolean isRunning(){
|
||||
return running;
|
||||
}
|
||||
|
||||
public void setRunning(boolean b){
|
||||
running = b;
|
||||
}
|
||||
|
||||
public boolean shouldClose(){
|
||||
return glfwWindowShouldClose(getWindow());
|
||||
}
|
||||
|
||||
public static long getWindow() {
|
||||
return window;
|
||||
}
|
||||
|
||||
public void setWindow(long window) {
|
||||
Engine.window = window;
|
||||
}
|
||||
|
||||
/**
|
||||
* Est appelé à a chaque modification de la taille de la fenêtre, et modifie la taille de la zone de rendu
|
||||
* pour quelle corresponde à la taille de la fenêtre
|
||||
*/
|
||||
private static final GLFWFramebufferSizeCallback resizeWindow = new GLFWFramebufferSizeCallback(){
|
||||
@Override
|
||||
public void invoke(long window, int width, int height){
|
||||
glViewport(0,0,width,height);
|
||||
}
|
||||
};
|
||||
|
||||
public static void main(String[] args) {
|
||||
Engine engine = new Engine();
|
||||
int speed = 10 ; //vitesse déplacement Object
|
||||
engine.init();
|
||||
|
||||
// Add objects to render
|
||||
String path = "textures/zangief_sprite.png";
|
||||
|
||||
String path2 = "textures/awesomeface.png";
|
||||
|
||||
ObjectGl zangief = new ObjectGl(0f,60f,80f,10f, path, null);
|
||||
zangief.setTextureWrap(58,0,62,84, ObjectGl.STICK_TOP);
|
||||
engine.add_objectGl(zangief);
|
||||
zangief.translate(new Vector3f(-5000.0f,500.0f,10.0f));
|
||||
zangief.setColor(new Vector3f(0.0f, 0.0f, 1.0f));
|
||||
zangief.useTime = true;
|
||||
zangief.setShader("shaders/StylishShaders/BasicVert.glsl","shaders/StylishShaders/EnergyWave.glsl");
|
||||
|
||||
// ObjectGl smiley2 = new ObjectGl(0.0f,500.0f,500.0f, 1f, path2, null);
|
||||
// engine.add_objectGl(smiley2);
|
||||
// smiley2.translate(new Vector3f(0.0f,0.0f,5.0f));
|
||||
|
||||
long timer = System.currentTimeMillis();
|
||||
long lastFrame;
|
||||
int frame = 0;
|
||||
boolean nextFrame = false;
|
||||
|
||||
while(engine.isRunning()){
|
||||
lastFrame = System.currentTimeMillis();
|
||||
// Game logic should fit here
|
||||
|
||||
if (present) {
|
||||
gamepadInput(zangief, speed);
|
||||
}
|
||||
|
||||
input(zangief, speed);
|
||||
// input(smiley2, speed);
|
||||
|
||||
/*
|
||||
********************
|
||||
* essential part v *
|
||||
********************
|
||||
*/
|
||||
engine.update();
|
||||
engine.render();
|
||||
|
||||
frame++;
|
||||
|
||||
if (System.currentTimeMillis() - timer > 1000) {
|
||||
timer += 1000;
|
||||
System.out.println("FPS: " + frame);
|
||||
frame = 0;
|
||||
}
|
||||
|
||||
while(!nextFrame){
|
||||
nextFrame = System.currentTimeMillis() - lastFrame >= 16.66f;
|
||||
}
|
||||
|
||||
nextFrame = false;
|
||||
if(engine.shouldClose()) engine.setRunning(false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void gamepadInput(ObjectGl token, int speed) {
|
||||
ByteBuffer gamepadButton = glfwGetJoystickButtons(GLFW_JOYSTICK_1);
|
||||
FloatBuffer gamepadAxes = glfwGetJoystickAxes(GLFW_JOYSTICK_1);
|
||||
|
||||
assert gamepadAxes != null;
|
||||
assert gamepadButton != null;
|
||||
|
||||
String name = GLFW.glfwGetJoystickName(GLFW_JOYSTICK_1);
|
||||
System.out.println("GamePad Name :" + name);
|
||||
// for (int i =0 ; i < gamepadAxes.capacity(); i++) {
|
||||
// System.out.println(i + " :" + gamepadAxes.get(i));
|
||||
// }
|
||||
|
||||
|
||||
if (gamepadButton.get(0) ==1 ) { // appuie sur croix(PlayStation) A (Xbox)
|
||||
token.translate(new Vector3f ( 0.0f, speed * 5.0f, 0.0f));
|
||||
}
|
||||
if ( (gamepadAxes.get(2) < -0.1 || gamepadAxes.get(2) > 0.1) ) { // de droite à gauche //joystick gauche
|
||||
token.translate(new Vector3f (5*speed * gamepadAxes.get(2), 0.0f, 0.0f));
|
||||
if ( gamepadAxes.get(2) < -0.1 ){
|
||||
token.setTextureWrap(121,0,57,80, ObjectGl.DEFAULT);
|
||||
}else if (gamepadAxes.get(2) > 0.1) {
|
||||
token.setTextureWrap(178,0,62,82, ObjectGl.DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
if ( (gamepadAxes.get(3) < -0.1 || gamepadAxes.get(3) > 0.1) ) { // de haut en bas //joystick gauche
|
||||
token.translate(new Vector3f (0.0f, -5* speed * gamepadAxes.get(3), 0.0f));
|
||||
|
||||
}
|
||||
|
||||
/* Buttons
|
||||
0 : Croix / A
|
||||
1: rond /B
|
||||
2: carré / X
|
||||
3: triangle / Y
|
||||
4: L1 / LB
|
||||
5: R1 / RB
|
||||
6:select
|
||||
7:start
|
||||
8:L3
|
||||
9:R3
|
||||
10: haut
|
||||
11: droite
|
||||
12: bas
|
||||
13: gauche
|
||||
*/
|
||||
|
||||
/* Axes
|
||||
0 : left X axe ( right : 1 left -1)
|
||||
1: left Y axe ( down : 1 , Up -1)
|
||||
2: right X axe ( right : 1 left -1)
|
||||
3: right Y axe ( down : 1 , Up -1)
|
||||
4:L2 / LT : 1 active, -1 unactive
|
||||
5: R2 /RT : 1 active, -1 unactive
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
public static void input(ObjectGl token, int speed) {
|
||||
boolean keyPressed = false;
|
||||
if (Input.isKeyDown(GLFW.GLFW_KEY_S)) {
|
||||
token.setTextureWrap(161,260,56,59, ObjectGl.STICK_BOTTOM);
|
||||
keyPressed = true;
|
||||
} else if (Input.isKeyDown(GLFW.GLFW_KEY_W)) {
|
||||
// token.translate(new Vector3f (0.0f, speed * 5.0f, 0.0f));
|
||||
keyPressed = true;
|
||||
}
|
||||
if (Input.isKeyDown(GLFW.GLFW_KEY_A)) {
|
||||
token.translate(new Vector3f (speed *-5.0f, 0.0f, 0.0f));
|
||||
// token.setTextureWrap(121,0,57,80, ObjectGl.STICK_TOP);
|
||||
token.setTextureWrap(121,0,57,82, ObjectGl.STICK_TOP);
|
||||
keyPressed = true;
|
||||
}
|
||||
else if (Input.isKeyDown(GLFW.GLFW_KEY_D)) {
|
||||
token.translate(new Vector3f (speed * 5.0f, 0.0f, 0.0f));
|
||||
// token.setTextureWrap(178,0,62,82, ObjectGl.STICK_TOP);
|
||||
token.setTextureWrap(178,0,62,82, ObjectGl.STICK_TOP);
|
||||
keyPressed = true;
|
||||
}
|
||||
// if (!keyPressed) token.setTextureWrap(58,0,62,84, ObjectGl.STICK_TOP);
|
||||
if (!keyPressed) token.setTextureWrap(58,0,62,82, ObjectGl.STICK_TOP);
|
||||
}
|
||||
}
|
||||
|
26
src/engine/Input.java
Normal file
26
src/engine/Input.java
Normal file
@ -0,0 +1,26 @@
|
||||
package engine;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.glfw.GLFWKeyCallback;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.*;
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
public class Input extends GLFWKeyCallback {
|
||||
|
||||
public static boolean[] keys = new boolean[65536];
|
||||
|
||||
@Override
|
||||
public void invoke(long window, int key, int scancode, int action, int mods) {
|
||||
keys[key] = action != GLFW.GLFW_RELEASE;
|
||||
if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
else if(key == GLFW_KEY_SPACE && action == GLFW_PRESS) //Switch to wireframe
|
||||
if (glGetInteger(GL_POLYGON_MODE) == GL_FILL) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
else glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
public static boolean isKeyDown(int keyCode) {
|
||||
return glfwGetKey(Engine.getWindow(), keyCode) == 1;
|
||||
}
|
||||
|
||||
}
|
75
src/engine/graphics/Shader.java
Normal file
75
src/engine/graphics/Shader.java
Normal file
@ -0,0 +1,75 @@
|
||||
package engine.graphics;
|
||||
|
||||
import engine.math.Matrix4f;
|
||||
import engine.utils.ShaderUtils;
|
||||
import engine.math.Vector3f;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.lwjgl.opengl.GL20.*;
|
||||
|
||||
public class Shader {
|
||||
|
||||
private boolean enabled = false;
|
||||
|
||||
//Identifiant du programme resultat de la compilation des shaders
|
||||
private final int ID;
|
||||
private Map<String, Integer> locationCache = new HashMap<String, Integer>();
|
||||
|
||||
/*
|
||||
Crée le fragment et le vertex shader les lie dans un programme dont il renvoie l'identifiant.
|
||||
*/
|
||||
public Shader(String vertex, String fragment) {
|
||||
ID = ShaderUtils.load(vertex, fragment);
|
||||
}
|
||||
|
||||
public int getUniform(String name){
|
||||
if (locationCache.containsKey(name)) return locationCache.get(name);
|
||||
int result = glGetUniformLocation(ID, name);
|
||||
if (result == -1) System.err.println("Could not find uniform variable " + name);
|
||||
else locationCache.put(name, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setUniform1i(String name, int value) {
|
||||
if (!enabled) enable();
|
||||
glUniform1i(getUniform(name), value);
|
||||
}
|
||||
|
||||
public void setUniform1f(String name, float value) {
|
||||
if (!enabled) enable();
|
||||
glUniform1f(getUniform(name), value);
|
||||
}
|
||||
|
||||
public void setUniform2f(String name, float x, float y) {
|
||||
if (!enabled) enable();
|
||||
glUniform2f(getUniform(name), x, y);
|
||||
}
|
||||
|
||||
public void setUniform3f(String name, Vector3f vector) {
|
||||
if (!enabled) enable();
|
||||
glUniform3f(getUniform(name), vector.x, vector.y, vector.z);
|
||||
}
|
||||
|
||||
public void setUniform4f(String name, float x, float y, float z, float w) {
|
||||
if (!enabled) enable();
|
||||
glUniform4f(getUniform(name), x, y, z, w);
|
||||
}
|
||||
|
||||
public void setUniformMat4f(String name, Matrix4f matrix){
|
||||
if (!enabled) enable();
|
||||
glUniformMatrix4fv(getUniform(name), false, matrix.toFloatBuffer());
|
||||
}
|
||||
|
||||
public void enable() {
|
||||
glUseProgram(ID);
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
glUseProgram(0);
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
}
|
75
src/engine/graphics/Texture.java
Normal file
75
src/engine/graphics/Texture.java
Normal file
@ -0,0 +1,75 @@
|
||||
package engine.graphics;
|
||||
|
||||
import engine.utils.BufferUtils;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
import static org.lwjgl.opengl.GL30.*;
|
||||
|
||||
public class Texture {
|
||||
|
||||
private int width, height;
|
||||
private int texture;
|
||||
private int index;
|
||||
|
||||
public Texture(String path, int index) {
|
||||
this.index = index;
|
||||
texture = load(path);
|
||||
}
|
||||
|
||||
private int load(String path) {
|
||||
int[] pixels = null;
|
||||
try {
|
||||
BufferedImage image = ImageIO.read(new FileInputStream(path));
|
||||
width = image.getWidth();
|
||||
height = image.getHeight();
|
||||
pixels = new int[width * height];
|
||||
image.getRGB(0, 0, width, height, pixels, 0, width);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
int[] data = new int[width * height];
|
||||
for (int i = 0; i < width * height; i++) {
|
||||
int a = (pixels[i] & 0xff000000) >> 24;
|
||||
int r = (pixels[i] & 0xff0000) >> 16;
|
||||
int g = (pixels[i] & 0xff00) >> 8;
|
||||
int b = (pixels[i] & 0xff);
|
||||
|
||||
data[i] = a << 24 | b << 16 | g << 8 | r;
|
||||
}
|
||||
|
||||
int result = glGenTextures();
|
||||
glBindTexture(GL_TEXTURE_2D, result);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
GL11.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, BufferUtils.createIntBuffer(data));
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void bind() {
|
||||
glActiveTexture(GL_TEXTURE0 + this.index);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
}
|
||||
|
||||
public void unbind() {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
public int getWidth(){
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight(){
|
||||
return height;
|
||||
}
|
||||
|
||||
}
|
89
src/engine/graphics/VertexArray.java
Normal file
89
src/engine/graphics/VertexArray.java
Normal file
@ -0,0 +1,89 @@
|
||||
package engine.graphics;
|
||||
|
||||
import engine.utils.BufferUtils;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
import static org.lwjgl.opengl.GL15.*;
|
||||
import static org.lwjgl.opengl.GL30.*;
|
||||
|
||||
public class VertexArray {
|
||||
|
||||
private int VAO ,VBO, EBO, CBO, TBO;
|
||||
private int count;
|
||||
|
||||
public VertexArray(float[] vertices, byte[] indices, float[] color, float[] texture) {
|
||||
count = indices.length;
|
||||
// VERTEX ARRAY OBJECT
|
||||
VAO = glGenVertexArrays();
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
// VERTEX BUFFER OBJECT
|
||||
createVertexBufferObject(vertices);
|
||||
// COLOR BUFFER OBJECT
|
||||
if (color != null) createColorBufferObject(color);
|
||||
// TEXTURE BUFFER OBJECT
|
||||
if (texture != null) createTextureBufferObject(texture);
|
||||
|
||||
EBO = glGenBuffers();
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, BufferUtils.createByteBuffer(indices), GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
}
|
||||
|
||||
private void createVertexBufferObject(float[] vertices){
|
||||
VBO = glGenBuffers();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, BufferUtils.createFloatBuffer(vertices), GL_STATIC_DRAW);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
|
||||
glEnableVertexAttribArray(0);
|
||||
}
|
||||
|
||||
private void createColorBufferObject(float[] color){
|
||||
CBO = glGenBuffers();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, CBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, BufferUtils.createFloatBuffer(color), GL_STATIC_DRAW);
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, false, 0, 0);
|
||||
glEnableVertexAttribArray(1);
|
||||
}
|
||||
|
||||
private void createTextureBufferObject(float[] texture){
|
||||
TBO = glGenBuffers();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, TBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, BufferUtils.createFloatBuffer(texture), GL_STATIC_DRAW);
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, false, 0, 0);
|
||||
glEnableVertexAttribArray(2);
|
||||
}
|
||||
|
||||
public void swapVertexBufferObject(float[] vertices){
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, BufferUtils.createFloatBuffer(vertices), GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
public void swapTextureBufferObject(float [] texture){
|
||||
glBindBuffer(GL_ARRAY_BUFFER, TBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, BufferUtils.createFloatBuffer(texture), GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
public void bind(){
|
||||
glBindVertexArray(this.VAO);
|
||||
}
|
||||
|
||||
public void unbind(){
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
public void draw(){
|
||||
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_BYTE, 0);
|
||||
}
|
||||
|
||||
public void render(){
|
||||
bind();
|
||||
draw();
|
||||
unbind();
|
||||
}
|
||||
|
||||
}
|
123
src/engine/math/Matrix4f.java
Normal file
123
src/engine/math/Matrix4f.java
Normal file
@ -0,0 +1,123 @@
|
||||
package engine.math;
|
||||
|
||||
import engine.utils.BufferUtils;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
public class Matrix4f {
|
||||
|
||||
public static final int SIZE = 4 * 4;
|
||||
public float[] elements = new float[4 * 4];
|
||||
|
||||
public Matrix4f(){
|
||||
|
||||
}
|
||||
|
||||
public static Matrix4f identity(){
|
||||
Matrix4f result = new Matrix4f();
|
||||
for (int i = 0; i < SIZE; i++){
|
||||
result.elements[i] = 0.0f;
|
||||
}
|
||||
result.elements[0 + 0 * 4] = 1.0f;
|
||||
result.elements[1 + 1 * 4] = 1.0f;
|
||||
result.elements[2 + 2 * 4] = 1.0f;
|
||||
result.elements[3 + 3 * 4] = 1.0f;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Matrix4f orthographic(float left, float right, float bottom, float top, float near, float far){
|
||||
Matrix4f result = identity();
|
||||
|
||||
result.elements[0 + 0 * 4] = 2.0f / (right - left);
|
||||
result.elements[1 + 1 * 4] = 2.0f / (top - bottom);
|
||||
result.elements[2 + 2 * 4] = 2.0f / (near - far);
|
||||
|
||||
result.elements[0 + 3 * 4] = (left + right) / (left - right);
|
||||
result.elements[1 + 3 * 4] = (bottom + top) / (bottom - top);
|
||||
result.elements[2 + 3 * 4] = (far + near) / (far - near);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Matrix4f translate(Vector3f vector){
|
||||
Matrix4f result= identity();
|
||||
result.elements[0 + 3*4] = vector.x;
|
||||
result.elements[1 + 3*4] = vector.y;
|
||||
result.elements[2 + 3*4] = vector.z;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Matrix4f scale(Vector3f vector){
|
||||
Matrix4f result= identity();
|
||||
result.elements[0 + 0*4] = vector.x;
|
||||
result.elements[1 + 1*4] = vector.y;
|
||||
result.elements[2 + 2*4] = vector.z;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Matrix4f rotateX(float angle){
|
||||
Matrix4f result = identity();
|
||||
float r = (float) Math.toRadians(angle);
|
||||
float cos = (float) Math.cos(r);
|
||||
float sin = (float) Math.sin(r);
|
||||
|
||||
result.elements[1 + 1 * 4] = cos;
|
||||
result.elements[2 + 1 * 4] = -sin;
|
||||
|
||||
result.elements[1 + 2 * 4] = sin;
|
||||
result.elements[2 + 2 * 4] = cos;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Matrix4f rotateY(float angle){
|
||||
Matrix4f result = identity();
|
||||
float r = (float) Math.toRadians(angle);
|
||||
float cos = (float) Math.cos(r);
|
||||
float sin = (float) Math.sin(r);
|
||||
|
||||
result.elements[0 + 0 * 4] = cos;
|
||||
result.elements[2 + 0 * 4] = sin;
|
||||
|
||||
result.elements[0 + 2 * 4] = -sin;
|
||||
result.elements[2 + 2 * 4] = cos;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Matrix4f rotateZ(float angle){
|
||||
Matrix4f result = identity();
|
||||
float r = (float) Math.toRadians(angle);
|
||||
float cos = (float) Math.cos(r);
|
||||
float sin = (float) Math.sin(r);
|
||||
|
||||
result.elements[0 + 0 * 4] = cos;
|
||||
result.elements[1 + 0 * 4] = -sin;
|
||||
|
||||
result.elements[0 + 1 * 4] = sin;
|
||||
result.elements[1 + 1 * 4] = cos;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Matrix4f multiply(Matrix4f matrix){
|
||||
Matrix4f result = new Matrix4f();
|
||||
for (int y = 0; y< 4; y++){
|
||||
for (int x = 0; x< 4; x++){
|
||||
float sum = 0.0f;
|
||||
for (int e = 0; e< 4; e++){
|
||||
sum += this.elements[x + e * 4] * matrix.elements[e + y * 4];
|
||||
}
|
||||
result.elements[x + y * 4] = sum;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public FloatBuffer toFloatBuffer() {
|
||||
return BufferUtils.createFloatBuffer(elements);
|
||||
}
|
||||
|
||||
}
|
38
src/engine/math/Primitive.java
Normal file
38
src/engine/math/Primitive.java
Normal file
@ -0,0 +1,38 @@
|
||||
package engine.math;
|
||||
|
||||
import engine.math.Vector3f;
|
||||
|
||||
public class Primitive {
|
||||
|
||||
public static float[] createRectangle(float z, float w, float h){
|
||||
return new float[] {
|
||||
0 , 0 , z, // Haut gauche
|
||||
0 + w, 0 , z, // Haut droit
|
||||
0 + w, 0 - h, z, // Bas droit
|
||||
0 , 0 - h, z // Bas gauche
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Chaque point correspond à un vertex de la primite le reste est interpolé
|
||||
*/
|
||||
public static float[] stdTexWrap = new float[] {
|
||||
0.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
1.0f, 1.0f,
|
||||
0.0f, 1.0f
|
||||
};
|
||||
|
||||
public static float[] upperHalfTexWrap = new float[] {
|
||||
0.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
1.0f, 0.5f,
|
||||
0.0f, 0.5f
|
||||
};
|
||||
|
||||
public static byte[] rectangle_indices = new byte[] {
|
||||
0, 1, 3,
|
||||
1, 2, 3
|
||||
};
|
||||
|
||||
}
|
24
src/engine/math/Vector3f.java
Normal file
24
src/engine/math/Vector3f.java
Normal file
@ -0,0 +1,24 @@
|
||||
package engine.math;
|
||||
|
||||
public class Vector3f {
|
||||
|
||||
public float x, y, z;
|
||||
|
||||
public Vector3f(){
|
||||
x = 0.0f;
|
||||
y = 0.0f;
|
||||
z = 0.0f;
|
||||
}
|
||||
|
||||
public Vector3f(float x, float y, float z){
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public void divXY(float div){
|
||||
this.x /= div;
|
||||
this.y /= div;
|
||||
}
|
||||
|
||||
}
|
237
src/engine/object/ObjectGl.java
Normal file
237
src/engine/object/ObjectGl.java
Normal file
@ -0,0 +1,237 @@
|
||||
package engine.object;
|
||||
|
||||
import engine.graphics.*;
|
||||
import engine.math.*;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.glfwGetTime;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class ObjectGl {
|
||||
|
||||
/**
|
||||
* STATE CONST DECLARATION
|
||||
*/
|
||||
public static final int DEFAULT = 0, STICK_BOTTOM = 1, STICK_TOP = 2;
|
||||
|
||||
private int stick_state;
|
||||
|
||||
protected VertexArray vertexArray;
|
||||
protected Shader shader;
|
||||
protected Matrix4f transform;
|
||||
|
||||
/**
|
||||
* Projection and view matrix are set by the engine do not modify
|
||||
*/
|
||||
public static Matrix4f projection;
|
||||
public static Matrix4f view;
|
||||
|
||||
private float zPos;
|
||||
private float width; // To be used in setTextureWrap
|
||||
private float height;
|
||||
private float scalingFactor;
|
||||
|
||||
public boolean useTime;
|
||||
|
||||
private Texture texture;
|
||||
|
||||
/**
|
||||
* Create a rectangle shape, use setTextureWrap to correctly align the texture with the model
|
||||
* @param z depth of your model the larger it is the more it will be "close" to the camera
|
||||
* @param w height of the rectangle
|
||||
* @param h width of the rectangle
|
||||
* @param size scaling factor of the rectangle, the model could not show up because this value is too small or too large, a good compromise is between 2 and 15
|
||||
* @param tex set to null if you don't want a tex on your model
|
||||
* @param color set to null if you don't want a Color on your model
|
||||
*/
|
||||
public ObjectGl(float z, float w, float h, float size, String tex, Vector3f color){
|
||||
float[] colorBuffer = null;
|
||||
// Check des options
|
||||
if (color != null){
|
||||
colorBuffer = new float[] {
|
||||
color.x, color.y, color.z,
|
||||
color.x, color.y, color.z,
|
||||
color.x, color.y, color.z,
|
||||
color.x, color.y, color.z
|
||||
};
|
||||
}
|
||||
|
||||
if (tex != null){
|
||||
this.texture = new Texture(tex, 0);
|
||||
}
|
||||
|
||||
this.zPos = z;
|
||||
this.height = h;
|
||||
this.width = w;
|
||||
|
||||
this.vertexArray = new VertexArray(Primitive.createRectangle(this.zPos, this.width, this.height), Primitive.rectangle_indices, colorBuffer, Primitive.stdTexWrap);
|
||||
|
||||
this.scalingFactor = size;
|
||||
this.transform = Matrix4f.identity();
|
||||
this.scale(new Vector3f(size, size,1f));
|
||||
this.stick_state = DEFAULT;
|
||||
this.useTime = false;
|
||||
|
||||
// use different shader for each set of option
|
||||
if (tex == null && color == null){
|
||||
this.shader = new Shader("shaders/ObjectGl/vert.glsl","shaders/ObjectGl/frag.glsl");
|
||||
} else if (tex == null){
|
||||
this.shader = new Shader("shaders/ObjectGlColor/vert.glsl","shaders/ObjectGlColor/frag.glsl");
|
||||
} else if (color == null){
|
||||
this.shader = new Shader("shaders/ObjectGlTex/vert.glsl","shaders/ObjectGlTex/frag.glsl");
|
||||
} else {
|
||||
this.shader = new Shader("shaders/ObjectGlTexColor/vert.glsl","shaders/ObjectGlTexColor/frag.glsl");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the transform matrix, the model will appear at the 0.0.0 coordinate, his scaleFactor will be set to zero
|
||||
* Because the model is at position 0 on the z axis he will not show up on screen
|
||||
*/
|
||||
public void resetTransform(){
|
||||
this.transform = Matrix4f.identity();
|
||||
this.scalingFactor = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the object according to vec, direction can change if rotation method have been used
|
||||
* @param vec Vector3f
|
||||
*/
|
||||
public void translate(Vector3f vec){
|
||||
vec.divXY(this.scalingFactor);
|
||||
this.transform = this.transform.multiply(Matrix4f.translate(vec));
|
||||
this.zPos += vec.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale the model with the vec vector, the x component is used to mitigate size modification in the behavior of other transformation method
|
||||
* @param vec Vector3f
|
||||
*/
|
||||
public void scale(Vector3f vec){
|
||||
this.scalingFactor *= vec.x;
|
||||
this.transform = this.transform.multiply(Matrix4f.scale(vec));
|
||||
}
|
||||
|
||||
/**
|
||||
* rotate the model by angle degree on the local x axis, beware this will change the behavior of the translate method
|
||||
* @param angle in degree
|
||||
*/
|
||||
public void rotateX(float angle){
|
||||
this.transform = this.transform.multiply(Matrix4f.rotateX(angle));
|
||||
}
|
||||
|
||||
/**
|
||||
* rotate the model by angle degree on the local y axis, beware this will change the behavior of the translate method
|
||||
* @param angle in degree
|
||||
*/
|
||||
public void rotateY(float angle){
|
||||
this.transform = this.transform.multiply(Matrix4f.rotateY(angle));
|
||||
}
|
||||
|
||||
/**
|
||||
* rotate the model by angle degree on the local z axis, beware this will change the behavior of the translate method
|
||||
* @param angle in degree
|
||||
*/
|
||||
public void rotateZ(float angle){
|
||||
this.transform = this.transform.multiply(Matrix4f.rotateZ(angle));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new texture to be used on the model. You may need to use setTextureWrap tp get the correct wrap
|
||||
* @param texPath path to the new texture
|
||||
*/
|
||||
public void setTexture(String texPath){
|
||||
this.texture = new Texture(texPath, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the wrapping coordinate
|
||||
* @param x starting wrapping on the horizontal axis
|
||||
* @param y starting wrapping on the vertical axis
|
||||
* @param w the length of the wrapping on the horizontal axis
|
||||
* @param h the length of the wrapping on the vertical axis
|
||||
*/
|
||||
public void setTextureWrap(float x, float y, float w, float h, int sticky){
|
||||
// TODO set sticky property + precision issue
|
||||
if (this.stick_state != sticky){ // Check if we're using a new dimension
|
||||
if (sticky == STICK_BOTTOM){
|
||||
this.stick_state = STICK_BOTTOM;
|
||||
this.translate(new Vector3f(0.0f, (h - this.height)*this.scalingFactor, 0.0f));
|
||||
} else if (sticky == STICK_TOP){
|
||||
this.stick_state = STICK_TOP;
|
||||
this.translate(new Vector3f(0.0f, (h - this.height)*this.scalingFactor, 0.0f));
|
||||
} else {
|
||||
this.stick_state = DEFAULT;
|
||||
}
|
||||
}
|
||||
this.height = h;
|
||||
this.width = w;
|
||||
this.vertexArray.swapVertexBufferObject(Primitive.createRectangle(this.zPos, w, h));
|
||||
int texWidth = this.texture.getWidth();
|
||||
int texHeight = this.texture.getHeight();
|
||||
x /= texWidth;
|
||||
w /= texWidth;
|
||||
y /= texHeight;
|
||||
h /= texHeight;
|
||||
float[] result = {
|
||||
x , y ,
|
||||
x + w , y ,
|
||||
x + w , y + h ,
|
||||
x , y + h ,
|
||||
};
|
||||
this.setTextureWrap(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new shader to be used by this object
|
||||
* @param vert path to glsl Vertex Shader
|
||||
* @param frag path to glsl Fragment Shader
|
||||
*/
|
||||
public void setShader(String vert, String frag){
|
||||
this.shader = new Shader(vert, frag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new Color for the object if the shader do not use the color attrib this will make no change.
|
||||
* @param color Vector3f r,g,b format
|
||||
*/
|
||||
public void setColor(Vector3f color){
|
||||
float[] colorBuffer = new float[] {
|
||||
color.x, color.y, color.z,
|
||||
color.x, color.y, color.z,
|
||||
color.x, color.y, color.z,
|
||||
color.x, color.y, color.z
|
||||
};
|
||||
this.vertexArray = new VertexArray(Primitive.createRectangle(this.zPos, this.width, this.height), Primitive.rectangle_indices, colorBuffer, Primitive.stdTexWrap);
|
||||
}
|
||||
|
||||
private void setTextureWrap(float[] texture){
|
||||
this.vertexArray.swapTextureBufferObject(texture);
|
||||
}
|
||||
|
||||
public float getZPos(){
|
||||
return zPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do shader binding, texture binding and vertexArray drawing
|
||||
*/
|
||||
public void render(){
|
||||
|
||||
this.shader.enable();
|
||||
if (this.texture != null) this.texture.bind();
|
||||
|
||||
if (this.useTime) this.shader.setUniform1f("time", (float) glfwGetTime());
|
||||
|
||||
this.shader.setUniformMat4f("projection", projection);
|
||||
this.shader.setUniformMat4f("view", view);
|
||||
this.shader.setUniformMat4f("transform", this.transform);
|
||||
|
||||
this.vertexArray.render();
|
||||
|
||||
if (this.texture != null) this.texture.unbind();
|
||||
this.shader.disable();
|
||||
}
|
||||
|
||||
}
|
11
src/engine/object/SortZ.java
Normal file
11
src/engine/object/SortZ.java
Normal file
@ -0,0 +1,11 @@
|
||||
package engine.object;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
public class SortZ implements Comparator<ObjectGl>
|
||||
{
|
||||
public int compare(ObjectGl a, ObjectGl b)
|
||||
{
|
||||
return (int) (a.getZPos() - b.getZPos());
|
||||
}
|
||||
}
|
32
src/engine/utils/BufferUtils.java
Normal file
32
src/engine/utils/BufferUtils.java
Normal file
@ -0,0 +1,32 @@
|
||||
package engine.utils;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
public class BufferUtils {
|
||||
|
||||
private BufferUtils() {
|
||||
|
||||
}
|
||||
|
||||
public static ByteBuffer createByteBuffer(byte[] array){
|
||||
ByteBuffer result = ByteBuffer.allocateDirect(array.length).order(ByteOrder.nativeOrder());
|
||||
result.put(array).flip();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static FloatBuffer createFloatBuffer(float[] array){
|
||||
FloatBuffer result = ByteBuffer.allocateDirect(array.length << 2).order(ByteOrder.nativeOrder()).asFloatBuffer();
|
||||
result.put(array).flip();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static IntBuffer createIntBuffer(int[] array){
|
||||
IntBuffer result = ByteBuffer.allocateDirect(array.length << 2).order(ByteOrder.nativeOrder()).asIntBuffer();
|
||||
result.put(array).flip();
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
29
src/engine/utils/FileUtils.java
Normal file
29
src/engine/utils/FileUtils.java
Normal file
@ -0,0 +1,29 @@
|
||||
package engine.utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
|
||||
public class FileUtils {
|
||||
|
||||
private FileUtils() {
|
||||
|
||||
}
|
||||
|
||||
public static String loadAsString(String file){
|
||||
StringBuilder result = new StringBuilder();
|
||||
try {
|
||||
BufferedReader reader = new BufferedReader(new FileReader(file));
|
||||
String buffer = "";
|
||||
while ((buffer = reader.readLine()) != null) {
|
||||
result.append(buffer +"\n");
|
||||
}
|
||||
reader.close();
|
||||
} catch (IOException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
}
|
60
src/engine/utils/ShaderUtils.java
Normal file
60
src/engine/utils/ShaderUtils.java
Normal file
@ -0,0 +1,60 @@
|
||||
package engine.utils;
|
||||
|
||||
import engine.utils.FileUtils;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
import static org.lwjgl.opengl.GL20.*;
|
||||
|
||||
public class ShaderUtils {
|
||||
|
||||
private ShaderUtils(){
|
||||
|
||||
}
|
||||
|
||||
public static int load(String vertPath, String fragPath){
|
||||
String vert = FileUtils.loadAsString(vertPath);
|
||||
String frag = FileUtils.loadAsString(fragPath);
|
||||
return create(vert, frag);
|
||||
}
|
||||
|
||||
public static int create(String vert, String frag){
|
||||
// On crée et compile le vertex et le fragment shader
|
||||
int vertID = glCreateShader(GL_VERTEX_SHADER);
|
||||
int fragID = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(vertID, vert);
|
||||
glShaderSource(fragID, frag);
|
||||
|
||||
glCompileShader(vertID);
|
||||
if (glGetShaderi(vertID, GL_COMPILE_STATUS) == GL_FALSE){
|
||||
System.err.println("Failed to compile vertex shader");
|
||||
System.err.println(glGetShaderInfoLog(vertID));
|
||||
return -1;
|
||||
}
|
||||
|
||||
glCompileShader(fragID);
|
||||
if (glGetShaderi(fragID, GL_COMPILE_STATUS) == GL_FALSE){
|
||||
System.err.println("Failed to compile fragment shader");
|
||||
System.err.println(glGetShaderInfoLog(fragID));
|
||||
return -1;
|
||||
}
|
||||
//on lie les shaders au programme
|
||||
int program = glCreateProgram();
|
||||
glAttachShader(program, vertID);
|
||||
glAttachShader(program, fragID);
|
||||
glLinkProgram(program);
|
||||
|
||||
if(glGetProgrami(program, GL_LINK_STATUS) == GL_FALSE) {
|
||||
System.err.println("Failed to link vertex and fragment shader");
|
||||
System.err.println(glGetShaderInfoLog(program));
|
||||
return -1;
|
||||
}
|
||||
|
||||
glValidateProgram(program);
|
||||
|
||||
glDeleteShader(vertID);
|
||||
glDeleteShader(fragID);
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
}
|
@ -9,12 +9,26 @@
|
||||
|
||||
package launcher;
|
||||
|
||||
public class Launcher {
|
||||
import java.io.FileInputStream;
|
||||
|
||||
public void launch() throws Exception {
|
||||
import javafx.application.Application;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.fxml.*;
|
||||
|
||||
public class Launcher extends Application {
|
||||
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
FileInputStream r_launcher = new FileInputStream("ui/launcher.fxml");
|
||||
FXMLLoader floader = new FXMLLoader();
|
||||
Parent root = floader.load(r_launcher);
|
||||
Scene main = root.getScene();
|
||||
|
||||
System.out.println("Hello world!");
|
||||
primaryStage.setTitle("Boulevard Combattant");
|
||||
|
||||
primaryStage.setScene(main);
|
||||
primaryStage.show();
|
||||
}
|
||||
|
||||
}
|
||||
|
BIN
textures/awesomeface.png
Normal file
BIN
textures/awesomeface.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
BIN
textures/container.jpg
Normal file
BIN
textures/container.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 181 KiB |
BIN
textures/perso1_sprite(to update).png
Normal file
BIN
textures/perso1_sprite(to update).png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 MiB |
BIN
textures/zangief_sprite.png
Normal file
BIN
textures/zangief_sprite.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
91
ui/launcher.fxml
Normal file
91
ui/launcher.fxml
Normal file
@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
Copyright (c) 2015, 2019, Gluon and/or its affiliates.
|
||||
All rights reserved. Use is subject to license terms.
|
||||
|
||||
This file is available and licensed under the following license:
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of Oracle Corporation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-->
|
||||
|
||||
<?import javafx.geometry.Rectangle2D?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.image.Image?>
|
||||
<?import javafx.scene.image.ImageView?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
|
||||
<HBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" style="-fx-background-color: #151619;" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<children>
|
||||
<VBox prefHeight="400.0" prefWidth="157.0">
|
||||
<children>
|
||||
<ImageView accessibleText="Logo" fitHeight="240.0" fitWidth="158.0" pickOnBounds="true" preserveRatio="true">
|
||||
<image>
|
||||
</image>
|
||||
</ImageView>
|
||||
<VBox alignment="BOTTOM_CENTER" prefHeight="263.0" prefWidth="158.0">
|
||||
<children>
|
||||
<VBox alignment="CENTER" prefHeight="200.0" prefWidth="100.0">
|
||||
<children>
|
||||
<Button mnemonicParsing="false" text="Run" />
|
||||
</children>
|
||||
</VBox>
|
||||
<Button mnemonicParsing="false" prefHeight="25.0" prefWidth="176.0" text="Settings" />
|
||||
<Button mnemonicParsing="false" prefHeight="25.0" prefWidth="161.0" style="-fx-background-color: #e80000;" text="X Quit" textFill="WHITE" />
|
||||
</children>
|
||||
</VBox>
|
||||
</children>
|
||||
</VBox>
|
||||
<VBox prefHeight="400.0" prefWidth="455.0">
|
||||
<children>
|
||||
<HBox alignment="CENTER" prefHeight="266.0" prefWidth="475.0">
|
||||
<children>
|
||||
<VBox alignment="BOTTOM_CENTER" prefHeight="249.0" prefWidth="233.0">
|
||||
<children>
|
||||
<ImageView fitHeight="172.0" fitWidth="211.0" pickOnBounds="true" preserveRatio="true">
|
||||
<image>
|
||||
</image>
|
||||
<viewport>
|
||||
<Rectangle2D />
|
||||
</viewport>
|
||||
</ImageView>
|
||||
</children>
|
||||
</VBox>
|
||||
<VBox alignment="BOTTOM_CENTER" prefHeight="249.0" prefWidth="233.0">
|
||||
<children>
|
||||
<ImageView fitHeight="200.0" fitWidth="233.0" pickOnBounds="true" preserveRatio="true">
|
||||
<image>
|
||||
</image>
|
||||
</ImageView>
|
||||
</children>
|
||||
</VBox>
|
||||
</children>
|
||||
</HBox>
|
||||
<HBox prefHeight="168.0" prefWidth="432.0" />
|
||||
</children></VBox>
|
||||
</children>
|
||||
</HBox>
|
Loading…
x
Reference in New Issue
Block a user