[PUREBASIC] Bump Mapping 2D

Cpl.Bator Message lu Posté le 27 Déc 2008 à 13:02 Bulle
Avatar de Cpl.Bator
Nouveau Membre

Messages : 17
GCPoints : 8751
Voici un petit effet Oldshool , le bump mapping 2D en 640x480

Code :
;BUMP MAPPING BASIC
;PAR CPL.BATOR


Procedure CreationLumiere(Size.l,LightIntensity.l)
Protected NormalX.f,NormalY.f,NormalZ.f
Global EnvMapSize.l

EnvMapSize = Size

Global Dim Light(Size,Size) ; Tableau qui va contenir l'intensité de la lumière
                             ; Pour cette exemple c'est une lumière circulaire (omnidirectionnel)
                             ; La lumière peut etre fabriquer à partir d'un Bitmap , mais attention
                             ; Les calculs de l'intensité de vont pas de 0 à 255 , il vont dans cette
                             ; exemple de 0 à 5 ou 6 "1-Sqr((Pow(NormalX,2)) + (Pow(NormalY,2)))"
For y = 0 To Size
For x = 0 To Size

 NormalX = (x-(Size/2))/(Size/4)
 NormalY = (y-(Size/2))/(Size/4)
 NormalZ = 1-Sqr((Pow(NormalX,2)) + (Pow(NormalY,2)))
 
If NormalZ<=0 : NormalZ=0 : EndIf
Light(x,y) = (LightIntensity * NormalZ)

Next x
Next y

EndProcedure



Procedure LoadBumpImage(ImageID.l,File$)
Protected Color.l

LoadImage(ImageID,File$)

Global Dim BumpImage(ImageWidth(ImageID),ImageHeight(ImageID)) ; Ici va etre ranger l'image qui va servir de bump
                                                                 ; Les valeurs qui vont etre stockés vont etre additionnée
StartDrawing(ImageOutput(ImageID))                               ; à Light afin d'obtenir une "pertubation" qui simule le relief
 For  y = 0 To ImageHeight(ImageID)-1
  For  x = 0 To ImageWidth(ImageID)-1
   Color.l = Point(x,y) ; peut etre optimiser avec DrawingBuffer()
    BumpImage(x,y)=  (Red(Color) + Blue(Color) + Green(Color) ) / 3 ; Calcul simple pour convertir une image en niveau de gris
   Next                                                             
  Next
 StopDrawing()
 
EndProcedure





Procedure Bumping(ImageID.l,Light_X.l,Light_Y.l)

Shared LightX.l,LightY.l
Shared NLightX.l,NLightY.l
Shared Normal_X.l,Normal_Y.l
Shared Color.l



LightX = Light_X
LightY = Light_Y


StartDrawing(ScreenOutput())

 For  y = 0 To ImageHeight(ImageID)-1
  For  x = 0 To ImageWidth(ImageID)-1

If x > 0 And x < ImageWidth(ImageID)-2 And y > 0 And y < ImageHeight(ImageID)-2 ; on controle bien que X & Y
                                                                                 ; ne sort pas du tableau
                                                                                 ; de cette manière les lignes aux extrémités ne sont pas pris en compte
   Normal_X = (BumpImage(x+1,y)-BumpImage(x-1,y))                                ; il faudrait d'autre if-endif pour les prendres en comptes
   Normal_Y = (BumpImage(x,y+1)-BumpImage(x,y-1))


   NLightX = X-LightX
   NLightY = Y-LightY
   Normal_X=Normal_X + NLightX   
   Normal_Y=Normal_Y + NLightY 
   Normal_X=Normal_X + (EnvMapSize/2) ; on postionne la lumiere au centre de LigthX & Y 
   Normal_Y=Normal_Y + (EnvMapSize/2)


 If Normal_X<=0                 :  Normal_X=0                : EndIf
 If Normal_Y<=0                 :  Normal_Y=0                : EndIf
 If Normal_X=>EnvMapSize        :  Normal_X=EnvMapSize       : EndIf
 If Normal_Y=>EnvMapSize        :  Normal_Y=EnvMapSize       : EndIf
   


Color  = RGB(Light(Normal_X,Normal_Y),Light(Normal_X,Normal_Y),Light(Normal_X,Normal_Y)) ; On recupere la valeur de la lumière suivant la normal
                                                                                         ; on peut aussi modifier la couleur de la lumière 
Plot(x,y,Color) ; on l'affiche
 
 
EndIf

  Next x
Next y

StopDrawing()


EndProcedure


InitSprite()
InitKeyboard() : InitMouse()

OpenScreen(640,480,32,"Bump")
 CreationLumiere(512,200)
  LoadBumpImage(1,"Bump.bmp")


;-Boucle Principale
Repeat
 ExamineKeyboard() : ExamineMouse()
  Bumping(1,MouseX(),MouseY())
   FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape)
Mod Message lu Posté le 31 Déc 2008 à 10:18 Bulle
Avatar de Mod
Webmaster

Messages : 4954
GCPoints : 2100823
Et en voici la conversion Dark Basic Pro que j'en avais faite il y a quelques années, si tu t'en souviens ^^ :

Code :
` --------------------------------------------------------------
` Bump Mapping ---------------- 05 / 07 / 2006 -----------------
` Code original de Cpl.Bator -----------------------------------
` Converti du Pure Basic vers le Dark Basic par Mod ------------
` --------------------------------------------------------------

` ce programme créé un bump mapping logiciel, ce n'est plus la carte graphique qui se charge des calculs,
` mais le programme, cela allège la carte graphique, mais charge le processeur, donc en fait ça sert rien %)
` . . . mis à part montrer que le Pure Basic dessine un pixel plus vite que le Dark Basic :/
` sur un A64 35400+ / Radeon X800XT je tourne à 8/9 FPS
` des tests rapides montrent que ça passe à 11 FPS avec des memblocks.

