Пример #1
0
    def plot(self):

        # Specify shader to be used
        glUseProgram(self.gls_pgr.program_id)

        # Bind VAO - this will automatically
        # bind all the vbo's saving us a bunch
        # of calls
        #glBindVertexArray(self.vao_id)

        glUniform4fv(self.gls_id_xy_color,1, self.plot_color)

        # Modern GL makes the draw call really simple
        # All the complexity has been pushed elsewhere


        glEnableVertexAttribArray(self.vertIndex)


        # set buffers
        glBindBuffer(GL_ARRAY_BUFFER, self.vertexBuffer)
        glVertexAttribPointer(self.vertIndex,2, GL_FLOAT, GL_FALSE, 0, None)

        glDrawArrays(GL_LINE_STRIP, 0, self.data_points-1)

        # Lets unbind the shader and vertex array state
        glUseProgram(0)
        # disable arrays
        glDisableVertexAttribArray(self.vertIndex)

        glBindVertexArray(0)
Пример #2
0
    def draw(self):
        """Draw test object."""

        glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
        glEnableVertexAttribArray(0)
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None)
        glDrawArrays(GL_TRIANGLES, 0, 6)
        glDisableVertexAttribArray(0)
        glBindBuffer(GL_ARRAY_BUFFER, 0)
Пример #3
0
 def add_attribute(self, vid, data, name):
     """Add array vertex attribute for shaders."""
     if data.ndim > 1:
         data = data.flatten()
     glBindBuffer(GL_ARRAY_BUFFER, self.__vbo_id[vid])
     glBufferData(GL_ARRAY_BUFFER, data.nbytes, data, GL_STATIC_DRAW)
     glVertexAttribPointer(glGetAttribLocation(self.__program, name),
                           3, GL_FLOAT, GL_FALSE, 0, None)
     glEnableVertexAttribArray(vid)
     self.__attributes.append(data)
Пример #4
0
    def bind_attributes(self, buffer_objects, attribute_inputs):
        # TODO
        for attr_name, attr_index in self._attributes.items():
            data = attribute_inputs[attr_name]
            bufname = data['buffer']
            buf = buffer_objects[bufname]

            buf.bind()
            glEnableVertexAttribArray(attr_index)
            # TODO
            buf.bind_to_attribute(attr_index, data['buffer_view'])
Пример #5
0
    def render(self):
        """Render game world."""

        for vbo in self.vbos:

            if vbo.render:

                glBindBuffer(GL_ARRAY_BUFFER, vbo.name)
                glEnableVertexAttribArray(0)
                glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None)

                glDrawArrays(
                    GL_TRIANGLES,
                    0,
                    vbo.vertexes_count)
                glDisableVertexAttribArray(0)
                glBindBuffer(GL_ARRAY_BUFFER, 0)
Пример #6
0
	def setup(self, actor):
		'''
		Setup the shader uniforms / attributes.
		Assumes actor.vbo is already bound
		'''
		# Bind the shader
		shaders.glUseProgram(self.program)

		# Enable vertex attribute arrays
		glEnableVertexAttribArray(self.attrib_position)
			
		# Set the Attribute pointers			
		glVertexAttribPointer(self.attrib_position, 4, GL_FLOAT, False, 0, actor.vbo)

		# Apply uniforms
		glUniformMatrix4fv(self.uniform_modelCamera, 1, GL_TRUE, actor.modelCamera_matrix)
		glUniformMatrix4fv(self.uniform_projection, 1, GL_TRUE, actor.projection_matrix)
		glUniform1f(self.uniform_alpha, actor.alpha)
		
		# Bind to the correct texture
		glBindTexture(GL_TEXTURE_2D, actor.texid)
Пример #7
0
	def setup(self, actor):
		'''
		Setup the shader uniforms / attributes.
		Assumes actor.vbo is already bound
		'''
		# Bind the shader
		shaders.glUseProgram(self.program)

		# Enable vertex attribute arrays
		glEnableVertexAttribArray(self.attrib_position)
		glEnableVertexAttribArray(self.attrib_color)
			
		# colorOffset is sizeof float (4) * floats per point (4) * num of points (vbo/2)
		colorOffset = 4 * 4 * (len(actor.vbo) / 2) 

		# Set the Attribute pointers			
		glVertexAttribPointer(self.attrib_position, 4, GL_FLOAT, False, 0, actor.vbo)
		glVertexAttribPointer(self.attrib_color,    4, GL_FLOAT, False, 0, actor.vbo + colorOffset)

		# Apply uniforms
		glUniformMatrix4fv(self.uniform_modelCamera, 1, GL_TRUE, actor.modelCamera_matrix)
		glUniformMatrix4fv(self.uniform_projection, 1, GL_TRUE, actor.projection_matrix)
		glUniform1f(self.uniform_alpha, actor.alpha)
Пример #8
0
def buff_vertices(verts: list, indes: list=None) -> int:
    """Given a list of vertex-like objects, an optional list of indices, returns a VAO handle.
    Format (all should be floats): [[pX, pY, pZ, nX, nY, nZ, cR, cR, cB, tU, tV]] * len."""
    vao = glGenVertexArrays(1)
    glBindVertexArray(vao)

    v = vbo.VBO(array(verts, 'f'))
    v.bind()
    glVertexAttribPointer(0, 3, GL_FLOAT, False, 44, v)
    glVertexAttribPointer(1, 3, GL_FLOAT, False, 44, v+12)
    glVertexAttribPointer(2, 3, GL_FLOAT, False, 44, v+24)
    glVertexAttribPointer(3, 2, GL_FLOAT, False, 44, v+36)
    glEnableVertexAttribArray(0)
    glEnableVertexAttribArray(1)
    glEnableVertexAttribArray(2)
    glEnableVertexAttribArray(3)
    # Maybe you want to include the vertices verbatim? Go for it.
    if indes is not None:
        ebo = glGenBuffers(1)
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo)
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, len(indes)*8, array(indes, 'i'), GL_STATIC_DRAW)

    glBindVertexArray(0)
    return vao
Пример #9
0
 def enable(self):
     " Enable the shader attribute "
     glEnableVertexAttribArray(self.loc)
Пример #10
0
    # Bind a buffer before we can use it
    glBindBuffer(GL_ARRAY_BUFFER, vbo_id[0])

    # Now go ahead and fill this bound buffer with some data
    glBufferData(GL_ARRAY_BUFFER,
        ArrayDatatype.arrayByteCount(vertex_data),
        vertex_data, GL_STATIC_DRAW)

    # Now specify how the shader program will be receiving this data
    # In this case the data from this buffer will be
    # available in the shader as the vin_position vertex attribute
    glVertexAttribPointer(program.attribute_location('vin_position'),
        3, GL_FLOAT, GL_FALSE, 0, None)

    # Turn on this vertex attribute in the shader
    glEnableVertexAttribArray(0)

    # Now do the same for the other vertex buffer
    glBindBuffer(GL_ARRAY_BUFFER, vbo_id[1])
    glBufferData(GL_ARRAY_BUFFER,
        ArrayDatatype.arrayByteCount(color_data),
        color_data, GL_STATIC_DRAW)
    glVertexAttribPointer(program.attribute_location('vin_color'),
        3, GL_FLOAT, GL_FALSE, 0, None)
    glEnableVertexAttribArray(1)

    # Lets unbind our vbo and vao state
    # We will bind these again in the draw loop
    glBindBuffer(GL_ARRAY_BUFFER, 0)
    glBindVertexArray(0)
Пример #11
0
def render_thing(thing, position_location, normal_location, color_location, modelview_location, context_matrix):
    try:
        translate = np.array(matrix_translate(thing["position"]), 'f')
    except:
        print "render_thing can't translate thing: ", thing
        exit()
    #print "render_thing type: ", thing["type"], thing["position"]
    context_matrix = np.dot(context_matrix, translate)

    rotates = thing["rotates"]
    if len(rotates) == 2:
        rotate0 = np.array(matrix_rotate_ortho(rotates[0]["angle"], rotates[0]["axis"]), 'f')
        tmp_matrix = np.dot(context_matrix, rotate0)
        rotate1 = np.array(matrix_rotate_ortho(rotates[1]["angle"], rotates[1]["axis"]), 'f')
        context_matrix = np.dot(tmp_matrix, rotate1)
    #print "render_thing:\n {}\n{}\n{}".format(translate, rotate0, rotate1)
    #print "context_matrix:\n", context_matrix
    glUniformMatrix4fv(modelview_location, 1, True, context_matrix)
    geometry = thing["geometry"]

    if geometry != None:
        if geometry["static"]:
            key = int(float(geometry["id"]))
            #print "thing type: {}, key: {}".format(thing["type"], key)
            if not key in vbos:
                vertices = geometry["vertices"]
                #print "adding geometry:\n{}".format(vertices[0])
                #vbos[key] = (vbo.VBO(np.array(vertices, 'f')), len(vertices))
                vbos[key] = (vbo.VBO(vertices), len(vertices))
            buffer_object, buffer_size = vbos[key]
        else:
            vertices = geometry["vertices"]
            buffer_object = vbo.VBO(vertices)
            buffer_size = len(vertices)
        #print "rendering type: {}, size: {}".format(buffer_object, buffer_size)
        #pdb.set_trace()
        buffer_object.bind()
        try:
            glEnableVertexAttribArray( position_location )
            glEnableVertexAttribArray( normal_location )
            glEnableVertexAttribArray( color_location )
            stride = 10*4
            glVertexAttribPointer(
                position_location,
                3, GL_FLOAT,False, stride, buffer_object
            )
            glVertexAttribPointer(
                normal_location,
                3, GL_FLOAT,False, stride, buffer_object+12
            )
            glVertexAttribPointer(
                color_location,
                4, GL_FLOAT,False, stride, buffer_object+24
            )
            glDrawArrays(GL_TRIANGLES, 0, buffer_size)
            #print 'buffer size: ', buffer_size

        finally:
            buffer_object.unbind()
            glDisableVertexAttribArray( position_location )
            glDisableVertexAttribArray( color_location )
    else:
        for child in thing["children"]:
            render_thing(child, position_location, normal_location, color_location, modelview_location, context_matrix)
