OpenGL 4.3 and glTexStorage2D

Hi forum,

I started my learning with the most recent opengl profile and i am having problem with the function glTexStorage2D(…). I did it as follows:


   //generate a name for the texture
   glGenTextures(1, &textureID);

   //now bind the name to the context using the GL_TEXTURE_2D binding point
   glBindTexture(GL_TEXTURE_2D,textureID);

   GL_CHECK_ERRORS;

   //set texture parameters
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);

   
   //allocate texture memory
   glTexStorage2D(GL_TEXTURE_2D,0,GL_RGB,texture_width,texture_height);

   
   GL_CHECK_ERRORS;
   
   //specify some data for the texture
   glTexSubImage2D(GL_TEXTURE_2D,0,0,0,texture_width,texture_height,GL_RGB,GL_UNSIGNED_BYTE,pData);
 

   //the following statement seems redundant to me
   //since we are using a single texture in this application
   //will sort out later
   glActiveTexture(GL_TEXTURE0);

It did not work and i got the GL_INVALID_OPERATION. If i replace the glStorage2D(…) and glTexSubImage2D(…) with the glTexImage2D() as follows, i get the output i am looking for:


  glTexImage2D(GL_TEXTURE_2D,
		0,
		GL_RGB,
		texture_width,
		texture_height, 0, GL_RGB, GL_UNSIGNED_BYTE, pData);


Any reason behind this? What is that i am missing ?

Thanks

The ‘levels’ parameter to glTexStorage2D must be at least 1, see errors section of the man page.

Hi Carsten,

I tried it as well and i have the blank screen now. Check the following snippet that i tried with:


void loadTexture(const string &filename)
{
   //load the image using SOIL image library
   int texture_width = 0, texture_height = 0, channels = 0;
   
   GLubyte* pData = SOIL_load_image(filename.c_str(),
				    &texture_width,
				    &texture_height,
				    &channels,
				    SOIL_LOAD_AUTO);

   if(pData == NULL)
   {
      cerr<<"Cannot load image: "<<filename.c_str()<<endl;
      exit(EXIT_FAILURE);
   }
   //vertically flip the image on Y axis since it is inverted
   int i,j;
   for( j = 0; j*2 < texture_height; ++j )
   {
      int index1 = j * texture_width * channels;
      int index2 = (texture_height - 1 - j) * texture_width * channels;
      for( i = texture_width * channels; i > 0; --i )
      {
	 GLubyte temp = pData[index1];
	 pData[index1] = pData[index2];
	 pData[index2] = temp;
	 ++index1;
	 ++index2;
      }
   }


   //setup opengl texture

   //generate a name for the texture
   glGenTextures(1, &textureID);

   //the following statement seems redundant to me
   //since we are using a single texture in this application
   //will sort out later
   glActiveTexture(GL_TEXTURE0);
   
   
   //now bind the name to the context using the GL_TEXTURE_2D binding point
   glBindTexture(GL_TEXTURE_2D,textureID);

   GL_CHECK_ERRORS;

   //set texture parameters
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);

   
   //allocate texture memory
   glTexStorage2D(GL_TEXTURE_2D,1,GL_RGB,texture_width,texture_height);

   GL_FIND_ERRORS;
   GL_CHECK_ERRORS;
   
   //specify some data for the texture
   glTexSubImage2D(GL_TEXTURE_2D,0,0,0,texture_width,texture_height,GL_RGB,GL_UNSIGNED_BYTE,pData);
   /*
   glTexImage2D(GL_TEXTURE_2D,
		0,
		GL_RGB,
		texture_width,
		texture_height, 0, GL_RGB, GL_UNSIGNED_BYTE, pData);
   */

   
   //free SOIL image data
   SOIL_free_image_data(pData);

   GL_FIND_ERRORS;
   //GL_CHECK_ERRORS;

   std::cout << "Initialization successful" << std::endl;
}

Funny logic: I tried it the right way - didn’t work, so I decided to go against the specification! :slight_smile:
The levels parameter must be 1, do not push more bugs into the code - there will always be enough. :slight_smile:
The GL_CLAMP parameter is deprecated, use GL_CLAMP_TO_EDGE.
The GL_RGB as internal format - just a recommendation - always use sized formats, like GL_RGB8 (but this is not a source of errors anyway).
I see glTexImage2D in comments - ensure it stays there because you can not use it for textures allocated with glTexStorage2D to upload texture data.
Nothing else bad I mentioned. :slight_smile:

So, does that mean you are no longer getting GL errors from the code you posted? Do you get GL errors from the rest of your code? There are so many reason that could cause you to get a blank screen it really is not very efficient to speculate which one might be your problem.
Did you ever have the code in a state where you did not get a blank screen? What changed from that state? What else have you done so far to narrow down the problem?

Hi forum,

Eventually i got it correct with the following snippet :


void loadTexture(const string &filename)
{
   //load the image using SOIL image library
   int texture_width = 0, texture_height = 0, channels = 0;
   
   GLubyte* pData = SOIL_load_image(filename.c_str(),
				    &texture_width,
				    &texture_height,
				    &channels,
				    SOIL_LOAD_AUTO);

   if(pData == NULL)
   {
      cerr<<"Cannot load image: "<<filename.c_str()<<endl;
      exit(EXIT_FAILURE);
   }
   //vertically flip the image on Y axis since it is inverted
   int i,j;
   for( j = 0; j*2 < texture_height; ++j )
   {
      int index1 = j * texture_width * channels;
      int index2 = (texture_height - 1 - j) * texture_width * channels;
      for( i = texture_width * channels; i > 0; --i )
      {
	 GLubyte temp = pData[index1];
	 pData[index1] = pData[index2];
	 pData[index2] = temp;
	 ++index1;
	 ++index2;
      }
   }


   //setup opengl texture

   //generate a name for the texture
   glGenTextures(1, &textureID);

   //the following statement seems redundant to me
   //since we are using a single texture in this application
   //will sort out later
   glActiveTexture(GL_TEXTURE0);
   
   
   //now bind the name to the context using the GL_TEXTURE_2D binding point
   glBindTexture(GL_TEXTURE_2D,textureID);

   GL_CHECK_ERRORS;

   //set texture parameters
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_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);

   
   //allocate texture memory
   glTexStorage2D(GL_TEXTURE_2D,1,GL_RGB8,texture_width,texture_height);

   //GL_FIND_ERRORS;
   GL_CHECK_ERRORS;
   
   //specify some data for the texture
   glTexSubImage2D(GL_TEXTURE_2D,0,0,0,texture_width,texture_height,GL_RGB,GL_UNSIGNED_BYTE,pData);
   
   
   //free SOIL image data
   SOIL_free_image_data(pData);

   
   GL_CHECK_ERRORS;

   std::cout << "Initialization successful" << std::endl;
}

I made some changes while defining the texture parameters GL_CLAMP_TO_EDGE from GL_CLAMP and then GL_RGB8 from GL_RGB. Thanks to Yandersen.

I also make the changes to the mipmap level - from 0 to 1.

Now i can see what i expected.