C++:参考和指针问题(有关 OpenGL 的示例)

发布于 2024-10-09 16:04:10 字数 869 浏览 4 评论 0原文

我想加载纹理,然后让它们被多个对象使用。这行得通吗?

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

即使可行,我是否应该采取不同的方式来做到这一点?

谢谢。

I would like to load textures, and then have them be used by multiple objects. Would this work?

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

And is there a different way I should do this, even if it would work?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦里人 2024-10-16 16:04:10
  1. 是的,这工作,
  2. 不需要让它们成为引用:您存储/传递指针的副本(速度很快),并且您不打算在
  3. 很多地方 更改此指针执行此操作的方法有多种,正确的方法取决于您的其他代码要求。

例如,您可以使用纹理的全局实例:

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

这是一种简单的方法并且足够安全,因为纹理将被加载一次并且加载不存在静态初始化顺序模糊的问题

  1. yes, this would work
  2. no need to make them be a reference: you store/pass a copy of a pointer (it's fast), and you don't plan to change this pointer outside
  3. there're many different ways to do this, and the right one depends on your other code requirements.

e.g. you can use a global instance of 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();

it's a simple approach and safe enough because textures will be loaded once and loading doesn't have a problem of static initialization order ambiguity

梦初启 2024-10-16 16:04:10

这个特殊情况应该有效。然而,一旦“the_textures”超出范围,Sprite 所持有的指针就会变得无效。即使它是一个参考,那也是一样的。
在这种情况下,我建议您将 std::vector<>相反,它位于 Sprite 类中,并由该类实例拥有和管理。

That particular case should work. However, as soon as "the_textures" goes out of scope, then the pointer held by Sprite will become invalid. That would be the same, even if it was a reference.
In this, case, I suggest you put the std::vector<> inside the Sprite class instead, and have it owned and managed by that class instance.

奢欲 2024-10-16 16:04:10

我想知道为什么 Draw 不能只引用它正在绘制的对象。

class Sprite
{
public:

    Sprite()
    {
    }

    void Draw( GLuint & texture )
    {
        glBindTexture( GL_TEXTURE_2D, texture );
        // drawing code
    }
};
  • Sprite 是一种以特定方式绘制的类型
  • GLuint 是一种绘制的类型

这里可能存在多态性:
- 你有不同的绘制算法
- 在绘制的不同类型的对象中存在多态(虚拟)方法,

因此 Draw 可能是虚拟方法,而 GLuint 可能是抽象基类,在这种情况下,实际向量将不是对象的向量,而是指向不同对象的指针对象的类型。

当然,您应该将对象的绘制方式与对象的存储方式解耦,因此在绘图类中存储向量,或者甚至传入一个假设它们位于某种数组中的指针不太可能是好主意。

顺便说一下,main 应该返回 int 而不是 void。

I am wondering why Draw cannot just take a reference to the object it is drawing.

class Sprite
{
public:

    Sprite()
    {
    }

    void Draw( GLuint & texture )
    {
        glBindTexture( GL_TEXTURE_2D, texture );
        // drawing code
    }
};
  • Sprite is a type that does drawing in a specific way
  • GLuint is a type that gets drawn

There could be polymorphism somewhere here in that:
- you have different draw algorithms
- there are polymorphic (virtual) methods in the different types of objects that get drawn

so Draw might be a virtual method and GLuint might be an abstract base class, in which case the actual vector will not be of the objects but of pointers to different types of the object.

You should certainly decouple out the way the objects are drawn from the way the objects are stored though, so storing a vector in the drawing class, or even passing in a pointer that assumes they are in some kind of array is not likely to be a good idea.

By the way, main should return int not void.

玉环 2024-10-16 16:04:10

由于纹理 id 不会改变,那么在 Sprite 中使用 GLuint 值而不是存储 array-ptr 并选择要绘制的 sprite 怎么样?

看起来更简单,并且无需担心作用域

,除非您需要在应用程序退出之前调用 glDeleteTextures,否则我建议您创建一个 TextureMgr 类或一劳永逸地解决此问题的类。 ;)

Since the texture id doesn't change, what about using a GLuint value in Sprite instead of storing the array-ptr and choosing which sprite to draw?

Seems simpler, and no need to worry about scoping

This is unless you need to call glDeleteTextures before app-exit, then I suggest you create a TextureMgr class or something that solves this issue once and for all. ;)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文