def drawnvc( self, normals, points, colors, idxs ): '''draw tri mesh using glDrawElements using input normals points colors and indexes''' n = 1 for dim in idxs.shape: n *= dim iptr = vecutil.numpy2pointer(idxs) nptr = vecutil.numpy2pointer(normals) vptr = vecutil.numpy2pointer(points) cptr = vecutil.numpy2pointer(colors) mode = self.ui.fillmodes[self.ui.fillmode] gl.glPolygonMode( gl.GL_FRONT, mode ) gl.glEnableClientState(gl.GL_VERTEX_ARRAY) gl.glEnableClientState(gl.GL_NORMAL_ARRAY) gl.glEnableClientState(gl.GL_COLOR_ARRAY) gl.glVertexPointer(3, gl.GL_FLOAT, 0, vptr) gl.glNormalPointer( gl.GL_FLOAT, 0, nptr) gl.glColorPointer(3, gl.GL_FLOAT, 0, cptr) gl.glDrawElements(gl.gl.GL_TRIANGLES, n, gl.GL_UNSIGNED_INT, iptr) gl.glDisableClientState(gl.GL_VERTEX_ARRAY) gl.glDisableClientState(gl.GL_NORMAL_ARRAY) gl.glDisableClientState(gl.GL_COLOR_ARRAY) gl.glPolygonMode( gl.GL_FRONT, gl.GL_FILL )
def __init__(self, radius, inner_radius, slices, inner_slices): # Create the vertex and normal arrays. vertices = [] normals = [] u_step = 2 * math.pi / (slices - 1) v_step = 2 * math.pi / (inner_slices - 1) u = 0. for i in range(slices): cos_u = math.cos(u) sin_u = math.sin(u) v = 0. for j in range(inner_slices): cos_v = math.cos(v) sin_v = math.sin(v) d = (radius + inner_radius * cos_v) x = d * cos_u y = d * sin_u z = inner_radius * sin_v nx = cos_u * cos_v ny = sin_u * cos_v nz = sin_v vertices.extend([x, y, z]) normals.extend([nx, ny, nz]) v += v_step u += u_step # Create ctypes arrays of the lists vertices = (gl.GLfloat * len(vertices))(*vertices) normals = (gl.GLfloat * len(normals))(*normals) # Create a list of triangle indices. indices = [] for i in range(slices - 1): for j in range(inner_slices - 1): p = i * inner_slices + j indices.extend([p, p + inner_slices, p + inner_slices + 1]) indices.extend([p, p + inner_slices + 1, p + 1]) indices = (gl.GLuint * len(indices))(*indices) # Compile a display list self.list = gl.glGenLists(1) gl.glNewList(self.list, gl.GL_COMPILE) gl.glPushClientAttrib(gl.GL_CLIENT_VERTEX_ARRAY_BIT) gl.glEnableClientState(gl.GL_VERTEX_ARRAY) gl.glEnableClientState(gl.GL_NORMAL_ARRAY) gl.glVertexPointer(3, gl.GL_FLOAT, 0, vertices) gl.glNormalPointer(gl.GL_FLOAT, 0, normals) gl.glDrawElements(gl.GL_TRIANGLES, len(indices), gl.GL_UNSIGNED_INT, indices) gl.glPopClientAttrib() gl.glEndList()
def __init__(self, radius, inner_radius, slices, inner_slices): # Create the vertex and normal arrays. vertices = [] normals = [] u_step = 2 * pi / (slices - 1) v_step = 2 * pi / (inner_slices - 1) u = 0. for i in range(slices): cos_u = cos(u) sin_u = sin(u) v = 0. for j in range(inner_slices): cos_v = cos(v) sin_v = sin(v) d = (radius + inner_radius * cos_v) x = d * cos_u y = d * sin_u z = inner_radius * sin_v nx = cos_u * cos_v ny = sin_u * cos_v nz = sin_v vertices.extend([x, y, z]) normals.extend([nx, ny, nz]) v += v_step u += u_step # Create ctypes arrays of the lists vertices = (GLfloat * len(vertices))(*vertices) normals = (GLfloat * len(normals))(*normals) # Create a list of triangle indices. indices = [] for i in range(slices - 1): for j in range(inner_slices - 1): p = i * inner_slices + j indices.extend([p, p + inner_slices, p + inner_slices + 1]) indices.extend([p, p + inner_slices + 1, p + 1]) indices = (GLuint * len(indices))(*indices) # Compile a display list self.list = glGenLists(1) glNewList(self.list, GL_COMPILE) glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT) glEnableClientState(GL_VERTEX_ARRAY) glEnableClientState(GL_NORMAL_ARRAY) glVertexPointer(3, GL_FLOAT, 0, vertices) glNormalPointer(GL_FLOAT, 0, normals) glDrawElements(GL_TRIANGLES, len(indices), GL_UNSIGNED_INT, indices) glPopClientAttrib() glEndList()
def _display_movements(self, has_vbo): self.vertex_buffer.bind() glVertexPointer(3, GL_FLOAT, 0, self.vertex_buffer.ptr) self.vertex_color_buffer.bind() glColorPointer(3, GL_FLOAT, 0, self.vertex_color_buffer.ptr) self.vertex_normal_buffer.bind() glNormalPointer(GL_FLOAT, 0, self.vertex_normal_buffer.ptr) self.index_buffer.bind() # Prevent race condition by using the number of currently loaded layers max_layers = self.layers_loaded start = 1 layer_selected = self.num_layers_to_draw <= max_layers if layer_selected: end_prev_layer = self.layer_stops[self.num_layers_to_draw - 1] else: end_prev_layer = 0 end = self.layer_stops[min(self.num_layers_to_draw, max_layers)] glDisableClientState(GL_COLOR_ARRAY) glColor3f(*self.color_printed[:-1]) # Draw printed stuff until end or end_prev_layer cur_end = min(self.printed_until, end) if not self.only_current: if 1 <= end_prev_layer <= cur_end: self._draw_elements(1, end_prev_layer) elif cur_end >= 1: self._draw_elements(1, cur_end) glEnableClientState(GL_COLOR_ARRAY) # Draw nonprinted stuff until end_prev_layer start = max(cur_end, 1) if end_prev_layer >= start: if not self.only_current: self._draw_elements(start, end_prev_layer) cur_end = end_prev_layer # Draw current layer if layer_selected: glDisableClientState(GL_COLOR_ARRAY) glColor3f(*self.color_current_printed[:-1]) if cur_end > end_prev_layer: self._draw_elements(end_prev_layer + 1, cur_end) glColor3f(*self.color_current[:-1]) if end > cur_end: self._draw_elements(cur_end + 1, end) glEnableClientState(GL_COLOR_ARRAY) # Draw non printed stuff until end (if not ending at a given layer) start = max(self.printed_until, 1) if not layer_selected and end >= start: self._draw_elements(start, end) self.index_buffer.unbind() self.vertex_buffer.unbind() self.vertex_color_buffer.unbind() self.vertex_normal_buffer.unbind()
def normal(self): gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.buffers["normal"]) gl.glNormalPointer(gl.GL_FLOAT, 0, 0)
def render(self, scene): """ Add a ring to the view. :param scene: The view to render the model into :type scene: pyglet_helper.objects.View """ if self.degenerate: return # The number of subdivisions around the hoop's radial direction. if self.thickness: band_coverage = scene.pixel_coverage(self.pos, self.thickness) else: band_coverage = scene.pixel_coverage(self.pos, self.radius * 0.1) if band_coverage < 0: band_coverage = 1000 bands = sqrt(band_coverage * 4.0) bands = clamp(4, bands, 40) # The number of subdivisions around the hoop's tangential direction. ring_coverage = scene.pixel_coverage(self.pos, self.radius) if ring_coverage < 0: ring_coverage = 1000 rings = sqrt(ring_coverage * 4.0) rings = clamp(4, rings, 80) slices = int(rings) inner_slices = int(bands) radius = self.radius inner_radius = self.thickness # Create the vertex and normal arrays. vertices = [] normals = [] outer_angle_step = 2 * pi / (slices - 1) inner_angle_step = 2 * pi / (inner_slices - 1) outer_angle = 0. for i in range(slices): cos_outer_angle = cos(outer_angle) sin_outer_angle = sin(outer_angle) inner_angle = 0. for j in range(inner_slices): cos_inner_angle = cos(inner_angle) sin_inner_angle = sin(inner_angle) diameter = (radius + inner_radius * cos_inner_angle) vertex_x = diameter * cos_outer_angle vertex_y = diameter * sin_outer_angle vertex_z = inner_radius * sin_inner_angle normal_x = cos_outer_angle * cos_inner_angle normal_y = sin_outer_angle * cos_inner_angle normal_z = sin_inner_angle vertices.extend([vertex_x, vertex_y, vertex_z]) normals.extend([normal_x, normal_y, normal_z]) inner_angle += inner_angle_step outer_angle += outer_angle_step # Create ctypes arrays of the lists vertices = (gl.GLfloat *len(vertices))(*vertices) normals = (gl.GLfloat * len(normals))(*normals) # Create a list of triangle indices. indices = [] for i in range(slices - 1): for j in range(inner_slices - 1): pos = i * inner_slices + j indices.extend([pos, pos + inner_slices, pos + inner_slices + 1]) indices.extend([pos, pos + inner_slices + 1, pos + 1]) indices = (gl.GLuint * len(indices))(*indices) # Compile a display list self.list = gl.glGenLists(1) gl.glNewList(self.list, gl.GL_COMPILE) self.color.gl_set(self.opacity) gl.glPushClientAttrib(gl.GL_CLIENT_VERTEX_ARRAY_BIT) gl.glEnableClientState(gl.GL_VERTEX_ARRAY) gl.glEnableClientState(gl.GL_NORMAL_ARRAY) self.model_world_transform(scene.gcf, Vector([self.radius, self.radius, self.radius])).gl_mult() gl.glVertexPointer(3, gl.GL_FLOAT, 0, vertices) gl.glNormalPointer(gl.GL_FLOAT, 0, normals) gl.glDrawElements(gl.GL_TRIANGLES, len(indices), gl.GL_UNSIGNED_INT, indices) gl.glPopClientAttrib() gl.glEndList() gl.glCallList(self.list)
def createVAO(vertexBuffer, textureCoordBuffer=None, normalBuffer=None, colorBuffer=None): """Create a Vertex Array Object (VAO) with specified Vertex Buffer Objects. VAOs store buffer binding states, reducing binding overhead when drawing objects with vertext data stored in VBOs. Parameters ---------- vertexBuffer : :obj:`VertexBufferObject` Vertex buffer descriptor, must have 'bufferType' as GL_VERTEX_ARRAY. textureCoordBuffer : :obj:`VertexBufferObject` or None, optional Vertex buffer descriptor of texture coordinates, must have 'bufferType' as GL_TEXTURE_COORD_ARRAY. normalBuffer : :obj:`VertexBufferObject` or None, optional Vertex buffer descriptor of normals, must have 'bufferType' as GL_NORMAL_ARRAY. colorBuffer :obj:`VertexBufferObject` or None, optional Vertex buffer descriptor of colors, must have 'bufferType' as GL_COLOR_ARRAY. Returns ------- VertexArrayObject A descriptor with vertex buffer information. Examples -------- # create a VAO vaoDesc = createVAO(vboVerts, vboTexCoords, vboNormals) # draw the VAO, renders the mesh drawVAO(vaoDesc, GL.GL_TRIANGLES) """ # create a vertex buffer ID vaoId = GL.GLuint() GL.glGenVertexArrays(1, ctypes.byref(vaoId)) GL.glBindVertexArray(vaoId) # must have a vertex pointer assert vertexBuffer.bufferType == GL.GL_VERTEX_ARRAY # bind and set the vertex pointer, this is must be bound GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vertexBuffer.id) GL.glVertexPointer(vertexBuffer.vertexSize, vertexBuffer.dtype, 0, None) GL.glEnableClientState(vertexBuffer.bufferType) # texture coordinates if textureCoordBuffer is not None: if vertexBuffer.indices != textureCoordBuffer.indices: raise RuntimeError( "Texture and vertex buffer indices do not match!") GL.glBindBuffer(GL.GL_ARRAY_BUFFER, textureCoordBuffer.id) GL.glTexCoordPointer(textureCoordBuffer.vertexSize, textureCoordBuffer.dtype, 0, None) GL.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY) # normals if normalBuffer is not None: if vertexBuffer.indices != normalBuffer.indices: raise RuntimeError( "Normal and vertex buffer indices do not match!") GL.glBindBuffer(GL.GL_ARRAY_BUFFER, normalBuffer.id) GL.glNormalPointer(normalBuffer.dtype, 0, None) GL.glEnableClientState(GL.GL_NORMAL_ARRAY) # colors if colorBuffer is not None: if vertexBuffer.indices != colorBuffer.indices: raise RuntimeError("Color and vertex buffer indices do not match!") GL.glBindBuffer(GL.GL_ARRAY_BUFFER, colorBuffer.id) GL.glColorPointer(colorBuffer.vertexSize, colorBuffer.dtype, 0, None) GL.glEnableClientState(GL.GL_COLOR_ARRAY) GL.glBindVertexArray(0) return VertexArrayObject(vaoId, vertexBuffer.indices, dict())
def drawVertexbuffers(vertexBuffer, *args, mode=GL.GL_TRIANGLES, flush=True): """Draw a vertex buffer using glDrawArrays. This method does not require shaders. Parameters ---------- vertexBuffer : :obj:`Vertexbuffer` Vertex buffer descriptor, must have 'bufferType' as GL_VERTEX_ARRAY. Optional vertex buffer descriptors can be passed as seperate arguments, they must have 'bufferTypes' as GL_TEXTURE_COORD_ARRAY, GL_NORMAL_ARRAY or GL_COLOR_ARRAY. mode : :obj:`int` Drawing mode to use (e.g. GL_TRIANGLES, GL_QUADS, GL_POINTS, etc.) flush : :obj:`bool` Flush queued drawing commands before returning. Returns ------- None Examples -------- # vertices of a triangle verts = [ 1.0, 1.0, 0.0, # v0 0.0, -1.0, 0.0, # v1 -1.0, 1.0, 0.0] # v2 # triangle vertex colors colors = [1.0, 0.0, 0.0, # v0 0.0, 1.0, 0.0, # v1 0.0, 0.0, 1.0] # v2 # load vertices to graphics device, return a descriptor vertexBuffer = createVertexbuffer(verts, 3) colorBuffer = createVertexbuffer(c, 3, GL.GL_COLOR_ARRAY) # draw the VBO drawVertexbuffer(vertexBuffer, colorBuffer, GL.GL_TRIANGLES) """ # must have a vertex pointer assert vertexBuffer.bufferType == GL.GL_VERTEX_ARRAY # bind and set the vertex pointer GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vertexBuffer.id) GL.glVertexPointer(vertexBuffer.vertexSize, vertexBuffer.dtype, 0, None) GL.glEnableClientState(vertexBuffer.bufferType) # handle additional buffers if args: for buffer in args: # check if the number of indicies are the same if vertexBuffer.indices != buffer.indices: raise RuntimeError("Vertex buffer indices do not match!") GL.glBindBuffer(GL.GL_ARRAY_BUFFER, buffer.id) if buffer.bufferType == GL.GL_TEXTURE_COORD_ARRAY: GL.glTexCoordPointer(buffer.dtype, 0, None) elif buffer.bufferType == GL.GL_NORMAL_ARRAY: GL.glNormalPointer(buffer.dtype, 0, None) elif buffer.bufferType == GL.GL_COLOR_ARRAY: GL.glColorPointer(buffer.vertexSize, buffer.dtype, 0, None) GL.glEnableClientState(buffer.bufferType) GL.glDrawArrays(mode, 0, vertexBuffer.indices) # draw arrays # reset GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0) GL.glDisableClientState(vertexBuffer.bufferType) if args: for vbo in args: GL.glDisableClientState(vbo.bufferType) if flush: GL.glFlush()