Example #1
0
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
Example #2
0
    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
Example #3
0
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
Example #4
0
    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