Пример #12
0
    def __init__(self, vertices, indices, normals=None, uvs=None):
        """Constructor.

        Creates and initializes corresponding OpenGL objects with given data.

        :param vertices: Vertex data, specified as a contiguous list of X,Y,Z
            floating point values.
        :type vertices: list

        :param indices: Indices which identify model faces. The only supported
            geometry primitive is the triangle, thus, the size of indices list must
            be a multiple of 3.
        :type indices: list

        :param normals: Normals data, specified as a contiguos list of Xn,Yn,Zn
            floating point values. List length must be a multiple of 3.
        :type normals: list

        :param uvs: List of texture coordinates, specified as a contigous array
            of U,V floating pont values.. List length must be a multiple of 2.
        :type uvs: list
        """
        if len(vertices) < 3 or len(vertices) % 3:
            raise ValueError(
                'Vertex data must be an array of floats, which length is a '
                'positive multiple of 3')

        if len(indices) < 3 or len(indices) % 3:
            raise ValueError('Indices count must be a positive multiple of 3')

        if normals and (len(normals) < 3 or len(normals) % 3):
            raise ValueError(
                'Normals data must be an array of floats, which length is a '
                'positive multiple of 3')

        if uvs is not None and len(uvs) % 2:
            raise ValueError('UVs count must be a positive multiple of 2')

        self.num_elements = len(indices)

        # generate vertex array object and make it active
        self.vao = glGenVertexArrays(1)
        glBindVertexArray(self.vao)

        # generate buffers
        self.buffers = glGenBuffers(2)
        vbo, ibo = self.buffers

        # initialize vertex buffer
        vertex_data = np.array(vertices, np.float32)

        # append normals data, if provided
        normals_offset = 0
        if normals:
            normals_offset = vertex_data.nbytes
            vertex_data = np.append(vertex_data, np.array(normals, np.float32))

        # append UVs data, if provided
        uvs_offset = 0
        if uvs:
            uvs_offset = vertex_data.nbytes
            vertex_data = np.append(vertex_data, np.array(uvs, np.float32))

        glBindBuffer(GL_ARRAY_BUFFER, vbo)
        glBufferData(GL_ARRAY_BUFFER, vertex_data.nbytes,
                     vertex_data, GL_STATIC_DRAW)

        # initialize index buffer
        index_data = np.array(indices, np.uint32)
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo)
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_data.nbytes,
                     index_data, GL_STATIC_DRAW)

        # specify first attribute as vertex data
        glEnableVertexAttribArray(0)
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None)

        # if provided, specify normals as second attribute
        if normals is not None:
            glEnableVertexAttribArray(1)
            glVertexAttribPointer(
                1,
                3,
                GL_FLOAT,
                GL_FALSE,
                0,
                ctypes.c_void_p(normals_offset))

        # if provided, specify UVs as third attribute
        if uvs is not None:
            glEnableVertexAttribArray(2)
            glVertexAttribPointer(
                2,
                2,
                GL_FLOAT,
                GL_FALSE,
                0,
                ctypes.c_void_p(uvs_offset))

        # unbind the vertex array object
        glBindVertexArray(0)
Пример #13
0
def run():
	#Start OpenGL and ask it for an OpenGL context
	pygame.init()
	clock = pygame.time.Clock()
	screen = pygame.display.set_mode(SCREEN_SIZE, pygame.HWSURFACE|pygame.OPENGL|pygame.DOUBLEBUF)
	
	#The first thing we do is print some OpenGL details and check that we have a good enough version
	print("OpenGL Implementation Details:")
	if glGetString(GL_VENDOR):
		print("\tGL_VENDOR: {}".format(glGetString(GL_VENDOR).decode()))
	if glGetString(GL_RENDERER):
		print("\tGL_RENDERER: {}".format(glGetString(GL_RENDERER).decode()))
	if glGetString(GL_VERSION):
		print("\tGL_VERSION: {}".format(glGetString(GL_VERSION).decode()))
	if glGetString(GL_SHADING_LANGUAGE_VERSION):
		print("\tGL_SHADING_LANGUAGE_VERSION: {}".format(glGetString(GL_SHADING_LANGUAGE_VERSION).decode()))
	
	major_version = int(glGetString(GL_VERSION).decode().split()[0].split('.')[0])
	minor_version = int(glGetString(GL_VERSION).decode().split()[0].split('.')[1])
	if major_version < 3 or (major_version < 3 and minor_version < 0):
		print("OpenGL version must be at least 3.0 (found {0})".format(glGetString(GL_VERSION).decode().split()[0]))
	
	#Now onto the OpenGL initialisation
	
	#Set up depth culling
	glEnable(GL_CULL_FACE)
	glEnable(GL_DEPTH_TEST)
	glDepthMask(GL_TRUE)
	glDepthFunc(GL_LEQUAL)
	glDepthRange(0.0, 1.0)
	
	#We create out shaders which do little more than set a flat colour for each face
	
	VERTEX_SHADER = shaders.compileShader(b"""
	#version 130
	
	in vec4 position;
	in vec4 normal;
	
	uniform mat4 projectionMatrix;
	uniform mat4 viewMatrix;
	uniform mat4 modelMatrix;
	
	flat out float theColor;
	
	void main()
	{
		vec4 temp = modelMatrix * position;
		temp = viewMatrix * temp;
		gl_Position = projectionMatrix * temp;
		
		theColor = clamp(abs(dot(normalize(normal.xyz), normalize(vec3(0.9,0.1,0.5)))), 0, 1);
	}
	""", GL_VERTEX_SHADER)
	
	
	FRAGMENT_SHADER = shaders.compileShader(b"""
	#version 130
	
	flat in float theColor;
	
	out vec4 outputColor;
	void main()
	{
		outputColor = vec4(1.0, 0.5, theColor, 1.0);
	}
	""", GL_FRAGMENT_SHADER)
	
	shader = shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER)
	
	#And then grab our attribute locations from it
	glBindAttribLocation(shader, 0, b"position")
	glBindAttribLocation(shader, 1, b"normal")
	
	#Create the Vertex Array Object to hold our volume mesh
	vertexArrayObject = GLuint(0)
	glGenVertexArrays(1, vertexArrayObject)
	glBindVertexArray(vertexArrayObject)
	
	#Create the index buffer object
	indexPositions = vbo.VBO(indices, target=GL_ELEMENT_ARRAY_BUFFER, usage=GL_STATIC_DRAW)
	#Create the VBO
	vertexPositions = vbo.VBO(vertices, usage=GL_STATIC_DRAW)
	
	#Bind our VBOs and set up our data layout specifications
	with indexPositions, vertexPositions:
		glEnableVertexAttribArray(0)
		glVertexAttribPointer(0, 3, GL_FLOAT, False, 6*vertices.dtype.itemsize, vertexPositions+(0*vertices.dtype.itemsize))
		glEnableVertexAttribArray(1)
		glVertexAttribPointer(1, 3, GL_FLOAT, False, 6*vertices.dtype.itemsize, vertexPositions+(3*vertices.dtype.itemsize))
		
		glBindVertexArray(0)
		glDisableVertexAttribArray(0)
	
	#Now grab out transformation martix locations
	modelMatrixUnif = glGetUniformLocation(shader, b"modelMatrix")
	viewMatrixUnif = glGetUniformLocation(shader, b"viewMatrix")
	projectionMatrixUnif = glGetUniformLocation(shader, b"projectionMatrix")
	
	modelMatrix = np.array([[1.0,0.0,0.0,-32.0],[0.0,1.0,0.0,-32.0],[0.0,0.0,1.0,-32.0],[0.0,0.0,0.0,1.0]], dtype='f')
	viewMatrix = np.array([[1.0,0.0,0.0,0.0],[0.0,1.0,0.0,0.0],[0.0,0.0,1.0,-50.0],[0.0,0.0,0.0,1.0]], dtype='f')
	projectionMatrix = np.array([[0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0]], dtype='f')
	
	#These next few lines just set up our camera frustum
	fovDeg = 45.0
	frustumScale = 1.0 / tan(radians(fovDeg) / 2.0)
	
	zNear = 1.0
	zFar = 1000.0
	
	projectionMatrix[0][0] = frustumScale
	projectionMatrix[1][1] = frustumScale
	projectionMatrix[2][2] = (zFar + zNear) / (zNear - zFar)
	projectionMatrix[2][3] = -1.0
	projectionMatrix[3][2] = (2 * zFar * zNear) / (zNear - zFar)
	
	#viewMatrix and projectionMatrix don't change ever so just set them once here
	with shader:
		glUniformMatrix4fv(projectionMatrixUnif, 1, GL_TRUE, projectionMatrix)
		glUniformMatrix4fv(viewMatrixUnif, 1, GL_TRUE, viewMatrix)
	
	#These are used to track the rotation of the volume
	LastFrameMousePos = (0,0)
	CurrentMousePos = (0,0)
	xRotation = 0
	yRotation = 0
	
	while True:
		clock.tick()
		
		for event in pygame.event.get():
			if event.type == pygame.QUIT:
				return
			if event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE:
				return
			if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
				CurrentMousePos = event.pos
				LastFrameMousePos = CurrentMousePos
			if event.type == pygame.MOUSEMOTION and 1 in event.buttons:
				CurrentMousePos = event.pos
				diff = (CurrentMousePos[0] - LastFrameMousePos[0], CurrentMousePos[1] - LastFrameMousePos[1])
				xRotation += event.rel[0]
				yRotation += event.rel[1]
				LastFrameMousePos = CurrentMousePos
		
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
		
		#Perform the rotation of the mesh
		moveToOrigin = np.array([[1.0,0.0,0.0,-32.0],[0.0,1.0,0.0,-32.0],[0.0,0.0,1.0,-32.0],[0.0,0.0,0.0,1.0]], dtype='f')
		rotateAroundX = np.array([[1.0,0.0,0.0,0.0],[0.0,cos(radians(yRotation)),-sin(radians(yRotation)),0.0],[0.0,sin(radians(yRotation)),cos(radians(yRotation)),0.0],[0.0,0.0,0.0,1.0]], dtype='f')
		rotateAroundY = np.array([[cos(radians(xRotation)),0.0,sin(radians(xRotation)),0.0],[0.0,1.0,0.0,0.0],[-sin(radians(xRotation)),0.0,cos(radians(xRotation)),0.0],[0.0,0.0,0.0,1.0]], dtype='f')
		
		modelMatrix = rotateAroundY.dot(rotateAroundX.dot(moveToOrigin))
		
		with shader:
			glUniformMatrix4fv(modelMatrixUnif, 1, GL_TRUE, modelMatrix)
			glBindVertexArray(vertexArrayObject)
			
			glDrawElements(GL_TRIANGLES, len(indices), GL_UNSIGNED_INT, None)
			
			glBindVertexArray(0)
		
		# Show the screen
		pygame.display.flip()
