Archive for the ‘LUA’ Category

Generation of high quality bitmap fonts

here is how to quickly and automatically generate bitmap fonts with an alpha channel, providing a perfect anti-aliasing on any background. Any vector font can be used and combined with an infinity of graphic effects.

The software that does 99% of the job is ImageMagick, a free, open-source image processing tool that I consider as a « GUI-less Photoshop » : as powerful as Adobe’s product, ImageMagick is used only from another program, or even from the shell. Install it urgently.

Below is the small batch file that creates a few files containing words including the font.png with the « font » text used in the image above :

@echo off
rem Function: Create transparent background, aliased texts from a list of words
rem Author: Philippe Guglielmetti
rem Requires: ImageMagick v.6 or later (www.imagemagick.org)
set texts=OK Abort Cancel font "This is Great !"
set params=-background none -font Bauhaus-93 -pointsize 72 -density 300 -fill blue -blur 0x5
for %%a in (%texts%) do convert.exe %params% label:%%a %%a.png
set texts=
set params=

« params » define the font to create:

  • -background none is mandatory to draw the font on a transparent background (alpha channel)
  • -font Bauhaus-93 defines the vector font to use (its name is sometimes not the same as the one displayed in Windows « Fonts » folder…)
  • -pointsize 72 -density 300 specifies the font should be 72pt high on a 300dpi device. The bitmap size will therefore be larger on screen, but it can be printed or used as a texture in a 3D game or a Demoniak3D demo with a perfect quality.
  • -fill blue -blur 0x5 are two basic effects : the symbol is filled with blue, and its contour (1 pixel of black by default) is slightly blured on 5 pixels. This creates semi-transparent pixels at the symbols borders, which enables a perfect superimposition whatever the background color, as shown on the zoom right:

To superimpose the text on a background texture for a quality check, another ImageMagick is called:

composite.exe -tile back.png -compose Dst_Over font.png test.jpg

Once the test passed, we can generate all the chars of the font. When only a few symbols are required, we could re-use the batch file above, definining for exemple

set texts=0 1 2 3 4 5 6 7 8 9

This can be cumbersome for a complete font, and for application programming reasons it might be useful to name the files by the ASCII code of each char. As this is not possible to code in Windows batch language, we have to code it in a real language such as LUA:

params="-background none -font Bauhaus-93 -pointsize 72 -density 300 -fill white -blur 0x5 "
for i=32,167 do
os.execute("convert.exe "..params.."label:"..string.char(i).." "..i..".png")
end

These 4 lines automatically generate 130 files of nice symbols ready to be loaded as textures in your game. Note that these files total about 10 Mb au total, more than ImageMagick. It might therefore be worth to consider including ImageMagick in your product and use it at insall time to generate the required fonts instead of creating a heavy distribution

Now, if the fonts above are a bit rough for you, have a look at  this page which will give you some idea of the possible effects, and explore this one for the full picture.

Publicités

Génération de polices bitmap de haute qualité

Voici comment générer rapidement et automatiquement des polices de caractères bitmap avec canal alpha, donnant un anti-aliasing parfait quel que soit la texture de fond utilisée. Toutes les polices vectorielles peuvent être utilisées et combinées avec une infinité d’effets graphiques.

Le logiciel réalisant 99% du travail est ImageMagick, un programme de traitement d’images open-source gratuit que je considère comme un « Photoshop sans GUI » : aussi puissant que l’outil d’Adobe, ImageMagick s’utilise uniquement depuis un autre programme, voire simplement la ligne de commande du shell. A installer d’urgence.

Voici par exemple le petit fichier batch qui crée quelques fichiers contenant des mots, dont le fichier font.png contenant le mot « font » de l’image ci-dessus :

@echo off
rem Function: Create transparent background, aliased texts from a list of words
rem Author: Philippe Guglielmetti
rem Requires: ImageMagick v.6 or later (www.imagemagick.org)
set texts=OK Abort Cancel font "This is Great !"
set params=-background none -font Bauhaus-93 -pointsize 72 -density 300 -fill blue -blur 0x5
for %%a in (%texts%) do convert.exe %params% label:%%a %%a.png
set texts=
set params=

Les « params » définissent la police à réaliser:

  • -background none est essentiel pour dessiner la police sur un fond transparent (canal alpha)
  • -font Bauhaus-93 définit la police vectorielle à utiliser (dont le nom n’est parfois pas identique à celui apparaissant dans le dossier « Fonts » de Windows…)
  • -pointsize 72 -density 300 spécifient que la police doit faire 72pt de haut à 300dpi. La taille du bitmap sera donc supérieure à l’écran, mais il pourra être imprimé ou utilisé comme texture dans un jeu 3D ou une démo Demoniak3D avec un résultat d’excellente qualité
  • -fill blue -blur 0x5 sont deux petits effets de base : on remplit le caractère en bleu, et on adoucit le tracé de la lettre, qui est d’un pixel de noir par défaut. Ceci crée des pixels semi-transparents au bord des caractères, ce qui permet une découpe parfaite des caractères quel que soit le fond, comme on le voit sur le zoom ci-contre:

