View Full Version : GL_TEXTURE_RECTANGLE_ARB + glTexSubImage2D = ?

01-14-2010, 12:42 PM
A little confusion about glTexSubImage + GL_TEXTURE_RECTANGLE_ARB

Okay I'll confess. I'm sure I'm doing something wrong (as usual), but from what I've read, this should work...

According to the OpenGL spec for glTexSubImage, GL_TEXTURE_RECTANGLE_ARB isn't a valid target, but according to the GL_TEXTURE_RECTANGLE_ARB page, it is, so long as level is 0, and GL_TEXTURE_RECTANGLE_ARB should be appended to the list of valid targets. I've been experimenting with this and getting kind of odd results. No errors generated, but when I try to replace a 4x16 patch of a 64x64 texture, nothing is being replaced. When I change the target back to GL_TEXTURE_2D, everything works as expected.

The code is a bit large so I'll try to post as small chunk as I can..

#define TEXWIDTH 64
#define TEXHEIGHT 64

TextureHandler::TextureHandler() {

m_InternalFormat = GL_RGBA;
m_Format = GL_RGBA;
m_Type = GL_FLOAT;
m_Height = TEXHEIGHT;
m_Width = TEXWIDTH;


void TextureHandler::Initialize() {

// prepare all m_Data cells as blue, full alpha
for ( int i = 0; i < m_Width; i++ ) {
for ( int j = 0; j < m_Height; j++ ) {

m_Data[i][j][0] = 0.0;
m_Data[i][j][1] = 0.0;
m_Data[i][j][2] = 1.0;
m_Data[i][j][3] = 1.0;


void TextureHandler::GenAndBindTexture() {

glGenTextures( 1, &amp;m_id ); // generate a texture
// glActiveTexture(GL_TEXTURE0 + m_id); // for the shader later
glBindTexture( m_Target, m_id ); // bind it to the target type


glTexImage2D( m_Target, 0, m_InternalFormat,
m_Width, m_Height, 0,
m_Format, m_Type, m_Data );


void TextureHandler::EditTexture( ) {

glBindTexture( m_Target, m_id );

float l_Data[4][15][4];

// prepare a purple rectangle.
for ( int i = 0; i < 4; i++ ) {
for ( int j = 0; j < 15; j++ ) {

l_Data[i][j][0] = 1.;
l_Data[i][j][1] = 0.;
l_Data[i][j][2] = 1.;
l_Data[i][j][3] = 1.;


// make the change...
glTexSubImage2D( m_Target, 0, 1, 1, //target, level, offsets
15, 4, m_Format, m_Type, l_Data );


void static Redraw() {

// render implemented as singleton
Render* l_Render = Render::GetInstance();

// swap to model view and clear everything
glMatrixMode( GL_MODELVIEW );

// set Color to red so we know if the texture doesn't
// even show up, then back up 3.6
glColor3f( 1.0, 0.0, 0.0 );
glTranslatef( 0.0, 0.0, -3.6 );

// enable textures in decal mode
// with target specified by m_Texture.m_Target
glEnable( l_Render->m_Texture.m_Target );

// bind the texture we want to use
glBindTexture( l_Render->m_Texture.m_Target,
l_Render->m_Texture.m_id );

// move back and draw
glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-2.0, 1.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f( 0.0, 1.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f( 0.0, -1.0, 0.0);

glDisable( l_Render->m_Texture.m_Target );


I know that's a large chunk (and it's by far not the full app), but I wanted to provide context.. Like I said, if I change it to TEXTURE_2D (and then change the TexParameteri calls, then it displays fine.. but with GL_TEXTURE_RECTANGLE_ARB, it doesn't work.. so I don't know what to think..

(Also.. as an aside, I'm curious as to why if I make a glActiveTexture call, I can't see any texture changes, even with GL_TEXTURE_2D as the target...)

01-14-2010, 02:04 PM
I see you are using normalized texture coordinates [0.0,1.0]. This is not the way it works with rectangular textures. Texture coordinates go from 0 to width-1 and 0 to height-1.

01-14-2010, 05:28 PM
Ahah! Okay, yes, that was it apparently. Thanks for that! :) Does that apply to inside the shader as well then as well?

Also, I'm still kind of curious why if I make that glActiveTexture call, it makes any changes I make not appear.. whether target is GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE_ARB.. anyone know?

01-14-2010, 07:19 PM
yes, this is true inside a shader too. BTW, re-reading the spec of this extension, I made a mistake, it is no from 0 to width-1 but from 0 to width, etc.

01-14-2010, 09:08 PM
THAT explains it then.. the reason I was mapping this texture onto the surface is to get a view of what was happening in the shader, no matter where I sampled, I was getting the changed value.. but I was always sampling texture location (0,0) essentially because I was dividing the (x,y) location I was trying to reference by the texture width,height. Makes sense now..