Я не знаю, почему произошел сбой glDelete, но я вполне уверен, что он вам все равно не нужен и слишком усложняет это.
glGenTextures создает «имя» для вашей текстуры. glTexImage3D предоставляет OpenGL некоторые данные для привязки к этому имени. Если мое понимание верно, нет причин удалять имя, если вы больше не хотите получать данные .
Вместо этого вы должны просто снова вызвать glTexImage3D с тем же именем текстуры и поверить, что драйвер будет знать, что ваши старые данные больше не нужны. Это позволяет вам каждый раз заново указывать новый размер, вместо того, чтобы сначала указывать максимальный размер, а затем вызывать glTexSubImage3D, что затруднит фактическое использование данных, поскольку текстура все равно сохранит свой максимальный размер.
Ниже приведен глупый тест на python (необходим pyglet), который выделяет целую кучу текстур (просто для проверки того, что измерение использования памяти графическим процессором в GPU-Z действительно работает), а затем перераспределяет новые данные для одной и той же текстуры в каждом кадре. со случайным новым размером и некоторыми случайными данными, чтобы обойти любые оптимизации, которые могут существовать, если данные остаются постоянными.
Это (очевидно) медленный ад, но он определенно показывает, по крайней мере, на моей системе (Windows Server 2003 x64, NVidia Quadro FX1800, драйверы 259.81), что использование памяти графическим процессором НЕ увеличивается при циклическом перераспределении текстура.
import pyglet
from pyglet.gl import *
import random
def toGLArray(input):
return (GLfloat*len(input))(*input)
w, h = 800, 600
AR = float(h)/float(w)
window = pyglet.window.Window(width=w, height=h, vsync=False, fullscreen=False)
def init():
glActiveTexture(GL_TEXTURE1)
tst_tex = GLuint()
some_data = [11.0, 6.0, 3.2, 2.8, 2.2, 1.90, 1.80, 1.80, 1.70, 1.70, 1.60, 1.60, 1.50, 1.50, 1.40, 1.40, 1.30, 1.20, 1.10, 1.00]
some_data = some_data * 1000*500
# allocate a few useless textures just to see GPU memory load go up in GPU-Z
for i in range(10):
dummy_tex = GLuint()
glGenTextures(1, dummy_tex)
glBindTexture(GL_TEXTURE_2D, dummy_tex)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, 1000, 1000, 0, GL_RGBA, GL_FLOAT, toGLArray(some_data))
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
# our real test texture
glGenTextures(1, tst_tex)
glBindTexture(GL_TEXTURE_2D, tst_tex)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, 1000, 1000, 0, GL_RGBA, GL_FLOAT, toGLArray(some_data))
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
def world_update(dt):
pass
pyglet.clock.schedule_interval(world_update, 0.015)
@window.event
def on_draw():
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
# randomize texture size and data
size = random.randint(1, 1000)
data = [random.randint(0, 100) for i in xrange(size)]
data = data*1000*4
# just to see our draw calls 'tick'
print pyglet.clock.get_fps()
# reallocate texture every frame
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, 1000, size, 0, GL_RGBA, GL_FLOAT, toGLArray(data))
def main():
init()
pyglet.app.run()
if __name__ == '__main__':
main()