Texture mapping acts weird on some images.

Started by
26 comments, last by babaliaris 5 years, 4 months ago
4 minutes ago, JWColeman said:

It sounds like your shader is the problem then, a null value in an alpha channel in your shader could cause some unexpected behavior.

 

Have you tried stepping through the graphics debug and checking the alpha value, when from your paint file, the alpha isn't there?

I don't think i have a graphics debug. Can I somehow use Visual Studio for that?


void life()
{
  while (!succeed())
    try_again();

  die_happily();
}

 

Advertisement

Yep, 

image.png.6f10a4cac7577fdbbaac04302c423f88.png

Now, how to use it, is a whole other discussion :D

I'm sure openGL has a device debug layer as well, its possible it could be throwing some warnings at you because of this.

Also, it may be that if you're pushing an RGBA through to your device but only sending it data for an RGB, it could be that each frame your RGB is getting shifted by sizeof(A)...

I'm really no expert on the rendering pipeline but these are oddities that I'm aware can occur when data is not pairing up just right.

17 minutes ago, JWColeman said:

Yep, 

image.png.6f10a4cac7577fdbbaac04302c423f88.png

Now, how to use it, is a whole other discussion :D

I'm sure openGL has a device debug layer as well, its possible it could be throwing some warnings at you because of this.

I searched and they say you can't debug shaders natively. They have also Nvdia Inslight gor visual studio but i have amd and i cant use that debugger. I will see This gDebugger  and i will come back later to post re results ;) 

3 minutes ago, JWColeman said:

Also, it may be that if you're pushing an RGBA through to your device but only sending it data for an RGB, it could be that each frame your RGB is getting shifted by sizeof(A)...

I'm really no expert on the rendering pipeline but these are oddities that I'm aware can occur when data is not pairing up just right.

what do you mean by that? Can you understand if I;m doing it in the code below? What is what you're saying and where i might be doing that?


Texture::Texture(std::string path, int unit)
{

	//Try to load the image.
	unsigned char *data = stbi_load(path.c_str(), &m_width, &m_height, &m_channels, 0);


	//Image loaded successfully.
	if (data)
	{

		//Generate the texture and bind it.
		GLCall(glGenTextures(1, &m_id));
		GLCall(glActiveTexture(GL_TEXTURE0 + unit));
		GLCall(glBindTexture(GL_TEXTURE_2D, m_id));

		//Not Transparent texture.
		if (m_channels == 3)
		{
			GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_RGB, GL_UNSIGNED_BYTE, data));
		}

		//Transparent texture.
		else if (m_channels == 4)
		{
			GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data));
		}

		//This image is not supported.
		else
		{
			std::string err = "The Image: " + path;
			err += " , is using " + m_channels;
			err += " channels which are not supported.";
			throw VampEngine::EngineError(err);
		}

		//Texture Filters.
		GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT));
		GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT));
		GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST));
		GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));

		//Generate mipmaps.
		GLCall(glGenerateMipmap(GL_TEXTURE_2D));
	}


	//Loading Failed.
	else
		throw VampEngine::EngineError("There was an error loading image \
		(Myabe the image format is not supported): " + path);



	//Unbind the texture.
	GLCall(glBindTexture(GL_TEXTURE_2D, 0));

	//Free the image data.
	stbi_image_free(data);
}

 


void life()
{
  while (!succeed())
    try_again();

  die_happily();
}

 

It looks to me that you are not filling the whole memory of the image on the GPU. If you look closely at the rendered image you will notice at the last pixel-line that some pixels are missing. The amount seems to be about the same as the height of your image, which would mean the width is one pixel too wide. Your image loading code seems alright on first glance so that is strange.


I do not think that the problem is that you are loading an RGBA image and treating it as RGB. This would create a different effect as the image is fully opaque. In this case, every pixel in the black area would be I think either red, green or blue. 

I tried to force how many channels to use in stbi_load() and it worked! Now from your expirience do you now why this might have fixed that? The files have 3 channels only.

The code:


Texture::Texture(std::string path, int unit)
{

	//Try to load the image.
	unsigned char *data = stbi_load(path.c_str(), &m_width, &m_height, &m_channels, 4);

	m_channels = 4;

	std::cout << m_channels << std::endl;

	//Image loaded successfully.
	if (data)
	{

		//Generate the texture and bind it.
		GLCall(glGenTextures(1, &m_id));
		GLCall(glActiveTexture(GL_TEXTURE0 + unit));
		GLCall(glBindTexture(GL_TEXTURE_2D, m_id));

		//Not Transparent texture.
		if (m_channels == 3)
		{
			GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_RGB, GL_UNSIGNED_BYTE, data));
		}

		//Transparent texture.
		else if (m_channels == 4)
		{
			GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data));
		}

		//This image is not supported.
		else
		{
			std::string err = "The Image: " + path;
			err += " , is using " + m_channels;
			err += " channels which are not supported.";
			throw VampEngine::EngineError(err);
		}

		//Texture Filters.
		GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT));
		GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT));
		GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST));
		GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));

		//Generate mipmaps.
		GLCall(glGenerateMipmap(GL_TEXTURE_2D));
	}


	//Loading Failed.
	else
		throw VampEngine::EngineError("There was an error loading image \
		(Myabe the image format is not supported): " + path);



	//Unbind the texture.
	GLCall(glBindTexture(GL_TEXTURE_2D, 0));

	//Free the image data.
	stbi_image_free(data);
}

 


void life()
{
  while (!succeed())
    try_again();

  die_happily();
}

 

It worked with the old image?

Just now, JWColeman said:

It worked with the old image?

Yes, with the ones from paint which was causing the problem. These images have 3 channels (according with stb_image when i don't force how many channels to be used).


void life()
{
  while (!succeed())
    try_again();

  die_happily();
}

 

Well, likely, my best guess, is that stbi_load is putting something other than a null value in the A channel when its not present, therefore your shader handles it normally.

1 minute ago, JWColeman said:

Well, likely, my best guess, is that stbi_load is putting something other than a null value in the A channel when its not present, therefore your shader handles it normally.

Well, how do you explain then the gimp images. They have 3 channels too and they work without the need to force 4 channels. Also in my code, if the file has only 3 channels i'm telling the driver through the glTexImage2D function to handle the data as rgb not rgba. And if 4 as rgba.


void life()
{
  while (!succeed())
    try_again();

  die_happily();
}

 

This topic is closed to new replies.

Advertisement