GL_TEXTURE_RECTANGLE with GLuint data?

No matter what values i fill my data with, the texture is drawn black. Since it is being drawn to the screen, I use the screen coordinates as texel coordinates in the shader.
<div class=“ubbcode-block”><div class=“ubbcode-header”>Click to reveal… <input type=“button” class=“form-button” value=“Show me!” onclick=“toggle_spoiler(this, ‘Yikes, my eyes!’, ‘Show me!’)” />]<div style=“display: none;”>


static const Uint32 MAX_UINT32 = 0xFFFFFFFF;
void CreateTexture(){
	Uint32 lsize = SCREEN_WIDTH*SCREEN_HEIGHT*4;
	GLuint* ldata = new GLuint[lsize];
	for( Uint32 i=0; i<lsize; ++i ){
		if( (i+1)%4 ){
			ldata[i]=0;  //black
		}
		else{
			ldata[i]=MAX_UINT32;  //alpha
		}
	}
        //white pixel in center of screen
	ldata[lsize/2+(Uint32)HALF_W] = MAX_UINT32;
	ldata[lsize/2+(Uint32)HALF_W+1] = MAX_UINT32;
	ldata[lsize/2+(Uint32)HALF_W+2] = MAX_UINT32;
		
	glActiveTexture( GL_TEXTURE0 );

	glGenTextures( 1, &mTexId );
	glBindTexture( GL_TEXTURE_RECTANGLE, mTexId );
	glTexImage2D(	GL_TEXTURE_RECTANGLE, 0, GL_RGBA, 
			SCREEN_WIDTH, SCREEN_HEIGHT, 0, 
			GL_RGBA, GL_UNSIGNED_INT, ldata );
	delete[] ldata;
}

[/QUOTE]</div>

No white pixels show up, even if I initialize all the data to MAX_UINT32

Try this

 
Uint32 lsize = SCREEN_WIDTH*SCREEN_HEIGHT*4;
Uint32 HALF_W = SCREEN_WIDTH>>1;
Uint32 HALF_H = SCREEN_HEIGHT>>1;
GLuint* ldata = new GLuint[lsize];
for( Uint32 i=0; i<lsize; ++i ){
   if( (i+1)%4 ){
      ldata[i]=0;  //black
   }
   else{
      ldata[i]=MAX_UINT32;  //alpha
   }
}
  //white pixel in center of screen
  ldata[(SCREEN_WIDTH*HALF_W+ HALF_H)*4] = MAX_UINT32;
  ldata[(SCREEN_WIDTH*HALF_W+ HALF_H)*4+1] = MAX_UINT32;
  ldata[(SCREEN_WIDTH*HALF_W+ HALF_H)*4+2] = MAX_UINT32; 		
  glActiveTexture( GL_TEXTURE0 );
  glGenTextures( 1, &mTexId );
  glBindTexture( GL_TEXTURE_RECTANGLE, mTexId );
  glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexImage2D(	GL_TEXTURE_RECTANGLE, 0, GL_RGBA, SCREEN_WIDTH, SCREEN_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_INT, ldata );
  delete[] ldata;

Also make sure that the texture coordinates you assign to the geometry are not normalized like this,


glBegin(GL_QUADS);
   glTexCoord2f(0,0);glVertex2i(0,0);
   glTexCoord2f(SCREEN_WIDTH,0);glVertex2i(SCREEN_WIDTH,0);
   glTexCoord2f(SCREEN_WIDTH,SCREEN_HEIGHT);glVertex2i(SCREEN_WIDTH,SCREEN_HEIGHT);
   glTexCoord2f(0,SCREEN_HEIGHT);glVertex2i(0,SCREEN_HEIGHT);
glEnd();

Still can’t get anything but black pixels to draw. And yes, since the texel coords and screen coords co-incide, I am just passing on the texture coordinates like so [tt]out vec2 texPos = inVertex.xy[/tt]

Isn’t MAX_UINT32 supposed to be white for a texture specified with
GL_UNSIGNED_INT as the type? Even if I fill my data with all MAX_UINT32 values, it still draws black.