Пример #14
0
def create_field(rows, cols, size, fun, gen_textures, gen_relief=False):

    normals_vec = np.zeros((rows * cols, 3), dtype=np.float32)

    vertices_list = []
    texcoords_list = []
    faces_list = []
    indices_list = []

    if not gen_relief:
        for z in range(0, rows):
            for x in range(0, cols):

                # if (x**2 + z**2)**(1/2) <= cols:
                xx = -size / 2 + x * size / cols
                zz = -size / 2 + z * size / rows

                try:
                    yy = fun(xx, zz)
                    if yy < -size / 2:
                        yy = -size / 2
                    if yy > size / 2:
                        yy = size / 2
                except (ArithmeticError, ValueError):
                    yy = 0.0

                vertices_list.append([xx, yy, zz])
                if gen_textures:
                    texcoords_list.append(
                        [x / float(cols - 1), z / float(rows - 1)])
    else:
        buff1 = []
        vertices_list_mountain = []
        for z in range(0, rows):
            del buff1[:]
            for x in range(0, cols):
                xx = -size / 2 + x * size / cols
                zz = -size / 2 + z * size / rows
                yy = 0.0

                buff1.append([xx, yy, zz])

            vertices_list_mountain.append(buff1[:])
        for i in range(0, 250):
            radius = 12
            z = randint(0, rows - 1)
            x = randint(0, cols - 1)
            for iz in range(z - radius, z + radius):
                if iz < 0 or iz > rows - 1:
                    continue
                else:
                    for ix in range(x - radius, x + radius):
                        if ix < 0 or ix > cols - 1:
                            continue
                        else:
                            if radius**2 - (
                                (z - iz + 10)**2 + (x - ix)
                            ) > vertices_list_mountain[iz][ix][1]**(2):
                                vertices_list_mountain[iz][ix][1] = (
                                    radius**2 - ((z - iz + 10)**2 +
                                                 (x - ix)))**(1 / 2)
                            else:
                                continue

        v = vertices_list_mountain[:]
        vec_lines = []
        for ii in range(0, 10):
            i = 2 * ii
            for z in range(0, rows - 1):
                for x in range(0, cols - 1):
                    xx = -size / 2 + x * size / cols
                    zz = -size / 2 + z * size / rows

                    if v[z][x][1] < i and v[z][x + 1][1] < i and v[z + 1][x][1] < i and v[z + 1][x + 1][1] < i or \
                            v[z][x][1] >= i and v[z][x + 1][1] >= i and v[z + 1][x][1] >= i and v[z + 1][x + 1][1] >= i:
                        continue
                    elif v[z][x][1] >= i and v[z][x + 1][1] < i and v[
                            z + 1][x][1] < i and v[z + 1][x + 1][1] < i:
                        vec_lines.append([xx + 0.25, i, zz])
                        vec_lines.append([xx, i, zz + 0.25])
                    elif v[z][x][1] < i and v[z][x + 1][1] >= i and v[
                            z + 1][x][1] < i and v[z + 1][x + 1][1] < i:
                        vec_lines.append([xx + 0.25, i, zz])
                        vec_lines.append([xx + 0.5, i, zz + 0.25])
                    elif v[z][x][1] < i and v[z][x + 1][1] < i and v[
                            z + 1][x][1] >= i and v[z + 1][x + 1][1] < i:
                        vec_lines.append([xx + 0.25, i, zz + 0.5])
                        vec_lines.append([xx, i, zz + 0.25])
                    elif v[z][x][1] < i and v[z][x + 1][1] < i and v[
                            z + 1][x][1] < i and v[z + 1][x + 1][1] >= i:
                        vec_lines.append([xx + 0.25, i, zz + 0.5])
                        vec_lines.append([xx + 0.5, i, zz + 0.25])

                    elif v[z][x][1] < i and v[z][x + 1][1] >= i and v[
                            z + 1][x][1] >= i and v[z + 1][x + 1][1] >= i:
                        vec_lines.append([xx + 0.25, i, zz])
                        vec_lines.append([xx, i, zz + 0.25])
                    elif v[z][x][1] >= i and v[z][x + 1][1] < i and v[
                            z + 1][x][1] >= i and v[z + 1][x + 1][1] >= i:
                        vec_lines.append([xx + 0.25, i, zz])
                        vec_lines.append([xx + 0.5, i, zz + 0.25])
                    elif v[z][x][1] >= i and v[z][x + 1][1] >= i and v[
                            z + 1][x][1] < i and v[z + 1][x + 1][1] >= i:
                        vec_lines.append([xx + 0.25, i, zz + 0.5])
                        vec_lines.append([xx, i, zz + 0.25])
                    elif v[z][x][1] >= i and v[z][x + 1][1] >= i and v[
                            z + 1][x][1] >= i and v[z + 1][x + 1][1] < i:
                        vec_lines.append([xx + 0.25, i, zz + 0.5])
                        vec_lines.append([xx + 0.5, i, zz + 0.25])

                    elif v[z][x][1] < i and v[z][x + 1][1] < i and v[z + 1][x][1] >= i and v[z + 1][x + 1][1] >= i or \
                         v[z][x][1] >= i and v[z][x + 1][1] >= i and v[z + 1][x][1] < i and v[z + 1][x + 1][1] < i:
                        vec_lines.append([xx, i, zz + 0.25])
                        vec_lines.append([xx + 0.5, i, zz + 0.25])
                    elif v[z][x][1] >= i and v[z][x + 1][1] < i and v[z + 1][x][1] >= i and v[z + 1][x + 1][1] < i or \
                            v[z][x][1] < i and v[z][x + 1][1] >= i and v[z + 1][x][1] < i and v[z + 1][x + 1][1] >= i:
                        vec_lines.append([xx + 0.25, i, zz])
                        vec_lines.append([xx + 0.25, i, zz + 0.5])

                    elif v[z][x][1] >= i and v[z][x + 1][1] < i and v[z + 1][x][1] < i and v[z + 1][x + 1][1] >= i or \
                            v[z][x][1] < i and v[z][x + 1][1] >= i and v[z + 1][x][1] >= i and v[z + 1][x + 1][1] < i:
                        vec_lines.append([xx, i, zz + 0.25])
                        vec_lines.append([xx + 0.25, i, zz])
                        vec_lines.append([xx + 0.5, i, zz + 0.25])
                        vec_lines.append([xx + 0.25, i, zz + 0.5])

        index_lines = [it for it in range(0, len(vec_lines))]
        vector_lines = np.array(vec_lines, dtype=np.float32)
        vector_line_indexes = np.array(index_lines, dtype=np.uint32)

        for z in range(0, rows):
            for x in range(0, cols):
                vertices_list.append(vertices_list_mountain[z][x])

    primRestart = rows * cols

    vertices_vec = np.array(vertices_list, dtype=np.float32)
    print(len(vertices_list))
    print(vertices_vec.size)
    print(len(indices_list))
    print(size)
    if gen_textures:
        texcoords_vec = np.array(texcoords_list, dtype=np.float32)

    for x in range(0, cols - 1):
        for z in range(0, rows - 1):
            if ((50 - x)**2 +
                (50 - z)**2)**(1 / 2) <= (rows - 1) / 2 or gen_relief == True:
                offset = x * cols + z
                if z == 0:
                    indices_list.append(offset)
                    indices_list.append(offset + rows)
                    indices_list.append(offset + 1)
                    indices_list.append(offset + rows + 1)
                else:
                    indices_list.append(offset + 1)
                    indices_list.append(offset + rows + 1)
                    if z == rows - 2:
                        indices_list.append(primRestart)

    print(len(indices_list))
    indices_vec = np.array(indices_list, dtype=np.uint32)

    print(indices_vec.size)
    currFace = 1
    for i in range(0, indices_vec.size - 2):
        index0 = indices_vec[i]
        index1 = indices_vec[i + 1]
        index2 = indices_vec[i + 2]

        face = np.array([0, 0, 0], dtype=np.int32)
        if (index0 != primRestart) and (index1 != primRestart) and (
                index2 != primRestart):
            if currFace % 2 != 0:
                face[0] = indices_vec[i]
                face[1] = indices_vec[i + 1]
                face[2] = indices_vec[i + 2]
                currFace += 1
            else:
                face[0] = indices_vec[i]
                face[1] = indices_vec[i + 2]
                face[2] = indices_vec[i + 1]
                currFace += 1

            faces_list.append(face)

    faces = np.reshape(faces_list, newshape=(len(faces_list), 3))

    for i in range(0, faces.shape[0]):
        A = np.array([
            vertices_vec[faces[i, 0], 0], vertices_vec[faces[i, 0], 1],
            vertices_vec[faces[i, 0], 2]
        ],
                     dtype=np.float32)
        B = np.array([
            vertices_vec[faces[i, 1], 0], vertices_vec[faces[i, 1], 1],
            vertices_vec[faces[i, 1], 2]
        ],
                     dtype=np.float32)
        C = np.array([
            vertices_vec[faces[i, 2], 0], vertices_vec[faces[i, 2], 1],
            vertices_vec[faces[i, 2], 2]
        ],
                     dtype=np.float32)

        edge1A = normalize(B - A)
        edge2A = normalize(C - A)

        face_normal = np.cross(edge1A, edge2A)

        normals_vec[faces[i, 0]] += face_normal
        normals_vec[faces[i, 1]] += face_normal
        normals_vec[faces[i, 2]] += face_normal

    for i in range(0, normals_vec.shape[0]):
        normals_vec[i] = normalize(normals_vec[i])

    vao = glGenVertexArrays(1)
    vbo_vertices = glGenBuffers(1)
    vbo_normals = glGenBuffers(1)
    if gen_textures:
        vbo_texcoords = glGenBuffers(1)
    vbo_indices = glGenBuffers(1)

    glBindVertexArray(vao)

    glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices)
    glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(vertices_vec),
                 vertices_vec.flatten(), GL_STATIC_DRAW)  #
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None)
    glEnableVertexAttribArray(0)

    glBindBuffer(GL_ARRAY_BUFFER, vbo_normals)
    glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(normals_vec),
                 normals_vec.flatten(), GL_STATIC_DRAW)  #
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, None)
    glEnableVertexAttribArray(1)

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_indices)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,
                 ArrayDatatype.arrayByteCount(indices_vec),
                 indices_vec.flatten(), GL_STATIC_DRAW)

    if gen_textures:
        glBindBuffer(GL_ARRAY_BUFFER, vbo_texcoords)
        glBufferData(GL_ARRAY_BUFFER,
                     ArrayDatatype.arrayByteCount(texcoords_vec),
                     texcoords_vec.flatten(), GL_STATIC_DRAW)
        glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, None)
        glEnableVertexAttribArray(2)

    glEnable(GL_PRIMITIVE_RESTART)
    glPrimitiveRestartIndex(primRestart)

    glBindVertexArray(0)
    if gen_relief:
        return (vao, indices_vec.size, vector_lines, vector_line_indexes)
    else:
        return (vao, indices_vec.size)
