2011-01-02 1 views
0

Je voudrais charger des textures, puis les faire utiliser par plusieurs objets. Cela fonctionnerait-il?C++: question de référence et de pointeur (exemple concernant OpenGL)

class Sprite 
{ 
    GLuint* mTextures; // do I need this to also be a reference? 

    Sprite(GLuint* textures) // do I need this to also be a reference? 
    { 
     mTextures = textures; 
    } 

    void Draw(textureNumber) 
    { 
     glBindTexture(GL_TEXTURE_2D, mTextures[ textureNumber ]); 
     // drawing code 
    } 
}; 

// normally these variables would be inputed, but I did this for simplicity. 
const int NUMBER_OF_TEXTURES = 40; 
const int WHICH_TEXTURE = 10; 

void main() 
{ 
    std::vector<GLuint> the_textures; 
    the_textures.resize(NUMBER_OF_TEXTURES); 

    glGenTextures(NUMBER_OF_TEXTURES, &the_textures[0]); 

    // texture loading code 

    Sprite the_sprite(&the_textures[0]); 
    the_sprite.Draw(WHICH_TEXTURE); 
} 

Et est-il une autre façon je le faire, même si cela fonctionnerait?

Merci.

+1

Juste un Remarque. Si vous définissez (vs déclarant) quelque chose comme une référence, cela signifie généralement que quelque chose ne va pas avec votre conception. – Falmarri

+0

@Falmarri, que voulez-vous dire? Êtes-vous en train de suggérer que le fait d'avoir un champ de classe comme référence ou une variable locale comme référence est faux? – Kos

+0

@Kos: Je parle de définir un champ de classe comme référence. – Falmarri

Répondre

2
  1. oui, ce serait travail
  2. pas besoin de les faire être une référence: vous magasin/pass une copie d'un pointeur (il est rapide), et vous ne prévoyez pas de changer cette pointeur à l'extérieur
  3. Il existe de nombreuses façons différentes de le faire, et la bonne dépend de vos autres exigences de code.

par exemple. vous pouvez utiliser une instance globale de textures:

textures.cpp:

static std::vector load_once_textures(); 
std::vector<GLuint> const& get_textures() 
{ 
    static std::vector<GLuint> const the_textures = load_once_textures(); 
    return the_textures; 
} 

std::vector load_once_textures() 
{ 
    // loading 
} 

textures.h

std::vector<GLuint> const& get_textures(); 

c'est une approche simple et assez sûr, car les textures seront chargés une fois et le chargement ne pose pas de problème d'ambiguïté de l'ordre d'initialisation statique

+0

très intéressant. Merci! –

2

Ce cas particulier devrait fonctionner. Cependant, dès que "the_textures" est hors de portée, le pointeur maintenu par Sprite devient invalide. Ce serait la même chose, même si c'était une référence. Dans ce cas, je vous suggère de mettre à la place le std :: vector <> dans la classe Sprite, et de le posséder et de le gérer par cette instance de classe.

+0

oui, je réalise le problème de la portée. mais dans ce cas, il est dans main(), donc il ne sortira jamais de la portée. Pour ce qui est de placer le 'vector' dans la classe' Sprite', je devrais charger les textures à nouveau pour chaque sprite, ce qui serait mauvais pour la performance. c'est pourquoi je voulais faire quelque chose comme mon OP. Cependant, cela fonctionnerait-il pour la classe 'Sprite' pour avoir une référence au vecteur? –

+0

Vos textures ne sont que des identifiants GLuint utilisés par OpenGL, donc la copie du vecteur dans l'objet Sprite ne les chargera plus. – tibur

+0

@tibur oui, je le réalise. Je pensais que Jon Watte signifiait ne pas avoir de 'vecteur' dans main(), et faire tout cela dans la classe' Sprite'. –

0

Je me demande pourquoi Draw ne peut pas simplement prendre une référence à l'objet qu'il dessine.

class Sprite 
{ 
public: 

    Sprite() 
    { 
    } 

    void Draw(GLuint & texture) 
    { 
     glBindTexture(GL_TEXTURE_2D, texture); 
     // drawing code 
    } 
}; 
  • Sprite est un type qui ne dessin d'une manière spécifique
  • GLuint est un type qui est dessiné

Il pourrait y avoir polymorphisme quelque part ici en ce que: - vous avez différents dessiner des algorithmes - il existe des méthodes polymorphes (virtuelles) dans les différents types d'objets qui sont dessinés

alors Draw pourrait b e une méthode virtuelle et GLuint peut être une classe de base abstraite, auquel cas le vecteur réel ne sera pas des objets mais des pointeurs vers différents types de l'objet. Vous devriez certainement découpler la façon dont les objets sont dessinés à partir de la façon dont les objets sont stockés, donc stocker un vecteur dans la classe de dessin, ou même passer dans un pointeur qui suppose qu'ils sont dans une sorte de tableau n'est pas susceptible d'être une bonne idée. Par ailleurs, main devrait retourner int int void.

+0

J'ai besoin de stocker plusieurs textures dans la classe 'Sprite' ... aussi loin que' main() ', je sais qu'il devrait retourner un' int'. mais je voulais garder l'exemple de code aussi court que possible, et si je donnais le type de retour à 'int', j'aurais dû ajouter' return 0' à la fin. ou si je ne l'avais pas quelqu'un me dirait que j'ai oublié de retourner une valeur ... haha ​​ –

0

Étant donné que l'ID de texture ne change pas, qu'en est-il de l'utilisation d'une valeur GLuint dans Sprite au lieu de stocker le tableau-ptr et de choisir le sprite à dessiner?

semble plus simple, et pas à vous soucier de la portée

Ceci est à moins que vous devez appeler glDeleteTextures avant app-sortie, je vous suggère de créer une classe de TextureMgr ou quelque chose qui permet de résoudre ce problème une fois pour toutes. ;)

Questions connexes