问题描述
我正在尝试绘制一些框线并在屏幕上呈现一些文本。但是我观察到内存(RAM)仅在进行6次绘制调用时才逐渐增加。我有8 GB RAM。当我运行程序时,内存使用量在1分钟内从4.2变为6。这是完整的代码。
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GL import shaders
from shader import *
import glfw
import freetype
import glm
import numpy as np
from PIL import Image
import math
class CharacterSlot:
def __init__(self,texture,glyph):
self.texture = texture
self.textureSize = (glyph.bitmap.width,glyph.bitmap.rows)
if isinstance(glyph,freetype.GlyphSlot):
self.bearing = (glyph.bitmap_left,glyph.bitmap_top)
self.advance = glyph.advance.x
elif isinstance(glyph,freetype.BitmapGlyph):
self.bearing = (glyph.left,glyph.top)
self.advance = None
else:
raise RuntimeError('unknown glyph type')
def _get_rendering_buffer(xpos,ypos,w,h,zfix=0.0):
return np.asarray([
xpos,ypos + h,xpos,1,xpos + w,0
],np.float32)
def init_chars(shaderProgram,window_height,window_width,font_size=24,fontfile = "Vera.ttf"):
glUseProgram(shaderProgram)
#get projection
shader_projection = glGetUniformLocation(shaderProgram,"projection")
W = window_width
H = window_height
projection = glm.ortho(-W/2,W/2,-H/2,H/2)
glUniformMatrix4fv(shader_projection,GL_FALSE,glm.value_ptr(projection))
#disable byte-alignment restriction
glPixelStorei(GL_UNPACK_ALIGNMENT,1)
face = freetype.Face(fontfile)
face.set_char_size(font_size*64 )
#load first 128 characters of ASCII set
Characters = dict()
for i in range(0,128):
face.load_char(chr(i))
glyph = face.glyph
#generate texture
texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D,texture)
glTexImage2D(GL_TEXTURE_2D,GL_RED,glyph.bitmap.width,glyph.bitmap.rows,GL_UNSIGNED_BYTE,glyph.bitmap.buffer)
#texture options
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_TEXTURE_MIN_FILTER,GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR)
#now store character for later use
Characters[chr(i)] = CharacterSlot(texture,glyph)
glBindTexture(GL_TEXTURE_2D,0)
glUseProgram(0)
return Characters
def render_text(window,shaderProgram,text,x,y,scale,Characters,color=(170,250,255)):
r,g,b = color
glUseProgram(shaderProgram)
#configure VAO/VBO for texture quads
VAO = glGenVertexArrays(1)
glBindVertexArray(VAO)
VBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER,VBO)
glBufferData(GL_ARRAY_BUFFER,6 * 4 * 4,None,GL_STATIC_DRAW)
glEnableVertexAttribArray(0)
glVertexAttribPointer(0,4,GL_FLOAT,None)
glBindBuffer(GL_ARRAY_BUFFER,0)
glBindVertexArray(0)
glUniform3f(glGetUniformLocation(shaderProgram,"textColor"),r/255,g/255,b/255)
glActiveTexture(GL_TEXTURE0)
glBindVertexArray(VAO)
for c in text:
ch = Characters[c]
w,h = ch.textureSize
w = w*scale
h = h*scale
vertices = _get_rendering_buffer(x,h)
#render glyph texture over quad
glBindTexture(GL_TEXTURE_2D,ch.texture)
#update content of VBO memory
glBindBuffer(GL_ARRAY_BUFFER,VBO)
glBufferSubData(GL_ARRAY_BUFFER,vertices.nbytes,vertices)
glBindBuffer(GL_ARRAY_BUFFER,0)
#render quad
glDrawArrays(GL_TRIANGLES,6)
#now advance cursors for next glyph (note that advance is number of 1/64 pixels)
x += (ch.advance>>6)*scale
glBindTexture(GL_TEXTURE_2D,0);
glUseProgram(0)
#UNBIND and DELETE VAO/VBO
glBindVertexArray(0)
glBindBuffer(GL_ARRAY_BUFFER,0)
glDeleteBuffers(1,id(VBO))
glDeleteBuffers(1,id(VAO))
def triangle(shaderProgram,window,x=0,y=0):
vertices = [-0.5,-0.5,0.0,0.5,0.0]
vertices = np.array(vertices,dtype=np.float32)
VBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER,vertices,GL_STATIC_DRAW)
glVertexAttribPointer(0,3,None)
glEnableVertexAttribArray(0)
#use shader program
glUseProgram(shaderProgram)
#accessing ourColor variable from shaderProgram
vertexColorLoc = glGetUniformLocation(shaderProgram,"ourColor")
glUniform4f(vertexColorLoc,255,28/255.0,20/255.0,0.7);
#transform matrix
transform = glm.mat4(1)
transform = glm.translate(transform,glm.vec3(x,0))
MVP = glGetUniformLocation(shaderProgram,"MVP")
glUniformMatrix4fv(MVP,glm.value_ptr(transform))
#drawing trangle
glLineWidth(3)
glDrawArrays(GL_TRIANGLES,3)
glUseProgram(0)
#UNBIND and DELETE VAO/VBO
glBindVertexArray(0)
glBindBuffer(GL_ARRAY_BUFFER,id(VBO))
def main():
glfw.init()
window = glfw.create_window(640,640,"EXAMPLE PROGRAM",None)
glfw.make_context_current(window)
#initliaze shader programs
shaderProgram = get_shaderProgram()
text_shaderProgram = get_text_shaderProgram()
#load characters and VAO/VBO for text rendering
Characters = init_chars(text_shaderProgram,640)
#window loop
while not glfw.window_should_close(window):
glfw.poll_events()
#screen
glClearColor(0,1)
glClear(GL_COLOR_BUFFER_BIT)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)
#draw functions
render_text(window,text_shaderProgram,"TRIANGLE",-50,-200,Characters)
render_text(window,"A",180,"B",-160,-180,"C",150,Characters)
triangle(shaderProgram,window)
triangle(shaderProgram,x=0.5,y=0.5)
#swap buffers
glfw.swap_buffers(window)
glfw.swap_interval(1)
glfw.terminate()
if __name__ == '__main__':
main()
着色器程序为here。但是我认为问题出在缓冲对象中。我试图通过下面的代码解除绑定VAO / VBO并删除缓冲区。但是我看不到任何变化。
#UNBIND and DELETE VAO/VBO
glBindVertexArray(0)
glBindBuffer(GL_ARRAY_BUFFER,id(VAO))
以下是相关的problem,其中已接受的答案表明 glGenBuffers 会导致内存泄漏。替代功能 glCreateBuffers 在pyopengl中不可用。我该如何解决这个问题?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)