Пример #15
0
    vbo_id = glGenBuffers(2)

    # Bind a buffer before we can use it
    glBindBuffer(GL_ARRAY_BUFFER, vbo_id[0])

    # Now go ahead and fill this bound buffer with some data
    glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(vertex_data),
                 vertex_data, GL_STATIC_DRAW)

    # Now specify how the shader program will be receiving this data
    # In this case the data from this buffer will be available in the shader as the vin_position vertex attribute
    glVertexAttribPointer(program.attribute_location('vin_position'), 3,
                          GL_FLOAT, GL_FALSE, 0, None)

    # Turn on this vertex attribute in the shader
    glEnableVertexAttribArray(0)

    # Now do the same for the other vertex buffer
    glBindBuffer(GL_ARRAY_BUFFER, vbo_id[1])
    glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(color_data),
                 color_data, GL_STATIC_DRAW)
    glVertexAttribPointer(program.attribute_location('vin_color'), 3, GL_FLOAT,
                          GL_FALSE, 0, None)
    glEnableVertexAttribArray(1)

    # Lets unbind our vbo and vao state
    # We will bind these again in the draw loop
    glBindBuffer(GL_ARRAY_BUFFER, 0)
    glBindVertexArray(0)

    running = True
Пример #16
0
    def build(self) -> bool:
        """
        Build OpenGL Vertex Array for the object

        This function gets automatically called if `self._vao` does not
        exists in the first render cycle. Once the vba is built,
        geometry changes or material display mode changes will not be
        automatically effected. So, in every geometry or display mode
        change, a `build` call is necessary.

        If `self.static` is `True`, then the system assumes that another update
        call is not expected, thus frees `_normals`, `_textcoords`,
        `_vertices` and `_indices` lists to free memory.
        So in this case, calling `build` function twice will result in
        an invisible object (will not be drawn).

        Returns:
          bool
        """
        if len(self._indices) == 0:
            return False

        # If we don't have a VAO yet, we need to create one
        if not self.has_vao:
            # Generate Vertex Array
            self._vao = glGenVertexArrays(1)
            # We need 5 buffers (vertex, normal, texcoord, color, indices)
            self._vbos = glGenBuffers(5)
            glBindVertexArray(self._vao)
            # Material shader must be built when there is an active binding
            # to vertex array
            self.material.build_shader()
        else:
            # Ok, we already have vertex array object, just bind it to modify
            glBindVertexArray(self._vao)

        # Turn python arrays into C type arrays using Numpy.
        # This is required for OpenGL. Python memory model is a bit
        # different than raw memory model of C (OpenGL)
        vertices = np.array(self._vertices, dtype=np.float32).flatten()
        normals = np.array(self._normals, dtype=np.float32).flatten()
        texcoords = np.array(self._texcoords, dtype=np.float32).flatten()
        colors = np.array(self._vertex_colors, dtype=np.float32).flatten()
        indices = np.array(self._indices, dtype=np.int32).flatten()
        self._calc_bounds()

        # OpenGL allocates buffers in different mechanisms between
        # STATIC and DYNAMIC draw modes. If you select STATIC, then OpenGL
        # will assume that object buffer will not change and allocate it in a
        # more suitable way.
        draw = GL_STATIC_DRAW
        if not self.static:
            draw = GL_DYNAMIC_DRAW

        # Buffer overflow, we need more space.
        if self._buffer_size < vertices.nbytes:
            self._buffer_size = vertices.nbytes
            self._buffer_size_changed = True
        if self._t_buffer_size < texcoords.nbytes:
            self._t_buffer_size = texcoords.nbytes
            self._t_buffer_size_changed = True

        # Bind Vertices
        glBindBuffer(GL_ARRAY_BUFFER, self._vbos[0])
        glEnableVertexAttribArray(0)  # shader layout location
        glVertexAttribPointer(0, 3, GL_FLOAT, False, 0, ctypes.c_void_p(0))
        if self._buffer_size_changed:
            # glBufferData creates a new data area
            glBufferData(GL_ARRAY_BUFFER, self._buffer_size, vertices, draw)
        else:
            # glBufferSubData just replaces memory area in buffer so it is
            # much more efficient way to handle things.
            glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.nbytes, vertices)

        # Bind Normals
        glBindBuffer(GL_ARRAY_BUFFER, self._vbos[1])
        glEnableVertexAttribArray(1)  # shader layout location
        glVertexAttribPointer(1, 3, GL_FLOAT, False, 0, ctypes.c_void_p(0))
        if self._buffer_size_changed:
            glBufferData(GL_ARRAY_BUFFER, self._buffer_size, normals, draw)
        else:
            glBufferSubData(GL_ARRAY_BUFFER, 0, normals.nbytes, normals)

        # Bind TexCoords
        if len(self._texcoords) == len(self._vertices):
            glBindBuffer(GL_ARRAY_BUFFER, self._vbos[2])
            glEnableVertexAttribArray(2)  # shader layout location
            glVertexAttribPointer(2, 2, GL_FLOAT, False, 0, ctypes.c_void_p(0))
            if self._t_buffer_size_changed:
                glBufferData(
                    GL_ARRAY_BUFFER, self._t_buffer_size, texcoords, draw
                )
            else:
                glBufferSubData(
                    GL_ARRAY_BUFFER, 0, texcoords.nbytes, texcoords
                )

        # Bind Vertex Colors
        if len(self._vertex_colors) == len(self._vertices):
            glBindBuffer(GL_ARRAY_BUFFER, self._vbos[4])
            glEnableVertexAttribArray(3)  # shader layout location
            glVertexAttribPointer(3, 3, GL_FLOAT, False, 0, ctypes.c_void_p(0))
            self._has_vertex_colors = True
            if self._buffer_size_changed:
                glBufferData(GL_ARRAY_BUFFER, self._buffer_size, colors, draw)
            else:
                glBufferSubData(GL_ARRAY_BUFFER, 0, colors.nbytes, colors)

        self._buffer_size_changed = False
        self._t_buffer_size_changed = False

        # Bind Indices
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self._vbos[3])
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.nbytes, indices, draw)
        self._vertex_count = len(indices)

        glBindVertexArray(0)
        glBindBuffer(GL_ARRAY_BUFFER, 0)

        if self.static:
            # we can clear this data to free some more memory
            glDeleteBuffers(4, self._vbos)
            self._vbos = []

        self._needs_update = False

        return True
