我打算画点通常只会改变屏幕上的位置。
颜色和大小通常不会有所不同。
所以我在python中做了这个类Point
:
class Point2D():
_verts = None
_vshader_code = '''
#version 330
in vec2 pos;
uniform float size;
void main() {
gl_Position = vec4(pos, 0.0, 1.0);
gl_PointSize = size;
}
'''
_fshader_code = '''
#version 330
uniform vec4 col;
void main() {
gl_FragColor = col;
}
'''
def __init__(self, size, col):
## CREATE PROGRAM/SHADER ##
self.program = GL.glCreateProgram()
self.shaders = [
CreateShader(self._vshader_code, GL.GL_VERTEX_SHADER),
CreateShader(self._fshader_code, GL.GL_FRAGMENT_SHADER)
]
for shader in self.shaders:
GL.glAttachShader(self.program, shader)
GL.glLinkProgram(self.program)
#CheckShaderError(self.program, GL.GL_LINK_STATUS, True, "Error: Program linking failed:")
GL.glValidateProgram(self.program)
#CheckShaderError(self.program, GL.GL_VALIDATE_STATUS, True, "Error: Program is invalid:")
self.unif_size = GL.glGetUniformLocation(self.program, 'size')
self.unif_col = GL.glGetUniformLocation(self.program, 'col')
GL.glUseProgram(self.program)
GL.glUniform1f(self.unif_size, size)
GL.glUniform4fv(self.unif_col, 1, col)
## FLAGS ##
#GL.glEnable(GL.GL_PROGRAM_POINT_SIZE);
GL.glEnable(GL.GL_VERTEX_PROGRAM_POINT_SIZE)
def bind_array(self, array):
self._verts = array
## BIND BUFFER ##
self.vertexArrayObject = GL.glGenVertexArrays(1)
GL.glBindVertexArray(self.vertexArrayObject)
self.buff = GL.glGenBuffers(1)
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.buff)
GL.glBufferData(GL.GL_ARRAY_BUFFER, self._verts.nbytes, self._verts, GL.GL_STATIC_DRAW)
self.attr_pos = GL.glGetAttribLocation(self.program, 'pos')
GL.glEnableVertexAttribArray(0)
GL.glVertexAttribPointer(self.attr_pos, 2, GL.GL_FLOAT, GL.GL_FALSE, 8, None)
GL.glBindVertexArray(0)
def update_size_and_color(self, size, col):
#GL.glPointSize(size)
GL.glUseProgram(self.program)
GL.glUniform1f(self.unif_size, size)
GL.glUniform4fv(self.unif_col, 1, col)
def update_elem(self, index, value):
GL.glUseProgram(self.program)
self._verts[index] = value
GL.glBindVertexArray(self.vertexArrayObject)
GL.glBufferSubData(GL.GL_ARRAY_BUFFER, index * 8, 8, value)
GL.glBindVertexArray(0)
def Draw(self):
GL.glUseProgram(self.program)
GL.glBindVertexArray(self.vertexArrayObject)
GL.glDrawArrays(GL.GL_POINTS, 0, len(self._verts))
GL.glBindVertexArray(0)
def __del__(self):
try:
#if the context is alive, you want to try and delete shader/program stuff manually
#this could be triggered with e.g. `del Display`
for shader in self.shaders:
GL.glDetachShader(self.program, shader)
GL.glDeleteShader(shader)
GL.glDeleteProgram(self.program)
except OpenGL.error.NullFunctionError as error:
print("context already deleted my shader/program stuff!")
GL.glDisable(GL.GL_VERTEX_PROGRAM_POINT_SIZE)
使用创建的点对象,我可以按如下方式绘制点图:
point = Point2D(10.0, numpy.array((1.0, 0.0, 0.0, 1.0), 'f4'))
point.bind_array(numpy.zeros((2, 2), 'f4'))
## DRAW ##
point.update_elem(0, numpy.array((0.5, 0.0), 'f4'))
point.update_elem(1, numpy.array((-0.5, 0.0), 'f4'))
point.Draw()
(...code...)
point.update_elem(1, numpy.array((0.25, 0.25), 'f4'))
point.Draw()
这幅画很实用,看似很有效,但问题是......:
- 我做得对吗?