Thứ Sáu, 4 tháng 9, 2015

BÁO CÁO BÀI TẬP LỚN: ĐỒ HỌA MÁY TÍNH


Đề Tài: Viết Chương Trình Mô Phỏng Bắn Pháo Hoa
GV: Trần Xuân Thanh

I. Thành Viên Trong Nhóm

Nhóm 8 (bài 8)
1. Lương Kim Lượng
2. Lê Hữu Đoàn
3. Hoàng Văn Sơn
4. Lê Xuân Linh
5. Lại Văn Dũng

II. Tóm Tăt Lý Thuyết Và Thuật Toán Liên Quan

  1. Tóm tắt lý thuyết
Pháo hoa hay pháo bông là loại pháo sử dụng thuốc phóng, thuốc nổ và các phụ gia đặc biệt tạo nên quang cảnh hoành tráng màu sắc của ánh sáng đa dạng hình khối phong phú, sinh động nhằm quy tụ cộng đồng trong những sinh hoạt văn hóa có tính tập thể như khai mạc, bế mạc ngày lễ tết, giao thừa, lễ hội chào mừng quốc khánh, đại hội thể thao các cấp. Là loại pháo lễ hội có lịch sử lâu đời, pháo hoa rất thịnh hành trong dân gian các nước phương Đông đặc biệt là Trung Hoa từ thời cổ đại. Tuy nhiên, hiện nay pháo hoa đã trở nên phổ biến toàn cầu và được sản xuất chủ yếu tại các nhà máy công nghiệp.

Trong bài viết này, chúng tôi sẽ mô phỏng kỹ thuật bắn pháo hoa, bằng ngôn ngữ lập trình C++ trong môi trường đồ họa (graphics)
Bài viết và chương trình có thể chưa hoàn thiện rất mong sự góp ý và tư vấn nhiệt tình từ phía thầy cô và các bạn.

Các hàm Sử Dụng
 a) Hàm delay

 Mục đích sử dụng : tạo độ trễ cho chương trình
Sử dụng thư viện : dos.h
Tham số bên trong hàm delay() là một con số (ngừng trong 1/1000 giây) ví dụ delay(1000) = 1s
Cách sử dụng
+ Cung cấp giá trị cho đối số n (có tham số trong lời gọi hàm)
 delay(5000);      //Đối số n=5000
+ Sử dụng giá trị mặc định của đối số (Không có hàm số trong lời gọi)
 delay(); //Đối số n=1000

b) Hàm random() - Tạo 1 giá trị ngẫu nhiên bất kỳ

Để tạo ra một số ngẫu nhiên, chúng ta sử dụng hàm random(), Hàm này trả về cho chúng ta kết quả là một giá trị nguyên có giá trị từ 0 đến RANDOM_MAX
Với RANDOM_MAX là một hằng số được định nghĩa trong thư viện <stdlib>.

 c) Một số hàm sẵn có trong thư viện đồ họa

putpixel(int x,int y,int c) vẽ 1 điểm trên màn hình với tọa độ x,y và màu c

bar3d(int x1,int y1,int x2,int y2,int deth,int top) vẽ 1 hình hộp 3D với tọa độ x1y1,x2y2 với depth là chiều sâu,top=0(hộp k có nắp)