Пример #17
0
    def create_vaos(self) -> None:
        """Bind VAOs to define vertex data."""
        self._vao, self._vao_picking, self._vao_outline = glGenVertexArrays(3)
        vbo = glGenBuffers(6)

        # --- standard viewcube ---

        vertices = glm.array.from_numbers(
            ctypes.c_float,
            1.0,
            1.0,
            1.0,
            0.7,
            0.7,
            0.7,
            1.0,
            -1.0,
            1.0,
            0.7,
            0.7,
            0.7,
            1.0,
            -1.0,
            -1.0,
            0.4,
            0.4,
            0.4,
            1.0,
            1.0,
            -1.0,
            0.4,
            0.4,
            0.4,
            -1.0,
            1.0,
            -1.0,
            0.4,
            0.4,
            0.4,
            -1.0,
            1.0,
            1.0,
            0.7,
            0.7,
            0.7,
            -1.0,
            -1.0,
            1.0,
            0.7,
            0.7,
            0.7,
            -1.0,
            -1.0,
            -1.0,
            0.4,
            0.4,
            0.4,
        )
        indices = glm.array.from_numbers(
            ctypes.c_uint,
            0,
            1,
            2,
            2,
            3,
            0,
            0,
            3,
            4,
            4,
            5,
            0,
            0,
            5,
            6,
            6,
            1,
            0,
            1,
            6,
            7,
            7,
            2,
            1,
            7,
            4,
            3,
            3,
            2,
            7,
            4,
            7,
            6,
            6,
            5,
            4,
        )
        glBindVertexArray(self._vao)

        glBindBuffer(GL_ARRAY_BUFFER, vbo[0])
        glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices.ptr,
                     GL_STATIC_DRAW)
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 24, ctypes.c_void_p(0))
        glEnableVertexAttribArray(0)

        glBindBuffer(GL_ARRAY_BUFFER, vbo[1])
        glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices.ptr,
                     GL_STATIC_DRAW)
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 24,
                              ctypes.c_void_p(12))
        glEnableVertexAttribArray(1)

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[2])
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.nbytes, indices.ptr,
                     GL_STATIC_DRAW)

        # --- viewcube for picking ---

        vertices = glm.array.from_numbers(
            ctypes.c_float,
            1.0,
            -1.0,
            1.0,  # 1 front  (id = 0)
            -1.0,
            -1.0,
            1.0,  # 6
            -1.0,
            -1.0,
            -1.0,  # 7
            1.0,
            -1.0,
            -1.0,  # 2
            1.0,
            1.0,
            1.0,  # 0 top    (id = 1)
            -1.0,
            1.0,
            1.0,  # 5
            -1.0,
            -1.0,
            1.0,  # 6
            1.0,
            -1.0,
            1.0,  # 1
            1.0,
            1.0,
            1.0,  # 0 right  (id = 2)
            1.0,
            -1.0,
            1.0,  # 1
            1.0,
            -1.0,
            -1.0,  # 2
            1.0,
            1.0,
            -1.0,  # 3
            -1.0,
            -1.0,
            -1.0,  # 7 bottom (id = 3)
            -1.0,
            1.0,
            -1.0,  # 4
            1.0,
            1.0,
            -1.0,  # 3
            1.0,
            -1.0,
            -1.0,  # 2
            -1.0,
            -1.0,
            -1.0,  # 7 left   (id = 4)
            -1.0,
            -1.0,
            1.0,  # 6
            -1.0,
            1.0,
            1.0,  # 5
            -1.0,
            1.0,
            -1.0,  # 4
            1.0,
            1.0,
            1.0,  # 0 back   (id = 5)
            1.0,
            1.0,
            -1.0,  # 3
            -1.0,
            1.0,
            -1.0,  # 4
            -1.0,
            1.0,
            1.0,  # 5
        )
        colors = np.zeros(72, dtype=np.float32)
        colors[::3] = np.arange(6).repeat(4) / 255.0
        glBindVertexArray(self._vao_picking)

        glBindBuffer(GL_ARRAY_BUFFER, vbo[3])
        glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices.ptr,
                     GL_STATIC_DRAW)
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0))
        glEnableVertexAttribArray(0)

        glBindBuffer(GL_ARRAY_BUFFER, vbo[4])
        glBufferData(GL_ARRAY_BUFFER, colors.nbytes, colors, GL_STATIC_DRAW)
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0))
        glEnableVertexAttribArray(1)

        # --- outlined face of viewcube ---

        border_colors = glm.array.from_numbers(ctypes.c_float, 0.0000, 0.4088,
                                               0.9486).repeat(24)
        glBindVertexArray(self._vao_outline)

        glBindBuffer(GL_ARRAY_BUFFER, vbo[3])
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0))
        glEnableVertexAttribArray(0)

        glBindBuffer(GL_ARRAY_BUFFER, vbo[5])
        glBufferData(GL_ARRAY_BUFFER, border_colors.nbytes, border_colors.ptr,
                     GL_STATIC_DRAW)
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0))
        glEnableVertexAttribArray(1)

        # ---

        glBindVertexArray(0)
        glDeleteBuffers(6, vbo)
