2011-04-19 94 views
1

我嘗試在兩個類之間共享HPBUFFERARB:TGLForm和TGLForm2。 (我試過FBO,但有一個老的Borland Builder 6版本無法使用FBO進行管理)wglShareLists失敗,錯誤6:ERROR_INVALID_HANDLE句柄無效

我的目標是在兩個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; 

我intialize它以具有相同的像素格式爲第一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); 
} 

而這裏是我的s的Econd GLForm的drawScene函數:問題是,我只看到了彩色四但這QUAD沒有紋理,或質地空:

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

當調用wglShareLists時,上下文肯定不是是最新的。在做其他事情之前,先分享一下。共享上下文將共享以後創建的任何內容。最好的辦法是創建所有需要在啓動時共享的上下文。如果您使用WGL_ARB_create_context,那麼您甚至可以在創建調用中以原子方式執行此操作。

如果因爲某些原因(但是,爲什麼?)不能(因爲?),那麼首先需要wglMakeCurrent(0,0);(在代碼中做相反的處理,在共享之前使上下文保持最新狀態)。

+0

確定,所以I(由Borland函數創建窗口時)移動wglsharelists到 「FORMCREATE」 這樣: RTT.wgl.hBuffer = RTT.wgl.wglCreatePbufferARB(GHDC,的PixelFormats,ClientWidth,ClientHeight,屬性); RTT.wgl.hdc = RTT.wgl.wglGetPbufferDCARB(RTT.wgl.hBuffer); RTT.wgl.hGlRc = wglCreateContext(RTT.wgl。HDC); wglMakeCurrent(NULL,NULL); (wglShareLists(ghRC,RTT.wgl.hGlRc)== FALSE) \t SCmsgError(AnsiString()。sprintf(「wglShareLists returned%i」,GetLastError())); 但現在我對我在第二個窗口調用wglSharelists的 「錯誤6」(第2 Borland的文件) – Arnaud 2011-04-21 14:00:45

+0

無效__fastcall TGLForm2 :: FORMCREATE(TObject中*發件人) \t { \t \t如果(!bSetupPixelFormat(GHDC) ) 關(); \t \t ghRC = wglCreateContext(ghDC); \t wglMakeCurrent(ghDC,ghRC); \t wglMakeCurrent(NULL,NULL); \t \t如果(wglShareLists(GHRC,RTT.wgl.hGlRc)== FALSE) \t \t \t SCmsgError(AnsiString類型()的sprintf( 「wglShareLists 2返回%i」 的,GetLastError函數())。); // GetLastError會告訴我們爲什麼失敗 \t wglMakeCurrent(ghDC,ghRC); \t \t InitializeGL(); \t} – Arnaud 2011-04-21 14:24:54

+0

在上面的第二個窗口中,我想我在wglShareLists上有這個錯誤6,因爲第二個窗口的ghDC與RTT.wgl.hDC的像素格式不一樣,但我不知道如何設置這個ghDC像素格式轉換爲相同的格式,所有這些ghDC設置爲Borland面板的GetHandle(PanelPreview):句柄。如何將ghDC的像素格式設置爲與RTT.wgl.hDC相同的格式? – Arnaud 2011-04-21 14:25:40

1

我也有類似的問題,即:

wglShareLists返回0

GetLastError()返回3221684311(0xc0070057)

事實證明,你不能做太多與hglrc2(第二個參數傳遞到wglShareLists ),然後再調用wglShareLists。在我的情況下,我創建了,並glUseProgram着色器,然後嘗試wglShareLists導致上面顯示的錯誤。將第二個RC的wglCreateContext(hDC)工作後,立即將wglShareLists移動。我能夠在兩種情況下分享紋理。

相關問題