Wednesday, May 25, 2011

eglWaitGL example c c++ objc java

Name

eglWaitGL - complete GL execution prior to subsequent native rendering calls

C Specification

EGLBoolean eglWaitGL(void)

Description

GL rendering calls made prior to eglWaitGL are guaranteed to be executed before native rendering calls made after eglWaitGL. The same result can be achieved using glFinish.
eglWaitGL is ignored if there is no current EGL rendering context.

Errors

EGL_FALSE is returned if eglWaitGL fails, EGL_TRUE otherwise.
EGL_BAD_NATIVE_SURFACE is generated if the surface associated with the current context has a native window or pixmap, and that window or pixmap is no longer valid.

Copyright

Copyright © 2003 Silicon Graphics, Inc.
This document is licensed under the SGI Free Software B License. For details, see http://oss.sgi.com/projects/FreeB/.

See Also

glFinish, glFlush, eglWaitNative

Example

// OpenGLES2_0_EGL_Demo.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "OpenGLES2_0_EGL_Demo.h"
#include <windows.h>
#include <commctrl.h>

#include <gles2/gl2.h>
#include <egl/egl.h>

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE            g_hInst;            // current instance
#ifdef SHELL_AYGSHELL
HWND                g_hWndMenuBar;        // menu bar handle
#else // SHELL_AYGSHELL
HWND                g_hWndCommandBar;    // command bar handle
#endif // SHELL_AYGSHELL

EGLDisplay        display;
EGLSurface        surface;
EGLContext        context;
EGLConfig         config;

NativeDisplayType g_dpy;

HWND                gHWND;

extern void AniPolkaRender();
extern int AniPolkaDemo();
extern int AniPolkaDeinit();
extern int PostProcessFBODemo();
extern void PostProcessFBORender();
extern int PostProcessFBODeinit();
extern int TeapotElementsDemo();
extern void TeapotElementsRender();
extern int TeapotElementsDeinit();


typedef int (*pfnDemoInit)(void);
typedef void (*pfnDemoRender)(void);
typedef int (*pfnDemoDeinit)(void);

typedef struct _DemoFunction {
    pfnDemoInit        pfnInit;   
    pfnDemoRender        pfnRender;
    pfnDemoDeinit    pfnDeinit;
} DemoFunction;

DemoFunction    DemoList[3] =
{
    {AniPolkaDemo, AniPolkaRender, AniPolkaDeinit},
    {PostProcessFBODemo, PostProcessFBORender, PostProcessFBODeinit},
    {TeapotElementsDemo, TeapotElementsRender, TeapotElementsDeinit}
};

int selectedDemo=0;

// Forward declarations of functions included in this code module:
ATOM            MyRegisterClass(HINSTANCE, LPTSTR);
BOOL            InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

void            initializeEGL();
void            deinitializeEGL();
void            render();

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPTSTR    lpCmdLine,
                   int       nCmdShow)
{
    MSG msg; 

    DWORD dwFrames = 0;
    DWORD dwPrevTicks = GetTickCount();
    int stats_time = 0; // Assume no statistics

    // Perform application initialization:
    if (!InitInstance(hInstance, nCmdShow))
    {
        return FALSE;
    }

    initializeEGL();
    printf("EGL Init Done!!\n");

    HACCEL hAccelTable;
    hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_OPENGLES2_0_EGL_DEMO));

    // Main message loop:
    /*
    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }*/

    DemoList[selectedDemo].pfnInit();
    for (;;)
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if (WM_QUIT == msg.message)
                break;
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            render();
            dwFrames++;
        }
        const DWORD dwTicks = GetTickCount();
        if (stats_time > 0 && dwTicks - dwPrevTicks >= (DWORD)stats_time*1000)
        {
            TCHAR szMsg[16];
            wsprintf(szMsg, TEXT("%d FPS\n"), (1000 * dwFrames) / (dwTicks - dwPrevTicks));
            OutputDebugString(szMsg);
            dwPrevTicks = GetTickCount();
            dwFrames = 0;
        }
    }

    DemoList[selectedDemo].pfnDeinit();
    deinitializeEGL();

    return (int) msg.wParam;
}

