I have a class with the Load texture that is responsible for loading an image and add the pixels of this to a variable char * pixels. Then, in the main class, Engine class, I have another method that adds this texture loaded to a std::list , so that once you have loaded all the textures generate. The problem is that all objects that use a texture, appear with the last texture I uploaded.
In the method Engine::CreateWorld() I add the objets for my 3D World:
void Engine::CreateWorld(void)
{
GameScreen *gs1 = new GameScreen("hola");
PushGameScreen(gs1);
Camera *cam = new Camera();
gs1->AddComponent(cam);
cam->setPosition(glm::vec3(0.0, 2.0, 4.0));
Plane* pln = new Plane();
gs1->AddComponent(pln);
pln->setPosition(glm::vec3(0.0f,-1.0f,0.0f));
Cube* cb = new Cube();
gs1->AddComponent(cb);
cb->setPosition(glm::vec3(1.2f));
cb->setScale(glm::vec3(.2f));
}
Every time I add a Component to GameScreen, it call the Load method:
Plane.cpp
void Plane::Load(void)
{
mesh = getParent()->getEngine()->content.Load<Mesh>("Models/plane.obj");
ApplyMaterials();
}
void Plane::ApplyMaterials()
{
Texture_mat *texturemat = new Texture_mat; // Instanciamos el material
getParent()->AddComponent(texturemat); // Añadimos el material a los component para que se cargue
texturemat->setDiffuseTexture("Textures/plane.png");
materials.insert(std::pair<std::string, Material*>("Material.005",texturemat)); //Añadimos el material e indicamos odnde se tiene que aplicar
}
Cube.cpp
void Cube::Load(void)
{
mesh = getParent()->getEngine()->content.Load<Mesh>("Models/untitled.obj");
ApplyMaterials();
}
void Cube::ApplyMaterials()
{
Color_mat *colormat = new Color_mat; // Instanciamos el material
getParent()->AddComponent(colormat); // Añadimos el material a los component para que se cargue
Texture_mat *texturemap = new Texture_mat;
getParent()->AddComponent(texturemap); //Añadimos el material a los component
materials.insert(std::pair<std::string, Material*>("Material.002",colormat)); //Añadimos el material e indicamos odnde se tiene que aplicar
materials.insert(std::pair<std::string, Material*>("Material.003",texturemap));
}
Plane and Cube use Texture material:
void Texture_mat::Load(void)
{
shader = getParent()->getEngine()->content.Load<Shader>("Shaders/SimpleShader.glsl"); //texture shader
Material::Load();
diffvalue = getParent()->getEngine()->LoadTexture( //return texture value for to use in glUniform1i
getParent()->getEngine()->content.Load<Texture>("Textures/cube.bmp") //return texture loaded
);
DiffuseUniformLocation = shader->GetUniformLocation("texture0"); // get the texture uniform location form shader
ExitOnGLError("Error: Could not load texture");
}
void Texture_mat::Prepare3dDraw(glm::mat4 ModelMatrix)
{
Material::Prepare3dDraw(ModelMatrix); //
glUniform1i(DiffuseUniformLocation, diffvalue);
}
Texture.cpp
#include "gl/glew.h"
#include "../../include/Texture.hpp"
#include "../../include/Util.hpp"
#include "../../include/IL/il.h"
Texture::Texture(){};
Texture::~Texture()
{
};
void Texture::Load(std::string filename)
{
name = filename;
ILuint imageID;
ilGenImages(1, &imageID);
ilBindImage(imageID);
ILboolean success = ilLoadImage(filename.c_str());
if(!success)
{
ExitOnError("ERROR: Imagen no cargada adecuadamente");
}
width = ilGetInteger(IL_IMAGE_WIDTH);
height = ilGetInteger(IL_IMAGE_HEIGHT);
ILint image_format = ilGetInteger(IL_IMAGE_FORMAT);
ILint image_type = ilGetInteger(IL_IMAGE_TYPE);
pixels = new BYTE[width*height*3];
ilCopyPixels(0,0,0,width,height, 1, IL_RGB, IL_UNSIGNED_BYTE, pixels);
ilBindImage(0);
ilDeleteImage(imageID);
}
bool operator == (const Texture &tex1, const Texture &tex2)
{
return (
tex1.name == tex2.name
);
};
Engine.cpp
GLint Engine::LoadTexture(Texture* n_tex)
{
int c = 0;
for (std::list<Texture*>::iterator it = texturelist.begin(); it != texturelist.end(); it++)
{
if( (*it)->name == n_tex->name )
{
return (GLint) c;
}
c++;
}
texturelist.push_back(n_tex);
return (GLint) texturelist.size()-1;
}
After the method CreateWorld(), call to GenerateTextures()
void Engine::GenerateTextures()
{
// Gneramos las texturas para OpenGL
GLuint texturesID[texturelist.size()];
glGenTextures(texturelist.size(), texturesID);
int c = 0;
foreach(std::list<Texture*>, texturelist)
{
glBindTexture(GL_TEXTURE_2D, texturesID[c]);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB, (*it)->width, (*it)->height, 0, GL_RGB,GL_UNSIGNED_BYTE,(*it)->pixels );
ExitOnGLError("Error: Could not create the texture with glTexImage2D");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glGenerateMipmap(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0+c);
glBindTexture(GL_TEXTURE_2D, texturesID[c]);
ExitOnGLError("Error: Could not bind the texture");
c++;
}
}