Hi all!
Im trying to draw a cube with two different textures
the problem is that actually is being drawing two textures but with the same image.
How can i draw two textures with different images?
This is the class that actually draws on the screen
#include "sg3d.h"
#include <SDL/SDL.h>
#include "gl_util.h"
#include "immediate.h"
#include "DisplayList.h"
#include "vertex_buffer_object.h"
#include "loader.h"
#include "Texture.h"
#include <iostream>
namespace topicos
{
SG3D::SG3D()
{
_end = false;
_rotation = 0;
start();
}
SG3D::~SG3D()
{
for (unsigned i = 0; i < _sceneObject.size(); ++i)
{
delete _sceneObject[i];
}
}
void SG3D::start()
{
unsigned w, h;
w = 800;
h = 600;
_sdl.videoMode(w, h);
GLUtil::initGL();
GLUtil::setView(w, h);
GLUtil::initGlew();
initTexture();
// initObjects();
// initLight();
// initShader();
mainLoop();
}
void SG3D::initShader()
{
Shader *sh = new Shader();
sh->makeFragmentShader("build\\shader\
oShader.frag");
sh->makeVertexShader("build\\shader\
oShader.vert");
sh->ativarShader();
}
void SG3D::initLight()
{
//posicao da luz. Um vetor apontando para baixo.
float light_position[] = { 1.f, 1.f, 1.f, 0.f};
//cor ambiente da luz zero
float light_ambient[] = {.0f, .0f, .0f, 1.f};
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
//cor difusa da luz zero
float light_diffuse[] = { .9f, 1.f, .9f, 1.f};
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
//cor especular da luz zero
float light_specular[] = { 1.f, 1.f, 1.f, 1.f};
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
//posicao da luz. Se w = 0 -> luz direcional; se w = 1 -> luz pontual.
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
float mat_specular[] = {1.f, 1.f, 1.f, 1.f};
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
float shininess[] = {50.f};
glMaterialfv(GL_FRONT, GL_SHININESS, shininess);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
}
void SG3D::initTexture()
{
///drawing a simple cube with texture
text = new Texture();
index_texture = text->geraTextureDePNG();
}
/**
* Inicia aqui os diferentes objetos
**/
void SG3D::initObjects()
{
std::cout << "loading obj" << std::endl;
Mesh m = Loader::loadObj("build/obj/cavalo1.obj");
std::cout << " end." << std::endl;
std::cout << "creating Immediate mode" << std::endl;
_sceneObject.push_back(new Immediate(m));
std::cout << " end." << std::endl;
std::cout << "creating Display List mode" << std::endl;
Object* dl = new DisplayList(m);
dl->translate(Vec3(-8, 0, 0));
dl->color(Vec3(1, 0, 0));
dl->rotate(-90, Vec3(1, 0, 0));
_sceneObject.push_back(dl);
std::cout << " end." << std::endl;
std::cout << "creating VBO mode" << std::endl;
Object* vbo = new Vertex_buffer_object(m);
vbo->translate(Vec3(8, 0, 0));
vbo->color(Vec3(0, 1, 0));
vbo->rotate(-90, Vec3(1, 0, 0));
_sceneObject.push_back(vbo);
std::cout << " end." << std::endl;
}
/**
* Para evitar que o sistema de eventos
* fique complicado ele nao vai ficar na classe MediaControl,
* mas deveria ficar lah. Assim evitaria o include de SDL
* nesta classe.
**/
void SG3D::mainLoop()
{
SDL_Event e;
while(!_end)
{
while(SDL_PollEvent(&e))
{
switch(e.type)
{
case SDL_QUIT:
_end = true;
break;
case SDL_KEYDOWN:
switch(e.key.keysym.sym)
{
case SDLK_ESCAPE:
_end = true;
break;
} //END keydow check
break;
default:
break;
} //END type check
}//END while poll
update();
draw();
}//END while end
_sdl.quit();
}
/**
* Funcao responsavel por atualizacoes.
*
**/
void SG3D::update()
{
//Esse update eh para bonito. Nao seria legal ficar fazendo esse tipo de verificacao dentro do update.
if (_sceneObject.size() == 0)
{
std::cout << "Voce nao pode acessar o elemento zero. O tamanho da sua lista eh zero" << std::endl;
}
else
{
Object* obj = _sceneObject[0]; //Pegando o elemento zero (Erro caso não tenhamos objetos)
obj->rotate((_rotation++), Vec3(1, 0, 0)); //Rodando o elemento zero.
}
}
void SG3D::draw()
{
GLUtil::resetDraw();
/* for (std::vector<Object*>::iterator it = _sceneObject.begin(); it != _sceneObject.end(); ++it)
{
(*it)->draw();
}*/
text->TexturedCube(index_texture);
_sdl.swap();
}
}
and this is the texture class where the cube texture is built.
#include "Texture.h"
#include <iostream>
#include <string>
Texture::Texture()
{
}
unsigned int* Texture::geraTextureDePNG()
{
unsigned int _tex[2];
std::string s("data/test.png");
SDL_Surface* surface = loadImage(s);
//IMG_Load carrega uma imagem (pode ser qualquer uma, mas usem png para garantir o resto do código).
int _imgW = surface->w; //tamanhos.
int _imgH = surface->h;
glGenTextures(1, &_tex[2]); //gera id de textura (lembrando que _tex é um unsigned int).
glBindTexture(GL_TEXTURE_2D, _tex[0]); //inicia o uso da texturo com o id gerado
//usa passa a imagem para a textura
glTexImage2D(GL_TEXTURE_2D, 0, 4, surface->w, surface->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);
//muda alguns parametros
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
SDL_FreeSurface(surface); //destrói a imagem carregada.
surface = loadImage("data/wisp.png");
_imgW = surface->w; //tamanhos.
_imgH = surface->h;
glBindTexture(GL_TEXTURE_2D, _tex[1]);
glTexImage2D(GL_TEXTURE_2D, 0, 4, surface->w, surface->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
SDL_FreeSurface(surface);
return _tex;
}
Texture::~Texture()
{
//termina o uso da textura.
glBindTexture(GL_TEXTURE_2D, 0);
}
SDL_Surface* Texture::loadImage(const std::string& path)
{
SDL_Surface* surface = IMG_Load(path.c_str());
if(!surface)
{
printf("IMG_Load: %s
", IMG_GetError());
// handle error
}
return surface;
}
void Texture::TexturedCube(unsigned int* _tex)
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glLoadIdentity ( );
glPushMatrix();
glTranslatef ( 0.0, 0.0, -5.0 );
//glRotatef ( xrot, 1.0, 0.0, 0.0 );
glRotatef ( yrot, 0.0, 1.0, 0.0 );
// glRotatef ( zrot, 0.0, 0.0, 1.0 );
glEnable ( GL_TEXTURE_2D );
// define qual das texturas usar
glBindTexture ( GL_TEXTURE_2D, _tex[0] );
glBegin ( GL_QUADS );
// Front Face
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glBindTexture ( GL_TEXTURE_2D, _tex[1] );
// Back Face
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
// Top Face
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
// Bottom Face
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
glPopMatrix();
xrot+=0.5f;
yrot+=0.5f;
zrot+=0.5f;
}
thanks!