//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
{
    WNDCLASS wc;

    wc.style         = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_OPENGLES2_0_EGL_DEMO));
    wc.hCursor       = 0;
    wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName  = 0;
    wc.lpszClassName = szWindowClass;

    return RegisterClass(&wc);
}

//
//   FUNCTION: InitInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    HWND hWnd;
    TCHAR szTitle[MAX_LOADSTRING];        // title bar text
    TCHAR szWindowClass[MAX_LOADSTRING];    // main window class name

    g_hInst = hInstance; // Store instance handle in our global variable

#if defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)
    // SHInitExtraControls should be called once during your application's initialization to initialize any
    // of the device specific controls such as CAPEDIT and SIPPREF.
    SHInitExtraControls();
#endif // WIN32_PLATFORM_PSPC || WIN32_PLATFORM_WFSP

    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadString(hInstance, IDC_OPENGLES2_0_EGL_DEMO, szWindowClass, MAX_LOADSTRING);

#if defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)
    //If it is already running, then focus on the window, and exit
    hWnd = FindWindow(szWindowClass, szTitle);   
    if (hWnd)
    {
        // set focus to foremost child window
        // The "| 0x00000001" is used to bring any owned windows to the foreground and
        // activate them.
        SetForegroundWindow((HWND)((ULONG) hWnd | 0x00000001));
        return 0;
    }
#endif // WIN32_PLATFORM_PSPC || WIN32_PLATFORM_WFSP

    if (!MyRegisterClass(hInstance, szWindowClass))
    {
        return FALSE;
    }

    gHWND = hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
    /*gHWND = hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU,
        300, 200, 400, 240, NULL, NULL, hInstance, NULL);*/

    if (!hWnd)
    {
        return FALSE;
    }

#ifdef WIN32_PLATFORM_PSPC
    // When the main window is created using CW_USEDEFAULT the height of the menubar (if one
    // is created is not taken into account). So we resize the window after creating it
    // if a menubar is present
    if (g_hWndMenuBar)
    {
        RECT rc;
        RECT rcMenuBar;

        GetWindowRect(hWnd, &rc);
        GetWindowRect(g_hWndMenuBar, &rcMenuBar);
        rc.bottom -= (rcMenuBar.bottom - rcMenuBar.top);
       
        MoveWindow(hWnd, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, FALSE);
    }
#endif // WIN32_PLATFORM_PSPC

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

#ifndef SHELL_AYGSHELL
    if (g_hWndCommandBar)
    {
        CommandBar_Show(g_hWndCommandBar, TRUE);
    }
#endif // !SHELL_AYGSHELL

    return TRUE;
}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND    - process the application menu
//  WM_PAINT    - Paint the main window
//  WM_DESTROY    - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

#if defined(SHELL_AYGSHELL) && !defined(WIN32_PLATFORM_WFSP)
    static SHACTIVATEINFO s_sai;
