Insertar imágenes en C con Open GL

Iniciado por Markitukas, 28 Febrero 2012, 15:51 PM

0 Miembros y 2 Visitantes están viendo este tema.

Markitukas

Hola gente, estoy haciendo un juego tipo pc futbol y la parte programación esta bastante aceptable ya, pero me quise adentrar a la programación Básica y resulta que no puedo poner por ejemplo en un rectángulo una imagen de una cancha de futbol que quiero poner, alguien me puede dar una mano?

Muchas gracias.

BlackZeroX

#1
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!¡.
The Dark Shadow is my passion.

Markitukas

Muchísimas gracias Man! ya las voy a leer tranquilo y voy a intentar, si tengo alguna duda te consulto. Muchísimas gracias por respodener tan rápido un abrazo.

Markitukas

Buenas acabo de ver el post que me pasaste y sigo con una duda muy grande. Cuando le paso el archivo? por que es como si esa parte todo el mundo se la salteara y la verdad que se me complica mucho. Muchos tutoriales me dicen que cargue la imagen en memoria y ninguna de las que hago me funciona. Un abrazo.

Saludos

Markitukas

Aver mirando un tutorial trate de hacer esto pero sigue sin aparecer mi textura, me esta volviendo loco...

#include <stdio.h>
#include <windows.h>
#include "GL/glut.h"

typedef struct // Utilizamos esta estructura
{
GLubyte *imageData;
GLuint bpp;
GLuint width;
GLuint height;
GLuint texID;
} Imagen;
int textura;

void *CargaTGA(char *cancha,int *tam)
{
GLubyte TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0};
GLubyte TGAcompare[12];
GLubyte header[6];
GLuint bytesPerPixel;
GLuint imageSize;
GLuint temp,i;
GLuint type=GL_RGBA;
Imagen texture;
GLubyte *aux;
FILE *file = fopen(cancha, "rb");
if (file == NULL)
return NULL;
/* Esto abre y comprueba que es un TGA */
fread(TGAcompare,1,sizeof(TGAcompare),file);
if (memcmp(TGAheader,TGAcompare,sizeof(TGAheader))!=0)
return NULL;

/* Leemos la cabecera*/
fread(header,1,sizeof(header),file);
/* Determinamos el tamaño */
texture.width = header[1] * 256 + header[0];
texture.height = header[3] * 256 + header[2];

/* Vemos las características y comprobamos si son correctas*/
if( texture.width <=0 ||texture.height <=0 ||texture.width >256 ||texture.height !=texture.width ||( header[4]!=32))
{
fclose(file);
return NULL;
}
/* Calculamos la memoria que será necesaria */
texture.bpp = header[4];
bytesPerPixel = texture.bpp/8;
imageSize = texture.width*texture.height*bytesPerPixel;

/* Reservamos memoria */
texture.imageData=(GLubyte *)malloc(imageSize);

/* Cargamos y hacemos alguna comprobaciones */
if( texture.imageData==NULL ||
fread(texture.imageData, 1, imageSize, file)!=imageSize)
{
if(texture.imageData!=NULL)
free(texture.imageData);
fclose(file);
return NULL;
}


/* El TGA viene en formato BGR, lo pasamos a RGB */
for(i=0; i<(GLuint)(imageSize); i+=bytesPerPixel)
{
temp=texture.imageData;
texture.imageData = texture.imageData[i + 2];
texture.imageData[i + 2] = temp;
}
fclose (file);

/* Ahora, cambiamos el orden de las líneas, como si hiciesemosun flip vertical. */
aux=(GLubyte *)malloc(imageSize);
for(i=0; i<texture.height; i++)
memcpy(&aux[imageSize-((i+1)*texture.width*4)],&texture.imageData[i*texture.width*4],texture.width*4);

/* tam devolverá el tamaño */
*tam=texture.width;

/* Liberamos memoria */
free(texture.imageData);

/* Todo fue bien!*/
return aux;

}

int carga_texturas(void) {

Imagen texture;
int tam;
texture.imageData=(char *)CargaTGA("cancha.tga",&tam);if (texture.imageData == NULL) {
return -1;
}

/* Genera una textura, referenciada por el entero textura */
glGenTextures (1, &textura);

/* Esta función indica que será una textura en 2D. Las siguientes funciones hará referncia a esta textura */
glBindTexture (GL_TEXTURE_2D, textura);

/* Aquí ajustamos algunos parámetros de la textura, concretamente los filtros */
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);

/* Con esta función de GLU, creamos un mipmap. Nótese que especificamos el tamaño con tam, que devolvia la función CargaTGA*/
gluBuild2DMipmaps (GL_TEXTURE_2D, 4, tam, tam, GL_RGBA,GL_UNSIGNED_BYTE, texture.imageData);

/* Liberamos la memoria que ya no utilizaremos */
free(texture.imageData);

return 0;
}

      
  void display()
  {
   
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glClear(GL_COLOR_BUFFER_BIT);
    glColor4f(0.0, 0.5, 0.2,0.0);
   glBindTexture(GL_TEXTURE_2D, textura);
    glBegin(GL_POLYGON);
      glTexCoord2f(0.0, 0.0);
        glVertex2f(-0.5, 0.9);
      glTexCoord2f(1.0, 0.0);
      glVertex2f(0.5, 0.9);
      glTexCoord2f(1.0, 1.0);
        glVertex2f(0.5, -0.9);
      glTexCoord2f(0.0, 1.0);
        glVertex2f(-0.5,-0.9);
    glEnd();
    glColor3f(1.0, 1.0, 1.0);
    glTranslatef(0.1,0.1,0);
    glPushMatrix();
    glTranslatef(0.1,0.1,0.1);
    glutSolidSphere(0.02,300,300);
    glPopMatrix();
    glutSolidSphere(0.02,300,300);

   glFlush();
  }

  void init()
  {
    glClearColor(0.000, 0.110, 0.392, 0.0); // JMU Gold

    glColor3f(0.314, 0.314, 0.000); // JMU Purple

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(-1.0, 1.0, -1.0, 1.0);
  }

  int main(int argc, char** argv)
  {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(640, 480);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("Test");
    glutDisplayFunc(display);
    init();
    glutMainLoop();
  }

Aver si me pueden ayudar. Saludos.