setfillstyle(int b,int c) xác định mẫu tô màu với b là mẫu và c là màu vẽ (mẫu vẽ nằm trong dải từ 1 đến 12 với 1 là nét tô đậm
và 12 là nét vẽ do người dùng tự định nghĩa.

floodfill(int x,int y,int c) hàm tô màu với tọa độ xy và c là màu biên

hàm text trong chế độ đồ họa
settextstyle(int <phông chữ>,int <hướng chữ>,int <cỡ chữ>)

outtextxy(int x,int y,char *s) viết chữ với tọa độ xy và xâu s


  2. Thuật Toán
 Một số thuật toán vẽ đồ họa (tham khảo cuốn tài liệu Kỹ Thuật Đồ Họa - 2006 Học Viện Công Nghệ Bưu Chính Viễn Thông Hà Nội).
Thuật toán vẽ đường thẳng DDA (Digital Differential Analizer)
Thuật toán sinh đường tròn Midpoint và Bresenham
Các giải thuật tô màu...

                                     hình ảnh chương trình khi chạy
                                                        

► Video giới thiệu, cài đặt và chạy thử chương trình

<iframe width="560" height="315" src="https://www.youtube.com/embed/UEuEClFXkBY?rel=0&amp;showinfo=0" frameborder="0" allowfullscreen></iframe>


II. Cài Đặt Mã Nguồn

#include <conio.h>
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#include <graphics.h>
#include <dos.h>
#include <math.h>

#define round(a) int(a+0.5)

void InitGraph()
{
    int gd=DETECT,gm,error;

    initgraph(&gd,&gm,"../bgi");
    error=graphresult();
    if (error!=grOk)
    {   printf("Loi do hoa %s",grapherrormsg(error));
        printf("An phim bat ky de thoat");
        getch(); exit(1);
    }
}

void dda(int x1, int y1, int x2, int y2, int c)
{
    float x=x1,y=y1,m;
    if (x1!=x2)
    {   m=float(y2-y1)/(x2-x1);
        putpixel(x,round(y),c);
        if ( m>-1 && m<1)
        {   if (x1<x2)
                for (x=x1; x<=x2; x++)
                y+=m,putpixel(x,round(y),c);
            if (x1>x2)
                for (x=x1; x>=x2; x--)
                    y-=m,putpixel(x,round(y),c);
        }
        if (m<=-1 || m>=1)
        {   if (y1<y2)
                for (y=y1; y<=y2; y++)
                    x+=1/m,putpixel(round(x),y,c);
            if (y1>y2)
                for (y=y1; y>=y2; y--)
                    x-=1/m,putpixel(round(x),y,c);
        }
        }
    else
            for (int i=y1; i<=y2; i++) putpixel(x1,i,c);
}

void toquet1(int xmin,int ymin, int xmax, int ymax, int c)   // dung cho hcn
{
    for (int i=ymin+1; i<ymax; i++)
        dda(xmin,i,xmax,i,c);
}

void toquet2(int xt,int yt,int r,int c) // dung cho hinh tron
{
    int xmin=xt-r,ymin=yt-r,xmax=xt+r,ymax=yt+r,i,j;
    for (i=xmin; i<=xmax; i++)
        for (j=ymin; j<=ymax; j++)
            if (((i-xt)*(i-xt)+(j-yt)*(j-yt))<=r*r)
                putpixel(i,j,c);
}

void totrai(int x, int y, int mauto, int maubien);
void tophai(int x, int y, int mauto, int maubien);
void totren(int x, int y, int mauto, int maubien);
void toduoi(int x, int y, int mauto, int maubien);

void totrai(int x, int y, int mauto, int maubien)
{
    int maudiem;
    maudiem=getpixel(x,y);
    if ((maudiem!=mauto)&&(maudiem!=maubien))
    {   putpixel(x,y,mauto);
        totrai(x-1,y,mauto,maubien);
        totren(x,y-1,mauto,maubien);
        toduoi(x,y+1,mauto,maubien);
    }
}

void tophai(int x, int y, int mauto, int maubien)
{
    int maudiem;
    maudiem=getpixel(x,y);
    if ((maudiem!=mauto)&&(maudiem!=maubien))
    {   putpixel(x,y,mauto);
tophai(x+1,y,mauto,maubien);
totren(x,y-1,mauto,maubien);
toduoi(x,y+1,mauto,maubien);
    }
}

void totren(int x, int y, int mauto, int maubien)
{
    int maudiem;
    maudiem=getpixel(x,y);
    if ((maudiem!=mauto)&&(maudiem!=maubien))
    {   putpixel(x,y,mauto);
totrai(x-1,y,mauto,maubien);
tophai(x+1,y,mauto,maubien);
totren(x,y-1,mauto,maubien);
    }
}

void toduoi(int x, int y, int mauto, int maubien)
{
    int maudiem;
    maudiem=getpixel(x,y);
    if ((maudiem!=mauto)&&(maudiem!=maubien))
    {   putpixel(x,y,mauto);
totrai(x-1,y,mauto,maubien);
tophai(x+1,y,mauto,maubien);
toduoi(x,y+1,mauto,maubien);
    }
}

void tomau(int x, int y, int mauto, int maubien)    //(x,y) toa do tam
{
    int maudiem;
    maudiem=getpixel(x,y);
    if ((maudiem!=mauto)&&(maudiem!=maubien))
    {   putpixel(x,y,mauto);
totrai(x-1,y,mauto,maubien);
tophai(x+1,y,mauto,maubien);
totren(x,y-1,mauto,maubien);
toduoi(x,y+1,mauto,maubien);
    }
}

void put8pixel(int x,int y,int xt,int yt, int color)    // (xt,yt) toa do tam
{
    putpixel(x+xt,y+yt,color);  putpixel(y+xt,x+yt,color);
    putpixel(x+xt,-y+yt,color); putpixel(y+xt,-x+yt,color);
    putpixel(-x+xt,y+yt,color); putpixel(-y+xt,x+yt,color);
    putpixel(-x+xt,-y+yt,color);    putpixel(-y+xt,-x+yt,color);
}

void put30pixel(int a,int b,int xt, int yt,int c)
{   int i;
    float x[30],y[30],grad=(12*3.14)/180;
    x[0]=a; y[0]=b;
    for(i=1; i<30; i++)
    {   x[i]=x[0]*cos(i*grad)-y[0]*sin(i*grad)+yt*sin(i*grad)+xt*(1-cos(i*grad));
y[i]=x[0]*sin(i*grad)+y[0]*cos(i*grad)+yt*(1-cos(i*grad))-xt*sin(i*grad);
    }
    for (i=0; i<30; i++)    putpixel(round(x[i]),round(y[i]),c);
}

void put8ht(int x, int y, int xt, int yt, int c)
{
    toquet2(x+xt,y+yt,2,c);     toquet2(y+xt,x+yt,2,c);
    toquet2(x+xt,-y+yt,2,c);    toquet2(y+xt,-x+yt,2,c);
    toquet2(-x+xt,y+yt,2,c);    toquet2(-y+xt,x+yt,2,c);
    toquet2(-x+xt,-y+yt,2,c);   toquet2(-y+xt,-x+yt,2,c);
}

//************************************************************************


void hcn(int x1, int y1, int x2, int y2,int c)
{
    dda(x1,y1,x2,y1,c); dda(x1,y2,x2,y2,c);
    dda(x1,y1,x1,y2,c);     dda(x2,y1,x2,y2,c);
}



void hinhtron1(int xt, int yt, int r,int color) //(xt,yt) toa do tam
{
    int x=0,y=r,p=3-2*r;
    put8pixel(x,y,xt,yt,color);
    while (x<=y)
    {   if (p<0) p+=4*x+6;
else p+=4*(x-y)+10,y--;
x++;
put8pixel(x,y,xt,yt,color);
    }
}

void hinhtron2(int xt, int yt, int r,int c) //(xt,yt) toa do tam
{
    int x=0,y=r,p=3-2*r;
    put8ht(x,y,xt,yt,c);
    while (x<=y)
    {   if (p<0) p+=4*x+6;
else p+=4*(x-y)+10,y--;
x++;
  if (x%8==0)  put8ht(x,y,xt,yt,c);
else put8ht(x,y,xt,yt,0);
    }
}



//*****************************************************************************************

void bonghoa(int xt, int yt,int r,int c)
{
    float x[5],y[5],grad=(72*3.14)/180;
    x[0]=xt; y[0]=yt-2*r;
    for (int i=1; i<5; i++)
    {   x[i]=x[0]*cos(i*grad)-y[0]*sin(i*grad)+yt*sin(i*grad)+xt*(1-cos(i*grad));
y[i]=x[0]*sin(i*grad)+y[0]*cos(i*grad)+yt*(1-cos(i*grad))-xt*sin(i*grad);
    }
    hinhtron1(round(x[0]),round(y[0]),2*r,c); toquet2(round(x[0]),round(y[0]),2*r,c);
    hinhtron1(round(x[1]),round(y[1]),2*r,c); toquet2(round(x[1]),round(y[1]),2*r,c);
    hinhtron1(round(x[2]),round(y[2]),2*r,c); toquet2(round(x[2]),round(y[2]),2*r,c);
    hinhtron1(round(x[3]),round(y[3]),2*r,c); toquet2(round(x[3]),round(y[3]),2*r,c);
    hinhtron1(round(x[4]),round(y[4]),2*r,c); toquet2(round(x[4]),round(y[4]),2*r,c);
    hinhtron1(xt,yt,r,14); toquet2(xt,yt,r,14);
}

void ngoisao(int xt, int yt, int r)
{
    float x[5],y[5],grad=(72*3.14)/180;
    x[0]=xt; y[0]=yt-2*r;
    for (int i=1; i<5; i++)
    {   x[i]=x[0]*cos(i*grad)-y[0]*sin(i*grad)+yt*sin(i*grad)+xt*(1-cos(i*grad));
y[i]=x[0]*sin(i*grad)+y[0]*cos(i*grad)+yt*(1-cos(i*grad))-xt*sin(i*grad);
    }
dda(round(x[0]),round(y[0]),round(x[2]),round(y[2]),15);
dda(round(x[0]),round(y[0]),round(x[3]),round(y[3]),15);
    dda(round(x[1]),round(y[1]),round(x[3]),round(y[3]),15);
    dda(round(x[1]),round(y[1]),round(x[4]),round(y[4]),15);
dda(round(x[2]),round(y[2]),round(x[4]),round(y[4]),15);

    tomau(xt,yt,14,15);                 tomau(xt-r/2,yt+r,14,15);
    tomau(xt,yt-r,14,15);                   tomau(xt+4*r/5,yt+r,14,15);
    tomau(xt-r,round((yt+y[1])/2),14,15);           tomau(xt+r,round((yt+y[4])/2),14,15);
}

void cay(int xt, int yt,int r)
{
    toquet2(xt,yt,r,10);
    toquet1(xt-r/4,yt,xt+r/4,yt+4*r,6);
    toquet2(xt-r,yt,r,10);
    toquet2(xt+r,yt,r,10);
    toquet2(xt,yt-r,r,10);
}

void chauhoa(int xt, int yt, int r, int c)
{
    int i,j,k;
    arc(xt,yt,180,360,r);
dda(xt-r,yt,xt+r,yt,c);
    hcn(xt-r/2,yt,xt+r/2,yt+2*r,c);
    toquet1(xt-r/2,yt,xt+r/2,yt+2*r,c);
    for(i=xt-r; i<=xt+r; i++)
for(j=yt; j<=yt+r; j++)
   if (((i-xt)*(i-xt)+(j-yt)*(j-yt))<=r*r) putpixel(i,j,c);
    randomize(); k=1;
    while (k<=30)
    {   i=random(2*r)+xt-r;
j=random(r)+yt-r;
bonghoa(i,j,1,random(13)+1);
k++;
    }
}

void moon(int xt, int yt, int r)
{
    toquet2(xt,yt,r,14);
    toquet2(xt+r/2,yt,r,0);
}

void phongnen()
{
     int i;
hcn(0,415,getmaxx(),500,4); toquet1(0,415,getmaxx(),500,8);//to mau san truong
bar3d(200,300,440,450,30,1); toquet1(200,300,440,450,7);//khung ngoi nha 3D
hcn(200,300,440,450,WHITE);
setfillstyle(9,4);
floodfill(450,430,WHITE);//To mau canh ben
setfillstyle(1,12);
floodfill(430,290,WHITE);// to mau noc nha
  setcolor(RED);
  settextstyle(3,0,1);settextjustify(0,0); outtextxy(210,375,"Truong Dai Hoc Thanh Do");
  //ve va to cua so
    for(i=0;i<4;i++)
      {
       hcn(215+i*60,320,250+i*60,350,WHITE);
       toquet1(215+i*60,320,250+i*60,350,BLACK);
       }
       //cua chinh
       hcn(295,390,345,450,WHITE);setfillstyle(1,BLACK);
       floodfill(320,400,WHITE);
       setcolor(WHITE);
      // duong vien
     hcn(200,380,440,389,WHITE);
      toquet1(200,380,440,389,3);

    //bac thang
    hcn(280,465,360,470,0); toquet1(280,465,360,470,7);
    hcn(285,460,355,465,0); toquet1(285,460,355,465,7);
    hcn(290,455,350,460,0); toquet1(290,455,350,460,7);
    hcn(295,450,345,455,0); toquet1(295,450,345,455,7);
    toquet1(295,465,345,470,4); toquet1(300,460,340,465,4);
    toquet1(305,455,335,460,4);     toquet1(310,450,330,455,4);
    //tuong dai 2ben
    for(i=0;i<5;i++)
    {   hcn(440+i*20,443-i*7,640,450-i*7,0);    toquet1(440+i*20,443-i*7,640,450-i*7,7);
hcn(200-i*20,443-i*7,0,450-i*7,0);  toquet1(200-i*20,443-i*7,0,450-i*7,7);
    }
    //cot co, ngoi sao,chau hoa va cay
    hcn(210,460,250,480,0);setfillstyle(5,YELLOW);floodfill(215,470,0); //toquet1(210,460,250,480,7);
    hcn(210,460,250,480,6);
    toquet1(228,280,232,460,15); toquet2(230,279,2,15);
    toquet1(232,280,272,310,4); ngoisao(252,295,5);
    cay(50,370,30);  cay(150,400,20);
    cay(590,370,30); cay(490,400,20);
    moon(30,30,20);
    for (i=0; i<4; i++)
    {   chauhoa(460+i*40,450,15,15);
chauhoa(180-i*40,450,15,15);
    }
}
//SET PHAO HOA
//Set tia phao
void tiaphao(int xt, int yt,int c)
{
    toquet2(xt,yt,2,c);     dda(xt,yt,xt,yt+10,c);
    dda(xt,yt+10,xt-2,yt,c);        dda(xt,yt+10,xt+2,yt,c);
    randomize();
    for(int i=0;i<5;i++) putpixel(xt,yt+10+2*i,c);

}
//Set hieu ung phao no
void phaono(int xt,int yt)
{
    int i,j;
    for(i=yt;i>=yt-80;i--)
   {   put30pixel(xt,i,xt,yt,14); delay(20); }
   toquet2(xt,yt,85,0);
   for (i=0; i<10; i++)
   {   int k=random(14)+1;
if (i%2==0)
   for (j=0;j<10;j++)  hinhtron2(xt,yt,j*8,k);
else
   for (j=0;j<10;j++)  hinhtron2(xt,yt,j*8,0);
delay(100);
   }
}
//Loai phao hoa tron
void phaohoa()
{
    int i,j,xt,yt,chon;
    chon=random(5)+1;
    switch(chon)
    {   case 1:
{   xt=random(108)+1;
   yt=random(110)+130;
   for(i=289; i>=yt+2; i--)
   {   tiaphao(xt,i,14);delay(10);tiaphao(xt,i,0);}
   phaono(xt,yt);
   break;
}
case 2:
{   xt=random(107)+109;
   yt=random(25)+110;
   for(i=340; i>=yt+2; i--)
   {   tiaphao(xt,i,14);delay(10);tiaphao(xt,i,0);}
   phaono(xt,yt);
   break;
}
case 3:
{   xt=random(170)+227;
   yt=random(25)+110;
   for(i=255; i>=yt+2; i--)
   {   tiaphao(xt,i,14);delay(10);tiaphao(xt,i,0);}
   phaono(xt,yt);
   break;
}
case 4:
{   xt=random(128)+401;
   yt=random(25)+110;
   for(i=240; i>=yt+2; i--)
   {   tiaphao(xt,i,14);delay(10);tiaphao(xt,i,0);}
   phaono(xt,yt);
   break;
}
case 5:

{   xt=random(108)+530;
   yt=random(110)+110;
   for(i=289; i>=yt+2; i--)
   {   tiaphao(xt,i,14);delay(10);tiaphao(xt,i,0);}
   phaono(xt,yt);
   break;
}
    }

}
//Goi phao hoa
void banphaohoa()
{
     int i,j,yt;
    randomize();
    for (i=0;i<10;i++) phaohoa();
    yt=random(25)+130;
    for (i=255; i>=yt+2; i--)
    {   tiaphao(160,i,14);  tiaphao(320,i,14);
tiaphao(480,i,14);
delay(10);
tiaphao(160,i,0);   tiaphao(320,i,0);
tiaphao(480,i,0);
    }
    for(i=yt;i>=yt-80;i--)
    {   put30pixel(160,i,160,yt,14);
put30pixel(320,i,320,yt,14);
put30pixel(480,i,480,yt,14);
delay(20);
    }
    toquet1(0,48,640,255,0);
    for (i=0; i<6; i++)
    {   int k=random(14)+1;
if (i%2==0)
   for (j=0;j<10;j++)
   {   hinhtron2(160,yt,j*8,k);    hinhtron2(320,yt,j*8,k);
hinhtron2(480,yt,j*8,k);
   }
else
   for (j=0;j<10;j++)
   {   hinhtron2(160,yt,j*8,0);    hinhtron2(320,yt,j*8,0);
hinhtron2(480,yt,j*8,0);
   }
delay(100);
    }
//*********************************
    yt=random(25)+130;
    for (i=255; i>=yt+2; i--)
    {   tiaphao(80,i,14);   tiaphao(240,i,14);
tiaphao(400,i,14);  tiaphao(560,i,14);
delay(10);
tiaphao(80,i,0);    tiaphao(240,i,0);
tiaphao(400,i,0);   tiaphao(560,i,0);
    }
    for(i=yt;i>=yt-80;i--)
    {   put30pixel(80,i,80,yt,14);
put30pixel(240,i,240,yt,14);
put30pixel(400,i,400,yt,14);
put30pixel(560,i,560,yt,14);
delay(20);
    }
    toquet1(0,48,640,255,0);
    for (i=0; i<16; i++)
    {   int k=random(14)+1;
if (i%2==0)
   for (j=0;j<10;j++)
   {   hinhtron2(80,yt,j*8,k); hinhtron2(240,yt,j*8,k);
hinhtron2(400,yt,j*8,k); hinhtron2(560,yt,j*8,k);
   }
else
   for (j=0;j<10;j++)
   {   hinhtron2(80,yt,j*8,0); hinhtron2(240,yt,j*8,0);
hinhtron2(400,yt,j*8,0); hinhtron2(560,yt,j*8,0);
   }
delay(100);
    }
//*****************************
    yt=170;
    for (i=255; i>=yt+2; i--)
    {   tiaphao(80,i,14);   tiaphao(240,i,14);
tiaphao(400,i,14);  tiaphao(560,i,14);
tiaphao(160,i-40,14);   tiaphao(320,i-40,14);
tiaphao(480,i-40,14);
delay(10);
tiaphao(80,i,0);    tiaphao(240,i,0);
tiaphao(400,i,0);   tiaphao(560,i,0);
tiaphao(160,i-40,0);    tiaphao(320,i-40,0);
tiaphao(480,i-40,0);
    }
    for(i=yt;i>=yt-80;i--)
    {   put30pixel(80,i,80,yt,14);
put30pixel(240,i,240,yt,14);
put30pixel(400,i,400,yt,14);
put30pixel(560,i,560,yt,14);
put30pixel(160,i-40,160,yt-40,14);
put30pixel(320,i-40,320,yt-40,14);
put30pixel(480,i-40,480,yt-40,14);
delay(20);
    }
    toquet1(0,48,640,255,0);
    for (i=0; i<10; i++)
    {
if (i%2==0)
   for (j=0;j<10;j++)
   {   hinhtron2(80,yt,j*8,random(14)+1);  hinhtron2(240,yt,j*8,random(14)+1);
hinhtron2(400,yt,j*8,random(14)+1);     hinhtron2(560,yt,j*8,random(14)+1);
hinhtron2(160,yt-40,j*8,random(14)+1);  hinhtron2(320,yt-40,j*8,random(14)+1);
hinhtron2(480,yt-40,j*8,random(14)+1);
   }
else
   for (j=0;j<10;j++)
   {   hinhtron2(80,yt,j*8,0);     hinhtron2(240,yt,j*8,0);
hinhtron2(400,yt,j*8,0);    hinhtron2(560,yt,j*8,0);
hinhtron2(160,yt-40,j*8,0); hinhtron2(320,yt-40,j*8,0);
hinhtron2(480,yt-40,j*8,0);
   }
delay(100);cleardevice();
    }
}
void main()
{


    InitGraph();
    phongnen();
    banphaohoa();
    getch();
    closegraph();

}

III. Đánh Giá Và Kết Luận

Việc sử dụng kỹ thuật đồ họa C++ giúp ta mô phỏng khá tốt kỹ thuật bắn pháo hoa. Ngày nay, với sự phát triển nhanh chóng của công nghệ, việc mô phỏng có thể thực hiện tốt với đồ họa đẹp mắt và trơn tru hơn thì chúng ta có thể sử dụng thư viện đồ họa với thư viện và kỹ xảo 3D như OPENGL hay DIRECTX của hãng Microsoft kết hợp với lập trình C++.
Bài báo cáo đến đây là kết thúc, cảm ơn các thành viên đã cố gắng trong thời gian qua, cảm ơn quý thầy cô và các bạn đã đón đọc bài viết.

Không có nhận xét nào:

Đăng nhận xét