簡體   English   中英

OpenGL:使用FBO和視口偏移問題渲染到紋理

[英]OpenGL: Rendering to texture by using FBO and viewport offset problems

我已經注意到渲染到紋理時幀緩沖對象(FBO)的意外行為。

如果我們通過以下方式設置視口:

glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity() ;

(w和h不需要匹配窗口大小)一切都呈現良好:

因此,可以說我們需要繪制視口的邊界矩形:

glBegin(GL_LINE_STRIP);
    glVertex2f(0.0, 0.0);
    glVertex2f(0.0, 1.0);
    glVertex2f(1.0, 1.0);
    glVertex2f(1.0, 0.0);
glEnd();

如果我們在紋理上進行相同的繪制,則覆蓋整個視口:

glBegin(GL_QUADS);
    glTexCoord2f(0.0, 1.0);
    glVertex2f(0.0, 0.0);
    glTexCoord2f(0.0, 0.0);
    glVertex2f(0.0, 1.0);
    glTexCoord2f(1.0, 0.0);
    glVertex2f(1.0, 1.0);
    glTexCoord2f(1.0, 1.0);
    glVertex2f(1.0, 0.0);
glEnd();

我們得到相同的結果:

但是,如果我們將第一行更改為:

glViewport(x, y, w, h);

其中x和y不等於0-執行FBO版本時會有一個奇怪的偏移量。 偏移量完全等於(x,y),但它相對於視口,因此我們得到的偏移量為(2 * x,2 * y)

這是演示問題的完整代碼。

void initialize()
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
}

void resize(int w, int h)
{
    glViewport(50, 50, w-100, h-100);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluOrtho2D(0.0, 1.0, 1.0, 0.0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity() ;
}

void paint()
{
    glClear(GL_COLOR_BUFFER_BIT);

    // FBO Drawing
    GLuint fb, texColor;
    glGenFramebuffers(1, &fb);
    glGenTextures(1, &texColor);

    glBindFramebuffer(GL_FRAMEBUFFER, fb);
    glBindTexture(GL_TEXTURE_2D, texColor);
    glTexImage2D(   GL_TEXTURE_2D,
                0,
                GL_RGBA,
                width()-100, height()-100, // Maching size of viewport (size of window - unused area)
                0,
                GL_RGBA,
                GL_UNSIGNED_BYTE,
                NULL);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColor, 0);

    glLineWidth(10.0);
    glColor4f(1.0, 0.0, 0.0, 1.0);
    glBegin(GL_LINE_STRIP);
        glVertex2f(0.0, 0.0);
        glVertex2f(0.0, 1.0);
        glVertex2f(1.0, 1.0);
        glVertex2f(1.0, 0.0);
    glEnd();
    glBegin(GL_LINES);
        glVertex2f(0.0, 0.0);
        glVertex2f(1.0, 1.0);
        glVertex2f(0.0, 1.0);
        glVertex2f(1.0, 0.0);
    glEnd();


    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);

    glLineWidth(10.0);
    glColor4f(0.0, 1.0, 0.0, 1.0);
    glBegin(GL_LINE_STRIP);
        glVertex2f(0.0, 0.0);
        glVertex2f(0.0, 1.0);
        glVertex2f(1.0, 1.0);
        glVertex2f(1.0, 0.0);
    glEnd();
    glBegin(GL_LINES);
        glVertex2f(0.0, 0.0);
        glVertex2f(1.0, 1.0);
        glVertex2f(0.0, 1.0);
        glVertex2f(1.0, 0.0);
    glEnd();

    glEnable(GL_TEXTURE_2D);

    glBindTexture(GL_TEXTURE_2D, texColor);
    glColor4f(1.0, 1.0, 1.0, 0.3);
    glBegin(GL_QUADS);
        glTexCoord2f(0.0, 1.0);
        glVertex2f(0.0, 0.0);
        glTexCoord2f(0.0, 0.0);
        glVertex2f(0.0, 1.0);
        glTexCoord2f(1.0, 0.0);
        glVertex2f(1.0, 1.0);
        glTexCoord2f(1.0, 1.0);
        glVertex2f(1.0, 0.0);
    glEnd();

    glDisable(GL_TEXTURE_2D);
    glDisable(GL_BLEND);

    glDeleteTextures(1, &texColor);
    glDeleteFramebuffers(1, &fb);

為什么綠色和紅色繪圖不匹配?

截圖

當然,您會獲得兩倍的視口-因為您基本上將視口應用了兩次-視口在移到紋理時也是有效的,因此最終將對象原點映射到紋理中的像素(x,y)。 然后,再次使用視口繪制該紋理,以便四邊形從窗口坐標的(x,y)開始,並且紋理中的對象進一步移開-兩個偏移量累積。

只需將視口設置為在渲染到紋理時從原點開始。

如果width() == wheight() == hresize函數中的wh值),則紋理(和FBO)大小與視口大小不同。 明確地說,您的視口為(w-100) * (h-100) ,紋理為(w-150) * (h-150)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM