2011-01-02 14 views
0

Ich möchte Texturen laden, und dann von mehreren Objekten verwendet werden. Würde das funktionieren?C++: Referenz und Zeiger Frage (Beispiel in Bezug auf 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); 
} 

Und gibt es einen anderen Weg, ich sollte dies tun, auch wenn es funktionieren würde?

Danke.

+1

einfach mal Hinweis. Wenn Sie etwas als Referenz definieren (oder deklarieren), bedeutet das normalerweise, dass etwas mit Ihrem Design nicht stimmt. – Falmarri

+0

@Falmarri, was meinst du? Stellen Sie vor, dass ein Klassenfeld, das eine Referenz oder eine lokale Variable als Referenz ist, falsch ist? – Kos

+0

@Kos: Ich spreche über ein Klassenfeld als Referenz definieren. – Falmarri

Antwort

2
  1. ja, das würde Arbeit
  2. keine Notwendigkeit, ihnen eine Referenz zu machen sein: Sie speichern/eine Kopie eines Zeigers übergeben (es ist schnell), und Sie nicht vorhaben, dies zu ändern Zeiger außerhalb
  3. gibt es viele verschiedene Möglichkeiten, dies zu tun, und das richtige hängt von Ihren anderen Code-Anforderungen.

z.B. Sie können eine globale Instanz von Texturen verwenden:

Texturen.cav:

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(); 

es ist ein einfacher Ansatz und sicher genug, da Texturen einmal geladen und laden Problem der statischen Initialisierungsreihenfolge Zweideutigkeit nicht

+0

sehr interessant. Vielen Dank! –

2

Dieser spezielle Fall sollte funktionieren. Sobald "the_textures" jedoch den Gültigkeitsbereich verlässt, wird der von Sprite gehaltene Zeiger ungültig. Das wäre das Gleiche, auch wenn es eine Referenz wäre. In diesem Fall schlage ich vor, dass Sie std :: vector <> stattdessen in die Sprite-Klasse einfügen und von dieser Klasseninstanz besitzen und verwalten.

+0

Ja, ich verstehe das Problem mit dem Oszilloskop. aber in diesem Fall ist es in main(), so wird es nie außerhalb des Geltungsbereichs gehen. soweit ich den 'vector' in die 'Sprite'-Klasse setzen würde, müsste ich die Texturen für jedes einzelne Sprite erneut laden, was die Performance beeinträchtigen würde. deshalb wollte ich so etwas wie mein OP machen. würde es jedoch für die "Sprite" -Klasse funktionieren, einen Verweis auf den Vektor zu haben? –

+0

Ihre Texturen sind nur GLuint-Bezeichner, die von OpenGL verwendet werden, daher würde das Kopieren des Vektors innerhalb des Sprite-Objekts sie nicht erneut laden. – tibur

+0

@tibur Ja, das merke ich. Ich dachte, Jon Watte meinte, in main() keinen "Vektor" zu haben und stattdessen alles in der "Sprite" -Klasse. –

0

Ich frage mich, warum Draw nicht nur einen Verweis auf das Objekt, das es zeichnet, nehmen kann.

class Sprite 
{ 
public: 

    Sprite() 
    { 
    } 

    void Draw(GLuint & texture) 
    { 
     glBindTexture(GL_TEXTURE_2D, texture); 
     // drawing code 
    } 
}; 
  • Sprite ist ein Typ, der in einer bestimmten Art und Weise
  • GLuint eine Art tut Zeichnung ist, die

Es gezogen wird, dass hier irgendwo Polymorphismus sein könnte: - Sie haben unterschiedliche Zeichnungsalgorithmen - Es gibt polymorphe (virtuelle) Methoden in den verschiedenen Arten von Objekten, die gezeichnet werden

so Draw könnte b e Eine virtuelle Methode und GLuint können eine abstrakte Basisklasse sein. In diesem Fall ist der tatsächliche Vektor nicht das Objekt, sondern der Zeiger auf verschiedene Objekttypen.

Sie sollten die Art und Weise, wie die Objekte gezeichnet werden, sicherlich von der Art der gespeicherten Objekte entkoppeln, also das Speichern eines Vektors in der Zeichenklasse oder sogar das Eingeben eines Zeigers, der davon ausgeht, dass sie sich in einer Art Array befinden wahrscheinlich eine gute Idee.

Übrigens sollte main int int void zurückgeben.

+0

Ich muss mehrere Texturen in der 'Sprite'-Klasse speichern ... so weit' main() ', weiß ich, dass es ein' int' zurückgeben soll. aber ich wollte den Beispielcode so kurz wie möglich halten, und wenn ich den Rückgabetyp auf "int" setze, hätte ich am Ende "return 0" hinzufügen müssen. oder wenn ich nicht jemand würde mir sagen, ich habe vergessen, einen Wert zurückgeben ... haha ​​ –

0

Da sich die Textur-ID nicht ändert, wie wäre es mit einem GLuint Wert in Sprite anstatt das Array-PTR zu speichern und welches Sprite zu zeichnen?

scheint einfacher, und keine Notwendigkeit, über Scoping

Sorgen Dies ist, wenn Sie glDeleteTextures vor app-Exit aufrufen müssen, dann empfehle ich Ihnen eine TextureMgr Klasse oder etwas zu schaffen, die dieses Problem ein für allemal löst. ;)

Verwandte Themen