#endif // SHELL_AYGSHELL && !WIN32_PLATFORM_WFSP
   
    switch (message)
    {
        case WM_COMMAND:
            wmId    = LOWORD(wParam);
            wmEvent = HIWORD(wParam);
            // Parse the menu selections:
            switch (wmId)
            {
                case IDM_HELP_ABOUT:
                    DialogBox(g_hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, About);
                    break;
#ifndef SHELL_AYGSHELL
                case IDM_FILE_EXIT:
                    DestroyWindow(hWnd);
                    break;
#endif // !SHELL_AYGSHELL
#ifdef WIN32_PLATFORM_PSPC
                case IDM_OK:
                    SendMessage (hWnd, WM_CLOSE, 0, 0);               
                    break;
#endif // WIN32_PLATFORM_PSPC
                default:
                    return DefWindowProc(hWnd, message, wParam, lParam);
            }
            break;
        case WM_CREATE:
#ifndef SHELL_AYGSHELL
            g_hWndCommandBar = CommandBar_Create(g_hInst, hWnd, 1);
            CommandBar_InsertMenubar(g_hWndCommandBar, g_hInst, IDR_MENU, 0);
            CommandBar_AddAdornments(g_hWndCommandBar, 0, 0);
#endif // !SHELL_AYGSHELL
#ifdef SHELL_AYGSHELL
            SHMENUBARINFO mbi;

            memset(&mbi, 0, sizeof(SHMENUBARINFO));
            mbi.cbSize     = sizeof(SHMENUBARINFO);
            mbi.hwndParent = hWnd;
            mbi.nToolBarId = IDR_MENU;
            mbi.hInstRes   = g_hInst;

            if (!SHCreateMenuBar(&mbi))
            {
                g_hWndMenuBar = NULL;
            }
            else
            {
                g_hWndMenuBar = mbi.hwndMB;
            }

            // Initialize the shell activate info structure
            memset(&s_sai, 0, sizeof (s_sai));
            s_sai.cbSize = sizeof (s_sai);
#endif // SHELL_AYGSHELL
            break;
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
           
            // TODO: Add any drawing code here...
           
            EndPaint(hWnd, &ps);
            break;
        case WM_DESTROY:
#ifndef SHELL_AYGSHELL
            CommandBar_Destroy(g_hWndCommandBar);
#endif // !SHELL_AYGSHELL
#ifdef SHELL_AYGSHELL
            CommandBar_Destroy(g_hWndMenuBar);
#endif // SHELL_AYGSHELL
            PostQuitMessage(0);
            break;

#if defined(SHELL_AYGSHELL) && !defined(WIN32_PLATFORM_WFSP)
        case WM_ACTIVATE:
            // Notify shell of our activate message
            SHHandleWMActivate(hWnd, wParam, lParam, &s_sai, FALSE);
            break;
        case WM_SETTINGCHANGE:
            SHHandleWMSettingChange(hWnd, wParam, lParam, &s_sai);
            break;
#endif // SHELL_AYGSHELL && !WIN32_PLATFORM_WFSP

        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_INITDIALOG:
#ifndef SHELL_AYGSHELL
            RECT rectChild, rectParent;
            int DlgWidth, DlgHeight;    // dialog width and height in pixel units
            int NewPosX, NewPosY;

            // trying to center the About dialog
            if (GetWindowRect(hDlg, &rectChild))
            {
                GetClientRect(GetParent(hDlg), &rectParent);
                DlgWidth    = rectChild.right - rectChild.left;
                DlgHeight    = rectChild.bottom - rectChild.top ;
                NewPosX        = (rectParent.right - rectParent.left - DlgWidth) / 2;
                NewPosY        = (rectParent.bottom - rectParent.top - DlgHeight) / 2;
               
                // if the About box is larger than the physical screen
                if (NewPosX < 0) NewPosX = 0;
                if (NewPosY < 0) NewPosY = 0;
                SetWindowPos(hDlg, 0, NewPosX, NewPosY,
                    0, 0, SWP_NOZORDER | SWP_NOSIZE);
            }
#endif // !SHELL_AYGSHELL
#ifdef SHELL_AYGSHELL
            {
                // Create a Done button and size it. 
                SHINITDLGINFO shidi;
                shidi.dwMask = SHIDIM_FLAGS;
                shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN | SHIDIF_EMPTYMENU;
                shidi.hDlg = hDlg;
                SHInitDialog(&shidi);
            }
#endif // SHELL_AYGSHELL

            return (INT_PTR)TRUE;

        case WM_COMMAND:
#ifndef SHELL_AYGSHELL
            if ((LOWORD(wParam) == IDOK) || (LOWORD(wParam) == IDCANCEL))
#endif // !SHELL_AYGSHELL
#ifdef SHELL_AYGSHELL
            if (LOWORD(wParam) == IDOK)
#endif
            {
                EndDialog(hDlg, LOWORD(wParam));
                return (INT_PTR)TRUE;
            }
            break;

        case WM_CLOSE:
            EndDialog(hDlg, message);
            return (INT_PTR)TRUE;

    }
    return (INT_PTR)FALSE;
}


