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