Пример #18
0
def run():
    #Start OpenGL and ask it for an OpenGL context
    pygame.init()
    clock = pygame.time.Clock()
    screen = pygame.display.set_mode(
        SCREEN_SIZE, pygame.HWSURFACE | pygame.OPENGL | pygame.DOUBLEBUF)

    #The first thing we do is print some OpenGL details and check that we have a good enough version
    print("OpenGL Implementation Details:")
    if glGetString(GL_VENDOR):
        print("\tGL_VENDOR: {}".format(glGetString(GL_VENDOR).decode()))
    if glGetString(GL_RENDERER):
        print("\tGL_RENDERER: {}".format(glGetString(GL_RENDERER).decode()))
    if glGetString(GL_VERSION):
        print("\tGL_VERSION: {}".format(glGetString(GL_VERSION).decode()))
    if glGetString(GL_SHADING_LANGUAGE_VERSION):
        print("\tGL_SHADING_LANGUAGE_VERSION: {}".format(
            glGetString(GL_SHADING_LANGUAGE_VERSION).decode()))

    major_version = int(
        glGetString(GL_VERSION).decode().split()[0].split('.')[0])
    minor_version = int(
        glGetString(GL_VERSION).decode().split()[0].split('.')[1])
    if major_version < 3 or (major_version < 3 and minor_version < 0):
        print("OpenGL version must be at least 3.0 (found {0})".format(
            glGetString(GL_VERSION).decode().split()[0]))

    #Now onto the OpenGL initialisation

    #Set up depth culling
    glEnable(GL_CULL_FACE)
    glEnable(GL_DEPTH_TEST)
    glDepthMask(GL_TRUE)
    glDepthFunc(GL_LEQUAL)
    glDepthRange(0.0, 1.0)

    #We create out shaders which do little more than set a flat colour for each face

    VERTEX_SHADER = shaders.compileShader(
        b"""
	#version 130
	
	in vec4 position;
	in vec4 normal;
	
	uniform mat4 projectionMatrix;
	uniform mat4 viewMatrix;
	uniform mat4 modelMatrix;
	
	flat out float theColor;
	
	void main()
	{
		vec4 temp = modelMatrix * position;
		temp = viewMatrix * temp;
		gl_Position = projectionMatrix * temp;
		
		theColor = clamp(abs(dot(normalize(normal.xyz), normalize(vec3(0.9,0.1,0.5)))), 0, 1);
	}
	""", GL_VERTEX_SHADER)

    FRAGMENT_SHADER = shaders.compileShader(
        b"""
	#version 130
	
	flat in float theColor;
	
	out vec4 outputColor;
	void main()
	{
		outputColor = vec4(1.0, 0.5, theColor, 1.0);
	}
	""", GL_FRAGMENT_SHADER)

    shader = shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER)

    #And then grab our attribute locations from it
    glBindAttribLocation(shader, 0, b"position")
    glBindAttribLocation(shader, 1, b"normal")

    #Create the Vertex Array Object to hold our volume mesh
    vertexArrayObject = GLuint(0)
    glGenVertexArrays(1, vertexArrayObject)
    glBindVertexArray(vertexArrayObject)

    #Create the index buffer object
    indexPositions = vbo.VBO(indices,
                             target=GL_ELEMENT_ARRAY_BUFFER,
                             usage=GL_STATIC_DRAW)
    #Create the VBO
    vertexPositions = vbo.VBO(vertices, usage=GL_STATIC_DRAW)

    #Bind our VBOs and set up our data layout specifications
    with indexPositions, vertexPositions:
        glEnableVertexAttribArray(0)
        glVertexAttribPointer(0, 3, GL_FLOAT, False,
                              6 * vertices.dtype.itemsize,
                              vertexPositions + (0 * vertices.dtype.itemsize))
        glEnableVertexAttribArray(1)
        glVertexAttribPointer(1, 3, GL_FLOAT, False,
                              6 * vertices.dtype.itemsize,
                              vertexPositions + (3 * vertices.dtype.itemsize))

        glBindVertexArray(0)
        glDisableVertexAttribArray(0)

    #Now grab out transformation martix locations
    modelMatrixUnif = glGetUniformLocation(shader, b"modelMatrix")
    viewMatrixUnif = glGetUniformLocation(shader, b"viewMatrix")
    projectionMatrixUnif = glGetUniformLocation(shader, b"projectionMatrix")

    modelMatrix = np.array([[1.0, 0.0, 0.0, -32.0], [0.0, 1.0, 0.0, -32.0],
                            [0.0, 0.0, 1.0, -32.0], [0.0, 0.0, 0.0, 1.0]],
                           dtype='f')
    viewMatrix = np.array([[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0],
                           [0.0, 0.0, 1.0, -50.0], [0.0, 0.0, 0.0, 1.0]],
                          dtype='f')
    projectionMatrix = np.array([[0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0],
                                 [0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0]],
                                dtype='f')

    #These next few lines just set up our camera frustum
    fovDeg = 45.0
    frustumScale = 1.0 / tan(radians(fovDeg) / 2.0)

    zNear = 1.0
    zFar = 1000.0

    projectionMatrix[0][0] = frustumScale
    projectionMatrix[1][1] = frustumScale
    projectionMatrix[2][2] = (zFar + zNear) / (zNear - zFar)
    projectionMatrix[2][3] = -1.0
    projectionMatrix[3][2] = (2 * zFar * zNear) / (zNear - zFar)

    #viewMatrix and projectionMatrix don't change ever so just set them once here
    with shader:
        glUniformMatrix4fv(projectionMatrixUnif, 1, GL_TRUE, projectionMatrix)
        glUniformMatrix4fv(viewMatrixUnif, 1, GL_TRUE, viewMatrix)

    #These are used to track the rotation of the volume
    LastFrameMousePos = (0, 0)
    CurrentMousePos = (0, 0)
    xRotation = 0
    yRotation = 0

    while True:
        clock.tick()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return
            if event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE:
                return
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                CurrentMousePos = event.pos
                LastFrameMousePos = CurrentMousePos
            if event.type == pygame.MOUSEMOTION and 1 in event.buttons:
                CurrentMousePos = event.pos
                diff = (CurrentMousePos[0] - LastFrameMousePos[0],
                        CurrentMousePos[1] - LastFrameMousePos[1])
                xRotation += event.rel[0]
                yRotation += event.rel[1]
                LastFrameMousePos = CurrentMousePos

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        #Perform the rotation of the mesh
        moveToOrigin = np.array(
            [[1.0, 0.0, 0.0, -32.0], [0.0, 1.0, 0.0, -32.0],
             [0.0, 0.0, 1.0, -32.0], [0.0, 0.0, 0.0, 1.0]],
            dtype='f')
        rotateAroundX = np.array(
            [[1.0, 0.0, 0.0, 0.0],
             [0.0, cos(radians(yRotation)), -sin(radians(yRotation)), 0.0],
             [0.0, sin(radians(yRotation)),
              cos(radians(yRotation)), 0.0], [0.0, 0.0, 0.0, 1.0]],
            dtype='f')
        rotateAroundY = np.array(
            [[cos(radians(xRotation)), 0.0,
              sin(radians(xRotation)), 0.0], [0.0, 1.0, 0.0, 0.0],
             [-sin(radians(xRotation)), 0.0,
              cos(radians(xRotation)), 0.0], [0.0, 0.0, 0.0, 1.0]],
            dtype='f')

        modelMatrix = rotateAroundY.dot(rotateAroundX.dot(moveToOrigin))

        with shader:
            glUniformMatrix4fv(modelMatrixUnif, 1, GL_TRUE, modelMatrix)
            glBindVertexArray(vertexArrayObject)

            glDrawElements(GL_TRIANGLES, len(indices), GL_UNSIGNED_INT, None)

            glBindVertexArray(0)

        # Show the screen
        pygame.display.flip()
