[opengl] klasy i tekstury

0

zaczynam zabawę z OpneGL i mam następujący problem:
chciałem wszystko z kursu NeHe powoli pozamykać w klasy (później będzie mi wygodniej). Zrobiłem 3 klasy:
Image

#include <windows.h>         // Nagłówek dla Windows
#include <stdio.h>         // Standardowe wejście/wyjście ( NOWE )
#include <gl\gl.h>         // Nagłówek dla OpenGL
#include <gl\glu.h>         // Nagłówek dla GLu32
#include <gl\glaux.h>         // Nagłówek dla GLaux
#include "Image.h"

Image::Image(char *fileName)
{
    this->loadImage(fileName);
}

bool Image::loadImage(char *fileName)
{
    FILE *File=NULL;         // Uchwyt pliku
    if (!fileName)         // Upewnij się że podano nazwę pliku
    {
        this->Success=false;
        return false;         // Jeżeli nie to zwróć NULL
    } 
    
    File=fopen(fileName,"r");         // Sprawdź czy plik istnieje
    
    if (File)         // Czy plik istnieje
    {
        fclose(File);         // Zamknij plik
        this->File=auxDIBImageLoad(fileName);
        this->Success=true;
        return true;         // Załaduj bitmapę i zwróć wskaźnik
    }

    MessageBox(0,"Podany plik nie istnieje!","Błąd",0);
    
    this->Success=false;
    return false;
}

AUX_RGBImageRec *Image::getHandle()
{
    return this->File;
}

bool Image::loaded()
{
     return this->Success;
}

Texture

#include <gl\glaux.h>         // Nagłówek dla GLaux
#include "Texture.h"
#include "Image.h"

Texture::Texture(char * fileName)
{
       Image *img = new Image(fileName);
       static GLuint x=1;
       if (!img->loaded())
       {
          delete img;
          this->Success=false;
          return;
       }
       
       this->File=img->getHandle();
       
       delete img;
       glGenTextures(1, &x);         // Stwórz obiekt tekstury
        // Powiązanie z obiektem tekstury
       glBindTexture(GL_TEXTURE_2D, x);
       
       // Stwórz teksturę
       glTexImage2D(GL_TEXTURE_2D, 0, 3, this->File->sizeX, this->File->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, this->File->data); 
       
       glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);         // Filtrowanie liniowe
       glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);         // Filtrowanie liniowe
       
       this->WhichTexture=x;
       x++;
}

Texture::~Texture()
{
    //zwalniam zasoby
    if (this->File)
    {
        if (this->File->data)
           free(this->File->data);
           
        free(this->File);
    }
}

AUX_RGBImageRec *Texture::getHandle()
{
    return this->File;
}

bool Texture::loaded()
{
     return this->Success;
}

char * Texture::getFileName()
{
     return this->FileName;
}

GLuint Texture::getTexture()
{
     return this->WhichTexture;
}

i Tank

#include <gl\glaux.h>         // Nagłówek dla GLaux
#include "Texture.h"
#include "Tank.h"
#include "header.h"

Tank::Tank(char * fileName, GLfloat x, GLfloat y)
{
      static int countTextures=0;
      t[countTextures] = new Texture(fileName);
      if (!t[countTextures]->loaded())
      {
         this->Success=false;
         delete t;
         return;
      }
      
      this->Success=true;
      this->File=t[countTextures]->getHandle();
      this->WhichTexture=t[countTextures]->getTexture();
      this->X=x;
      this->Y=y;
      
      this->pos=UP;                      //ustawiam pozycję czołgu (wycelowany do góry)
}

Tank::~Tank()
{
    delete t;
}

void Tank::print()
{
    glBindTexture(GL_TEXTURE_2D, this->WhichTexture);         // Wybierz naszą teksturę
    glBegin(GL_QUADS);         // Rysujemy kwadrat
        glVertex3f( X+0.0f, Y+unit, 0.0f);         // górny lewy
        glVertex3f( X+unit, Y+unit, 0.0f);         // górny prawy
        glVertex3f( X+unit, Y+0.0f, 0.0f);         // dolny prawy
        glVertex3f( X+0.0f, Y+0.0f, 0.0f);         // dolny lewy
    glEnd();         // Koniec rysowania kwadratu 
}

void Tank::moveDown()
{
     this->Y-=step;
}

void Tank::moveUp()
{
     this->Y+=step;
}

