NPOT FBOs in OpenGL 2.0
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
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
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.
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;
}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. :-)
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
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:
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.
Possibly Related Threads...
| Thread: | Author | Replies: | Views: | Last Post | |
| Draw to texture using FBOs - aspect ratio issues | Madrayken | 2 | 3,306 |
Jul 15, 2010 11:47 AM Last Post: Madrayken |
|
| Understanding multisampled FBOs | Coyote | 12 | 7,102 |
Nov 27, 2009 01:01 AM Last Post: arekkusu |
|

