CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[3D Java 100% software] JavaGL

N_I_C_S
N_I_C_S
Niveau 5
11 juillet 2012 à 16:58:56

Bonjour à tous,

J'aimerais aujourd'hui présenter ce projet que je développe épisodiquement depuis plusieurs années maintenant : JavaGL . Il s'agit d'une petite bibliothèque de fonctions graphiques à mi-chemin entre lib d'affichage bas niveau et moteur 3D.
En effet, l'ensemble dispose d'une part d'un système d'affichage 3D software basé sur le modèle OpenGL dont on retrouve les principales fonctionnalités : paramètres de rendu (perspective, clipping, cull-facing), transformations spatiales (rotations, translations, échelles, pushMatrix/popMatrix), matériau basique (couleur diffuse, brillance, face pleine/fil de fer), lumière dynamique, affichage de primitives (triangles, lignes, sprites bitmap), etc...
D'autre part, par-dessus sont construites de nombreuses fonctionnalité touchant divers domaines : animation squelettale, collisions/physique, chargement de fichiers, gestion de scène, gestion de jeu temps réel (maps, décors, entités, évènements, pathfinding), etc...

Je précise, puisque on ne manque pas de faire la comparaison, que le but n'est pas de concurrencer 3DzzD ou jPCT qui sont de fantastiques moteurs mais qui émulent en gros le fonctionnement d'une carte graphique. Le propos est plutôt de revenir à une 3D "à l'ancienne", comme on pouvait en faire sur Atari ST, où l'accélération matérielle et les buffers d'affichage n'existaient pas. En conséquence il y a de gros manques dont le plus criant est l'absence de textures, mais aussi quelques avantages comme un nombre de faces affichées plus important, ou permettre les grands écrans sans (trop de) perte de performance ;) .

Et j'annonce donc avec fierté la mise en ligne de JavaGL V0.8 !

Cette version ne révolutionne pas la précédente mais en corrige plutôt les principaux défauts tout en ajoutant des nouvelles fonctionnalités que j'ai appris à implémenter depuis 2 ans de Flesh Snatcher :p .

Au menu des améliorations :

- Passage du timer aux nanosecondes (-> JavaGL est désormais compatible Java 1.5 et +)
- Correction d'un bug sur la gravité
- Correction d'un bug de détection de collisions multiples
- Correction d'un bug sur la gestion des rebonds
- Correction d'un bug sur le chargement des animations Milkshape3D
- Mécanisme de détection et correction des éventuelles erreurs de collision
- Prévention des crashes lors d'erreurs de chargement
- Fonctions de duplication de toutes les structures de données (du vecteur à la map de jeu complète)
- Mécanisme de contrôle de "propreté" des BSP
- Optimisation de l'affichage des lignes

Les nouveautés :

- Support du format OBJ
- Système de détection d'intersection de formes en tous genres
- Mécanisme de nettoyage des faces non visibles d'un ensemble de meshes
- primitives graphiques procédurales (cube, sphère, géosphère, cylindre, cône, height-map)
- Système de gestion des terrains (génération, affichage, collision)
- Intégration des sprites bitmap en billboard
- Système de gestion des évènements ingame
- Fonction de recherche du plus court chemin dans un graphe de points 3D (algorithme de Dantzig)
- Gestion des maps de jeu (décors modifiables en temps réel + entités)
- Implémentation d'une boucle de jeu simple

