2011-01-02 10 views
0

テクスチャを読み込んで複数のオブジェクトで使用したいと思います。これは効果がありますか?C++:リファレンスとポインタの質問(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); 
} 

これは動作しても違う方法がありますか?

ありがとうございました。

+1

だけではありませんので、それは単純なアプローチと十分に安全です注意。参照として何かを定義(宣言)する場合は、通常、デザインに何か問題があることを意味します。 – Falmarri

+0

@Falmarri、どういう意味ですか?あなたはクラスフィールドを参照、または参照されているローカル変数を持つことが間違っていることを示唆していますか? – Kos

+0

@Kos:私はクラスフィールドを参照として定義することを話しています。 – Falmarri

答えて

2
  1. はい、このでしょう仕事
  2. それらを参照することにする必要はありません:あなたストアは/ポインタのコピーを渡す(それは)速い、あなたはこれを変更する予定はありません。外側のポインタ
  3. これを行うにはさまざまな方法があり、適切なものは他のコード要件によって異なります。

テクスチャのグローバルインスタンスを使用することができます:

テクスチャ。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(); 

テクスチャが一度ロードされ、ロードが静的初期化順序の曖昧さの問題

+0

非常に興味深い。ありがとう! –

2

そのような場合はうまくいくはずです。ただし、 "the_textures"が有効範囲外になるとすぐに、Spriteが保持するポインタは無効になります。たとえそれが参考であったとしても、それは同じであろう。 この場合、std :: vector <をSpriteクラスの内側に置き、そのクラスインスタンスが所有して管理することをお勧めします。

+0

はい、私は範囲の問題を認識します。この場合はmain()にあり、スコープから外れることはありません。 Spriteクラスの中に 'vector'を置くのであれば、すべてのスプライトごとにテクスチャを読み込む必要があります。それで私は私のOPのようなことをしたいと思ったのです。しかし、 'Sprite'クラスがベクトルへの参照を持つように働くでしょうか? –

+0

あなたのテクスチャは、OpenGLによって使用されるGLuint識別子だけです。したがって、Spriteオブジェクト内でベクターをコピーしても、それらを再度ロードすることはありません。 – tibur

+0

@tiburはい、私はそれを実現します。私はJon Watteがmain()に 'vector'を持たず、その代わりに' Sprite'クラスでそれをやっていると思っていました。 –

0

私は、Drawが描画しているオブジェクトへの参照を取るだけでは不思議です。

class Sprite 
{ 
public: 

    Sprite() 
    { 
    } 

    void Draw(GLuint & texture) 
    { 
     glBindTexture(GL_TEXTURE_2D, texture); 
     // drawing code 
    } 
}; 
  • スプライトはGLuintはどこかここでその中の多型があるかもしれません

を引かれますタイプです

  • 特定の方法で描くないタイプです: - あなたは異なってい描画アルゴリズム - 描画されるさまざまな種類のオブジェクトに多相(仮想)メソッドがあります。

    だからDraw b e仮想メソッドであり、GLuintは抽象基本クラスであり、その場合、実際のベクトルはオブジェクトのものではなく、オブジェクトの異なるタイプへのポインタである。

    オブジェクトを格納する方法からオブジェクトを引き出す方法を確実に切り離す必要があります。そのため、ベクターを描画クラスに格納したり、何らかの配列になっていることを前提としたポインタを渡したりすることはできません。おそらく良いアイデアかもしれない。

    ところで、mainはintを返すべきではありません。

  • +0

    'Sprite'クラスに複数のテクスチャを格納する必要があります...' main() 'のように、' int'を返すべきであることを知っています。サンプルコードをできるだけ短くしたいのですが、戻り値の型を 'int'に設定すると、最後に' return 0'を追加する必要があります。または私が誰かが私に値を返すことを忘れていたことを教えてくれなかったら... haha​​ –

    0

    テクスチャIDは変更されないため、の値をSpriteに設定すると、array-ptrを保存してスプライトを選択するのはどうですか?

    は単純に思えない、とあなたはアプリ出口の前にglDeleteTexturesを呼び出す必要がない限り、これは

    のスコープを心配する必要は、私はあなたがTextureMgrクラスまたはきっぱりとこの問題を解決し、何かを作成することをおすすめします。 ;)