Hallo Mesa Developers,

I'm trying to make run a little test program with Mesa.
It runs smoothly with the Windows OpenGL system driver.

But I have problems implementing wglShareLists,
because I don't know much about the inner structures of Mesa.

I saw there is already a function _mesa_share_state.
But if I call it from wglShareLists, I get crashes when resizing my window.

Which structures must be safe-guarded with Mutexes to make it more stable?

Greetings,
Andreas


This is my test program:
//_______________________________________________________________________

#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <GL/gl.h>

HWND hWnd=0;
HDC hDC=0;
RECT rect;
BOOL done=FALSE;

HANDLE hThread=0;
DWORD iThread=0;
DWORD id=0;
int count=0, sizeNow=0;

HGLRC g_hRC=0;


float rnd()
{
    return float(rand())/RAND_MAX;
}

void mySwapBuffers()
{
    glReadBuffer(GL_BACK);
    glDrawBuffer(GL_FRONT);

    GLboolean isat, isblend, isclop, iscm, isdi, isdt, isfog,
        islop, isps, islight, istex;

    glGetBooleanv(GL_ALPHA_TEST, &isat);
    glGetBooleanv(GL_BLEND, &isblend);
    glGetBooleanv(GL_COLOR_LOGIC_OP, &isclop);
    glGetBooleanv(GL_COLOR_MATERIAL, &iscm);
    glGetBooleanv(GL_DEPTH_TEST, &isdt);
    glGetBooleanv(GL_DITHER, &isdi);
    glGetBooleanv(GL_FOG, &isfog);
    glGetBooleanv(GL_LIGHTING, &islight);
    glGetBooleanv(GL_LOGIC_OP, &islop);
    glGetBooleanv(GL_POINT_SMOOTH, &isps);
    glGetBooleanv(GL_TEXTURE_2D, &istex);

    glDisable(GL_ALPHA_TEST);
    glDisable(GL_BLEND);
    glDisable(GL_COLOR_LOGIC_OP);
    glDisable(GL_COLOR_MATERIAL);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_DITHER);
    glDisable(GL_FOG);
    glDisable(GL_LIGHTING);
    glDisable(GL_LOGIC_OP);
    glDisable(GL_POINT_SMOOTH);
    glDisable(GL_TEXTURE_2D);
    glLogicOp(GL_COPY);

    int mm;
    glGetIntegerv(GL_MATRIX_MODE, &mm);
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    glCopyPixels(0,0,rect.right-rect.left, rect.bottom-rect.top, GL_COLOR);
    glPopMatrix();
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(mm);

    if (isat)
        glEnable(GL_ALPHA_TEST);
    if (isblend)
        glEnable(GL_BLEND);
    if (isclop)
        glEnable(GL_COLOR_LOGIC_OP);
    if (iscm)
        glEnable(GL_COLOR_MATERIAL);
    if (isdt)
        glEnable(GL_DEPTH_TEST);
    if (isdi)
        glEnable(GL_DITHER);
    if (isfog)
        glEnable(GL_FOG);
    if (islight)
        glEnable(GL_LIGHTING);
    if (islop)
        glEnable(GL_LOGIC_OP);
    if (isps)
        glEnable(GL_POINT_SMOOTH);
    if (istex)
        glEnable(GL_TEXTURE_2D);

    glDrawBuffer (GL_BACK);
    glFinish();
}

void clear(int nr)
{
    int count2=count-1;
    glColor4f(0.0f, float(count2-(nr-1))/count2, float(nr-1)/count2, 1.0f);
    glBegin(GL_QUADS);
    glVertex3f((nr-2)*2.0f/count2-1, 1,0);
    glVertex3f((nr-1)*2.0f/count2-1, 1,0);
    glVertex3f((nr-1)*2.0f/count2-1,-1,0);
    glVertex3f((nr-2)*2.0f/count2-1,-1,0);
    glEnd();
}

void drawSomeLines(int nr)
{
    int count2=count-1;
    float c=rnd();
    glColor4f(c*(nr-1)/count2, 0.0f, c*(count2-(nr-1))/count2, 1.0f);
    glBegin(GL_LINES);
    glVertex3f((rnd()+nr-2)*2/count2-1,rnd()*2-1,0);
    glVertex3f((rnd()+nr-2)*2/count2-1,rnd()*2-1,0);
    glEnd();
}

/* Creates a GL context attached to the window owned
   by the other thread and paints the client area blue */