Voilà, je me suis donné comme objectif de factoriser dans la lib toutes les fonctions possibles permettant de faire, par exemple, un jeu comme Tesseract : -
http://tesseract-fps.sourceforge.net/tesseract800x600.html
- avec un minimum de code. De plus, la manipulation de la lib pouvant être différente par certains aspects de moteurs "classiques" (à cause, en particulier, de l'absence de Z-buffer), l'accessibilité est également une priorité avec des fonctions simples (je l'espère) et une série de démos/tutoriels intégrés en montrant les côtés les plus "déroutants" :p . Enfin, la pédagogie est aussi un aspect important du projet (pour moi en premier), pour cette raison le code est disponible sous licence GPL (c'est même le contenu principal de la lib, j'ai choisi de la distribuer sous cette forme) pour que chacun puisse juger les "bizarreries" implémentées ainsi qu'appréhender des algorithmes plus classiques.

Eh bien merci de votre attention, désolé pour le pavé, et voici les quelques liens traditionnels ;) :

Téléchargement :
http://sourceforge.net/projects/javagl/

Site internet :
http://javagl.sourceforge.net/

Accès direct aux démos :
http://javagl.sourceforgeorge.net/demo/applet_logo.html
http://javagl.sourceforgege.net/demo/applet_shapes.html
http://javagl.sourceforge.net/demo/applet_collision.html
http://javagl.sourceforge.net/demo/applet_animation.html
http://javagl.sourceforgee.net/demo/applet_sprites.html
http://javagl.sourceforgee.net/demo/applet_terrain.html

N'hésitez pas à me faire part de vos commentaires ;) .

hapliniste
hapliniste
Niveau 9
11 juillet 2012 à 17:56:40

non de dieu :ouch:

Ca doit être un énorme travail de créer ça :peur: par contre je me demande si ça a une réelle utilité vu qu'à peu près toutes les config supportent l'accélération matérielle...

En tout cas c'est vachement impressionnant, bien joué :)

godrik
godrik
Niveau 30
11 juillet 2012 à 20:02:35

Projet interessant.
Ca tire quoi comme perf?

Aldebran
Aldebran
Niveau 10
11 juillet 2012 à 20:18:10

J'avoue que recoder une bibliothèque 3D 100% software c'est un travail de fou :)

Par contre, je suis pas convaincu de l'utilité du 100% software, ça plombe juste les performances, non ? Et même ça rend impossible un paquet de trucs (textures, ombres portées, effets sur l'image, etc.) ?

Mais encore une fois bravo pour ton travail.

Bunyan
Bunyan
Niveau 17
11 juillet 2012 à 20:40:08

Rapide coup d'oeil dans les sources :
Je te conseils de supporter directement la 1.6, vu qu'Oracle accélère en prime les cycles de vie ... La 1.4 est morte, la 1.5 devrait suivre, la 1.6 meurt l'année prochaine si je me souviens bien (ou l'année suivante).

Es-tu en environnement multi-thread ?
Car je remarque que tu utilises des Vector (non-générifié), et ceux-ci sont déconseillés à l'usage car thread-safe. Dans un environnement mono-thread, il est conseillé d'utiliser plutôt une autre structure de données (ArrayList typiquement).

Le code est propre, je vois ça assez rarement pour le souligner.

Ps : ne pas le prendre mal, ça m'amuse la revue de code.

[-ArK-]
[-ArK-]
Niveau 30
11 juillet 2012 à 21:06:11

Respect :oui:

N_I_C_S
N_I_C_S
Niveau 5
11 juillet 2012 à 21:38:02

Merci à vous ^^ !

@hapliniste, Aldebran
Ha ha, pourquoi du software ? Ben j'ai pas vraiment de réponse définitive... Au départ c'était un projet d'études que j'ai étoffé peu à peu et le rendu software est resté ;) . Disons que ça permet d'avoir de la 3D en Java (donc portable et très accessible) avec un code non-signé. Et puis je me suis dit qu'avec la vague rétro actuelle ça pouvait intéresser quelqu'un (pourquoi pas pour des remakes de jeux style StarFox, etc... sans avoir à utiliser des moteurs plus lourds). Et puis je me dis que de nouveaux matériels sans accélération hardware vont toujours arriver et peut-être que les libs software seront alors utiles. Genre jouer bientôt sur sa cafetière, ça serait délire !!

