PDA

View Full Version : Loading image for texture problem



shotoreaper
01-27-2013, 02:40 PM
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++;
}
}

tonyo_au
01-27-2013, 06:14 PM
Can you post your shaders

hlewin
01-27-2013, 11:41 PM
In the last code Fragment you call BindTexture twice: once at the beginning of the Loop and once at the end with the correct texture-unit set. I guess that isn't what you're trying to do: you will end up overriding the result of the last Loop Iteration by calling BindTexture at the beginning of the next.
Move the glActiveTexture line to the beginning of the Loop and remove the second glBindTexture.
The selection done with glActiveTexture stays in effect permanently.

shotoreaper
01-28-2013, 01:14 PM
It is the problem!!!! Thanks!!!