将像素传递到 glTexImage2D() 后会发生啥情况?

Posted

技术标签:

【中文标题】将像素传递到 glTexImage2D() 后会发生啥情况?【英文标题】:What happens to pixels after passing them into glTexImage2D()?将像素传递到 glTexImage2D() 后会发生什么情况? 【发布时间】:2009-04-19 21:45:39 【问题描述】:

例如,如果我创建一个像素数组,如下所示:

int *getPixels()

    int *pixels = new int[10];
    pixels[0] = 1;
    pixels[1] = 0;
    pixels[1] = 1;
    // etc...


glTexImage2D(..., getPixels());

glTexImage2D 是使用该引用还是将像素复制到它自己的内存中?

如果答案是前者,那我应该这样做吗?

int *p = getPixels();
glTexImage2D(..., p);

/* Just changed to delete[], because delete
 * would only delete the first element! */
delete[] p;

【问题讨论】:

【参考方案1】:

从man page 中的这句话来看,听起来 glTexImage2D 分配了自己的内存。 这是有道理的,理想情况下,OpenGL API 会发送数据以存储在显卡本身上(如果驱动程序/实现/等允许)。

在 GL 版本 1.1 或更高版本中,像素可能是空指针。 在这种情况下,纹理内存被分配以容纳纹理 宽度宽度和高度高度。然后,您可以将子纹理下载到 初始化这个纹理内存。如果用户尝试,图像未定义 应用纹理的未初始化部分 图像转换为基元。

所以是的,我想一旦你生成了你的纹理,释放内存并没有什么坏处。

【讨论】:

我不确定 PC 上是否是这种情况,但在控制台上,纹理上传功能通常只是存储指向纹理的指针并安排 DMA 传输以供以后使用,因此您无法尽快释放内存返回的函数。【参考方案2】:

是的,在对geTexImage2D() 的调用返回后,丢弃传递给它的数据是安全的。事实上,如果你不这样做,就会发生内存泄漏,就像这段代码一样:

int *getPixels()

    int *pixels = new int[10];
    pixels[0] = 1;
    pixels[1] = 0;
    pixels[1] = 1;
    // etc...


glTexImage2D(..., getPixels());

您将指向缓冲区的指针传递给调用,但随后指针丢失并且很可能泄漏。您应该做的是存储它并在调用 retuns 后将其删除:

int *pbuf = getPixels();
glTexImage2D(..., pbuf);
delete[] pbuf;

或者,如果纹理的大小是恒定的,您可以将指针传递给堆栈中的数组:


    int buf[10];
    ...
    glTexImage2D(..., pbuf);

最后,如果不想担心指针和数组,可以使用STL:

vector<int> buf;
fillPixels(buf);
getTexImage2D(..., buf.begin());

【讨论】:

糟糕!我最初的 sn-p 使用 delete 而不是 delete[] 来删除像素缓冲区。 实际上,delete[] 是您应该使用的。我的坏,现在修好了。顺便说一句,这正是你应该使用 STL 的原因 :) 从技术上讲,buf.begin() 可能不起作用,但 &buf[0] 保证可以工作。在大多数 STL 实现中,向量迭代器是一个指针,但它不一定是。【参考方案3】:

我认为你需要在绘制完像素后调用 glDeleteTextures() 来释放内存。

【讨论】:

以上是关于将像素传递到 glTexImage2D() 后会发生啥情况?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 OpenGL 中的帧缓冲区纹理中采样像素?

通过 glTexSubImage3d 上传纹理数据时,像素传输格式可以改变吗?

对符号 glTexImage2D 的未定义引用

如何将2D像素数组传递给BitmapSource.Create()?

C++ OpenGL glTexImage2D 访问冲突

glTexImage2D() 函数访问冲突错误