Pour placer la police sur la texture de fond afin de vérifier sa qualité, on utilise un autre module d’ImageMagick;

composite.exe -tile back.png -compose Dst_Over font.png test.jpg

Une fois ce test réalisé, on peut s’attaquer à la génération de tous les caractères de la police. Si seuls quelques caractères sont nécessaires, on peut utiliser le batch ci-dessus en définissant par exemple

set texts=0 1 2 3 4 5 6 7 8 9

Mais ceci est fastidieux pour une police complète, et pour des raisons de programmation de l’application finale, il peut être utile de nommer les fichiers d’après le code ASCII de chaque caractère. Comme cette fonctionnalité n’est pas disponible dans le langage de commande Windows, il faut programmer ceci dans un langage évolué. Par exemple en LUA:

params="-background none -font Bauhaus-93 -pointsize 72 -density 300 -fill white -blur 0x5 "
for i=32,167 do
os.execute("convert.exe "..params.."label:"..string.char(i).." "..i..".png")
end

Ces 2 lignes génèrent automatiquement 130 fichiers de belles lettres prêtes à être utilisées comme textures dans votre jeu. A noter que ces fichiers pèsent déjà 10 Mb au total, soit plus que l’exécutable d’ImageMagick : il peut donc être intéressant d’inclure ImageMagick à votre produit et de l’utiliser pour créer les polices nécessaires lors de l’installation plutôt que d’alourdir votre distribution…

Enfin, si vous trouvez les polices ci-dessus un peu trop carrées, visitez cette page qui vous donnera une petite idée des effets possibles, et explorez celle-ci pour une vision plus complète.

librairie GLua

GLua est une librairie open source qui offre au programmeurs LUA des classes et functions qui singent celles disponibles en GLSL, le « OpenGL Shading Language ».

GLua a été spécialement conçue comme librairie de base pour Demoniak3D, pour fournir un ensemble cohérent avec les shaders GLSL.

Contenu:

  • vec3.lua : vecteurs et arithmétique 3D
  • mat3.lua : matrice et arithmétique 3D
  • vec4.lua : vecteurs et arithmétique 3D
  • glsl.lua : fonctions génériques suivant les prototypes glsl comme définis dans le livre « OpenGL Shading Language » by Randi J. Rost
  • test.X.lua : tests unitaires du module X

Utilisation et exemples:

L’utilisation des classes et fonctions est relativement simple.

Regardez les fichiers test.X.lua pour plus de détails et d’exemples.

Téléchargement:

GLua est disponible sur http://luaforge.net/projects/glua/ sous licence LGPL.

Détails d’implémentation:

  • les classes sont basées sur class.lua, décrite ici: http://lua-users.org/wiki/SimpleLuaClasses
  • glsl.lua offre des fonctions génériques fonctionnant sur les nombres et tables LUA, et donc avec toutes les classes matrice/vecteur. Elle utilise intensivement la « programmation fonctionnelle » pour ce faire:
    • la fonction « apply » est définie comme suit:
      --- applies a function to a table of parameters
      -- @param f : function to apply to each element in v
      -- @param v : (vector of) parameter(s) to f function
      -- @return : (vector of) result(s) of f(v)
      function apply(f,v)
      if type(v)=="number" then return f(v) end
      if type(v)=="table" then
      local res={}
      for i,x in ipairs(v) do res[i]=f(x) end
      return res
      end
      error("apply "..f.."("..type(v)..") not implemented")
      end
    • ainsi, les fonctions peuvent facilement être définies pour accepter des nombres, vecteurs et tables:
      function sin(rad)
      return apply(math.sin,rad)
      end
  • le produit scalaire est implanté de 2 manières distinctes :
    • dans l’opérateur « exposant » ^ des classes
    • comme fonction générique dot(p1,p2) dans glsl.lua

GLua library

GLua is an open source library which provides LUA programmers with classes and functions that mimic those available in GLSL, the OpenGL Shading Language.

GLua was especially designed as a base library for the Demoniak3D real-time engine, as it provides a consistent framework with GLSL shaders.

Contents:

  • vec3.lua : 3D vectors and arithmetic
  • mat3.lua : 3D matrix and arithmetic
  • vec4.lua : 4D vectors and arithmetic
  • glsl.lua : generic functions following glsl prototypes as defined in book « OpenGL Shading Language » by Randi J. Rost
  • test.X.lua : unit test of module X

