shader 3D Editor
Posted: Tue Sep 23, 2025 6:29 pm
Hi guys,
My little shader editor.
It's not very practical to use (which is why I hesitated to publish it), but it saves a lot of time.
To use it in your 3D code:
- Add: IncludeFile “...\shader_editor.pb” (corresponding to the code below)
- Use engine3D in debug mode: “InitEngine3D(#PB_Engine3D_DebugLog)”
- Your material must be created in a procedure
- Add below: editshadermaterial(@procedure_namel())
e.g.:
Procedure ShaderMaterial()
...
EndProcedure
editshadermaterial(@ShaderMaterial())
- When closing the editor, the shader code is copied to the clipboard (included in “CreateShader(...)”)
Select the line “CreateShader...” and paste it
- To add an automatic parameter (at the cursor position), click on “Auto param.”
shader_editor.pb
Example of use: (quantification of the normal)
My little shader editor.
It's not very practical to use (which is why I hesitated to publish it), but it saves a lot of time.
To use it in your 3D code:
- Add: IncludeFile “...\shader_editor.pb” (corresponding to the code below)
- Use engine3D in debug mode: “InitEngine3D(#PB_Engine3D_DebugLog)”
- Your material must be created in a procedure
- Add below: editshadermaterial(@procedure_namel())
e.g.:
Procedure ShaderMaterial()
...
EndProcedure
editshadermaterial(@ShaderMaterial())
- When closing the editor, the shader code is copied to the clipboard (included in “CreateShader(...)”)
Select the line “CreateShader...” and paste it
- To add an automatic parameter (at the cursor position), click on “Auto param.”
shader_editor.pb
Code: Select all
; Editeur Shader3D
EnableExplicit
;{ =========================== String
#separateurs=" =:;,()[]{}+-/*.\<>?%|&§"+#CR$+#LF$+Chr(34)+#TAB$
Procedure.s lirefic(nom.s)
Protected txt.s,n
n=ReadFile(-1,nom,#PB_File_SharedRead):txt=ReadString(n,#PB_File_IgnoreEOL):CloseFile(n)
ProcedureReturn txt
EndProcedure
Procedure ecrirefic(nom.s,txt.s,verif.b=1)
Protected n
If FileSize(nom)>0
If verif And MessageRequester("Attention","Le fichier "+nom+" existe déjà"+#CRLF$+"remplacer ?",#PB_MessageRequester_YesNo) <>#PB_MessageRequester_Yes:ProcedureReturn:EndIf
DeleteFile(nom)
EndIf
n=OpenFile(-1,nom):WriteString(n,txt):CloseFile(n)
EndProcedure
Procedure Split(Array t.s(1),l.s,sep.s=",",nmax=200)
Protected ap,p,n,ls
Dim t(nmax)
ls=Len(sep)
l+sep
p=1-ls
Repeat
ap=p+ls:p=FindString(l,sep,ap)
If p=0:Break:EndIf
n+1
t(n)= Mid(l,ap,p-ap)
ForEver
ReDim t(n)
ProcedureReturn n
EndProcedure
Procedure.s supspace(l.s)
Protected i
Protected.s ll,ac,c
l=ReplaceString(l,#TAB$," ")
l=ReplaceString(l,#LF$," ")
l=ReplaceString(l,#CR$," ")
i=0:While i<Len(l)
Repeat
i+1
ac=c:c=Mid(l,i,1)
Until c<>" " Or ac<>" "
ll+c
Wend
ProcedureReturn Trim(ll)
EndProcedure
Procedure.s Stringparse(t.s,before.s,after.s,pi=0)
Protected pf
pi=FindString(t,before,pi+1)
If pi=0:ProcedureReturn:EndIf
pf=FindString(t,after,pi+Len(before)):If pf=0:pf=Len(t):EndIf
pi+Len(before)
ProcedureReturn Mid(t,pi,pf-pi)
EndProcedure
Procedure.s lirefct(Array p.s(1),txt.s,pd=1)
#g=Chr(34)
Protected i,n,np,pi,pf,l,p,ch
Protected.s c,fct
Dim p(100)
pi=FindString(txt,"(",pd)
fct=Trim(Mid(txt,pd,pi-pd))
pi+1
; ----------- recherche parametre
For i=pi To Len(txt)
c=Mid(txt,i,1)
If ch=0
If (c="," Or c=")") And np<=0:n+1:p(n)=Trim(Mid(txt,pi,i-pi)):pi=i+1:EndIf
If c="(":np+1:EndIf
If c=")":np-1:EndIf
EndIf
If c=#g:ch=~ch:EndIf
If np<0:Break:EndIf
Next
ReDim p(n)
ProcedureReturn fct
EndProcedure
Procedure FindStringRev(t.s,find.s,p=0,mode=#PB_String_CaseSensitive)
Protected l=Len(find)
If p=0:p=Len(t):EndIf
Repeat
If p=0 Or Mid(t,p,L)=find:Break:EndIf
p-1
ForEver
ProcedureReturn p
EndProcedure
Procedure.i FindStringww(txt.s,mot.s,p=1,mode=0); findstring whole word
Repeat
p=FindString(txt,mot,p,mode):If p=0:Break:EndIf
If FindString(#separateurs,Mid(txt,p-1,1))>0 And FindString(#separateurs,Mid(txt,p+Len(mot),1))>0:ProcedureReturn p:EndIf
p+Len(mot)
ForEver
EndProcedure
Procedure.s ReplaceStringww(txt.s,mot.s,rep.s,p=1,mode=0); ReplaceString whole word
Protected lm,lr
lm=Len(mot)
lr=Len(rep)
Repeat
p=FindStringww(txt,mot,p+1,mode):If p=0:Break:EndIf
txt=Left(txt,p-1)+rep+Mid(txt,p+lm)
;p+lm-lr+1
ForEver
ProcedureReturn txt
EndProcedure
Procedure.s ReplaceStringwwnum(txt.s,mot.s,rep.s,p=1,mode=0); ReplaceString whole word
Protected i
For i=0 To 9
txt=ReplaceStringww(txt,mot+Str(i),rep+Str(i),p,mode)
Next
ProcedureReturn txt
EndProcedure
;}
Declare shaderexport(compression,format)
Structure sparamauto
type.s
param.s
nomc.s
nomOgre.s
comment.s
EndStructure
Global Dim lword.s(20)
Global SciPos,SciStart, SciLine, SciCol, SciIndent,KeyWord.s
Global wedit,gSc,gsticky, gparamauto
Global wparam,gpauto_liste,gpauto_comment
Global e_sid, e_vpg.s,e_fpg.s,e_materialproc, e_return.s, e_tile.s="Shader Editor "
Global Dim paramauto.sparamauto(136)
Enumeration ScStyle
#Style_Keyword
#Style_input
#Style_Type
#Style_UniformI
#Style_VaryingI
#Style_Uniform
#Style_Varying
#Style_Variable
#Style_Macro
#Style_Comment
#Style_NonKeyword
EndEnumeration
Macro ssm(message,param=0,lparam=0)
ScintillaSendMessage(gSc,message,param,lparam)
EndMacro
Procedure.s ssmgettext()
Protected *buf,bufsize,txt.s
bufsize=ssm(#SCI_GETLENGTH)+1
*buf=AllocateMemory(bufsize)
ssm(#SCI_GETTEXT,bufsize,*buf)
txt=PeekS(*buf,-1,#PB_UTF8)
FreeMemory(*buf)
ProcedureReturn txt
EndProcedure
Procedure.s ssmGETCURLINE()
Protected *buf,bufsize,txt.s
bufsize=100
*buf=AllocateMemory(bufsize)
ssm(#SCI_GETCURLINE,bufsize,*buf)
txt=PeekS(*buf,-1,#PB_UTF8)
FreeMemory(*buf)
ProcedureReturn txt
EndProcedure
Procedure paramautoevent()
Protected n
If Event()=#PB_Event_CloseWindow:CloseWindow(EventWindow()):ProcedureReturn:EndIf
n=GetGadgetState(gpauto_liste):If n<0:ProcedureReturn:EndIf
If EventType()=#PB_EventType_LeftClick:SetGadgetText(gpauto_comment,paramauto(n)\type+" "+paramauto(n)\nomc+" ("+paramauto(n)\nomOgre+")"+#LF$+#LF$+paramauto(n)\comment):EndIf
;SetGadgetText(gpauto_comment,lparam()\nom+#CR$+lparam()\type+#CR$+lparam()\valdef)
If EventType()=#PB_EventType_LeftDoubleClick
ssm(#SCI_INSERTTEXT,ssm(#SCI_GETANCHOR),UTF8("uniform "+paramauto(n)\type+" "+paramauto(n)\nomc+";//+"+n+#LF$))
CloseWindow(EventWindow())
EndIf
EndProcedure
Procedure waffparamauto()
Protected i,col,nom.s
wparam=OpenWindow(-1,0,0,800,416,e_tile+" Auto parameters",#PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_Tool,WindowID(wedit))
gpauto_liste=ListIconGadget(-1,8,8,250,400,"Param_Auto",250-22,#PB_ListIcon_FullRowSelect)
HideGadget(gpauto_liste,1)
For i=0 To ArraySize(paramauto())
col=$eeeeee
nom= LCase(paramauto(i)\nomOgre)
If FindString(nom,"time"):col=$aaaaaa:EndIf
If FindString(nom,"colour"):col=$8888ff:EndIf
If FindString(nom,"position"):col=$ff6666:EndIf
If FindString(nom,"direction"):col=$ff8888:EndIf
If FindString(nom,"matrix"):col=$88ccff:EndIf
If FindString(nom,"array"):col=$66aadd:EndIf
AddGadgetItem(gpauto_liste,-1,Str(i)+" "+paramauto(i)\nomc)
SetGadgetItemColor(gpauto_liste,i,#PB_Gadget_BackColor,col)
Next
HideGadget(gpauto_liste,0)
BindEvent(#PB_Event_Gadget,@paramautoevent(),wparam,gpauto_liste)
BindEvent(#PB_Event_CloseWindow,@paramautoevent(),wparam)
gpauto_comment=EditorGadget(-1,266,8,526,400,#PB_Editor_ReadOnly|#PB_Editor_WordWrap)
EndProcedure
Procedure ScintillaProperties()
;Style par defaut du gadget scintilla (Couleur de fond et de caractére, police .....)
ssm(#SCI_STYLESETFORE, #STYLE_DEFAULT, $0) ;Couleur des caracteres du ScintillaGadget
ssm(#SCI_STYLESETBACK, #STYLE_DEFAULT, $aaddee) ;Couleur de fond du ScintillaGadget
ssm(#SCI_STYLESETFONT,#STYLE_DEFAULT, UTF8("Consolas")) ;Police à utiliser
ssm(#SCI_STYLESETSIZE, #STYLE_DEFAULT, 10) ;Taille de la police
ssm(#SCI_STYLECLEARALL)
ssm(#SCI_SETCARETLINEVISIBLE, #True);Activation et couleur de la ligne en cours d'édition
ssm(#SCI_SETCARETLINEBACK, RGB(255, 228, 181))
ssm(#SCI_STYLESETFORE, #STYLE_BRACELIGHT, $ff) :ssm(#SCI_STYLESETBOLD, #STYLE_BRACELIGHT, 1)
;ssm(#SCI_SETUSETABS, #False);Les tabulations sont remplacées par des espaces
ssm(#SCI_SETINDENT, 4) ;Nombre d'espaces pour une tabulation
ssm(#SCI_SETMARGINTYPEN, 0, #SC_MARGIN_NUMBER);Affichage de la colone de numérotation des lignes
ssm(#SCI_SETMARGINWIDTHN, 0, 30) ;Largeur de la colonne
ssm(#SCI_STYLESETBACK, #STYLE_LINENUMBER, $aaccdd) ;Couleur de fond
ssm(#SCI_STYLESETFORE, #STYLE_LINENUMBER, $ffffff) ;Couleur des numéros
;ssm(#SCI_SETMARGINMASKN, 2, #SC_MASK_FOLDERS);Affichage de la colonne de pliages de code
;ssm(#SCI_SETMARGINWIDTHN, 2, 20)
ssm(#SCI_SETMARGINSENSITIVEN, 2, #True)
; ssm(#SCI_BRACEScStyleINDICATOR, #True)
ssm(#SCI_AUTOCSETMAXHEIGHT, 20);Parametres de la liste d'autocomplétion des mots clés
ssm(#SCI_AUTOCSETMAXWIDTH, 150)
ssm(#SCI_AUTOCSETAUTOHIDE, #True)
ssm(#SCI_AUTOCSETCHOOSESINGLE, #True)
ssm(#SCI_AUTOCSETIGNORECASE, #True)
ssm(#SCI_AUTOCSETORDER, #SC_ORDER_PERFORMSORT);Tri de la liste d'autocomplétion
;ssm(#SCI_AUTOCCANCEL, #True)
;Coloration syntaxique
Macro style(num,col,bold=0,ital=0,under=0)
ssm(#SCI_STYLESETFORE, num, col)
If bold:ssm(#SCI_STYLESETBOLD, num, 1):EndIf
If ital:ssm(#SCI_STYLESETITALIC, num, 1):EndIf
If under:ssm(#SCI_STYLESETUNDERLINE, num, 1):EndIf
EndMacro
style(#Style_Type, $888800,1,0,0)
style(#Style_Keyword, $88,1,0,0)
style(#Style_input, $ff0000,0,0,0)
style(#Style_UniformI, $880000,0,1)
style(#Style_Uniform, $880000)
style(#Style_VaryingI, $880088,0,1)
style(#Style_Varying, $880088,0,0)
style(#Style_Variable, $004488)
style(#Style_Macro, $0044aa,0,1)
style(#Style_Comment, $8800,0,1)
style(#Style_NonKeyword, 0)
EndProcedure
Procedure ScStyle(*sn.SCNotification,majliste=0)
Protected.s ac.s,c.s,word.s,aword,aaword,txt.s
Protected StyleID,aStyleID, i,k,l
Protected lg,poslgf,pos,posf=*sn\position
Macro addkw(liste,mot)
If FindString(liste," "+mot+" ")=0:liste+mot+" ":EndIf
EndMacro
If majliste
lword(#Style_Varying)=" "
lword(#Style_Uniform)=" "
lword(#Style_Variable)=" "
pos=0
posf=ssm(#SCI_GETLENGTH)
Else
pos= ssm(#SCI_GETENDSTYLED)
lg=ssm(#SCI_LINEFROMPOSITION,pos)
pos=ssm(#SCI_POSITIONFROMLINE,lg)-1
EndIf
While pos <= posf
ssm(#SCI_STARTSTYLING, pos,0)
word="":l=0:Repeat:ac=c:c=Chr(ssm(#SCI_GETCHARAT, pos+l)):If FindString(#separateurs,c):Break:EndIf:word+c:l+1:Until pos+l>=posf
If l
astyleID=StyleID:StyleID=#Style_NonKeyword
If majliste And astyleID=#Style_Type;:Debug ""+aaword+" "+aword+" "+word
If aaword="varying" Or aaword="out":addkw(lword(#Style_Varying),word):EndIf
If aaword="uniform":addkw(lword(#Style_Uniform),word):EndIf
If aaword="" :addkw(lword(#Style_Variable),word):EndIf
EndIf
aaword=aword:aword=word
For k=0 To #Style_NonKeyword
If FindString(lword(k)," "+word+" ") :StyleID=k:Break:EndIf
Next
ssm(#SCI_SETSTYLING, l, StyleID)
pos+l:ssm(#SCI_STARTSTYLING, pos,0)
EndIf
If ac+c="//"
poslgf=ssm(#SCI_GETLINEENDPOSITION,ssm(#SCI_LINEFROMPOSITION,pos))+1:l=poslgf-pos:pos=poslgf:ssm(#SCI_SETSTYLING, l, #Style_Comment)
Else
pos+1:ssm(#SCI_SETSTYLING, 1, #Style_NonKeyword)
EndIf
If c=";" Or c="}" Or c="{":aaword="":aword="":EndIf
Wend
EndProcedure
Procedure ScCallBack(g, *sn.SCNotification)
Static i,ag, lw,l,ti
gSc=g;: If ag<>g:ag=g:majScintilla():EndIf
SciPos = ssm(#SCI_GETANCHOR);Determination de la position à l'intérieur de la chaine scintilla
SciStart=ssm(#SCI_WORDSTARTPOSITION, SciPos, 1)
SciLine = ssm(#SCI_LINEFROMPOSITION, SciPos);Determination de la ligne en cours
SciCol = ssm(#SCI_GETCOLUMN, SciPos) ;Determination de la colonne en cours
;Debug ""+g+" "+*sn\nmhdr\code+" "+*sn\length
;If *sn\text:Debug PeekS(*sn\text,-1,#PB_UTF8):endif
;If *sn\nmhdr\code<>2013 And *sn\nmhdr\code<>2000 :Debug ""+*sn\nmhdr\code+"-"+ssmGETCURLINE():EndIf
If ElapsedMilliseconds()-ti>5000:ScStyle(*sn,1):ti=ElapsedMilliseconds():EndIf
Select *sn\nmhdr\code
Case #SCN_MODIFIED
Case #SCN_CHARADDED
;Autocomplétion
KeyWord="":For i=0 To #Style_Macro:KeyWord+Mid(lword(i),2):Next:KeyWord=Trim(KeyWord)
l=scipos-SciStart
If l>1 And *sn\ch>='a' And *sn\ch<='z':ssm(#SCI_AUTOCSHOW, l, UTF8(KeyWord)):EndIf
Case #SCN_STYLENEEDED
ScStyle(*sn)
Case #SCN_MARGINCLICK
ssm(#SCI_TOGGLEFOLD, ssm(#SCI_LINEFROMPOSITION, *sn\Position))
Case #SCN_UPDATEUI
If FindString("()[]{}",Chr(ssm(#SCI_GETCHARAT,scipos-1))):ssm(#SCI_BRACEHIGHLIGHT, scipos-1, ssm(#SCI_BRACEMATCH,scipos-1))
ElseIf FindString("()[]{}",Chr(ssm(#SCI_GETCHARAT,scipos))):ssm(#SCI_BRACEHIGHLIGHT, scipos, ssm(#SCI_BRACEMATCH,scipos))
Else:ssm(#SCI_BRACEBADLIGHT,-1):EndIf
EndSelect
EndProcedure
Procedure editorevent()
Protected aw=GetActiveWindow()
Select Event()
Case #PB_Event_CloseWindow:
shaderexport(2,0):SetClipboardText(e_return)
;ClearDebugOutput():ShowDebugOutput():Debug e_return
;chemin=SaveFileRequester("save as","C:\PureBasic-code\MaterialScriptsGeneric\","Material (*.material)|*.material",0):If chemin<>"":script(chemin):EndIf
End
Case #PB_Event_Menu
Select EventMenu()
Case 1:If shaderexport(2,0) And aw<>-1:ReleaseMouse(0):SetWindowState(wedit,#PB_Window_Minimize):EndIf
EndSelect
Case #PB_Event_Timer
If aw<>-1 And Left(GetWindowTitle(aw),Len(e_tile))<>e_tile:SetWindowState(wedit,#PB_Window_Minimize):ReleaseMouse(0):EndIf
;If KeyboardPushed(#PB_Key_F5):DisableWindow(wedit,0):ResizeWindow(wedit,#PB_Ignore,#PB_Ignore,wdx,wdy):SetWindowState(wedit,#PB_Window_Normal):ReleaseMouse(1):EndIf
If KeyboardPushed(#PB_Key_F5):SetWindowState(wedit,#PB_Window_Normal):ReleaseMouse(1):SetActiveGadget(gSc):EndIf
Case #PB_Event_Gadget
If EventType()=#PB_EventType_Change
Select EventGadget()
EndSelect
EndIf
If EventType()=#PB_EventType_LeftClick
Select EventGadget()
Case gsticky:StickyWindow(wedit,GetGadgetState(gsticky))
Case gparamauto:waffparamauto()
EndSelect
EndIf
EndSelect
EndProcedure
Procedure editorShow()
Protected i,event,g.s=Chr(34),c.s,opt,hs,lg.s=#LF$+LSet("", 80, "_")+#LF$
ExamineDesktops():hs=DesktopHeight(0)*0.6
wedit=OpenWindow(-1, 00, 30, 800, hs, e_tile+" [F5] Test/Editor", #PB_Window_SystemMenu)
AddKeyboardShortcut(wedit,#PB_Shortcut_F5,1)
AddWindowTimer(wedit,333,100)
BindEvent(#PB_Event_Menu,@editorevent(),wedit ,#PB_All ,#PB_All )
BindEvent(#PB_Event_CloseWindow,@editorevent(),wedit ,#PB_All ,#PB_All )
BindEvent(#PB_Event_Gadget,@editorevent(),wedit ,#PB_All ,#PB_All )
BindEvent(#PB_Event_Timer,@editorevent(),wedit ,#PB_All ,#PB_All )
gsticky=ButtonGadget(-1,800-50-8,0,50,30,"Sticky",#PB_Button_Toggle)
gparamauto=ButtonGadget(-1,8,0,80,30,"Param auto")
gSc=ScintillaGadget(-1, 0, 30 , 800, WindowHeight(wedit,#PB_Window_InnerCoordinate)-30, @ScCallBack()):
ScintillaProperties();:BindGadgetEvent(gSc,@waffparamauto(),#PB_EventType_RightClick)
;Neutraliser la touche TAB et les caractéres spéciaux
RemoveKeyboardShortcut(wedit, #PB_Shortcut_Tab)
ssm(#SCI_SETTEXT, 0,UTF8(InsertString(lg,"Vertex",40)+e_vpg+InsertString(lg,"Fragment",40)+e_fpg))
EndProcedure
Procedure init()
Protected i,atc.s=" "
Restore paramauto
For i=0 To 136
With paramauto(i)
Read.s \type
Read.s \param
Read.s \nomc
Read.s \nomOgre
Read.s \comment
atc+\nomc+" "
EndWith
Next
;lword(#Style_UniformI)=atc
;lword(#Style_VaryingI)=" ouv ovcolor olightdir oviewdir olightatt onormal ofogf opos_w "
lword(#Style_Type)=" float vec2 vec3 vec4 bool bvec2 bvec3 bvec4 int ivec2 ivec3 ivec4 mat2 mat3 mat4 sampler1D sampler2D sampler3D samplerCube sampler2DShadow "
lword(#Style_Keyword)="const dFdx dFdy floor ceil sin cos tan atan mod for fract abs attribute ftransform uniform varying normalize distance length if else clamp mix min max cross dot reflect refract pow texture return step smoothstep "
lword(#Style_input)=" tangent gl_Vertex gl_Normal gl_Color gl_Position gl_TextureMatrix gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 gl_FragColor gl_FragCoord gl_FragDepth gl_FrontFacing "
;lword(#Style_Macro)=" tbn diff spec fresnel "
EndProcedure
Structure suniform
nom.s
nomc.s
param.s
EndStructure
Procedure.s shCodec(txt.s,sens=0)
Protected.s sh,np,ll,c,fl
Protected i,j,pg,p,pp,n,nl
Dim l.s(0)
Dim c.s(0)
NewList u.suniform()
If sens=0:fl="%":Else:fl=#LF$:EndIf
txt=ReplaceString(txt,#CRLF$,#LF$)
sh=""
nl=Split(l(),txt,fl)
For j=1 To nl
ll=supspace(l(j))
Split(c(),ll," ")
If sens=0
For i=2 To Len(#separateurs)
c=Mid(#separateurs,i,1)
ll=ReplaceString(ll," "+c,c)
ll=ReplaceString(ll,c+" ",c)
Next
EndIf
If c(1)="uniform"
p=FindString(c(3),";//+")
If p And ArraySize(c())<4 ; pas de param opt
n=Val(Mid(c(3),p+4))
pp=FindString(c(3),"["):If pp:p=pp:EndIf
AddElement(u()):u()\nom=Left(c(3),p-1):If sens=0:u()\nomc="P"+n:Else:u()\nomc=paramauto(n)\nomc:EndIf
EndIf
EndIf
sh+ll:If j<nl:sh+fl:EndIf
Next
ForEach u():sh=ReplaceStringww(sh,u()\nom,u()\nomc):Next
ProcedureReturn sh
EndProcedure
Procedure shaderexport(compression,format)
Protected txt.s,chemin.s,g.s=Chr(34),t.s=ssmgettext()
e_vpg=Stringparse(t,"___"+#LF$,#LF$+"___")
e_fpg=Stringparse(t+"%","___"+#LF$,"%",FindString(t,"___"+#LF$)+1)
If compression
e_vpg=ReplaceString(e_vpg,#LF$,"%"):e_vpg=ReplaceString(e_vpg,#CR$,"")
e_fpg=ReplaceString(e_fpg,#LF$,"%"):e_fpg=ReplaceString(e_fpg,#CR$,"")
EndIf
If compression=2:e_vpg=shCodec(e_vpg):e_fpg=shCodec(e_fpg):EndIf
Select format
Case 0;pb
txt="CreateShader("+e_sid+","+g+e_vpg+g+","+g+e_fpg+g+")"+#CRLF$
Case 1;c
txt=","+g+e_vpg+g+#CRLF$+","+g+e_fpg+g+#CRLF$
Case 2;gen
txt="v="+g+e_vpg+g+#CRLF$+"f="+g+e_fpg+g+#CRLF$
EndSelect
CreateShader(e_sid,e_vpg,e_fpg)
RenderWorld()
Static posf,m.s,l
Protected ok=1,p,log.s,fic.s=GetCurrentDirectory()+"Ogre"
CopyFile(fic+".log", fic+".tmp")
log=lirefic(fic+".tmp")
Macro sokmess(balise,pgtype)
p=FindString(log,"sh"+e_sid+balise,posf)
If p
m=Mid(log,p+11,FindString(log,#LF$,p+11)-(p+11))
l=Val(Stringparse(m,"0:",":"))+CountString(Left(t,FindString(t,"_"+pgtype+"_")),#LF$)+1
MessageRequester(e_tile+"ERROR "+pgtype+" shader", m+#CRLF$+"ligne "+l)
ok=0
EndIf
EndMacro
;ogre v1.8
sokmess("VPERROR","Vertex")
sokmess("FPERROR","Fragment")
;ogre v1.14
sokmess("VP' ERROR","Vertex")
sokmess("FP' ERROR","Fragment")
posf=FileSize(fic+".tmp")
If ok:e_return=txt:CallFunctionFast(e_materialproc):EndIf
ProcedureReturn ok
EndProcedure
Procedure CreateShader_(shaderid,vertexprogram.s,fragmentprogram.s)
CreateShader(shaderid,vertexprogram,fragmentprogram)
EndProcedure
Macro CreateShader(shaderid,vertexprogram,fragmentprogram)
e_sid=shaderid
e_vpg=vertexprogram
e_fpg=fragmentprogram
CreateShader_(shaderid,vertexprogram,fragmentprogram)
e_vpg=ReplaceString(e_vpg,"%",#LF$)
e_fpg=ReplaceString(e_fpg,"%",#LF$)
e_vpg=shCodec(e_vpg,1)
e_fpg=shCodec(e_fpg,1)
ReleaseMouse(1)
EndMacro
Procedure editshadermaterial(proc)
e_materialproc=proc
editorShow()
EndProcedure
init()
DataSection
paramauto:
Data.s "mat4","","world_mx","world_matrix","The current world matrix"
Data.s "mat4","","inverse_world_mx","inverse_world_matrix","The current world matrix, inverted"
Data.s "mat4","","transpose_world_mx","transpose_world_matrix","Provides transpose of world matrix."
Data.s "mat4","","inverse_transpose_world_mx","inverse_transpose_world_matrix","The current world matrix, inverted & transposed"
Data.s "mat4","","bone_3x4","bone_matrix_array_3x4","An array of bone matrices, each represented as only a 3x4 matrix (3 rows of4columns) usually for doing hardware skinning.You should make enough entries available in your vertex program for the number ofbones in use, i.e. an array of numBones*3 float4’s."
Data.s "mat4","","bone_mx","bone_matrix_array","The current array of bone matrices, used for blending"
Data.s "mat4","","bone_dualquaternion_2x4","bone_dualquaternion_array_2x4","The current array of bone matrices transformed to an array of dual quaternions,represented as a 2x4 matrix"
Data.s "mat4","","bone_scale_shear_matrix_3x4","bone_scale_shear_matrix_array_3x4","The scale and shear components of the current array of bone matrices"
Data.s "mat4","","view_mx","view_matrix","The current view matrix"
Data.s "mat4","","inverse_view_mx","inverse_view_matrix","The current view matrix, inverted"
Data.s "mat4","","transpose_view_mx","transpose_view_matrix","Provides transpose of view matrix."
Data.s "mat4","","inverse_transpose_view_mx","inverse_transpose_view_matrix","Provides inverse transpose of view matrix."
Data.s "mat4","","projection_mx","projection_matrix","The current projection matrix"
Data.s "mat4","","inverse_projection_mx","inverse_projection_matrix","Provides inverse of projection matrix."
Data.s "mat4","","transpose_projection_mx","transpose_projection_matrix","Provides transpose of projection matrix."
Data.s "mat4","","inverse_transpose_projection_mx","inverse_transpose_projection_matrix","Provides inverse transpose of projection matrix."
Data.s "mat4","","viewproj_mx","viewproj_matrix","The current view & projection matrices concatenated"
Data.s "mat4","","inverse_viewproj_mx","inverse_viewproj_matrix","Provides inverse of concatenated view and projection matrices."
Data.s "mat4","","transpose_viewproj_mx","transpose_viewproj_matrix","Provides transpose of concatenated view and projection matrices."
Data.s "mat4","","inverse_transpose_viewproj_mx","inverse_transpose_viewproj_matrix","Provides inverse transpose of concatenated view and projection matrices."
Data.s "mat4","","worldview_mx","worldview_matrix","The current world & view matrices concatenated"
Data.s "mat4","","inverse_worldview_mx","inverse_worldview_matrix","The current world & view matrices concatenated, then inverted"
Data.s "mat4","","transpose_worldview_mx","transpose_worldview_matrix","Provides transpose of concatenated world and view matrices."
Data.s "mat4","","inverse_transpose_worldview_mx","inverse_transpose_worldview_matrix","The current world & view matrices concatenated, then inverted & transposed"
Data.s "mat4","","normal_mx","normal_matrix","Provides inverse transpose of the upper 3x3 of the worldview matrix.ivalent to @c gl_NormalMatrix."
Data.s "mat4","","worldviewproj_mx","worldviewproj_matrix","The current world, view & projection matrices concatenated"
Data.s "mat4","","inverse_worldviewproj_mx","inverse_worldviewproj_matrix","Provides inverse of concatenated world, view and projection matrices."
Data.s "mat4","","transpose_worldviewproj_mx","transpose_worldviewproj_matrix","Provides transpose of concatenated world, view and projection matrices."
Data.s "mat4","","inverse_transpose_worldviewproj_mx","inverse_transpose_worldviewproj_matrix","Provides inverse transpose of concatenated world, view and projectionrices."
Data.s "float","","render_target_flipping","render_target_flipping","render target related values-1 if requires texture flipping, +1 otherwise. It's useful when you bypassedjection matrix transform, still able use this value to adjust transformed yition."
Data.s "float","","vertex_winding","vertex_winding","-1 if the winding has been inverted, +1 otherwise..g. for reflections"
Data.s "vec4","","fog_colour","fog_colour","Fog colour"
Data.s "vec4","","fog_params","fog_params","Fog params: `(density, linear start, linear end, 1/(end-start))`"
Data.s "vec4","","surface_ambient_colour","surface_ambient_colour","Surface ambient colour, as set in Pass::setAmbient"
Data.s "vec4","","surface_diffuse_colour","surface_diffuse_colour","Surface diffuse colour, as set in Pass::setDiffuse"
Data.s "vec4","","surface_specular_colour","surface_specular_colour","Surface specular colour, as set in Pass::setSpecular"
Data.s "vec4","","surface_emissive_colour","surface_emissive_colour","Surface emissive colour, as set in Pass::setSelfIllumination"
Data.s "float","","shininess","surface_shininess","Surface shininess, as set in Pass::setShininess"
Data.s "float","","surface_alpha_rejection_value","surface_alpha_rejection_value","Surface alpha rejection value, not as set in @ref Pass::setAlphaRejectValue, but afloating number between 0.0f and 1.0f instead (255.0f /@ref Pass::getAlphaRejectValue())"
Data.s "float","","light_count","light_count","The number of active light sources"
Data.s "vec4","","ambient_light_colour","ambient_light_colour","The ambient light colour set in the scene"
Data.s "vec4","0","light_diffuse_colour","light_diffuse_colour","Light diffuse colour (index determined by setAutoConstant call).this requires an index in the ’extra_params’ field, and relates to the ’nth’ closestlight which could affect this object(i.e. 0 refers to the closest light - note that directional lights are always firstin the list and always present).NB if there are no lights this close, then the parameter will be set to black."
Data.s "vec4","0","light_specular_colour","light_specular_colour","Light specular colour (index determined by setAutoConstant call)"
Data.s "vec4","0","light_att","light_attenuation","Light attenuation parameters.acked as `(range, constant, linear, quadric)`.or area lights this contains the height half-vector `(x, y, z, 0)` of the light in viewspace."
Data.s "vec4","0","spotlight_params","spotlight_params","Spotlight parameters.ked as `(innerFactor, outerFactor, falloff, spotType)`erFactor and outerFactor are cos(angle/2)spotType parameter is 0.0f for non-spotlights, 1.0f for spotlights and 2.0f fora spotlights.area lights this contains the width half-vector `(x, y, z, 2)` of the light in viewspace.o for non-spotlights the inner and outer factors are 1 and 0 respectively"
Data.s "vec4","0","light_pos","light_position","A light position in world space (index determined by setAutoConstant call).s requires an index in the ’extra_params’ field, and relates to the ’nth’ closestht which could affect this object (i.e. 0 refers to the closest light).if there are no lights this close, then the parameter will be set to all zeroes.e that this property will work with all kinds of lights, even directional lights,ce the parameter is set as a 4D vector.nt lights will be `(pos.x, pos.y, pos.z, 1.0f)` whilst directional lights will bedir.x, -dir.y, -dir.z, 0.0f)`.rations like dot products will work consistently on both."
Data.s "vec4","0","light_pos_os","light_position_object_space","A light position in object space (index determined by setAutoConstant call)"
Data.s "vec4","0","light_pos_vs","light_position_view_space","A light position in view space (index determined by setAutoConstant call)"
Data.s "vec4","0","light_dir","light_direction","A light direction in world space (index determined by setAutoConstant call)@deprecated this property only works on directional lights, and we recommend thatyou use light_position instead since that returns a generic 4D vector."
Data.s "vec4","0","light_dir_os","light_direction_object_space","A light direction in object space (index determined by setAutoConstant call)"
Data.s "vec4","0","light_dir_vs","light_direction_view_space","A light direction in view space (index determined by setAutoConstant call)"
Data.s "float","0","light_distance_os","light_distance_object_space","The distance of the light from the center of the objectseful approximation as an alternative to per-vertex distanceculations."
Data.s "float","","light_power_scale","light_power_scale","Light power level, a single scalar as set in Light::setPowerScale (index determinedsetAutoConstant call) */"
Data.s "vec4","","light_diffuse_colour_power_scaled","light_diffuse_colour_power_scaled","Light diffuse colour pre-scaled by Light::setPowerScale (index determined bysetAutoConstant call)"
Data.s "vec4","","light_specular_colour_power_scaled","light_specular_colour_power_scaled","Light specular colour pre-scaled by Light::setPowerScale (index determined bysetAutoConstant call)"
Data.s "vec4","0","light_diffuse_colour_array","light_diffuse_colour_array","Array of light diffuse colours (count set by extra param)"
Data.s "vec4","0","light_specular_colour_array","light_specular_colour_array","Array of light specular colours (count set by extra param)"
Data.s "vec4","0","light_diffuse_colour_power_scaled_array","light_diffuse_colour_power_scaled_array","Array of light diffuse colours scaled by light power (count set by extra param)"
Data.s "vec4","0","light_specular_colour_power_scaled_array","light_specular_colour_power_scaled_array","Array of light specular colours scaled by light power (count set by extra param)"
Data.s "float","0","light_attenuation_array","light_attenuation_array","Array of light attenuation parameters.@copydetails #ACT_LIGHT_ATTENUATION (count set by extra param)"
Data.s "vec4","0","light_pos_array","light_position_array","Array of light positions in world space (count set by extra param)"
Data.s "vec4","0","light_pos_os_array","light_position_object_space_array","Array of light positions in object space (count set by extra param)"
Data.s "vec4","0","light_pos_vs_array","light_position_view_space_array","Array of light positions in view space (count set by extra param)"
Data.s "vec4","0","light_dir_array","light_direction_array","Array of light directions in world space (count set by extra param)"
Data.s "vec4","0","light_dir_os_array","light_direction_object_space_array","Array of light directions in object space (count set by extra param)"
Data.s "vec4","0","light_dir_vs_array","light_direction_view_space_array","Array of light directions in view space (count set by extra param)"
Data.s "float","0","light_distance_os_array","light_distance_object_space_array","Array of distances of the lights from the center of the objectseful approximation as an alternative to per-vertex distanceculations. (count set by extra param)"
Data.s "float","","light_power_scale_array","light_power_scale_array","Array of light power levels, a single scalar as set in Light::setPowerScaleunt set by extra param)"
Data.s "float","0","spotlight_params_array","spotlight_params_array","Spotlight parameters arraycopydetails #ACT_SPOTLIGHT_PARAMScount set by extra param)"
Data.s "vec4","","ambient_ml","derived_ambient_light_colour","The derived ambient light colour, with 'r', 'g', 'b' components filled withduct of surface ambient colour and ambient light colour, respectively,'a' component filled with surface diffuse alpha component."
Data.s "vec4","","derived_scene_colour","derived_scene_colour","The derived scene colour, with 'r', 'g' and 'b' components filled with sumderived ambient light colour and surface emissive colour, respectively,'a' component filled with surface diffuse alpha component."
Data.s "vec4","0","diffuse_ml","derived_light_diffuse_colour","The derived light diffuse colour (index determined by setAutoConstant call),h 'r', 'g' and 'b' components filled with product of surface diffuse colour,ht power scale and light diffuse colour, respectively, and 'a' component filledh surfacefuse alpha component."
Data.s "vec4","0","specular_ml","derived_light_specular_colour","The derived light specular colour (index determined by setAutoConstant call),h 'r', 'g' and 'b' components filled with product of surface specular colourlight specular colour, respectively, and 'a' component filled with surfacecular alpha component."
Data.s "vec4","0","diffuse_ml_array","derived_light_diffuse_colour_array","Array of derived light diffuse colours (count set by extra param)"
Data.s "vec4","0","specular_ml_array","derived_light_specular_colour_array","Array of derived light specular colours (count set by extra param)"
Data.s "float","","light_number","light_number","The absolute light number of a local light index. Each pass may haveumber of lights passed to it, and each of these lights will haveindex in the overall light list, which will differ from the localht index due to factors like setStartLight and setIteratePerLight.s binding provides the global light index for a local index."
Data.s "float","","light_casts_shadows","light_casts_shadows","Returns (int) 1 if the given light casts shadows, 0 otherwise (index set in extraparam)"
Data.s "","","light_casts_shadows_array","light_casts_shadows_array","Returns (int) 1 if the given light casts shadows, 0 otherwise (index set in extraparam)"
Data.s "float","","shadow_extrusion_distance","shadow_extrusion_distance","The distance a shadow volume should be extruded when usingite extrusion programs."
Data.s "vec4","","camera_pos","camera_position","The current camera's position in world space"
Data.s "vec4","","camera_pos_os","camera_position_object_space","The current camera's position in object space"
Data.s "","","camera_relative_position","camera_relative_position","The current camera's position in world space even when camera relative rendering is enabled"
Data.s "mat4","0","texture_viewproj_matrix","texture_viewproj_matrix","The view/projection matrix of the assigned texture projection frustum.licable to vertex programs which have been specified as the ’shadow receiver’ vertexgram alternative, or where a texture unit is marked as content_type shadow; thisvides details of the view/projection matrix for the current shadow projector. Theional ’extra_params’ entry specifies which light the projector refers to (for thee of content_type shadow where more than one shadow texture may be present in agle pass), where 0 is the default and refers to the first light referenced in thiss."
Data.s "float","0","texture_viewproj_matrix_array","texture_viewproj_matrix_array","Array of view/projection matrices of the first n texture projection frustums"
Data.s "mat4","","texture_worldviewproj_matrix","texture_worldviewproj_matrix","The view/projection matrix of the assigned texture projection frustum,bined with the current world matrix"
Data.s "float","0","texture_worldviewproj_matrix_array","texture_worldviewproj_matrix_array","Array of world/view/projection matrices of the first n texture projection frustums"
Data.s "mat4","0","spotlight_viewproj_matrix","spotlight_viewproj_matrix","The view/projection matrix of a given spotlight"
Data.s "float","0","spotlight_viewproj_matrix_array","spotlight_viewproj_matrix_array","Array of view/projection matrix of a given spotlight"
Data.s "mat4","","spotlight_worldviewproj_matrix","spotlight_worldviewproj_matrix","The view/projection matrix of a given spotlight projection frustum,bined with the current world matrix"
Data.s "","","spotlight_worldviewproj_matrix_array","spotlight_worldviewproj_matrix_array","An array of the view/projection matrix of a given spotlight projection frustum,bined with the current world matrix"
Data.s "vec4","0","custom","custom","A custom parameter which will come from the renderable, using 'data' as thentifiers allows you to map a custom parameter on an individual Renderable (seederable::setCustomParameter) to a parameter on a GPU program. It requires that youplete the ’extra_params’ field with the index that was used in thederable::setCustomParameter call, and this will ensure that whenever this Renderableused, it will have it’s custom parameter mapped in. It’s very important that thisameter has been defined on all Renderables that are assigned the material thattains this automatic mapping, otherwise the process will fail."
Data.s "float","","time","time","provides current elapsed time"
Data.s "float","0","time_0_x","time_0_x","Single float value, which repeats itself based on given asameter 'cycle time'."
Data.s "float","","costime_0_x","costime_0_x","Cosine of 'Time0_X'."
Data.s "float","","sintime_0_x","sintime_0_x","Sine of 'Time0_X'."
Data.s "float","","tantime_0_x","tantime_0_x","Tangent of 'Time0_X'."
Data.s "float","","time_0_x_packed","time_0_x_packed","Vector of 'Time0_X', 'SinTime0_X', 'CosTime0_X',nTime0_X'."
Data.s "float","","time_0_1","time_0_1","Single float value, which represents scaled time value [0..1],ch repeats itself based on given as parameter 'cycle time'."
Data.s "float","","costime_0_1","costime_0_1","Cosine of 'Time0_1'."
Data.s "float","","sintime_0_1","sintime_0_1","Sine of 'Time0_1'."
Data.s "float","","tantime_0_1","tantime_0_1","Tangent of 'Time0_1'."
Data.s "float","","time_0_1_packed","time_0_1_packed","Vector of 'Time0_1', 'SinTime0_1', 'CosTime0_1',nTime0_1'."
Data.s "float","","time_0_2pi","time_0_2pi","Single float value, which represents scaled time value [0..2*Pi],ch repeats itself based on given as parameter 'cycle time'."
Data.s "float","","costime_0_2pi","costime_0_2pi","Cosine of 'Time0_2PI'."
Data.s "float","","sintime_0_2pi","sintime_0_2pi","Sine of 'Time0_2PI'."
Data.s "float","","tantime_0_2pi","tantime_0_2pi","Tangent of 'Time0_2PI'."
Data.s "float","","time_0_2pi_packed","time_0_2pi_packed","Vector of 'Time0_2PI', 'SinTime0_2PI', 'CosTime0_2PI',nTime0_2PI'."
Data.s "float","","frame_time","frame_time","provides the scaled frame time, returned as a floating point value."
Data.s "float","","fps","fps","provides the calculated frames per second, returned as a floating point value."
Data.s "float","","viewport_width","viewport_width","viewport-related valuesCurrent viewport width (in pixels) as floating point value."
Data.s "float","","viewport_height","viewport_height","Current viewport height (in pixels) as floating point value."
Data.s "float","","inverse_viewport_width","inverse_viewport_width","This variable represents `1/ViewportWidth`."
Data.s "float","","inverse_viewport_height","inverse_viewport_height","This variable represents `1/ViewportHeight`."
Data.s "float","","viewport","viewport_size","Viewport dimensions.ked as `(ViewportWidth, ViewportHeight, 1/ViewportWidth, 1/ViewportHeight)`"
Data.s "vec4","","view_dir","view_direction","view parametersThis variable provides the view direction vector (world space)."
Data.s "float","","view_side_vector","view_side_vector","This variable provides the view side vector (world space)."
Data.s "float","","view_up_vector","view_up_vector","This variable provides the view up vector (world space)."
Data.s "float","","fov","fov","This variable provides the field of view as a floating point value."
Data.s "float","","near_clip_distance","near_clip_distance","This variable provides the near clip distance as a floating point value."
Data.s "float","","far_clip_distance","far_clip_distance","This variable provides the far clip distance as a floating point value."
Data.s "float","","pass_number","pass_number","provides the pass index number within the techniquethe active material."
Data.s "float","","pass_iteration_number","pass_iteration_number","provides the current iteration number of the pass. The iterationber is the number of times the current render operation hasn drawn for the active pass."
Data.s "float","","animation_parametric","animation_parametric","Provides a parametric animation value [0..1], only availablere the renderable specifically implements it.morph animation, sets the parametric value.1) representing the distance between the first position keyframe (bound toitions) and the second position keyframe (bound to the first free texturerdinate) so that the vertex program can interpolate between them. For posemation, indicates a group of up to 4 parametric weight values applying to auence of up to 4 poses (each one bound to x, y, z and w of the constant), one forh pose. The original positions are held in the usual position buffer, and thesets to take those positions to the pose where weight == 1.0 are in the first ’n’e texture coordinates; ’n’ being determined by the value passed toludes_pose_animation. If more than 4 simultaneous poses are required, then you’lld more than 1 shader constant to hold the parametric values, in which case youuld use this binding more than once, referencing a different constant entry; theond one will contain the parametrics for poses 5-8, the third for poses 9-12, andon."
Data.s "float","","texel_offsets","texel_offsets","Provides the texel offsets required by this rendersystem to mapels to pixels. Packed asbsoluteHorizontalOffset, absoluteVerticalOffset, horizontalOffset / viewportWidth, verticalOffset / viewportHeight)`"
Data.s "vec4","","scene_depth_range","scene_depth_range","Provides information about the depth range of the scene as viewedm the current camera.sed as `(minDepth, maxDepth, depthRange, 1 / depthRange)`"
Data.s "vec4","","shadow_scene_depth_range","shadow_scene_depth_range","Provides information about the depth range of the scene as viewedm a given shadow camera. Requires an index parameter which mapsa light index relative to the current light list.sed as `(minDepth, maxDepth, depthRange, 1 / depthRange)`"
Data.s "","","shadow_scene_depth_range_array","shadow_scene_depth_range_array","Provides an array of information about the depth range of the scene as viewedm a given shadow camera. Requires an index parameter which mapsa light index relative to the current light list.sed as `(minDepth, maxDepth, depthRange, 1 / depthRange)`"
Data.s "vec4","","shadow_colour","shadow_colour","Provides the fixed shadow colour as configured via SceneManager::setShadowColour;ful for integrated modulative shadows."
Data.s "vec4","","texture_size","texture_size","Provides texture size of the texture unit (index determined by setAutoConstantl). Packed as `(width, height, depth, numMipMaps)`"
Data.s "vec4","","inverse_texture_size","inverse_texture_size","Provides inverse texture size of the texture unit (index determined byAutoConstantl). Packed as `(1 / width, 1 / height, 1 / depth, 1 / numMipMaps)`"
Data.s "vec4","","packed_texture_size","packed_texture_size","Provides packed texture size of the texture unit (index determined byAutoConstantl). Packed as `(width, height, 1 / width, 1 / height)`"
Data.s "mat4","0","texture_matrix","texture_matrix","Provides the current transform matrix of the texture unit (index determined byAutoConstantl), as seen by the fixed-function pipeline.s requires an index in the ’extra_params’ field, and relates to the ’nth’ texturet of the pass in question.if the given index exceeds the number of texture units available for this pass,n the parameter will be set to Matrix4::IDENTITY."
Data.s "vec4","","lod_camera_pos","lod_camera_position","Provides the position of the LOD camera in world space, allowing youperform separate LOD calculations in shaders independent of the renderingera. If there is no separate LOD camera then this is the real cameraition. See Camera::setLodCamera."
Data.s "vec4","","lod_camera_pos_os","lod_camera_position_object_space","Provides the position of the LOD camera in object space, allowing youperform separate LOD calculations in shaders independent of the renderingera. If there is no separate LOD camera then this is the real cameraition. See Camera::setLodCamera."
Data.s "????","","light_custom","light_custom","Binds custom per-light constants to the shaders. */"
Data.s "","","point_params","point_params","Point attenuation params.Packed as `(size, constant, linear, quadratic)`"
Data.s "","","material_lod_index","material_lod_index","the LOD index as selected by the active LodStrategy"
EndDataSection
DisableExplicit
Example of use: (quantification of the normal)
Code: Select all
IncludeFile "...\shader_editor.pb"
InitEngine3D(#PB_Engine3D_DebugLog):InitSprite():InitKeyboard():InitMouse()
ExamineDesktops():dx=DesktopWidth(0)*0.8:dy=DesktopHeight(0)*0.8
OpenWindow(0, 0,0, DesktopUnscaledX(dx),DesktopUnscaledY(dy), "CreateShaderMaterial - [Esc] quit",#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, dx, dy, 0, 0, 0)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures/nvidia", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Packs/desert.zip", #PB_3DArchive_Zip)
Parse3DScripts()
SkyBox("desert07.jpg")
Macro lt(face):LoadTexture(#PB_Any,"desert07_"+face+".jpg"):EndMacro
tx_Cubic=CreateCubicTexture(#PB_Any,lt("px"),lt("nx"),lt("py"),lt("ny"),lt("pz"),lt("nz"))
tx_rock_diff=LoadTexture(#PB_Any,"dirt_grayrocky_diffusespecular.jpg")
tx_rock_normal=LoadTexture(#PB_Any,"dirt_grayrocky_normalheight.jpg")
CreateCamera(0, 0, 0, 100, 100):MoveCamera(0,0,8,16):CameraLookAt(0,0,0,0)
CreateLight(0, $ffffff, 8000, 5700,4500); ;light on the sun of the skybox !
AmbientColor($444444)
CreateCone(0,2,3)
CreateCapsule(1,1,1.5)
CreateSphere(2,1.5,32,32)
CreateTorus(3,1.5,0.6,32,32)
CreateTube(4,1.5,1,2)
CreateShader(0,"%#version 130%uniform mat4 P0;//+0%uniform mat4 P25;//+25%uniform vec4 P79;//+79%uniform vec4 P45;//+45%uniform vec4 P32;//+32%%varying vec3 oviewdir;%varying vec3 olightdir;%varying vec3 onormal;%varying vec4 ovcolor;%varying vec2 ouv;%varying float ofogf;%%void main()%{%vec4 pos=P0*gl_Vertex;%oviewdir=normalize(P79.xyz-pos.xyz);%olightdir=normalize(P45.xyz-pos.xyz);%gl_Position=P25*gl_Vertex;%onormal=gl_Normal;%ouv=(gl_TextureMatrix[0]*gl_MultiTexCoord0).xy;%ovcolor=gl_Color;%ofogf=P32.z>0?min(abs(gl_Position.z)*P32.w,1):0;%}","#version 130%%uniform vec4 P69;//+69%uniform vec4 P71;//+71%uniform vec4 P31;//+31%uniform mat4 P0;//+0%%uniform samplerCube cubemap;//0%uniform sampler2D diffuseMap;//1%%uniform float fc;//4%uniform float glossy;//0.5%%varying vec3 oviewdir;%varying vec3 olightdir;%varying vec3 onormal;%varying vec4 ovcolor;%varying vec2 ouv;%varying float ofogf;%%void main()%{%vec3 normal=normalize(floor(onormal*fc)/fc);normal=mat3(P0)*normal;%vec3 viewdir=normalize(oviewdir);%vec3 lightdir=normalize(olightdir);%%float dif=max(dot(lightdir,normal),0);%vec3 r=reflect(-oviewdir,normal);r.z*=-1;%vec4 tcolor1=texture(diffuseMap,ouv)*ovcolor;%vec4 tcolor2=texture(cubemap,r);%%vec4 color=mix(vec4(tcolor1.rgb,1)*(P69+P71*dif),tcolor2,glossy);%gl_FragColor=mix(color,P31,ofogf);%}%")
Procedure ShaderMaterial()
Shared tx_Cubic,tx_rock_diff,tx_rock_normal
For i=0 To 9
CreateShaderMaterial(i,0)
MaterialShaderTexture(i,TextureID(tx_Cubic),TextureID(tx_rock_diff),0,0)
SetMaterialAttribute(i,#PB_Material_TAM,#PB_Material_ClampTAM,0)
SetMaterialColor(i,3,RGB(128+Random(127),128+Random(127),128+Random(127)))
MaterialShininess(i,32*Pow(2,Random(5)),$ffffff)
;MaterialShaderParameter(i,#PB_Shader_Fragment,"fc",#PB_Shader_Float,Random(6,2),0,0,0)
MaterialShaderParameter(i,#PB_Shader_Fragment,"glossy",#PB_Shader_Float,Random(3,1)/4,0,0,0)
CreateEntity(i,MeshID(i%5),MaterialID(i)):RotateEntity(i,Random(360),Random(360),Random(360),#PB_Absolute)
Next
EndProcedure
editshadermaterial(@ShaderMaterial())
ShaderMaterial()
Procedure CameraUserControl(camera,speed.f=0.1,smooth.f=0.1,yfixed.f=1e10)
Static.f MouseX,Mousey,depx,depz,sdepx,sdepz, fdf.b
depx=-speed*(KeyboardPushed(#PB_Key_Left)-KeyboardPushed(#PB_Key_Right))
depz=-speed*(KeyboardPushed(#PB_Key_Down)-KeyboardPushed(#PB_Key_Up)-MouseWheel()*20)
If KeyboardReleased(#PB_Key_F12):fdf=1-fdf:If fdf:CameraRenderMode(0,#PB_Camera_Wireframe):Else:CameraRenderMode(0,#PB_Camera_Textured):EndIf:EndIf
MouseX = -MouseDeltaX() * 0.05
MouseY = -MouseDeltaY() * 0.05
RotateCamera(camera, MouseY, MouseX, 0, #PB_Relative)
sdepx+(depx-sdepx)*smooth
sdepz+(depz-sdepz)*smooth
MoveCamera (camera, sdepX, 0, -sdepz)
If yfixed<>1e10:MoveCamera(camera,CameraX(camera),yfixed,CameraZ(camera),#PB_Absolute):EndIf
EndProcedure
Repeat
While WindowEvent():Wend
ExamineKeyboard()
ExamineMouse()
CameraUserControl(0)
da.f+0.001
For i=0 To 9
a.f=i*2*#PI/10+da
MoveEntity(i,Cos(a)*8,2,Sin(a)*8,#PB_Absolute):RotateEntity(i,0.2,0.2,0.2,#PB_Relative)
Next
RenderWorld()
FlipBuffers()
Until KeyboardReleased(#PB_Key_Escape) Or MouseButton(3)