FBO and TEXTURE_RECTANGLE_ARB

Hi Guys,

RenderToBitamp (target bitmap is not square and not power of two): we are switching to the slower glReadPixel in the case GL_TEXTURE_RECTANGLE extension is not present but it is really necessary? FBO cares about NPOTS or not?

Below the code we use ONLY when both FBO and GL_TEXTURE_RECTANGLE are available.

Thanks,

Alberto

glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);

DrawScene(...);

glBindTexture(GL_TEXTURE_RECTANGLE_ARB, color_tex);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

glGetTexImage(GL_TEXTURE_RECTANGLE_ARB, 0, GL_BGR, GL_UNSIGNED_BYTE, bitmapData);

FBO with texture-rectangle is not slower than tex2D, in my experience.

Hi Ilian,

My question is: if I use GL_TEXTURE2D and target a rectangular texture will it work on all OpenGL implementations? On my ATI FIRE GL it works.

Thanks,

Alberto

You can safely create an 888x333 GL_TEXTURE_2D if the NPOT extension-string is available. And you can use that texture as a render-target.
Just think about it: all current-gen games do render-to-texture and then do post-processing on that texture :). In DX9/10, there’s no texRECT, it’s all tex2D.

But if you mean creation of a GL_TEXTURE_RECTANGLE, and then binding that same texture to a GL_TEXTURE_2D target, then I don’t know. Your question is ambiguous imho. (also “a rectangular texture” can mean both a 888x333 GL_TEXTURE_2D and an 888x333 GL_TEXTURE_RECTANGLE, so it can be confusing)

if I use GL_TEXTURE2D and target a rectangular texture will it work on all OpenGL implementations?

No. Not if it is a real rectangle textures.

Rectangle Textures (created with the type GL_TEXTURE_RECTANGLE) are a fundamentally different type from 2D textures. You cannot interchange them with 2D textures.

I suspect ATi works because they use a regular 2D texture for Rectangle Textures internally. nVidia hardware has special handling for rectangle textures.

Please note that rectangle textures are different from NPOT textures (which are not new texture types; they’re just a modification for the size rules on textures), which is what Ilian is talking about.

Ilian,

I thought that when you check for existance of the GL_ARB_TEXTURE_RECTANGLE extension you need to target it as GL_TEXTURE_RECTANGLE_ARB.

By the way here: http://www.opengl.org/registry/specs/ARB/texture_rectangle.txt you find:

3) How is the image of a rectangular texture specified?

     Using the standard OpenGL API for specifying a 2D texture
     image: glTexImage2D, glSubTexImage2D, glCopyTexImage2D,
     and glCopySubTexImage2D.  The target for these commands is
     GL_TEXTURE_RECTANGLE_ARB though.

     This is similar to how the texture cube map functionality uses the 2D
     texture image specification API though with its own texture target.

     The texture target GL_TEXTURE_RECTANGLE_ARB should also
     be used for glGetTexImage, glGetTexLevelParameteriv, and
     glGetTexLevelParameterfv.

But your observation is right. It works also specifying GL_TEXTURE2D.

This is the source of my doubts.

Thanks,

Alberto

Korval,

We are talking about getting a bitmap from a OpenGL viewport, docked inside a variable size Windows form: dimension can be all the possible combinations.

My question is: should I discard the FBO approach if OpenGL extension GL_ARB_texture_rectangle is not available?

Thanks,

Alberto

So, in conclusion:


CFBO* g_FBO;
...
int texWid=111,texHei=444;

if(extensionFBO){
	int realTexWid,realTexHei;
	if(extensionNPOT){
		realTexWid=texWid;
		realTexHid=texHid;
	}else{
		realTexWid = 128; // = fixupSize(texWid);
		realTexHei = 512; // = fixupSize(texHei);
	}
	g_FBO = createFBO(realTexWid,realTexHei,texWid,texHei); // this uses only GL_TEXTURE_2D
}else{
	#if OK_TO_USE_glCopyTexImage2D
		g_FBO = null;
	#else
		msgbox("Sorry, but Radeon9550 or even more ancient silicon is not supported");
		ExitProcess(0);
	#endif
}


Ilian,

Yes, more or less like you coded but glCopyTexImage2D would need to handle NPOT dimensions, that’s why we use glReadPixels.

Alberto

Your wording is quite confusing for me. oÔ

There may be only a “problem” if the ARB_texture_non_power_of_two is not supported and ARB_texture_rectangle is (you say the opposite IMO).

if ARB_texture_non_power_of_two is supported, you do anything you want.

Actually, what do you practically need to do? Retrieve image data in a texture or in system memory? glReadPixels and glCopyTexImage2D is not for the same purpose…

dletozeun,

We need to get the OpenGL viewport contents in a bitmap. AFAIK the fastest method is FBO and FBO requires to pass through a texture, right?

Supposing that the viewport can have any dimension combination, do I need the ARB_texture_rectangle or I need only the ARB_texture_non_power_of_two?

