I have noticed unexpected behavior of frame-buffer objects (FBO) when rendering to a texture.
If we set viewport in following way:
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity() ;
(w and h doesn't need to match window size) everything is rendered fine:
So lets say we need to draw bounding rectangle of viewport:
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();
If we do the same drawing on a texture then covering whole viewport:
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();
We get same results:
But, if we change first line to:
glViewport(x, y, w, h);
where x and y are NOT equal 0 - there is a strange offset when doing FBO version. Offset is exactly equal to (x, y) but it is relative to a viewport so we get resulting offset off (2*x, 2*y)
Here is full code demonstrating problem.
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);
Why green and red drawing do not match?