@godrik
Oh, niveau perfs j'ai pas de stats précises mais disons que ça affiche sans problèmes 15000-20000 polys à ~=60 fps sur un portable VAIO de 2007 ;) .

@Bunyan
Hey, super que tu aies regardé le code, c'est fait pour :D !
Pour Java 1.5, disons que c'est pour le max de compatibilité (si je pouvais compiler en Java 1.0 je le ferais ;) ).
Exact, la lib est mono-thread, mais j'utilise les Vector car à l'époque j'avais fait des tests et c'était la structure la + rapide (assez inexplicablement) mais c'est vrai que ça a pu changer...
Pour la généricité, tu as raison, j'avais commencé la lib en 1.4 et après j'ai toujours eu la flemme de la rajouter :p , arf il faudra bien que je le fasse !
Merci pour ton retour ^^ .

@[-ArK-]
5 you !

Bunyan
Bunyan
Niveau 17
11 juillet 2012 à 21:54:29

Je peux te faire un retour complet si tu veux, en Pm ou ici.
Mon inspection me retourne ~4 000 points d'intérêts (je dois sans doute supprimer quelques critères ...).

Dreamzy
Dreamzy
Niveau 2
11 juillet 2012 à 22:20:07

Je suis perdu je ne comprend rien a tous sa mes j'aimerais que tu aille jeter un coup d'oeil a mon topic : creation de tchat 2D

N_I_C_S
N_I_C_S
Niveau 5
11 juillet 2012 à 23:25:52

@Bunyan
Yes, avec joie !
Ici c'est très bien, les sources sont publiques, leur flinguage peut l'être aussi :peur: !
Tout cet intérêt, je suis flatté :-) .

@Dreamzy
Hey, merci d'avoir pensé à moi, mais bon je dois refuser, mon truc c'est plutôt la 3D...

[-ArK-]
[-ArK-]
Niveau 30
12 juillet 2012 à 00:16:14

