Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Markitukas en 28 Febrero 2012, 15:51 pm



Título: Insertar imágenes en C con Open GL
Publicado por: Markitukas en 28 Febrero 2012, 15:51 pm
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.


Título: Re: Insertar imágenes en C con Open GL
Publicado por: BlackZeroX en 28 Febrero 2012, 19:22 pm
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
Código:
#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
Código:

#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
Código:

#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
Código:

#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!¡.


Título: Re: Insertar imágenes en C con Open GL
Publicado por: Markitukas en 28 Febrero 2012, 21:26 pm
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.


Título: Re: Insertar imágenes en C con Open GL
Publicado por: Markitukas en 1 Marzo 2012, 15:24 pm
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


Título: Re: Insertar imágenes en C con Open GL
Publicado por: Markitukas en 6 Marzo 2012, 16:36 pm
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.