Bump

Partagez votre expérience de PureBasic avec les autres utilisateurs.
bombseb
Messages : 445
Inscription : jeu. 25/août/2005 22:59
Localisation : 974
Contact :

Bump

Message par bombseb »

Bonjour voici un prog de bump, (je me suis inspiré d'un algo déja existant) :

Code : Tout sélectionner

If InitSprite () = 0 Or InitKeyboard()= 0
   MessageRequester ("Erreur", "Impossible d'initialiser directx",#PB_MessageRequester_Ok)
   End
EndIf

;---------- Plein écran  ----------
#WindowWidth    = 640
#WindowHeight   = 480
If OpenScreen(#WindowWidth, #WindowHeight, 32, "Starfield") = 0
   MessageRequester ("Erreur", "Impossible d'ouvrir l'écran",#PB_MessageRequester_Ok)
   End
EndIf
;----------------------------------

UsePNGImageDecoder()

nSprite = CatchSprite(#PB_Any, ?IMGNuages)
If nSprite = 0
  MessageRequester ("Erreur", "Erreur à l'ouverture de l'image !", #PB_MessageRequester_Ok)
  End
EndIf




Global SpriteWidth  = SpriteWidth (nSprite)
Global SpriteHeight = SpriteHeight(nSprite)
Global Dim Hauteur.c (SpriteWidth, SpriteHeight)
Global Dim EnvMap.c (SpriteWidth, SpriteHeight)
DisplaySprite (nSprite, 0, 0)

StartDrawing (ScreenOutput ())
For X = 0 To SpriteWidth-1
  For Y = 0 To SpriteHeight-1
    Hauteur.c = Point (X,Y)
    Hauteur(X,Y) = Red (Hauteur)
  Next
Next


nX.f = 0
nY.f = 0
nZ.f = 0

diffuse = 255
ambient = 0
specular = 255


For Y = 0 To #WindowHeight - 1
  For X = 0 To #WindowWidth - 1
    nX = (X - (SpriteWidth / 2)) / (SpriteWidth / 2)
    nY = (Y - (SpriteHeight / 2)) / (SpriteHeight / 2)
    nZ=1-Sqr(nX*nX+nY*nY)
    
    If (nZ<0) 
      nZ=0
    EndIf
      
    tmp = nZ * diffuse + nZ * nZ * specular
    
    ;tmp = ambient + diffuse * nZ
    
    If tmp > 255
      tmp = 255
    EndIf
    
    tmp2.c = tmp
    EnvMap(X,Y) = ambient + tmp2
    
  Next
Next

;EnableDebugger
;CallDebugger


Procedure Bump (lx.w, ly.w)
  ; Ajuster la source lumineuse pour qu'elles soient à l'origine
  lx = lx + #WindowWidth / 2
  ly = ly + #WindowHeight / 2

  For Y=1 To #WindowHeight-1
    For X=1 To #WindowWidth-1
      ; Obtenir la "pente" de la bumpmap
      nX = (Hauteur(X+1,Y) - Hauteur(X-1,Y))
      nY = (Hauteur (X,Y+1) - Hauteur (X, Y-1))
      
      ; Ajustement de la normale d'après la source lumineuse
      nX = nX - (X-lx)
      nY = nY - (Y-ly)
      
      ; On s'assure qu'On ne dépasse pas l'envmap
      If nX>SpriteWidth Or  nX<=0
        nX=SpriteWidth
      EndIf
      
      If nY>SpriteHeight Or nY<=0
        nY=SpriteHeight
      EndIf
      
      Plot (X,Y, RGB(EnvMap(nX,nY),EnvMap(nX,nY), EnvMap(nX,nY)))
          
    Next
  Next
          
  
EndProcedure



StopDrawing()

ClearScreen(0)
FlipBuffers()
ClearScreen (0)

xCentre = #WindowWidth/2
yCentre = #WindowHeight/2
angle.f = 0

Repeat

  angle = angle + 0.2
   
  ClearScreen (0)
  
  If StartDrawing (ScreenOutput ())
    Bump (xCentre + Cos (angle) * 100, yCentre + Sin (angle) * 100)
    StopDrawing ()
  EndIf
  
  FlipBuffers ()
  
  ExamineKeyboard ()
Until KeyboardPushed (#PB_Key_Escape) Or WindowEvent() = #PB_Event_CloseWindow



End

DataSection
IMGNuages: IncludeBinary "oldskull2.png"
et voici l'image qui va avec :

http://bombseb.free.fr/TEMP/oldskull2.PNG


une question : je ne comprend pas sur mon athlon 3400+ (1go ram) ca marche super bien, c'est super fluide, aucun probleme
par contre sur mon athlon XP 2000+ (1go ram) ca rame à MORT, et je ne pense pas que le processeur est le principal fautif :roll: si quelqu'un a une idée svp....
bombseb
Messages : 445
Inscription : jeu. 25/août/2005 22:59
Localisation : 974
Contact :

Message par bombseb »

ouarf chui trop bête :roll:

le debugger était activé sur mon 2000+ héhéhéhéhé

ca marche nickel maintenant :lol:


(mais je vais quand même remplacer le plot par un pointeur)
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Message par tmyke »

Très bon code, et cela très bien. Super cool.

Pour la difference de perf, comme cela je ne vois pas. Tu n'étais pas en mode debug
sur ton Athlon XP2000 par hazard ? (j'ai essayé avec et sans, la différence est impressionnante sur
une meme machine...)
Force et sagesse...
bombseb
Messages : 445
Inscription : jeu. 25/août/2005 22:59
Localisation : 974
Contact :

Message par bombseb »

crosspost...

oui le debug était activé :D
bombseb
Messages : 445
Inscription : jeu. 25/août/2005 22:59
Localisation : 974
Contact :

Message par bombseb »

coool !!!

avec un pointeur, c'est aussi fluide sur mes 2 pcs :


remplacez la procedure bump par ceci (n'oubliez pas la structure Pixel) :

Code : Tout sélectionner

Structure Pixel
  b.c
  G.c
  R.c
  A.c
EndStructure

Procedure Bump (lx.w, ly.w)
  ; Ajuster la source lumineuse pour qu'elles soient à l'origine
  lx = lx + #WindowWidth / 2
  ly = ly + #WindowHeight / 2
  offset = 0
  
  Buffer = DrawingBuffer()
  Pitch   = DrawingBufferPitch()
  
  For X=1 To #WindowWidth-1
    ptr = Buffer + X<<2
    For Y=1 To #WindowHeight-1
      *Pixel.Pixel = ptr + Y * Pitch
      ; Obtenir la "pente" de la bumpmap
      nX = (Hauteur(X+1,Y) - Hauteur(X-1,Y))
      nY = (Hauteur (X,Y+1) - Hauteur (X, Y-1))
      
      ; Ajustement de la normale d'après la source lumineuse
      nX = nX - (X-lx)
      nY = nY - (Y-ly)
      
      ; On s'assure qu'On ne dépasse pas l'envmap
      If nX>SpriteWidth Or  nX<=0
        nX=SpriteWidth
      EndIf
      
      If nY>SpriteHeight Or nY<=0
        nY=SpriteHeight
      EndIf
      
      ;Plot (X,Y, RGB(EnvMap(nX,nY),EnvMap(nX,nY), EnvMap(nX,nY)))

      *Pixel\R = EnvMap(nX,nY)
      *Pixel\G = EnvMap(nX,nY)
      *Pixel\b = EnvMap(nX,nY)
      
    Next
  Next
          
  
EndProcedure
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

tres impressionant ! :D
super ! :D
bombseb
Messages : 445
Inscription : jeu. 25/août/2005 22:59
Localisation : 974
Contact :

Message par bombseb »

héhéhé

et le principe de l'algo est super simple... et peu gourmand en proc

:P
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Message par tmyke »

bombseb a écrit :héhéhé

et le principe de l'algo est super simple... et peu gourmand en proc

:P
c'est pour cela qu'en 3D on préfère passer par le GPU pour faire la choses
(prog de shader donc...)

;)
Force et sagesse...
bombseb
Messages : 445
Inscription : jeu. 25/août/2005 22:59
Localisation : 974
Contact :

Message par bombseb »

ben oui je me doute bien qu'il y a une fonction bump (x,y) dans toutes les cartes graphique maintenant
mais bon c'est quand même moins interressant de se limiter à appeller une fonction déja toute faite sans même savoir comment c'est fait...

bientôt tout sera déja précodé dans la carte graphique, il n'y aura même plus d'interet à programmer :cry:
minirop
Messages : 321
Inscription : mer. 02/août/2006 21:06

Message par minirop »

bombseb a écrit :bientôt tout sera déja précodé dans la carte graphique, il n'y aura même plus d'interet à programmer :cry:
pour les effets peut être mais y'a peux de chance qu'on se retouve avec ceci :

Code : Tout sélectionner

makeGame("Halflife2")
:lol:
bombseb
Messages : 445
Inscription : jeu. 25/août/2005 22:59
Localisation : 974
Contact :

Message par bombseb »

ca viendra.... 8O
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Message par tmyke »

bombseb a écrit :ben oui je me doute bien qu'il y a une fonction bump (x,y) dans toutes les cartes graphique maintenant
mais bon c'est quand même moins interressant de se limiter à appeller une fonction déja toute faite sans même savoir comment c'est fait...

bientôt tout sera déja précodé dans la carte graphique, il n'y aura même plus d'interet à programmer :cry:
En fait, contrairement a ce que pourrais penser, il n'y a pas de fonction bump de
pré-programmé dans les cartes video, mais pour résumer, le programme que tu as fais en PB, il faut en
fait le faire en programmant directement le PGU (processor graphic unit), entre autre termes
directement le processeur de ta carte video... ce qui est tout aussi interessant, les effet possibleétant infinie,
ce qui donne cela pour du NormalMap par exemple:

Code : Tout sélectionner

struct Mtrl
{
	float4 ambient;
	float4 diffuse;
	float4 spec;
	float  specPower;
};

struct DirLight
{
	float4 ambient;
	float4 diffuse;
	float4 spec;
};

uniform extern float4x4 gWorldInv;
uniform extern float4x4 gWVP;
uniform extern Mtrl     gMtrl;
uniform extern DirLight gLight;
uniform extern float3   gEyePosW;
uniform extern float3   dirW;  
uniform extern texture  gTex;
uniform extern texture  gNormalMap;

sampler TexS = sampler_state
{
	Texture = <gTex>;
	MinFilter = ANISOTROPIC;
	MaxAnisotropy = 8;
	MagFilter = LINEAR;
	MipFilter = LINEAR;
	AddressU  = WRAP;
    AddressV  = WRAP;
};

sampler NormalMapS = sampler_state
{
	Texture = <gNormalMap>;
	MinFilter = ANISOTROPIC;
	MaxAnisotropy = 8;
	MagFilter = LINEAR;
	MipFilter = LINEAR;
	AddressU  = WRAP;
    AddressV  = WRAP;
};
 
struct OutputVS
{
    float4 posH      : POSITION0;
    float3 toEyeT    : TEXCOORD0;
    float3 lightDirT : TEXCOORD1;
    float2 tex0      : TEXCOORD2;
};

OutputVS NormalMapVS(float3 posL      : POSITION0, 
                     float3 tangentL  : TANGENT0,
                     float3 binormalL : BINORMAL0,
                     float3 normalL   : NORMAL0, 
                     float2 tex0      : TEXCOORD0)
{
    // Zero out our output.
	OutputVS outVS = (OutputVS)0;
	
	// Build TBN-basis.
	float3x3 TBN;
	TBN[0] = tangentL;
	TBN[1] = binormalL;
	TBN[2] = normalL;
	
	// Matrix transforms from object space to tangent space.
	float3x3 toTangentSpace = transpose(TBN);
	
	// Transform eye position to local space.
	float3 eyePosL = mul(float4(gEyePosW, 1.0f), gWorldInv);
	
	// Transform to-eye vector to tangent space.
	float3 toEyeL = eyePosL - posL;
	outVS.toEyeT = mul(toEyeL, toTangentSpace);
	
	// Transform light direction to tangent space.
	float3 lightDirL = mul(float4(dirW, 0.0f), gWorldInv).xyz;
	outVS.lightDirT  = mul(lightDirL, toTangentSpace);
	
	// Transform to homogeneous clip space.
	outVS.posH = mul(float4(posL, 1.0f), gWVP);
	
	// Pass on texture coordinates to be interpolated in rasterization.
	outVS.tex0 = tex0;
	
	// Done--return the output.
    return outVS;
}

float4 NormalMapPS(float3 toEyeT    : TEXCOORD0,
                   float3 lightDirT : TEXCOORD1,
                   float2 tex0      : TEXCOORD2) : COLOR
{
	// Interpolated normals can become unnormal--so normalize.
	toEyeT    = normalize(toEyeT);
	lightDirT = normalize(lightDirT);
	
	// Light vector is opposite the direction of the light.
	float3 lightVecT = -lightDirT;
	
	// Sample normal map.
	float3 normalT = tex2D(NormalMapS, tex0);
	
	// Expand from [0, 1] compressed interval to true [-1, 1] interval.
    normalT = 2.0f*normalT - 1.0f;
    
    // Make it a unit vector.
	normalT = normalize(normalT);
	
	// Compute the reflection vector.
	float3 r = reflect(-lightVecT, normalT);
	
	// Determine how much (if any) specular light makes it into the eye.
	float t  = pow(max(dot(r, toEyeT), 0.0f), gMtrl.specPower);
	
	// Determine the diffuse light intensity that strikes the vertex.
	float s = max(dot(lightVecT, normalT), 0.0f);
	
	// If the diffuse light intensity is low, kill the specular lighting term.
	// It doesn't look right to add specular light when the surface receives 
	// little diffuse light.
	if(s <= 0.0f)
	     t = 0.0f;
	
	// Compute the ambient, diffuse and specular terms separatly. 
	float3 spec = t*(gMtrl.spec*gLight.spec).rgb;
	float3 diffuse = s*(gMtrl.diffuse*gLight.diffuse).rgb;
	float3 ambient = gMtrl.ambient*gLight.ambient;
	
	// Get the texture color.
	float4 texColor = tex2D(TexS, tex0);
	
	// Combine the color from lighting with the texture color.
	float3 color = (ambient + diffuse)*texColor.rgb + spec;
	
	// Output the color and the alpha.
    return float4(color, gMtrl.diffuse.a*texColor.a);
}

technique NormalMapTech
{
    pass P0
    {
        // Specify the vertex and pixel shader associated with this pass.
        vertexShader = compile vs_2_0 NormalMapVS();
        pixelShader  = compile ps_2_0 NormalMapPS();
    }
}
Force et sagesse...
bombseb
Messages : 445
Inscription : jeu. 25/août/2005 22:59
Localisation : 974
Contact :

Message par bombseb »

ouaouhhhh !!! 8O

mais c'est génial caaaaa !!!

on peux programmer le GPU avec purebasic aussi ???
je vais me pencher sur la question à l'occaze...merci pour l'info !
Répondre