Сбой wglShareLists с ошибкой 6: ERROR_INVALID_HANDLE Неверный дескриптор - PullRequest
1 голос
/ 19 апреля 2011

Я пытаюсь разделить HPBUFFERARB между двумя классами: TGLForm и TGLForm2.(Я пробовал FBO, но, имея старую версию Borland Builder 6, я не могу управлять с помощью FBO)

Моя цель - отобразить один и тот же буфер в двух окнах openGL.

Поэтому я объявил внепервый Форма этого объекта:

struct GLRenderToTexture
{
struct
{
    HDC          hdc;
    HGLRC        hGlRc;
    HPBUFFERARB  hBuffer;
    PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB;
    PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB;
    PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB;
    PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB;
    PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB;
    PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB;
    PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB;
    PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB;
    PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB;
} wgl;
unsigned int  texture;  // the texture we're going to render to
};

GLRenderToTexture  RTT;

Я инициализирую его так, чтобы иметь тот же формат пикселей, что и первая GLForm:

void __fastcall TGLForm::FormCreate(TObject *Sender)
{
    ghDC = GetDC(Handle);
    if (!bSetupPixelFormat(ghDC)) Close();
    ghRC = wglCreateContext(ghDC);
wglMakeCurrent(ghDC, ghRC);
    InitializeGL();

    int     pixelFormats;
    int     intAttrs[32] ={WGL_RED_BITS_ARB,8,WGL_GREEN_BITS_ARB,8,WGL_BLUE_BITS_ARB,8,WGL_ALPHA_BITS_ARB,8,WGL_DRAW_TO_PBUFFER_ARB, GL_TRUE,WGL_BIND_TO_TEXTURE_RGBA_ARB, GL_TRUE,WGL_SUPPORT_OPENGL_ARB,GL_TRUE,WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,WGL_DOUBLE_BUFFER_ARB,GL_FALSE,0}; // 0 terminate the list
    unsigned int numFormats = 0;
    // get an acceptable pixel format to create the PBuffer with
    if (RTT.wgl.wglChoosePixelFormatARB(ghDC, intAttrs, NULL, 1, &pixelFormats, &numFormats)==FALSE)
        AnsiString error = AnsiString().sprintf("wglChoosePixelFormatARB returned %i", GetLastError()); // GetLastError will tell us why it failed

    //Set some p-buffer attributes so that we can use this p-buffer as a 2d texture target
    const int attributes[]= {WGL_TEXTURE_FORMAT_ARB,  WGL_TEXTURE_RGBA_ARB, // p-buffer will have RBA texture format
                    WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, 0}; // Of texture target will be GL_TEXTURE_2D
    // the size of the PBuffer must be the same size as the texture
    RTT.wgl.hBuffer= RTT.wgl.wglCreatePbufferARB(ghDC, pixelFormats, ClientWidth, ClientHeight, attributes);
    RTT.wgl.hdc= RTT.wgl.wglGetPbufferDCARB(RTT.wgl.hBuffer);
    RTT.wgl.hGlRc= wglCreateContext(RTT.wgl.hdc);

wglMakeCurrent(NULL,NULL);
}

Вот мой первый DrawScene: "PaintGL () "Рисование отлично прорисовано в этой форме:

void TGLForm::DrawSceneForm1()
{
wglMakeCurrent(ghDC, ghRC);
            ClientWidth = 1920;
            ClientHeight = 1080;

    // create a texture to use as the backbuffer
    glGenTextures(1, &RTT.texture);
    glBindTexture(GL_TEXTURE_2D, RTT.texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    // make sure this is the same color format as the screen
    glTexImage2D(GL_TEXTURE_2D, 0, 4,  ClientWidth, ClientHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);


    // switch to the texture context
wglMakeCurrent(RTT.wgl.hdc, RTT.wgl.hGlRc);
    glEnable(GL_TEXTURE_2D);              // Enable Texture Mapping
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_MODULATE);

    glClear(GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glClearColor(0,0,0,1);
    glClear(GL_COLOR_BUFFER_BIT);

    glDisable(GL_TEXTURE_2D);


    // switch back to the screen context
wglMakeCurrent(ghDC, ghRC);
    wglShareLists(ghRC, RTT.wgl.hGlRc);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_MODULATE);

    glClear(GL_DEPTH_BUFFER_BIT);
    glViewport(0, 0, ClientWidth, ClientHeight);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();


wglMakeCurrent(RTT.wgl.hdc, RTT.wgl.hGlRc);
    glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, RTT.texture);
        PaintGL();
    glDisable(GL_TEXTURE_2D);


