2/5 (8 avis)
Vue 11 293 fois - Téléchargée 435 fois
#include <conio.h> #include <dos.h> #include <fcntl.h> #include <go32.h> #include <io.h> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/farptr.h> #include <sys/stat.h> #include <unistd.h> #define PIXEL(x,y,c) ((((x)>=0)&&((x)<320)&&((y)>=0)&&((y)<200))?buffer[((y)<<8)+((y)<<6)+(x)]=(c):0) typedef struct { double x; double y; double z; } VERTEX; int main(int argc,char **argv); int savePCX(); void mouse(); void initGraph(); void stopGraph(); void display(); void drawCube(VERTEX* cube); void scanLine(int x1,int y1,int x2,int y2,int* scanboard); void fillFace(VERTEX a,VERTEX b,VERTEX c,int color); void drawLine(VERTEX a,VERTEX b); void writeText(char* text,int c,int posx,int posy); char ascii[1024]; char buffer[64000]; double matrix[360][3][3]; VERTEX cube[8]; VERTEX O; /* -------------------------- */ /* --- CORPS DU PROGRAMME --- */ /* -------------------------- */ int main(int argc,char **argv) { char str[23]; char key; int i; int param[4]={0,0,0,0}; VERTEX v; initGraph(); do { /* --- AFFICHAGE --- */ for (i=63999 ; i>=0 ; i--) buffer[i]=0; /* --- DESSINE LES FACES --- */ if (param[3]) drawCube(cube); /* --- DESSINE LES SEGMENTS --- */ else { drawLine(cube[0],cube[1]); drawLine(cube[1],cube[2]); drawLine(cube[2],cube[3]); drawLine(cube[3],cube[0]); drawLine(cube[4],cube[5]); drawLine(cube[5],cube[6]); drawLine(cube[6],cube[7]); drawLine(cube[7],cube[4]); drawLine(cube[0],cube[4]); drawLine(cube[1],cube[5]); drawLine(cube[2],cube[6]); drawLine(cube[3],cube[7]); } writeText(" appuyez sur '?' pour afficher l'aide ",1,0,24); display(); /* --- SI UNE TOUCHE A ETE PRESSEE --- */ if (kbhit()) { key=getch(); if (key=='1') param[2]='-'; if (key=='2') param[2]='0'; if (key=='3') param[2]='+'; if (key=='4') param[1]='-'; if (key=='5') param[1]='0'; if (key=='6') param[1]='+'; if (key=='7') param[0]='-'; if (key=='8') param[0]='0'; if (key=='9') param[0]='+'; if (key==' ') param[3]=~param[3]; if ((key=='c')||(key=='C')) savePCX(); /* --- AFFICHE L'ECRAN D'AIDE --- */ if (key=='?') { writeText(" ",512,6,5); writeText(" ? aide ",512,6,6); writeText(" mouse bouger ",512,6,7); writeText(" space grille/faces ",512,6,8); writeText(" 1->9 tourner ",512,6,9); writeText(" escape quitter ",512,6,10); writeText(" C capture d'ecran ",512,6,11); writeText(" ",512,6,12); for (i=0 ; i<6 ; i++) { sprintf(str," V%d(%4d,%4d,%4d) ",i+1,(int)cube[i].x,(int)cube[i].y,(int)cube[i].z); writeText(str,512,6,13+i); } writeText(" ",512,6,19); display(); getch(); } } /* --- ROTATIONS --- */ if (param[0]=='+') for (i=0 ; i<8 ; i++) { v=cube[i]; cube[i].y=v.y*0.9998476951-v.z*0.0174524064; cube[i].z=v.y*0.0174524064+v.z*0.9998476951; } else if (param[0]=='-') for (i=0 ; i<8 ; i++) { v=cube[i]; cube[i].y=v.y*0.9998476951+v.z*0.0174524064; cube[i].z=v.z*0.9998476951-v.y*0.0174524064; } if (param[1]=='+') for (i=0 ; i<8 ; i++) { v=cube[i]; cube[i].x=v.x*0.9998476951-v.z*0.0174524064; cube[i].z=v.z*0.9998476951+v.x*0.0174524064; } else if (param[1]=='-') for (i=0 ; i<8 ; i++) { v=cube[i]; cube[i].x=v.x*0.9998476951+v.z*0.0174524064; cube[i].z=v.z*0.9998476951-v.x*0.0174524064; } if (param[2]=='+') for (i=0 ; i<8 ; i++) { v=cube[i]; cube[i].x=v.x*0.9998476951-v.y*0.0174524064; cube[i].y=v.y*0.9998476951+v.x*0.0174524064; } else if (param[2]=='-') for (i=0 ; i<8 ; i++) { v=cube[i]; cube[i].x=v.x*0.9998476951+v.y*0.0174524064; cube[i].y=v.y*0.9998476951-v.x*0.0174524064; } mouse(); } while (key!=27); stopGraph(); return 0; } /* -------------------------------- */ /* --- FAIT UNE CAPTURE D'ECRAN --- */ /* -------------------------------- */ int savePCX() { int file; char header[128]; char pal[768]; char c; char n; unsigned int width=(320+(320&1)); unsigned long max=320*200; unsigned long i; /* --- CREATION DU PCX --- */ file=creat("capture.pcx",S_IRUSR|S_IWUSR); if (file==-1) { close(file); return 0; } /* --- EN-TETE --- */ header[0]=10; /* octet PCX */ header[1]=5; /* version de PCX */ header[2]=1; /* RLE active */ header[3]=8; /* 8 bits pour un pixel */ header[4]=0; /* Xmin */ header[5]=0; /* Xmin */ header[6]=0; /* Ymin */ header[7]=0; /* Ymin */ header[8]=(320-1)&0x00FF; /* Xmax */ header[9]=((320-1)&0xFF00)>>8; /* Xmax */ header[10]=(200-1)&0x00FF; /* Ymax */ header[11]=((200-1)&0xFF00)>>8; /* Ymax */ header[12]=72; /* resolution horizontale */ header[13]=0; /* resolution horizontale */ header[14]=72; /* resolution verticale */ header[15]=0; /* resolution verticale */ for (i=0 ; i<16 ; i++) /* palette 16 couleurs */ { header[i*3+16]=15-i; header[i*3+17]=15-i; header[i*3+18]=15-i; } header[64]=0; /* toujours 0 */ header[65]=1; /* toujours 1 */ header[66]=width&0x00FF; /* largeur, doit etre un nombre pair */ header[67]=(width&0xFF00)>>8; /* largeur, doit etre un nombre pair */ header[68]=1; /* 1 = couleurs, 2 = noir et blanc */ for (i=69 ; i<128 ; i++) header[i]=0; /* tout le reste c'est 0 */ _write(file,header,128); /* on ecrit l'en-tete */ /* --- IMAGE --- */ i=0; do { c=buffer[i]; i++; n=1; if (i!=max) while (buffer[i]==c) { if ((n<63)&&(i%320)) n++; else break; i++; if (i==max) break; } if ((n==1)&&((c&0xC0)!=0xC0)) _write(file,&c,1); else { if ((i%320==0)&&(320!=width)&&(c==(char)(255))) { n++; width=0; } n|=0xC0; _write(file,&n,1); _write(file,&c,1); } if (!width) width=320+1; else if ((i%320==0)&&(320!=width)) _write(file,"\xC1\xFF",2); } while (i!=max); /* --- PALETTE --- */ c=12; _write(file,&c,1); for (i=0 ; i<768 ; i++) pal[i]=0; pal[3]=255; pal[4]=255; pal[5]=255; pal[6]=255; pal[7]=0; pal[8]=0; pal[9]=0; pal[10]=255; pal[11]=0; pal[12]=0; pal[13]=0; pal[14]=255; pal[15]=0; pal[16]=255; pal[17]=255; pal[18]=255; pal[19]=0; pal[20]=255; pal[21]=255; pal[22]=255; pal[23]=0; _write(file,pal,768); return 1; } /* ----------------------------- */ /* --- S'OCCUPE DE LA SOURIS --- */ /* ----------------------------- */ void mouse() { union REGS regs; regs.x.ax=0x0003; // MOV AX,0003h int86(0x33,®s,®s); // INT 33h O.x=(regs.x.cx&0x03FF)>>1; O.y=regs.x.dx&0x00FF; if ((regs.x.bx&1)&&(O.z>400)) O.z-=4; if ((regs.x.bx&2)&&(O.z<1000)) O.z+=4; } /* ----------------------- */ /* --- INITIALISATIONS --- */ /* ----------------------- */ void initGraph() { int i; union REGS regs; /* --- INITIALISE LE MODE GRAPHIQUE --- */ regs.x.ax=0x0013; // MOV AX,0013h int86(0x10,®s,®s); // INT 10h _farsetsel(_dos_ds); // pour pouvoir acceder a la memoire outportb(0x03C8,0); outportb(0x03C9,0); // noir outportb(0x03C9,0); outportb(0x03C9,0); outportb(0x03C8,1); outportb(0x03C9,63); // blanc outportb(0x03C9,63); outportb(0x03C9,63); outportb(0x03C8,2); outportb(0x03C9,63); // rouge outportb(0x03C9,0); outportb(0x03C9,0); outportb(0x03C8,3); outportb(0x03C9,0); // vert outportb(0x03C9,63); outportb(0x03C9,0); outportb(0x03C8,4); outportb(0x03C9,0); // bleu outportb(0x03C9,0); outportb(0x03C9,63); outportb(0x03C8,5); outportb(0x03C9,0); // jaune outportb(0x03C9,63); outportb(0x03C9,63); outportb(0x03C8,6); outportb(0x03C9,63); // magenta outportb(0x03C9,0); outportb(0x03C9,63); outportb(0x03C8,7); outportb(0x03C9,63); // cyan outportb(0x03C9,63); outportb(0x03C9,0); /* --- CREE UN CUBE --- */ O.x=160.0; O.y=100.0; O.z=500.0; // definit l'origine cube[0].x=-100.0; cube[0].y=-100.0; cube[0].z=-100.0; cube[1].x= 100.0; cube[1].y=-100.0; cube[1].z=-100.0; cube[2].x= 100.0; cube[2].y= 100.0; cube[2].z=-100.0; cube[3].x=-100.0; cube[3].y= 100.0; cube[3].z=-100.0; cube[4].x=-100.0; cube[4].y=-100.0; cube[4].z= 100.0; cube[5].x= 100.0; cube[5].y=-100.0; cube[5].z= 100.0; cube[6].x= 100.0; cube[6].y= 100.0; cube[6].z= 100.0; cube[7].x=-100.0; cube[7].y= 100.0; cube[7].z= 100.0; /* --- INITIALISE LA SOURIS --- */ regs.x.ax=0x0000; // MOV AX,0000h int86(0x33,®s,®s); // INT 33h regs.x.ax=0x0002; // MOV AX,0002h int86(0x33,®s,®s); // INT 33h /* --- VA CHERCHER LA POLICE DE CARACTERE --- */ for (i=0 ; i<1024 ; i++) ascii[i]=_farnspeekb(i+0x000FFA6E); } /* ---------------------------- */ /* --- RETOUR AU MODE TEXTE --- */ /* ---------------------------- */ void stopGraph() { union REGS regs; regs.x.ax=0x0003; // MOV AX,03h int86(0x10,®s,®s); // INT 10h } /* -------------------------- */ /* --- RAFRAICHIT L'ECRAN --- */ /* -------------------------- */ void display() { unsigned int i; unsigned long i2; i=0; i2=0xA0000; // adresse de la memoire video while (!(inportw(0x03DA)&8)); // synchronise avec l'ecran while (inportw(0x03DA)&8); while (i<64000) _farnspokeb(i2++,buffer[i++]); // affichage } /* -------------------------------------- */ /* --- DESSINE LE CUBE AVEC LES FACES --- */ /* -------------------------------------- */ void drawCube(VERTEX* cube) { int b[7]; int b2[7]={0,1,2,3,4,5,6}; int i; int i2; /* --- TRIE LES FACES POUR NE PAS DESSINER LES FACES ARRIERES --- */ b[0]=cube[0].z+cube[1].z+cube[2].z+cube[3].z; b[1]=cube[4].z+cube[5].z+cube[6].z+cube[7].z; b[2]=cube[0].z+cube[3].z+cube[4].z+cube[7].z; b[3]=cube[1].z+cube[2].z+cube[5].z+cube[6].z; b[4]=cube[0].z+cube[1].z+cube[4].z+cube[5].z; b[5]=cube[2].z+cube[3].z+cube[6].z+cube[7].z; for (i2=0 ; i2<6 ; i2++) { for (i=0 ; i<5 ; i++) if (b[i]>b[i+1]) { b[7]=b[i]; b[i]=b[i+1]; b[i+1]=b[7]; b2[7]=b2[i]; b2[i]=b2[i+1]; b2[i+1]=b2[7]; } } /* --- DESSINE LES 3 FACES AVANT --- */ for (i=2 ; i>=0 ; i--) { if (b2[i]==0) { fillFace(cube[0],cube[1],cube[2],2); fillFace(cube[2],cube[3],cube[0],2); } else if (b2[i]==1) { fillFace(cube[4],cube[5],cube[6],3); fillFace(cube[6],cube[7],cube[4],3); } else if (b2[i]==2) { fillFace(cube[4],cube[0],cube[3],4); fillFace(cube[4],cube[7],cube[3],4); } else if (b2[i]==3) { fillFace(cube[1],cube[2],cube[6],5); fillFace(cube[5],cube[1],cube[6],5); } else if (b2[i]==4) { fillFace(cube[4],cube[5],cube[0],6); fillFace(cube[0],cube[5],cube[1],6); } else if (b2[i]==5) { fillFace(cube[2],cube[3],cube[7],7); fillFace(cube[7],cube[6],cube[2],7); } } } /* ------------------------ */ /* --- SCANNE UNE LIGNE --- */ /* ------------------------ */ void scanLine(int x1,int y1,int x2,int y2,int* scanboard) { int x; int y; int m; if (y2!=y1) { if (y2<y1) { m=y1; y1=y2; y2=m; m=x1; x1=x2; x2=m; } x=x1<<8; m=((x2-x1)<<8)/(y2-y1); x+=m; y1++; for (y=y1 ; y<=y2 ; y++) { if ((y<200)&&(y>=0)) { if (scanboard[y]==-16000) scanboard[y]=x>>8; else scanboard[y+200]=x>>8; } x+=m; } } } /* ------------------------ */ /* --- REMPLIT UNE FACE --- */ /* ------------------------ */ void fillFace(VERTEX a,VERTEX b,VERTEX c,int color) { int ax=(int)((a.x*256.0)/(a.z+O.z)+O.x); int ay=(int)((a.y*256.0)/(a.z+O.z)+O.y); int bx=(int)((b.x*256.0)/(b.z+O.z)+O.x); int by=(int)((b.y*256.0)/(b.z+O.z)+O.y); int cx=(int)((c.x*256.0)/(c.z+O.z)+O.x); int cy=(int)((c.y*256.0)/(c.z+O.z)+O.y); int x; int y; int scanboard[400]; for(y=0 ; y<200 ; y++) scanboard[y]=scanboard[y+200]=-16000; scanLine(ax,ay,bx,by,scanboard); scanLine(bx,by,cx,cy,scanboard); scanLine(cx,cy,ax,ay,scanboard); for(y=0;y<200;y++) { if(scanboard[y]>scanboard[y+200]) { x=scanboard[y]; scanboard[y]=scanboard[y+200]; scanboard[y+200]=x; } if (scanboard[y]!= -16000) { if(scanboard[y+200]==-16000) scanboard[y+200]=scanboard[y]; for(x=scanboard[y] ; x<scanboard[y+200] ; x++) PIXEL(x,y,color); } } } /* ----------------------- */ /* --- TRACE UNE LIGNE --- */ /* ----------------------- */ void drawLine(VERTEX a,VERTEX b) { int fx=(int)((a.x*256.0)/(a.z+O.z)+O.x); int fy=(int)((a.y*256.0)/(a.z+O.z)+O.y); int lx=(int)((b.x*256.0)/(b.z+O.z)+O.x); int ly=(int)((b.y*256.0)/(b.z+O.z)+O.y); int x1; int y1; int x2; int y2; int dx; int dy; int sub; int remain; int error; int inc1; int inc2; if (fx>lx) { x1=lx; x2=fx; y1=ly; y2=fy; } else { x1=fx; x2=lx; y1=fy; y2=ly; } dx=x2-x1; dy=y2-y1; if ((!dx)&&(!dy)) return; if (dy<0) { dy=-dy; inc1=-1; inc2=1; } else { inc1=1; inc2=1; } if (dx>dy) { sub=dx-dy; error=dy-(dx>>1); remain=(dx+1)>>1; do { PIXEL(x1,y1,1); PIXEL(x2,y2,1); x1+=inc2; x2-=inc2; if (error>=0) { y1+=inc1; y2-=inc1; error-=sub; } else error+=dy; } while (--remain>0); if (!(dx&1)) PIXEL(x1,y1,1); } else { sub=dy-dx; error=dx-(dy>>1); remain=(dy+1)>>1; do { PIXEL(x1,y1,1); PIXEL(x2,y2,1); y1+=inc1; y2-=inc1; if (error>=0) { x1+=inc2; x2-=inc2; error-=sub; } else error+=dx; } while (--remain>0); if (!(dy&1)) PIXEL(x1,y1,1); } } /* ---------------------- */ /* --- ECRIT DU TEXTE --- */ /* ---------------------- */ void writeText(char* text,int c,int posx,int posy) { unsigned int i; unsigned int i2; unsigned int pos1; unsigned int pos2; pos1=posy<<3; pos1=(pos1<<8)+(pos1<<6)+(posx<<3); // convertit les positions for (i=0 ; text[i] ; i++) // tant que le texte n'est pas fini { pos2=text[i]<<3; // va au caractere demande for (i2=0 ; i2<8 ; i2++) // 8 lignes par caracteres { /* --- AFFICHE LES 8 PIXELS DE LA LIGNE --- */ if (ascii[pos2]&0x80) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; if (ascii[pos2]&0x40) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; if (ascii[pos2]&0x20) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; if (ascii[pos2]&0x10) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; if (ascii[pos2]&0x08) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; if (ascii[pos2]&0x04) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; if (ascii[pos2]&0x02) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; if (ascii[pos2]&0x01) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; pos1+=320-8; pos2++; } pos1-=320*8-8; } }
27 août 2004 à 21:44
sinon désolé je vois vraiment pas d'où vient le problème :-/
6 août 2004 à 00:22
J'ai réussi à installer DJGPP :) et à compiler ton prog; tout marche impec sauf quand j'appuie sur ESPACE. Dans l'aide de ton prog, tu dis que quand on appuie sur "space" ça remplit les faces et que quand on appuie sur "espace" ça quitte, alors le prog fait les 2 :p Je vois les faces se remplir pendant un très court moment avant qu'il quitte avec un message qui fait pas plaisir sur la console, je cite :
Stack Fault at eip=00001b80
eax=00000000 ebx=000085a4 ecx=0000041c edx=000a0020 esi=000227d8 edi=000ab0d8
ebp=00000001 esp=000ab0f0 program=F:\DOWNLO~2\CPPFRA~1\CUBEVG~1\CUBE.EXE
cs: sel=00a7 base=85a4e000 limit=000affff
ds: sel=00af base=85a4e000 limit=000affff
es: sel=00af base=85a4e000 limit=000affff
fs: sel=00bf base=00000000 limit=0010ffff
gs: sel=00bf base=00000000 limit=0010ffff
ss: sel=00af base=85a4e000 limit=000affff
App stack: [000ab178..0002b178] Exceptn stack: [0002b0d4..00029194]
Call frame traceback EIPs:
0x00001b80
Je suis sous Win98.
Si tu pouvais avoir une idée d'où ça vient...
4 août 2004 à 16:40
4 août 2004 à 10:36
En fait j'ai un vieux bouquin, "PC interdit : le meilleur programmation jeux 3D" qui utilise Pascal, l'ASM et un truc qui s'appelle le Mode X mais les exes plantent sous Windows :/
Voilà, si tu pouvais m'éclaircir un peu sur le sujet merci ;)
3 août 2004 à 13:51
J'ai également rajouté la possibilité d'enregistrer l'image en PCX (vu que j'en avais besoin pour faire la capture).
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.