Thanks,

Alberto

glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);

DrawScene(…);

glBindTexture(GL_TEXTURE_RECTANGLE_ARB, color_tex);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

glGetTexImage(GL_TEXTURE_RECTANGLE_ARB, 0, GL_BGR, GL_UNSIGNED_BYTE, bitmapData);

No, you can make a RenderBuffer instead.


glGenFramebuffersEXT(1, &fboID2);
glBindFramebufferEXT(GL_FRAMEBUFFER, fboID2);
glGenRenderbuffersEXT(1, &ColorBufferID2);
glBindRenderbufferEXT(GL_RENDERBUFFER, ColorBufferID2);
glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_RGBA8, width, height);
glGenRenderbuffersEXT(1, &DepthBufferID2);
glBindRenderbufferEXT(GL_RENDERBUFFER, DepthBufferID2);
glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, ColorBufferID2);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, DepthBufferID2);

				ReturnVal=glExtCheckFramebufferStatus();

and use glReadPixels

Is it fast like the one I shown above?

glReadPixel isn’t always slow?

Thanks,

Alberto

By the way, what is the real difference between GL_ARB_texture_rectangle and ARB_texture_non_power_of_two and NV_texture_rectangle?

Thanks,

Alberto

Frankly, in these modern times, I don’t see the point in da texture rect.

Put it this way: what can you do with a rect that you can’t do with a NPOT? (without getting nasty).

Is it fast like the one I shown above?

glReadPixel isn’t always slow?

I don’t know how glGetTexImage and glReadPixels work internally, but I seeing their prototype I want to say that they do the same thing (I mean, for 2D texture) if you omit the thing that the 1st operate on a texture and the 2nd on the framebuffer.
So IMO none of them is faster than the other.

By the way, what is the real difference between GL_ARB_texture_rectangle and ARB_texture_non_power_of_two and NV_texture_rectangle?

You need to take a look to these extension spec (just the description). It is helpful.

Very quickly. GL_ARB_texture_rectangle allow you to use NPOT 2D and only 2D texture but all native wrap mode are not supported and texture coordinates are not normalized. You need to use in addition, a special texture target : TEXTURE_RECTANGLE_ARB

When ARB_texture_non_power_of_two is supported, it is like, you hardware support 1D, 2D, 3D and cube map NPOT texture natively. You don’t need any special target, you keep the current ones. So you have litterally nothing much to do and you don’t have to care of texture dimension whatsoever the texture nature.
In addition, all wrapping mode, mipmapping, normalized texture coordinates are supported.

Now, hoping that you understand this, you will see that you actually don’t have any problem to copy the data in system memory.

Supposing that the viewport can have any dimension combination, do I need the ARB_texture_rectangle or I need only the ARB_texture_non_power_of_two?

Either one. NPOT requires higher-end hardware, but texture_rectangle isn’t going to go into the standard (and there are limits in glslang as to the use of it).

By the way, what is the real difference between GL_ARB_texture_rectangle and ARB_texture_non_power_of_two and NV_texture_rectangle?

A GL_TEXTURE_RECTANGLE is not a GL_TEXTURE_2D. That’s probably the #1 most important take home point. If you create a texture rectangle, it is as different from a GL_TEXTURE_2D as a GL_TEXTURE_2D is from a GL_TEXTURE_CUBE. You cannot interchange them.

NPOT isn’t a new texture type; it is merely a change to the wording in the spec. It removes the restriction for all texture types that the sizes be 2^n.

Also, GL_TEXTURE_RECTANGLE textures are access in pixel units, not normalized texture coordinates [0.0, 1.0].

Either one. NPOT requires higher-end hardware, but texture_rectangle isn’t going to go into the standard (and there are limits in glslang as to the use of it).

Mmm… so what would you use to display a 333x888 bitmap into a 333x888 viewport?

I start to be a little confused.

Thanks,

Alberto

Mmm… so what would you use to display a 333x888 bitmap into a 333x888 viewport?

What part of “Either one” is confusing to you? Check the extensions; if one of them is available, use it. If it isn’t, check the other. If neither, punt or some fallback.

You are right, differences a well explained in the specification.

I will opt for the non_poer_of_two and stretch the bitmap to the closest POT dimension if it is missing.

Thanks,

Alberto

+ In ARB_texture_non_power_of_two:
        * mipmapping is allowed, default filter remains unchanged.
        * all wrap modes are allowed, default wrap mode remains unchanged.
        * borders are supported.
        * paletted textures are not unsupported.
        * texture coordinates are addressed parametrically [0..1],[0..1]
      + In EXT_texture_rectangle:
        * mipmapping is not allowed, default filter is changed to LINEAR.
        * only CLAMP* wrap modes are allowed, default is CLAMP_TO_EDGE.
        * borders are not supported.
        * paletted textures are unsupported.
        * texture coordinates are addressed non-parametrically [0..w],[0..h].