Пример #19
0
def create_surface(rows, cols, size, fun, gen_textures, gen_relief=False):

    normals_vec = np.zeros((rows * cols, 3), dtype=np.float32)

    vertices_list = []
    texcoords_list = []
    faces_list = []
    indices_list = []

    if not gen_relief:
        for z in range(0, rows):
            for x in range(0, cols):
                xx = -size / 2 + x * size / cols
                zz = -size / 2 + z * size / rows

                try:
                    yy = fun(xx, zz)
                    if yy < -size / 2:
                        yy = -size / 2
                    if yy > size / 2:
                        yy = size / 2
                except (ArithmeticError, ValueError):
                    yy = 0.0

                vertices_list.append([xx, yy, zz])
                if gen_textures:
                    texcoords_list.append(
                        [x / float(cols - 1), z / float(rows - 1)])
    else:
        buff1 = []
        vertices_list_twodimensional = []
        for z in range(0, rows):
            buff1.clear()
            for x in range(0, cols):
                xx = -size / 2 + x * size / cols
                zz = -size / 2 + z * size / rows
                yy = 0.0

                buff1.append([xx, yy, zz])
            vertices_list_twodimensional.append(buff1.copy())

        for i in range(0, 150):
            radius = randint(1, 15)
            z = randint(0, rows - 1)
            x = randint(0, cols - 1)
            for iz in range(z - radius, z + radius):
                if iz < 0 or iz > rows - 1:
                    continue
                else:
                    for ix in range(x - radius, x + radius):
                        if ix < 0 or ix > cols - 1:
                            continue
                        else:
                            if 2 * radius**2 - (
                                (z - iz)**2 + (x - ix)**2
                            ) > vertices_list_twodimensional[iz][ix][1]**(2):
                                vertices_list_twodimensional[iz][ix][1] = (
                                    2 * radius**2 - ((z - iz)**2 +
                                                     (x - ix)**2))**(1 / 2)
                            else:
                                continue
        v = vertices_list_twodimensional.copy()
        vec_lines = []
        for ii in range(0, 10):
            i = 2 * ii
            for z in range(0, rows - 1):
                for x in range(0, cols - 1):
                    xx = -size / 2 + x * size / cols
                    zz = -size / 2 + z * size / rows

                    if v[z][x][1] < i and v[z][x + 1][1] < i and v[z + 1][x][1] < i and v[z + 1][x + 1][1] < i or \
                            v[z][x][1] >= i and v[z][x + 1][1] >= i and v[z + 1][x][1] >= i and v[z + 1][x + 1][1] >= i:
                        continue
                    elif v[z][x][1] >= i and v[z][x + 1][1] < i and v[
                            z + 1][x][1] < i and v[z + 1][x + 1][1] < i:
                        vec_lines.append([xx + 0.25, i, zz])
                        vec_lines.append([xx, i, zz + 0.25])
                    elif v[z][x][1] < i and v[z][x + 1][1] >= i and v[
                            z + 1][x][1] < i and v[z + 1][x + 1][1] < i:
                        vec_lines.append([xx + 0.25, i, zz])
                        vec_lines.append([xx + 0.5, i, zz + 0.25])
                    elif v[z][x][1] < i and v[z][x + 1][1] < i and v[
                            z + 1][x][1] >= i and v[z + 1][x + 1][1] < i:
                        vec_lines.append([xx + 0.25, i, zz + 0.5])
                        vec_lines.append([xx, i, zz + 0.25])
                    elif v[z][x][1] < i and v[z][x + 1][1] < i and v[
                            z + 1][x][1] < i and v[z + 1][x + 1][1] >= i:
                        vec_lines.append([xx + 0.25, i, zz + 0.5])
                        vec_lines.append([xx + 0.5, i, zz + 0.25])

                    elif v[z][x][1] < i and v[z][x + 1][1] >= i and v[
                            z + 1][x][1] >= i and v[z + 1][x + 1][1] >= i:
                        vec_lines.append([xx + 0.25, i, zz])
                        vec_lines.append([xx, i, zz + 0.25])
                    elif v[z][x][1] >= i and v[z][x + 1][1] < i and v[
                            z + 1][x][1] >= i and v[z + 1][x + 1][1] >= i:
                        vec_lines.append([xx + 0.25, i, zz])
                        vec_lines.append([xx + 0.5, i, zz + 0.25])
                    elif v[z][x][1] >= i and v[z][x + 1][1] >= i and v[
                            z + 1][x][1] < i and v[z + 1][x + 1][1] >= i:
                        vec_lines.append([xx + 0.25, i, zz + 0.5])
                        vec_lines.append([xx, i, zz + 0.25])
                    elif v[z][x][1] >= i and v[z][x + 1][1] >= i and v[
                            z + 1][x][1] >= i and v[z + 1][x + 1][1] < i:
                        vec_lines.append([xx + 0.25, i, zz + 0.5])
                        vec_lines.append([xx + 0.5, i, zz + 0.25])

                    elif v[z][x][1] < i and v[z][x + 1][1] < i and v[z + 1][x][1] >= i and v[z + 1][x + 1][1] >= i or \
                         v[z][x][1] >= i and v[z][x + 1][1] >= i and v[z + 1][x][1] < i and v[z + 1][x + 1][1] < i:
                        vec_lines.append([xx, i, zz + 0.25])
                        vec_lines.append([xx + 0.5, i, zz + 0.25])
                    elif v[z][x][1] >= i and v[z][x + 1][1] < i and v[z + 1][x][1] >= i and v[z + 1][x + 1][1] < i or \
                            v[z][x][1] < i and v[z][x + 1][1] >= i and v[z + 1][x][1] < i and v[z + 1][x + 1][1] >= i:
                        vec_lines.append([xx + 0.25, i, zz])
                        vec_lines.append([xx + 0.25, i, zz + 0.5])

                    elif v[z][x][1] >= i and v[z][x + 1][1] < i and v[z + 1][x][1] < i and v[z + 1][x + 1][1] >= i or \
                            v[z][x][1] < i and v[z][x + 1][1] >= i and v[z + 1][x][1] >= i and v[z + 1][x + 1][1] < i:
                        vec_lines.append([xx, i, zz + 0.25])
                        vec_lines.append([xx + 0.25, i, zz])
                        vec_lines.append([xx + 0.5, i, zz + 0.25])
                        vec_lines.append([xx + 0.25, i, zz + 0.5])

        index_lines = [it for it in range(0, len(vec_lines))]
        vector_lines = np.array(vec_lines, dtype=np.float32)
        vector_line_indexes = np.array(index_lines, dtype=np.uint32)

        for z in range(0, rows):
            for x in range(0, cols):
                vertices_list.append(vertices_list_twodimensional[z][x])

    primRestart = rows * cols
    vertices_vec = np.array(vertices_list, dtype=np.float32)
    if gen_textures:
        texcoords_vec = np.array(texcoords_list, dtype=np.float32)

    for x in range(0, cols - 1):
        for z in range(0, rows - 1):
            offset = x * cols + z
            if z == 0:
                indices_list.append(offset)
                indices_list.append(offset + rows)
                indices_list.append(offset + 1)
                indices_list.append(offset + rows + 1)
            else:
                indices_list.append(offset + 1)
                indices_list.append(offset + rows + 1)
                if z == rows - 2:
                    indices_list.append(primRestart)

    indices_vec = np.array(indices_list, dtype=np.uint32)

    currFace = 1
    for i in range(0, indices_vec.size - 2):
        index0 = indices_vec[i]
        index1 = indices_vec[i + 1]
        index2 = indices_vec[i + 2]

        face = np.array([0, 0, 0], dtype=np.int32)
        if (index0 != primRestart) and (index1 != primRestart) and (
                index2 != primRestart):
            if currFace % 2 != 0:
                face[0] = indices_vec[i]
                face[1] = indices_vec[i + 1]
                face[2] = indices_vec[i + 2]
                currFace += 1
            else:
                face[0] = indices_vec[i]
                face[1] = indices_vec[i + 2]
                face[2] = indices_vec[i + 1]
                currFace += 1

            faces_list.append(face)

    faces = np.reshape(faces_list, newshape=(len(faces_list), 3))

    for i in range(0, faces.shape[0]):
        A = np.array([
            vertices_vec[faces[i, 0], 0], vertices_vec[faces[i, 0], 1],
            vertices_vec[faces[i, 0], 2]
        ],
                     dtype=np.float32)
        B = np.array([
            vertices_vec[faces[i, 1], 0], vertices_vec[faces[i, 1], 1],
            vertices_vec[faces[i, 1], 2]
        ],
                     dtype=np.float32)
        C = np.array([
            vertices_vec[faces[i, 2], 0], vertices_vec[faces[i, 2], 1],
            vertices_vec[faces[i, 2], 2]
        ],
                     dtype=np.float32)

        edge1A = normalize(B - A)
        edge2A = normalize(C - A)

        face_normal = np.cross(edge1A, edge2A)

        normals_vec[faces[i, 0]] += face_normal
        normals_vec[faces[i, 1]] += face_normal
        normals_vec[faces[i, 2]] += face_normal

    for i in range(0, normals_vec.shape[0]):
        normals_vec[i] = normalize(normals_vec[i])

    vao = glGenVertexArrays(1)
    vbo_vertices = glGenBuffers(1)
    vbo_normals = glGenBuffers(1)
    if gen_textures:
        vbo_texcoords = glGenBuffers(1)
    vbo_indices = glGenBuffers(1)

    glBindVertexArray(vao)

    glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices)
    glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(vertices_vec),
                 vertices_vec.flatten(), GL_STATIC_DRAW)  #
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None)
    glEnableVertexAttribArray(0)

    glBindBuffer(GL_ARRAY_BUFFER, vbo_normals)
    glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(normals_vec),
                 normals_vec.flatten(), GL_STATIC_DRAW)  #
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, None)
    glEnableVertexAttribArray(1)

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_indices)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,
                 ArrayDatatype.arrayByteCount(indices_vec),
                 indices_vec.flatten(), GL_STATIC_DRAW)

    if gen_textures:
        glBindBuffer(GL_ARRAY_BUFFER, vbo_texcoords)
        glBufferData(GL_ARRAY_BUFFER,
                     ArrayDatatype.arrayByteCount(texcoords_vec),
                     texcoords_vec.flatten(), GL_STATIC_DRAW)  #
        glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, None)
        glEnableVertexAttribArray(2)

    glEnable(GL_PRIMITIVE_RESTART)
    glPrimitiveRestartIndex(primRestart)

    # der_z_y = lambda x,y,z: z * math.cos(y)
    # der_y_z = lambda x,y,z: y * math.cos(z)
    # der_x_z = lambda x,y,z: x * math.cos(z)
    # der_z_x = lambda x,y,z: z * math.cos(x)
    # der_y_x = lambda x,y,z: y * math.cos(x)
    # der_x_y = lambda x,y,z: x * math.cos(y)
    # rot = lambda x,y,z: math.sqrt( (der_z_y(x,y,z) - der_y_z(x,y,z))**2 + (der_x_z(x,y,z) - der_z_x(x,y,z))**2 + (der_y_x(x,y,z) - der_x_y(x,y,z))**2 )
    #
    # # max and min of rot lengths
    # max_rot = 0
    # min_rot = 0
    # rott_lst = []
    # for i in vertices_list:
    #
    #     rott = rot(i[0], i[1], i[2])
    #     rott_lst.append(rott)

    glBindVertexArray(0)
    if gen_relief:
        return (vao, indices_vec.size, vector_lines, vector_line_indexes)
    else:
        return (vao, indices_vec.size)
