2012-05-25 218 views
5

我希望能夠在OpenGL上渲染紋理,所以我可以在任何時候進一步使用它,而無需再次渲染。這個網站here給了我這樣做的指導,而不使用FrameBuffer。由於兼容性問題,我不想使用FrameBuffer對象,因爲這臺舊機器不支持它。我做了一些代碼,它創建了我的紋理,渲染了我的場景,然後創建了一個Quad來渲染紋理。唯一的問題是,紋理被渲染爲「Alpha蒙版」,這意味着,看起來它只考慮Alpha值,保持我的矩形總是具有相同的顏色,但只是改變像素的透明度。下面是一些代碼,我這樣做的遠:OpenGL - 渲染成紋理

void CreateTexture() 
{ 
    xSize = 512; 
    ySize = 512; //size of texture 
//new array 
    char* colorBits = new char[ xSize * ySize * 3 ]; 
//texture creation.. 
    glGenTextures(1,&texture); 
    glBindTexture(GL_TEXTURE_2D,texture); 
    glTexImage2D(GL_TEXTURE_2D,0 ,3 , xSize, 
       ySize, 0 , GL_RGB, 
       GL_UNSIGNED_BYTE, colorBits); 
//you can set other texture parameters if you want 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
//clean up 
    delete[] colorBits; 
} 

然後:

int viewport[4]; 
    glGetIntegerv(GL_VIEWPORT,(int*)viewport); 
    glViewport(0,0,xSize,ySize); 


    DrawScene(hDC); 

    //save data to texture using glCopyTexImage2D 
    glBindTexture(GL_TEXTURE_2D,texture); 

    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 
        0,0, xSize, ySize, 0); 
    glClearColor(.0f, 0.5f, 0.5f, 1.0f);    // Set The Clear Color To Medium Blue 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glViewport(viewport[0],viewport[1],viewport[2],viewport[3]); 
    // glBindTexture(GL_TEXTURE_2D,texture); 

最後:

glEnable(GL_TEXTURE_2D);     // Enable 2D Texture Mapping 
     glBlendFunc(GL_DST_COLOR,GL_ONE);    // Set Blending Mode 
     glEnable(GL_BLEND); 

     glClear(GL_COLOR_BUFFER_BIT); 
     glBindTexture(GL_TEXTURE_2D,texture); 

     glRotatef(theta, 0.0f, 0.0f, 0.01f); 
     glBegin(GL_QUADS); 
     //Front Face 
     glTexCoord2f(0.0f, 0.0f); 
     glVertex3f(-0.5, -0.5f, 0.5f); 
     glTexCoord2f(1.0f, 0.0f); 
     glVertex3f(0.5f, -0.5f, 0.5f); 
     glTexCoord2f(1.0f, 1.0f); 
     glVertex3f(0.5f, 0.5f, 0.5f); 
     glTexCoord2f(0.0f, 1.0f); 
     glVertex3f(-0.5f, 0.5f, 0.5f); 
     glEnd(); 
     SwapBuffers(hDC); 

的drawScene函數()函數只是呈現一個三角形上的一個矩形頂部,每個頂點有不同的顏色..沒有什麼特別的。

glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
glClear(GL_COLOR_BUFFER_BIT);//| GL_DEPTH_BUFFER_BIT); 

glPushMatrix(); 
// glRotatef(theta, 0.0f, 0.0f, 1.0f); 

glBegin(GL_QUADS); 
glColor3f(1.0f, 0.0f, 0.0f); 
glVertex3f(-1.0f, -1.0f, 1.0f); 
glColor3f(0.0f, 1.0f, 0.0f); 
glVertex3f(1.0f, -1.0f, 1.0f); 
glColor3f(0.0f, 0.0f, 1.0f); 
glVertex3f(1.0f, 1.0f, 1.0f); 
glColor3f(1.0f, 1.0f, 1.0f); 
glVertex3f(-1.0f, 1.0f, 1.0f); 
glEnd(); 

glBegin(GL_TRIANGLES); 

glColor3f(1.0f, 0.0f, 0.0f); 
glVertex2f(0.0f, 1.0f); 
glColor3f(0.0f, 1.0f, 0.0f); 
glVertex2f(0.87f, -0.5f); 
glColor3f(0.0f, 0.0f, 1.0f); 
glVertex2f(-0.87f, -0.5f); 
glEnd(); 
glPopMatrix(); 
+0

請編輯您的文本以在所有情況下將可渲染表面稱爲FrameBuffer對象 - 而不僅僅是誤導性的framebuffer。 – Ani

+0

完成。感謝您的關注。 – filipehd

+0

渲染時你似乎在混合。這是你的意圖嗎?你有沒有調用swapBuffers來查看實際渲染的內容? – Ani

回答

4

我發現在NVIDIA網站上的東西看起來很有用的,別人誰也無法做到與屏幕外渲染FBO:

http://developer.download.nvidia.com/SDK/9.5/Samples/samples.html

該網ite包含一個名爲「Simple P-Buffer」的項目,它基本上包含一個P緩衝區的實現。示例的想法是,您將上下文切換到pBuffer,而您想在屏幕外模式下繪製像素,比方說。使用普通渲染函數繪製場景後,我們使用glReadPixels將pBuffer中的數據讀取爲無符號字節數組(GLubyte)。之後,我們再次進行上下文切換,將其設置回屏幕上下文,以便您可以使用glReadPixels從我們的數組中讀取內容。

0

宗教組織是可利用之前所述的方法是使用一個備用渲染緩衝器(see glDrawBuffer(GL_AUX0),然後從該緩衝液(see glReadBuffer)到紋理(see glCopyTexImage2D複製像素。直接渲染到紋理需要宗教組織。

+0

Ben Voigt,感謝您的回答,我會在星期一嘗試一下,如果我能夠實現這個目標,我會在這裏發佈結果以及解決方案。 – filipehd

+0

輔助緩衝區比FBO支持得更少。支持最廣泛的方法是使用PBuffer設備上下文/渲染上下文作爲渲染目標(與主OpenGL上下文共享對象)並將渲染後的圖片複製到紋理中。谷歌「PBuffer渲染紋理」 – datenwolf

+0

datenwolf,謝謝你的回答。它讓我產生了一些有趣的結果,正如我在下面的答案中發佈的那樣。 – filipehd