Forums Archived

The forums are being archived. See this topic for more information.

SFont not transparent

Get help and support with Rubygame

SFont not transparent

Postby XPac27 » Wed Jul 07, 2010 9:02 pm

Hi !

I'm trying to use Rubygame::SFont to display text but I can't find a way to make the font transparent (so there is not black boxes behind each letter). As written in the doc: The image file should contain ... the colorkey color at the bottom-left pixel ... The colorkey color is applied to the image file when it is loaded, so that all pixels of that color appear transparent. I'm using the image given in the Rubygame's samples folder term16.png which is a SFont-compatible file and seams ok, but it does not work (see result).

Here is the code I run from the samples folder:
Code: Select all
require "rubygems"
require "rubygame"
require "rubygame/sfont"
include Rubygame

def main(*args)
  font_name = ""

   if args.length < 1
    font_name = "term16.png"
      puts <<EOF
You can pass the filename of a SFont-compatible font as the
first argument to try it, e.g.: ./demo_sfont.rb my_font.png

There are many sample fonts available online:   
http://user.cs.tu-berlin.de/~karlb/sfont/fonts.html
EOF
  else
    font_name = args[0]
   end

  screen = Screen.open([700,400])
  queue = EventQueue.new()
  queue.ignore = [ActiveEvent,MouseMotionEvent,MouseUpEvent,MouseDownEvent,KeyDownEvent]


  screen.title = "SFont Test (%s)"%font_name
  screen.draw_circle_s([100, 100], 200, [255,255,0])
  font = SFont.new(font_name)
  renders = []
  renders << font.render("This font is: %s"%font_name)
  renders << font.render("I say, \"I love pie!\"")
  renders << font.render("I could eat #{Math::PI} pies.")
  renders << font.render("0 1 2 3 4 5 6 7 8 9")
  renders << font.render("!@\#$%^&*()[]{}<>;:/\\+=-_'`\"")
  renders << font.render("abcdefghijklmnopqrstuvwxyz")
  renders << font.render("ABCDEFGHIJKLMNOPQRSTUVWXYZ")

  (renders.length).times do |i|
    renders[i].blit(screen,[10,10+font.height*i])
  end
  screen.update()

      queue.wait()
end

main(*ARGV)


Is it a known bug ? or does any body know how to fix this kind of issue ?

Thanks in advence :)
User avatar
XPac27
 
Posts: 3
Joined: Wed Jul 07, 2010 8:44 pm

Re: SFont not transparent

Postby jacius » Thu Jul 08, 2010 4:35 am

You're right. This is a known issue, but it slipped through the cracks. I've set a reminder for myself to make sure I fix it for Rubygame 2.7.

The problem is related to a long-time bug that new Surfaces couldn't be created fully transparent. Instead, the new surfaces would be created filled with black. Since SFont created a new surface for each of the glyphs, those glyphs had black backgrounds.

I have a solution for that, plus some other enhancements for SFont, but I never got around to releasing them. So, thanks for the reminder!
User avatar
jacius
Site Admin
 
Posts: 131
Joined: Fri Feb 06, 2009 11:13 pm

Re: SFont not transparent

Postby XPac27 » Thu Jul 08, 2010 8:24 am

Cool ! I can't wait for 2.7 then :)

I also noticed that any image loaded by a surface has no red channel. It's the same for SFont, look on my screenshot the text supposed to be white is cyan. Maybe that as something to see with some RGBA vs ARGB stuff ... don't know ^^
User avatar
XPac27
 
Posts: 3
Joined: Wed Jul 07, 2010 8:44 pm

Re: SFont not transparent

Postby jacius » Thu Jul 08, 2010 9:36 pm

XPac27 wrote:I also noticed that any image loaded by a surface has no red channel. It's the same for SFont, look on my screenshot the text supposed to be white is cyan. Maybe that as something to see with some RGBA vs ARGB stuff ... don't know ^^

Strange, the screenshot you posted looks right to me. The SFont text is white on my computer. If you draw white shapes, do they also appear cyan on your computer?
User avatar
jacius
Site Admin
 
Posts: 131
Joined: Fri Feb 06, 2009 11:13 pm

Re: SFont not transparent

Postby XPac27 » Sun Jul 11, 2010 5:00 pm

I'm sorry, I got confused. :?
I don't have color issue with the sfont demo. In fact this color issue occures when I use sfont with OpenGL : example.

I followed the instruction from the documentation using the pixel method. Loading any image results on missing red channel (sfont images or other kind of images). I test directly with a surface object loading JPG, PNG and tried several type of compression setting but the result is allways the same: pictures are red-less when opengl display them. I noticed that the colorkey is not working too. Drawing white rectangles (like the one on the screenshot) works, so I think the problem is related to the pixel method.

Here is the code I use to display SFont in OpenGL:
Code: Select all
class Text

  def initialize
    sfont = SFont.new 'game/media/font/term16.png'
    @letters = {}

    SFont::default_glyphs.each{|item|
      surface = sfont.render(item)
      #surface.set_colorkey [0,0,0,255]     # attempt to force colorkey
      #surface = surface.to_display_alpha   # attempt to force alpha
      @letters[item] = {
        :surface => surface,
        :width   => sfont.string_width(item)
      }
    }
  end

  def print x, y, string
    glColor3f 1, 1, 1

    glPushMatrix
      glTranslatef x, y, 0

      string.each_char {|char|
        if @letters[char]
          glTranslatef    @letters[char][:width], 0, 0
          glBindTexture   GL_TEXTURE_2D, glGenTextures(1)[0]
          glTexImage2D    GL_TEXTURE_2D, 0, GL_RGBA, @letters[char][:surface].w, @letters[char][:surface].h, 0, GL_RGBA, GL_UNSIGNED_BYTE, @letters[char][:surface].pixels
          glTexParameter  GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR
          glTexParameter  GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST
          glEnable        GL_TEXTURE_2D
          glBegin         GL_QUADS
            glTexCoord2i  1,                       0
            glVertex2i    @letters[char][:width],  0
            glTexCoord2i  1,                       1
            glVertex2i    @letters[char][:width],  16
            glTexCoord2i  0,                       1
            glVertex2i    0,                       16
            glTexCoord2i  0,                       0
            glVertex2i    0,                       0
          glEnd
          glDeleteTextures 1
        else
          glTranslatef 10, 0, 0
        end
      }

    glPopMatrix
  end

end


The sfont file is loaded during the initialize (it's the same than the one I talked about in my post above) and surfaces are rendered and stored in an object. The print methode is called from the main class in the draw method :
Code: Select all
  def draw
    #ObjectSpace.garbage_collect

    glViewport 0, 0, 800, 600
    glMatrixMode GL_PROJECTION
    glLoadIdentity
    glOrtho 0, 800, 600, 0, -1, 1
    glMatrixMode GL_MODELVIEW
    glLoadIdentity
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    @game.draw
    @text.print('hello')

    GL.swap_buffers

    $screen.title = 'FPS: ' + $clock.framerate.to_i.to_s
  end


basically : transparency does not work in normal mod, and color + transparency are not ok when using surface and opengl on any kind of image.
I'm still trying to find a solution ... let me know if you know it :)
User avatar
XPac27
 
Posts: 3
Joined: Wed Jul 07, 2010 8:44 pm


Return to Help & Support

Who is online

Users browsing this forum: No registered users and 1 guest

cron