[英]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() == w
和height() == h
( resize
函數中的w
& h
值),則紋理(和FBO)大小與視口大小不同。 明確地說,您的視口為(w-100)
* (h-100)
,紋理為(w-150)
* (h-150)
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.