def drawfont2(glpane, msg=None, charwidth=None, charheight=None, testpattern=False, pixelwidth=None): """ Draws a rect of chars (dimensions given as char counts: charwidth x charheight [#e those args are misnamed] using vv's font texture [later 061113: assumed currently bound, i think -- see ensure_courierfile_loaded()], in a klugy way; msg gives the chars to draw (lines must be shorter than charwidth or they will be truncated) """ _bind_courier_font_texture() # adjust these guessed params (about the specific font image we're using as # a texture) until they work right: # (tex_origin_chars appears lower down, since it is revised there) tex_size = (128, 128) # tex size in pixels tex_nx = 16 # number of chars in a row, in the tex image tex_ny = 8 # number of chars in a column if msg is None: msg = "(redraw %d)" % env.redraw_counter charwidth = tex_nx charheight = tex_ny + 1 lines = msg.split('\n') # tab not supported if charwidth is None: charwidth = 14 # could be max linelength plus 1 if charheight is None: charheight = len(lines) if not testpattern: while len(lines) < charheight: lines.append('') # draw individual chars from font-texture, # but first, try to position it so they look perfect (which worked for a # while, but broke sometime before 060728) ## glTranslatef( 0, pixelheight / 2, 0 ) # perfect! # (Ortho mode, home view, a certain window size -- not sure if that # matters but it might) # restoring last-saved window position (782, 44) and size (891, 749) ## gap = 2 # in pixels - good for debugging # good for looking nice! but note that idlehack uses one extra pixel of # vspace, and that does probably look better. gap = 0 # to do that efficiently i'd want another image to start from. # (or to modify this one to make the texture, by moving pixrects around) pixfactor = 1 # try *2... now i can see some fuzz... what if i start at origin, to draw? # Did that, got it tolerable for pixfactor 2, then back to 1 and i've lost # the niceness! Is it no longer starting at origin? ##pixelwidth = pixelheight = 0.05 * 2/3 #070124 revisions, general comment... current caveats/bugs: #### # - Only tested in Ortho mode. # - Working well but the bugs depend on whether we add "1 or" before # "pixelwidth is None" in if statement below: # Bugs when it computes pixelwidth here (even when passed, as always in # these tests): # - Textlabel for "current redraw" (in exprs/test.py bottom_left_corner) # disappears during highlighting. # Bugs when it doesn't [usual state & state I'll leave it in]: # - Not tested with displists off, maybe. ### # - Fuzzy text in testexpr_18 [not yet understood.] # - [fixed] Fuzzy text in "current redraw" textlabel during anything's # highlighting. [Fixed by removing DisplayListChunk from that.] # - [No bug in clarity of text in highlighted checkbox prefs themselves.] # - Works with displists on or off now. # - Is disable_translate helping?? Not sure (only matters when it computes # pixelwidth here -- not now.) # - ##e Use direct drawing_phase test instead? doesn't seem to be needed # anymore, from remaining bugs listed above. disable_translate = False #070124 #061211 permit caller to pass it [note: the exprs module usually or always # passes it, acc'd to test 070124] if pixelwidth is None: p1junk, p2a = mymousepoints(glpane, 10, 10) p1junk, p2b = mymousepoints(glpane, 11, 10) px, py, pz = vec = p2b - p2a # should be DX * pixelwidth ## print px,py,pz ### 0.0313971755382 0.0 0.0 (in Ortho mode, near but not at home view, ### also at it (??)) # 0.0313971755382 0.0 0.0 home ortho # 0.03139613018 0.0 0.0 home perspective -- still looks good (looks # the same) (with false "smoother textures") ## pixelwidth = pixelheight = px * pixfactor # 061211 Work better for rotated text (still not good unless # screen-parallel.) pixelwidth = pixelheight = vlen(vec) * pixfactor # print "pixelwidth",pixelwidth ####@@@@ can be one of: # 0.0319194157846 # or 0.0313961295259 # or 0.00013878006302 if pixelwidth < 0.01: # print "low pixelwidth:",pixelwidth, glpane.drawing_phase # e.g. 0.000154639183832 glselect pixelwidth = 0.0319194157846 ### kluge, in case you didn't notice [guess: formula is wrong during # highlighting] but this failed to fix the bug in which a TextRect # doesn't notice clicks unless you slide onto it from a Rect # ####@@@@ # Q 070124: when this happens (presumably due to small window in # glSelect) should we disable glTranslatef below? # I guess yes, so try it. Not that it'll help when we re-disable # always using this case. disable_translate = True # I'll leave this in since it seems right, but it's not obviously # helping by test. pass else: pixelheight = pixelwidth tex_origin_chars = V(3, 64) # revised 070124 #070124 -- note that disable_translate is never set given if statements #above -- if 1 and not disable_translate: ##e Use glpane.drawing_phase == 'glselect' instead? doesn't seem to ## be needed anymore, from remaining bugs listed above. # Translate slightly to make characters clearer (since we're still too # lazy to use glDrawPixels or whatever it's called). # Caveats: # - Assumes we're either not in a displist, or it's always drawn in the # same place. # - Will only work if we're drawing at correct depth for pixelwidth, I # presume -- and of course, parallel to screen. x, y, depth = gluProject(0.0, 0.0, 0.0) # Where we'd draw without any correction (ORIGIN). # Change x and y to a better place to draw (in pixel coords on screen.) # (note: This int(x+0.5) was compared by test to int(x) and int(x)+0.5 # -- this is best, as one might guess; not same for y...) ## if we need a "boldface kluge", using int(x)+0.5 here would be one... x = int(x + 0.5) ### NOT UNDERSTOOD: Why x & y differ, in whether it's best to add this ### 0.5. y = int(y + 0.5) + 0.5 # [btw I'd guessed y+0.5 in int() should be (y-0.5)+0.5 due to outer # +0.5, but that looks worse in checkbox_pref centering; I don't know # why.] # [later, 080521: could it be +0.5 effect differing for x & y due to # different sign, since int() rounds towards zero rather than # towards neginf? ### REVIEW: fix this using intRound?] # # Adding outer 0.5 to y became best after I fixed a bug of # translating before glu*Project (just before this if-statement), # which fails inside displists since the translate effect doesn't # show up in glu*Project then. # # I wonder if the x/y difference could be related to the use of # CenterY around TextRect inside displists, which ought to produce a # similar bug if the shift is not by an exact number of pixels # (which is surely the case since the caller is guessing pixelwidth # as a hardcoded constant, IIRC). So the guess is that caller's # pixelwidth is wrong and/or CenterY shifts by an odd number of # halfpixels, inside displist and not seen by this glu*Project, # causing a bug which this +0.5 sometimes compensates for, but not # always due to pixelwidth being wrong. It's not worth # understanding this compared to switching over to glDrawPixels or # whatever it's called. ###DO THAT SOMETIME. p1 = A(gluUnProject(x, y, depth)) # where we'd like to draw (p1) # Test following code -- with this line, it should make us draw # noticeably higher up the screen -- works. ## p1 += DY glTranslatef(p1[0], p1[1], p1[2]) # fyi: NameError if we try glTranslatefv or glTranslatev -- didn't # look for other variants or in gl doc. pass tex_dx = V(tex_width, 0) # in pixels tex_dy = V(0, tex_height) # Using those guesses, come up with tex-rects for each char as triples of # 2-vectors (tex_origin, tex_dx, tex_dy). # i for y, j or x (is that order normal??), still starting at bottom left def ff(i, j): """ Which char to draw at this position? i is y, going up, -1 is lowest line (sorry.) """ nlines = len(lines) bottom = -1 # Change this api sometime. # This one too -- caller ought to be able to use 0 or 1 for the top # (first) line. abovethat = i - bottom if abovethat < nlines: # Draw chars from lines. test = lines[nlines - 1 - abovethat] # Few-day(?)-old comment [as of 060728], not sure why it's # exactly here, maybe since this tells when we redraw, but it # might be correct other than that: this shows that mouseover of # objects (pixels) w/o glnames causes redraws! I understand # glselect ones, but they should not be counted, and should not # show up on the screen, so I don't understand any good reason # for these visible ones to happen. #e To try to find out, we could also record compact_stack of the # first gl_update that caused this redraw... if j < len(test): # Replace i,j with new ones so as to draw those chars instead. ch1 = ord(test[j]) - 32 j = ch1 % tex_nx i = 5 - (ch1 / tex_nx) else: # Draw a blank instead. ch1 = 32 - 32 j = ch1 % tex_nx i = 5 - (ch1 / tex_nx) else: # Use i,j to index the texture, meaning, draw test chars, perhaps # the entire thing. pass return tex_origin_chars + i * tex_dy + j * tex_dx, tex_dx, tex_dy # Now think about where to draw all this... use a gap, but otherwise the # same layout. charwidth1 = tex_width * pixelwidth charheight1 = tex_height * pixelheight char_dx = (tex_width + gap) * pixelwidth char_dy = (tex_height + gap) * pixelheight def gg(i, j): return (ORIGIN + j * char_dx * DX + (i + 1) * char_dy * DY, charwidth1 * DX, charheight1 * DY) # Now draw them. if 1: #### for n in range(65): # Simulate delay of a whole page of chars. # Note, this is significantly slow even if we just draw 5x as many # chars! (range was -1,tex_ny == 8, length 9) - Note, increasing i goes # up on screen, not down! for i in range(-1, charheight - 1): for j in range(charwidth): # Was tex_nx == 16 origin, dx, dy = gg(i, j) # Where to draw this char ###k # Still in pixel ints. # What tex coords to use to find it? tex_origin, ltex_dx, ltex_dy = ff(i, j) # Kluge until i look up how to use pixels directly. tex_origin, ltex_dx, ltex_dy = 1.0/tex_size[0] \ * V(tex_origin, ltex_dx, ltex_dy) #print (origin, dx, dy, tex_origin, tex_dx, tex_dy) # Cool bug effect bfr 'l's here. draw_textured_rect(origin, dx, dy, tex_origin, ltex_dx, ltex_dy) # draw some other ones? done above, with test string inside ff function. # Interesting q -- if i use vertex arrays or displist-index arrays, can # drawing 10k chars be fast? (guess: yes.) # Some facts: this window now has 70 lines, about 135 columns... of course # it's mostly blank, and in fact just now it has about 3714 chars, not 70 * # 135 = 9450 as if it was nowhere blank. # Above we draw 9 * 16 = 144, so ratio is 3714 / 144 = 25, or 9450 / 144 = # 65. # Try 65 redundant loops above & see what happens. It takes it a couple # seconds! Too slow! Of course it's mostly the py code. # Anyway, it means we *will* have to do one of those optims mentioned, or # some other one like not clearing/redrawing the entire screen during most # text editing, or having per-line display lists. glpane.kluge_reset_texture_mode_to_work_around_renderText_bug() return #drawfont2 #e rename, clean up
def draw(self): # bind texture for image filename [#e or other image object], # doing whatever is needed of allocating texture name, loading image object, loading texture data; ###e optim: don't call glBindTexture if it's already bound, and/or have a "raw draw" which assumes it's already bound if 'workaround bug in formula for texture_options': texture_options = dict(clamp = self.clamp, pixmap = self.pixmap, use_mipmaps = self.use_mipmaps, decal = self.decal) else: texture_options = self.texture_options # never used, but desired once bug is fixed self.bind_texture( **texture_options) try: # figure out texture coords (from optional args, not yet defined ###e) -- stub for now nreps = float(self.nreps) # float won't be needed once we have type coercion; not analyzed whether int vs float matters in subr ## tex_origin = ORIGIN2 # see also testdraw's drawtest1, still used in testmode to draw whole font texture rect tex_origin = V(self.tex_origin[0], self.tex_origin[1]) ## tex_dx = D2X ; tex_dx *= nreps # this modifies a shared, mutable Numeric array object, namely D2X! Not what I wanted. tex_dx = D2X * nreps tex_dy = D2Y * nreps # where to draw it -- act like a 2D Rect for now, determined by self's lbox, # which presently comes from self.size origin = V(-self.bleft, -self.bbottom, 0) # see also the code in drawfont2 which tweaks the drawing position to improve the pixel alignment # (in a way which won't work right inside a display list if any translation occurred before now in that display list) # in case we want to offer that option here someday [070124 comment] ## dx = DX * self.bright ## dy = DY * self.btop dx = DX * (self.bleft + self.bright) # bugfix 070304: include bleft, bbottom here dy = DY * (self.bbottom + self.btop) blend = self.blend alpha_test = self.alpha_test two_sided = self.two_sided shape = self.shape # for now, None or a symbolic string (choices are hardcoded below) if blend: glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) if alpha_test: glEnable(GL_ALPHA_TEST) # (red book p.462-463) glAlphaFunc(GL_GREATER, 0.0) # don't draw the fully transparent parts into the depth or stencil buffers ##e maybe let that 0.0 be an option? eg the value of alpha_test itself? Right now, it can be False ~== 0 (not None). if two_sided: glDisable(GL_CULL_FACE) if not shape: draw_textured_rect( origin, dx, dy, tex_origin, tex_dx, tex_dy) else: # support sub-shapes of the image rect, but with unchanged texture coords relative to the whole rect [070404 ###UNTESTED] if type(shape) == type(""): ##e use an external shape name->value mapping? # in fact, should such a mapping be part of the dynamic graphics-instance env (self.env)?? if shape == 'upper-left-half': shape = ((0,0), (1,1), (0,1)) elif shape == 'lower-right-half': shape = ((0,0), (1,0), (1,1)) elif shape == 'upper-right-half': #070628 shape = ((0,1), (1,0), (1,1)) elif shape == 'lower-left-half': #070628; untested shape = ((0,0), (1,0), (0,1)) else: assert 0, "in %r, don't know this shape name: %r" % (self, shape) # otherwise assume it might be the right form to pass directly # (list of 3 2d points in [0,1] x [0,1] relative coords -- might need to be in CCW winding order) draw_textured_rect_subtriangle( origin, dx, dy, tex_origin, tex_dx, tex_dy, shape ) pass if blend: glDisable(GL_BLEND) if alpha_test: glDisable(GL_ALPHA_TEST) if two_sided: glEnable(GL_CULL_FACE) finally: self.kluge_reset_texture_mode_to_work_around_renderText_bug() return # from Image.draw
def drawfont2(glpane, msg = None, charwidth = None, charheight = None, testpattern = False, pixelwidth = None): """ Draws a rect of chars (dimensions given as char counts: charwidth x charheight [#e those args are misnamed] using vv's font texture [later 061113: assumed currently bound, i think -- see ensure_courierfile_loaded()], in a klugy way; msg gives the chars to draw (lines must be shorter than charwidth or they will be truncated) """ _bind_courier_font_texture() # adjust these guessed params (about the specific font image we're using as # a texture) until they work right: # (tex_origin_chars appears lower down, since it is revised there) tex_size = (128,128) # tex size in pixels tex_nx = 16 # number of chars in a row, in the tex image tex_ny = 8 # number of chars in a column if msg is None: msg = "(redraw %d)" % env.redraw_counter charwidth = tex_nx charheight = tex_ny + 1 lines = msg.split('\n') # tab not supported if charwidth is None: charwidth = 14 # could be max linelength plus 1 if charheight is None: charheight = len(lines) if not testpattern: while len(lines) < charheight: lines.append('') # draw individual chars from font-texture, # but first, try to position it so they look perfect (which worked for a # while, but broke sometime before 060728) ## glTranslatef( 0, pixelheight / 2, 0 ) # perfect! # (Ortho mode, home view, a certain window size -- not sure if that # matters but it might) # restoring last-saved window position (782, 44) and size (891, 749) ## gap = 2 # in pixels - good for debugging # good for looking nice! but note that idlehack uses one extra pixel of # vspace, and that does probably look better. gap = 0 # to do that efficiently i'd want another image to start from. # (or to modify this one to make the texture, by moving pixrects around) pixfactor = 1 # try *2... now i can see some fuzz... what if i start at origin, to draw? # Did that, got it tolerable for pixfactor 2, then back to 1 and i've lost # the niceness! Is it no longer starting at origin? ##pixelwidth = pixelheight = 0.05 * 2/3 #070124 revisions, general comment... current caveats/bugs: #### # - Only tested in Ortho mode. # - Working well but the bugs depend on whether we add "1 or" before # "pixelwidth is None" in if statement below: # Bugs when it computes pixelwidth here (even when passed, as always in # these tests): # - Textlabel for "current redraw" (in exprs/test.py bottom_left_corner) # disappears during highlighting. # Bugs when it doesn't [usual state & state I'll leave it in]: # - Not tested with displists off, maybe. ### # - Fuzzy text in testexpr_18 [not yet understood.] # - [fixed] Fuzzy text in "current redraw" textlabel during anything's # highlighting. [Fixed by removing DisplayListChunk from that.] # - [No bug in clarity of text in highlighted checkbox prefs themselves.] # - Works with displists on or off now. # - Is disable_translate helping?? Not sure (only matters when it computes # pixelwidth here -- not now.) # - ##e Use direct drawing_phase test instead? doesn't seem to be needed # anymore, from remaining bugs listed above. disable_translate = False #070124 #061211 permit caller to pass it [note: the exprs module usually or always # passes it, acc'd to test 070124] if pixelwidth is None: p1junk, p2a = mymousepoints(glpane, 10, 10) p1junk, p2b = mymousepoints(glpane, 11, 10) px,py,pz = vec = p2b - p2a # should be DX * pixelwidth ## print px,py,pz ### 0.0313971755382 0.0 0.0 (in Ortho mode, near but not at home view, ### also at it (??)) # 0.0313971755382 0.0 0.0 home ortho # 0.03139613018 0.0 0.0 home perspective -- still looks good (looks # the same) (with false "smoother textures") ## pixelwidth = pixelheight = px * pixfactor # 061211 Work better for rotated text (still not good unless # screen-parallel.) pixelwidth = pixelheight = vlen(vec) * pixfactor # print "pixelwidth",pixelwidth ####@@@@ can be one of: # 0.0319194157846 # or 0.0313961295259 # or 0.00013878006302 if pixelwidth < 0.01: # print "low pixelwidth:",pixelwidth, glpane.drawing_phase # e.g. 0.000154639183832 glselect pixelwidth = 0.0319194157846 ### kluge, in case you didn't notice [guess: formula is wrong during # highlighting] but this failed to fix the bug in which a TextRect # doesn't notice clicks unless you slide onto it from a Rect # ####@@@@ # Q 070124: when this happens (presumably due to small window in # glSelect) should we disable glTranslatef below? # I guess yes, so try it. Not that it'll help when we re-disable # always using this case. disable_translate = True # I'll leave this in since it seems right, but it's not obviously # helping by test. pass else: pixelheight = pixelwidth tex_origin_chars = V(3, 64) # revised 070124 #070124 -- note that disable_translate is never set given if statements #above -- if 1 and not disable_translate: ##e Use glpane.drawing_phase == 'glselect' instead? doesn't seem to ## be needed anymore, from remaining bugs listed above. # Translate slightly to make characters clearer (since we're still too # lazy to use glDrawPixels or whatever it's called). # Caveats: # - Assumes we're either not in a displist, or it's always drawn in the # same place. # - Will only work if we're drawing at correct depth for pixelwidth, I # presume -- and of course, parallel to screen. x,y,depth = gluProject(0.0, 0.0, 0.0) # Where we'd draw without any correction (ORIGIN). # Change x and y to a better place to draw (in pixel coords on screen.) # (note: This int(x+0.5) was compared by test to int(x) and int(x)+0.5 # -- this is best, as one might guess; not same for y...) ## if we need a "boldface kluge", using int(x)+0.5 here would be one... x = int(x+0.5) ### NOT UNDERSTOOD: Why x & y differ, in whether it's best to add this ### 0.5. y = int(y+0.5)+0.5 # [btw I'd guessed y+0.5 in int() should be (y-0.5)+0.5 due to outer # +0.5, but that looks worse in checkbox_pref centering; I don't know # why.] # [later, 080521: could it be +0.5 effect differing for x & y due to # different sign, since int() rounds towards zero rather than # towards neginf? ### REVIEW: fix this using intRound?] # # Adding outer 0.5 to y became best after I fixed a bug of # translating before glu*Project (just before this if-statement), # which fails inside displists since the translate effect doesn't # show up in glu*Project then. # # I wonder if the x/y difference could be related to the use of # CenterY around TextRect inside displists, which ought to produce a # similar bug if the shift is not by an exact number of pixels # (which is surely the case since the caller is guessing pixelwidth # as a hardcoded constant, IIRC). So the guess is that caller's # pixelwidth is wrong and/or CenterY shifts by an odd number of # halfpixels, inside displist and not seen by this glu*Project, # causing a bug which this +0.5 sometimes compensates for, but not # always due to pixelwidth being wrong. It's not worth # understanding this compared to switching over to glDrawPixels or # whatever it's called. ###DO THAT SOMETIME. p1 = A(gluUnProject(x, y, depth)) # where we'd like to draw (p1) # Test following code -- with this line, it should make us draw # noticeably higher up the screen -- works. ## p1 += DY glTranslatef( p1[0], p1[1], p1[2]) # fyi: NameError if we try glTranslatefv or glTranslatev -- didn't # look for other variants or in gl doc. pass tex_dx = V(tex_width, 0) # in pixels tex_dy = V(0, tex_height) # Using those guesses, come up with tex-rects for each char as triples of # 2-vectors (tex_origin, tex_dx, tex_dy). # i for y, j or x (is that order normal??), still starting at bottom left def ff(i,j): """ Which char to draw at this position? i is y, going up, -1 is lowest line (sorry.) """ nlines = len(lines) bottom = -1 # Change this api sometime. # This one too -- caller ought to be able to use 0 or 1 for the top # (first) line. abovethat = i - bottom if abovethat < nlines: # Draw chars from lines. test = lines[nlines-1 - abovethat] # Few-day(?)-old comment [as of 060728], not sure why it's # exactly here, maybe since this tells when we redraw, but it # might be correct other than that: this shows that mouseover of # objects (pixels) w/o glnames causes redraws! I understand # glselect ones, but they should not be counted, and should not # show up on the screen, so I don't understand any good reason # for these visible ones to happen. #e To try to find out, we could also record compact_stack of the # first gl_update that caused this redraw... if j < len(test): # Replace i,j with new ones so as to draw those chars instead. ch1 = ord(test[j]) - 32 j = ch1 % tex_nx i = 5 - (ch1 / tex_nx) else: # Draw a blank instead. ch1 = 32 - 32 j = ch1 % tex_nx i = 5 - (ch1 / tex_nx) else: # Use i,j to index the texture, meaning, draw test chars, perhaps # the entire thing. pass return tex_origin_chars + i * tex_dy + j * tex_dx , tex_dx, tex_dy # Now think about where to draw all this... use a gap, but otherwise the # same layout. charwidth1 = tex_width * pixelwidth charheight1 = tex_height * pixelheight char_dx = (tex_width + gap) * pixelwidth char_dy = (tex_height + gap) * pixelheight def gg(i,j): return (ORIGIN + j * char_dx * DX + (i + 1) * char_dy * DY, charwidth1 * DX, charheight1 * DY) # Now draw them. if 1: #### for n in range(65): # Simulate delay of a whole page of chars. # Note, this is significantly slow even if we just draw 5x as many # chars! (range was -1,tex_ny == 8, length 9) - Note, increasing i goes # up on screen, not down! for i in range(-1, charheight - 1): for j in range(charwidth): # Was tex_nx == 16 origin, dx, dy = gg(i,j) # Where to draw this char ###k # Still in pixel ints. # What tex coords to use to find it? tex_origin, ltex_dx, ltex_dy = ff(i,j) # Kluge until i look up how to use pixels directly. tex_origin, ltex_dx, ltex_dy = 1.0/tex_size[0] \ * V(tex_origin, ltex_dx, ltex_dy) #print (origin, dx, dy, tex_origin, tex_dx, tex_dy) # Cool bug effect bfr 'l's here. draw_textured_rect(origin, dx, dy, tex_origin, ltex_dx, ltex_dy) # draw some other ones? done above, with test string inside ff function. # Interesting q -- if i use vertex arrays or displist-index arrays, can # drawing 10k chars be fast? (guess: yes.) # Some facts: this window now has 70 lines, about 135 columns... of course # it's mostly blank, and in fact just now it has about 3714 chars, not 70 * # 135 = 9450 as if it was nowhere blank. # Above we draw 9 * 16 = 144, so ratio is 3714 / 144 = 25, or 9450 / 144 = # 65. # Try 65 redundant loops above & see what happens. It takes it a couple # seconds! Too slow! Of course it's mostly the py code. # Anyway, it means we *will* have to do one of those optims mentioned, or # some other one like not clearing/redrawing the entire screen during most # text editing, or having per-line display lists. return #drawfont2 #e rename, clean up
def draw(self): # bind texture for image filename [#e or other image object], # doing whatever is needed of allocating texture name, loading image object, loading texture data; ###e optim: don't call glBindTexture if it's already bound, and/or have a "raw draw" which assumes it's already bound if 'workaround bug in formula for texture_options': texture_options = dict(clamp=self.clamp, pixmap=self.pixmap, use_mipmaps=self.use_mipmaps, decal=self.decal) else: texture_options = self.texture_options # never used, but desired once bug is fixed self.bind_texture(**texture_options) try: # figure out texture coords (from optional args, not yet defined ###e) -- stub for now nreps = float( self.nreps ) # float won't be needed once we have type coercion; not analyzed whether int vs float matters in subr ## tex_origin = ORIGIN2 # see also testdraw's drawtest1, still used in testmode to draw whole font texture rect tex_origin = V(self.tex_origin[0], self.tex_origin[1]) ## tex_dx = D2X ; tex_dx *= nreps # this modifies a shared, mutable Numeric array object, namely D2X! Not what I wanted. tex_dx = D2X * nreps tex_dy = D2Y * nreps # where to draw it -- act like a 2D Rect for now, determined by self's lbox, # which presently comes from self.size origin = V(-self.bleft, -self.bbottom, 0) # see also the code in drawfont2 which tweaks the drawing position to improve the pixel alignment # (in a way which won't work right inside a display list if any translation occurred before now in that display list) # in case we want to offer that option here someday [070124 comment] ## dx = DX * self.bright ## dy = DY * self.btop dx = DX * (self.bleft + self.bright ) # bugfix 070304: include bleft, bbottom here dy = DY * (self.bbottom + self.btop) blend = self.blend alpha_test = self.alpha_test two_sided = self.two_sided shape = self.shape # for now, None or a symbolic string (choices are hardcoded below) if blend: glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) if alpha_test: glEnable(GL_ALPHA_TEST) # (red book p.462-463) glAlphaFunc( GL_GREATER, 0.0 ) # don't draw the fully transparent parts into the depth or stencil buffers ##e maybe let that 0.0 be an option? eg the value of alpha_test itself? Right now, it can be False ~== 0 (not None). if two_sided: glDisable(GL_CULL_FACE) if not shape: draw_textured_rect(origin, dx, dy, tex_origin, tex_dx, tex_dy) else: # support sub-shapes of the image rect, but with unchanged texture coords relative to the whole rect [070404 ###UNTESTED] if type(shape) == type(""): ##e use an external shape name->value mapping? # in fact, should such a mapping be part of the dynamic graphics-instance env (self.env)?? if shape == 'upper-left-half': shape = ((0, 0), (1, 1), (0, 1)) elif shape == 'lower-right-half': shape = ((0, 0), (1, 0), (1, 1)) elif shape == 'upper-right-half': #070628 shape = ((0, 1), (1, 0), (1, 1)) elif shape == 'lower-left-half': #070628; untested shape = ((0, 0), (1, 0), (0, 1)) else: assert 0, "in %r, don't know this shape name: %r" % ( self, shape) # otherwise assume it might be the right form to pass directly # (list of 3 2d points in [0,1] x [0,1] relative coords -- might need to be in CCW winding order) draw_textured_rect_subtriangle(origin, dx, dy, tex_origin, tex_dx, tex_dy, shape) pass if blend: glDisable(GL_BLEND) if alpha_test: glDisable(GL_ALPHA_TEST) if two_sided: glEnable(GL_CULL_FACE) finally: self.kluge_reset_texture_mode_to_work_around_renderText_bug() return # from Image.draw