La pagina de Nehe tiene buenas guías mírate estos:
http://nehe.gamedev.net/tutorial/lessons_06__10/17010/
1ro debes cargar la imagen:
glGenTextures(1 , &this->uiID); // Generamos la ID de la textura
glBindTexture(GL_TEXTURE_2D , this->uiID-1);
glTexParameteri(GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR);
// Una vez creado el ID para la tectura debes cargarla y asignarla a este ID...
::glBindTexture( GL_TEXTURE_2D, this->uiID);
::glTexImage2D(GL_TEXTURE_2D,
0,
3,
oBMPReader.getInfo().bmiHeader.biWidth,
oBMPReader.getInfo().bmiHeader.biHeight,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
(GLvoid*)oBMPReader.getBytes().lpData);
Para implementarla debes usar
if(this->uiID > 0 && this->enabled)
::glBindTexture(GL_TEXTURE_2D , this->uiID - 1);
else
::glBindTexture(GL_TEXTURE_2D , 0);
Para poderla dibujar debes definir antes los vértices que definen la textura a implementar y (estos vertices pueden inclusive estirar la textura) de la textura:
glTexCoord3f();
Antes de llamar a
glVertex3f();
Te dejo mis clases con las que realizo estas acciones:
CTexture.h
#ifndef CTexture_H
#define CTexture_H
#include "native.h"
#include "_Formatos/mBitmap/CBMPReader.h"
#include <windows.h>
#include <GL/glut.h>
class CGL_Texture;
typedef CGL_Texture CGL_TEXTURE, *LPCGL_TEXTURE;
class CGL_Texture: public Object
{
private:
unsigned int uiID;
void create();
bool bLoadBMP;
public:
CGL_Texture();
~CGL_Texture();
bool itsLoad();
bool enabled;
void remove();
void use();
bool loadBMP(const char* szFile);
};
#endif // CTexture_H
CTexture.cpp
#include "OpenGL/ctexture.h"
//---------------------------------------------------------------
// Nombre: Constructor
// Descripcion: Constructor de la clase. Inicializa las variables
// Parametros: Ninguno
//---------------------------------------------------------------
CGL_Texture::CGL_Texture():
Object()
{
this->uiID = 0;
this->enabled = false;
this->bLoadBMP = false;
}
//---------------------------------------------------------------
// Nombre: Destructor
// Descripcion: Destructor de la clase. Elimina la textura
// Parametros: Ninguno
//---------------------------------------------------------------
CGL_Texture::~CGL_Texture()
{
this->remove();
}
//---------------------------------------------------------------
// Nombre: Crear
// Descripcion: Establece los parámetros GL para cargar
// Parametros:
// char* szNombreFichero: Nombre del fichero a cargar
//---------------------------------------------------------------
void CGL_Texture::create()
{
this->remove();
::glGenTextures(1 , &this->uiID); // Generamos la ID de la textura
this->uiID++; // Usamos un offset de +1 para diferenciar del estado no-inicializado
::glBindTexture(GL_TEXTURE_2D , this->uiID-1);
::glTexParameteri(GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR);
::glTexParameteri(GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR);
}
//---------------------------------------------------------------
// Nombre: Elimina
// Descripcion: Elimina la textura
// Parametros: Ninguno
//---------------------------------------------------------------
void CGL_Texture::remove()
{
if( this->uiID > 0)
::glDeleteTextures(1 , &(--this->uiID));
this->uiID = 0;
this->bLoadBMP = false;
}
//---------------------------------------------------------------
// Nombre: Usa
// Descripcion: Usa la textura actual
// Parametros: Ninguno
//---------------------------------------------------------------
void CGL_Texture::use()
{
if(this->uiID > 0 && this->enabled)
::glBindTexture(GL_TEXTURE_2D , this->uiID - 1);
else
::glBindTexture(GL_TEXTURE_2D , 0);
}
//---------------------------------------------------------------
// Nombre: CargarBMP
// Descripcion: Carga un fichero BMP y almacena los datos
// Parametros: Ninguno
//---------------------------------------------------------------
bool CGL_Texture::loadBMP(const char *szFile)
{
CBMPReader oBMPReader;
this->remove();
if(oBMPReader.loadBMP(szFile) != NULL)
{
this->create();
::glBindTexture( GL_TEXTURE_2D, this->uiID);
::glTexImage2D(GL_TEXTURE_2D,
0,
3,
oBMPReader.getInfo().bmiHeader.biWidth,
oBMPReader.getInfo().bmiHeader.biHeight,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
(GLvoid*)oBMPReader.getBytes().lpData);
return this->bLoadBMP = true;
}
return this->bLoadBMP = false;
}
//---------------------------------------------------------------
// Nombre: itsLoad
// Descripcion: Esta cargada la textura en memoria?.
// Parametros: Ninguno
//---------------------------------------------------------------
bool
CGL_Texture::itsLoad()
{
return this->bLoadBMP;
}
CDrawn.h
#ifndef CGL_DRAWN_H
#define CGL_DRAWN_H
#include <windows.h>
#include <stack>
#include "native.h"
#include "OpenGL/cglobject.h"
using namespace std;
class CGL_Drawn;
typedef CGL_Drawn CGL_DRAWN, *LPCGL_DRAWN;
class CGL_Drawn: public Object, public stack<LPCGL_OBJECT>
{
public:
CGL_Drawn();
CGL_Drawn(int idWin);
virtual ~CGL_Drawn();
int draw();
int draw(int idWin);
protected:
int idWin;
private:
};
#endif // CGL_DRAWN_H
CDrawn.cpp
#include "OpenGL/cdrawn.h"
#include <iostream>
#include <algorithm>
using namespace std;
CGL_Drawn::CGL_Drawn(int idWin):
Object()
{
this->idWin = idWin;
//ctor
}
CGL_Drawn::CGL_Drawn():
Object(), idWin(0)
{
//ctor
}
CGL_Drawn::~CGL_Drawn()
{
//dtor
}
int CGL_Drawn::draw()
{
return this->draw(idWin);
}
int CGL_Drawn::draw(int idWin)
{
LPCGL_OBJECT lpCGL_Object = NULL;
LPCASE_MATERIAL lpMaterial = NULL;
LPCASE_MESH lpCASE_Mesh = NULL;
TAnimObject* lpAniObj = NULL;
int iRet = 0,
n = 0,
tv = 0,
v = 0;
int i = 0,
j = 0;
float fMax = 0.0f;
::glutPushWindow();
::glutSetWindow(idWin);
while(!this->empty())
{
::glPushMatrix();
lpCGL_Object = this->top();
lpCASE_Mesh = lpCGL_Object->lpCASE_Object->lpMesh;
::glTranslatef(lpCGL_Object->x, lpCGL_Object->y, lpCGL_Object->z);
/// Animación...
lpAniObj = &lpCGL_Object->lpCASE_Object->udtAnimate.udtAnimObject;
if (lpAniObj->iPosCount)
{
if (lpAniObj->iStepPos >= lpAniObj->iPosCount)
lpAniObj->iStepPos = 0;
::glTranslatef(lpAniObj->lpPosTrack[i]->fPosition[0],
lpAniObj->lpPosTrack[i]->fPosition[1],
lpAniObj->lpPosTrack[i]->fPosition[2]);
lpAniObj->iStepPos++;
}
else
{
::glTranslatef(lpCGL_Object->lpCASE_Object->lpNodeTM->fTMPos[0],
lpCGL_Object->lpCASE_Object->lpNodeTM->fTMPos[1],
lpCGL_Object->lpCASE_Object->lpNodeTM->fTMPos[2]);
}
if (lpAniObj->iRotCount)
{
if (lpAniObj->iStepRot >= lpAniObj->iRotCount)
lpAniObj->iStepRot = 0;
::glRotatef(lpAniObj->lpRotTrack[lpAniObj->iStepRot]->fAngle,
lpAniObj->lpRotTrack[lpAniObj->iStepRot]->fAxis[0],
lpAniObj->lpRotTrack[lpAniObj->iStepRot]->fAxis[1],
lpAniObj->lpRotTrack[lpAniObj->iStepRot]->fAxis[2]);
lpAniObj->iStepPos++;
}
else
{
::glRotatef(lpCGL_Object->lpCASE_Object->lpNodeTM->fTMRotAngle,
lpCGL_Object->lpCASE_Object->lpNodeTM->fTMRotAxis[0],
lpCGL_Object->lpCASE_Object->lpNodeTM->fTMRotAxis[1],
lpCGL_Object->lpCASE_Object->lpNodeTM->fTMRotAxis[2]);
}
/// End
//cout << lpCGL_Object->lpCASE_Object->sNodeName << "\t" << lpCGL_Object->lpCASE_Object->iMaterialRef <<endl;
if (lpCGL_Object->lpCASE_Object->iMaterialRef != -1)
lpMaterial = lpCGL_Object->lpCASE_Object->lpModels->listMaterials[lpCGL_Object->lpCASE_Object->iMaterialRef];
if (lpMaterial)
{
::glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, lpMaterial->fMaterialAmbient);
::glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, lpMaterial->fMaterialDiffuse);
::glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, lpMaterial->fMaterialSpecular);
::glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, lpMaterial->fMaterialShine);
}
if (lpMaterial)
::glColor3fv(lpMaterial->fMaterialDiffuse);
// Aplicar color o Textura al objeto.
::glColor3fv(lpCGL_Object->lpCASE_Object->fWireFameColor);
// Malla de Poligonos.
for(v = 0 ; v < lpCASE_Mesh->listFace.size(); ++v)
{
::glBegin(GL_TRIANGLES);
for(n = 0 ; n < 3 ; ++n) // Vertices(Triangulos).
{
if(lpCGL_Object->oTexture.itsLoad())// && lpCGL_Object->oTexture.enabled) // Textura.
{
switch(n)
{
case 0: tv = lpCASE_Mesh->listTFace[v]->ia; break;
case 1: tv = lpCASE_Mesh->listTFace[v]->ib; break;
case 2: tv = lpCASE_Mesh->listTFace[v]->ic; break;
}
lpCGL_Object->oTexture.use();
::glTexCoord3f(lpCASE_Mesh->listTVertex[tv]->fx,
lpCASE_Mesh->listTVertex[tv]->fy,
lpCASE_Mesh->listTVertex[tv]->fz);
} // Textura
//cout << lpCASE_Mesh->listFace.size() << "\t" << n << "\t" << v << "\t" << endl;
switch(n)
{
case 0: tv = lpCASE_Mesh->listFace[v]->ia; break;
case 1: tv = lpCASE_Mesh->listFace[v]->ib; break;
case 2: tv = lpCASE_Mesh->listFace[v]->ic; break;
}
::glVertex3f(lpCASE_Mesh->listVertex[tv]->fx,
lpCASE_Mesh->listVertex[tv]->fy,
lpCASE_Mesh->listVertex[tv]->fz);
}
} // v < lpCASE_Mesh->ListFace.size();
::glEnd();
iRet++;
this->pop();
::glPopMatrix();
}
// cout << fMax << endl;
::glutPopWindow();
return iRet;
}
P.D.: No son todos los archivos de mi proyecto... solo te los dejo para/como Guía.
Dulces Lunas!¡.