Usage & Samples:

Usage of the classes and functions is pretty straightforward.

Check the test.X.lua modules for more details or examples

Download:

GLua is available on http://luaforge.net/projects/glua/ under LGPL licence.

Implementation details:

  • the classes are based on class.lua, described on http://lua-users.org/wiki/SimpleLuaClasses
  • glsl.lua offers generic function that work on LUA numbers and tables, and therefore all vector / matrix classes. It makes extensive use of functional programming to achieve this:
    • the « apply » function is defined as follows:
      --- applies a function to a table of parameters
      -- @param f : function to apply to each element in v
      -- @param v : (vector of) parameter(s) to f function
      -- @return : (vector of) result(s) of f(v)
      function apply(f,v)
      if type(v)=="number" then return f(v) end
      if type(v)=="table" then
      local res={}
      for i,x in ipairs(v) do res[i]=f(x) end
      return res
      end
      error("apply "..f.."("..type(v)..") not implemented")
      end
    • then, functions can easily be defined to support numbers, vectors, or matrices:
      function sin(rad)
      return apply(math.sin,rad)
      end
  • dot product is implemented in 2 different ways :
    • through the « power » ^ operator in classes
    • as a generic dot(p1,p2) function in glsl.lua

Fractales IFS, Flame, Moutons Electriques et GPU

Un « système de fonctions itérées » ou « Iterated function system » (IFS) permet de produire des « fractales autosimilaires » ressemblant parfois à des feuilles, comme cette fougère calculée par Paul Nylander en Mathematica.

Les fractales « flamme » sont une généralisation des IFS inventée par Scott Draves. Son algorithme est décrit en détail ici. Ils produisent des motifs plus abstraits mais plus colorés, qu’il est possible de faire varier progressivement pour créer des animations spectaculaires.

Les « flame fractals » ont été popularisées par le superbe screen saver « Electric Sheep » que j’ai utilisé un temps avant de me rendre compte que c’était en réalité un simple player de vidéos téléchargées munies d’un système de vote. En effet, le calcul des « moutons électriques » est très lent même sur un processeur puissant, et c’est un autre logiciel, Apophysis qui est utilisé pour les générer.

Serait-il possible de calculer des « flame fractals » sur un GPU, voire même en temps réel ? Jusqu’ici, trois tentatives ont été faites:

  1. Simon G. Green, de nVidia, a présenté « GPUflame – a GPU-accelerated IFS fractal renderer« au SIGGraph 2005. Son executable pour Windows avec un shader en Cg (ne fonctionnant donc pas avec une carte ATI…) est disponible. Sur une GeForce 6600, il tourne à 2 fps environ. Exemple de résultat:
  2. RapidMind a réalisé un « Electric Sheep » sur GPU sur la base de leur framework C++ dont j’ai parlé ici. Il fonctionne à 10 fps environ sur une GeForce 8800, soit 60x plus vite que sur un Intel Duo 6700. Ce programme n’est hélas pas disponible, on ne peut qu’admirer la video:
  3. Christopher Emory Moore a codé « GPU Flame Fractal » en GLSL + LUA, sur la base de son surprenant GL Lua Shell qui lui permet de tourner sur Mac, PC, et Linux. Et le code source est disponible! Il produit des flammes de 16’000 points à 85fps en faisant 20 itérations par frame. Le résultat est un peu brut, mais quand ça bouge c’est très joli:

reste plus qu’à en faire une version pour Demoniak3D

Flower Power Demo

C’est un peu long à expliquer pourquoi, mais Thierry a suggéré de faire pousser des tulipes avec Hyperion… Je me suis attaqué à une petite démo en partant du code sample 84 qui fait bouger de l’herbe avec un shader GLSL, le but étant de faire balancer les tulipes dans le vent virtuel aussi plus tard.

Voilà où ça en est pour l’instant:

L’idée de base pour faire pousser une fleur est de manipuler l’échelle d’un modèle 3D de la tulipe en temps réel. Dans une première phase on fait pousser la fleur en hauteur avec

HYP_Object.SetScale(tulip,h/3,h,h/3)

puis on fait éclore la tulipe en agissant sur les facteurs d’échelle x et z. Le paragraphe suivant présente une manière élégante de faire ceci tout en traitant le cas de nombreuses fleurs.

En effet, la difficulté essentielle consiste à faire pousser les fleurs « presque » en même temps, « presque » à la même vitesse, « presque » à la même hauteur et « presque » verticalement, puis à les faire « presque » éclore en même temps.

Pour faire ceci, j’ai développé une petite librairie d’animation en LUA dont je suis très fier, car elle permet de faire de très nombreuses autres choses, pour ne pas dire tout ! (et encore, je suis modeste…)

Animate

Lire la suite