Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[OpenGL, WinAPI, C++] OpenGL i WinAPI w jednym programie z dwoma oknami

Ostatnio zmodyfikowano 2015-08-10 14:47
Autor Wiadomość
Cansisti
Temat założony przez niniejszego użytkownika
» 2015-08-09 20:35:03
W jednym oknie nie byłoby źle, ale trzeba by użyć tego kontekstu a ja na razie umiem tylko zainicjować okno GLUT i przekazać mu funkcje renderujace, zmiany rozmiaru okna itp.
Pomysł z wątkiem jest niezły o tyle że nie musiałbym się martwić o zatrzymywanie glutmainloop()
P-135946
Cansisti
Temat założony przez niniejszego użytkownika
» 2015-08-09 21:06:45
Niestety próba utworzenia okna GLUT w wątku skończyła się tak: :)

C:\Cpp\_LIBS\freeglut\lib\libfreeglut_static.a(freeglut_init.o):freeglut_init.c|| undefined reference to `_imp__GetDeviceCaps@8'|
C:\Cpp\_LIBS\freeglut\lib\libfreeglut_static.a(freeglut_init.o):freeglut_init.c|| undefined reference to `_imp__CreateDCA@16'|
C:\Cpp\_LIBS\freeglut\lib\libfreeglut_static.a(freeglut_init.o):freeglut_init.c|| undefined reference to `_imp__DeleteDC@4'|
C:\Cpp\_LIBS\freeglut\lib\libfreeglut_static.a(freeglut_window.o):freeglut_window.c|| undefined reference to `_imp__GetDeviceCaps@8'|
C:\Cpp\_LIBS\freeglut\lib\libfreeglut_static.a(freeglut_window.o):freeglut_window.c|| undefined reference to `_imp__ChoosePixelFormat@8'|
C:\Cpp\_LIBS\freeglut\lib\libfreeglut_static.a(freeglut_window.o):freeglut_window.c|| undefined reference to `_imp__DeleteDC@4'|
C:\Cpp\_LIBS\freeglut\lib\libfreeglut_static.a(freeglut_window.o):freeglut_window.c|| undefined reference to `_imp__SetPixelFormat@12'|
C:\Cpp\_LIBS\freeglut\lib\libfreeglut_static.a(freeglut_window.o):freeglut_window.c|| undefined reference to `_imp__CreateDCA@16'|
C:\Cpp\_LIBS\freeglut\lib\libfreeglut_static.a(freeglut_window.o):freeglut_window.c|| undefined reference to `_imp__SetPixelFormat@12'|
C:\Cpp\_LIBS\freeglut\lib\libfreeglut_static.a(freeglut_display.o):freeglut_display.c|| undefined reference to `_imp__SwapBuffers@4'|
C:\Cpp\_LIBS\freeglut\lib\libfreeglut_static.a(freeglut_state.o):freeglut_state.c|| undefined reference to `_imp__GetPixelFormat@4'|
||=== Build finished: 11 errors, 0 warnings (0 minutes, 2 seconds) ===|

Zostawiłem ścieżki w logu żeby było widać że to nie moje pliki zgłaszają błędy...
P-135952
pekfos
» 2015-08-09 21:32:45
Niestety próba utworzenia okna GLUT w wątku skończyła się tak: :)
Na moje oko, to tu żadnej próby nie było, bo program nie został wygenerowany. Nie linkujesz gdzieś gdi32. Taką informację można znaleźć w google w 5 sekund.
P-135963
Monika90
» 2015-08-09 21:42:16
Powinno się to dać zrobić bez wątku, komunikaty Windows można obsługiwać w którymś z callbacków gluta (może glutIdleFunc?), używając nieblokującej funkcji, czyli PeekMessage.

Zresztą to nawet nie musi być potrzebne, bo być może glut sam roześle komunikaty do odpowiednich okien, (sprawdź w kodzie źródłowym gluta).
P-135967
Cansisti
Temat założony przez niniejszego użytkownika
» 2015-08-09 23:02:09
Hmm, glutIdleFunc() może zadziałać. Udało mi się utworzyć kolejne okno za pomocą glutCreateWindow() (Nie spodziewałem się że obsłuży dwa okna, a okazuje się że ma nawet mechanizm przełączania się między oknami)
Dzięki wszystkim za pomoc, popróbuję wspomagając się manual'em gluta i może coś się uda :)
(Nie wiedziałem że glut tyle może, tak bym od razu sięgnął po manual)
P-135972
Kaikso
» 2015-08-10 00:38:26
Nie spodziewałem się że obsłuży dwa okna, a okazuje się że ma nawet mechanizm przełączania się między oknami
Tak jak myślałem. Całość działa dlatego że FreeGLUT na Windows-a jest napisany własnie w WinAPI (sprawdzałem w kodzie źródłowym) i to WinAPI zajmuje się kontrolą pętli i zdarzeń które przekazuje do FreeGLUT.

Funkcja która tworzy okno w FreeGLUT na Windowsie:

C/C++
void fgPlatformOpenWindow( SFG_Window * window, const char * title,
GLboolean positionUse, int x, int y,
GLboolean sizeUse, int w, int h,
GLboolean gameMode, GLboolean isSubWindow )
{
   
    WNDCLASS wc;
    DWORD flags = 0;
    DWORD exFlags = 0;
    BOOL atom;
   
    /* Grab the window class we have registered on glutInit(): */
    atom = GetClassInfo( fgDisplay.pDisplay.Instance, _T( "FREEGLUT" ), & wc );
    FREEGLUT_INTERNAL_ERROR_EXIT( atom, "Window Class Info Not Found",
    "fgOpenWindow" );
   
    /* Determine window style flags*/
    if( gameMode )
    {
        FREEGLUT_INTERNAL_ERROR_EXIT( window->Parent == NULL,
        "Game mode being invoked on a subwindow",
        "fgOpenWindow" );
       
        /*
                 * Set the window creation flags appropriately to make the window
                 * entirely visible:
                 */
        flags = WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE;
    }
    else
    {
        flags = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
       
        /*
                 * There's a small difference between creating the top, child and
                 * menu windows
                 */
        if( window->IsMenu )
        {
            flags |= WS_POPUP;
            exFlags |= WS_EX_TOOLWINDOW;
        }
        #if defined(_WIN32_WCE)
        /* no decorations for windows CE */
        #else
        /* if this is not a subwindow (child), set its style based on the requested window decorations */
        else if( window->Parent == NULL )
             fghGetDefaultWindowStyle( & flags );
       
        #endif
        else
        /* subwindows always have no decoration, but are marked as a child window to the OS */
             flags |= WS_CHILD;
       
    }
   
    /* determine window size and position */
    if( gameMode )
    {
        /* if in gamemode, query the origin of specified by the -display
                 * command line parameter (if any) and offset the upper-left corner
                 * of the window so we create the window on that screen.
                 * The -display argument doesn't do anything if not trying to enter
                 * gamemode.
                 */
        int xoff = 0, yoff = 0;
        get_display_origin( & xoff, & yoff );
        x += xoff;
        y += yoff;
    }
    if( !positionUse )
    {
        x = CW_USEDEFAULT;
        y = CW_USEDEFAULT;
    }
    if( !sizeUse )
    {
        w = CW_USEDEFAULT;
        h = CW_USEDEFAULT;
    }
    #if !defined(_WIN32_WCE)    /* no decorations for windows CE, so nothing to do */
    else
    {
        RECT windowRect;
        /*
                 * Update the window dimensions, taking the window decorations
                 * into account.  FreeGLUT is to create the window with the
                 * topleft outside corner at (x,y) and with client area
                 * dimensions (w,h).
                 * note: don't need to do this when w=h=CW_USEDEFAULT, so in the
                 * if( sizeUse ) here is convenient.
                 */
        windowRect.left = x;
        windowRect.top = y;
        windowRect.right = x + w;
        windowRect.bottom = y + h;
       
        fghComputeWindowRectFromClientArea_UseStyle( & windowRect, flags, exFlags, TRUE );
       
        /* NB: w and h are now width and height of window including non-client area! */
        w = windowRect.right - windowRect.left;
        h = windowRect.bottom - windowRect.top;
    }
    #endif /* !defined(_WIN32_WCE) */
   
    #if defined(_WIN32_WCE)
    {
        wchar_t * wstr = fghWstrFromStr( title );
       
        window->Window.Handle = CreateWindow(
        _T( "FREEGLUT" ),
        wstr,
        WS_VISIBLE | WS_POPUP,
        0, 0, 240, 320,
        NULL,
        NULL,
        fgDisplay.pDisplay.Instance,
        ( LPVOID ) window
        );
       
        free( wstr );
       
        SHFullScreen( window->Window.Handle, SHFS_HIDESTARTICON );
        SHFullScreen( window->Window.Handle, SHFS_HIDESIPBUTTON );
        SHFullScreen( window->Window.Handle, SHFS_HIDETASKBAR );
        MoveWindow( window->Window.Handle, 0, 0, 240, 320, TRUE );
        ShowWindow( window->Window.Handle, SW_SHOW );
        UpdateWindow( window->Window.Handle );
    }
    #else
    window->Window.Handle = CreateWindowEx(
    exFlags,
    _T( "FREEGLUT" ),
    title,
    flags,
    x, y, w, h,
    ( HWND ) window->Parent == NULL ? NULL
        : window->Parent->Window.Handle
         ,( HMENU ) NULL
         , fgDisplay.pDisplay.Instance
         ,( LPVOID ) window );
    #endif /* defined(_WIN32_WCE) */
   
    /* WM_CREATE message got sent and was handled by window proc */
   
    if( !( window->Window.Handle ) )
         fgError( "Failed to create a window (%s)!", title );
   
    /* Store title */
    window->State.pWState.WindowTitle = strdup( title );
   
    #if !defined(_WIN32_WCE)
    /* Need to set requested style again, apparently Windows doesn't listen when requesting windows without title bar or borders */
    SetWindowLong( window->Window.Handle, GWL_STYLE, flags );
    SetWindowPos( window->Window.Handle, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED );
    #endif /* defined(_WIN32_WCE) */
   
    /* Make a menu window always on top - fix Feature Request 947118 */
    if( window->IsMenu || gameMode )
    SetWindowPos(
    window->Window.Handle,
    HWND_TOPMOST,
    0, 0, 0, 0,
    SWP_NOMOVE | SWP_NOSIZE
         );
   
    /* Enable multitouch: additional flag TWF_FINETOUCH, TWF_WANTPALM */
    #ifdef WM_TOUCH
    if( fghRegisterTouchWindow ==( pRegisterTouchWindow ) 0xDEADBEEF )
         fghRegisterTouchWindow =( pRegisterTouchWindow ) GetProcAddress( GetModuleHandle( "user32" ), "RegisterTouchWindow" );
   
    if( fghRegisterTouchWindow )
         fghRegisterTouchWindow( window->Window.Handle, TWF_FINETOUCH | TWF_WANTPALM );
   
    #endif
   
    #if defined(_WIN32_WCE)
    ShowWindow( window->Window.Handle, SW_SHOW );
    #else
    if( !window->IsMenu ) /* Don't show window after creation if its a menu */
    {
        BOOL iconic = fgState.ForceIconic && !gameMode && !isSubWindow;
        ShowWindow( window->Window.Handle,
        iconic ? SW_SHOWMINIMIZED: SW_SHOWNORMAL );
    }
    #endif /* defined(_WIN32_WCE) */
   
    ShowCursor( TRUE );
}

Funkcja glutCreateWindow zwraca wskaźnik na SFG_Window, a to możesz wykorzystać do większej kontroli nad oknem.

SFG_Window:
C/C++
struct tagSFG_Window
{
    SFG_Node Node;
    int ID; /* Window's ID number        */
   
    SFG_Context Window; /* Window and OpenGL context */
    SFG_WindowState State; /* The window state          */
    SFG_Proc CallBacks[ TOTAL_CALLBACKS ]; /* Array of window callbacks */
    void * UserData; /* For use by user           */
   
    SFG_Menu * Menu[ FREEGLUT_MAX_MENUS ]; /* Menus appended to window  */
    SFG_Menu * ActiveMenu; /* The window's active menu  */
   
    SFG_Window * Parent; /* The parent to this window */
    SFG_List Children; /* The subwindows d.l. list  */
   
    GLboolean IsMenu; /* Set to 1 if we are a menu */
};

SFG_Context:
C/C++
struct tagSFG_Context
{
    SFG_WindowHandleType Handle; /* The window's handle                 */
    SFG_WindowContextType Context; /* The window's OpenGL/WGL context     */
   
    SFG_PlatformContext pContext; /* The window's FBConfig (X11) or device context (Windows) */
   
    int DoubleBuffered; /* Treat the window as double-buffered */
   
    /* When drawing geometry to vertex attribute buffers, user specifies
         * the attribute indices for vertices, normals and/or texture coords
         * to freeglut. Those are stored here
         */
    GLint attribute_v_coord;
    GLint attribute_v_normal;
    GLint attribute_v_texture;
};

A SFG_WindowHandlType to
typedef HWND SFG_WindowHandleType;

Czyli wszystko co ci potrzebne do kontroli okna FreeGLUT przez interfejs WinAPI.
P-135975
Cansisti
Temat założony przez niniejszego użytkownika
» 2015-08-10 14:47:38
A masz może pomysł jak napisać funkcję zwrotną dla glutIdleFunc() tak żeby odbierała komunikaty od kontrolek? (np. naciśnięcie przycisku)

EDIT: Widzę że post został oznaczony jako rozwiązany więc tworzę nowy
P-135996
1 « 2 »
Poprzednia strona Strona 2 z 2