Texture mapping acts weird on some images.

Started by
26 comments, last by babaliaris 5 years, 4 months ago

Hello!

My texture problems just don't want to stop keep coming...

After a lot of discussions here with you guys, I've learned a lot about textures and digital images and I fixed my bugs. But right now I'm making an animation system and this happened.

 

Now if you see, the first animation (bomb) is ok. But the second and the third (which are arrows changing direction) are being render weird (They get the GL_REPEAT effect).

In order to be sure, I only rendered (without using my animation system or anything else i created in my project, just using simple opengl rendering code) the textures that are causing this issue and this is the result (all these textures have exactly 115x93 resolution)

Capture.png

I will attach all the images which I'm using.

giphy-27 and giphy-28 are rendering just fine.

All the others not.They give me an effect like GL_REPEAT which I use in my code. This is why I'm getting this result? But my texture coordinates are inside the range of -1 and 1 so why?

My Texture Code:


#include "Texture.h"
#include "STB_IMAGE/stb_image.h"
#include "GLCall.h"
#include "EngineError.h"
#include "Logger.h"



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);
}


Texture::~Texture()
{
	GLCall(glDeleteTextures(1, &m_id));
}

void Texture::Bind(int unit)
{
	GLCall(glActiveTexture(GL_TEXTURE0 + unit));
	GLCall(glBindTexture(GL_TEXTURE_2D, m_id));
}

 

My Render Code:


#include "Renderer.h"
#include "glcall.h"
#include "shader.h"




Renderer::Renderer()
{

	//Vertices.
	float vertices[] =
	{

		//Positions    Texture Coordinates.

		0.0f, 0.0f,    0.0f, 0.0f, //Left Bottom.
		0.0f, 1.0f,    0.0f, 1.0f, //Left Top.
		1.0f, 1.0f,    1.0f, 1.0f, //Right Top.
		1.0f, 0.0f,    1.0f, 0.0f  //Right Bottom.
	};

	//Indices.
	unsigned int indices[] = 
	{
		0, 1, 2, //Left Up Triangle.
		0, 3, 2  //Right Down Triangle.
	};

	
	
	//Create and bind a Vertex Array.
	GLCall(glGenVertexArrays(1, &VAO));
	GLCall(glBindVertexArray(VAO));

	
	//Create and bind a Vertex Buffer.
	GLCall(glGenBuffers(1, &VBO));
	GLCall(glBindBuffer(GL_ARRAY_BUFFER, VBO));

	//Create and bind an Index Buffer.
	GLCall(glGenBuffers(1, &EBO));
	GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO));

	//Transfer the data to the VBO and EBO.
	GLCall(glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW));
	GLCall(glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW));

	//Enable and create the attribute for both Positions and Texture Coordinates.
	GLCall(glEnableVertexAttribArray(0));
	GLCall(glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 4, (void *)0));

	//Create the shader program.
	m_shader = new Shader("Shaders/sprite_vertex.glsl", "Shaders/sprite_fragment.glsl");

}




Renderer::~Renderer()
{
	//Clean Up.
	GLCall(glDeleteVertexArrays(1, &VAO));
	GLCall(glDeleteBuffers(1, &VBO));
	GLCall(glDeleteBuffers(1, &EBO));
	delete m_shader;
}



void Renderer::RenderElements(glm::mat4 model)
{

	//Create the projection matrix.
	glm::mat4 proj = glm::ortho(0.0f, 600.0f, 600.0f, 0.0f, -1.0f, 1.0f);

	//Set the texture unit to be used.
	m_shader->SetUniform1i("diffuse", 0);

	//Set the transformation matrices.
	m_shader->SetUniformMat4f("model", model);
	m_shader->SetUniformMat4f("proj", proj);

	//Draw Call.
	GLCall(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL));
}

 

Vertex Shader:


#version 330 core

layout(location = 0) in vec4 aData;

uniform mat4 model;
uniform mat4 proj;


out vec2 TexCoord;

void main()
{
	gl_Position = proj * model * vec4(aData.xy, 0.0f, 1.0);

	TexCoord = aData.zw;
}

 

Fragment Shader:


#version 330 core

out vec4 Color;
in vec2 TexCoord;

uniform sampler2D diffuse;

void main()
{
	Color = texture(diffuse, TexCoord);
}

 

down.png

left.png

right.png

up.png

giphy-27.png

giphy-28.png


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

  die_happily();
}

 

Advertisement

Are you using individual images for the arrows? Or, are they packed together in an atlas? If you're sure it's not UV's...

 

Try making your own set of arrows in gimp or something, maybe that will change it?

24 minutes ago, JWColeman said:

Are you using individual images for the arrows? Or, are they packed together in an atlas? If you're sure it's not UV's...

 

Try making your own set of arrows in gimp or something, maybe that will change it?

I created the images using paint in Windows 10 and saved them as PNG.

I'm not sure what do you mean by atlas???

Edited:

You mean sprite sheets. No I'm not using them, the images are individual made with windows 10 paint program.


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

  die_happily();
}

 

What I mean is are they all packed into one image, or individual images. It looks like they are individual images so i dont think that is the problem (U/V's)

Just now, JWColeman said:

What I mean is are they all packed into one image, or individual images. It looks like they are individual images so i dont think that is the problem (U/V's)

Yes they are not packed, they are individual images made with paint from windows 10.


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

  die_happily();
}

 

How many channels does your image have? Could there be a problem where you are reading in a channel that isn't there, or, applying a value to a channel that is causing the distortion?

 

IIRC paint does not support alpha channel

4 minutes ago, JWColeman said:

How many channels does your image have? Could there be a problem where you are reading in a channel that isn't there, or, applying a value to a channel that is causing the distortion?

 

IIRC paint does not support alpha channel

it has 3 channels. Also I tried to make this image on gimp and saved it as a PNG and it works just fine.


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

  die_happily();
}

 

So, the file from gimp worked but not from paint?

Just now, JWColeman said:

So, the file from gimp worked but not from paint?

Exactly.


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

  die_happily();
}

 

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?

The quick solution is to just not use any png files that don't have an alpha :)

This topic is closed to new replies.

Advertisement