void Tank::moveRight()
{
     this->X+=step;
}

void Tank::moveLeft()
{
     this->X-=step;
}

bool Tank::loaded()
{
     return this->Success;
}

i potem mam funkcję LoadGLTextures

int LoadGLTextures()         // Ładuj bitmapę i przekształć ją w teksturę
{ 
    int Status=true;         // Status tworzenia tekstury
    
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);         // Filtrowanie liniowe
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);         // Filtrowanie liniowe
    
    tank= new Tank("tank1.bmp",0,0);
    
    if (!tank->loaded())
    {
       return false;
    }

    return Status;         // Zwróć status operacji
} 

a na samym końcu InitGL

int InitGL(GLvoid)    
{ 
    if (!LoadGLTextures())         // Załaduj tekstury ( NOWE )
    {
        return FALSE;         // Jeżeli tekstury nie załadowano zrwóć FALSE ( NOWE )
    }
    glEnable(GL_TEXTURE_2D);         // Włącz nakładanie tekstur ( NOWE )
    
    glShadeModel(GL_SMOOTH); 
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
    glClearDepth(1.0f);                   // ustawienie bufora głebi
    glEnable(GL_DEPTH_TEST);              // włączenie testowania głębi
    glDepthFunc(GL_LEQUAL);               // ustawienie typu testowania
    
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 
    return true;
}

nie wczytuje mi tekstury i nie wiem dlaczego :( na ekranie mam biały kwadracik ;P

0
Texture::Texture(char * fileName)
{
       Image *img = new Image(fileName);
       static GLuint x=1;
       if (!img->loaded())
       {
          delete img;
          this->Success=false;
          return;
       }
       
       this->File=img->getHandle();
       
       delete img;
       glGenTextures(1, &x);         // Stwórz obiekt tekstury
        // Powiązanie z obiektem tekstury
       glBindTexture(GL_TEXTURE_2D, x);
       
       // Stwórz teksturę
       glTexImage2D(GL_TEXTURE_2D, 0, 3, this->File->sizeX, this->File->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, this->File->data);  wg mmnie zle
       

       this->WhichTexture=x; tyy to po co w ogole unsigned int przekazujesz mialoby to sens kiedy whichtexture byloby wskaznikiem
       x++; //x ++ zadne x++
}

				//Generate an ID for texture binding
  glGenTextures(1, &PLAIN_CLOUDS_TEXTURE);           //Texture binding
  glBindTexture(GL_TEXTURE_2D, PLAIN_CLOUDS_TEXTURE);

  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
zamiast glTexImage2D to nizej
  gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, 256, 256, GL_RGB, GL_UNSIGNED_BYTE, texture);

gdzie
char texture[256][256][3];

0

próbowałem się zastosować do Twoich rad i napisałem coś takiego:

Texture::Texture(char * fileName)
{
       Image *img = new Image(fileName);
       static GLuint x=1;
       if (!img->loaded())
       {
          delete img;
          this->Success=false;
          return;
       }
       
       this->File=img->getHandle();
       
       delete img;
       glGenTextures(1, &this->WhichTexture);           //Texture binding
       glBindTexture(GL_TEXTURE_2D, this->WhichTexture);

       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
       //zamiast glTexImage2D to nizej
        gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, this->File->sizeX, this->File->sizeY, GL_RGB, GL_UNSIGNED_BYTE, this->File->data);
       
       this->WhichTexture=x;
       x++;
}

no i dalej nie działa... Wiem, że to jest proste, ale to moje początki z OpenGL :P

0

dochodzi ci w ogole do glubuildmipmaps czy nie ... wlaczyles glenable(GL_TEXTURE_2d);przed narysowaniem kwadratu

jak rysujesz kwadrat

   glBindTexture(GL_TEXTURE_2D, this->WhichTexture);         // Wybierz naszą teksturę
    glBegin(GL_QUADS);         // Rysujemy kwadrat
        glVertex3f( X+0.0f, Y+unit, 0.0f);         // górny lewy
        glVertex3f( X+unit, Y+unit, 0.0f);         // górny prawy
        glVertex3f( X+unit, Y+0.0f, 0.0f);         // dolny prawy
        glVertex3f( X+0.0f, Y+0.0f, 0.0f);         // dolny lewy
    glEnd();         // Koniec rysowania kwadratu 
}

