def render2D(self, actors): """Render 2D decorations. """ if not actors: return #print("Render %s decorations" % len(actors)) # Set modelview/projection modelview = Matrix4() self.shader.uniformMat4('modelview', modelview.gl()) left = 0. # -0.5 right = float(self.canvas.width()) # -0.5 bottom = 0. # -0.5 top = float(self.canvas.height()) # -0.5 near = -1. far = 1. projection = orthogonal_matrix(left, right, bottom, top, near, far) self.shader.uniformMat4('projection', projection.gl()) GL.glDisable(GL.GL_DEPTH_TEST) GL.glDisable(GL.GL_CULL_FACE) GL.glDepthMask(GL.GL_FALSE) # ALPHABLEND # # We need blending for text rendering! # # 2D actors are by default opak! opaque = [a for a in actors if a.opak is None or a.opak] transp = [a for a in actors if a.opak is False] # First render the opaque objects self.renderObjects(opaque) # Then the transparent ones # Disable writing to the depth buffer # as everything behind the transparent object # also needs to be drawn GL.glEnable(GL.GL_BLEND) GL.glBlendEquation(GL.GL_FUNC_ADD) if pf.cfg['render/textblend'] == 'mult': GL.glBlendFunc(GL.GL_ZERO, GL.GL_SRC_COLOR) elif pf.cfg['render/textblend'] == 'add': GL.glBlendFunc(GL.GL_ONE, GL.GL_ONE) elif pf.cfg['render/textblend'] == 'trad1': GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE) elif pf.cfg['render/textblend'] == 'zero': GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ZERO) else: GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA) self.renderObjects(transp) GL.glDisable(GL.GL_BLEND) GL.glDepthMask(GL.GL_TRUE)
def setup_blend(self): GL.glEnable(GL.GL_BLEND) if self.use_separate_blend: GL.glBlendEquationSeparate(*self.blend_equation_separate) GL.glBlendFuncSeparate(*self.blend_func_separate) else: GL.glBlendEquation(self.blend_equation) GL.glBlendFunc(*self.blend_func) GL.glEnable(GL.GL_DEPTH_TEST) GL.glDepthFunc(self.depth_test)
def shader_proj(event_coll, event): '''Use projection shader''' print("Changing shader to projection") scene = event_coll.scene for coll in scene.collections: coll.set_shader("default.v") coll.set_shader("projection.f") scene.set_shader("passthrough.v") scene.set_shader("apply_colormap.f") for collection in scene.collections: collection.set_fields_log(False) scene.update_minmax() GL.glBlendFunc(GL.GL_ONE, GL.GL_ONE) GL.glBlendEquation(GL.GL_FUNC_ADD) return True
def shader_max(event_coll, event): '''Use maximum intensity shader''' print("Changing shader to max(intensity)") scene = event_coll.scene for coll in scene.collections: coll.set_shader("default.v") coll.set_shader("max_intensity.f") scene.set_shader("passthrough.v") scene.set_shader("apply_colormap.f") for collection in scene.collections: collection.set_fields_log(True) scene.update_minmax() GL.glBlendFunc(GL.GL_ONE, GL.GL_ONE) GL.glBlendEquation(GL.GL_MAX) return True
def main(): pygame.init() screen = pygame.display.set_mode((512, 512), pygame.OPENGL | pygame.DOUBLEBUF) GL.glClearColor(0.5, 0.5, 0.5, 1.0) GL.glEnable(GL.GL_BLEND) GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA) GL.glBlendEquation(GL.GL_FUNC_ADD) GL.glViewport(0, 0, 512, 512) texture = create_texture('container.jpg') shader = create_shader(vertex_shader, fragment_shader) vertex_array_object = create_object(shader) clock = pygame.time.Clock() pos = 250, 250 angle = 0 model1 = transform4x4((250.0, 256.0), 0.0, (250.0, 250.0)) model2 = transform4x4(pos, angle, (200.0, 200.0)) view = transform4x4((0.0, 0.0), 0.0, (1.0, 1.0)) projection = ortho4x4(0, 512, 0, 512, -1, 1) while True: 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: if event.button == 1: pos = event.pos[0], 512 - event.pos[1] if event.button == 4: angle = (angle + 10.0) % 360.0 if event.button == 5: angle = (angle - 10.0) % 360.0 model2 = transform4x4(pos, angle, (200.0, 200.0)) yellow = 1.0, 0.0, 0.0, 1.0 red = 1.0, 1.0, 1.0, 0.75 clear() display(shader, vertex_array_object, texture, yellow, model1, view, projection) display(shader, vertex_array_object, texture, red, model2, view, projection) pygame.display.flip() clock.tick(60)
def shader_lines(event_coll, event): print("Changing shader to projection") scene = event_coll.scene for coll in scene.collections: coll.set_shader("default.v") coll.set_shader("drawlines.f") scene.set_shader("passthrough.v") scene.set_shader("noop.f") for collection in scene.collections: collection.set_fields_log(True) #scene.update_minmax() # https://www.opengl.org/sdk/docs/man/html/glBlendFunc.xhtml #GL.glBlendFunc(GL.GL_ONE, GL.GL_DST_ALPHA) #GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA) #GL.glBlendFunc(GL.GL_ONE_MINUS_SRC_ALPHA, GL.GL_SRC_ALPHA) GL.glBlendFunc(GL.GL_ONE, GL.GL_ONE) GL.glBlendEquation(GL.GL_MAX) return True
def main(): pygame.init() screen = pygame.display.set_mode((512, 512), pygame.OPENGL|pygame.DOUBLEBUF) GL.glClearColor(0.5, 0.5, 0.5, 1.0) GL.glEnable(GL.GL_BLEND) GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); GL.glBlendEquation(GL.GL_FUNC_ADD); GL.glViewport(0, 0, 512, 512) texture = create_texture('container.jpg') shader = create_shader(vertex_shader, fragment_shader) vertex_array_object = create_object(shader) clock = pygame.time.Clock() pos = 250, 250 angle = 0 model1 = transform4x4((250.0, 256.0), 0.0, (250.0, 250.0)) model2 = transform4x4(pos, angle, (200.0, 200.0)) view = transform4x4((0.0, 0.0), 0.0, (1.0, 1.0)) projection = ortho4x4(0, 512, 0, 512, -1, 1) while True: 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: if event.button == 1: pos = event.pos[0], 512-event.pos[1] if event.button == 4: angle = (angle + 10.0) % 360.0 if event.button == 5: angle = (angle - 10.0) % 360.0 model2 = transform4x4(pos, angle, (200.0, 200.0)) yellow = 1.0, 0.0, 0.0, 1.0 red = 1.0, 1.0, 1.0, 0.75 clear() display(shader, vertex_array_object, texture, yellow, model1, view, projection) display(shader, vertex_array_object, texture, red, model2, view, projection) pygame.display.flip() clock.tick(60)
def OnDraw(self, fast=False): # Prepare by setting things to their defaults. This might release some # memory so result in a bigger chance that the shader is run in # hardware mode. On ATI, the line and point smoothing should be off # if you want to use gl_FragCoord. (Yeah, I do not see the connection # either...) gl.glPointSize(1) gl.glLineWidth(1) gl.glDisable(gl.GL_LINE_STIPPLE) gl.glDisable(gl.GL_LINE_SMOOTH) gl.glDisable(gl.GL_POINT_SMOOTH) # only draw front-facing parts gl.glEnable(gl.GL_CULL_FACE) gl.glCullFace(gl.GL_BACK) gl.glBlendFunc(gl.GL_ONE, gl.GL_ONE) gl.glBlendEquation(gl.GL_MAX) gl.glDisable(gl.GL_DEPTH_TEST) if self._program1.IsUsable(): self._program1.Enable() if fast: self._program1.SetUniformf('stepRatio', [0.4]) else: self._program1.SetUniformf('stepRatio', [1.0]) self._program1.SetUniformi('texture', [0]) self._colormap.Enable(1) self._program1.SetUniformi('colormap', [1]) # enable this texture t1 = time.time() for i, tex in enumerate(self._textures): tex.Enable(0) if not tex._shape: continue # fragment shader on # bind texture- and help-textures (create if it does not exist) # set uniforms: parameters shape = tex._shape # as in opengl self._program1.SetUniformf('shape', reversed(list(shape))) # do the actual drawing self._DrawQuads(tex, i) tex.Disable() # clean up gl.glFlush() t2 = time.time() print("Rendering: %0.3e" % (t2 - t1)) self._colormap.Disable() self._program1.Disable() # gl.glBlendEquation(gl.GL_FUNC_ADD) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) gl.glDisable(gl.GL_CULL_FACE) gl.glEnable(gl.GL_LINE_SMOOTH) gl.glEnable(gl.GL_POINT_SMOOTH) gl.glEnable(gl.GL_DEPTH_TEST)
def _init_blending(self): GL.glEnable(GL.GL_BLEND) GL.glBlendColor(1.0, 1.0, 1.0, 1.0) GL.glBlendFunc(GL.GL_ONE, GL.GL_ONE) GL.glBlendEquation(GL.GL_MAX)
def render(self, draw_data): # perf: local for faster access io = self.io display_width, display_height = self.io.display_size fb_width = int(display_width * io.display_fb_scale[0]) fb_height = int(display_height * io.display_fb_scale[1]) if fb_width == 0 or fb_height == 0: return draw_data.scale_clip_rects(*io.display_fb_scale) # backup GL state # todo: provide cleaner version of this backup-restore code last_program = gl.glGetIntegerv(gl.GL_CURRENT_PROGRAM) last_texture = gl.glGetIntegerv(gl.GL_TEXTURE_BINDING_2D) last_active_texture = gl.glGetIntegerv(gl.GL_ACTIVE_TEXTURE) last_array_buffer = gl.glGetIntegerv(gl.GL_ARRAY_BUFFER_BINDING) last_element_array_buffer = gl.glGetIntegerv( gl.GL_ELEMENT_ARRAY_BUFFER_BINDING) last_vertex_array = gl.glGetIntegerv(gl.GL_VERTEX_ARRAY_BINDING) last_blend_src = gl.glGetIntegerv(gl.GL_BLEND_SRC) last_blend_dst = gl.glGetIntegerv(gl.GL_BLEND_DST) last_blend_equation_rgb = gl.glGetIntegerv(gl.GL_BLEND_EQUATION_RGB) last_blend_equation_alpha = gl.glGetIntegerv( gl.GL_BLEND_EQUATION_ALPHA) last_viewport = gl.glGetIntegerv(gl.GL_VIEWPORT) last_scissor_box = gl.glGetIntegerv(gl.GL_SCISSOR_BOX) last_enable_blend = gl.glIsEnabled(gl.GL_BLEND) last_enable_cull_face = gl.glIsEnabled(gl.GL_CULL_FACE) last_enable_depth_test = gl.glIsEnabled(gl.GL_DEPTH_TEST) last_enable_scissor_test = gl.glIsEnabled(gl.GL_SCISSOR_TEST) gl.glEnable(gl.GL_BLEND) gl.glBlendEquation(gl.GL_FUNC_ADD) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) gl.glDisable(gl.GL_CULL_FACE) gl.glDisable(gl.GL_DEPTH_TEST) gl.glEnable(gl.GL_SCISSOR_TEST) gl.glActiveTexture(gl.GL_TEXTURE0) gl.glViewport(0, 0, int(fb_width), int(fb_height)) ortho_projection = [[2.0 / display_width, 0.0, 0.0, 0.0], [0.0, 2.0 / -display_height, 0.0, 0.0], [0.0, 0.0, -1.0, 0.0], [-1.0, 1.0, 0.0, 1.0]] gl.glUseProgram(self._shader_handle) gl.glUniform1i(self._attrib_location_tex, 0) gl.glUniformMatrix4fv(self._attrib_proj_mtx, 1, gl.GL_FALSE, ortho_projection) gl.glBindVertexArray(self._vao_handle) for commands in draw_data.commands_lists: idx_buffer_offset = 0 gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._vbo_handle) # todo: check this (sizes) gl.glBufferData(gl.GL_ARRAY_BUFFER, commands.vtx_buffer_size * imgui.VERTEX_SIZE, ctypes.c_void_p(commands.vtx_buffer_data), gl.GL_STREAM_DRAW) gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self._elements_handle) # todo: check this (sizes) gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, commands.idx_buffer_size * imgui.INDEX_SIZE, ctypes.c_void_p(commands.idx_buffer_data), gl.GL_STREAM_DRAW) # todo: allow to iterate over _CmdList for command in commands.commands: gl.glBindTexture(gl.GL_TEXTURE_2D, command.texture_id) # todo: use named tuple x, y, w, z = command.clip_rect gl.glScissor(int(x), int(fb_height - w), int(z - x), int(w - y)) if imgui.INDEX_SIZE == 2: gltype = gl.GL_UNSIGNED_SHORT else: gltype = gl.GL_UNSIGNED_INT gl.glDrawElements(gl.GL_TRIANGLES, command.elem_count, gltype, ctypes.c_void_p(idx_buffer_offset)) idx_buffer_offset += command.elem_count * imgui.INDEX_SIZE # restore modified GL state gl.glUseProgram(last_program) gl.glActiveTexture(last_active_texture) gl.glBindTexture(gl.GL_TEXTURE_2D, last_texture) gl.glBindVertexArray(last_vertex_array) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, last_array_buffer) gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer) gl.glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha) gl.glBlendFunc(last_blend_src, last_blend_dst) if last_enable_blend: gl.glEnable(gl.GL_BLEND) else: gl.glDisable(gl.GL_BLEND) if last_enable_cull_face: gl.glEnable(gl.GL_CULL_FACE) else: gl.glDisable(gl.GL_CULL_FACE) if last_enable_depth_test: gl.glEnable(gl.GL_DEPTH_TEST) else: gl.glDisable(gl.GL_DEPTH_TEST) if last_enable_scissor_test: gl.glEnable(gl.GL_SCISSOR_TEST) else: gl.glDisable(gl.GL_SCISSOR_TEST) gl.glViewport(last_viewport[0], last_viewport[1], last_viewport[2], last_viewport[3]) gl.glScissor(last_scissor_box[0], last_scissor_box[1], last_scissor_box[2], last_scissor_box[3])
def draw(self, d2s=None, col=None): """This function causes the shape to render itself into the current GL context. d2s is a function of x,y which will convert data coordinates to screen coordinates. For data coordinate shapes, only the positional information is in data coordinates, font size, line width, etcare in screen units. col can be used to override the current shape's color.""" # global glut_inited s = self.shape if s[0] == "hidden": return if col == None: col = self.shape[1:4] if d2s == None: d2s = shidentity v = d2s(s[4], s[5]) v2 = d2s(s[4] + 1, s[5] + 1) sc = v2[0] - v[0] GL.glPopMatrix() GL.glPushMatrix() if self.isanimated: # print self.blend, "was the blend value" GL.glEnable(GL.GL_BLEND) depth_testing_was_on = GL.glIsEnabled(GL.GL_DEPTH_TEST) GL.glDisable(GL.GL_DEPTH_TEST) try: GL.glBlendEquation(GL.GL_FUNC_ADD) except: pass GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA) col = [self.shape[1], self.shape[2], self.shape[3], self.blend] if s[0] == "rect": assert self.shape[8] >= 0 GL.glLineWidth(s[8] * pixelratio) #if self.isanimated: #v1 = d2s(s[4],s[5]) #v2 = d2s(s[6],s[7]) #dx = (v1[0]+v2[0])/2.0 #dy = (v1[1]+v2[1])/2.0 #GL.glPushMatrix() #GL.glTranslate(dx,dy,0) #GL.glScale(self.blend,self.blend,1) #GL.glTranslate(-dx,-dy,0) GL.glBegin(GL.GL_LINE_LOOP) GL.glColor(*col) GL.glVertex(*d2s(s[4], s[5])) GL.glVertex(*d2s(s[6], s[5])) GL.glVertex(*d2s(s[6], s[7])) GL.glVertex(*d2s(s[4], s[7])) GL.glEnd() if s[0] == "rect4point": assert self.shape[12] >= 0 GL.glLineWidth(s[12] * pixelratio) GL.glBegin(GL.GL_LINE_LOOP) GL.glColor(*col) GL.glVertex(*d2s(s[4], s[5])) GL.glVertex(*d2s(s[6], s[7])) GL.glVertex(*d2s(s[8], s[9])) GL.glVertex(*d2s(s[10], s[11])) GL.glEnd() elif s[0] == "rectline": #This makes a rectangle based on a width and two points #The two points are the endpoints for the longer axis of symmetry #Those two points implicitly define the length #The width is a parameter and together with the two coordinates, defines the rectangle assert s[4] != s[6] or s[5] != s[7], "The endpoints cannot coincide" assert self.shape[8] >= 0, "The width must be positive" assert self.shape[9] >= 0, "The line-width must be positive" pt0 = (s[4], s[5]) #first coordinate pt1 = (s[6], s[7]) #second coordinate width = s[8] #width GL.glLineWidth(s[9] * pixelratio) #l_vect = (pt1[0]-pt0[0], pt1[1]-pt2[0]) #vector parallel to a longer side -- length vector w_vect = (-(pt1[1] - pt0[1]), pt1[0] - pt0[0] ) #vector parallel to a shorter side -- width vector mag = sqrt(w_vect[0]**2 + w_vect[1]**2) w_uvect = (old_div(w_vect[0], mag), old_div(w_vect[1], mag) ) #unit vector parallel to a short side #vertices - add/subtract a vector of half the box width with w_uvect direction v1 = (pt0[0] - w_uvect[0] * width / 2.0, pt0[1] - w_uvect[1] * width / 2.0) v2 = (pt0[0] + w_uvect[0] * width / 2.0, pt0[1] + w_uvect[1] * width / 2.0) v3 = (pt1[0] + w_uvect[0] * width / 2.0, pt1[1] + w_uvect[1] * width / 2.0) v4 = (pt1[0] - w_uvect[0] * width / 2.0, pt1[1] - w_uvect[1] * width / 2.0) #rectangle GL.glLineWidth(pixelratio) GL.glBegin(GL.GL_LINE_LOOP) GL.glColor(*col) GL.glVertex(*d2s(*v1)) GL.glVertex(*d2s(*v2)) GL.glVertex(*d2s(*v3)) GL.glVertex(*d2s(*v4)) GL.glEnd() #line GL.glBegin(GL.GL_LINES) GL.glColor(*col) GL.glVertex(*d2s(*pt0)) GL.glVertex(*d2s(*pt1)) GL.glEnd() elif s[0] == "rectpoint": assert self.shape[8] >= 0 GL.glLineWidth(s[8] * pixelratio) GL.glPointSize(s[8]) #rectangle GL.glBegin(GL.GL_LINE_LOOP) GL.glColor(*col) GL.glVertex(*d2s(s[4], s[5])) GL.glVertex(*d2s(s[6], s[5])) GL.glVertex(*d2s(s[6], s[7])) GL.glVertex(*d2s(s[4], s[7])) GL.glEnd() #midpoint GL.glBegin(GL.GL_POINTS) p1 = d2s(s[4], s[5]) p2 = d2s(s[6], s[7]) GL.glVertex(old_div((p1[0] + p2[0]), 2), old_div((p1[1] + p2[1]), 2)) GL.glEnd() elif s[0] == "rcirclepoint": assert self.shape[8] >= 0 GL.glLineWidth(s[8] * pixelratio) GL.glPointSize(s[8]) #midpoint GL.glBegin(GL.GL_POINTS) p1 = d2s(s[4], s[5]) p2 = d2s(s[6], s[7]) GL.glVertex(old_div((p1[0] + p2[0]), 2), old_div((p1[1] + p2[1]), 2)) GL.glEnd() v2 = d2s(s[6], s[7]) GL.glPushMatrix() GL.glColor(*col) #circle inscribed in the rectangle GL.glTranslate(old_div((v[0] + v2[0]), 2.0), old_div((v[1] + v2[1]), 2.0), 0) GL.glScalef(old_div((v2[0] - v[0]), 2.0), old_div((v2[1] - v[1]), 2.0), 1.0) GL.glBegin(GL.GL_LINE_LOOP) for i in range(60): GL.glVertex(CIRCLE[0][i], CIRCLE[1][i]) GL.glEnd() GL.glPopMatrix() elif s[0] == "rcircle": v2 = d2s(s[6], s[7]) assert self.shape[8] >= 0 GL.glLineWidth(s[8] * pixelratio) GL.glPushMatrix() GL.glColor(*col) GL.glTranslate(old_div((v[0] + v2[0]), 2.0), old_div((v[1] + v2[1]), 2.0), 0) GL.glScalef(old_div((v2[0] - v[0]), 2.0), old_div((v2[1] - v[1]), 2.0), 1.0) GL.glBegin(GL.GL_LINE_LOOP) for i in range(60): GL.glVertex(CIRCLE[0][i], CIRCLE[1][i]) GL.glEnd() GL.glPopMatrix() elif s[0] == "point": GL.glColor(*col) GL.glPointSize(s[6]) p1 = d2s(s[4], s[5]) GL.glBegin(GL.GL_POINTS) GL.glVertex(p1[0], p1[1]) GL.glEnd() elif s[0] == "line": # print "A line ",s[4],s[5],s[6],s[7] # print "A line ",d2s(s[4],s[5]),d2s(s[6],s[7]) GL.glColor(*col) assert self.shape[8] >= 0 GL.glLineWidth(s[8] * pixelratio) GL.glBegin(GL.GL_LINES) GL.glVertex(*d2s(s[4], s[5])) GL.glVertex(*d2s(s[6], s[7])) GL.glEnd() elif s[0] == "mask": # print "A line ",s[4],s[5],s[6],s[7] # print "A line ",d2s(s[4],s[5]),d2s(s[6],s[7]) GL.glColor(*col) GL.glBegin(GL.GL_TRIANGLE_STRIP) GL.glVertex(*d2s(s[4], s[5])) GL.glVertex(*d2s(s[6], s[7])) GL.glVertex(*d2s(s[8], s[9])) GL.glVertex(*d2s(s[10], s[11])) GL.glVertex(*d2s(s[12], s[13])) GL.glVertex(*d2s(s[14], s[15])) GL.glVertex(*d2s(s[16], s[17])) GL.glVertex(*d2s(s[18], s[19])) #First Vertex GL.glVertex(*d2s(s[4], s[5])) GL.glVertex(*d2s(s[6], s[7])) GL.glEnd() elif s[0] == "linemask": assert self.shape[12] >= 0 GL.glLineWidth(s[12] * pixelratio) GL.glColor(*col) GL.glBegin(GL.GL_LINE_LOOP) GL.glVertex(*d2s(s[4], s[5])) GL.glVertex(*d2s(s[6], s[7])) GL.glVertex(*d2s(s[8], s[9])) GL.glVertex(*d2s(s[10], s[11])) GL.glEnd() elif s[0] == "label": if len(col) == 4: col = col[:3] GL.glPushMatrix() if EMShape.font_renderer != None: GL.glPushAttrib(GL.GL_ALL_ATTRIB_BITS) GL.glTranslate(v[0], v[1], .2) EMShape.font_renderer.set_face_size(int(s[7])) if s[8] < 0: # try for a sensible background color if col[0] + col[1] + col[2] > .4 and col[0] + col[1] + col[ 2] < .6: bgcol = (0.0, 0.0, 0.0) else: bgcol = (1.0 - col[0], 1.0 - col[1], 1.0 - col[2]) bbox = EMShape.font_renderer.bounding_box(s[6]) GLUtil.mx_bbox(bbox, col, bgcol) GL.glEnable(GL.GL_TEXTURE_2D) GL.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE) GL.glColor(*col) EMShape.font_renderer.render_string(s[6]) GL.glPopAttrib() else: pass #if s[8]<0 : #GL.glColor(1.,1.,1.) #GL.glTranslate(v[0],v[1],0) #GL.glScalef(s[7]/100.0/sc,s[7]/100.0/sc,s[7]/100.0/sc) #GL.glLineWidth(-s[8]*pixelratio) #w=104.76*len(s[6]) #GL.glBegin(GL.GL_QUADS) #GL.glVertex(-10.,-33.0) #GL.glVertex(w+10.,-33.0) #GL.glVertex(w+10.,119.05) #GL.glVertex(-10.,119.05) #GL.glEnd() #GL.glColor(*col) #for i in s[6]: #GLUT.glutStrokeCharacter(GLUT.GLUT_STROKE_MONO_ROMAN,ord(i)) #else: #GL.glColor(*col) #GL.glTranslate(v[0],v[1],0) ## GL.glScalef(s[7]/100.0,s[7]/100.0,s[7]/100.0) #GL.glScalef(s[7]/100.0/sc,s[7]/100.0/sc,s[7]/100.0/sc) #GL.glLineWidth(fabs(s[8])*pixelratio) #for i in s[6]: #GLUT.glutStrokeCharacter(GLUT.GLUT_STROKE_ROMAN,ord(i)) GL.glPopMatrix() elif s[0] == "circle": # print(s[6],v) GL.glPushMatrix() GL.glColor(*col) GL.glLineWidth(s[7] * pixelratio) GL.glTranslate(v[0], v[1], 0) # GL.glScalef(s[6]*(v2[0]-v[0]),s[6]*(v2[1]-v[1]),1.0) GL.glScalef(sc * s[6], sc * s[6], 1.0) GL.glBegin(GL.GL_LINE_LOOP) for i in range(60): GL.glVertex(CIRCLE[0][i], CIRCLE[1][i]) GL.glEnd() GL.glPopMatrix() elif s[0] == "ellipse": # print s[6],v,v2 GL.glPushMatrix() GL.glColor(*col) GL.glLineWidth(s[9] * pixelratio) GL.glTranslate(v[0], v[1], 0) GL.glScalef((v2[0] - v[0]), (v2[1] - v[1]), 1.0) GL.glRotatef(s[8], 0, 0, 1.0) GL.glScalef(s[6], s[7], 1.0) GL.glBegin(GL.GL_LINE_LOOP) for i in range(60): GL.glVertex(CIRCLE[0][i], CIRCLE[1][i]) GL.glEnd() GL.glPopMatrix() else: #mx=GL.glGetFloatv(GL.GL_MODELVIEW_MATRIX) #GL.glPopMatrix() #GL.glPushMatrix() if s[0] == "scrrect": x1 = int(round(s[4])) y1 = int(round(s[5])) x2 = int(round(s[6])) y2 = int(round(s[7])) GL.glLineWidth(s[8] * pixelratio) GL.glBegin(GL.GL_LINE_LOOP) GL.glColor(*col) GL.glVertex(x1, y1) GL.glVertex(x2, y1) GL.glVertex(x2, y2) GL.glVertex(x1, y2) GL.glEnd() elif s[0] == "scrline": x1 = int(round(s[4])) y1 = int(round(s[5])) x2 = int(round(s[6])) y2 = int(round(s[7])) GL.glColor(*col) assert self.shape[8] >= 0 GL.glLineWidth(s[8] * pixelratio) GL.glBegin(GL.GL_LINES) GL.glVertex(x1, y1) GL.glVertex(x2, y2) GL.glEnd() elif s[0] == "scrlabel": if len(col) == 4: col = col[:3] x1 = int(round(s[4])) y1 = int(round(s[5])) # if s[8]<0 : if EMShape.font_renderer != None: GL.glPushAttrib(GL.GL_ALL_ATTRIB_BITS) GL.glTranslate(x1, y1, .2) if s[8] < 0: # try for a sensible background color if col[0] + col[1] + col[2] > .4 and col[0] + col[ 1] + col[2] < .6: bgcol = (0.0, 0.0, 0.0) else: bgcol = (1.0 - col[0], 1.0 - col[1], 1.0 - col[2]) bbox = EMShape.font_renderer.bounding_box(s[6]) GLUtil.mx_bbox( bbox, col, (1.0 - col[0], 1.0 - col[1], 1.0 - col[2])) GL.glEnable(GL.GL_TEXTURE_2D) GL.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE) GL.glColor(*col) EMShape.font_renderer.render_string(s[6]) GL.glPopAttrib() else: pass #else: #GL.glColor(1.,1.,1.) #GL.glTranslate(x1,y1,0) ##GL.glScalef(s[7]/1500.0/sc,s[7]/1500.0/sc,s[7]/1500.0/sc) #GL.glScalef(s[7]/1500.0,s[7]/1500.0,1) #GL.glLineWidth(-s[8]) #w=104.76*len(text) #GL.glBegin(GL.GL_QUADS) #GL.glVertex(-10.,-33.0) #GL.glVertex(w+10.,-33.0) #GL.glVertex(w+10.,119.05) #GL.glVertex(-10.,119.05) #GL.glEnd() #GL.glTranslate(0,0,.1) #GL.glColor(*col) #for i in text: #GLUT.glutStrokeCharacter(GLUT.GLUT_STROKE_MONO_ROMAN,ord(i)) #else: #GL.glColor(*col) #GL.glTranslate(x1,y1,-1) ## GL.glScalef(y2/100.0,y2/100.0,y2/100.0) #GL.glScalef(s[7]/1500.0/sc,s[7]/1500.0/sc,1) #GL.glLineWidth(fabs(s[8])) #for i in text: #GLUT.glutStrokeCharacter(GLUT.GLUT_STROKE_ROMAN,ord(i)) elif s[0] == "scrcircle": x1 = int(round(s[4])) y1 = int(round(s[5])) GL.glColor(*col) GL.glLineWidth(s[7] * pixelratio) GL.glTranslate(x1, y1, 0) GL.glScalef(s[6], s[6], s[6]) GL.glCallList(EMShape.dlists) #GL.glLoadMatrixf(mx) if self.isanimated: GL.glDisable(GL.GL_BLEND) if (depth_testing_was_on): GL.glEnable(GL.GL_DEPTH_TEST)
def render(self): self.framebufferObject().setAttachment( QOpenGLFramebufferObject.CombinedDepthStencil) e = GL.glGetError() #clear any pending errors c = self.background_color GL.glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF()) GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT) GL.glEnable(GL.GL_BLEND) GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA) GL.glBlendEquation(GL.GL_FUNC_ADD) GL.glEnable(GL.GL_PRIMITIVE_RESTART) GL.glPrimitiveRestartIndex(0xFFFFFFFF) GL.glDrawBuffers(len(self.draw_buffers), self.draw_buffers) #opengl_error_check(currentframe()) if self.render_to_texture_attachment != -1: GL.glFramebufferTexture2D( GL.GL_FRAMEBUFFER, self.draw_buffers[self.render_to_texture_attachment], GL.GL_TEXTURE_2D, self.locked_render_to_texture_array.___tex___.textureId(), 0) GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT) if GL.glCheckFramebufferStatus( GL.GL_FRAMEBUFFER) != GL.GL_FRAMEBUFFER_COMPLETE: raise RuntimeError("glCheckFramebufferStatus() problem") #opengl_error_check(currentframe()) for actor in self.bo_actors: try: program = actor['program'] indices = actor['indices'] attribs = actor['attribs'] textures = actor['textures'] out_textures = actor['out_textures'] transform = actor['transform'] uniforms = actor['uniforms'] primitiveType = actor['primitiveType'] point_size = actor['point_size'] line_width = actor['line_width'] program.bind() self.vertex_array.bind() for name, bo in viewitems(attribs): if bo is None: continue bo.bind() loc = program.attributeLocation(name) program.enableAttributeArray(loc) dim = bo.shape[1] if len(bo.shape) > 1 else 1 if bo.dtype == np.float32: program.setAttributeBuffer(loc, GL.GL_FLOAT, 0, dim) elif bo.dtype == np.int32: program.setAttributeBuffer(loc, GL.GL_INT, 0, dim) else: raise ValueError( f'Unsupported dtype {bo.dtype} for attrib {name}') #opengl_error_check(currentframe()) m = transform v = self.view_matrix p = self.perspective_matrix if program.uniformLocation("matrix") == -1: program.setUniformValue("model_matrix", m) program.setUniformValue("view_matrix", v) program.setUniformValue("projection_matrix", p) program.setUniformValue("normal_matrix", m.normalMatrix()) program.setUniformValue("view_matrix_inv", v.inverted()[0]) else: program.setUniformValue("matrix", p * v * m) if program.uniformLocation("ortho_matrix") != -1: program.setUniformValue("ortho_matrix", self.orthographic_matrix) if program.uniformLocation("aspect_ratio") != -1: program.setUniformValue( "aspect_ratio", self.viewport_width / self.viewport_height) #opengl_error_check(currentframe()) if program.uniformLocation("point_size") != -1: GL.glDisable(GL.GL_PROGRAM_POINT_SIZE) program.setUniformValue("point_size", float(point_size)) elif point_size != 1: try: GL.glEnable(GL.GL_PROGRAM_POINT_SIZE) GL.glPointSize(GL.GLfloat(point_size)) except Exception as e: # glPointSize is refused by the driver LoggingManager.instance().warning( f"glPointSize failed with: exception {e}") #opengl_error_check(currentframe()) for name, value in viewitems(uniforms): program.setUniformValue(name, value) #opengl_error_check(currentframe(), f"error with uniform {name}, {value}") texture_unit = 0 for name, tex in viewitems(textures): tex.bind(texture_unit) program.setUniformValue(name, texture_unit) #opengl_error_check(currentframe(), f"error with texture {name}, {value}") texture_unit += 1 for name, tex in viewitems(out_textures): if tex is None: LoggingManager.instance().warning( f'output texture {name} is null') continue # in your fragment shader, you can specify the location via the layout decoration # e.g. layout(location = 1) out vec4 my_output; loc = GL.glGetFragDataLocation(program.programId(), name) GL.glFramebufferTexture2D(GL.GL_FRAMEBUFFER, self.get_texture_attachment(loc), GL.GL_TEXTURE_2D, tex.textureId(), 0) if GL.glCheckFramebufferStatus( GL.GL_FRAMEBUFFER) != GL.GL_FRAMEBUFFER_COMPLETE: raise RuntimeError( "glCheckFramebufferStatus() problem") #opengl_error_check(currentframe()) if line_width != 1: try: GL.glEnable(GL.GL_LINE_SMOOTH) #opengl_error_check(currentframe()) GL.glLineWidth(GL.GLfloat(line_width)) except Exception as e: aliased_r = (GL.GLfloat * 2)() GL.glGetFloatv(GL.GL_ALIASED_LINE_WIDTH_RANGE, aliased_r) smooth_r = (GL.GLfloat * 2)() GL.glGetFloatv(GL.GL_SMOOTH_LINE_WIDTH_RANGE, smooth_r) line_r = (GL.GLfloat * 2)() GL.glGetFloatv(GL.GL_LINE_WIDTH_RANGE, line_r) LoggingManager.instance().warning( f"{e}: yout asked for line_width = {line_width}, line range is {list(line_r)}, aliased range is {list(aliased_r)}, smooth range is {list(smooth_r)}" ) else: GL.glDisable(GL.GL_LINE_SMOOTH) #opengl_error_check(currentframe()) if indices is not None and indices.shape[0] > 0: indices.bind() GL.glDrawElements(primitiveType, indices.shape[0], GL.GL_UNSIGNED_INT, None) indices.release() elif attribs["vertices"].shape[0] > 0: GL.glDrawArrays(primitiveType, 0, attribs["vertices"].shape[0]) for name, bo in viewitems(attribs): if bo is not None: bo.release() program.disableAttributeArray(name) for name, tex in viewitems(textures): if tex is not None: tex.release() for name, tex in viewitems(out_textures): if tex is not None: tex.release() for name, tex in viewitems(out_textures): shape = tex.shape tex.bind() loc = GL.glGetFragDataLocation(program.programId(), name) GL.glReadBuffer(self.get_texture_attachment(loc)) if shape[2] == 4: if tex.dtype == np.uint8: pixels = GL.glReadPixels( 0, 0, shape[0], shape[1], GL.GL_RGBA, GL.GL_UNSIGNED_INT_8_8_8_8) self.out_textures[tex] = pixels.view( np.uint8).reshape(shape[1], shape[0], 4) elif tex.dtype == np.float32: pixels = GL.glReadPixels(0, 0, shape[0], shape[1], GL.GL_RGBA, GL.GL_FLOAT) self.out_textures[tex] = pixels tex.release() except Exception as e: LoggingManager.instance().warning(traceback.format_exc()) finally: self.vertex_array.release() program.release() if self.render_to_texture_attachment != -1: shape = self.locked_render_to_texture_array.ndarray.shape self.locked_render_to_texture_array.___tex___.bind() GL.glReadBuffer( self.draw_buffers[self.render_to_texture_attachment]) r = GL.glReadPixels(0, 0, shape[0], shape[1], GL.GL_RGBA, GL.GL_UNSIGNED_INT_8_8_8_8) self.locked_render_to_texture_array.___tex___.release() self.locked_render_to_texture_array.ndarray = np.flipud( r.view(np.uint8).reshape(shape[1], shape[0], 4)[..., ::-1]) self.update()
def render3D(self, actors, pick=None): """Render the 3D actors in the scene. """ if not actors: return ## # Split off rendertype 1 ## actors1 = [ a for a in actors if a.rendertype == -1 ] ## actors = [ a for a in actors if a.rendertype != -1 ] # Get the current modelview*projection matrix modelview = self.camera.modelview projection = self.camera.projection transinv = self.camera.modelview.transinv().rot # Propagate the matrices to the uniforms of the shader self.shader.uniformMat4('modelview', modelview.gl()) self.shader.uniformMat4('projection', projection.gl()) self.shader.uniformMat3('normalstransform', transinv.flatten().astype(np.float32)) # sort actors in back and front, and select visible actors = back(actors) + front(actors) actors = [o for o in actors if o.visible is not False] GL.glEnable(GL.GL_DEPTH_TEST) GL.glDepthMask(GL.GL_TRUE) if pick: # PICK MODE from pyformex.opengl import camera pickmat = camera.pick_matrix(*pick) self.shader.uniformMat4('pickmat', pickmat.gl()) self.pickObjects(actors) elif not self.canvas.settings.alphablend: # NO ALPHABLEND self.renderObjects(actors) else: # ALPHABLEND # 2D actors are by default transparent! opaque = [a for a in actors if a.opak] transp = [a for a in actors if not a.opak] # First render the opaque objects self.renderObjects(opaque) # Then the transparent ones # Disable writing to the depth buffer # as everything behind the transparent object # also needs to be drawn GL.glDepthMask(GL.GL_FALSE) if pf.cfg['render/transp_nocull']: GL.glDisable(GL.GL_CULL_FACE) GL.glEnable(GL.GL_BLEND) GL.glBlendEquation(GL.GL_FUNC_ADD) if pf.cfg['render/alphablend'] == 'mult': GL.glBlendFunc(GL.GL_ZERO, GL.GL_SRC_COLOR) elif pf.cfg['render/alphablend'] == 'add': GL.glBlendFunc(GL.GL_ONE, GL.GL_ONE) elif pf.cfg['render/alphablend'] == 'trad1': GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE) else: GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA) self.renderObjects(transp) GL.glDisable(GL.GL_BLEND) ## if actors1: ## modelview = Matrix4() ## modelview[:3,:3] = self.camera.modelview.rot ## projection = perspective_matrix(-1, 0.5, -1, 0.5, 0.1, 10.) ## #self.shader.uniformMat4('modelview', modelview.gl()) ## self.shader.uniformMat4('projection', projection.gl()) ## self.renderObjects(actors1) GL.glDepthMask(GL.GL_TRUE)
def draw(self,d2s=None,col=None): """This function causes the shape to render itself into the current GL context. d2s is a function of x,y which will convert data coordinates to screen coordinates. For data coordinate shapes, only the positional information is in data coordinates, font size, line width, etcare in screen units. col can be used to override the current shape's color.""" # global glut_inited s=self.shape if s[0]=="hidden": return if col==None: col=self.shape[1:4] if d2s==None : d2s=shidentity v=d2s(s[4],s[5]) v2=d2s(s[4]+1,s[5]+1) sc=v2[0]-v[0] if self.isanimated: # print self.blend, "was the blend value" GL.glEnable(GL.GL_BLEND); depth_testing_was_on = GL.glIsEnabled(GL.GL_DEPTH_TEST); GL.glDisable(GL.GL_DEPTH_TEST); try:GL.glBlendEquation(GL.GL_FUNC_ADD) except:pass GL.glBlendFunc(GL.GL_SRC_ALPHA,GL.GL_ONE_MINUS_SRC_ALPHA); col=[self.shape[1],self.shape[2],self.shape[3],self.blend] if s[0]=="rect": assert self.shape[8] >= 0 GL.glLineWidth(s[8]) #if self.isanimated: #v1 = d2s(s[4],s[5]) #v2 = d2s(s[6],s[7]) #dx = (v1[0]+v2[0])/2.0 #dy = (v1[1]+v2[1])/2.0 #GL.glPushMatrix() #GL.glTranslate(dx,dy,0) #GL.glScale(self.blend,self.blend,1) #GL.glTranslate(-dx,-dy,0) GL.glBegin(GL.GL_LINE_LOOP) GL.glColor(*col) GL.glVertex(*d2s(s[4],s[5])) GL.glVertex(*d2s(s[6],s[5])) GL.glVertex(*d2s(s[6],s[7])) GL.glVertex(*d2s(s[4],s[7])) GL.glEnd() if s[0]=="rect4point": assert self.shape[12] >= 0 GL.glLineWidth(s[12]) GL.glBegin(GL.GL_LINE_LOOP) GL.glColor(*col) GL.glVertex(*d2s(s[4],s[5])) GL.glVertex(*d2s(s[6],s[7])) GL.glVertex(*d2s(s[8],s[9])) GL.glVertex(*d2s(s[10],s[11])) GL.glEnd() elif s[0]=="rectline": #This makes a rectangle based on a width and two points #The two points are the endpoints for the longer axis of symmetry #Those two points implicitly define the length #The width is a parameter and together with the two coordinates, defines the rectangle assert s[4] != s[6] or s[5] != s[7], "The endpoints cannot coincide" assert self.shape[8] >= 0, "The width must be positive" assert self.shape[9] >= 0, "The line-width must be positive" pt0 = (s[4], s[5]) #first coordinate pt1 = (s[6], s[7]) #second coordinate width = s[8] #width GL.glLineWidth(s[9]) #l_vect = (pt1[0]-pt0[0], pt1[1]-pt2[0]) #vector parallel to a longer side -- length vector w_vect = ( -(pt1[1]-pt0[1]), pt1[0]-pt0[0] ) #vector parallel to a shorter side -- width vector mag = sqrt(w_vect[0]**2 + w_vect[1]**2) w_uvect = (w_vect[0]/mag, w_vect[1]/mag) #unit vector parallel to a short side #vertices - add/subtract a vector of half the box width with w_uvect direction v1 = ( pt0[0]-w_uvect[0]*width/2.0, pt0[1]-w_uvect[1]*width/2.0 ) v2 = ( pt0[0]+w_uvect[0]*width/2.0, pt0[1]+w_uvect[1]*width/2.0 ) v3 = ( pt1[0]+w_uvect[0]*width/2.0, pt1[1]+w_uvect[1]*width/2.0 ) v4 = ( pt1[0]-w_uvect[0]*width/2.0, pt1[1]-w_uvect[1]*width/2.0 ) #rectangle GL.glLineWidth(1) GL.glBegin(GL.GL_LINE_LOOP) GL.glColor(*col) GL.glVertex(*d2s(*v1)) GL.glVertex(*d2s(*v2)) GL.glVertex(*d2s(*v3)) GL.glVertex(*d2s(*v4)) GL.glEnd() #line GL.glBegin(GL.GL_LINES) GL.glColor(*col) GL.glVertex(*d2s(*pt0)) GL.glVertex(*d2s(*pt1)) GL.glEnd() elif s[0]=="rectpoint": assert self.shape[8] >= 0 GL.glLineWidth(s[8]) GL.glPointSize(s[8]) #rectangle GL.glBegin(GL.GL_LINE_LOOP) GL.glColor(*col) GL.glVertex(*d2s(s[4],s[5])) GL.glVertex(*d2s(s[6],s[5])) GL.glVertex(*d2s(s[6],s[7])) GL.glVertex(*d2s(s[4],s[7])) GL.glEnd() #midpoint GL.glBegin(GL.GL_POINTS) p1 = d2s(s[4],s[5]) p2 = d2s(s[6],s[7]) GL.glVertex((p1[0]+p2[0])/2,(p1[1]+p2[1])/2) GL.glEnd() elif s[0]=="rcirclepoint": assert self.shape[8] >= 0 GL.glLineWidth(s[8]) GL.glPointSize(s[8]) #midpoint GL.glBegin(GL.GL_POINTS) p1 = d2s(s[4],s[5]) p2 = d2s(s[6],s[7]) GL.glVertex((p1[0]+p2[0])/2,(p1[1]+p2[1])/2) GL.glEnd() v2=d2s(s[6],s[7]) GL.glPushMatrix() GL.glColor(*col) #circle inscribed in the rectangle GL.glTranslate((v[0]+v2[0])/2.0,(v[1]+v2[1])/2.0,0) GL.glScalef((v2[0]-v[0])/2.0,(v2[1]-v[1])/2.0,1.0) GL.glCallList(EMShape.dlists) GL.glPopMatrix() elif s[0]=="rcircle": v2=d2s(s[6],s[7]) assert self.shape[8] >= 0 GL.glLineWidth(s[8]) GL.glPushMatrix() GL.glColor(*col) GL.glTranslate((v[0]+v2[0])/2.0,(v[1]+v2[1])/2.0,0) GL.glScalef((v2[0]-v[0])/2.0,(v2[1]-v[1])/2.0,1.0) GL.glCallList(EMShape.dlists) GL.glPopMatrix() elif s[0]=="point": GL.glColor(*col) GL.glPointSize(s[6]) p1 = d2s(s[4],s[5]) GL.glBegin(GL.GL_POINTS) GL.glVertex(p1[0],p1[1]) GL.glEnd() elif s[0]=="line": # print "A line ",s[4],s[5],s[6],s[7] # print "A line ",d2s(s[4],s[5]),d2s(s[6],s[7]) GL.glColor(*col) assert self.shape[8] >= 0 GL.glLineWidth(s[8]) GL.glBegin(GL.GL_LINES) GL.glVertex(*d2s(s[4],s[5])) GL.glVertex(*d2s(s[6],s[7])) GL.glEnd() elif s[0]=="mask": # print "A line ",s[4],s[5],s[6],s[7] # print "A line ",d2s(s[4],s[5]),d2s(s[6],s[7]) GL.glColor(*col) GL.glBegin(GL.GL_TRIANGLE_STRIP) GL.glVertex(*d2s(s[4],s[5])) GL.glVertex(*d2s(s[6],s[7])) GL.glVertex(*d2s(s[8],s[9])) GL.glVertex(*d2s(s[10],s[11])) GL.glVertex(*d2s(s[12],s[13])) GL.glVertex(*d2s(s[14],s[15])) GL.glVertex(*d2s(s[16],s[17])) GL.glVertex(*d2s(s[18],s[19])) #First Vertex GL.glVertex(*d2s(s[4],s[5])) GL.glVertex(*d2s(s[6],s[7])) GL.glEnd() elif s[0]=="linemask": assert self.shape[12] >= 0 GL.glLineWidth(s[12]) GL.glColor(*col) GL.glBegin(GL.GL_LINE_LOOP) GL.glVertex(*d2s(s[4],s[5])) GL.glVertex(*d2s(s[6],s[7])) GL.glVertex(*d2s(s[8],s[9])) GL.glVertex(*d2s(s[10],s[11])) GL.glEnd() elif s[0]=="label": if len(col)==4 : col=col[:3] GL.glPushMatrix() if EMShape.font_renderer != None : GL.glPushAttrib(GL.GL_ALL_ATTRIB_BITS) GL.glTranslate(v[0],v[1],.2) EMShape.font_renderer.set_face_size(int(s[7])) if s[8]<0 : # try for a sensible background color if col[0]+col[1]+col[2]>.4 and col[0]+col[1]+col[2]<.6 : bgcol=(0.0,0.0,0.0) else : bgcol = (1.0-col[0],1.0-col[1],1.0-col[2]) bbox = EMShape.font_renderer.bounding_box(s[6]) GLUtil.mx_bbox(bbox,col,bgcol) GL.glEnable(GL.GL_TEXTURE_2D) GL.glTexEnvi (GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE) GL.glColor(*col) EMShape.font_renderer.render_string(s[6]) GL.glPopAttrib() else : pass #if s[8]<0 : #GL.glColor(1.,1.,1.) #GL.glTranslate(v[0],v[1],0) #GL.glScalef(s[7]/100.0/sc,s[7]/100.0/sc,s[7]/100.0/sc) #GL.glLineWidth(-s[8]) #w=104.76*len(s[6]) #GL.glBegin(GL.GL_QUADS) #GL.glVertex(-10.,-33.0) #GL.glVertex(w+10.,-33.0) #GL.glVertex(w+10.,119.05) #GL.glVertex(-10.,119.05) #GL.glEnd() #GL.glColor(*col) #for i in s[6]: #GLUT.glutStrokeCharacter(GLUT.GLUT_STROKE_MONO_ROMAN,ord(i)) #else: #GL.glColor(*col) #GL.glTranslate(v[0],v[1],0) ## GL.glScalef(s[7]/100.0,s[7]/100.0,s[7]/100.0) #GL.glScalef(s[7]/100.0/sc,s[7]/100.0/sc,s[7]/100.0/sc) #GL.glLineWidth(fabs(s[8])) #for i in s[6]: #GLUT.glutStrokeCharacter(GLUT.GLUT_STROKE_ROMAN,ord(i)) GL.glPopMatrix() elif s[0]=="circle": # print s[6],v,v2 GL.glPushMatrix() GL.glColor(*col) GL.glLineWidth(s[7]) GL.glTranslate(v[0],v[1],0) GL.glScalef(s[6]*(v2[0]-v[0]),s[6]*(v2[1]-v[1]),1.0) GL.glCallList(EMShape.dlists) GL.glPopMatrix() elif s[0]=="ellipse": # print s[6],v,v2 GL.glPushMatrix() GL.glColor(*col) GL.glLineWidth(s[9]) GL.glTranslate(v[0],v[1],0) GL.glScalef((v2[0]-v[0]),(v2[1]-v[1]),1.0) GL.glRotatef(s[8],0,0,1.0) GL.glScalef(s[6],s[7],1.0) GL.glCallList(EMShape.dlists) GL.glPopMatrix() else: #mx=GL.glGetFloatv(GL.GL_MODELVIEW_MATRIX) GL.glPopMatrix() GL.glPushMatrix() if s[0]=="scrrect": x1 = int( round(s[4]) ) y1 = int( round(s[5]) ) x2 = int( round(s[6]) ) y2 = int( round(s[7]) ) GL.glLineWidth(s[8]) GL.glBegin(GL.GL_LINE_LOOP) GL.glColor(*col) GL.glVertex(x1,y1) GL.glVertex(x2,y1) GL.glVertex(x2,y2) GL.glVertex(x1,y2) GL.glEnd() elif s[0]=="scrline": x1 = int( round(s[4]) ) y1 = int( round(s[5]) ) x2 = int( round(s[6]) ) y2 = int( round(s[7]) ) GL.glColor(*col) assert self.shape[8] >= 0 GL.glLineWidth(s[8]) GL.glBegin(GL.GL_LINES) GL.glVertex(x1,y1) GL.glVertex(x2,y2) GL.glEnd() elif s[0]=="scrlabel": if len(col)==4 : col=col[:3] x1 = int( round(s[4]) ) y1 = int( round(s[5]) ) # if s[8]<0 : if EMShape.font_renderer != None : GL.glPushAttrib(GL.GL_ALL_ATTRIB_BITS) GL.glTranslate(x1,y1,.2) if s[8]<0 : # try for a sensible background color if col[0]+col[1]+col[2]>.4 and col[0]+col[1]+col[2]<.6 : bgcol=(0.0,0.0,0.0) else : bgcol = (1.0-col[0],1.0-col[1],1.0-col[2]) bbox = EMShape.font_renderer.bounding_box(s[6]) GLUtil.mx_bbox(bbox,col,(1.0-col[0],1.0-col[1],1.0-col[2])) GL.glEnable(GL.GL_TEXTURE_2D) GL.glTexEnvi (GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE) GL.glColor(*col) EMShape.font_renderer.render_string(s[6]) GL.glPopAttrib() else : pass #else: #GL.glColor(1.,1.,1.) #GL.glTranslate(x1,y1,0) ##GL.glScalef(s[7]/1500.0/sc,s[7]/1500.0/sc,s[7]/1500.0/sc) #GL.glScalef(s[7]/1500.0,s[7]/1500.0,1) #GL.glLineWidth(-s[8]) #w=104.76*len(text) #GL.glBegin(GL.GL_QUADS) #GL.glVertex(-10.,-33.0) #GL.glVertex(w+10.,-33.0) #GL.glVertex(w+10.,119.05) #GL.glVertex(-10.,119.05) #GL.glEnd() #GL.glTranslate(0,0,.1) #GL.glColor(*col) #for i in text: #GLUT.glutStrokeCharacter(GLUT.GLUT_STROKE_MONO_ROMAN,ord(i)) #else: #GL.glColor(*col) #GL.glTranslate(x1,y1,-1) ## GL.glScalef(y2/100.0,y2/100.0,y2/100.0) #GL.glScalef(s[7]/1500.0/sc,s[7]/1500.0/sc,1) #GL.glLineWidth(fabs(s[8])) #for i in text: #GLUT.glutStrokeCharacter(GLUT.GLUT_STROKE_ROMAN,ord(i)) elif s[0]=="scrcircle": x1 = int( round(s[4]) ) y1 = int( round(s[5]) ) GL.glColor(*col) GL.glLineWidth(s[7]) GL.glTranslate(x1,y1,0) GL.glScalef(s[6],s[6],s[6]) GL.glCallList(EMShape.dlists) #GL.glLoadMatrixf(mx) if self.isanimated: GL.glDisable( GL.GL_BLEND); if (depth_testing_was_on): GL.glEnable(GL.GL_DEPTH_TEST)
def on_draw(self, default_framebuffer, W, H, frame, time, mouse_down, mouse_press_pos, mouse_release_pos, mouse_move_pos, key, key_modifiers, plugins): # Bind gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, default_framebuffer) self.program.bind() self.vao.bind() self.index_buffer.bind() gl.glViewport(0, 0, W, H) # Enable capabilites last_capabilities = [] for capability in self.config.get('capabilities', []): last_capabilities += [gl.glIsEnabled(getattr(gl, capability))] gl.glEnable(getattr(gl, capability)) # Blend setting if self.config.get('blend'): gl.glEnable(gl.GL_BLEND) gl.glBlendEquation(gl.GL_FUNC_ADD) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) # TODO: for now it's so adhoc for plugin in plugins: plugin.on_bind_program(self.program.programId()) # Set uniform gl.glUniform1f(self.program.uniformLocation('iTime'), time) gl.glUniform1i(self.program.uniformLocation('iFrame'), frame) gl.glUniform3f(self.program.uniformLocation('iResolution'), W, H, W / H) gl.glUniform1ui(self.program.uniformLocation('iKey'), key) gl.glUniform1ui(self.program.uniformLocation('iKeyModifiers'), key_modifiers) mz, mw = mouse_press_pos or (0, H - 1) if mouse_down: mx, my = mouse_move_pos or (0, H - 1) my, mw = [H - 1 - t for t in [my, mw]] else: mx, my = mouse_release_pos or (0, H - 1) my, mw = [H - 1 - t for t in [my, mw]] mz, mw = [-t for t in [mz, mw]] gl.glUniform4f(self.program.uniformLocation('iMouse'), mx, my, mz, mw) # Draw call primitive = getattr(gl, self.config['primitive']) instance_count = self.config.get('instance_count', 1) if type(instance_count) == str: instance_count = eval(instance_count) gl.glDrawElementsInstanced(primitive, len(self.index_data), gl.GL_UNSIGNED_INT, ctypes.c_void_p(0), instance_count) # Reset capabilites for last, capability in zip(last_capabilities, self.config.get('capabilities', [])): if not last: gl.glDisable(getattr(gl, capability)) gl.glDisable(gl.GL_BLEND) # Release self.vao.release() self.program.release() gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
def OnDraw(self, fast=False): # Prepare by setting things to their defaults. This might release some # memory so result in a bigger chance that the shader is run in # hardware mode. On ATI, the line and point smoothing should be off # if you want to use gl_FragCoord. (Yeah, I do not see the connection # either...) gl.glPointSize(1) gl.glLineWidth(1) gl.glDisable(gl.GL_LINE_STIPPLE) gl.glDisable(gl.GL_LINE_SMOOTH) gl.glDisable(gl.GL_POINT_SMOOTH) # only draw front-facing parts gl.glEnable(gl.GL_CULL_FACE) gl.glCullFace(gl.GL_BACK) gl.glBlendFunc(gl.GL_ONE, gl.GL_ONE) gl.glBlendEquation(gl.GL_MAX) gl.glDisable(gl.GL_DEPTH_TEST) if self._program1.IsUsable(): self._program1.Enable() if fast: self._program1.SetUniformf('stepRatio', [0.4]) else: self._program1.SetUniformf('stepRatio', [1.0]) self._program1.SetUniformi('texture', [0]) self._colormap.Enable(1) self._program1.SetUniformi('colormap', [1]) # enable this texture t1 = time.time() for i,tex in enumerate(self._textures): tex.Enable(0) if not tex._shape: continue # fragment shader on # bind texture- and help-textures (create if it does not exist) # set uniforms: parameters shape = tex._shape # as in opengl self._program1.SetUniformf('shape',reversed(list(shape)) ) # do the actual drawing self._DrawQuads(tex, i) tex.Disable() # clean up gl.glFlush() t2 = time.time() print ("Rendering: %0.3e" % (t2-t1)) self._colormap.Disable() self._program1.Disable() # gl.glBlendEquation(gl.GL_FUNC_ADD) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) gl.glDisable(gl.GL_CULL_FACE) gl.glEnable(gl.GL_LINE_SMOOTH) gl.glEnable(gl.GL_POINT_SMOOTH) gl.glEnable(gl.GL_DEPTH_TEST)