void            initializeEGL()
{
    EGLint config_list[] = {
        EGL_RED_SIZE,       5,
        EGL_GREEN_SIZE,     6,
        EGL_BLUE_SIZE,      5,
#if defined(OPENGLES_TEST)       
        EGL_DEPTH_SIZE,     24,
#endif       
        EGL_NONE
    };

    EGLint num_config;

   
    g_dpy = GetDC(gHWND);

    display = eglGetDisplay(g_dpy);

    if (eglInitialize(display, NULL, NULL) == EGL_FALSE || eglGetError() != EGL_SUCCESS)
    {
        printf("eglInitialize Error!\r\n");
        return;
    }

    eglChooseConfig(display, config_list, &config, 1, &num_config);

    eglBindAPI(EGL_OPENGL_ES_API);

    surface = eglCreateWindowSurface( display, config, (NativeWindowType)(gHWND) , NULL);
    if ( surface == EGL_NO_SURFACE || eglGetError() != EGL_SUCCESS )
    {
        printf("eglCreateWindowSurface Error!\r\n");
        return ;
    }

    context = eglCreateContext( display, config, NULL,  NULL );
    if ( context == EGL_NO_CONTEXT || eglGetError() != EGL_SUCCESS )
    {
        printf("eglCreateContext Error!\r\n");
        return ;
    }

    if ( eglMakeCurrent( display, surface, surface, context ) == EGL_FALSE || eglGetError() != EGL_SUCCESS )
    {
        printf("eglMakeCurrent Error!\r\n");
        return;
    }

}


void    deinitializeEGL()
{
    eglMakeCurrent   (display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    eglDestroySurface(display, surface);
    eglDestroyContext(display, context);
    eglTerminate(display);
    ReleaseDC(gHWND, (HDC)g_dpy);
}

void render()
{
    HDC         memdc;
    HBITMAP     bitmap;   
    RECT          rect;
    int width, height;
#if 0

    GetClientRect( gHWND, &rect );
   
    width  = rect.right - rect.left;
    height = rect.bottom - rect.top;

    bitmap = CreateCompatibleBitmap((HDC)display, width, height);
#endif

    DemoList[selectedDemo].pfnRender();

//    glFlush ();

    eglSwapBuffers(display, surface);

#if 0

    glClearColor( 1.0f, 0.0f, 0.0f, 1.0f );        // Red
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
   
    eglSwapBuffers(display, surface);
    
    glClearColor( 0.0f, 1.0f, 0.0f, 1.0f );        // Green
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    eglSwapBuffers(display, surface);

     glFinish();
     eglWaitGL();
     eglCopyBuffers( display, surface, bitmap ); // Get Red Buffer

     /*
    glClearColor( 0.0f, 1.0f, 0.0f, 1.0f );      // Green
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
     glFinish();
     eglWaitGL();
     eglCopyBuffers( display, surface, bitmap );  // Still Get Red Buffer, not Green Buffer    
     */




    //eglCopyBuffers(display, surface, bitmap);

    memdc  = CreateCompatibleDC( (HDC)display );
    SelectObject( memdc, bitmap );
   
    BitBlt( (HDC)display, 0, 0, width, height, memdc, 0, 0, SRCCOPY );
#endif
//    printf("[%d] demo eglSwapBuffers Done\n", selectedDemo);
    if (EGL_SUCCESS != eglGetError())
    {
        RETAILMSG(1, (TEXT("eglSwapBuffers error: %x\r\n"), eglGetError()));
    }

    DeleteDC( memdc );      
    DeleteObject( bitmap );
}