nie ma tam pomiedzy glvertex3f glTexCoord2f(x,y); ktory definiuje koordynaty tekstur

0

Pewnie źle ładujesz teksturę: rozmiary obrazu 2^n, i niekiedy musisz załadować wszystkie mipmapy - przeskalowane wersje tej tekstury.

Potem zwykle używamy glTexCoord2f, albo jakieś automatyczne teksturowanie, np. sferyczne...

0

chciałem kod z kursu http://www.aklimx.sppieniezno.pl/nehepl/display.php?id=6 wepchnąć w klasy...

0

no i masz tam kod:\

    glBegin(GL_QUADS);
        // Przednia ściana
        glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);         // Lewy dolny wierzchołek tekstury i czworokąta
        glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);         // Prawy dolny wierzchołek tekstury i czworokąta
        glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);         // Prawy górny wierzchołek tekstury i czworokąta
        glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);         // Lewy górny wierzchołek tekstury i czworokąta
        // Tylna ściana
        glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);         // Prawy dolny
        glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);         // Prawy górny
        glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);         // Lewy górny 
        glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);         // Lewy dolny
        // Górna ściana
        glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);         // Lewy górny
        glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);         // Lewy dolny
        glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);         // Prawy doln
        glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);         // Prawy górny
        // Dolna ściana
        glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);         // Prawy górny
        glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);         // Lewy górny
        glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);         // Lewy dolny
        glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);         // Prawy dolny
        // Prawa ściana
        glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);         // Prawy dolny
        glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);         // Prawy górny
        glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);         // Lewy górny
        glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);         // Lewy dolny
        // Lewa ściana
        glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);         // Lewy dolny
        glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);         // Prawy dolny
        glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);         // Prawy górny
        glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);         // Lewy górny
    glEnd();

a ty masz

    glBegin(GL_QUADS);         // Rysujemy kwadrat
        glVertex3f( X+0.0f, Y+unit, 0.0f);         // górny lewy
        glVertex3f( X+unit, Y+unit, 0.0f);         // górny prawy
        glVertex3f( X+unit, Y+0.0f, 0.0f);         // dolny prawy
        glVertex3f( X+0.0f, Y+0.0f, 0.0f);         // dolny lewy
    glEnd();         // Koniec rysowania kwadratu 
}

co do tekstur najlepiej łądować tekstury o rozmiarach potegi dwojki np. 128x128

0

no wiem, ja chciałem zrobić coś w 2d...
i nawet w 2d mi tekstury nie chce wczytywać i po to tu napisałem, bo nie mam już pomysłów dlaczego...

0

dla ułatwienia daje kod z głównego pliku (jak to wywołuję)

int DrawGLScene(GLvoid)         // funkcja rysująca
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);         // czyść ekran
    glLoadIdentity();                                           // zresetuj macierz modeli
    glTranslatef(-4.4f,-2.45f,-6.0f);        // Porusz 1.5 w lewo i 6.0 wgłąb
    tank->print();
    
    delete tank;
    return TRUE;                           // wszystko jest ok
} 
int InitGL(GLvoid)    
{ 
    if (!LoadGLTextures())         // Załaduj tekstury ( NOWE )
    {
        return FALSE;         // Jeżeli tekstury nie załadowano zrwóć FALSE ( NOWE )
    }
    glEnable(GL_TEXTURE_2D);         // Włącz nakładanie tekstur ( NOWE )
    
    glShadeModel(GL_SMOOTH); 
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
    glClearDepth(1.0f);                   // ustawienie bufora głebi
    glEnable(GL_DEPTH_TEST);              // włączenie testowania głębi
    glDepthFunc(GL_LEQUAL);               // ustawienie typu testowania
    
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 
    return true;
}
int LoadGLTextures()         // Ładuj bitmapę i przekształć ją w teksturę
{ 
    int Status=true;         // Status tworzenia tekstury
    
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);         // Filtrowanie liniowe
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);         // Filtrowanie liniowe
    
    tank= new Tank("tank1.bmp",0,0);
    
    if (!tank->loaded())
    {
       //MessageBox(hWnd,"Nie udało się wczytać tekstury!","Błąd",0);
       return false;
    }

    return Status;         // Zwróć status operacji
} 

może to wam coś podpowie co robię źle

0