Well i get this output which is exactly what I should get.
Could u try this minimal glut code and tell me what u get?


#include <gl/glew.h>
#include <gl/glut.h> 
typedef unsigned int Uint32;
static const Uint32 SCREEN_WIDTH = 800;
static const Uint32 SCREEN_HEIGHT = 600;
static const Uint32 MAX_UINT32 = 0xFFFFFFFF;
int HALF_W = SCREEN_WIDTH>>1;
int HALF_H = SCREEN_HEIGHT>>1;
GLuint txt; 
unsigned char* bitmapData;
void Render()
{	
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
  glBegin(GL_QUADS);
    glTexCoord2i(0,0);glVertex2i(0,0);
    glTexCoord2i(SCREEN_WIDTH,0);glVertex2i(SCREEN_WIDTH,0);
    glTexCoord2i(SCREEN_WIDTH,SCREEN_HEIGHT);glVertex2i(SCREEN_WIDTH,SCREEN_HEIGHT);
    glTexCoord2i(0,SCREEN_HEIGHT);glVertex2i(0,SCREEN_HEIGHT);
  glEnd();

  glFinish();
  glutSwapBuffers();
}
void CreateTexture(GLuint* texID){
  Uint32 lsize = SCREEN_WIDTH*SCREEN_HEIGHT*4 ;
  GLuint* ldata = new GLuint[lsize ];
  memset(ldata,0,lsize );
  for( Uint32 i=0; i<lsize; ++i ){
    if( (i+1)%4 ){
	ldata[i]=0;  //black
    }else{
	ldata[i]=MAX_UINT32;  //alpha
    }
  }	
  //white pixel in center of screen
  ldata[(SCREEN_WIDTH*HALF_H+ HALF_W)*4] = MAX_UINT32;
  ldata[(SCREEN_WIDTH*HALF_H+ HALF_W)*4+1] = MAX_UINT32;
  ldata[(SCREEN_WIDTH*HALF_H+ HALF_W)*4+2] = MAX_UINT32; 

  glActiveTexture( GL_TEXTURE0 );
  glGenTextures( 1, texID );
  glBindTexture( GL_TEXTURE_RECTANGLE, *texID );
  glTexParameterf(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
  glTexImage2D(	GL_TEXTURE_RECTANGLE, 0, GL_RGBA, SCREEN_WIDTH, SCREEN_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_INT, ldata );
  delete[] ldata;
}


int main(int argc, char** argv)
{	
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);
  glutInitWindowSize(SCREEN_WIDTH,SCREEN_HEIGHT);
  glutCreateWindow("SIMPLE DISPLAY");
  glewInit();
  glutDisplayFunc(Render);	

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluOrtho2D(0,SCREEN_WIDTH, 0, SCREEN_HEIGHT);

  glEnable(GL_TEXTURE_RECTANGLE);    
  CreateTexture(&txt); 
  glutMainLoop();
  return 0;
} 

This should give u this output. There is a small white dot in the center.

I think it’s because I’m using sampler2D but I need samplerRECT

Is this not core functionality in a 3.3 context? How hard would it be to add?

I think it’s because I’m using sampler2D but I need samplerRECT

And that’s why it’s a good idea to post your shader.

Is this not core functionality in a 3.3 context? How hard would it be to add?

You just use a samplerRect in your shader instead of a sampler2d.

Okay I found that I can use a usampler2DRect,
but there does not seem to be defined a texture2DRect( , );, I get the shader compiler error C7531: "global function texture2DRect requires “#extension GL_EXT_gpu_shader4 : enable” before use

is this a line I can add to my code somewhere? or do I need some header files?

Edit: I got it, just add #extension GL_EXT_gpu_shader4 : enable to my shader now it all works :slight_smile:

Is GL_TEXTURE_RECTANGLE not compatible with glCopyTexImage2D? I wanted to copy the last frame into this texture but it would complicate things if the texture has to be a power of 2 instead of the screen dimensions.

glCopyTexImage2D should work fine with GL_TEXTURE_RECTANGLE. You should check your code. The first thing i would look at is my texture format and the internal format I am passing to glCopyTexImage2D.

