Moteur 3d hardcoder (fenetre sdl)

Soyez le premier à donner votre avis sur cette source.

Vue 8 759 fois - Téléchargée 870 fois

Description

se moteur, qui n'utilise aucunne fonction 3D toute faite, a pour but (ludique) la comprention du fonctionnement de la 3D : rotation d'objet (trigo), effet de persepective (pythagore), l'eclairage (vecteurs et normal), les loadeur de map (fichier ascii .ase vers memoire) ...

le source est portable =)

il n'est pas tres documenter car se serai trop long et sa restera comme sa

Source / Exemple :


/*****************************************************************************/
/*																			 */
/* fichier	: moteur.c									version : V2.1		 */
/* projet	: moteur									date :	24/05/2005	 */
/* par		: aerith														 */
/*																			 */
/* mini moteur 3D															 */
/*																			 */
/*****************************************************************************/

#include	"moteur.h"

SDL_Surface *pScreen;

char 	*gettok(const char *pData, int iPos, char *pCar)
{
	static char	Data[NBCARLINE];
	char *	Token;
	int		i;
	strcpy(Data, pData);
	for(Token = strtok(Data, pCar), i = 0; Token && (i < iPos); ++i, Token = strtok(0, pCar));

	return Token;
}

void	Load(char *pFichier, mesh *pMesh)
{
	FILE 	*Fichier;
	char	Data[NBCARLINE];

	Fichier = fopen(pFichier, "r");
	if(!Fichier)
	{
		perror("erreur map non trouver\n");
		exit(1);
	}

	while(!feof(Fichier))
	{
		if(fgets(Data, NBCARLINE, Fichier))
		{
			if(strcmp(gettok(Data, 0, ":* \t\n\""), "MESH_NUMVERTEX") == 0)
			{
				pMesh->NumVertex 	= atoi(gettok(Data, 1, ":* \t\n\""));
				pMesh->Vertex		= malloc(sizeof(vertex) * (pMesh->NumVertex + 1));
			}
			if(strcmp(gettok(Data, 0, ":* \t\n\""), "MESH_NUMFACES") == 0)
			{
				pMesh->NumFace 	= atoi(gettok(Data, 1, ":* \t\n\""));
				pMesh->Faces	= malloc(sizeof(face) * (pMesh->NumFace + 1));
			}
			if (strcmp(gettok(Data, 0, ":* \t\n"), "MESH_VERTEX") == 0)
			{
				pMesh->Vertex[atoi(gettok(Data, 1, ":* \t\n"))].v3D.x = (float)atof(gettok(Data, 2, ":* \t\n"));
				pMesh->Vertex[atoi(gettok(Data, 1, ":* \t\n"))].v3D.y = (float)atof(gettok(Data, 3, ":* \t\n"));
				pMesh->Vertex[atoi(gettok(Data, 1, ":* \t\n"))].v3D.z = (float)atof(gettok(Data, 4, ":* \t\n"));
			}
			if (strcmp(gettok(Data, 0, ":* \t\n"), "MESH_FACE") == 0)
			{
				pMesh->Faces[atoi(gettok(Data, 1, ":* \t\n"))].a = atoi(gettok(Data, 3, ":* \t\n"));
				pMesh->Faces[atoi(gettok(Data, 1, ":* \t\n"))].b = atoi(gettok(Data, 5, ":* \t\n"));
				pMesh->Faces[atoi(gettok(Data, 1, ":* \t\n"))].c = atoi(gettok(Data, 7, ":* \t\n"));
			}
			if (strcmp(gettok(Data, 0, ":* \t\n"), "MESH_FACENORMAL") == 0)
			{
				pMesh->Faces[atoi(gettok(Data, 1, ":* \t\n"))].normal.x = (float)atof(gettok(Data, 2, ":* \t\n"));
				pMesh->Faces[atoi(gettok(Data, 1, ":* \t\n"))].normal.y = (float)atof(gettok(Data, 3, ":* \t\n"));
				pMesh->Faces[atoi(gettok(Data, 1, ":* \t\n"))].normal.z = (float)atof(gettok(Data, 4, ":* \t\n"));
			}
		}
	}
	fclose(Fichier);
}

