Vous n'êtes pas identifié.
Voili voilou, j'ai un peu bossé le rendu 3D sur G100 :
et j'ai décidé de créer un jeu en "pseudo" 3D sur G100, un jeu de formule 1 ( c'est ce qui me parait le plus facile... ).
Pour le calcul des coordonnées des points, je me suis basé sur cette image :
qui devrait donner un aperçu du jeu même si seule la route sera tracée.
On est dans un repère ayant pour origine le milieu de l'écran en bas, chaque coordonnée X diminuant de deux fois par cran ( eh oui, ça simplifie... ).
La partie supérieure de l'écran sera constituée d'une image qui se déplacera à gauche et à droite suivant comment tourne la voiture.
voici un aperçu des sprites constituant les voitures :
j'ai déjà crée les fonctions permettant de convertir les coordonnées d'un point du repère énoncé plus haut sur l'écran.
Je donnerais donc régulièrement des nouvelles du dévellopement du programme
Dernière modification par phcorp (18 Aug 2007 14:36:46)
Hors ligne
voilà donc une question :
pour les fonctions mathématiques, j'utilise l'aide disponible ici : http://www.ltam.lu/Tutoriel_Ansi_C/prg-c162.htm
je me pose une question, par exemple je vois marqué :
double exp(double X)
est-ce obligé que la variable X soit un double ?
Hors ligne
La variable que tu utilises non mais elle sera convertie en double implicitement. Suivant ton compilateur il est possible qu'il y ait une fonction expf disponible qui travaille avec un float (DM devrait supporter je pense).
Dernière modification par tonton1664 (18 Aug 2007 17:33:20)
Hors ligne
Oui il fonctionne. Mais si tu as la fonction expf c'est mieux de l'utiliser, l'exécutable prendra moins de place. Et si tu peux de passer des calculs avec des float c'est encore mieux : toutes les fonctions travaillant avec des float et des double sur g100 utilisent une bibliothèque d'émulation qui prends pas mal de place et qui est relativement lente.
Dans ton cas il serait peut être préférable d'utiliser une table d'approximation, car je penses que ce calcul est utilisé dans le cœur de l'algorithme de calcul des coordonnées, et tu as besoin de vitesse, pas de précision.
Hors ligne
petit problême de compilation ( déjà ?! ) :
#include <stdlib.h> #include <math.h> #include <stdio.h> #include <dos.h> #include <mkeys.h> #include "gxlib10.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // DEFINITION DES STRUCTURES ET VARIABLES GLOBALES //////////////////////////////////////////////////////////////////////////////////////////////////// char carte[][32][16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, }; //////////////////////////////////////////////////////////////////////////////////////////////////// // DECLARATION DES FONCTIONS //////////////////////////////////////////////////////////////////////////////////////////////////// int convert_coord_x ( float, float ); int convert_coord_y ( float ); void draw_way ( float, float ); //////////////////////////////////////////////////////////////////////////////////////////////////// // DEFINITION DES FONCTIONS //////////////////////////////////////////////////////////////////////////////////////////////////// // Fonction de calcul de la coordonnée x d'un point en 3D sur l'écran int convert_coord_x ( float x, float y ) { // Déclaration des variables float demisy; int finalx; float demisx; // Calcul de la coordonnée x demisy = 32*exp(-0.693147*y); demisx = x*demisy+64; finalx = demisx; // Renvoi de la coordonnée x return ( finalx ); } // Fonction de calcul de la coordonnée y d'un point en 3D sur l'écran int convert_coord_y ( float y ) { // Déclaration des variables int finaly; float demisy; // Calcul de la coordonnée y demisy = 64*exp(-0.693147*y); finaly = demisy; // Renvoi de la coordonnée y return ( finaly ); } void draw_way ( float lastx, float lasty ) { int x = lastx; int y = lasty; // différence entre les coordonnées converties en entier et les coordonnées en float ( chiffres après la virgule ) double diffx = lastx - x; double diffy = lasty - y; int bcl = 2; int bcly; int bclx; int bcld; if ( ( x < 0 ) || ( y < 0 ) || ( x >= 32 ) || ( y >= 16 ) ) { // game_over (); } if ( carte[x][y] == 0 ) { // game_over (); } for ( bcly = 1; bcly <= 4; bcly++ ) { for ( bclx = -bcl; bclx <= bcl; bclx++ ) { if ( ( bclx >= 0 ) || ( bcly >= 0 ) || ( bclx < 32 ) || ( bcly < 16 ) ) { if ( carte[bclx][bcly] == 0 ) { for ( bcld = 0; bcld <= 32/bcl; bcld++ ) { // on colorie en noir toute la partie du terrain qui ne contiend pas la route gxHline( convert_coord_x ( bclx + diffx, bcly + 1/bcld + diffy ), convert_coord_x ( bclx + diffx, bcly + 1/bcld + diffy ), convert_coord_y ( bcly + 1/bcld + diffy ), 4 ); } } } } bcl = 2*bcl; } return; } int main() { gxSetMode ( true ); while ( 0 ) { gxClearBuff (); // 5, 4 sont les coordonnées de la voiture sur la carte draw_way ( 5, 4 ); gxRefresh (); } gxSetMode ( false ); return ( 0 ); }
erreurs :
ce code n'est qu'une ébauche et je ne comprend absolument pas quelle a pu etre mon erreur...
Dernière modification par phcorp (20 Aug 2007 07:58:29)
Hors ligne
Il y déjà gxHline qui est indéfini : c'est gxHLine (avec une majuscule sur le L).
Ensuite, essaye d'ajouter la librairie mathématique dans les propriétes du projet, je pense que le reste des erreurs vient de là.
Hors ligne
essaye d'ajouter la librairie mathématique dans les propriétes du projet
merci beaucoup pour ton aide mais comment je fais ça ?
merci pour gxHLine, le message d'erreur a disparu !!!
Dernière modification par phcorp (20 Aug 2007 14:00:07)
Hors ligne
C'est une case à cocher dans Project -> Properties où un truc du genre, à coté des options du compilateur et du choix du processeur cible si je me souviens bien. Ça s'appelle peut être floating point emulation. Je ne peux pas te donner plus de détails, vu que je n'ai pas de pc zindozs sous la main et que je n'ai pas le courage de chercher à émuler tc.
Hors ligne
Ç’est mieux optimise comme ça (il faut perdre un minimum de cycles) :
int convert_coord_x ( float x, float y )
{return ( (int)(x*32*exp(-0.693147*y)+64) );
}
int convert_coord_y ( float y )
{return ( (int)(64*exp(-0.693147*y)) );
}
ça serait quand méme bien de faire une fonx du type :
int exp (int ) ;
Le résultat serait trouvé grâce à une table de valeurs entières ce qui évitera d’utiliser le float point. Si tu veux garder une certaine précisions il suffit de multiplier toutes les valeurs par 100. Ainsi pour calculer exp(2.56) il faudrait faire exp(256) et traiter le résultat sachant que lui aussi est multiplié par 100.
j'ai décidé de créer un jeu en "pseudo" 3D sur G100, un jeu de formule 1 ( c'est ce qui me parait le plus facile... ).
Un jeux a la 1er personne comme Duke Nukem 3D ou Wolfenstein 3D est peut étre plus simple a faire sur G100 en utilisant la méthode dite du « Raycasting »
http://www.permadi.com/tutorial/raycast/
Vu que t’a l’aire intéressé par la 3D, tu pourrait peut être envisager un projet… ??
Hors ligne
Attention ! Sur la graph100 il n'y a pas de coprocesseur arithmétique, donc toutes les opérations de calcul en virgule flottante doivent être simulées par la bibliothèque mathématique de ton compilateur. C'est très lent. Et les fonctions de type cos/sin/exp sont TRES lentes aussi.
Si le besoin de précision n'est pas énorme, il vaudra toujours mieux utiliser des opérations en virgule fixe. Prendre un entier de N bits (suivant la précision voulue) et allouer M bits à la partie entière (le coefficient multiplicateur sera alors une puissance de 2, ce qui permet de retrouver très simplement une partie ou l'autre grâce à un décalage ou un masque de bits.)
Pour ce qui est du raycaster j'avais fait un essai il y a 3 ou 4 ans (déjà !), j'essaierai de retrouver le source. Mon raycaster simple en mode 3 couleurs (sol et plafond blanc et murs en gris/noir) scannait une grille en lançant 128 rayons et dessinait colonne par colonne, ça tournait à environ 11 ou 12 frames/secondes avec que du C (donné à titre indicatif vu que c'était pas forcément très bien programmé)
Le jeu starscape de casiomax utilisant le raycasting plaque des "textures" mais n'atteint un framerate plus élevé qu'en ne lançant un rayon sur 4 (32 au lieu de 128) et dessinant des "rectangles" des 4 pixels de large.
Pour un jeu de formule 1 tel qu'on pouvait en trouver sur game boy ou d'autres plates-formes de la même époque, nul n'est besoin d'utiliser une méthode aussi lourde en calcul (rappelez-vous que le processeur de la graph100 est beaucoup plus rapide que celui d'une gb ET est 16 bits. Seul l'impossibilité d'afficher des sprites en hardware est handicapant).
Il faut juste à mon avis utiliser des positions précalculées suivant les différentes portions de routes.
Hors ligne
Pour dessiner un élément de mure un rectangle de 2 pixels réduirait l’effet escalier.
Par contre les textures ne pourront être que « horizontale ».
Afin de réduire le nombre de rayons à envoyer il ne vaut mieux pas utiliser toute la largeur de l’écran. 100 pixels de large me parait convenable, ce qui fait 50 rayons a envoyer.
Pour envoyer les rayons il faudrait les envoyer deux par deux (ceux qui sont symétrique par apport à l’axe du regard). Dans ce cas les 50 rayons auront été envoyés en 25 tours de boucle.
Pour la direction des rayons il faudrait prendre model sur le tracé de ligne sous Paint :
-Incrémenter de N pixel en X
-Incrémenter de 1 pixel en Y
(Avec N qui correspond a un angle d’incidence du rayon)
Ce qui donne des lignes horizontales ou verticales les unes à coté autres mais en décalé comme ça pas besoin de virgule. Cette fonx pourras facilement être codé en asm (boucle, teste, incrémentation => rien de bien compliqué)
Bah, ça serait un bon projet. Ça serait bien qu’il le fasse Phcorp.
Hors ligne
Au passage si tu as besoin de vitesse et que les décors risquent d'être constamment en mouvement, le mode 5 couleurs n'est pas conseillé: ça ralentirait le jeu et on ne distinguerait de toute façon pas bien les nuances de couleurs. Je te conseille de passer en 3 couleurs pour ce genre de projets
Hors ligne
salut
mastermage a écrit:
Si le besoin de précision n'est pas énorme, il vaudra toujours mieux utiliser des opérations en virgule fixe. Prendre un entier de N bits (suivant la précision voulue) et allouer M bits à la partie entière (le coefficient multiplicateur sera alors une puissance de 2, ce qui permet de retrouver très simplement une partie ou l'autre grâce à un décalage ou un masque de bits.)
ce dont j'ai besoin c'est d'une fonction exponentielle et d'une fonction puissance qui fonctionnent avec des float ( ou double ), je suis obligé d'utiliser des chiffres à virgule. et j'avoue ne pas comprendre ce que tu m'expliques... les fonctions de calcul des coordonnées des points que j'ai crée sont primordiales quand à l'exécution de mon programme, il faut que je résolve ce problème en priorité
Vic a écrit:
Un jeux a la 1er personne comme Duke Nukem 3D ou Wolfenstein 3D est peut étre plus simple a faire sur G100 en utilisant la méthode dite du « Raycasting »
je connaissais déjà cette méthode mais je n'avais jamais songé à l'appliquer. cela peut être intéressant notamment sur le plan de la rotation... je vais essayer de l'utiliser, cependant je vais avoir un problème quand à l'application des textures
Vic a écrit:
Pour dessiner un élément de mure un rectangle de 2 pixels réduirait l’effet escalier.
Par contre les textures ne pourront être que « horizontale ».
je ne comprends pas ce que tu veux dire
Vic a écrit:
Ce qui donne des lignes horizontales ou verticales les unes à coté autres mais en décalé comme ça pas besoin de virgule. Cette fonx pourras facilement être codé en asm (boucle, teste, incrémentation => rien de bien compliqué)
désolé mais je ne fais pas d'asm
Julien a écrit:
Au passage si tu as besoin de vitesse et que les décors risquent d'être constamment en mouvement, le mode 5 couleurs n'est pas conseillé: ça ralentirait le jeu et on ne distinguerait de toute façon pas bien les nuances de couleurs. Je te conseille de passer en 3 couleurs pour ce genre de projets
Ce qui signifie Drawlib ?
merci à tous pour vos conseils
phcorp
Dernière modification par phcorp (24 Aug 2007 16:45:00)
Hors ligne
voilà petite question qui a rapport , entres autres, avec ce programme...
comment fait-on pour enregistrer un écran ( buffer ? ) et le recharger avec gxlib/drawlib ?
merci
phcorp
Hors ligne