<div class=“ubbcode-block”><div class=“ubbcode-header”>Click to reveal… <input type=“button” class=“form-button” value=“Show me!” onclick=“toggle_spoiler(this, ‘Yikes, my eyes!’, ‘Show me!’)” />]<div style=“display: none;”>

#version 330
#extension GL_EXT_gpu_shader4 : enable

uniform usampler2DRect tex;

in vec2 texPos;

out vec4 outFragColor;

void main()
{
	vec4 out_color;
	vec4 tex_color_left;

	vec2 top = vec2(0, 1);
	vec2 bottom = vec2(0, -1);
	vec2 right = vec2(1, 0);
	vec2 left = vec2(-1, 0);

	tex_color_left = texture(tex, texPos+left);

	if( tex_color_left.x>0.5 ){
		out_color = vec4(1.0, 1.0, 1.0, 1.0);
	}
	else{
		out_color = vec4(0.0, 0.0, 0.0, 1.0);
	}
	
	outFragColor = out_color;
}

[/QUOTE]</div>

Edit: ah, i answered my own question again :slight_smile: (problem with equality with floats)

Edit: I got it, just add #extension GL_EXT_gpu_shader4 : enable to my shader now it all works

You’re already defining GLSL version 3.30. So you have access to GLSL 3.30. You shouldn’t be using functions like “texture2D” and so forth. The preferred functions don’t mention the sampler type at all, because they’re all overloaded for the appropriate sampler type. The function you’re really looking for is “texture”.

Are you writing to the same buffer from where u r reading the data?

I got that sorted, the program just didn’t like when I checked for tex_color_left.x==1.0, so I changed it to tex_color_left.x>0.5 and that works.

However, when the white pixel gets to the right side of the screen, it doesn’t wrap around. I read in the spec that GL_TEXTURE_WRAP_R, S, T should default to repeat. So I have added the glTexParameteri( … , GL_REPEAT ); call to enable repeat but still it does not loop around

I just have a Texture bound to GL_TEXTURE_RECTANGLE. I read from this texture and draw to the current buffer. After I’m done drawing to the current buffer, before I swap I call glCopyTexImage2D( ); Well, you can see the loop here

Uint32 len = 500;
	for( Uint32 i=0; i<len; ++i ){
		glClear( GL_COLOR_BUFFER_BIT );
		myOnscreen.Draw();
		glCopyTexImage2D(	GL_TEXTURE_RECTANGLE, 0, GL_RGBA, 
		                        0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0 );
		SDL_GL_SwapWindow( mMainWindow );
	}

Could u issue a glFlush() or glFinish() after the glCopyTexImage call and before your SDL_GL_SwapWindow call.
And why do u need to render 500 times issuing a texture copy in each iteration?
You could render to an FBO directly which would save u these 500 copies.

I don’t have any experience with FBO.

However I don’t think I want to do that in this case: I can’t make changes to the underlying Texture until all of the pixels for the current frame have been processed (as their color depends on the neighboring pixels). If I was rendering into the original texture, I would be losing information that I need to update adjacent pixels.

Performance right now doesn’t seem to be a problem.

According to this thread GL_TEXTURE_RECTANGLE doesn’t support GL_REPEAT?

If so, it would make things very inconvenient. I suppose I would have to define a uniform float to store a normalized ‘pixel’ size ( 1/SCREEN_W and 1/SCREEN_H ) if I wanted to do adjecent pixel access?

Indeed, texture rectangle have lots of limitations, compared to normal 2D non-power-of-two textures.
Any reason you use RECTANGLE instead of NPOT textures ?

I was under the assumption that TEXTURE_2D was a power of two texture

I also wanted to keep coincidence with screen and texture coordinates so I could keep things more simple. It’s a full-screen cellular automata. seems with normalized coordinates it would get messy for a discrete math problem

You really need to read the GLSL 3.30 specification. Because you can access anything with “texelFetch,” which doesn’t use normalized texture coordinates. And you can get the size of a texture with the “textureSize” function. And OpenGL has supported NPOTs since GL 2.0. So there’s no need for you to use a rectangle texture here.

If the spec is too big, you could try reading the abridged version.