void	Init(char *pFichier, option *pOption)
{
	FILE 	*Fichier;
	char	Data[NBCARLINE];

	pOption->Zoom		= 10;
	pOption->Cliping	= 50;
	pOption->Camera.x	= 0;
	pOption->Camera.y	= 0;
	pOption->Camera.z	= 100;
	pOption->Rotate.a	= 0;
	pOption->Rotate.x	= 0;
	pOption->Rotate.y	= 0;
	pOption->Rotate.z	= 0;
	pOption->Light		= 1;
	pOption->Lcolor.i	= 100;
	pOption->Lcolor.r	= 255;
	pOption->Lcolor.g	= 255;
	pOption->Lcolor.b	= 255;
	pOption->Render		= 1;
	pOption->Allface	= 0;
	pOption->WindowX	= 320;
	pOption->WindowY	= 240;
	pOption->Color		= 16;
	strcpy(pOption->Title, "m3d");
	pOption->Triface	= 1;

	Fichier = fopen(pFichier, "r");
	if(!Fichier)
	{
		perror("erreur fichier init inexistant\n");
		exit(2);
	}

	while(!feof(Fichier))
	{
		if(fgets(Data, NBCARLINE, Fichier) != NULL)
		{
			if(!(Data[0] == '\\' && Data[1] == '\\') && Data[0] != '\n')
			{
				if(strcmp(gettok(Data, 0, "=: \t\n\""), "zoom") == 0)
					pOption->Zoom		= (float)atof(gettok(Data, 1, "=: \t\n\""));
				if(strcmp(gettok(Data, 0, "=: \t\n\""), "cliping") == 0)
					pOption->Cliping	= (float)atof(gettok(Data, 1, "=: \t\n\""));
				if(strcmp(gettok(Data, 0, "=: \t\n\""), "camera") == 0)
				{
					pOption->Camera.x	= (float)atof(gettok(Data, 1, "=: \t\n\""));
					pOption->Camera.y	= (float)atof(gettok(Data, 2, "=: \t\n\""));
					pOption->Camera.z	= (float)atof(gettok(Data, 3, "=: \t\n\""));
				}
				if(strcmp(gettok(Data, 0, "=: \t\n\""), "rotate") == 0)
				{
					pOption->Rotate.a	= (float)atof(gettok(Data, 1, "=: \t\n\""));
					pOption->Rotate.x	= (float)atof(gettok(Data, 2, "=: \t\n\""));
					pOption->Rotate.y	= (float)atof(gettok(Data, 3, "=: \t\n\""));
					pOption->Rotate.z	= (float)atof(gettok(Data, 4, "=: \t\n\""));
				}
				if(strcmp(gettok(Data, 0, "=: \t\n\""), "light") == 0)
					pOption->Light	= atoi(gettok(Data, 1, "=: \t\n\""));
				if(strcmp(gettok(Data, 0, "=: \t\n\""), "lcolor") == 0)
				{
					pOption->Lcolor.i	= atoi(gettok(Data, 1, "=: \t\n\""));
					pOption->Lcolor.r	= atoi(gettok(Data, 2, "=: \t\n\""));
					pOption->Lcolor.g	= atoi(gettok(Data, 3, "=: \t\n\""));
					pOption->Lcolor.b	= atoi(gettok(Data, 4, "=: \t\n\""));
				}
				if(strcmp(gettok(Data, 0, "=: \t\n\""), "render") == 0)
					pOption->Render	= atoi(gettok(Data, 1, "=: \t\n\""));
				if(strcmp(gettok(Data, 0, "=: \t\n\""), "allface") == 0)
					pOption->Allface	= atoi(gettok(Data, 1, "=: \t\n\""));
				if(strcmp(gettok(Data, 0, "=: \t\n\""), "window") == 0)
				{
					pOption->WindowX	= atoi(gettok(Data, 1, "=: \t\n\""));
					pOption->WindowY	= atoi(gettok(Data, 2, "=: \t\n\""));
					pOption->Color		= atoi(gettok(Data, 3, "=: \t\n\""));
				}
				if(strcmp(gettok(Data, 0, "=: \t\n\""), "title") == 0)
					strcpy(pOption->Title, gettok(Data, 1, "=: \t\n\""));
				if(strcmp(gettok(Data, 0, "=: \t\n\""), "triface") == 0)
					pOption->Triface	= atoi(gettok(Data, 1, "=: \t\n\""));
			}
		}
	}
	fclose(Fichier);
	
	if(SDL_Init(SDL_INIT_VIDEO) < 0)
	{
		perror("erreur init SDL\n");
		exit(3);
	}

	atexit(SDL_Quit);

	pScreen = SDL_SetVideoMode(pOption->WindowX, pOption->WindowY,
		pOption->Color, SDL_SWSURFACE | SDL_DOUBLEBUF);
	if(!pScreen)
	{
		perror("erreur creation screen\n");
		exit(4);
	}
	SDL_WM_SetCaption(pOption->Title, NULL);

	SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);	
}

