1) You only need to put 2 objects, the first one with your textures and all the shaders and more.
2) The second is the edge scaled a litle more big, with inverted culling to invert the normals and project the edge.
I guess it goes without saying that you should move the two objects and if they are animated, animate both objects at once.
This is a sample. For me it's enought. Now you have the ball to make a shader hehe

Where is my medal?

And my cup? heep!

Code: Select all
;{ GLOBALES
Global.b sal
Global.l contador
Global.b pantallaCompleta
;}
;{ FUENTES
Global fontLit= LoadFont(#PB_Any,"Arial",9)
;}
;{ SISTEMA 3D
Procedure spr2DText(spr, txt.s, ink.l=$ff00ffff)
Protected n,y=2,tl= CountString(txt,#CR$)
Protected tx.s
StartDrawing(SpriteOutput(spr))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0,0,OutputWidth(),OutputHeight(),$00000000)
DrawingMode(#PB_2DDrawing_AlphaBlend | #PB_2DDrawing_Transparent)
Box(0,0,OutputWidth(),OutputHeight(),$aa000000)
DrawingFont(FontID(fontLit))
For n=1 To tl+1
tx= StringField(txt,n,#CR$)
DrawText(5,y,tx,ink)
y+16
Next n
DrawingMode(#PB_2DDrawing_AlphaBlend | #PB_2DDrawing_Outlined)
Box(0,0,OutputWidth(),OutputHeight(),ink)
StopDrawing()
EndProcedure
Procedure eventosWindows()
Repeat
event= WindowEvent()
Select event
Case #PB_Event_Gadget
EventGadget= EventGadget()
EventType= EventType()
Case #PB_Event_CloseWindow
sal= 1
EndSelect
Until event= 0
EndProcedure
Procedure eventos3D(camara, speed.f=1, mouseSpd.f=0.05)
Protected.f KeyX,KeyY, MouseX,MouseY
If KeyboardPushed(#PB_Key_Escape)
sal=1
EndIf
If KeyboardPushed(#PB_Key_A)
KeyX= -speed
ElseIf KeyboardPushed(#PB_Key_D)
KeyX= speed
Else
KeyX= 0
EndIf
If KeyboardPushed(#PB_Key_W)
KeyY= -speed
ElseIf KeyboardPushed(#PB_Key_S)
KeyY= speed
Else
KeyY= 0
EndIf
If KeyboardPushed(#PB_Key_LeftShift)
keyY * 10
keyX * 10
EndIf
MouseX = -MouseDeltaX() * mouseSpd
MouseY = -MouseDeltaY() * mouseSpd
RotateCamera(camara, MouseY, MouseX, 0, #PB_Relative)
MoveCamera (camara, KeyX, 0, KeyY)
EndProcedure
Procedure iniDX(title.s="ToniEngine3D", width=800,height=600, fullscreen.b=#False, AA.i=#PB_AntialiasingMode_None, shadowmode= #PB_Shadow_Modulative, shadowres=4096, param=#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
Protected.b screenTestOK
InitEngine3D()
InitSprite()
InitKeyboard()
InitMouse()
AntialiasingMode(AA)
If width=0 And height=0
ExamineDesktops()
width= DesktopWidth(0)
height= DesktopHeight(0)
pantallaCompleta= 0
param= #PB_Window_BorderLess
EndIf
If fullscreen
pantallaCompleta= 1
If ExamineScreenModes()
While NextScreenMode()
; Debug Str(ScreenModeWidth())+"x"+Str(ScreenModeHeight())+"x"+Str(ScreenModeDepth())+"@"+Str(ScreenModeRefreshRate())+"Hz"
If ScreenModeWidth()=width And ScreenModeHeight()=height And ScreenModeDepth()=32
screenTestOK= 1
EndIf
Wend
EndIf
If screenTestOK= 0
width=1280:height=720
EndIf
OpenScreen(width,height,32,title,#PB_Screen_NoSynchronization)
Else
OpenWindow(0, 0, 0, width, height, title, param)
SetWindowColor(0,$444444)
OpenWindowedScreen(WindowID(0), 0, 0, (width * DesktopResolutionX()), (height * DesktopResolutionY()),0,0,0,#PB_Screen_NoSynchronization)
EndIf
KeyboardMode(#PB_Keyboard_International)
Add3DArchive("Data/Textures", #PB_3DArchive_FileSystem)
Add3DArchive("Data/Model", #PB_3DArchive_FileSystem)
Parse3DScripts()
Protected.b s= 100
If shadowmode= #PB_Shadow_TextureAdditive Or shadowmode= #PB_Shadow_TextureModulative
WorldShadows(shadowmode, -1, RGB(s,s,s), shadowres)
Else
WorldShadows(shadowmode, -1, RGB(s,s,s))
EndIf
EndProcedure
; iniDX("Base 3D",1280,800,#True) ;pantalla completa
iniDX("Base 3D",960,540,#False,#PB_AntialiasingMode_None,#PB_Shadow_Additive, 256) ;modo ventana
; iniDX("Base 3D",0,0,#False,#PB_AntialiasingMode_None,#PB_Shadow_Modulative, 512) ; pantalla completa en veentana
sprInfo= CreateSprite(#PB_Any,100,200,#PB_Sprite_AlphaBlending)
;}
Procedure creaSuelo(size=50, col1.l=$0,col2.l=$aaaaaa, res=256)
Protected.i suelo_tx3D, suelo_mate, suelo_mesh, suelo
suelo_tx3D= CreateTexture(#PB_Any,res,res)
StartDrawing(TextureOutput(suelo_tx3D))
Box(0,0,OutputWidth(),OutputHeight(),col1)
Box(2,2,OutputWidth()-4,OutputHeight()-4,col2)
StopDrawing()
suelo_mesh= CreatePlane(#PB_Any,size,size,1,1,1,1)
suelo_mate= CreateMaterial(#PB_Any,TextureID(suelo_tx3D))
ScaleMaterial(suelo_mate,1/size,1/size)
suelo= CreateEntity(#PB_Any, MeshID(suelo_mesh), MaterialID(suelo_mate))
ProcedureReturn suelo
EndProcedure
;{ DECORADO 3D
creaSuelo()
cubo_mesh= CreateCube(#PB_Any,1)
cubo_mate= CreateMaterial(#PB_Any, #Null,$0000ff)
cubo_enti= CreateEntity(#PB_Any, MeshID(cubo_mesh), MaterialID(cubo_mate),0,1,0)
; el borde
borde= CreateMaterial(#PB_Any, #Null,$000000)
MaterialCullingMode(borde,#PB_Material_AntiClockWiseCull)
cuboBorde= CreateEntity(#PB_Any, MeshID(cubo_mesh), MaterialID(borde),0,1,0)
ScaleEntity(cuboBorde,1.1,1.1,1.1)
;}
;{ CÁMARA Y LUZ
luz= CreateLight(#PB_Any,$ffffff,30,50,0,#PB_Light_Point)
camara= CreateCamera(#PB_Any,0,0,100,100)
MoveCamera(camara,3,5,7)
CameraRange(camara, 0.1,1000)
CameraLookAt(camara,0,0,0)
;}
;{ BUCLE PRINCIPAL
Repeat
;{ PROCESO EVENTOS
If pantallaCompleta= 0
eventosWindows()
EndIf
;}
ExamineKeyboard()
ExamineMouse()
eventos3D(camara, 0.1)
ElapsedTime = RenderWorld()
;{ HUD
If contador % 25 = 0
txt.s= "DEBUGGER"+ #CR$+
"FPS: "+Str(Engine3DStatus(#PB_Engine3D_CurrentFPS)) +#CR$+
Str(ScreenWidth())+" x "+Str(ScreenHeight()) +#CR$+
; "X: "+StrF(CameraX(camara),2)+#CR$+"Y: "+StrF(CameraY(camara),2)+#CR$+"Z: "+StrF(CameraZ(camara),2); +#CR$+
; "X: "+StrF(land\playX) +#CR$+
; "Z: "+StrF(land\playZ) +#CR$+
; "CAY: "+StrF(cya,2); +#CR$+
spr2DText(sprInfo,txt, $ff00ffff)
EndIf
DisplayTransparentSprite(sprInfo,ScreenWidth()-110,10)
;}
RotateEntity(cubo_enti,0,1,0,#PB_Relative)
RotateEntity(cuboBorde,0,1,0,#PB_Relative)
FlipBuffers()
contador +1
Delay(1)
Until sal=1
;}