Trang 1 trên tổng số 2 12 Cuối cùngCuối cùng
Từ 1 tới 10 trên tổng số 14 kết quả

Đề tài: Khởi động OPENGL in Linux

  1. #1
    Ngày gia nhập
    01 2008
    Nơi ở
    Gameloft Studio
    Bài viết
    294

    Mặc định Khởi động OPENGL in Linux

    Dành cho những bạn thích Linux Programing.

    I. Khởi tạo cửa sổ XWindow

    1. Xlib Headers

    Bao gồm 3 thư viện chính nhưng gọi chung là XLib. Thư viện này gần như là thư viện chuẩn lập để trình đồ họa trên X Window của Linux. Để hiểu rõ hơn về 3 thư viện này tốt nhất các bạn nên tham khảo trên GOOGLE.

    C++ Code:
    1. #include <X11/Xlib.h>
    2. #include <X11/Xutil.h>
    3. #include <X11/Xos.h>

    2. Kết nối X Server

    X Window System cung cấp các giao tiếp giúp chúng ta có thể khởi tạo các cửa sổ, nhận các sự kiện...

    X Window System quản lý nhiều cửa sổ, chuột, bàn phím hoặc các thiết bị nhập xuất khác trên Linux được gọi là X Server. Sử dụng con trỏ Display và hàm XOpenDisplay để kết nối với X Server. Và lúc này chương trình của chúng ta gọi là X Client.

    C++ Code:
    1. Display *display;
    2.  
    3. display = XOpenDisplay(NULL);
    4. if (display == NULL) {
    5.   cerr << “Failure connecting to X Server”
    6.   exit(1);
    7. }

    3. Các tham số khác của Display

    C++ Code:
    1. int intScreenNum = DefaultScreen(display);
    2. int intDisplayWidth = DisplayWidth(display, intScreenNum);
    3. int intDisplayHeight = DisplayHeight(display, intScreenNum);

    - DefaultScreen : Macro này sẽ trả về màn hình hiện hành đang sử dụng. Đừng nghĩ là lúc nào máy tính cũng chỉ có 1 màn hình, có những lúc người ta sử dụng 1 PC nhưng tới 2 màn hình, chủ yếu là ở những người thường xuyên làm việc thiết kế đồ họa.
    - DisplayWidth, DisplayHeight: Đây là 2 Macro (được viết = #define). 2 hàm này trả về độ phân giải (w, h) hiện tại của màn hình.

    4. Khởi tạo cửa sổ X Window

    C++ Code:
    1. Display *display;
    2.  
    3. display = XOpenDisplay(NULL);
    4. if (display == NULL) {
    5.   cerr << “Failure connecting to X Server”
    6.   exit(1);
    7.  
    8. int intScreenNum = DefaultScreen(display);
    9. int intDisplayWidth = DisplayWidth(display, intScreenNum);
    10. int intDisplayHeight = DisplayHeight(display, intScreenNum);
    11.  
    12. int intWidth = intDisplayWidth /2;
    13. int intHeight = intDisplayHeight /2;
    14.  
    15. // Xac dinh mau.
    16. int intBlackColor, intWhiteColor;
    17. intBlackColor = BlackPixel(display, intScreenNum);
    18. intWhiteColor = WhitePixel(display, intScreenNum);
    19. int XPos = 0;
    20. int YPos = 0;
    21.  
    22. Window win = [COLOR="Blue"]XCreateSimpleWindow[/COLOR](
    23.   display,                         // X server display struct
    24.   DefaultRootWindow(display),      // Parent window
    25.   intXPos, intYPos,                // Position
    26.   intWidth, intHeight,             // Window width & height
    27.   0,                               // Border width (default)
    28.   intBlackColor, intWhiteColor);   // Background, foreground

    Nếu đã lập trình Win32 rồi thì cũng ko lạ gì nữa.
    - Window => Cái này y chang HWND vậy.
    - XCreateSimpleWindow hao hao giống CreateWindow vậy. Tham số cần thiết là Parent, x,y,w,h và màu sắc.

    Còn tiếp...
    Đã được chỉnh sửa lần cuối bởi ZCoder87 : 09-03-2008 lúc 11:33 AM.

  2. #2
    Ngày gia nhập
    01 2008
    Nơi ở
    Gameloft Studio
    Bài viết
    294

    II. Làm việc với của sổ X Windows

    1. Thay đổi tiêu đề cửa sổ

    Code:
    XStoreName(display, win, “ OPENGL in Linux ”);
    + Hàm này giống SetWindowText cửa WINAPI.

    2. Hiển thị cửa sổ.

    Code:
    XMapWindow(display, win);
    + Hàm này giống ShowWindow
    + Còn muốn ShowWindow(hWnd, SW_HIDE); thì XUnmapWindow (...)

    4. Sửa đổi cửa sổ
    Bao gồm các hàm:
    + XConfigureWindow (Thay đổi vị trí, kích thước, chiều cao, rộng)
    + XMoveWindow (Di chuyển cửa sổ)
    + XResizeWindow
    + XSetWindowBorderWidth
    ... Và nhiều nữa mình sẽ share link tài liệu ở cuối bài viết...

    4. Nhận sự kiện

    Code:
    XSelectInput(display, win,  ExposureMask | KeyPressMask | StructureNotifyMask);
    EventMask ở đây chỉ báo trước cho X System biết chương trình sẽ nhận những sự kiện nào gồm.

    Code:
    NoEventMask 	 	No events
    KeyPressMask 	 	Keyboard down events
    KeyReleaseMask 	 	Keyboard up events
    ButtonPressMask 	Pointer button down events
    ButtonReleaseMask 	Pointer button up events
    EnterWindowMask 	Pointer window entry events
    LeaveWindowMask 	Pointer window leave events
    PointerMotionMask 	All pointer motion events
    PointerMotionHintMask 	Fewer pointer motion events
    Button1MotionMask 	Pointer motion while button 1 down
    Button2MotionMask 	Pointer motion while button 2 down
    Button3MotionMask 	Pointer motion while button 3 down
    Button4MotionMask 	Pointer motion while button 4 down
    Button5MotionMask 	Pointer motion while button 5 down
    ButtonMotionMask 	Pointer motion while any button down
    KeymapStateMask 	Any keyboard state change on 
     	 	 	EnterNotify , 
     	 	 	LeaveNotify , 
     	 	 	FocusIn 
     	 	 	or FocusOut
    
    ExposureMask 	 	Any exposure (except GraphicsExpose and NoExpose )
    VisibilityChangeMask 	Any change in visibility
    StructureNotifyMask 	Any change in window configuration.
    ResizeRedirectMask 	Redirect resize of this window
    SubstructureNotifyMask 	Notify about reconfiguration of children
    SubstructureRedirectMask 	Redirect reconfiguration of children
    FocusChangeMask 	Any change in keyboard focus
    PropertyChangeMask 	Any change in property
    ColormapChangeMask 	Any change in colormap
    OwnerGrabButtonMask 	Modifies handling of pointer events
    Tuy nhiên nếu bạn không nhớ mấy cái vớ vẫn này thì cứ "thà giết nhàm còn hơn bỏ sót"

    Code:
    const int event_mask = ExposureMask | 
        ButtonPressMask | 
        ButtonReleaseMask |
        EnterWindowMask | 
        LeaveWindowMask |
        PointerMotionMask |
        FocusChangeMask |
        KeyPressMask |
        KeyReleaseMask |
        SubstructureNotifyMask |
        StructureNotifyMask |
        SubstructureRedirectMask;
    là gần như đầy đủ các sự kiện thường dùng về phím, chuột . Rồi sau này chúng ta sẽ switch sau.

    5. Phân tích sự kiện

    Cũng là 1 vòng lặp while () giống Win32. Người ta vẫn gọi nó là Event Loop
    Code:
    bool done = false;
    XEvent event;
    while (!done) {
      XNextEvent(display, &event);
      switch (event.type) {
      case Expose:
        cout << “Expose event received” << endl;
        break;
      case ConfigureNotify:
        cout << “ConfigureNotify event received” << endl;
        break;
      case KeyPress:
        cout << “Keypress detected” << endl;
        done = true;   // Exit on any keypress
        break;
      }
    }
    Ở đây chúng ta quan tâm tới XEvent và Event Type.
    XEvent giống như là MSG cửa Windows. Nó chứa handle cửa sổ và xác định loại message tương ứng, và các tham số đi kem tương ứng như chuột thì x,y. Key thì là UCHAR....

    Một đoạn code mình copy tổng quá hơn về phân tích event
    Code:
    bool handle_event ( XEvent& report, window_base* p )
    {
    	switch ( report.type )
    	{
    		case Expose:    // Giống On_Paint
    		{
    			p->on_expose();
    			break;
    		}
    		case ButtonPress:
    		{
    			if ( report.xbutton.button & Button2 )
    			{
    				p->on_right_button_down ( report.xbutton.x,
    						  	report.xbutton.y );
    			}
    			else if ( report.xbutton.button & Button1 )
    			{
    				p->on_left_button_down ( report.xbutton.x,
    						 report.xbutton.y );
    			}
    			break;
    		}
    		case ButtonRelease:
    		{
    			if ( report.xbutton.button & Button2 )
    			{
    				p->on_right_button_up ( report.xbutton.x,
    						report.xbutton.y );
    			}
    			else if ( report.xbutton.button & Button1 )
    			{
    				p->on_left_button_up ( report.xbutton.x,
    					       report.xbutton.y );
    			}
    			break;
    		}
    		case EnterNotify:
    		{
    			p->on_mouse_enter ( report.xcrossing.x,
    					report.xcrossing.y );
    			break;
    		}
    		case LeaveNotify:
    		{
    			p->on_mouse_exit ( report.xcrossing.x,
    				       report.xcrossing.y );
    			break;
    		}
    		case MotionNotify:
    		{
    			p->on_mouse_move ( report.xmotion.x,
    				       report.xmotion.y );
    			break;
    		}
    		case FocusIn:
    		{
    			p->on_got_focus();
    			break;
    		}
    		case FocusOut:
    		{
    			p->on_lost_focus();
    			break;
    		}
    		case KeyPress:
    		case KeyRelease:
    		{
    			char buf[11];
    			KeySym keysym;
    			XComposeStatus status;
    			int count = XLookupString ( &report.xkey,
    						buf,
    						10,
    						&keysym,
    						&status );
    
    			buf[count] = 0;
    
    			if ( report.type == KeyPress )
    			{
    			p->on_key_press ( character(keysym,
    						    buf,
    						    report.xkey.state) );
    			}
    			else
    			{
    			p->on_key_release ( character(keysym,
    						      buf,
    						      report.xkey.state) );
    			}
    			break;
    		  }
    		  
    		case DestroyNotify:
    		{
    			p->on_destroy();
    			break;
    		}
    
    		case MapNotify:
    		{
    			p->on_show();
    			break;
    		}
    		case UnmapNotify:
    		{
    			p->on_hide();
    			break;
    		}
    		case ClientMessage:
    		{
    		
    		    break;
    		}
    	}
    }
    Còn đây là một chương trình tương đối đầy đủ:

    Code:
    Listing 26.3 xwelcome.cpp
    --------------------------------------------------------------------------------
    
    #include <iostream.h>
    #include <stdlib.h>     // Need exit()
    
    #include <X11/Xlib.h>   // Most X programs need these headers
    #include <X11/Xutil.h>
    #include <X11/Xos.h>
    
    Display *display;       // X server display structure
    
    int main()
    {
      // Attempt to establish communications with the X Server
      //
      display = XOpenDisplay(NULL);
      if (display == NULL) {
        cerr << “Failure connecting to X Server”
        exit(1);
      }
    
      // Calculate window’s dimensions and position
      //
      int intScreenNum = DefaultScreen(display);
      int intDisplayWidth = DisplayWidth(display, intScreenNum);
      int intDisplayHeight = DisplayHeight(display, intScreenNum);
      int intWidth = intDisplayWidth / 3;
      int intHeight = intDisplayHeight / 8;
      int intXPos = 0;
      int intYPos = 0;
    
      // Get the most basic of colors (black and white)
      //
      int intBlackColor, intWhiteColor;
      intBlackColor = BlackPixel(display, intScreenNum);
      intWhiteColor = WhitePixel(display, intScreenNum);
    
      // Create window (this does not make it visible)
      Window win =
      XCreateSimpleWindow(
        display,                         // X server display struct
        DefaultRootWindow(display),      // Parent window
        intXPos, intYPos,                // Position
        intWidth, intHeight,             // Window width & height
        0,                               // Border width (default)
        intBlackColor, intWhiteColor);   // Background, foreground
    
      // Assign a name for the window title bar (probably)
      //
      XStoreName(display, win, “Welcome to X Programming”);
    
      // Map the window to the display
      // Window is visible when first Expose event is received
      //
      XMapWindow(display, win);
    
      // Specify the types of events we want to receive
      //
      XSelectInput(display, win,
        ExposureMask | KeyPressMask | StructureNotifyMask);
    
      // The infamous event loop
      //
      bool done = false;
      XEvent event;
      while (!done) {
        XNextEvent(display, &event);
        switch (event.type) {
        case Expose:
          cout << “Expose event received” << endl;
          break;
        case ConfigureNotify:
          cout << “ConfigureNotify event received” << endl;
          break;
        case KeyPress:
          cout << “Keypress detected” << endl;
          done = true;   // Exit on any keypress
          break;
        }
      }
    
      // Disconnect X server connection and exit.
      // (Program may never get to here)
      //
      XCloseDisplay(display);
      return 0;
    }
    Đó chỉ là 1% kiến thức thiết yếu về X Programing in Linux
    Các bạn có thể tham khảo như MSDN for XLIB ở đây

    Init OPENGL mình xin hẹn lần sau... cón tiếp...
    Đã được chỉnh sửa lần cuối bởi ZCoder87 : 09-03-2008 lúc 11:39 AM.

  3. #3
    Ngày gia nhập
    01 2008
    Nơi ở
    Gameloft Studio
    Bài viết
    294

    XLib là một thư viện dễ lập trình vì mình cảm thấy nó gần giống với windows.h.

    Hôm nay mình sẽ Init OpenGL lên trên cửa sổ XLIB mà chúng ta đã khởi tạo.

    III. Khởi động OPENGL

    OpenGL là một thư viện đồ họa 3D khá nổi tiếng hiện nay mà hầu hết các Card đồ họa đều hỗ trợ. Phiên bản mới nhất là 2.0.

    OpenGL thể hiện tính năng "Open" của mình ở nhiều hệ điều hành như Window, Linux, Mac hay cả trên Symbian, Moblie...
    Được thiết kế độc lập với hệ điều hành. Do đó nên OGL có nhiều phiên bản:
    + For Windows: WGL.
    + For Linux: XGL.
    + For MAC AGL.

    1. OGL và DX. Chúng giống và khác chỗ nào???

    - Điểm giống giữa 2 lib này là sử dụng đồ họa dựa trên phần cứng (Hardware Acceleration).

    - Tuy nhiên có 1 sự khác nhau lớn nhất giữa OGL và DX. Chính là "Direct", MS có lẽ đã đặt trên cho DX = chữ "Direct" để thể hiện sự khác biệt trên. DX sử dụng phần cứng hiệu quả hơn bởi lẽ nó tương tác trực tiếp với Hardware trong khi OGL chỉ sử dụng các API của Driver. Do đó xuất hiện 1 khuyết điểm lớn nhất của OGL là chậm hơn DX. Nhưng dĩ nhiên Silicon phải chấp nhận khuyết điểm này khi thiết kế OGL bởi vì tính năng Open của nó. OGL chỉ có khẳ năng vẽ ảnh lên Buffer. Còn đưa ra màn hình nó phải nhờ hệ điều hành (trên Windows là GDI). Tuy nhiên thì OGL cũng ko phải quá tệ so với DX.

    2. Các hàm khởi động OGL

    - Đơn giản rất nhiều so với học Linux bởi lẽ chúng ta chỉ sử dụng một số hàm:
    Code:
    + Choose appropriate visuals:
    glXChooseVisual, glXChooseFBConfig
     
    + Manage OpenGL drawing contexts:
    glXCreateContext, glXDestroyContext, glXMakeCurrent
     
    + Create OpenGL windows
    glXCreateWindow
     
    + Do double-buffered drawing
    glXSwapBuffers
     
    + Create bitmap text fonts
    glXUseXFont
     
    + Do offscreen drawing
    glXCreateGLXPixmap, glXCreatePbuffer 
    Đã được chỉnh sửa lần cuối bởi ZCoder87 : 03-11-2008 lúc 11:24 PM.

  4. #4
    Ngày gia nhập
    01 2008
    Nơi ở
    Gameloft Studio
    Bài viết
    294

    3. SetPixelFormat

    Công việc đầu tiên là thiết lập kiểu PIXEL hỗ trợ OPENGL.

    For Windows

    C++ Code:
    1. PIXELFORMATDESCRIPTOR pixelDesc = {
    2.         sizeof(PIXELFORMATDESCRIPTOR),
    3.         1,
    4.         PFD_DRAW_TO_WINDOW |        // Ve ra cua so
    5.             PFD_SUPPORT_OPENGL |    // Ho tro OpenGL
    6.             PFD_DOUBLEBUFFER,       // Che do 2 buffer
    7.             PFD_TYPE_RGBA,          // Che do màu RGBA
    8.         24,                         // 24 bit màu
    9.         0,0,0,0,0,0,                // Không su dung
    10.         0,0,0,0,0,0,0,              // Không su dung
    11.         32,                         // 32bit depth buff
    12.         0,0,                        // Không su dung
    13.         PFD_MAIN_PLANE,             // Ve trong main plane
    14.         0,0,0,0 }; 
    15.  
    16.     m_hDC = ::GetDC(m_hWnd);
    17.     int nPixel = ChoosePixelFormat(m_hDC,&pixelDesc);
    18.     SetPixelFormat(m_StaticDC, nPixel , &pixelDesc);

    For Linux:
    C++ Code:
    1. int attributes[] = {
    2.   GLX_RGBA,
    3.   GLX_DOUBLEBUFFER,
    4.   GLX_RED_SIZE, 4,
    5.   GLX_GREEN_SIZE, 4,
    6.   GLX_BLUE_SIZE, 4,
    7.   GLX_DEPTH_SIZE, 16,
    8.   0
    9. };
    10.  
    11. Display *display;
    12. XVisualInfo *vinfo;
    13. vinfo = glXChooseVisual(display, DefaultScreen(display), attributes);

    - Một số CONST Attributes for LINUX

    Code:
    GLX_ACCUM_ALPHA_SIZE
     The number that follows specifies the minimum number of alpha bits that are required in the accumulation buffer.
     
    GLX_ACCUM_BLUE_SIZE
     The number that follows specifies the minimum number of blue bits that are required in the accumulation buffer.
     
    GLX_ACCUM_GREEN_SIZE
     The number that follows specifies the minimum number of green bits that are required in the accumulation buffer.
     
    GLX_ACCUM_RED_SIZE
     The number that follows specifies the minimum number of red bits that are required in the accumulation buffer.
     
    GLX_ALPHA_SIZE
     The number that follows specifies the minimum number of alpha bits that are required.
     
    GLX_AUX_BUFFERS
     The number that follows specifies the number of auxiliary buffers that are required.
     
    GLX_BLUE_SIZE
     The number that follows specifies the minimum number of blue bits that are required.
     
    GLX_BUFFER_SIZE
     The number that follows specifies the number of color index bits that are desired.
     
    GLX_DEPTH_SIZE
     The number that follows specifies the minimum number of depth bits that are required.
     
    GLX_DOUBLEBUFFER
     This token specifies that a double-buffered visual is desired.
     
    GLX_GREEN_SIZE
     The number that follows specifies the minimum number of green bits that are required.
     
    GLX_LEVEL
     This token specifies the buffer level in the number that follows; 0 is the main buffer, 1 is the first overlay buffer, –1 is the first underlay buffer, and so forth.
     
    GLX_RED_SIZE
     The number that follows specifies the minimum number of red bits that are required.
     
    GLX_RGBA
     This token specifies that an RGBA visual is desired.
     
    GLX_STENCIL_SIZE
     The number that follows specifies the minimum number of stencil bits that are required.
     
    GLX_STEREO
     This token specifies that a stereo visual is desired; stereo visuals provide separate left and right eye images.
     
    GLX_USE_GL
     This token specifies that OpenGL visuals are desired. This attribute is ignored because glXChooseVisual() returns only OpenGL visuals.
    Tại sao ngay cả trên Window hay Linux đều phải làm việc này??? Có lẽ chính là do OGL ko thể vẽ trực tiếp lên màn hình được. Do đó chúng ta bắc buộc phải định dạng PixelFormat của Device Context hệ điều hành giống như Buffer của OGL vậy.

    Vậy PixelFormat lại là gì???
    Nhưng để giải thích PixelFormat là gì thì mình lại phải giải thích FrameBuffer trước
    Đã được chỉnh sửa lần cuối bởi ZCoder87 : 09-03-2008 lúc 01:49 PM.

  5. #5
    Ngày gia nhập
    01 2008
    Nơi ở
    Gameloft Studio
    Bài viết
    294

    a. FrameBuffer

    - FrameBuffer là một vùng nhớ nằm trên VRAM nhưng vùng nhớ này có điểm đặc biệt là mọi dữ liệu nằm trên nó sẽ thể hiện trực tiếp lên màn hình. Tất cả các thiết bị có màn hình như di động, tivi đều có FrameBuffer.



    - Cấu trúc dữ liệu của FrameBuffer y chang như file BMP. Có nghĩa là nó sẽ có Buffer 1bit, 8bit, 16bit, 24bit và 32bit...
    - Kích thước của FrameBuffer tùy thuộc vào độ phân giải và PixelFormat



    B. PixelFormat

    ChoosePixelFormat???? Có ý nghĩa gì?
    FrameBuffer chứa nhiều w x h Pixel. Mỗi Pixel đó sẽ có 1 định dạng riêng như bao nhiều BIT.
    - Nếu FrameBuffer dùng 1bit làm Pixel có nghĩa đây là ảnh MONO (chỉ có 2 màu đen và trắng)
    - Nếu FrameBuffer dùng 16bit, 24bit, 32bit thì đây đều là ảnh HighColor.

    + Với 16bit thì thông thường có 2 dạng:
    . 1bit không sử dụng (hoặc có thể làm Transparent) , còn lại 5bit R, 5bit G, 5bit B đại diện cho màu sắc.
    . Hay là 5bit R, 6bit G, 5bit B.

    + 24bit: RGB sẽ chia đều 8 bit.
    + 32bit: RGB 8bit đồng thơi sẽ có 8Bit làm giá trị Alpha (độ trong suốt của ảnh => ARGB).

    - Riêng nếu FrameBuffer 8bit thì lại khác. Nó sẽ có 1 màu bảng chứa 256 màu gọi là Palette. Mỗi Entry trong bảng này là màu sắc 32bit. Sau đó chính là nội dung của Buffer. Cứ 8bit là 1 Pixel chứa chỉ số Index màu sắc trên bảng Palette.
    Đã được chỉnh sửa lần cuối bởi ZCoder87 : 09-03-2008 lúc 01:29 PM.

  6. #6
    Ngày gia nhập
    01 2008
    Nơi ở
    Gameloft Studio
    Bài viết
    294

    Mặc định Khởi động OPENGL in Linux

    c. Double Buffering, z-Buffering, and Texture

    Khi thiết lập OpenGL. Chúng ta có làm quen thêm 1 số Buffer khác (trong const) tương tự như FrameBuff như ZBuffer (Depth), Texture,....

    Ngoài ra riêng OGL còn có những Buffer khác nữa như Stencil, Accum... để hỗ trợ thêm cho đồ họa.

    + Double Buffering: Là công nghệ 2 vùng đệm. Nó có cái tên khác là BackBuffer.
    Khi thực hiện thao tác đồ họa, tất cả chỉ làm trên 1 Memory. Khi đã hoàn chỉnh nó mới swap với FrameBuffer để đưa ra màn hình. Nhờ vậy mà khi vẽ tránh được hiện tượng bị nhấp nháy.

    + ZBuffer (thông thường 32bit) là 1 buffer đặc biệt. Dữ liệu trên nó không phải là từng Pixel mà chính là chiều sâu (theo trục Z của phép chiếu) đối tượng. Nhờ đó nó có thể giải quyết được vấn đề đối tượng nào bị khuất, không khuất...

    Trên đây là 1 ZBuffer minh họa.

    + Texture là một vùng nhớ để chứa hỉnh ảnh 2D thể hiện trên đối tượng.

    Như vậy khi ta thiết lập PixelFormat có nghĩa là sẽ thiết lập đồng bộ các Buffer như FrameBuffer, ZBuffer, Texture. Chủ yếu là FrameBuffer và BackBuffer phải giống nhau về kích thước, về pixel... điều đó để khi swap sẽ tạo sự chính xác lên màn hình.

  7. #7
    Ngày gia nhập
    01 2008
    Nơi ở
    Gameloft Studio
    Bài viết
    294

    3. OpenGL Contexts

    For Windows:
    C++ Code:
    1. HGLRC g_hRC = ::wglCreateContext ( hDC );

    For Linux:

    C++ Code:
    1. GLXContext context;
    2. context = glXCreateContext(display, vinfo, 0, True);
    3. // Tham số cuối cùng có nghĩa là "direct = true". Mình đang tự đặt rất nhiều câu hỏi chỗ này???

    Giá trị này mình cũng ko biết giải thích làm sao??? Nhưng hiểu nó là 1 handle, là một cái gì đó để OpenGL có thể xác định được mình cần vẽ ở đâu để sau này Swap với Device Context HDH.

    4. Managing OpenGL Contexts

    Những hàm của OpenGL có dạng gl...
    Ví dụ như glBegin(), glVertex....

    Nhưng những hàm này chỉ có giá trị khi chúng ta thiết lập Current Contexts là OpenGL Contexts.

    For windows:
    C++ Code:
    1. ::wglMakeCurrent ( hDC, g_hRC);
    2.  
    3. // Các hàm gl có giá trị
    4.  
    5. ::wglMakeCurrent ( 0, 0);

    For linux:

    C++ Code:
    1. ::glXMakeCurrent(display, window, context);

    5. Swap Bufer

    Một hàm rất quan trọng. Vì nếu không có hàm này thì mọi thứ vẽ ra chỉ làm trên BackBuffer. Còn màn hình thì vẫn đen thui... Bạn nào lập trình với Glut hay Aux thì có lẽ sẽ biết hàm tương tự là glFlush();

    For Windows:
    C++ Code:
    1. ::SwapBuffers( hDC );

    For Linux:
    C++ Code:
    1. ::glXSwapBuffers(display, window);

    6. Hủy OpenGL Contexts

    For Windows:
    C++ Code:
    1. ::wglDeleteContext (g_hRC);
    For Linux:
    C++ Code:
    1. ::glXDestroyContext(display, context);
    Đã được chỉnh sửa lần cuối bởi ZCoder87 : 09-03-2008 lúc 02:08 PM.

  8. #8
    Ngày gia nhập
    01 2008
    Nơi ở
    Gameloft Studio
    Bài viết
    294

    7. Chương trình mẫu (copy code từ SILICON)
    Mệt quá rùi...

    C++ Code:
    1. /*
    2.  * simplest - simple single buffered RGBA xlib program.
    3.  */
    4. /* compile: cc -o simplest simplest.c -lGL -lX11 */
    5.  
    6. #include <GL/glx.h>
    7. #include <X11/keysym.h>
    8. #include <stdlib.h>
    9. #include <stdio.h>
    10.  
    11. static int attributeList[] = { GLX_RGBA, None };
    12.  
    13. static void draw_scene(void) {
    14.     glClearColor(0.5, 0.5, 0.5, 1.0);
    15.     glClear(GL_COLOR_BUFFER_BIT);
    16.     glColor3f(1.0,0.0,0.0);
    17.     glRectf(-.5,-.5,.5,.5);
    18.     glColor3f(0.0,1.0,0.0);
    19.     glRectf(-.4,-.4,.4,.4);
    20.     glColor3f(0.0,0.0,1.0);
    21.     glRectf(-.3,-.3,.3,.3);
    22.     glFlush();
    23. }
    24.  
    25. static void process_input(Display *dpy) {
    26.     XEvent event;
    27.     Bool redraw = 0;
    28.  
    29.     do {
    30.         char buf[31];
    31.         KeySym keysym;
    32.  
    33.         XNextEvent(dpy, &event);
    34.         switch(event.type) {
    35.         case Expose:
    36.             redraw = 1;
    37.             break;
    38.         case ConfigureNotify:
    39.             glViewport(0, 0, event.xconfigure.width,
    40.                     event.xconfigure.height);
    41.             redraw = 1;
    42.             break;
    43.         case KeyPress:
    44.             (void) XLookupString(&event.xkey, buf, sizeof(buf),
    45.                     &keysym, NULL);
    46.             switch (keysym) {
    47.  
    48.             case XK_Escape:
    49.                 exit(EXIT_SUCCESS);
    50.             default:
    51.                 break;
    52.             }
    53.         default:
    54.             break;
    55.         }
    56.     } while (XPending(dpy));
    57.     if (redraw) draw_scene();
    58. }
    59.  
    60. static void error(const char *prog, const char *msg) {
    61.     fprintf(stderr, “%s: %s\n”, prog, msg);
    62.     exit(EXIT_FAILURE);
    63. }
    64.  
    65. int main(int argc, char **argv) {
    66.     Display *dpy;
    67.     XVisualInfo *vi;
    68.     XSetWindowAttributes swa;
    69.     Window win;
    70.     GLXContext cx;
    71.  
    72.     // get a connection
    73.     dpy = XOpenDisplay(0);
    74.     if (!dpy) error(argv[0], "can't open display");
    75.  
    76.     // get an appropriate visual
    77.     vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributeList);
    78.     if (!vi) error(argv[0], "no suitable visual");
    79.  
    80.     // create a GLX context
    81.     cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
    82.     // create a colormap
    83.     swa.colormap = XCreateColormap(dpy, RootWindow(dpy, vi->screen),
    84.                                    vi->visual, AllocNone);
    85.     // create a window
    86.     swa.border_pixel = 0;
    87.     swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask;
    88.     win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 300,
    89.                         300, 0, vi->depth, InputOutput, vi->visual,
    90.                         CWBorderPixel|CWColormap|CWEventMask, &swa);
    91.     XStoreName(dpy, win, "simplest");
    92.     XMapWindow(dpy, win);
    93.  
    94.     // connect the context to the window
    95.     glXMakeCurrent(dpy, win, cx);
    96.  
    97.     for(;;)
    98.         process_input(dpy);
    99. }
    Đã được chỉnh sửa lần cuối bởi ZCoder87 : 09-03-2008 lúc 02:18 PM.

  9. #9
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Sorry, thật ra r2 không muốn hỏi xen ngang thế này, nhưng có lẽ chẳng biết hỏi chỗ nào nữa T_T, có gì chắc move sau vậy. Theo Zcoder nói cái này là for Linux, vậy nó là thuộc dòng nào vậy ? Fedora, Redhat, Debian, Ubuntu, Kbuntu.... Tìm mãi không ra package :(. Nếu được mong Zcoder có thể chỉ cách makefile cho thằng OpenGL trên Linux được không ? Vì tìm mãi mà không thấy cách làm sao dịch compile cho cái X Window này hết :(. Mà thằng này r2 google thì thấy nó là system thuộc Unix, chẳng hiểu sao nữa. Zcoder giải thích dùm chỗ này được không ?
    -Mình hiện đang xài Ubuntu 7.4, khá giống với Debian. Nếu được chỉ mình phần makefile của OpenGL nhé T_T ! Thanks !

  10. #10
    Ngày gia nhập
    01 2008
    Nơi ở
    Gameloft Studio
    Bài viết
    294

    Ko có gì đâu.
    Mình quên mất vấn đề này.
    - Đã là Linux thì tất cả đều chạy được hết.
    - Lúc trước mình có xài Ubuntu nhưng giờ thì chuyển sang Redhat rồi vì Redhat là môi trường mình học quản trị.

    Bạn có thể Download Package cho Ubuntu
    - Thư viện XLIB: Click here

    - Thư viện OGL (libgl1-mesa-dev)

    Àh còn Makefile thì:
    Code:
    CC    =    @CC@
    CFLAGS    =    @CFLAGS@
    LDFLAGS    =    @LDFLAGS@
    LIBS    =    @LIBS@
    
    myprogram:    myprogram.o
        $(CC) $(LDFLAGS) -o myprogram.c myprogram.o $(LIBS)
    LIBS = @LIBS@ thêm những thư viện cần thiết vào ví dụ như:
    Code:
    LIBS    =    -lGL -lX11 @LIBS@
    Goodluck.
    Đã được chỉnh sửa lần cuối bởi ZCoder87 : 10-03-2008 lúc 08:08 PM.

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

  1. Lập trình C Lập trình Multithreading + OpenGL trong linux như thế nào?
    Gửi bởi qwadro_fx trong diễn đàn Thắc mắc lập trình C/C++ trên Linux
    Trả lời: 3
    Bài viết cuối: 22-02-2013, 10:19 AM
  2. Muốn học về Linux để phát triển theo hướng mã nguồn mở trên Linux thì phải làm những gì?
    Gửi bởi vncoder trong diễn đàn Thắc mắc lập trình C/C++ trên Linux
    Trả lời: 7
    Bài viết cuối: 06-01-2012, 07:58 AM
  3. Biên Dịch Linux Với ToolChain mips-linux-gnu- và Qemu
    Gửi bởi trần trân trong diễn đàn Thắc mắc lập trình C/C++ trên Linux
    Trả lời: 3
    Bài viết cuối: 04-01-2011, 12:18 PM
  4. Lập trình C trong linux. Cách biên dịch chương trình C trên Linux như thế nào?
    Gửi bởi thangbn trong diễn đàn Thắc mắc lập trình C/C++ trên Linux
    Trả lời: 5
    Bài viết cuối: 30-05-2009, 11:38 AM
  5. Lập trình đồ họa OpenGL | Cách hoạt động của OpenGL trong lập trình C#
    Gửi bởi dieucay555 trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 13
    Bài viết cuối: 10-12-2008, 10:05 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