Owi un retour du code en public ça serait sympa, ça aiderait pas que l'auteur :oui:
J'aime connaître les bonnes pratiques aussi :oui:
D'ailleurs j'ai regardé le code (très très) vite fait et je savais pas qu'on pouvait mettre des | dans les switch case quand on compare des int :(
Je voulais le faire y'a pas longtemps avec des enum mais ça passe pas, c'est bizarre :( même si au final suffit de pas mettre de break pour avoir l'équivalent

Bunyan
Bunyan
Niveau 17
12 juillet 2012 à 08:11:09

Histoire de ... je règle mon inspection sur Java 1.6.
Vu que tu cibles Java 1.5, il y a obligatoirement les retours sur la différence entre les 2 versions.

Je ne calibre pas sur 1.5 car cette version est déjà relayée dans les "archives" d'Oracle => elle n'est pas proposée en téléchargement sauf si on va clairement la chercher.

Après recherche, en fait, le support officiel d'Oracle pour Java 1.5 s'arrêtera en mai 2014. Pour le moment, il est considéré comme "en fin de vie", donc soutenu, mais plus d'update majeur.
Java 1.6 subira le même destin et passera en fin de vie en novembre 2012 et son support se verra arrêté en décembre 2016.

Source : http://www.oracle.com/tecchnetwork/java/eol-135779.html

Sinon, si tu veux absolument supporter la 1.5 (y'a pas de mal), tu me dis, je changerai mon niveau d'inspection (ça évitera les retours inutile) :)

N_I_C_S
N_I_C_S
Niveau 5
12 juillet 2012 à 19:26:12

@[-ArK-]
Et oui, c'est logique : dans un enum le compilateur attend impérativement des valeurs constantes uniques pour chaque variable, ça interdit toute opération :-))) ...

@Bunyan
Oh, puisque tu le propose, c'est pas de refus le support Java 1.5 :content: (le chieur!).
Merci encore, je me demande ce que ça donne !

Bunyan
Bunyan
Niveau 17
13 juillet 2012 à 17:22:06

Je ne sais absolument pas si ça sera facile de corriger certains point sous Eclipse, je pense notamment au changement de visibilité.

Retour code JavaGL :

Déclaration de TOUTES les collections par des types concrets, non par des interfaces.

Ici, ça te fait comme problème de changer ET la déclaration ET l’initialisation.

Les collections n’ont pas de types génériques, ce qui implique de devoir obligatoirement passer par tout plein de instanceof pour ne pas se tromper dans l’ajout et le retrait.

Beaucoup de « magic number » => préférer des constantes nommées plutôt.

Exemple : if (string.length() < MAX_WORD_LENGTH) et if (string.length() < 12).

Le premier est plus parlant et permet de reutilizer la variable => plus facile à maintenir et faire évoluer (si la variable est bien utilisée pour un unique rôle)

Truc mineurs : a = a * norm => a *= norm. C’est pareil, plus court et souvent plus lisible (attention à ne pas en abuser).

Des assignements à l’indice d’une boucle « for ». Pas fan personnellement, je préfère éviter le plus possible, ça montre un souci d’algo, mais de temps en temps, c’est inévitable pour faire quelque chose de « court ». Peut-être passer par un itérateur, plutôt ?

Assignation d’une valeur à un paramètre de méthode. Ca, c’est personnel et dépend des équipes. Pour moi, les paramètres sont des constantes intouchables (dans le cas de type primitif), appel de méthode possibles.

Se renseigner sur la classe « MouseAdapter », et plutôt l’utiliser que « MouseListener » dans les cas qui correspondent (typiquement, pour toi : permet de définir 2 méthode au lieu de faire 6 méthodes dont 4 vides).

Ne pas hésiter à créer une classe réelle (interne ou non) au lieu d’une classe interne anonyme dans les cas de classe anonyme à forte complexité.

Il te manque pas mal d’annotation « @Override ». En soit, elle n’importe pas grand-chose (à ma connaissance), mais permettent de savoir directement que la méthode est redéfinie de quelque chose. Utile donc.

Des soucis avec « clone ».
• La première instruction doit plutôt être super.clone(), histoire de construire toute l’arborescence dans le cas de construction d’une classe fille d’un cloneable. Ce n’est pas obligatoire, juste que ne pas le mettre peut mener à des comportements étranges et difficilement compréhensibles.
• Beaucoup de méthodes « clone » dans des classes qui n’implémentent pas « cloneable », ce qui fait bizarre. L’implémentation de cloneable permet d’avoir une indication claire de la méthode, et de ne pas être au p’tit bonheur la chance.

Il reste des TODO (majoritairement générés par Eclipse).

Utilisation de Vector non générique. Franchement, remplace par des List à la déclaration, rend les génériques et tente de remplacer tes Vector par autre chose (ArrayList ou un autre conteneur plus adapté aux besoin).

Tu déclares tes tableaux comme en C :p
En Java, les crochets sont plutôt sur le type que sur la variable. Ca ne change strictement rien.

Pour la méthode « equals » avec des String, je te conseils très fortement d’invoquer la méthode sur la constante. Tu n’as ainsi pas besoin de faire de test de nullité avant. De plus, je te conseils aussi très fortement de mettre tes String constantes en static final, pas simplement en dur dans le code. Si elles sont utilisées à plusieurs endroits, ça permet d’éviter les erreurs de type, et quand il faut changer/renommer, c’est BEAUCOUP plus rapide.

Pour tester si une collection est vide, tu as la méthode isEmpty() généralement. Pas la peine de faire if (maCollec.size() == 0).

Concernant le « this », c’est une question de point de vue : pour moi, ne pas le mettre quand ce n’est pas nécessaire. Pour d’autre, le mettre tout le temps. Dans certaines classes, tu l’utilises de manière inutile, mais ça ne change strictement rien, si ce n’est l’esthétique.

Tu as beaucoup de parenthèses inutile pour le code, mais qui semble aider à la lecture (je n’ai pas tout regardé, mon inspection me retourne 643 de ces cas-là).

Question de goût aussi, mais quand il y a appel à des classes internes, tu as deux écoles : qualifier la classe interne par la classe l’englobant, ce qui permet de savoir où elle est, ce qui est fait, si sa place ici est logique, mais alourdit le code. Il y a l’autre, de simplement l’utiliser comme une classe. Je préfère le premier, mais c’est une question de goût.

Je te conseils aussi de t’intéresser au for each, qui est très pratique :)

