Trang 1 trên tổng số 4 123... Cuối cùngCuối cùng
Từ 1 tới 10 trên tổng số 37 kết quả

Đề tài: Lập trình đồ họa với OpenGL trên Visual C++

  1. #1
    Ngày gia nhập
    07 2006
    Nơi ở
    Hanoi, Vietnam
    Bài viết
    2,750

    Mặc định Lập trình đồ họa với OpenGL trên Visual C++

    Lập trình 3D thì phổ biến nhất là dùng Direct3D hoặc OpenGL. Direct3D chỉ dùng được trên Windows, còn OpenGL đã là Industrial Standard từ khá lâu và có thể dùng được trên mọi OS. Nếu không bị bắt buộc phải dùng Direct3D, nên chọn OpenGL

    Để học OpenGL, có lẽ không thể thiếu cuốn OpenGL Programming Guide, còn gọi là The Red Book. Ngoài ra nên tham khảo tutorial trên NeHe
    • Dùng thư viện cấp cao kiểu graphics hay game engine, như Irrlicht vs Ogre3D. Các này thì không cần biết OpenGL là gì.
    • Dùng trực tiếp API do OpenGL cung cấp kèm hoặc không kèm thư viện AUX. AUX là thư viện để tạo cửa sổ và quản lí input từ chuột, bàn phím. Không dùng AUX thì ta phải tự làm các việc trên. Nếu dùng AUX thì chương trình sẽ cross-platform
    Cách viết chương trình



    Bước 0 - Khai báo file header và library
    • File header của OpenGL thường được đặt riêng trong folder gl, nên khai:
    Code:
    #include gl\gl.h
    Chỉ với gl.h, đã có thể làm mọi thứ liên quan đến OpenGL. Tuy nhiên để tiết kiệm thời gian, có thể xài một số utility function. Những utility function này nằm trong glu.h:
    Code:
    #include gl\glu.h
    Function của gl.h và glu.h có prefix tương ứng là gl và glu. Sau khi compile, để link thành chương trình .exe, cần khai file library
    Nếu chỉ include gl.h, chỉ cần khai file opengl32.lib. Nếu xài thêm glu.h thì khai thêm glu32.lib. Phần khai này tùy compiler/linker, nếu xài IDE của Visual C++ 6 thì vào Project -> Settings -> Link, rồi gõ file .lib thích hợp vào Object/library modules.

    Fig2. Khai library

    Mẹo: với Visual C++, có thể khai file library ngay trong source code, chú ý không có dấu chấm phẩy.
    Code:
    #pragma comment(lib, "opengl32.lib")
    #pragma comment(lib, "glu32.lib")
    • Bước 1 - Khởi tạo
    1.1 - Lấy device context của window
    Trong Windows, mọi thứ đều là window. Muốn vẽ hình 3D lên window nào thì lấy device context của window đó. Để lấy device context của window nào, phải có handle của window đó.

    Ex:
    Chương trình Dialog based, xài MFC. Trên dialog đặt 1 cái Static Text có id là IDC_STATIC_OPENGL, hình 3D sẽ được vẽ lên đây.

    Fig3. Static Text đã được kéo to ra



    Code:
    HWND m_StaticWnd; // global
    HDC m_StaticDC; // global
    m_StaticWnd = ::GetDlgItem(m_hWnd, IDC_STATIC_OPENGL); // m_hWnd là handle của dialog
    m_StaticDC = ::GetDC(m_StaticWnd);
    Để phân biệt, khi xài API function trực tiếp, thêm dấu :: đằng trước. Bây giờ khi đã có device context của Static Text. Vì device context này chỉ được release khi thoát chương trình, nên khai báo thêm m_StaticWnd và m_StaticDC trong phần global.

    1.2 - Thay đổi pixel format của device context
    Device context cần được thay đổi phù hợp để OpenGL có thể vẽ lên đó.
    Code:
    PIXELFORMATDESCRIPTOR pfd =
    {
    sizeof(PIXELFORMATDESCRIPTOR),
    1,
    PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
    PFD_TYPE_RGBA,
    24,
    0, 0, 0, 0, 0, 0,
    0, 0,
    0, 0, 0, 0, 0,
    32,
    0,
    0,
    PFD_MAIN_PLANE,
    0,
    0, 0, 0
    };
    int PixelFormat = ::ChoosePixelFormat(m_StaticDC, &pfd);
    ::SetPixelFormat(m_StaticDC, PixelFormat, &pfd);
    Các tham số có thể tham khảo trong MSDN. PFD_DOUBLEBUFFER
    - Khi có tham số này, OpenGL không vẽ trực tiếp lên device context, mà sẽ vẽ lên buffer. Muốn hiện buffer này lên màn hình, sẽ swap buffer này với device context, xem bước 2. Nếu OpenGL vẽ trực tiếp lên device context, tốc độ sẽ rất chậm, vì vẽ được cái gì thì sẽ phải update lên màn hình cái đấy ngay.
    - PFD_SUPPORT_GDI và PFD_DOUBLEBUFFER là mutually exclusive, nên các thao tác GDI trên device context này sẽ không có tác dụng.

    1.3 - Tạo renderring context cho OpenGL
    Bước này báo cho OpenGL biết sẽ vẽ lên device context nào.
    Code:
    HGLRC m_OpenGLRC; // global
    
    m_OpenGLRC = wglCreateContext(m_StaticDC);
    wglMakeCurrent(m_StaticDC, m_OpenGLRC);
    Muốn OpenGL vẽ lên device context nào, wglMakeCurrent đến device context đó. Rendering context này chỉ được delete khi thoát chương trình, nên khai báo trong phần global.
    1.4 - Setup trạng thái cho OpenGL
    Điều chỉnh góc nhìn, màu nền,.. như sau:

    Code:
    // xóa đen window
    glClearColor(0, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);
    glFlush();
    
    // chỉnh viewport
    RECT rect;
    ::GetWindowRect(m_StaticWnd, &rect);
    int width = rect.right - rect.left;
    int height = rect.bottom - rect.top;
    glViewport(0, 0, width, height);
    
    // chỉnh góc nhìn
    double aspect = (double)width/height;
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60, aspect, 0.1, 1000);
    
    // chọn rendering mode
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glDrawBuffer(GL_BACK);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    Để hiểu rõ, tham khảo thêm MSDN. Nếu size của window bị thay đổi, nên gọi lại phần "chỉnh viewport" và "chỉnh góc nhìn".
    • Bước 2 - Update window
    Chỉ nên update window khi chương trình ở trong trạng thái idle. Xem ghi chú về idle ở cuối bài viết này.
    Code:
    Render();  // gọi Render
    SwapBuffers(m_StaticDC); // swap buffer với device context -> hiện buffer lên màn hình
    Muốn vẽ cái gì lên window thì vẽ ở Render. Vì phần vẽ này thường rất dài và phức tạp, nên mới được tách ra thành 1 function.
    Code:
    void Render()
    {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // xóa toàn bộ
    glPushMatrix();
    // OpenGL painting commands go here, dài và phức tạp lắm nghe :p
    glPopMatrix();
    }
    glPushMatrix và glPopMatrix dùng để lưu và phục hồi trạng thái của OpenGL. Nếu trong painting commands có command nào đó làm thay đổi trạng thái của OpenGL, mà Render không lưu và phục hồi trạng thái ban đầu, thì sau vài lần gọi Render, hình vẽ hiển thị lên màn hình sẽ không như ý muốn. Nhớ rằng OpenGL là state machine.
    • Bước 3 - Dọn dẹp
    Khi chương trình chương trình kết thúc, cần release device context và delete rendering context.
    Code:
    ReleaseDC(m_StaticWnd, m_StaticDC); // đây là lí do tôi khai m_StaticWnd trong phần global
    wglMakeCurrent(NULL, NULL);
    wglDeleteContext(m_OpenGLRC);
    Fig4. In Action


    Ghi chú về idle
    • 1. Chương trình Dialog based, xài MFC
    Không xài được cả WM_ENTERIDLE lẫn CWinApp::OnIdle()
    => xài WM_KICKIDLE trong afxpriv.h
    File header của dialog, phần message map, thêm:
    Code:
    afx_msg LRESULT  OnKickIdle(WPARAM , LPARAM);
    File implementation của dialog, thêm:
    Code:
    #include
     ON_MESSAGE(WM_KICKIDLE,  OnKickIdle)
     LRESULT CMyDlg::OnKickIdle(WPARAM wParam,  LPARAM lParam)
    {
        Render();
        SwapBuffers(m_StaticDC);
    return 0;
    }
    • 2. Chương trình BCB
    Code:
    __fastcall TForm1::TForm1(TComponent*  Owner): TForm(Owner)
     {
        Application->OnIdle = OnIdle;
        _control87(MCW_EM, MCW_EM);
    }
     void __fastcall TForm1::OnIdle(TObject*  Sender, bool &done)
    {
        done = false;
        Render();
        SwapBuffers(m_StaticDC);
    }
    • 3. Chương trình Win32
    Cách 1: Xài WM_ENTERIDLE

    Cách 2:
    Code:
    while (!done)
    
     {
        // is there a msg waiting?
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if (msg.message == WM_QUIT)
                done = TRUE;
            else
            {
                 TranslateMessage(&msg);
                 DispatchMessage(&msg);
            }
        }
        else
        {
            Render();
            SwapBuffers(m_StaticDC);
        }
    }
    Bài viết được sưu tầm tại Blog cộng đồng CNTT.
    Email: admin[@]congdongcviet.com | CC to: info[@]congdongcviet.com
    Phone: 0972 89 7667 (Office: 04 6329 2380)
    Yahoo & Skype: dreaminess_world (Vui lòng chỉ rõ mục đích ngay khi liên hệ, cảm ơn!)

    Một người nào đó coi thường ý thức kỷ luật cũng có nghĩa là người đó đã coi thường tương lai số phận của chính bản thân người đó. Những người coi thường ý thức kỷ luật sẽ không bao giờ có được sự thành công trong sự nghiệp!

  2. #2
    Ngày gia nhập
    07 2006
    Nơi ở
    Hà nội
    Bài viết
    204

    Ai giải thích cho em Idle là cái gì ko ?
    Ko biết có bản tiếng việt của quyển red book này ko nhi ?
    Life:\> dir

  3. #3
    Ngày gia nhập
    11 2006
    Bài viết
    9

    Thư viện này source down về ở đâu thế. Từ lâu mình bít cái này nhưng không tiếp cận được nó
    360 yahoospacetime blog
    Tripod blog
    cũng của spacetime trên wordpress
    The god programmin language-C
    My name is 7h36h5ng
    password yahoo:mDn4kdn1z

  4. #4
    Ngày gia nhập
    07 2006
    Nơi ở
    Hà nội
    Bài viết
    204

    Thư viện: http://www.box.net/shared/vuusdv22zh
    Trang web của opengl: http://www.opengl.org
    Red book, cuốn sách cơ bản cho những ng` mới vào nghề: http://www.opengl.org/documentation/red_book
    Trang này có nhiều code hay: http://www.codecolony.de/

    Còn 1 số chương đã dịch sang tiếng việt của red book ở máy, nhưng quên link down roài !
    Life:\> dir

  5. #5
    Ngày gia nhập
    11 2007
    Bài viết
    1

    Không biết có code dành cho VC6 WiN32 console không?

  6. #6
    Ngày gia nhập
    03 2008
    Bài viết
    1

    Mặc định Lập trình đồ họa với OpenGL trên Visual C++

    mấy bác pro làm ơn chỉ cho em những điều căn bản nhất của Đồ họa openGL đi.Em mới bắt đầu học môn này nên "gà" lắm...Thanks nhiều!

  7. #7
    Ngày gia nhập
    04 2008
    Bài viết
    2

    OpenGL , hay quá ! Tiện thể ai có cuốn sách Opengl programming guide ( 6th ) post lên đi ! Chúng ta sẽ tiếp tục trao đổi sau nhớ !

  8. #8
    Ngày gia nhập
    09 2008
    Bài viết
    13

    Post một một số project về opengl viết bằng vc++ cho xem đi bạn.

  9. #9
    Ngày gia nhập
    09 2008
    Bài viết
    13

    cài đặt vào máy thế nào vậy bạn, mình chạy nó cứ bị lỗi hoài à.

  10. #10
    Ngày gia nhập
    09 2008
    Bài viết
    13

    Xin bạn chỉ rõ cho mình từng bước sau khi tải opengl library về. Cài vào máy như thế nào. (dùng vc++ 2008 trong bộ visual studio). Mình tự học nên xin bạn chỉ dùm.

Các đề tài tương tự

  1. Lập Trình OpenGL trong Visual Studio (C#)?
    Gửi bởi gacongnghiep_cs trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 3
    Bài viết cuối: 07-05-2011, 08:34 PM
  2. Lỗi đề tài OpenGL ko chạy dc trên Visual C++ 2008
    Gửi bởi chuong01 trong diễn đàn Thắc mắc lập trình Visual C++
    Trả lời: 11
    Bài viết cuối: 30-06-2010, 08:44 PM
  3. Lỗi lập trình OpenGL trên Visual C++ express 2008
    Gửi bởi timeline trong diễn đàn Thắc mắc lập trình Visual C++
    Trả lời: 0
    Bài viết cuối: 23-05-2010, 01:10 PM
  4. OpenGL với Visual C++ | làm hình chuyển động
    Gửi bởi chuphuong233 trong diễn đàn Thắc mắc lập trình Visual C++
    Trả lời: 0
    Bài viết cuối: 04-04-2010, 02:20 AM
  5. Visual C++ and OpenGL
    Gửi bởi lauca trong diễn đàn Thắc mắc lập trình Visual C++
    Trả lời: 1
    Bài viết cuối: 17-04-2007, 02:39 PM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn