Chào mừng đến với Diễn đàn lập trình - Cộng đồng lập trình.
Trang 1 của 4 123 ... CuốiCuối
Kết quả 1 đến 10 của 38
  1. #1

    Đồ họa | Từng bước xây dựng cho mình một thư viện đồ họa

    Ý 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.

  2. #2
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Dành riêng....

  3. #3
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    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!

  4. #4
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    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.

  5. #5
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    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!

  6. #6
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    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ư:
    Mã:
    [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...
    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!

    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)

  7. #7
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    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à RASTERBITMAP

    => 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:


    Mã:
     // Định nghĩa lại hàm virtual Select_Image của Graphicsvoid 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_Linevoid 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:

    Mã:
    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 (...);}

  8. #8
    ^_^ 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,...)


    // 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( )
    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ỏ)!
    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ả!

  9. #9
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Ừm. Tuy nhiên chúng ta nên trông chờ thêm 1 số ý kiến nữa

  10. #10
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Mình bắt đầu đi RL.

    Bây giờ ta sẽ thảo chi tiết 2 Object GImage GAbsGraphics trước và sau đó chúng ta sẽ code. Nếu bạn ko bận thì chậm lắm tuần sau (tốt thứ 6) phải xong 2 phần này. Còn phần GImageFile => Save/Load thì kiến thức của mình chỉ đủ ở BMP (16, 24 hay 32, 8bit ko nén RLE gì đó) và TGA thôi, còn lại thì chưa có thời gian mà nghiên cứu T.T.

    GImage

    Cấu trúc định nghĩa sẵn của Windows.h

    Mã:
    typedef struct tagBITMAPINFO {     BITMAPINFOHEADER bmiHeader;     RGBQUAD          bmiColors[1]; } BITMAPINFO, *PBITMAPINFO;  typedef struct tagBITMAPINFOHEADER{    DWORD  biSize;     LONG   biWidth;     LONG   biHeight;     WORD   biPlanes;     WORD   biBitCount;     DWORD  biCompression;     DWORD  biSizeImage;     LONG   biXPelsPerMeter;     LONG   biYPelsPerMeter;     DWORD  biClrUsed;     DWORD  biClrImportant; } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
    Mã:
    class GImage{    protected:        BYTE *m_pImage;    public:        GImage ( int w, int h);        GImage ( const GImage& pImage );        ~GImage();         BYTE* Get_Bitmap_Data ();         // Trả về địa chỉ vùng DATA cho GAbsGraphics          BITMAPINFOHEADER* Get_Bitmap_Header();        // Trả về HEADER, Thông tin về Bitmap         BITMAPINFO* Get_Bitmap();         bool Create_Image ( int w, int h );                void Delete_Image ();         // Destructor gọi hàm này!         bool Save_Image (LPWSTR lpFileName, UINT nOption );        // Option là một số const định dạng .. Ví dụ như Save 24 bit hay 32 bit...         bool Load_Image (LPWSTR lpFileName);         bool Copy_FromImage (GImage *pImage);};
    GImage theo mình nên để là 32bit luôn (dĩ nhiên xử lý sẽ chậm hơn 24bit).
    Còn BYTE *m_pImage; sẽ là vùng nhớ giống như 1 file BMP.
    Mã:
    [ BITMAPINFOHEADER ] [ PALETTE (not use in 24, 32 bit) ] [ DATA... ]
     
    - InfoHeader  = 40 bytes.
    - Data  =  Width * Height * 4 (hoặc 3, đang thảo luận ) bytes
    Mình chỉ tạm thời nghĩ tới đó thôi... và cần thêm ý kiến

 

 
Trang 1 của 4 123 ... CuốiCuối

Quyền viết bài

  • Bạn Không thể gửi Chủ đề mới
  • Bạn Không thể Gửi trả lời
  • Bạn Không thể Gửi file đính kèm
  • Bạn Không thể Sửa bài viết của mình
  •