wglMakeCurrent(ghDC, ghRC);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, RTT.texture);
    RTT.wgl.wglBindTexImageARB(RTT.wgl.hBuffer, WGL_FRONT_LEFT_ARB);

    glBegin(GL_QUADS);
        glColor4ub(255,255,255,255);
        glTexCoord2f (0.0, 0.0); glVertex2f (-1.0, -1.0);
        glTexCoord2f (1.0, 0.0); glVertex2f (1.0, -1.0);
        glTexCoord2f (1.0, 1.0); glVertex2f (1.0, 1.0);
        glTexCoord2f (0.0, 1.0); glVertex2f (-1.0, 1.0);
    glEnd();

    RTT.wgl.wglReleaseTexImageARB(RTT.wgl.hBuffer, WGL_FRONT_LEFT_ARB);
    glDisable(GL_TEXTURE_2D);

glFlush();
SwapBuffers(ghDC);

wglMakeCurrent(NULL,NULL);
}

А вот и мой второй DrawScene GLForm: проблема в том, что я вижу только цветной квад, но этот КВАД не текстурирован, или текстура пуста:

void TGLForm2::DrawSceneForm2()
{
wglMakeCurrent(ghDC2, ghRC2);
    ClientWidth = 1920;
    ClientHeight = 1080;

    wglShareLists(RTT.wgl.hGlRc, ghRC2);
    if (wglShareLists(RTT.wgl.hGlRc,ghRC2) == FALSE)
        SCmsgError(AnsiString().sprintf("wglShareLists returned %i", GetLastError()));

    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_MODULATE); //ARC

    glClear(GL_DEPTH_BUFFER_BIT);
    glViewport(0, 0, ClientWidth, ClientHeight);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glEnable(GL_TEXTURE_2D);

    glBindTexture(GL_TEXTURE_2D, RTT.texture);
    RTT.wgl.wglBindTexImageARB(RTT.wgl.hBuffer, WGL_FRONT_LEFT_ARB);

    glBegin(GL_QUADS);
        glColor4ub(200,200,200,200);
        glTexCoord2f (0.0, 0.0); glVertex2f (-1.0, -1.0);
        glTexCoord2f (1.0, 0.0); glVertex2f (1.0, -1.0);
        glTexCoord2f (1.0, 1.0); glVertex2f (1.0, 1.0);
        glTexCoord2f (0.0, 1.0); glVertex2f (-1.0, 1.0);
    glEnd();

    RTT.wgl.wglReleaseTexImageARB(RTT.wgl.hBuffer, WGL_FRONT_LEFT_ARB);
    glDisable(GL_TEXTURE_2D);

    glFlush();
    SwapBuffers(ghDC);
}

=> Как я могу проверить, является ли эта текстура пустой или нет?

экспортировать ее в растровое изображение и проверить ее?

=> wglShareLists вDrawSceneForm2 возвращает ошибку с GetLastError:

Ошибка 6: ERROR_INVALID_HANDLE Неверный дескриптор.

=> Кто-то видит, что не так в этом wglShareList или в моем коде?

Ответы [ 2 ]

2 голосов
/ 19 апреля 2011

При вызове wglShareLists контекст не должен быть текущим. Желательно поделиться, прежде чем делать что-либо еще. Обмен контекстами поделится всем, что было создано после этого, просто отлично. Лучше всего создать все контексты, которыми нужно делиться при запуске. Если вы используете WGL_ARB_create_context, то вы можете даже сделать это атомарно в вызове создания.

Если вы не можете по какой-то причине (хотя, почему?), То сначала wglMakeCurrent(0,0); (вы делаете противоположное в своем коде, вы делаете контекст текущим непосредственно перед общим доступом).

1 голос
/ 16 мая 2016

У меня была похожая проблема, где:

wglShareLists возвращает 0

GetLastError () возвращает 3221684311 (0xc0070057)

Оказывается, вы не можете многое сделать с помощью hglrc2 (второй параметр передан в wglShareLists) перед вызовом wglShareLists. В моем случае я создал glUseProgram шейдер, а затем попытался использовать wglShareLists, что привело к ошибкам, показанным выше. Перемещение wglShareLists сразу после wglCreateContext (hDC) второго RC сработало. Я смог поделиться текстурами в двух контекстах.

...