Пример #20
0
def main(visualize):
    
    if args.config:
        config_path = args.config
    else:
        config_path = "config.yaml"
    
    with open(config_path) as file:
        config = yaml.load(file, Loader=yaml.FullLoader)
    
    teams, boxes, agents = generate_spatial_entities(config)
    
    agents_x_sorted = initial_sort(agents)
    
    if config["sotilaskoti"]["allow"]:
        # create queue to the sotilaskoti
        q = []
    
    # table of meetings between agents, from the previous simulation step
    meets_prev = dict() 
    
    if visualize:
        
        # verticies for area borders and inferred width and height of the map.
        # I.e. canvas contains map width and height in meters for computations
        fences_verts, canvas = generate_map(boxes, config)
        # verticies for traingles that represent agents
        agents_verts = generate_agents_verticies(config)
        
        
        if not glfw.init():
            return
    
        window = glfw.create_window(config["window"][ "width"],
                                    config["window"]["height"],
                                    config["window"][ "title"], 
                                    None, None)
        if not window:
            glfw.terminate()
            return
        
        glfw.make_context_current(window)
        
        # compile shader for on-the-fly configurable trianges
        shader = compile_shader()
        
        # create Buffer object in gpu
        VBO = glGenBuffers(2)
    
        # bind buffers
        glBindBuffer(GL_ARRAY_BUFFER, VBO[0])
        glBufferData(GL_ARRAY_BUFFER, 
                     fences_verts.nbytes, 
                     fences_verts, 
                     GL_STATIC_DRAW)
        
        glBindBuffer(GL_ARRAY_BUFFER, VBO[1])
        glBufferData(GL_ARRAY_BUFFER,
                     agents_verts.nbytes,
                     agents_verts,
                     GL_STATIC_DRAW)
        
        fences_stride = fences_verts.strides[0]
        agents_stride = agents_verts.strides[0]
    
        # get the position from vertex shader
        # stride offset
        offset = ctypes.c_void_p(0)
        init_pos = glGetAttribLocation(shader, 'init_pos')
        glVertexAttribPointer(init_pos, 2, GL_FLOAT,
                              GL_FALSE, agents_stride, offset)
        glEnableVertexAttribArray(init_pos)
    
        glUseProgram(shader)
    
        glClearColor(1.0, 1.0, 1.0, 1.0)
    
    """
    Prepare directories to store:
    - source configuration files,
    - intermediate results in the form of meeting tables
    - output statistical reports
    """
    if not os.path.exists("output"):
        os.makedirs("output")
    
    paths = {
        "configs"     : os.path.join("output", "configs"),
        "meet_tables" : os.path.join("output", "meetings_tables"),
        "agents"      : os.path.join("output", "agents"),
        "out_stats"   : os.path.join("output", "stat_results"),
        }
    
    for path in paths.values():
        if not os.path.exists(path):
             os.makedirs(path)
    
    if args.config:
        # in this usage scenario all identifiers are set manually
        # (unique tags are generated in meta-loop that launches these scripts)
        tag = args.name
    else:
        # in this usage scenario timestamp is autimatically appended to 
        # distinguish between consequtive manual program launches
        timestamp = datetime.now().strftime("%H:%M:%S")
        tag = args.name +'_'+  timestamp
    
    # store the config file for the reference
    dump_config_path = os.path.join(
        paths["configs"], "config_"+ tag +".yaml")
    
    shutil.copy(config_path, dump_config_path)
    
    # store agents for the further move speed / infection spread correlating
    agents_souls_path = os.path.join(
        paths["agents"], "spatial_agents_"+ tag +".bin")
    
    with open(agents_souls_path, 'wb') as file:
        pickle.dump(agents, file)
    
    # create the file with agent meetings
    # originally a .bin file, is later compressed to the .bin.tar.bz2 format
    meets_table_path = os.path.join(
        paths["meet_tables"], "meet_table_"+ tag +".bin")
    
    with open(meets_table_path, 'wb') as file:
        
        # run until the end of the set simulation period
        
        T  = config["simulationDuration"] * 24*60*60
        dt = config[ "minSimulationStep"]
        
        eval_times = np.arange(0, T, dt)
        
        for eval_time in tqdm(eval_times):
            
            """
            Transition agents between service and leave
            """
            entities = (teams, boxes, agents)
            
            # some agents prefer to stay on the base during holidays
            stay_chance = config.get('dontGoOffDuty', 0.0)
            
            rotate_teams(entities, stay_chance, eval_time, dt)
            
            """
            Transition agents to "Sotilaskoti" cafeteria and back
            """
            if config["sotilaskoti"]["allow"]:
                
                queue_sotilaskoti(entities, q, eval_time, dt, config)
            
            """
            Update agent positions (along one time step)
            """
            increment_agent_positions(agents)
            
            """
            Refresh the sorting of agents after the positions update
            """
            x_sort(agents_x_sorted)
            
            """
            Register new meetings between agents and export them to file
            """
            meets_curr = detect_meetings(agents_x_sorted, eval_time,
                                         config, visualize)
            
            # each key is a meeting link between two agents 
            # in the form {agent1_idx, agent2_idx}
            links_curr = set( meets_curr.keys() )
            links_prev = set( meets_prev.keys() )
            
            meets_new = dict()
            
            for link in links_curr:
                
                if link not in links_prev:
                    
                    meets_new[link] = meets_curr[link]
            
            if meets_new:
                
                timeline = {"timestamp" : eval_time,
                             "meetings" : meets_new}
                
                pickle.dump(timeline, file)
            
            meets_prev = meets_curr
            
            """
            Plot canvas if not specified otherwise (--no-visual option)
            """
            if visualize:
                
                if glfw.window_should_close(window):
                    break
                
                time_zero = time.time()
                
                glClear(GL_COLOR_BUFFER_BIT)
                
                """
                Indicate current day in window title
                """
                day_n = eval_time // (24*60*60) + 1
                
                dayly_title = config["window"]["title"] +", day: "+ str(day_n)
                
                glfw.set_window_title(window, dayly_title)

                """
                Draw borders (i.e. boxes, i.e. fences) - 1 px black outlines
                """
                glBindBuffer(GL_ARRAY_BUFFER, VBO[0])
                glVertexAttribPointer(init_pos, 2, GL_FLOAT,
                                      GL_FALSE, fences_stride, offset)
                glEnableVertexAttribArray(init_pos)
                
                transformLoc = glGetUniformLocation(shader, "dyn_pos")
                glUniform2f(transformLoc, 0.0, 0.0)
                
                transformLoc = glGetUniformLocation(shader, "dyn_color")
                glUniform4f(transformLoc, 0.0, 0.0, 0.0, 0.0)
        
                glDrawArrays(GL_TRIANGLES, 0, len(fences_verts))
                
                """
                Draw agents (i.e. conscripts and civilians)
                """
                glBindBuffer(GL_ARRAY_BUFFER, VBO[1])
                glVertexAttribPointer(init_pos, 2, GL_FLOAT,
                                      GL_FALSE, agents_stride, offset)
                glEnableVertexAttribArray(init_pos)
                
                for i, agent in enumerate(agents):
                    
                    poly_prop = np.zeros(1, [( "pos" , np.float32, 2),
                                             ("color", np.float32, 4)])
                    
                    # absolute to relative coordinates, meters -> fractions
                    x = (agent.x/canvas[ "width"]*2 - 1)*0.99
                    y = (agent.y/canvas["height"]*2 - 1)*0.99
                    
                    poly_prop["pos"] = (x, y)
                    
                    transformLoc = glGetUniformLocation(shader, "dyn_pos")
                    glUniform2f(transformLoc, *poly_prop["pos"].T)
                    
                    """
                    Agent triangle marker filling
                    """
                    poly_prop["color"] = agent.color
                    
                    transformLoc = glGetUniformLocation(shader, "dyn_color")
                    glUniform4f(transformLoc, *poly_prop["color"].T)
    
                    if agent.conscripted:
                        glDrawArrays(GL_TRIANGLES, 3, 6)
                    else:
                        glDrawArrays(GL_TRIANGLES, 0, 3)
                    
                    """
                    Marker outline
                    """
                    transformLoc = glGetUniformLocation(shader, "dyn_color")
                    glUniform4f(transformLoc, 0.0, 0.0, 0.0, 1.0) # black
                    
                    if agent.conscripted:
                        glDrawArrays(GL_LINE_LOOP, 3, 6)
                    else:
                        glDrawArrays(GL_LINE_LOOP, 0, 3)
                
                glfw.swap_buffers(window)
                
                # FPS limited to 60
                while(time.time() - time_zero < 1/60):
                    time.sleep(0.001)
                glfw.poll_events()
    
    if visualize:
        glfw.terminate()
    
    """
    Compress output file to save space 
    """
    compressed_path = os.path.join(
        paths["meet_tables"], "meet_table_"+ tag +".bin.tar.bz2")
    
    with tarfile.open(compressed_path, "w:bz2") as tar:
        tar.add(meets_table_path)
    
    # in case compressing went successful, remove the source file
    if os.path.exists(compressed_path):
        os.remove(meets_table_path)