void	Point(vecteur p1, int r, int g, int b)
{
	Uint16 *Pointer;

	if((p1.x > 0) && (p1.x < (float)pScreen->w) && (p1.y > 0) && (p1.y < (float)pScreen->h))
	{
		Pointer = (Uint16*)pScreen->pixels + ((pScreen->pitch / 2 * (int)p1.y) + (int)p1.x);

  • Pointer = SDL_MapRGB(pScreen->format, (Uint8)r, (Uint8)g, (Uint8)b);
} } void Line(vecteur p1, vecteur p2, int r, int g, int b) { vecteur p; float d; if(abs((int)(p1.x - p2.x)) > abs((int)(p1.y - p2.y))) { if(p1.x > p2.x) { p = p1; p1 = p2; p2 = p; } d = (p1.y - p2.y) / (p1.x - p2.x); for(; p1.x <= p2.x; p1.x++, p1.y += d) Point(p1, r, g, b); } else { if(p1.y > p2.y) { p = p1; p1 = p2; p2 = p; } d = (p1.x - p2.x) / (p1.y - p2.y); for(; p1.y <= p2.y; p1.x += d, p1.y++) Point(p1, r, g, b); } } void Triangle(vecteur p1, vecteur p2, vecteur p3, int r, int g, int b) { vecteur p; float d; if(abs((int)(p2.x - p3.x)) > abs((int)(p2.y - p3.y))) { if(p2.x > p3.x) { p = p2; p2 = p3; p3 = p; } d = (p2.y - p3.y) / (p2.x - p3.x); for(; p2.x <= p3.x; p2.x++, p2.y += d) Line(p1, p2, r, g, b); } else { if(p2.y > p3.y) { p = p2; p2 = p3; p3 = p; } d = (p2.x - p3.x) / (p2.y - p3.y); for(;p2.y <= p3.y; p2.x += d, p2.y++) Line(p1, p2, r, g, b); } } void Render(mesh *pMesh, option *pOption) { float cosT = (float)cos(pOption->Rotate.a); float sinT = (float)sin(pOption->Rotate.a); float cosT1 = 1 - cosT; float cosT2 = 1 + cosT; float xs = pOption->Rotate.x * sinT; float ys = pOption->Rotate.y * sinT; float zs = pOption->Rotate.z * sinT; float ex1 = cosT + cosT1 * (pOption->Rotate.x * pOption->Rotate.x); float ex2 = cosT1 * pOption->Rotate.x * pOption->Rotate.y - zs; float ex3 = cosT1 * pOption->Rotate.x * pOption->Rotate.z + ys; float ey1 = cosT2 * pOption->Rotate.x * pOption->Rotate.y + zs; float ey2 = cosT + cosT1 * (pOption->Rotate.y * pOption->Rotate.y); float ey3 = cosT1 * pOption->Rotate.y * pOption->Rotate.z - xs; float ez1 = cosT2 * pOption->Rotate.x * pOption->Rotate.z - ys; float ez2 = cosT1 * pOption->Rotate.y * pOption->Rotate.z + xs; float ez3 = cosT + cosT1 * (pOption->Rotate.z * pOption->Rotate.z); int i, j, n; float m, o; vecteur vt; face ft; clock_t start; static int Fpsc = 0; static int Fpsa = 0; int Fps = 0; Uint32 Color; light couleur; char Titre[256]; start = clock(); couleur.r = 255; couleur.g = 255; couleur.b = 255; for(i = 0; i < pMesh->NumVertex; i++) { pMesh->Vertex[i].v3D.x = ex1 * pMesh->Vertex[i].v3D.x + ex2 * pMesh->Vertex[i].v3D.y + ex3 * pMesh->Vertex[i].v3D.z; pMesh->Vertex[i].v3D.y = ey1 * pMesh->Vertex[i].v3D.x + ey2 * pMesh->Vertex[i].v3D.y + ey3 * pMesh->Vertex[i].v3D.z; pMesh->Vertex[i].v3D.z = ez1 * pMesh->Vertex[i].v3D.x + ez2 * pMesh->Vertex[i].v3D.y + ez3 * pMesh->Vertex[i].v3D.z; pMesh->Vertex[i].v2D.x = (pMesh->Vertex[i].v3D.x + pOption->Camera.x) * pOption->Zoom / ((pMesh->Vertex[i].v3D.z + pOption->Camera.z) / pOption->Cliping) + (pOption->WindowX / 2); pMesh->Vertex[i].v2D.y = (pMesh->Vertex[i].v3D.y + pOption->Camera.y) * pOption->Zoom / ((pMesh->Vertex[i].v3D.z + pOption->Camera.z) / pOption->Cliping) + (pOption->WindowY / 2); } for(i = 0; i < pMesh->NumFace; i++) { pMesh->Faces[i].normal.x = ex1 * pMesh->Faces[i].normal.x + ex2 * pMesh->Faces[i].normal.y + ex3 * pMesh->Faces[i].normal.z; pMesh->Faces[i].normal.y = ey1 * pMesh->Faces[i].normal.x + ey2 * pMesh->Faces[i].normal.y + ey3 * pMesh->Faces[i].normal.z; pMesh->Faces[i].normal.z = ez1 * pMesh->Faces[i].normal.x + ez2 * pMesh->Faces[i].normal.y + ez3 * pMesh->Faces[i].normal.z; pMesh->Faces[i].centre.x = (pMesh->Vertex[pMesh->Faces[i].a].v3D.x + pMesh->Vertex[pMesh->Faces[i].b].v3D.x + pMesh->Vertex[pMesh->Faces[i].c].v3D.x) / 3; pMesh->Faces[i].centre.y = (pMesh->Vertex[pMesh->Faces[i].a].v3D.y + pMesh->Vertex[pMesh->Faces[i].b].v3D.y + pMesh->Vertex[pMesh->Faces[i].c].v3D.y) / 3; pMesh->Faces[i].centre.z = (pMesh->Vertex[pMesh->Faces[i].a].v3D.z + pMesh->Vertex[pMesh->Faces[i].b].v3D.z + pMesh->Vertex[pMesh->Faces[i].c].v3D.z) / 3; vt.x = abs((int)(pOption->Camera.x - pMesh->Faces[i].centre.x)); vt.y = abs((int)(pOption->Camera.y - pMesh->Faces[i].centre.y)); vt.z = abs((int)(pOption->Camera.z - pMesh->Faces[i].centre.z)); pMesh->Faces[i].dist = (int)sqrt((vt.x * vt.x) + (vt.y * vt.y) + (vt.z * vt.z)); } if(pOption->Triface) { for(i = 0; i < (pMesh->NumFace - 1); i++) { for(j = i + 1; j < pMesh->NumFace; j++) { if(pMesh->Faces[i].dist > pMesh->Faces[j].dist) { memcpy((void *)&ft, (void *)&pMesh->Faces[i], sizeof(face)); memcpy((void *)&pMesh->Faces[i], (void *)&pMesh->Faces[j], sizeof(face)); memcpy((void *)&pMesh->Faces[j], (void *)&ft, sizeof(face)); } } } } Color = SDL_MapRGB(pScreen->format, 0, 0, 0); SDL_FillRect(pScreen, NULL, Color); if(SDL_MUSTLOCK(pScreen)) if(SDL_LockSurface(pScreen) < 0) return; vt.x = (int)(pOption->Camera.x * pOption->Camera.x); vt.y = (int)(pOption->Camera.y * pOption->Camera.y); vt.z = (int)(pOption->Camera.z * pOption->Camera.z); n = sqrt(vt.x + vt.y + vt.z); for(i = 0; i < pMesh->NumFace; i++) { vt.x = (pOption->Camera.x / n) + pMesh->Faces[i].normal.x; vt.y = (pOption->Camera.y / n) + pMesh->Faces[i].normal.y; vt.z = (pOption->Camera.z / n) + pMesh->Faces[i].normal.z; m = sqrt((vt.x * vt.x) + (vt.y * vt.y) + (vt.z * vt.z)); if(pOption->Light) { o = ((float)pOption->Lcolor.i / (float)pMesh->Faces[i].dist) / m; couleur.r = (int)(pOption->Lcolor.r * o); couleur.g = (int)(pOption->Lcolor.g * o); couleur.b = (int)(pOption->Lcolor.b * o); if(couleur.r > 255) couleur.r = 255; else if(couleur.r < 0) couleur.r = 0; if(couleur.g > 255) couleur.g = 255; else if(couleur.g < 0) couleur.g = 0; if(couleur.b > 255) couleur.b = 255; else if(couleur.b < 0) couleur.b = 0; } if((pMesh->Faces[i].normal.z <= 0) || pOption->Allface) { if(!pOption->Render) { Triangle(pMesh->Vertex[pMesh->Faces[i].a].v2D, pMesh->Vertex[pMesh->Faces[i].b].v2D, pMesh->Vertex[pMesh->Faces[i].c].v2D, couleur.r, couleur.g, couleur.b); } else { if(pOption->Render == 2) { Point(pMesh->Vertex[pMesh->Faces[i].a].v2D, couleur.r, couleur.g, couleur.b); } else { Line(pMesh->Vertex[pMesh->Faces[i].a].v2D, pMesh->Vertex[pMesh->Faces[i].b].v2D, couleur.r, couleur.g, couleur.b); Line(pMesh->Vertex[pMesh->Faces[i].b].v2D, pMesh->Vertex[pMesh->Faces[i].c].v2D, couleur.r, couleur.g, couleur.b); Line(pMesh->Vertex[pMesh->Faces[i].c].v2D, pMesh->Vertex[pMesh->Faces[i].a].v2D, couleur.r, couleur.g, couleur.b); } } } } if(SDL_MUSTLOCK(pScreen)) SDL_UnlockSurface(pScreen); SDL_Flip(pScreen); Fps = CLOCKS_PER_SEC / (clock() - start + 1); Fpsc++; Fpsa += Fps; if(Fpsc > Fps) { Fpsc = 1; Fpsa = Fps; sprintf(Titre, "%s - fps : %i", pOption->Title, Fpsa / Fpsc); SDL_WM_SetCaption(Titre, NULL); } }