Tu as la branche « else » de ta méthode « process » dans la classe JGL_Motion_Slide qui ne sert à rien (ligne 113). Déroule le code, tu devrais comprendre.

Tu as pas mal d’assignation après test de nullité. C’est une question de goût, mais tu pourrais mettre un opérateur ternaire ici. Attention, ceux-ci rendent facilement le code illisible.

Classe « JGL_Motion_Bounce », ligne 71-72. Tu fais un loops = 0 puis un while (loops == 0) => tu peux remplacer par un « while(true) ». Vu que je ne sais pas ce que tu veux faire ici, concrétement, ce n’est pas forcément une bonne idée de faire une boucle pseudo-infinie. Vérifie bien que tu en sortiras obligatoirement avec le code de sortie que tu as prévue (si ce n’est pas déjà fait).

Selon les conventions Java, les variables statiques sont plutôt mises avec CE_TYPE_DE_NOMENCLATURE. De plus, tu as pas mal de variable statique que tu considères comme des constantes qui ne sont pas déclarées en tant que telle (il manque le mot-clef « final »).

Les trucs comme « if (resultat == true), ça ne sert à rien :)
Autant remplacer par « if (resultat) », non ?

Pour ton switch de JGL_3DMatrix, je te conseils de mettre les valeurs en constantes, plutôt que de simple valeurs avec un commentaire non-javadoc à côté.

Tu as des switch sans branche « default » (classes JGL_ImageLoader et JGL_ImageScaler), vérifie bien que tu es obligatoirement dans une des branches, et que c’est strictement impossible sinon.
Sinon, rajoute plutôt un case « default ».

Tu as des « return ; » à la fin de méthode sensée retourner void. Ca ne sert à rien (classes JGL_Data3D et JGL_ReaderObj).

Ta gestion des Exceptions est calamiteuse. Ne fais JAMAIS de « catch (Exception) » ni de « throw new Exception() ». Utilise TOUJOURS des exceptions qui ont un véritables sens. Tu as fait, par exemple :

Catch (FileNotFoundException e)
{
e.printStackTrace() ;
throw new Exception(« Fichier introuvable ») ;
}

Pourquoi ? Pourquoi ne simplement pas avoir fait remonter l’exception en le déclarant dans le prototype de la méthode ?
De plus, Exception est EXTRÊMEMENT vaste. En faisant un catch (Exception), tu prends les IO, FileNotFound, NullPointer … tu prends beaucoup trop.

À un autre endroit, tu catch une exception pour la lancer immédiatement après. À quoi sert de la prendre ?

Mon inspection me dit que ta méthode « addBone » retourne absolument toujours « true ». Je ne sais pas si c’est vraiment le cas.

La méthode « getMaterials » dans JGL_ReaderObj ne lance jamais d’exception Exception.

Tu fais des accès directs à des attributs déclarés en tant que « private », pas une bonne pratique du tout. Passe plutôt par des accesseurs.

Tu as des visibilités « package » (i.e. : absence de modificateur de visibilité). Personnellement, je fais en sorte de ne pas en avoir, mais c’est aussi un peu à la discrétion.

Pour un bon principe d’encapsulation, mets tout tes attributs en « private » et utilise des accesseurs (getter/setter). Cela permet de bien délimiter les responsabilités de chacun, et de pouvoir facilement limiter les effets de bord (si c’est en lecture seule, le getter retourne une version non-modifiable de l’objet, par exemple).