` FPS illimité et changement de nom de la fenêtre
   sync on : sync rate 0 : set window title "Bump Mapping Software"


` chargement du bitmap à bump mapper
   load bitmap "CompilBump.bmp",1

` création des données de la lumière et du bump
   CreateLight(1024,255)
   CreateBump(1)


` -------------------------------------------------------------------------------------------------------------------------


` on répète tant que l'utilisateur n'a pas appuyé sur Echap / Esc
   repeat

      Bumping(1,MouseX(),MouseY(),0) ` on rend le BumpMapping 2D
      text 0,0,str$(screen fps())

      sync
      
   until escapekey()=1


`##########################################################################################################################

` on crée les données de dégradé de la lumière
` Size = taille de la lumière
` Intensité de la lumière dépasser les bornes 0 et 255 créera un bump mapping erroné
   function CreateLight(Size as dword, LightIntensity as dword)

      NormalX as float : NormalY as float : NormalZ as float

      global EnvMapSize = Size
      dim Light(Size,Size)

      for y = 0 to Size
         for x = 0 to Size

            NormalX = (x-(Size/2.0))/(Size/4.0)
            NormalY = (y-(Size/2.0))/(Size/4.0)
            NormalZ = 1-Sqrt( (NormalX^2) + (NormalY^2) )

            if NormalZ<=0 then NormalZ=0
            Light(x,y) = (LightIntensity * NormalZ)

         next x
      next y

   endfunction

`##########################################################################################################################

` génère les données de bump mapping
` BitmapID = numéro du bitmap à bump-mapper
   function CreateBump(BitmapID as dword)

    ` tableau stockant le niveau de gris de l'image pour le bump
      dim BumpImage( bitmap Width(BitmapID), bitmap Height(BitmapID) )

    ` on créé également un tableau contenant les données réelles de l'image (plus rapide qu'accéder aux données image)
      dim TrueImage( bitmap Width(BitmapID), bitmap Height(BitmapID) ,2)

      lock pixels ` on verouille pour un accès rapide aux données 2d

      for  y = 0 To bitmap height(BitmapID)-1
         for  x = 0 To bitmap width(BitmapID)-1

            color = point(x,y)
            TrueImage(x,y,0) = rgbr(Color) ` on enregistre la composante rouge
            TrueImage(x,y,1) = rgbg(Color) ` on enregistre la composante bleue
            TrueImage(x,y,2) = rgbb(Color) ` on enregistre la composante verte
         ` la moyenne des trois composantes donne un niveau de gris :
            BumpImage(x,y)=  ( TrueImage(x,y,0) + TrueImage(x,y,1) + TrueImage(x,y,2) ) / 3

         next
      next

      unlock pixels

      set current bitmap 0 ` on retourne à l'écran

   endfunction

`##########################################################################################################################

` le rendu du bump mapping
` BitmapID = numéro d'image
` Light_X = position de la lumière en x au moment du rendu
` Light_Y = position de la lumière en y au moment du rendu
` RenderColor = type de rendu :  0 -> pas de couleur
`                                1 -> couleurs de l'image
`                                autre -> pas de couleur

   function Bumping(BitmapID as dword, Light_X as dword, Light_Y as dword, RenderColor as integer)

      LightX = Light_X
      LightY = Light_Y

      lock pixels ` on vérouille pour un accès rapide aux données 2d

      for  y = 0 To bitmap height(BitmapID)-1
         for  x = 0 To bitmap width(BitmapID)-1

            if x > 0 And x < bitmap width(BitmapID)-2 And y > 0 And y < bitmap height(BitmapID)-2

               Normal_X = (BumpImage(x+1,y)-BumpImage(x-1,y))
               Normal_Y = (BumpImage(x,y+1)-BumpImage(x,y-1))

               NLightX = X-LightX
               NLightY = Y-LightY
               Normal_X=Normal_X + NLightX
               Normal_Y=Normal_Y + NLightY
               Normal_X=Normal_X + (EnvMapSize/2)
               Normal_Y=Normal_Y + (EnvMapSize/2)

               if Normal_X<=0 then Normal_X=0
               if Normal_Y<=0 then Normal_Y=0
               if Normal_X=>EnvMapSize then Normal_X=EnvMapSize
               if Normal_Y=>EnvMapSize then Normal_Y=EnvMapSize

               if RenderColor = 1
                  color  = RGB((Light(Normal_X,Normal_Y)/255.0)*TrueImage(x,y,0), (Light(Normal_X,Normal_Y)/255.0)*TrueImage(x,y,1), (Light(Normal_X,Normal_Y)/255.0)*TrueImage(x,y,2))
               else
                  Color  = RGB(Light(Normal_X,Normal_Y), Light(Normal_X,Normal_Y), Light(Normal_X,Normal_Y))
               endif

               dot x,y,color ` on affiche le pixel avec la couleur définie

            endif

         next x
      next y

      unlock pixels ` on dévérouille

   endfunction
Darktib Message lu Posté le 31 Déc 2008 à 18:06 Bulle
Avatar de Darktib
Membre Ultime

Messages : 4017
GCPoints : 347288
Sympa les codes :smile: je prend^^
Répondre
GameCorp - Site d'apprentissage et d'entraide à la création de jeux vidéo.
XHTML Valid 1.1 - Page générée en 0.0293 secondes