假设您glGenTextures
每次调用时都会生成一个新纹理glTexImage2D
,那么您就是在浪费内存,并且如果您不跟踪生成的所有纹理,则会泄漏内存。glTexImage2D
获取输入数据并将其存储在视频卡内存中。您在调用之前绑定的纹理名称glTexImage2D
- 您生成的纹理名称glGenTextures
是该块视频卡内存的句柄。
如果您的纹理很大,并且您每次使用它时都分配新内存来存储越来越多的副本,那么您将很快耗尽内存。glTexImage2D
解决方案是在应用程序初始化期间调用一次,仅glBindTexture
在您想使用它时调用。如果您想在单击时更改纹理本身,只需调用glBindTexture
和glTexImage2D
。如果您的新图像与前一个图像大小相同,您可以调用glTexSubImage2D
告诉 OpenGL 覆盖旧图像数据,而不是删除它并上传新图像。
更新
为了响应您的新代码,我正在用更具体的答案更新我的答案。您完全以错误的方式处理 OpenGL 纹理的输出glGenTextures
is aGLuint[]
而不是 a String
or char[]
。对于使用 生成的每个纹理glGenTextures
,OpenGL 都会为您返回一个纹理句柄(作为无符号整数)。这个句柄存储你给它的状态glTexParameteri
以及显卡上的一块内存,如果你用glTexImage[1/2/3]D
. 存储句柄并在需要更新时向其发送新数据由您决定。如果您覆盖句柄或忘记它,数据仍然保留在图形卡上,但您无法访问它。当您只需要 1 个纹理时,您还告诉 OpenGL 生成 3 个纹理。
看到原样texture_data
具有固定大小,您可以使用glTexSubImage2D
而不是更新纹理glTexImage2D
。这是您修改的代码以避免此问题导致的内存泄漏:
texture_data = new GLubyte[width*height]();
GLuint texname; //handle to a texture
glGenTextures(1, &texname); //Gen a new texture and store the handle in texname
//These settings stick with the texture that's bound. You only need to set them
//once.
glBindTexture(GL_TEXTURE_2D, texname);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//allocate memory on the graphics card for the texture. It's fine if
//texture_data doesn't have any data in it, the texture will just appear black
//until you update it.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB,
GL_UNSIGNED_BYTE, texture_data);
...
//bind the texture again when you want to update it.
glBindTexture(GL_TEXTURE_2D, texname);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, 0, GL_RGB,
GL_UNSIGNED_BYTE, texture_data);
...
//When you're done using the texture, delete it. This will set texname to 0 and
//delete all of the graphics card memory associated with the texture. If you
//don't call this method, the texture will stay in graphics card memory until you
//close the application.
glDeleteTextures(1, &texname);