def __init__(self, *args, **kwargs): self.boundary = '--boundarydonotcross' self.html = open('index.html', 'r').read() # Handle Arguments self.input_path = _args.i[0] self.rotation = _args.r[0] self.output_width = int(_args.c[0].split('x')[0]) self.output_height = int(_args.c[0].split('x')[1]) self.frame_rate = _args.f[0] self.frame_skip_rate = _args.k[0] self.recognize_scale = 0.2 self.predictor = dlib.shape_predictor('../shapes/shape_predictor_68_face_landmarks.dat') self.face_cascade = toolbox.loadCascade('haarcascade_frontalface_default.xml') # Define skipping vars self.skip_frames = None self.skip_frame_x = None self.skip_frame_y = None self.skip_rect = None self.skip_points = None # OpenGL self.quad = Quad() self.quad_program = ShaderProgram(fragment=self.quad.fragment, vertex=self.quad.vertex) self.quad.loadVBOs(self.quad_program) self.quad.loadElements() super(CustomHandler, self).__init__(*args, **kwargs)
def testUseUsesTheShaderProgram(self, mockGl): program = ShaderProgram() program.getLinkStatus = lambda: True program.use() self.assertEquals(mockGl.glUseProgram.call_args, ((program.id,), {}))
def __init__(self): self._shader_program = ShaderProgram(self._get_floor_vs_fn(), self._get_floor_fs_fn()) for _, attrib in EnvironmentRender.VertexAttributes.__members__.items(): self._shader_program.bind_attribute(attrib.value["location"], attrib.value["name"]) self._shader_program.compile() vertices, normals, texcoords = mesh.create_grid_mesh(1000, 1000, 100) self._vertices = np.asarray(vertices, dtype=np.float32) self._normals = np.asarray(normals, dtype=np.float32) self._texcoords = np.asarray(texcoords, dtype=np.float32) print(self._texcoords) self._vao = GL.glGenVertexArrays(1) GL.glBindVertexArray(self._vao) # Generate buffer object for the mesh vertices self._vertex_bo = GL.glGenBuffers(1) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self._vertex_bo) GL.glBufferData(GL.GL_ARRAY_BUFFER, self._vertices.nbytes, self._vertices, GL.GL_STATIC_DRAW) # Setup Vertex Attrib Pointer pos_attrib_pointer = EnvironmentRender.VertexAttributes.Position.value["location"] GL.glEnableVertexAttribArray(pos_attrib_pointer) GL.glVertexAttribPointer(pos_attrib_pointer, 3, GL.GL_FLOAT, False, 0, ctypes.c_void_p(0)) self._normal_bo = GL.glGenBuffers(1) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self._normal_bo) GL.glBufferData(GL.GL_ARRAY_BUFFER, self._normals.nbytes, self._normals, GL.GL_STATIC_DRAW) normal_attrib_pointer = EnvironmentRender.VertexAttributes.Normal.value["location"] GL.glEnableVertexAttribArray(normal_attrib_pointer) GL.glVertexAttribPointer(normal_attrib_pointer, 3, GL.GL_FLOAT, False, 0, ctypes.c_void_p(0)) self._texcoord_bo = GL.glGenBuffers(1) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self._texcoord_bo) GL.glBufferData(GL.GL_ARRAY_BUFFER, self._texcoords.nbytes, self._texcoords, GL.GL_STATIC_DRAW) texcoord_attrib_pointer = EnvironmentRender.VertexAttributes.TexCoord.value["location"] GL.glEnableVertexAttribArray(texcoord_attrib_pointer) GL.glVertexAttribPointer(texcoord_attrib_pointer, 2, GL.GL_FLOAT, False, 0, ctypes.c_void_p(0)) # Unbind each used GL object GL.glBindVertexArray(0) GL.glDisableVertexAttribArray(pos_attrib_pointer) GL.glDisableVertexAttribArray(normal_attrib_pointer) GL.glDisableVertexAttribArray(texcoord_attrib_pointer) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0) floor_image = PIL.Image.open('textures/floor.png') floor_texture_data = np.array(list(floor_image.getdata()), np.uint8) self.floor_texture = GL.glGenTextures(1) GL.glBindTexture(GL.GL_TEXTURE_2D, self.floor_texture) GL.glTexParameterf(GL.GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 8.0); GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR) GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR) GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, floor_image.size[0], floor_image.size[1], 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, floor_texture_data) GL.glGenerateMipmap(GL.GL_TEXTURE_2D)
def reloadShaders(self): from shader import FragmentShader, ShaderError, ShaderProgram, VertexShader def read_source(fname): f = open(fname) try: src = f.read() finally: f.close() return src fsrc = read_source('shaders/ocean.fragment') fshader = FragmentShader([fsrc]) vsrc = read_source('shaders/ocean.vertex') vshader = VertexShader([vsrc]) self.surfaceShader = ShaderProgram(fshader, vshader) self.surfaceShader.use() fsrc = read_source('shaders/oceanfloor.fragment') fshader = FragmentShader([fsrc]) vsrc = read_source('shaders/oceanfloor.vertex') vshader = VertexShader([vsrc]) self.groundShader = ShaderProgram(fshader, vshader) self.groundShader.use() self.surface.setShader(self.surfaceShader) self.ground.setShader(self.groundShader)
def testGetInfoLogForZeroLogSize(self): program = ShaderProgram() program.getInfoLogLength = lambda: 0 log = program.getInfoLog() self.assertEquals(log, '')
def testGetInfoLogLength(self): program = ShaderProgram() program._get = Mock(return_value=123) actual = program.getInfoLogLength() self.assertEquals(program._get.call_args, ((gl.GL_INFO_LOG_LENGTH,), {})) self.assertEquals(actual, 123)
def testGetInfoLog(self, mockGl): expected = 'logmessage' mockGl.glGetProgramInfoLog.side_effect = mockGetInfoLog(expected) program = ShaderProgram() program.getInfoLogLength = lambda: len(expected) log = program.getInfoLog() self.assertEquals(log, expected)
def install_shaders(fragment, vertex): fsrc = read_source(fragment) fshader = FragmentShader([fsrc]) vsrc = read_source(vertex) vshader = VertexShader([vsrc]) shader = ShaderProgram(fshader, vshader) shader.use()
def testUseCreatesProgram(self, mockGl): mockGl.glCreateProgram.return_value = 123 program = ShaderProgram() program.getLinkStatus = lambda: True program.use() self.assertTrue(mockGl.glCreateProgram.called) self.assertEquals(program.id, 123)
def testUseRaisesOnLinkFailure(self): program = ShaderProgram() program.getLinkStatus = lambda: False program.getInfoLog = lambda: 'linkerror' try: program.use() self.fail('should raise') except LinkError, e: self.assertTrue('linkerror' in str(e))
def testGet(self, mockGl): mockGl.glGetProgramiv.side_effect = mockGet(123) program = ShaderProgram() program.id = object() actual = program._get(456) self.assertEquals(mockGl.glGetProgramiv.call_args[0][:2], (program.id, 456)) self.assertEquals(actual, 123)
def init_gl(self): self.gs = glCreateShader(GL_GEOMETRY_SHADER) glShaderSource(self.gs, self.geometry_shader) glCompileShader(self.gs) log = glGetShaderInfoLog(self.gs) if log: print "Geometry Shader:", log self.shader_program = glCreateProgram() # glAttachShader(self.shader_program, self.gs) ShaderProgram.init_gl(self)
def _create_shaders(self): """Creates the shader program""" self._shader_program = ShaderProgram(self._get_vertex_shader_fn(), self._get_fragent_shader_fn()) # Setup Vertex Attributes for _, attrib in MotionRender.VertexAttributes.__members__.items(): self._shader_program.bind_attribute(attrib.value["location"], attrib.value["name"]) self._shader_program.compile()
def testUseReturnsConcatenatedMessages(self): shader1 = Mock() shader2 = Mock() shader1.getInfoLog = lambda: 's1' shader2.getInfoLog = lambda: 's2' program = ShaderProgram(shader1, shader2) program.getInfoLog = lambda: 'p0' program.getLinkStatus = lambda: True message = program.use() self.assertEquals(message, 's1\ns2\np0')
def initp(): global robot_program # Load shaders robot_program = ShaderProgram("resources/shaders/shader_robot.vs", "resources/shaders/shader_robot.fg") robot_program.init() global human_model # Load dae file human_model = ColladaModel("resources/human.dae") # Enable depth test glEnable(GL_DEPTH_TEST)
def __enter__(self): if not self.is_initialized: self.init_gl() ShaderProgram.__enter__(self) # print self.zNear, type(self.zNear), self.shader_program, glGetUniformLocation(self.shader_program, "zNear") glUniform1f(glGetUniformLocation(self.shader_program, "zNear"), self.zNear) glUniform1f(glGetUniformLocation(self.shader_program, "zFar"), self.zFar) glUniform1f(glGetUniformLocation(self.shader_program, "eye_shift"), self.eye_shift) bg = self.background_color glUniform4f(glGetUniformLocation(self.shader_program, "background_color"), bg[0], bg[1], bg[2], bg[3]) glUniform1f(glGetUniformLocation(self.shader_program, "atom_scale"), self.atom_scale) return self
def testGetLinkStatus(self): data = [ (gl.GL_TRUE, True), (gl.GL_FALSE, False), ] for getReturn, expected in data: program = ShaderProgram() program._get = Mock(return_value=getReturn) actual = program.getLinkStatus() self.assertEquals(program._get.call_args, ((gl.GL_LINK_STATUS,), {})) self.assertEquals(actual, expected) self.assertEquals(type(actual), type(expected))
def __init__( self, camera, scale=1.0, tileSize=128, tilesX=1, tilesZ=1, depth=30.0): self.depth = depth self.tileSize = tileSize self.tilesX = tilesX self.tilesZ = tilesZ self.camera = camera self.scale = scale self.surfaceShader = ShaderProgram.open('shaders/colour_by_height.shader') # Use the shallow pool ripple surface generator self.heightfield = Ripples(self.camera, self.tileSize) # The water surface self.surface = Surface( self.surfaceShader, self.camera, texture=None, heightfield=self.heightfield, tileSize=self.tileSize, tilesX=self.tilesX, tilesZ=self.tilesZ, scale=self.scale, offset=Vector3(0.0,self.depth,0.0))
def initGL(output_width, output_height): glutInit(sys.argv) glutInitDisplayMode(GLUT_3_2_CORE_PROFILE | GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH) glutInitWindowSize(output_width, output_height) glutCreateWindow("Virtual Window") print('') print('Vendor: ' + glGetString(GL_VENDOR).decode('utf-8')) print('Renderer: ' + glGetString(GL_RENDERER).decode('utf-8')) print('OpenGL Version: ' + glGetString(GL_VERSION).decode('utf-8')) print('Shader Version: ' + glGetString(GL_SHADING_LANGUAGE_VERSION).decode('utf-8')) if not glUseProgram: print('Missing Shader Objects!') sys.exit(1) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) global QUAD QUAD = Quad() global QUAD_PROGRAM QUAD_PROGRAM = ShaderProgram(fragment=QUAD.fragment, vertex=QUAD.vertex) QUAD.loadVBOs(QUAD_PROGRAM) QUAD.loadElements()
def __init__(self, width, height): self._createGlSurface() self.texture = 0 self.resize(width, height) self._createGlTexture() self.width = width self.height = height self.program = ShaderProgram('shaders/guiShader.vert', 'shaders/guiShader.frag') self.font = ImageFont.truetype('assets/minecraft_font.ttf', 16)
def __init__(self): ShaderProgram.__init__(self) this_dir = os.path.split(__file__)[0] self.vertex_shader = open(os.path.join(this_dir, "shaders/sphere_vtx.glsl")).read() self.fragment_shader = open(os.path.join(this_dir, "shaders/sphere_frg.glsl")).read() # experimental geometry shader self.geometry_shader = """ #version 120 #extension GL_EXT_geometry_shader4 : enable void main() { for(int i = 0; i < gl_VerticesIn; ++i) { gl_FrontColor = gl_FrontColorIn[i]; gl_Position = gl_PositionIn[i]; EmitVertex(); } } """ self.atom_scale = 1.0
def getGLFrame(frame, points, output_width, output_height): ############## OpengGL ############## p1, p2, p3 = points[39], points[42], points[33] w, h = output_width, output_height p1 = [(p1[1] / w) * 2 - 1, -((p1[0] / h) * 2 - 1)] p2 = [(p2[1] / w) * 2 - 1, -((p2[0] / h) * 2 - 1)] p3 = [(p3[1] / w) * 2 - 1, -((p3[0] / h) * 2 - 1)] triangle = Triangle(p1, p2, p3) tri_program = ShaderProgram(fragment=triangle.fragment, vertex=triangle.vertex) triangle.loadVBOs(tri_program) triangle.loadElements() glClear(GL_COLOR_BUFFER_BIT) glClearColor (0.0, 0.0, 0.0, 1.0) #-----------------------------------# QUAD_PROGRAM.start() toolbox.bind(QUAD) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_BGR, GL_UNSIGNED_BYTE, frame) glDrawElements(GL_TRIANGLES, len(QUAD.elements) * 3, GL_UNSIGNED_INT, None) toolbox.unbind() QUAD_PROGRAM.stop() #-----------------------------------# tri_program.start() toolbox.bind(triangle) glDrawElements(GL_TRIANGLES, len(triangle.elements) * 3, GL_UNSIGNED_INT, None) toolbox.unbind() tri_program.stop() #-----------------------------------# glFinish() glPixelStorei(GL_PACK_ALIGNMENT, 1) buffer = glReadPixels(0, 0, output_width, output_height, GL_BGR, GL_UNSIGNED_BYTE) image = Image.frombytes('RGB', (output_width, output_height), buffer) image = image.transpose(Image.FLIP_TOP_BOTTOM) frame = np.asarray(image, dtype=np.uint8) glutSwapBuffers() ##################################### return frame
def loadGlTextures(app): app.cubeVao, app.cubeBuffer = loadCubeVao() CLIENT_DATA.skyboxVao = loadSkyVao() CLIENT_DATA.glTextures = {} for (name, sides) in app.texturePaths.items(): CLIENT_DATA.glTextures[name] = imageToTexture(loadBlockUVFromSides(app, **sides)) CLIENT_DATA.breakTextures = [] for i in range(10): CLIENT_DATA.breakTextures.append(loadTexture(f'assets/destroy_stage_{i}.png')) CLIENT_DATA.blockProgram = ShaderProgram('shaders/blockShader.vert', 'shaders/blockShader.frag') CLIENT_DATA.chunkProgram = ShaderProgram('shaders/chunkShader.vert', 'shaders/chunkShader.frag') CLIENT_DATA.guiProgram = ShaderProgram('shaders/guiShader.vert', 'shaders/guiShader.frag') CLIENT_DATA.entityProgram = ShaderProgram('shaders/entityShader.vert', 'shaders/entityShader.frag') CLIENT_DATA.skyProgram = ShaderProgram('shaders/skyShader.vert', 'shaders/skyShader.frag') CLIENT_DATA.transProgram = ShaderProgram('shaders/transShader.vert', 'shaders/transShader.frag') vertices = np.array([ 1.0, 1.0, 1.0, 0.0, # top right 1.0, -1.0, 1.0, 1.0, # bottom right -1.0, -1.0, 0.0, 1.0, # bottom left -1.0, 1.0, 0.0, 0.0, # top left ], dtype='float32') indices = np.array([ 0, 1, 3, 1, 2, 3, ], dtype='uint32') vao: int = glGenVertexArrays(1) #type:ignore vbo: int = glGenBuffers(1) #type:ignore ebo: int = glGenBuffers(1) #type:ignore glBindVertexArray(vao) glBindBuffer(GL_ARRAY_BUFFER, vbo) glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL_STATIC_DRAW) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo) glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.nbytes, indices, GL_STATIC_DRAW) glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * 4, ctypes.c_void_p(0)) glEnableVertexAttribArray(0) glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * 4, ctypes.c_void_p(2 * 4)) glEnableVertexAttribArray(1) glBindBuffer(GL_ARRAY_BUFFER, 0) glBindVertexArray(0) CLIENT_DATA.fullscreenVao = vao
def init(): grid_vertices, grid_mesh = generate_grid_mesh(-10, 10, step=0.5) global shader_program shader_program = ShaderProgram("resources/shaders/shader.vs", "resources/shaders/shader.fg") shader_program.init() global robot_program robot_program = ShaderProgram("resources/shaders/shader_robot.vs", "resources/shaders/shader_robot.fg") robot_program.init() global grid_model grid_model = Model([grid_vertices], indices=[grid_mesh]) global human_model human_model = ColladaModel("resources/human.dae") glEnable(GL_DEPTH_TEST)
def initializeGL(self): glClearColor(0.4, 0.4, 0.4, 1.0) # if a starting image, load it # if self.startImg is not None: # print(self.img.width()) self.layers = [ Layer(self.canvasWidth,self.canvasHeight) ] self.strokeLayer = Layer(self.canvasWidth,self.canvasHeight) # if there's a starting image, draw it into the starting layer if self.imgPath is not None: bottomLayer = self.layers[-1] bottomLayer.bind() # setup the orthographic projection and viewport glMatrixMode(GL_PROJECTION) glPushMatrix() glLoadIdentity() glOrtho(0, self.canvasWidth, 0, self.canvasHeight, -1, 1) glViewport(0, 0, self.canvasWidth, self.canvasHeight) imgTextureId = self.bindTexture(self.startImg, GL_TEXTURE_RECTANGLE_ARB) self.drawTexture(QPointF(0,0), imgTextureId, GL_TEXTURE_RECTANGLE_ARB) self.deleteTexture(imgTextureId) # restore the previous projection matrix and viewport glMatrixMode(GL_PROJECTION) glPopMatrix() glViewport(0, 0, self.width(), self.height()) # should be saved off? bottomLayer.release() self.startImg = None # setup the necessary shaders self.program = ShaderProgram() self.program.attachShader(ShaderCode(GL_VERTEX_SHADER,'./shaders/basic.vert')) self.program.attachShader(ShaderCode(GL_FRAGMENT_SHADER,'./shaders/basic.frag'))
def testUseCompilesAndAttachesShaders(self, mockGl): shader1 = Mock() shader2 = Mock() program = ShaderProgram(shader1, shader2) program.id = 123 program._getMessage = DoNothing program.getLinkStatus = lambda: True program.use() self.assertEquals(shader1.compile.call_args, (tuple(), {})) self.assertEquals(shader2.compile.call_args, (tuple(), {})) self.assertEquals(mockGl.glAttachShader.call_args_list, [ ((program.id, shader1.id), {}), ((program.id, shader2.id), {}), ])
class Ocean(): def __init__( self, camera, cubemap=None, scale=1.0, tileSize=128, tilesX=1, tilesZ=1, depth=30.0, waveHeight=3.125e-5, wind=Vector2(64.0,128.0), period=10.0, photonScale=4.0, photonIntensity=2.0): if cubemap: self.cubemapTexture = cubemap.texture else: self.cubemapTexture = None self.wind = wind # Ocean wind in X,Z axis self.waveHeight = waveHeight # The phillips spectrum parameter self.oceanDepth = depth self.period = period # Period of ocean surface anim self.drawSeaSurface = True self.drawSeaFloor = True self.enableCaustics = True self.photonIntensity = photonIntensity self.photonScale = photonScale self.tileSize = tileSize self.tilesX = tilesX self.tilesZ = tilesZ self.length = tileSize # Ocean length parameter self.camera = camera self.scale = scale self.surfaceShader = shader.openfiles( 'shaders/ocean.vertex', 'shaders/ocean.fragment') self.groundShader = shader.openfiles( 'shaders/oceanfloor.vertex', 'shaders/oceanfloor.fragment') self.oceanFloorTexture = image.load('images/tiles.png').get_texture() # Caustic texture self.causticTexture = image.DepthTexture.create_for_size(GL_TEXTURE_2D, self.tileSize, self.tileSize, GL_RGBA) # Use Tessendorf FFT synthesis to create a convincing ocean surface. self.heightfield = Tessendorf( self.tileSize, self.waveHeight, self.wind, self.length, self.period) # The water surface self.surface = Surface( self.surfaceShader, self.camera, texture=self.oceanFloorTexture, causticTexture=self.causticTexture, cubemapTexture=self.cubemapTexture, heightfield=self.heightfield, tileSize=self.tileSize, tilesX=self.tilesX, tilesZ=self.tilesZ, scale=self.scale, offset=Vector3(0.0,self.oceanDepth,0.0)) # The caustics engine, uses the water surface to generate a caustic tex self.caustics = Caustics ( self.camera, self.surface, self.oceanDepth, self.causticTexture, self.photonScale, self.photonIntensity, ) # The sea bed, an undisturbed mesh self.ground = Surface( self.groundShader, self.camera, texture=self.oceanFloorTexture, causticTexture=self.causticTexture, heightfield=None, tileSize=1, tilesX=self.tilesX, tilesZ=self.tilesZ, scale=self.scale * self.tileSize, offset=Vector3(0.0,0.0,0.0)) def reloadShaders(self): from shader import FragmentShader, ShaderError, ShaderProgram, VertexShader def read_source(fname): f = open(fname) try: src = f.read() finally: f.close() return src fsrc = read_source('shaders/ocean.fragment') fshader = FragmentShader([fsrc]) vsrc = read_source('shaders/ocean.vertex') vshader = VertexShader([vsrc]) self.surfaceShader = ShaderProgram(fshader, vshader) self.surfaceShader.use() fsrc = read_source('shaders/oceanfloor.fragment') fshader = FragmentShader([fsrc]) vsrc = read_source('shaders/oceanfloor.vertex') vshader = VertexShader([vsrc]) self.groundShader = ShaderProgram(fshader, vshader) self.groundShader.use() self.surface.setShader(self.surfaceShader) self.ground.setShader(self.groundShader) def setCausticPhotonIntensity(self, intensity): self.photonIntensity = intensity self.caustics.photonIntensity = self.photonIntensity def setCausticPhotonScale(self, scale): self.photonScale = scale self.caustics.photonScale = self.photonScale def setDepth(self, depth): self.oceanDepth = depth self.caustics.setDepth(self.oceanDepth) self.surface.setDepth(self.oceanDepth) def resetHeightfield(self): ''' Recreate the heightfield engine with new initial parameters, this is required for heightfield engines such as Tessendorf as lookup tables are generated upon creation based on input paramters ''' del self.heightfield self.heightfield = Tessendorf( self.tileSize, self.waveHeight, self.wind, self.length, self.period) self.surface.setHeightfield( self.heightfield) def setWind(self, wind): self.wind = wind self.resetHeightfield() def setWaveHeight(self, waveHeight): self.waveHeight = waveHeight self.resetHeightfield() def draw(self,dt): if self.drawSeaSurface: self.surface.draw(dt) if self.drawSeaFloor: if self.enableCaustics: self.caustics.update(dt) self.ground.draw(dt)
class EnvironmentRender: class VertexAttributes(Enum): """ Name of each used vertex attribute""" Position = {"name": "in_Position", "location": 0} Normal = {"name": "in_Normal", "location": 1} TexCoord = {"name": "in_TexCoord", "location": 2} def __init__(self): self._shader_program = ShaderProgram(self._get_floor_vs_fn(), self._get_floor_fs_fn()) for _, attrib in EnvironmentRender.VertexAttributes.__members__.items(): self._shader_program.bind_attribute(attrib.value["location"], attrib.value["name"]) self._shader_program.compile() vertices, normals, texcoords = mesh.create_grid_mesh(1000, 1000, 100) self._vertices = np.asarray(vertices, dtype=np.float32) self._normals = np.asarray(normals, dtype=np.float32) self._texcoords = np.asarray(texcoords, dtype=np.float32) print(self._texcoords) self._vao = GL.glGenVertexArrays(1) GL.glBindVertexArray(self._vao) # Generate buffer object for the mesh vertices self._vertex_bo = GL.glGenBuffers(1) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self._vertex_bo) GL.glBufferData(GL.GL_ARRAY_BUFFER, self._vertices.nbytes, self._vertices, GL.GL_STATIC_DRAW) # Setup Vertex Attrib Pointer pos_attrib_pointer = EnvironmentRender.VertexAttributes.Position.value["location"] GL.glEnableVertexAttribArray(pos_attrib_pointer) GL.glVertexAttribPointer(pos_attrib_pointer, 3, GL.GL_FLOAT, False, 0, ctypes.c_void_p(0)) self._normal_bo = GL.glGenBuffers(1) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self._normal_bo) GL.glBufferData(GL.GL_ARRAY_BUFFER, self._normals.nbytes, self._normals, GL.GL_STATIC_DRAW) normal_attrib_pointer = EnvironmentRender.VertexAttributes.Normal.value["location"] GL.glEnableVertexAttribArray(normal_attrib_pointer) GL.glVertexAttribPointer(normal_attrib_pointer, 3, GL.GL_FLOAT, False, 0, ctypes.c_void_p(0)) self._texcoord_bo = GL.glGenBuffers(1) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self._texcoord_bo) GL.glBufferData(GL.GL_ARRAY_BUFFER, self._texcoords.nbytes, self._texcoords, GL.GL_STATIC_DRAW) texcoord_attrib_pointer = EnvironmentRender.VertexAttributes.TexCoord.value["location"] GL.glEnableVertexAttribArray(texcoord_attrib_pointer) GL.glVertexAttribPointer(texcoord_attrib_pointer, 2, GL.GL_FLOAT, False, 0, ctypes.c_void_p(0)) # Unbind each used GL object GL.glBindVertexArray(0) GL.glDisableVertexAttribArray(pos_attrib_pointer) GL.glDisableVertexAttribArray(normal_attrib_pointer) GL.glDisableVertexAttribArray(texcoord_attrib_pointer) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0) floor_image = PIL.Image.open('textures/floor.png') floor_texture_data = np.array(list(floor_image.getdata()), np.uint8) self.floor_texture = GL.glGenTextures(1) GL.glBindTexture(GL.GL_TEXTURE_2D, self.floor_texture) GL.glTexParameterf(GL.GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 8.0); GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR) GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR) GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, floor_image.size[0], floor_image.size[1], 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, floor_texture_data) GL.glGenerateMipmap(GL.GL_TEXTURE_2D) def set_render_matrices(self, view, projection): self._view_matrix = view self._proj_matrix = projection def draw(self): self._shader_program.bind() GL.glEnable(GL.GL_DEPTH_TEST) model_loc = self._shader_program.uniform_location('modelMatrix') view_loc = self._shader_program.uniform_location('viewMatrix') proj_loc = self._shader_program.uniform_location('projectionMatrix') sampler_loc = self._shader_program.uniform_location('color_map') FLOOR_SIZE = 1 scale = glm.scale(glm.mat4(), glm.vec3(FLOOR_SIZE, 1, FLOOR_SIZE)) * glm.translate(glm.mat4(), glm.vec3(0.0, -20.0, 0.0)) GL.glUniformMatrix4fv(model_loc, 1, GL.GL_FALSE, np.ascontiguousarray(scale)) GL.glUniformMatrix4fv(view_loc, 1, GL.GL_FALSE, np.ascontiguousarray(self._view_matrix)) GL.glUniformMatrix4fv(proj_loc, 1, GL.GL_FALSE, np.ascontiguousarray(self._proj_matrix)) GL.glActiveTexture(GL.GL_TEXTURE0) GL.glBindTexture(GL.GL_TEXTURE_2D, self.floor_texture) GL.glUniform1i(sampler_loc, 0) GL.glBindVertexArray(self._vao) GL.glDrawArrays(GL.GL_TRIANGLES, 0, int(self._vertices.size / 3)) def _get_floor_vs_fn(self): return './shaders/floor.vs' def _get_floor_fs_fn(self): return './shaders/floor.fs'
class MotionRender: class VertexAttributes(Enum): """ Name of each used vertex attribute""" Position = {"name": "in_Position", "location": 0} Normal = {"name": "in_Normal", "location": 1} def __init__(self, skeleton=None): self._cylinder_mem_info = None self._sphere_mem_info = None self._skeleton = None self._skeleton_trans = None self._motion_cache = {} self._character_color = glm.vec4(124.0 / 255.0, 174.0 / 255.0, 255.0 / 255.0, 1.0) self._joints_color = glm.vec4(200.0 / 255.0, 200.0 / 255.0, 200.0 / 255.0, 1.0) self._uniforms = {} self._setup_render_matrices() self._setup_ligthing() self._create_shaders() self._create_mesh_data() self._create_gl_objects() self.add_motion(skeleton) def set_render_matrices(self, view, project): self._view_matrix = view self._proj_matrix = project def _on_draw_part(self, ntype, name, transform, length, rest_rot): render_data = RENDER_DATA.get(ntype) if render_data is None or not render_data.enabled: return GL.glBindVertexArray(self._vao) # Draw body Parts scale = glm.scale(glm.mat4(), glm.vec3(0.5, max(length, 0.5), 0.5)) model = transform * rest_rot * scale GL.glUniformMatrix4fv(self._uniforms['model_mat_loc'], 1, GL.GL_FALSE, np.ascontiguousarray(model)) GL.glUniform4fv(self._uniforms['character_color_loc'], 1, np.ascontiguousarray(self._character_color)) GL.glDrawArrays(GL.GL_TRIANGLES, self._cylinder_mem_info[0], self._cylinder_mem_info[1]) # Draw joints # Ignoring the following parts # NodeType.UPPER_ARM: RightShoulder # NodeType.UPPER_ARM: LeftShoulder # NodeType.TORSO : RHipJoint # NodeType.TORSO : LHipJoint # NodeType.FINGER : LThumb # NodeType.FINGER : LeftFingerBase # NodeType.FINGER : LeftHandIndex1 IGNORED_PARTS = [NT.TORSO, NT.UPPER_ARM, NT.FINGER] if ntype not in IGNORED_PARTS: scale = glm.scale(glm.mat4(), glm.vec3(0.55, 0.55, 0.55)) model = transform * rest_rot * scale GL.glUniformMatrix4fv(self._uniforms['model_mat_loc'], 1, GL.GL_FALSE, np.ascontiguousarray(model)) GL.glUniform4fv(self._uniforms['character_color_loc'], 1, np.ascontiguousarray(self._joints_color)) GL.glDrawArrays(GL.GL_TRIANGLES, self._sphere_mem_info[0], self._sphere_mem_info[1]) def set_color(self, color): self._character_color = color def draw(self, frame): if self._skeleton is None: return frame = frame % self._skeleton.frame_count # TODO: remove these strings self._uniforms = { 'model_mat_loc': self._shader_program.uniform_location("modelMatrix"), 'view_mat_loc': self._shader_program.uniform_location("viewMatrix"), 'proj_mat_loc': self._shader_program.uniform_location("projectionMatrix"), 'normal_mat_loc': self._shader_program.uniform_location("normalMatrix"), 'character_color_loc': self._shader_program.uniform_location("characterColor"), #'ambient_color_loc': self._shader_program.uniform_location("ambientColor"), #'specular_color_loc': self._shader_program.uniform_location("specularColor"), #'shininess_loc': self._shader_program.uniform_location("shininess") } # Setting all shared data self._shader_program.bind() GL.glUniformMatrix4fv(self._uniforms['view_mat_loc'], 1, GL.GL_FALSE, np.ascontiguousarray(self._view_matrix)) GL.glUniformMatrix4fv(self._uniforms['proj_mat_loc'], 1, GL.GL_FALSE, np.ascontiguousarray(self._proj_matrix)) self._skeleton.traverse(frame, self._on_draw_part, self._skeleton_trans) def clean_up(self): """This function frees all used resources. It includes all VBO's, VAO's, and so on. It must be explicitly called since there is no guarantee that there will be a a OpenGL context when this object is garbage collected. """ GL.glDeleteVertexArrays(1, self._vao) GL.glDeleteBuffers(1, self._vertex_bo) GL.glDeleteBuffers(1, self._normal_bo) def add_motion(self, motion, trans=glm.mat4()): self._skeleton = motion self._skeleton_trans = trans def _setup_render_matrices(self): """It simply initializes model, view, and projection matrices""" self._view_matrix = glm.mat4() self._proj_matrix = glm.mat4() def _setup_ligthing(self): """Setup shading colors""" self._diffuse_color = glm.vec4(0.26, 0.80, 0.26, 1.0) self._ambient_color = self._diffuse_color * 0.3 self._specular_color = glm.vec4(0.84, 0.30, 0.74, 1.0) self._shininess = 64 def _create_shaders(self): """Creates the shader program""" self._shader_program = ShaderProgram(self._get_vertex_shader_fn(), self._get_fragent_shader_fn()) # Setup Vertex Attributes for _, attrib in MotionRender.VertexAttributes.__members__.items(): self._shader_program.bind_attribute(attrib.value["location"], attrib.value["name"]) self._shader_program.compile() def _create_mesh_data(self): """All mesh data is created by this function. So far, it basically creates one cube that will be used to draw the squared characters. Each character's body part is drawn as cube. TODO: It should be generalized to support multiple rendering styles. """ #vertices, normals = mesh.create_cube_mesh() cylinder_mesh = mesh.create_cylinder_mesh(15) sphere_mesh = mesh.create_sphere_mesh(30) self._vertices = np.concatenate( (cylinder_mesh.vertices, sphere_mesh.vertices)) self._normals = np.concatenate( (cylinder_mesh.normals, sphere_mesh.normals)) self._cylinder_mem_info = (0, len(cylinder_mesh.vertices) // 3) self._sphere_mem_info = (len(cylinder_mesh.vertices) // 3, len(sphere_mesh.vertices) // 3) def _create_gl_objects(self): """This function creates and initiliazes all opengl objects needed to render the character.""" self._vao = GL.glGenVertexArrays(1) GL.glBindVertexArray(self._vao) # Generate buffer object for the mesh vertices self._vertex_bo = GL.glGenBuffers(1) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self._vertex_bo) GL.glBufferData(GL.GL_ARRAY_BUFFER, self._vertices.nbytes, self._vertices, GL.GL_STATIC_DRAW) # Setup Vertex Attrib Pointer pos_attrib_pointer = MotionRender.VertexAttributes.Position.value[ "location"] GL.glEnableVertexAttribArray(pos_attrib_pointer) GL.glVertexAttribPointer(pos_attrib_pointer, 3, GL.GL_FLOAT, False, 0, ctypes.c_void_p(0)) self._normal_bo = GL.glGenBuffers(1) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self._normal_bo) GL.glBufferData(GL.GL_ARRAY_BUFFER, self._normals.nbytes, self._normals, GL.GL_STATIC_DRAW) normal_attrib_pointer = MotionRender.VertexAttributes.Normal.value[ "location"] GL.glEnableVertexAttribArray(normal_attrib_pointer) GL.glVertexAttribPointer(normal_attrib_pointer, 3, GL.GL_FLOAT, False, 0, ctypes.c_void_p(0)) # Unbind each used GL object GL.glBindVertexArray(0) GL.glDisableVertexAttribArray(pos_attrib_pointer) GL.glDisableVertexAttribArray(normal_attrib_pointer) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0) def _get_vertex_shader_fn(self): return "./shaders/squared_character.vs" def _get_fragent_shader_fn(self): return "./shaders/squared_character.fs"
def main(): setupWindow() mesh = Mesh(vertices, indices) camera = Camera2D(DIMENSIONS[0], DIMENSIONS[1]) # Create the shader program and configure its uniforms. shaderprogram = ShaderProgram("shaders/vertex.shader", "shaders/fragment.shader") shaderprogram.setUniform2f("resolution", DIMENSIONS[0], DIMENSIONS[1]) shaderprogram.setUniform2f("scale", camera.scaleVector[0], camera.scaleVector[1]) shaderprogram.setUniform1i("iterations", DEFAULT_ITERATIONS) while True: handleEvents() pan, zoom = camera.move() if pan: shaderprogram.setUniform2f("cameraPos", camera.position[0], camera.position[1]) if zoom: shaderprogram.setUniform2f("scale", camera.scaleVector[0], camera.scaleVector[1]) if AUTO_UPDATE_ITERATIONS: iterations = getIterationCount(camera.scale) shaderprogram.setUniform1i("iterations", iterations) renderer.clearScreen() # Render the quads. renderer.render2D(mesh, shaderprogram.shader) # Swap buffers. pygame.display.flip()
class Canvas(QGLWidget): def __init__(self, imgPath=None): QGLWidget.__init__(self) self.layers = [] self.canvasWidth = 640 # size of image, not entire widget self.canvasHeight = 480 if imgPath is None: self.imgPath = None self.setWindowTitle('untitled*') else: if not os.path.exists(imgPath): raise IOError self.imgPath = imgPath self.startImg = QImage() self.startImg.load(self.imgPath) self.canvasWidth = self.startImg.width() self.canvasHeight = self.startImg.height() self.setWindowTitle(imgPath) def mousePressEvent(self, event): #print('press') self.paintGL() def mouseReleaseEvent(self, event): print('release') def mouseMoveEvent(self, event): #print('move') self.paintGL() def paintGL(self): glClear(GL_COLOR_BUFFER_BIT) # draw FBO layers from the bottom up for layer in reversed(self.layers): self.drawTexture(QPointF(0,0), layer.texture(), GL_TEXTURE_RECTANGLE_ARB) # if stroke, draw to the stroke layer, draw stroke layer self.program.bind() glBegin(GL_LINE_STRIP) g=gluNewNurbsRenderer() x1 = y1 = 25 x2 = y2 = 450 scale = abs(x2-x1)/3.0 midx, midy = (abs(x2+x1)/2.0), abs(y2+y1)/2.0 degree = 3 ctrlpoints=[[x1, y1, 0], [x1+scale, y1, 0], [midx, midy, 0], [x2-scale, y2, 0], [x2, y2, 0]] glu.gluBeginCurve(g) glu.gluNurbsCurve(g, [[10,10,0],[50,30,0],[100,100,0],[110,220,0],[400,280,0]], [[0,0,0.1,0.1],[0,0,0.1,0.1],[0,0,0.1,0.1],[0,0,0.1,0.1],[0,0,0.1,0.1],[0,0,0.1,0.1],[0,0,0.1,0.1],[0,0,0.1,0.1],], GL_MAP1_VERTEX_3) glu.gluEndCurve(g) glVertex2f(10,10) glVertex2f(20,10) glVertex2f(10,200) glVertex2f(100,200) glEnd() self.program.release() def resizeGL(self, w, h): glViewport(0,0,w,h) glMatrixMode(GL_PROJECTION) glLoadIdentity() glOrtho(0, w, 0, h, -1, 1) def initializeGL(self): glClearColor(0.4, 0.4, 0.4, 1.0) # if a starting image, load it # if self.startImg is not None: # print(self.img.width()) self.layers = [ Layer(self.canvasWidth,self.canvasHeight) ] self.strokeLayer = Layer(self.canvasWidth,self.canvasHeight) # if there's a starting image, draw it into the starting layer if self.imgPath is not None: bottomLayer = self.layers[-1] bottomLayer.bind() # setup the orthographic projection and viewport glMatrixMode(GL_PROJECTION) glPushMatrix() glLoadIdentity() glOrtho(0, self.canvasWidth, 0, self.canvasHeight, -1, 1) glViewport(0, 0, self.canvasWidth, self.canvasHeight) imgTextureId = self.bindTexture(self.startImg, GL_TEXTURE_RECTANGLE_ARB) self.drawTexture(QPointF(0,0), imgTextureId, GL_TEXTURE_RECTANGLE_ARB) self.deleteTexture(imgTextureId) # restore the previous projection matrix and viewport glMatrixMode(GL_PROJECTION) glPopMatrix() glViewport(0, 0, self.width(), self.height()) # should be saved off? bottomLayer.release() self.startImg = None # setup the necessary shaders self.program = ShaderProgram() self.program.attachShader(ShaderCode(GL_VERTEX_SHADER,'./shaders/basic.vert')) self.program.attachShader(ShaderCode(GL_FRAGMENT_SHADER,'./shaders/basic.frag'))
class CustomHandler(BaseHTTPRequestHandler, object): def __init__(self, *args, **kwargs): self.boundary = '--boundarydonotcross' self.html = open('index.html', 'r').read() # Handle Arguments self.input_path = _args.i[0] self.rotation = _args.r[0] self.output_width = int(_args.c[0].split('x')[0]) self.output_height = int(_args.c[0].split('x')[1]) self.frame_rate = _args.f[0] self.frame_skip_rate = _args.k[0] self.recognize_scale = 0.2 self.predictor = dlib.shape_predictor('../shapes/shape_predictor_68_face_landmarks.dat') self.face_cascade = toolbox.loadCascade('haarcascade_frontalface_default.xml') # Define skipping vars self.skip_frames = None self.skip_frame_x = None self.skip_frame_y = None self.skip_rect = None self.skip_points = None # OpenGL self.quad = Quad() self.quad_program = ShaderProgram(fragment=self.quad.fragment, vertex=self.quad.vertex) self.quad.loadVBOs(self.quad_program) self.quad.loadElements() super(CustomHandler, self).__init__(*args, **kwargs) def do_GET(self): self.send_response(200) if self.path.endswith('.mjpg'): # Response headers (multipart) self.send_header('Cache-Control', 'no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0') self.send_header('Connection', 'close') self.send_header('Content-Type', 'multipart/x-mixed-replace; boundary=%s' % self.boundary) self.send_header('Expires', 'Mon, 3 Jan 2000 12:34:56 GMT') self.send_header('Pragma', 'no-cache') stream = self.init_connection(self.input_path) stream_bytes = b'' for line in stream.iter_content(chunk_size=2048, decode_unicode=False): stream_bytes += line a = stream_bytes.find(b'\xff\xd8') # Start of a frame b = stream_bytes.find(b'\xff\xd9') # End of a frame if a != -1 and b != -1: frame_bytes = stream_bytes[a:b+2] stream_bytes = stream_bytes[b+2:] frame = cv2.imdecode(np.fromstring(frame_bytes, dtype=np.uint8), cv2.IMREAD_COLOR) frame, points = self.processFrame(frame, self.rotation, self.frame_skip_rate, self.face_cascade, self.predictor, self.recognize_scale, self.output_width, self.output_height) if frame is not None: # if points is not None: # frame = self.getGLFrame(frame, points, self.output_width, self.output_height) jpg = cv2.imencode('.jpg', frame)[1] # Part boundary string self.end_headers() self.wfile.write(bytes(self.boundary.encode('utf-8'))) self.end_headers() # Part headers self.send_header('X-Timestamp', time.time()) self.send_header('Content-length', str(len(jpg))) self.send_header('Content-type', 'image/jpeg') self.end_headers() # Write Binary self.wfile.write(bytes(jpg)) else: self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write(bytes(self.html.encode('utf-8'))) def init_connection(self, url): session = requests.Session() request = requests.Request("GET", url).prepare() response_stream = session.send(request, stream=True) return response_stream def log_message(self, format, *args): return def rotateFrame(self, image, angle, crop=True): if (angle < 0): angle = 360 + angle if (angle == 0): return image if (angle != 90 and angle != 180 and angle != 270): raise NameError('You can only rotate the image in steps of 90 / -90 degree') return image if (angle == 180): (h, w) = image.shape[:2] center = (w / 2, h / 2) matrix = cv2.getRotationMatrix2D(center, -angle, 1.0) result = cv2.warpAffine(frame, matrix, (w, h)) return result (h, w) = image.shape[:2] size = max(w, h) canvas = np.zeros((size, size, 3), np.uint8) x = int((size - w) / 2) y = int((size - h) / 2) canvas[y:y+h, x:x+w] = image center = (size / 2, size / 2) matrix = cv2.getRotationMatrix2D(center, -angle, 1.0) canvas = cv2.warpAffine(canvas, matrix, (size, size)) if (crop): canvas = canvas[x:x+w, y:y+h] return canvas def cropFrame(self, frame, x, y, w, h): rows, cols = frame.shape[:2] if (cols > w and rows > h): return frame[y:y+h, x:x+w] else: return frame def getGLFrame(self, frame, points, output_width, output_height): p1, p2, p3 = points[39], points[42], points[33] w, h = output_width, output_height p1 = [(p1[1] / w) * 2 - 1, -((p1[0] / h) * 2 - 1)] p2 = [(p2[1] / w) * 2 - 1, -((p2[0] / h) * 2 - 1)] p3 = [(p3[1] / w) * 2 - 1, -((p3[0] / h) * 2 - 1)] triangle = Triangle(p1, p2, p3) tri_program = ShaderProgram(fragment=triangle.fragment, vertex=triangle.vertex) triangle.loadVBOs(tri_program) triangle.loadElements() glClear(GL_COLOR_BUFFER_BIT) glClearColor (0.0, 0.0, 0.0, 1.0) #-----------------------------------# self.quad_program.start() toolbox.bind(self.quad) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_BGR, GL_UNSIGNED_BYTE, frame) glDrawElements(GL_TRIANGLES, len(self.quad.elements) * 3, GL_UNSIGNED_INT, None) toolbox.unbind() self.quad_program.stop() #-----------------------------------# tri_program.start() toolbox.bind(triangle) glDrawElements(GL_TRIANGLES, len(triangle.elements) * 3, GL_UNSIGNED_INT, None) toolbox.unbind() tri_program.stop() #-----------------------------------# glFinish() glPixelStorei(GL_PACK_ALIGNMENT, 1) buffer = glReadPixels(0, 0, output_width, output_height, GL_BGR, GL_UNSIGNED_BYTE) image = Image.frombytes('RGB', (output_width, output_height), buffer) image = image.transpose(Image.FLIP_TOP_BOTTOM) frame = np.asarray(image, dtype=np.uint8) glutSwapBuffers() return frame def processFrame(self, frame, rotation, frame_skip_rate, face_cascade, predictor, recognize_scale, output_width, output_height): points = None # Roate the frame # frame = self.rotateFrame(frame, rotation) return (frame, points) scale = (1 / recognize_scale) # Check how many frames have been skipped if self.skip_frames is not None and self.skip_frames > 0: self.skip_frames -= 1 if self.skip_frame_x is not None and self.skip_frame_y is not None: frame = self.cropFrame(frame, self.skip_frame_x, self.skip_frame_y, output_width, output_height) points = self.skip_points else: self.skip_frames = frame_skip_rate # Get current frame width and height for later usage (frame_height, frame_width) = frame.shape[:2] # Create a low resolution version of the rotated frame small = cv2.resize(frame, (0,0), fx=recognize_scale, fy=recognize_scale) gray = cv2.cvtColor(small, cv2.COLOR_BGR2GRAY) # Recognize a face on the low reslution frame faces = face_cascade.detectMultiScale(gray, 1.1, 5) for (x, y, w, h) in faces: # Scale up coordinates x, y, w, h = int(x * scale), int(y * scale), int(w * scale), int(h * scale) # Crop the frame frame_x = int((frame_width - output_width) / 2) frame_y = y - int((output_height - h) / 2) frame = self.cropFrame(frame, frame_x, frame_y, output_width, output_height) # Normalize coordinates to the cropped frame x = x - frame_x y = y - frame_y # Create a low resolution version of the cropped frame small = cv2.resize(frame, (0,0), fx=recognize_scale, fy=recognize_scale) # Find all the landmarks on the face rs = recognize_scale low_rect = (x * rs, y * rs, w * rs, h * rs) shape = predictor(small, toolbox.rect2rectangle(low_rect)) points = np.array([[p.y * scale, p.x * scale] for p in shape.parts()]) toolbox.drawTriangles(frame, points) # Save values to use while skipping frames self.skip_frame_x = frame_x self.skip_frame_y = frame_y self.skip_rect = (x, y, w, h) self.skip_points = points return (frame, points)
def add_program(self, name, shaders): shaders = [self.shaders[i] for i in shaders] sp = ShaderProgram(shaders) self.programs[name] = sp
class Canvas: image: Image.Image draw: ImageDraw.ImageDraw vao: int program: ShaderProgram texture: int width: int height: int font: ImageFont.ImageFont def __init__(self, width, height): self._createGlSurface() self.texture = 0 self.resize(width, height) self._createGlTexture() self.width = width self.height = height self.program = ShaderProgram('shaders/guiShader.vert', 'shaders/guiShader.frag') self.font = ImageFont.truetype('assets/minecraft_font.ttf', 16) def resize(self, width, height): self.width = width self.height = height self.image = Image.new("RGB", (width, height), color=ALPHA_COLOR) self.draw = typing.cast(ImageDraw.ImageDraw, ImageDraw.Draw(self.image, "RGBA")) if self.texture == 0: self._createGlTexture() def create_oval(self, x0, y0, x1, y1, **kwargs): if 'fill' in kwargs: assert (kwargs['fill'] not in ['#000', '#000000', 'black']) fill = kwargs.pop('fill', '#0000') outline = kwargs.pop('outline', '#111F') width = kwargs.pop('width', 1) assert (len(kwargs) == 0) self.draw.ellipse([x0, y0, x1, y1], fill=fill, outline=outline, width=width) def create_rectangle(self, x0, y0, x1, y1, **kwargs): if 'fill' in kwargs: assert (kwargs['fill'] not in ['#000', '#000000', 'black']) fill = kwargs.pop('fill', '#0000') outline = kwargs.pop('outline', '#111F') width = kwargs.pop('width', 1) assert (len(kwargs) == 0) self.draw.rectangle([x0, y0, x1, y1], fill=fill, outline=outline, width=width) def create_text(self, x, y, **kwargs): text = kwargs.pop('text') fill = kwargs.pop('fill', '#FFF') anchor = convertAnchor(kwargs.pop('anchor', 'center')) font = kwargs.pop('font', ()) if len(kwargs) != 0: print(kwargs) assert (False) self.draw.text((int(x), int(y)), text=text, fill=fill, font=self.font, anchor=anchor) def create_image(self, x, y, **kwargs): image = kwargs.pop('image') anchor = kwargs.pop('anchor', 'center') if len(kwargs) != 0: print(kwargs) assert (False) if anchor == 'center': x -= image.width // 2 y -= image.height // 2 else: print(anchor) assert (False) mask = getCachedMask(image) self.image.paste(image, box=(int(x), int(y)), mask=mask) def _createGlSurface(self): vertices = numpy.array( [ 1.0, 1.0, 1.0, 0.0, # top right 1.0, -1.0, 1.0, 1.0, # bottom right -1.0, -1.0, 0.0, 1.0, # bottom left -1.0, 1.0, 0.0, 0.0, # top left ], dtype='float32') indices = numpy.array([ 0, 1, 3, 1, 2, 3, ], dtype='uint32') vao: int = glGenVertexArrays(1) #type:ignore vbo: int = glGenBuffers(1) #type:ignore ebo: int = glGenBuffers(1) #type:ignore glBindVertexArray(vao) glBindBuffer(GL_ARRAY_BUFFER, vbo) glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL_STATIC_DRAW) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo) glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.nbytes, indices, GL_STATIC_DRAW) glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * 4, ctypes.c_void_p(0)) glEnableVertexAttribArray(0) glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * 4, ctypes.c_void_p(2 * 4)) glEnableVertexAttribArray(1) glBindBuffer(GL_ARRAY_BUFFER, 0) glBindVertexArray(0) self.vao = vao def _createGlTexture(self): self.texture = glGenTextures(1) #type:ignore glBindTexture(GL_TEXTURE_2D, self.texture) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glBindTexture(GL_TEXTURE_2D, 0) def redraw(self): arr = numpy.asarray(self.image.convert('RGBA'), dtype=numpy.uint8) glActiveTexture(GL_TEXTURE0) glBindTexture(GL_TEXTURE_2D, self.texture) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self.image.width, self.image.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, arr) #type:ignore glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) self.program.useProgram() glUniform3f(self.program.getUniformLocation("alphaColor"), ALPHA_COLOR[0] / 255.0, ALPHA_COLOR[1] / 255.0, ALPHA_COLOR[2] / 255.0) glBindVertexArray(self.vao) glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, ctypes.c_void_p(0)) #type:ignore #glBlendFunc(GL_SRC_ALPHA, GL_ZERO) self.image = Image.new("RGB", (self.width, self.height), color=ALPHA_COLOR) self.draw = typing.cast(ImageDraw.ImageDraw, ImageDraw.Draw(self.image, "RGBA"))