QUÁ TRÌNH THỰC HIỆN
1. Thiết kế cấu trúc thư viện
Ý TƯỞNG
Sau khi bàn bạc với một người bạn mới quen trên diễn đàn là RadicalLight. 2 mình quyết định xây dựng 1 thư viện đồ họa.
Toàn bộ kỹ thuật tụi mình sẽ cố gắng làm thành 1 Tut để các bạn có thể theo dõi và tham gia và thật sự tụi mình rất cần nhiều sự trợ giúp từ các bạn. Ai cũng có thể tham gia đóng góp chút ít. Bởi vì Project này sẽ là OpenSource.
Đã được chỉnh sửa lần cuối bởi ZCoder87 : 14-03-2008 lúc 09:42 PM.
QUÁ TRÌNH THỰC HIỆN
1. Thiết kế cấu trúc thư viện
Đã được chỉnh sửa lần cuối bởi ZCoder87 : 14-03-2008 lúc 09:42 PM.
Dành riêng....
Đã được chỉnh sửa lần cuối bởi ZCoder87 : 13-03-2008 lúc 12:22 PM. Lý do: Nhầm (T.T)
ZCoder87 ơi, mình nghĩ nên bàn một chút về cấu trúc của lib mà mình định làm nha!
Mình định làm thế này:
Cái này chỉ mang tính minh họa thôi! Chi tiết chúng ta sẻ làm sau!
- Lib gồm 3 phần chính:
+ GImage : Là bufer dùng để vẻ! Gồm một số hàm cần thiết như resize,save,load...! Chức năng như một tờ giấy!
+ G2D : Chứa GImage và các thông tin về image đó (như size,bpp,... trong BITMAPINFO) và có chứa năng vẻ cái GImage đang chứa trong nó ra màng hình! Ngoài ra nó không có một thứ gì khác! Chỉ giống như một cái khung đựng ảnh mà thôi!
+ Các class dùng để xử lý vẻ ảnh : Giống như bút vẻ
Mình chia ra như vậy là để dể dàng cho việc lập trình và tính mở rộng sau này cho lib thôi! Trước kia mình gôm nhiều thứ lại, kết quả là compile chậm, code chạy chậm, kiểm tra code khó,...!
Bạn thấy sao!
Lúc đầu mình định làm theo cấu trúc giống GDI. Các hàm dồn vào chung 1 đối tượng.
-> Ưu điểm: Dễ sử dụng.
-> Nhược điểm: Complie chậm, code chậm, kiểm tra khó...
Tuy nhiên mình vẫn có cách khắc phục nhược điểm nảy bằng cách "chia để trị". Có nghĩa là tất cả dồn vào HEADER. Còn phần thực thi thì phân tán ra.
Ví dụ như:
Việc chia thành nhiều file .cpp sẽ khắc phục được tất cả các nhược điểm mà bạn vừa nêu ra!Code:[Graphics.h] class{ .... ... } [Drawing.cpp] #include "Graphics.h" ... Các hàm liên quan tới vẽ [GradientFill.cpp] #include "Graphics.h" ... Các hàm liên quan tới Fill Gradient...
Tuy nhiên mình cũng nghĩ giống bạn là sẽ nên thiết kế Object trước.
=> Dựa trên ý tưởng của bạn mình đã thiết kế mẫu sau (trông chờ ý kiến của các bạn)
Đã được chỉnh sửa lần cuối bởi ZCoder87 : 13-03-2008 lúc 12:28 PM.
GImage
=> Là trang giấy trắng như bạn nói. Mọi thao tác sẽ vẽ lên nó...
GAbsGraphics
=> Select_Image () để giúp Graphics giữ địa chỉ Image.
=> Swap_Buffer() Vẽ ra thiết bị Device... Đây là hàm duy nhất liên quan tới HDH.
Hiện tại mình quan tâm tới 2 hệ đồ họa chính là RASTER và BITMAP
=> GDrawing. Chính là đối tượng chịu trách nhiệm vẽ đồ họa Raster.
=> ImgProcess. Chịu trách nhiệm trên đồ họa BITMAP
Trong đó.
GDrawing đóng vai trò là Adapter. Sẽ thực hiện thao tác vẽ. Được kế thừa từ GAbsGraphics nên nó có những hàm như Select_Image và Swap_Buffer.
Ý tưởng thực hiện của mình như sau:
C++ Code:
// Định nghĩa lại hàm virtual Select_Image của Graphics void GDrawing::Select_Image( GImage *pImage){ m_pPen->Select_Image (pImage); m_pFill->Select_Image(pImage); } void GDrawing::Select_Pen (GPenDrawing *pPen) .... void GDrawing::Select_Fill (GFillDrawing *pFill) .... // Ví dụ hàm Draw_Line void GDrawing::Draw_Line (GPoint p1, GPoint p2){ // Chuyên đổi tọa độ chẳn hạn, theo phép biến đổi đã thiết lập m_pTF->Change(&p1); m_pTF->Change(&p2); // Vẽ đường thẳng. m_pPen->Draw_Line( p1, p2 ); // Theo nguyên tắc ĐA HÌNH nó sẽ // xác định đúng hàm cần vẽ là Soild Line hay Style Line // hoặc bất kỳ kiểu đường thẳng nào kế thùa từ GPenDrawing // Mấu chốt xác định đường thằng nào là ở Select_Pen( ) }
Hay là hàm này:
C++ Code:
void GDrawing::Draw_Rectangle (GPoint p1, GPoint p2){ // Chuyên đổi tọa độ chẳn hạn theo phép biến đổi m_pTF->Change(&p1); m_pTF->Change(&p2); // Tô mầu m_pFill->Draw_Rectangle( p1, p2 ); // Vẽ đường thẳng. ... m_pPen->Draw_Line (...); m_pPen->Draw_Line (...); m_pPen->Draw_Line (...); m_pPen->Draw_Line (...); }
Đã được chỉnh sửa lần cuối bởi ZCoder87 : 13-03-2008 lúc 12:56 PM.
^_^ quá là chi tiết!
Vậy chúng ta sẻ làm theo cấu trúc này!
À thêm một chút nửa là, vì chúng ta đả phân tán mọi thứ ra vì vậy những class chung thì chúng ta sẻ gom vào một file DLL luôn nha ZCoder87! (VD: Drawing,Pen,Brush -> Drawing.DLL; GImage ->GImage.DLL,...)
Dùng như vầy sẻ rất tiện nhưng speed bị giảm khoảng 5% đó bạn (chạy nhiều mới thấy rỏ)!// Theo nguyên tắc ĐA HÌNH nó sẽ
// xác định đúng hàm cần vẽ là Soild Line hay Style Line
// hoặc bất kỳ kiểu đường thẳng nào kế thùa từ GPenDrawing
// Mấu chốt xác định đường thằng nào là ở Select_Pen( )
Nhưng nếu bạn không định dùng nó cho 3D hay một số thứ cần vẻ nhiều thì không sao cả!
Đã được chỉnh sửa lần cuối bởi RadicalLight : 13-03-2008 lúc 12:54 PM. Lý do: Thêm
Ừm. Tuy nhiên chúng ta nên trông chờ thêm 1 số ý kiến nữa
Theo mình việc phân chia DLL sao cho càng ít càng tốt mà thôi.
Thật ra mình thích áp dụng Đa Hình hơn. Bởi vì cái chậm lớn nhất trong đồ họa là các thuật toán con. Còn việc xác định hàm nào thì cũng nhanh mà, dĩ nhiên mình chưa test cái này. Nhưng làm như vậy quả thật là tiện, chứ cứ if ... if thì code rắc rối lăm.
Còn việc 3D thì mình chưa tham đâu. 2D được rồi.
Đã được chỉnh sửa lần cuối bởi ZCoder87 : 14-03-2008 lúc 08:51 PM.
Thực ra thì cũng đâu cần if...else! Chẳng hạn khi viết hàm Line() thì chúng ta sẻ chia ra làm nhiều hàm (Như là Line(), LineWithAntiAliasing(),...)!
Vì mình cũng đả làm thử và thấy là tốt!
Nhưng theo ý bạn cũng được, quan trọng nhất là thuật toán!
Vậy chờ thêm một số ý kiến nửa chúng ta sẻ bắt đầu làm!