unit Loader; interface Uses OpenGl, SysUtils, Windows, GL, GLfw, Textures; type TCoord = Record X, Y, Z : glDouble; end; TFace = Record V1, V2, V3, V4 : Integer; Vt1, Vt2, Vt3, Vt4 : Integer; end; TVt = Record X, Y, Z : glDouble; End; Var Vertex : Array of TCoord; CoordText : Array of TVt; Face : Array of Tface; Nom_Texture : string; Image_texture : glUint; const LARGEUR = 640; HAUTEUR = 480; FAVY = 70; RATIO = LARGEUR/HAUTEUR; MIN = 1; MAX = 100; procedure main_loop (); function transfo_string(var S : string) : String; function calcul_string_vertex ( S : string ) : TCoord; function calcul_string_vt ( S : string ) : Tvt; function calcul_string_face ( S : String ) : TFace; function charger_models (filename : String) : boolean; function triangle_ou_cube (Face : Array of TFace; i : integer) : integer; Procedure LoadObjTexture (); procedure afficher_models (); implementation // initialise opengl procedure main_loop (); var exit : integer; begin //On initialise OpenGL glfwInit (); // On peut ouvrir la fenêtre glfwOpenWindow (LARGEUR, HAUTEUR, 0, 0, 0, 0, 42, 0, GLFW_WINDOW); //On dessine l'objet si il n'y a rien devant glEnable (GL_DEPTH_TEST); //Active encadrement ou texture en mémoire glEnable(Gl_TEXTURE_2D); //On initialise le module de projection pour pouvoir les utiliser glMatrixMode (GL_PROJECTION); //Chargement de la matrice identité pour un environement vierge glLoadIdentity (); //Dit a OpenGL notre vision gluPerspective (FAVY, RATIO, MIN, MAX); //On initialise le module de modelisation et de visualisation pour les utiliser glMatrixMode (GL_MODELVIEW); //Chargement de la matrice identité pour un environement vierge glLoadIdentity (); //Boucle de jeu Exit := 0; //Tant que on a pas toucher la touche echap on reste dans la boucle while Exit = 0 do begin glPushMatrix (); exit := glfwGetKey (GLFW_KEY_ESC); //On efface tout les tampons existant pour un environement vierge GLclear (GL_COLOR_BUFFER_BIT); Glclear (GL_DEPTH_BUFFER_BIT); //On place notre caméra gluLookAt (10, -10, 10, 0, 0, 0, 0, 0, 1); // on appel les fonctions charger_models ('ordi.obj'); afficher_models(); glPopMatrix(); glfwSwapBuffers (); end; //Pour fermer la fenêtre lorsque la touche echap a été enclenché GlfwTerminate(); end; // Enleve les points d'une string en virgule function transfo_string(var S : string) : String; var i : integer; begin i := 1; while S[i] <> #0 do begin if S[i] = '.' then begin S[i] := ',' end; i := i+ 1; end; result := S; end; // Prends les coord des Vertex a partir d'une String function calcul_string_vertex ( S : string ) : TCoord; var i,coord : integer; tmp : string; begin tmp := ''; i := 4; // mettre i = 3 pour loader des fichiers .blend coord := 0; while S[i] <> #0 do begin if S[i] = ' ' then begin if coord = 0 then result.x := StrToFloat (transfo_string(tmp)) else if coord = 1 then result.y := StrToFloat (transfo_string(tmp)); coord := coord + 1; tmp := ''; end else tmp := tmp + S[i]; i := i + 1; end; result.Z := StrToFloat (transfo_string(tmp)); end; function calcul_string_vt ( S : string ) : Tvt; var i, coord : integer; tmp : string; begin tmp := ''; i := 4; //idem voir vertex coord := 0; while S[i] <> #0 do begin if S[i] = ' ' then begin if coord = 0 then result.X := StrtoFloat (transfo_string(tmp)) else result.Y := StrtoFloat (transfo_string(tmp)); coord := coord + 1; tmp := ''; end else tmp := tmp + S[i]; i := i + 1; end; result.Z := StrtoFloat (transfo_string(tmp)); end; // Prends les coord des Faces a partir d'une String function calcul_string_face ( S : String ) : TFace; var i,j,coord : integer; tmp : string; begin tmp := ''; i := 3; j := Length(S); // on est obliger de comparer avec la longueur de la string car 3ds // met un espace a la fin de la string coord := 0; result.V1 := 0; result.V2 := 0; result.V3 := 0; result.V4 := 0; result.Vt1 := 0; result.Vt2 := 0; result.Vt3 := 0; result.Vt4 := 0; while i < j do begin if S[i] = ' ' then begin if coord = 0 then result.Vt1 := StrToInt (tmp) else if coord = 1 then result.Vt2 := StrToInt (tmp) else if coord = 2 then result.Vt3 := StrToInt (tmp); coord := coord + 1; tmp := ''; end else if S[i] = '/' then begin if coord = 0 then result.V1 := StrToInt (tmp) else if coord = 1 then result.V2 := StrToInt (tmp) else if coord = 2 then result.V3 := StrToInt (tmp) else if coord = 3 then result.V4 := StrToInt (tmp); tmp := ''; end else tmp := tmp + S[i]; i := i + 1; end; result.Vt4 := StrToInt (tmp); tmp := ''; end; // Charge les faces et les vertex dans leurs tableaux respectifs function charger_models (filename : String) : boolean; var f : TextFile; S : String; Vertexlength, FaceLength, CoordTextLength : integer; begin if FileExists(filename) = false then result := false else begin AssignFile(f, filename); Reset(f); VertexLength := 0; FaceLength := 0; CoordTextLength := 0; S := ''; while not(eof(f)) do begin Readln(f, S); if S = '' then S := '' else if S = '#nom' then begin readln(f,S); readln(f,S); Nom_texture := S; end else if (S[1] = 'v') and (S[2] = ' ') then begin Inc(VertexLength); SetLength(Vertex, VertexLength); Vertex[VertexLength - 1] := calcul_string_vertex(S); end else if (S[1] = 'v') and (S[2] = 't') then begin Inc(CoordTextLength); SetLength(CoordText, CoordTextLength); CoordText[CoordTextLength - 1] := calcul_string_vt(S); end else if S[1] = 'f' then begin Inc(FaceLength); SetLength(Face, FaceLength); Face[Facelength - 1] := calcul_string_face(S); end end; result := true; CloseFile(f); end; end; Procedure LoadObjTexture (); begin LoadTexture(Nom_texture, Image_texture, False); end; // determine si la face contient un cube ou un triangle function triangle_ou_cube (Face : Array of TFace; i : integer) : integer; begin if Face[i].V4 = 0 then result := 3 else result := 4 end; //dessine le model dans une fenetre OpenGl procedure afficher_models (); var i : integer; begin //glClear(GL_COLOR_BUFFER_BIT or dGL_DEPTH_BUFFER_BIT); // nettoie la scene et le deph buffer //glLoadIdentity(); // recentre la vue for i := 0 to length(face) - 1 do begin if triangle_ou_cube(Face,i) = 3 then begin GlBegin( Gl_Triangles ); //Glcolor3ub(255, 100, 250); glBindTexture(GL_TEXTURE_2D, Image_Texture); glTexCoord2f(CoordText[(Face[i].Vt1)].X, CoordText[(Face[i].Vt1)].Y); //-1? GlVertex3d(Vertex[Face[i].V1].X, Vertex[Face[i].V1].Y, Vertex[Face[i].V1].Z); glTexCoord2f(CoordText[(Face[i].Vt2)].X, CoordText[(Face[i].Vt2)].Y); GlVertex3d(Vertex[Face[i].V2].X, Vertex[Face[i].V2].Y, Vertex[Face[i].V2].Z); glTexCoord2f(CoordText[(Face[i].Vt2)].X, CoordText[(Face[i].Vt2)].Y); GlVertex3d(Vertex[Face[i].V3].X, Vertex[Face[i].V3].Y, Vertex[Face[i].V3].Z); GlEnd(); end else begin GlBegin( Gl_Quads ); // Glcolor3ub(140, 90, 180); glBindTexture(GL_TEXTURE_2D, Image_texture); glTexCoord2f(CoordText[(Face[i].Vt1)].X, CoordText[(Face[i].Vt1)].Y); GlVertex3d(Vertex[Face[i].V1].X, Vertex[Face[i].V1].Y, Vertex[Face[i].V1].Z); glTexCoord2f(CoordText[(Face[i].Vt2)].X, CoordText[(Face[i].Vt2)].Y); GlVertex3d(Vertex[Face[i].V2].X, Vertex[Face[i].V2].Y, Vertex[Face[i].V2].Z); glTexCoord2f(CoordText[(Face[i].Vt2)].X, CoordText[(Face[i].Vt2)].Y); GlVertex3d(Vertex[Face[i].V3].X, Vertex[Face[i].V3].Y, Vertex[Face[i].V3].Z); glTexCoord2f(CoordText[(Face[i].Vt1)].X, CoordText[(Face[i].Vt1)].Y); GlVertex3d(Vertex[Face[i].V4].X, Vertex[Face[i].V4].Y, Vertex[Face[i].V4].Z); GlEnd(); end; end; end; end.