NPOT FBOs in OpenGL 2.0

Apprentice
Posts: 7
Joined: 2009.06
Post: #1
Hello everyone. This is my first post here. Nice community you have going. :-)

I'm developing a Mac application on my 2008 Unibody MacBook (GeForce 9400M). I'm using OpenGL 2.0 and taking advantage of the relaxed requirements for GL_TEXTURE_2D sizes because my app works with lots of unusually sized images. Some of these images are rendered to using GL_FRAMEBUFFER_EXT functions. From my online readings my understanding is that rendering to NPOT textures is supported on my MacBook (and most Macs released in the last few years), however, my results suggest otherwise. For example, when rendering to an 880x912 texture, the drawing does not cover two bands on the left and top. I measured these bands, and they are the exact size needed to round up to 1024x1024. As an experiment, I changed my FBO code to use glViewport(0, 0, 1024, 1024) instead of glViewport(0, 0, w, h), and the bands disappeared.

I want to know what's going on. Am I incorrect about NPOT FBOs? Is OpenGL secretly padding my texture to be a larger size?

Any help is greatly appreciated,

Colin
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #2
Any particular reason to use NPOT over RECT? I do RECT FBOs all the time without incident. Obviously, there may be reasons why normalized tex coords are desirable, but I imagine that you can work around that.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #3
NPOT works fine (10.5.6, GeForce 8600M, which I believe should behave identically to yours)

Code:
#include <stdio.h>
#include <stdlib.h>
#include <GLUT/glut.h>

#define TEXTURE_WIDTH 889
#define TEXTURE_HEIGHT 514

static GLuint fbo;
static GLuint color_texture;

static void display(void)
{
    glBindTexture(GL_TEXTURE_2D, color_texture);
    glEnable(GL_TEXTURE_2D);
    glBegin(GL_QUADS);
    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();
    
    glutSwapBuffers();
    glutReportErrors();
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_ALPHA | GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("FBO");
    glutDisplayFunc(display);
    
    glGenFramebuffersEXT(1, &fbo);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
    
    glGenTextures(1, &color_texture);
    glBindTexture(GL_TEXTURE_2D, color_texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexImage2D(
        GL_TEXTURE_2D,
        0,
        GL_RGBA,
        TEXTURE_WIDTH,
        TEXTURE_HEIGHT,
        0,
        GL_BGRA,
        GL_UNSIGNED_INT_8_8_8_8_REV,
        NULL);
    glBindTexture(GL_TEXTURE_2D, 0);
    glFramebufferTexture2DEXT(
        GL_FRAMEBUFFER_EXT,
        GL_COLOR_ATTACHMENT0_EXT,
        GL_TEXTURE_2D,
        color_texture,
        0);
    
    GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
    {
        fprintf(stderr, "framebuffer status: 0x%04x\n", (unsigned)status);
    }
    
    glViewport(0, 0, TEXTURE_WIDTH, TEXTURE_HEIGHT);
    glBegin(GL_QUADS);
    glColor3f(1.0, 0.0, 0.0);
    glVertex2f(-1.0, -1.0);
    glColor3f(0.0, 1.0, 0.0);
    glVertex2f( 1.0, -1.0);
    glColor3f(0.0, 0.0, 1.0);
    glVertex2f( 1.0,  1.0);
    glColor3f(1.0, 1.0, 0.0);
    glVertex2f(-1.0,  1.0);
    glEnd();
    glColor3f(1.0, 1.0, 1.0);
    
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
    
    glutMainLoop();
    return EXIT_SUCCESS;
}
Quote this message in a reply
Apprentice
Posts: 7
Joined: 2009.06
Post: #4
TomorrowPlusX Wrote:Any particular reason to use NPOT over RECT? I do RECT FBOs all the time without incident. Obviously, there may be reasons why normalized tex coords are desirable, but I imagine that you can work around that.

I was originally using RECT, but when I realized that GL 2.0 natively supported all texture sizes, it seemed like the more "proper" way to do things. Additionally, I think I remember reading that mipmapping is not allowed with RECT, and I definitely need mipmapping.

Are there any other advantages/disadvantages of GL_TEXTURE_2D vs GL_TEXTURE_RECTANGLE that I should know about? I don't really care about the texture coordinates being normalized or not.

Thanks for the response. :-)
Quote this message in a reply
Apprentice
Posts: 7
Joined: 2009.06
Post: #5
OneSadCookie Wrote:NPOT works fine (10.5.6, GeForce 8600M, which I believe should behave identically to yours)

Thanks very much for the code sample. You're right, this does work properly on my machine, so my problem must be somewhere else.

The only major difference I can find is that my FBO texture is mipmapped, and the levels are generated after each rendering with glGenerateMipmapEXT. Do you think this is an issue? As a test, I will try modifying your code to use mipmaps in this way.

Also, on a slight tangent, I notice that you're using GL_BGRA and GL_UNSIGNED_INT_8_8_8_8_REV for your textures. Is this the ideal format on the Mac for FBO textures? Are these formats also the best for textures that are written to with glTexSubImage2D, or is something else better in that case?

Thanks!

Colin
Quote this message in a reply
Apprentice
Posts: 7
Joined: 2009.06
Post: #6
Solved!

The problem turned out to be with the gluBuild2DMipmaps function I was using to initially generate my texture. I'd failed to notice the following in the documentation:

Quote:Initially, the width and height of data are checked to see if they are a power of two. If not, a copy of data (not data), is scaled up or down to the nearest power of two. This copy will be used for subsequent mipmapping operations described below. (If width or height is exactly between powers of 2, then the copy of data will scale upwards.) For example, if width is 57 and height is 23 then a copy of data will scale up to 64 and down to 16, respectively, before mipmapping takes place.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Draw to texture using FBOs - aspect ratio issues Madrayken 2 4,040 Jul 15, 2010 11:47 AM
Last Post: Madrayken
  Understanding multisampled FBOs Coyote 12 8,703 Nov 27, 2009 01:01 AM
Last Post: arekkusu