glTexImage2D bug or stupid mistake?

So, ten years after learning OpenGL, here I am back on the boards with a glTexImage2D issue of all things :wink:

This code crashes with an invalid memory access in the call to glTexImage2D when creating the second texture on both my Quadro 5600 with 169.39 drivers and my 6800 Ultra with 169.21 drivers, compiled with Visual Studio 2008 professional and run on Windows XP 64 and 32. The only difference between the two textures is that the width and height are swapped. Itā€™s not that one is wider than it is tall either, itā€™s just that some width/height pairs work and some donā€™t.

I would really appreciate it if someone could glance at the code and see if Iā€™m doing something wrong. The code is self contained so if you want to try it you should just be able to copy-paste it somewhere inside your own OpenGL app to test.


  // This does not crash
  int w1 = 3000;
  int h1 = 2154;
  GLuint texture1 = 0;
  glGenTextures(1, &texture1);
  glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture1);
  glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);  
  glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);   
  glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);  
  glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);  
  unsigned char* data1 = new unsigned char[w1*h1];
  glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_ALPHA8, w1, h1, 0, 
      GL_ALPHA, GL_UNSIGNED_BYTE, data1); 
  delete [] data1;
  data1 = 0;
  cout << "Successfully created texture of width = " << w1 << " height = " << h1 << endl;

  // This crashes my Quadro 5600 with 169.39 drivers
  // Also crashes my 6800 Ultra with 169.21 drivers
  int w2 = 2154;
  int h2 = 3000;
  GLuint texture2 = 0;
  glGenTextures(1, &texture2);
  glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture2);
  glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);  
  glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);   
  glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);  
  glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);  
  unsigned char* data2 = new unsigned char[w2*h2];
  glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_ALPHA8, w2, h2, 0, 
      GL_ALPHA, GL_UNSIGNED_BYTE, data2); 
  delete [] data2;
  data2 = 0;
  cout << "Successfully created texture of height = " << w2 << " width = " << h2 << endl;

ah, the old missingā€¦

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

ā€¦problem.
Prevalent in these modern days of non-power-two textures.

Why are you using TEXTURE_RECTANGLE though? Both of those cards support non power of two textures.

That was it Knackered, thanks! I should have caught that myself.

BTW, I may not post around here much anymore, but I still enjoy reading your scathing commentariesā€¦Iā€™m lucky I got off so easy :slight_smile:

Malcolm - I would use NPOT except I have learned that even though my boss may say ā€œno problem, GeForce 6 is a reasonable minimum specā€, someone will inevitably try to run the program on a GeForce 2 (or worse) and then be surprised that it doesnā€™t work. Since I donā€™t need mipmapping for this application rectangle textures are a better solution to avoid future compatibility issues.

God no, perfectly understandable mistake, that pixelstore thing has got me more than once over the last few years. Itā€™s now the first function call in my GL setup code. I personally think they should have changed the default to 1 when they introduced non-power-two textures.

Changing default alignment would break existing code assuming four byte alignment by default.

no shi t sherlock.
I was of course being flippant.