J’ai tout plein de « uncheckedWarning » lié a l’absence de test avant de retirer d’une liste et de transtyper.

Tu as un constructeur publique dans la classe JGL_Loop, sauf que celle-ci est abstraite, donc au mieux doit en avoir un en protected.

Tu fais un tout petit peu d’auto—(un)boxing inutile.

Tu fais des copies de tableau « à la main ». Utilise plutôt System.arrayCopy :)
Pareil pour tableau vers collection. Utilise Collections.addAll :)

godrik
godrik
Niveau 30
13 juillet 2012 à 17:40:55

"Truc mineurs : a = a * norm => a *= norm. C’est pareil, plus court et souvent plus lisible (attention à ne pas en abuser)."

Note qu'en C++ (je sais que tu fais du java), *= est souvent plus rapide que = et * pour les types complexes.

"Pour tester si une collection est vide, tu as la méthode isEmpty() généralement. Pas la peine de faire if (maCollec.size() == 0)."

Note que isEmpty() est souvent plus rapide que size(). Par exemple, les listes ne connaissent generalement pas leur taille, elle est calculer quand size() est appelle.

[-ArK-]
[-ArK-]
Niveau 30
13 juillet 2012 à 17:51:07

Wow ça c'est du post, intéressant merci

Par contre je suis pas d'accord sur ça : "Tu as des « return ; » à la fin de méthode sensée retourner void. Ca ne sert à rien (classes JGL_Data3D et JGL_ReaderObj). "

Si on veut juste quitter la méthode on fait comment dans ce cas ? :( des if géant ? :(

godrik
godrik
Niveau 30
13 juillet 2012 à 18:00:19

"Tu as des « return ; » ***à la fin*** de méthode sensée retourner void."

emphasis is mine.

[-ArK-]
[-ArK-]
Niveau 30
13 juillet 2012 à 18:06:06

ah oops désolé :noel:

Bunyan
Bunyan
Niveau 17
13 juillet 2012 à 20:36:25

Mouais, comme je me doutais, la mise en page et la lisibilité allait pas être super sur le forum :/
Mes excuses pour ça, je peux faire un PDF au besoin.
Je me rends aussi compte que j'ai oublié une précision : le monde du développement de jeu vidéo (dans sa globalité) m'est inconnu. Il est possible que certains points soient en fait tout à fait normaux dans ce contexte.

Pour ce "return ;" il se trouve et en fin de méthode, et est la dernière ligne d'un catch.

Le point que tu soulèves Ark, en amène un autre : le nombre de point de sortie.
Je préfère les "if géant" (bien que je fasse en sorte de découper mes méthodes/fonctions pour les éviter) et n'avoir qu'un unique point de sortie normal.
Je trouve que faire une cascade de "return" pour une suite de test est beaucoup moins lisible qu'un booléen mis à jour et une suite de test sur celui-ci.

Par contre, cela peut justement dégrader la lisibilité dans le cas de "if géant" :)

Faire la part des choses, comme toujours.

N_I_C_S
N_I_C_S
Niveau 5
15 juillet 2012 à 22:42:44

Hey, je viens de trouver vos posts !
Merci à vous de l'intérêt que vous avez porté aux sources, c'est super cool ;) !

Et merci beaucoup à toi Bunyan, effectivement ça c'est du message ;) . J'ai juste survolé ton retour, car il me faut quand même prendre 2 minutes pour y répondre plus sérieusement, mais ça dépote ! Apparemment il en ressort par exemple une POO qui laisse parfois à désirer et c'est effectivement un aspect que j'ai encore à travailler...

Hé hé, "I'll be back !" :fier:

Sous forums
  • Aide à l'achat Mac
  • Macintosh
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Internet
  • Steam Deck
  • Hardware
La vidéo du moment