hmm... nie mam pojęcia już co jest źle w moim kodzie...
mam tam 3 klasy to próbowałem wpakować w wczytywanie pliku oraz tworzenie tekstury w jednym
miejscu i stworzyłem jedną klasę do tego (a nie tak jak poprzednio 2) i wyszło mi coś takiego:

Texture.cpp

#include <windows.h>         // nagłówek dla windowsa
#include <stdio.h>         // Standardowe wejście/wyjście ( NOWE )
#include <gl\gl.h>           // nagłówek dla opengl32
#include <gl\glu.h>          // nagłowek dla glu32
#include <gl\glaux.h>        // nagłówek dla glaux
#include "Texture.h"

Texture::Texture(char * fileName)
{
       this->loadTexture(fileName);
}

bool Texture::loadTexture(char * fileName)
{
       static GLuint x=1;
       //wczytuję obrazek
       FILE *File=NULL;         // Uchwyt pliku
       if (!fileName)         // Upewnij się że podano nazwę pliku
       {
          this->Success=false;
          return false;         // Jeżeli nie to zwróć NULL
       } 
       
       File=fopen(fileName,"r");         // Sprawdź czy plik istnieje
       
       if (!File)
       {
          this->Success=false;
          return false;
       }
       
       this->File=auxDIBImageLoad(fileName);
       
       glGenTextures(1, &this->WhichTexture);           //Texture binding
       glBindTexture(GL_TEXTURE_2D, this->WhichTexture);

       glTexImage2D(GL_TEXTURE_2D, 0, 3,this->File->sizeX, this->File->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, this->File->data); 
       
       glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);         // Filtrowanie liniowe
       glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);         // Filtrowanie liniowe
        
       this->WhichTexture=x;
       x++;
}
Texture::~Texture()
{
    //zwalniam zasoby
    if (this->File)
    {
        if (this->File->data)
           free(this->File->data);
           
        free(this->File);
    }
}

AUX_RGBImageRec *Texture::getHandle()
{
    return this->File;
}

bool Texture::loaded()
{
     return this->Success;
}

char * Texture::getFileName()
{
     return this->FileName;
}

GLuint Texture::getTexture()
{
     return this->WhichTexture;
}

i plik nagłówkowy Texture.h

#ifndef H_TEXTURE
#define H_TEXTURE
#include <windows.h>         // nagłówek dla windowsa
#include <gl\gl.h>           // nagłówek dla opengl32
#include <gl\glu.h>          // nagłowek dla glu32
#include <gl\glaux.h>        // nagłówek dla glaux
class Texture
{
      private:
              AUX_RGBImageRec *File;
              char *FileName;
              bool Success;
              GLuint WhichTexture;  //która to tekstura
      
      public:
             Texture(char * fileName);
             ~Texture();
             char * getFileName();
             AUX_RGBImageRec *getHandle();
             bool loaded();
             GLuint getTexture();
             bool loadTexture(char * fileName);
};
#endif

na pewno źle wczytuję teksturę bo jej po prostu nie ma!

na kursie NeHe to wygląda tak:

int LoadGLTextures()         // Ładuj bitmapę i przekształć ją w teksturę
{ 
    int Status=FALSE;         // Status tworzenia tekstury
    AUX_RGBImageRec *TextureImage[1];         // Rekord dla naszego obrazka
    memset(TextureImage,0,sizeof(void *)*1);         // Wyzeruj wskaźnik
        // Załaduj obrazek
    if (TextureImage[0]=LoadBMP("Data/NeHe.bmp"))
    {
        Status=TRUE;         // Ustaw Status na true (powodzenie)
        glGenTextures(1, &texture[0]);         // Stwórz obiekt tekstury
        // Powiązanie z obiektem tekstury
        glBindTexture(GL_TEXTURE_2D, texture[0]); 
        // Stwórz teksturę
        glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); 
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);         // Filtrowanie liniowe
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);         // Filtrowanie liniowe
    } 

    if (TextureImage[0])         // Jeżeli tekstura istnieje
    {
        if (TextureImage[0]->data)         // Jeżeli obrazek tekstury istnieje
        {
            free(TextureImage[0]->data);         // Zwolnij pamięć obrazka tekstury
        }
        free(TextureImage[0]);         // Zwolnij strukturę obrazka
    } 
    return Status;         // Zwróć status operacji
} 

ma ktoś jakiś pomysł?

1 użytkowników online, w tym zalogowanych: 0, gości: 1