DWORD WINAPI GLThread(LPVOID lpParams)
{
   PIXELFORMATDESCRIPTOR pfd = {0};
   hDC = GetDC(hWnd);
   HGLRC hRC = 0;

    count++;
    int threadNr=count;

   /* Set absolute minimum format attributes; i.e. select default mode */
   pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
   pfd.nVersion = 1;
   pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
   pfd.iPixelType = PFD_TYPE_RGBA;

   SetPixelFormat(hDC, ChoosePixelFormat(hDC, &pfd), &pfd);

   hRC = wglCreateContext(hDC);
   wglMakeCurrent(hDC, hRC);
    if (!g_hRC)
    {    g_hRC=hRC;
        glClear(GL_COLOR_BUFFER_BIT);
        mySwapBuffers();
    }else
        wglShareLists(hRC, g_hRC);

    glReadBuffer(GL_BACK);
    glDrawBuffer(GL_BACK);
    GetClientRect(hWnd, &rect);

    while (!done)
    {
        if (!sizeNow)
        {    for (int i=0; i<100; i++)
                drawSomeLines(threadNr);
            glFinish();
        }
        Sleep(0);

        if (sizeNow==threadNr)
        {    glViewport(0,0, rect.right-rect.left, rect.bottom-rect.top);
            clear(threadNr);
            sizeNow--;
        }
    }
    return 0;
}

DWORD WINAPI GLUpdateThread(LPVOID lpParams)
{
   PIXELFORMATDESCRIPTOR pfd = {0};
   hDC = GetDC(hWnd);
   HGLRC hRC = 0;

    count++;
    int threadNr=count;

   /* Set absolute minimum format attributes; i.e. select default mode */
   pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
   pfd.nVersion = 1;
   pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
   pfd.iPixelType = PFD_TYPE_RGBA;

   SetPixelFormat(hDC, ChoosePixelFormat(hDC, &pfd), &pfd);

   hRC = wglCreateContext(hDC);
   wglMakeCurrent(hDC, hRC);
    if (!g_hRC)
    {    g_hRC=hRC;
        glClear(GL_COLOR_BUFFER_BIT);
        mySwapBuffers();
    }else
        wglShareLists(hRC, g_hRC);

    GetClientRect(hWnd, &rect);

    while (!done)
    {    if (!sizeNow)
        {    Sleep(20);
            mySwapBuffers();
        }
        Sleep(0);
        if (sizeNow==threadNr)
        {    glViewport(0,0, rect.right-rect.left, rect.bottom-rect.top);
            sizeNow--;
        }
    }
    return 0;
}

LRESULT CALLBACK WinProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
    switch (Msg)
    {
        case WM_PAINT:
        case WM_ERASEBKGND:
            return 0;
        case WM_SIZE:
            GetClientRect(hWnd, &rect);
//            while (sizeNow)
//                Sleep(0);
            sizeNow=count;
            break;
        case WM_CHAR:
            switch (wParam)
            {
            case ' ':
                hThread=CreateThread(0, 0, GLThread, 0, iThread, &id);
                Sleep(100);
                sizeNow=count;
                break;
            case 'F':

                break;
            default:
                done=true;
            }
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
    }

    return DefWindowProc(hWnd, Msg, wParam, lParam);
}

INT WINAPI WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR lpCmdLine,
                         INT nShowCmd)
{
    WNDCLASSEX wcx = {0};
    DWORD wait = 0;
    MSG msg = {0};

    wcx.cbSize = sizeof(WNDCLASSEX);
    wcx.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
    wcx.lpfnWndProc = WinProc;
    wcx.hInstance = hInstance;
    wcx.lpszClassName = L"MTGL";
    wcx.hbrBackground = NULL;

    RegisterClassEx(&wcx);
    hWnd = CreateWindowEx(WS_EX_APPWINDOW, wcx.lpszClassName,
L"testMTOpenGL",
        WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
        0, 0,
        320,240,
//        800,600,
        0, 0, hInstance, 0);
    ShowWindow(hWnd, nShowCmd);

    hThread=CreateThread(0, 0, GLUpdateThread, 0, iThread, &id);
    Sleep(100);
    sizeNow=count;

    hThread=CreateThread(0, 0, GLThread, 0, iThread, &id);

    while (!done)
    {    if (GetMessage(&msg, hWnd, 0, 0) > 0)
        {    TranslateMessage(&msg);
            DispatchMessage(&msg);
        }else
            done=true;
    }
    return (INT)msg.wParam;
}
//_______________________________________________________________________




-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Mesa3d-dev mailing list
Mesa3d-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to