Conclusion :


y a un .c de test en plus

lisez le readme :p

oui je sais y a mieu que SDL, mais je ne veux pas de truc tout fait !

Codes Sources

Ajouter un commentaire Commentaires
Messages postés
41
Date d'inscription
dimanche 17 novembre 2002
Statut
Membre
Dernière intervention
14 avril 2004

Ben apparment il ne l'a pas fait ... ;-)
Messages postés
54
Date d'inscription
lundi 17 mars 2003
Statut
Membre
Dernière intervention
12 mars 2006

je ne sais pas a quoi t'as toucher mais le projet est pret a etre compiler dans le zip
as tu bien integrer les .lib, le dll et le .h au projet ?
Messages postés
5
Date d'inscription
mercredi 7 avril 2004
Statut
Membre
Dernière intervention
8 avril 2004

bonjour a tous
je suis debutant et g pris le code pour l'etudier, le discequer, bref en faire une analyse. mais rien de plus frustrant(et "inutile") que d'arriver sur un code ... que l'on arrive pas a faire tourner. es que quelqu'un pourait m'aider a decoder les erreurs. voila, g vc++ et quand je lance la compilation, il me marque:

--------------------Configuration: test - Win32 Debug--------------------
Linking...
test.obj : error LNK2001: unresolved external symbol _SDL_GetKeyState
test.obj : error LNK2001: unresolved external symbol _SDL_PollEvent
test.obj : error LNK2001: unresolved external symbol _SDL_EnableKeyRepeat
test.obj : error LNK2001: unresolved external symbol _SDL_WM_SetCaption
test.obj : error LNK2001: unresolved external symbol _SDL_SetVideoMode
test.obj : error LNK2001: unresolved external symbol _SDL_Quit
test.obj : error LNK2001: unresolved external symbol _SDL_Init
test.obj : error LNK2001: unresolved external symbol _SDL_MapRGB
test.obj : error LNK2001: unresolved external symbol _SDL_Flip
test.obj : error LNK2001: unresolved external symbol _SDL_FillRect
LIBCD.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
Debug/test.exe : fatal error LNK1120: 11 unresolved externals
Error executing link.exe.

test.exe - 12 error(s), 0 warning(s)

Pourquoi ? a quoi cela correspont ? me manque t-il des lib ou de .h ? ...

D'avance merci
Gignops
Messages postés
780
Date d'inscription
lundi 16 décembre 2002
Statut
Membre
Dernière intervention
16 avril 2009
1
"la comprention" T'aurais pu faire un effort niveau français!
Messages postés
54
Date d'inscription
lundi 17 mars 2003
Statut
Membre
Dernière intervention
12 mars 2006

c'est pas du a l'autolook le bug, sa doit etre a cause des valeur arondie

de toute façon je passe a opengl
Afficher les 11 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.