Artus wrote:No i dont mean the shader it self, i mean the integration in my programm vie PureBasic.
OK, I'll get back the example 201 in the retailer.
some global initializations,
Code: Select all
; Include files
IncludePath "includes" : IncludeFile "n3xtD_PB.pbi"
EnableExplicit
Declare CallbackShader(*services.IMaterialServices, userData.l)
; Globales
Global anglex.f, angley.f, flagXDown.w
Global mox.f, omx.f, moy.l, omy.l
Global *app.l, Quit.l, video.l
;----------------------------------------------------------
; open n3xt-D screen
*app = iCreateGraphics3D(800,600) : video = #EDT_OPENGL
; << OR >>
;*app = iCreateGraphics3D(800,600, 32, #False, #True, #EDT_DIRECT3D9) : video = #EDT_DIRECT3D9
If *app= #Null
End
EndIf
SetCurrentDirectory("media/")
;-----------------------------------------
; create skybox
Global *sky.IMesh = iCreateSkybox( iLoadTexture("up.jpg"),iLoadTexture("dn.jpg"),iLoadTexture("lf.jpg"),iLoadTexture("rt.jpg"),iLoadTexture("ft.jpg"),iLoadTexture("bk.jpg"))
Load and create two Shaders (HLSL or GLSL).
we make the difference between DX9 and OpenGL to load the correct class of shader.
We use for this, the
iCreateShaderHighLevel instruction:
iCreateShaderHighLevel.l(vsFileName.s, EntryNameVS.s, psFileName.s, EntryNamePS.s, videottype.l, *constantshaderFnt.l, *materialshaderFnt.l )
with this parameters:
vsFileName: vertex shader filename to load.
EntryNameVS.s: entry name procedure inside the shader for the vertex shader program.
psFileName.s: pixel shader filename to load.
EntryNamePS.s: entry name procedure inside the shader for the pixel shader program.
videottype.l: the number of the material type which can be set in SMaterial::MaterialType to use the renderer
*constantshaderFnt.l: Pointer to an implementation of OnSetConstants in which you can set the needed vertex and pixel shader.
*materialshaderFnt.l: not used here.
Code: Select all
;-----------------------------------------
; load and create shader
Global shad.l
Global shad2.l
iVersionShader(#EVST_VS_1_1, #EPST_PS_2_0)
If video = #EDT_DIRECT3D9
shad = iCreateShaderHighLevel("d3d9.hlsl", "vertexMain", "d3d9.hlsl", "pixelMain", #EMT_SOLID, @CallbackShader(), #Null)
shad2 = iCreateShaderHighLevel("d3d9.hlsl", "vertexMain", "d3d9.hlsl", "pixelMain", #EMT_TRANSPARENT_ADD_COLOR, @CallbackShader(), #Null)
Else
shad = iCreateShaderHighLevel("opengl.vert", "vertexMain", "opengl.frag", "pixelMain", #EMT_SOLID, @CallbackShader(), #Null)
shad2 = iCreateShaderHighLevel("opengl.vert", "vertexMain", "opengl.frag", "pixelMain", #EMT_TRANSPARENT_ADD_COLOR, @CallbackShader(), #Null)
EndIf
create one cube without shader,
Code: Select all
;-----------------------------------------
; add cube
Global *cube0.IMesh = iCreateCube(1.0)
iPositionNode(*cube0, -1,-1,1)
iLoadTextureNode(*cube0, "wall.jpg")
iMaterialFlagNode(*cube0, #EMF_LIGHTING, #False)
and create two cubes with shader for de rendering.
This is the instruction line
iMaterialTypeNode(*cube, shad) which assigns to our cube a specific shader.
Code: Select all
;-----------------------------------------
; add second cube
Global *cube.IMesh = iCreateCube(1.0)
iPositionNode(*cube, 0,-1.3,0)
iLoadTextureNode(*cube, "wall.jpg")
iMaterialFlagNode(*cube, #EMF_LIGHTING, #False)
iMaterialTypeNode(*cube, shad)
;-----------------------------------------
; add third cube
Global *cube2.IMesh = iCreateCube(1.0)
iPositionNode(*cube2, 1,-1.3,1)
iLoadTextureNode(*cube2, "wall.jpg")
iMaterialFlagNode(*cube2, #EMF_LIGHTING, #False)
iMaterialTypeNode(*cube2, shad2)
create camera
Code: Select all
;-----------------------------------------
; create first camera
Global *cam.ICamera = iCreateCamera( )
iPositionNode(*cam, 0,0,-3)
iTurnNode(*cam, 10,0,0)
and main loop, standart.
Code: Select all
Repeat
iTurnNode(*cube0, 0,0.5,0)
iTurnNode(*cube, 0,0.5,0)
iTurnNode(*cube2, 0,0.5,0)
; ------------------------------------------------
; move camera with dir key and mouse (left click)
If iGetKeyDown(#KEY_ARROW_UP)
iMoveNode(*cam, 0,0,0.1)
EndIf
If iGetKeyDown(#KEY_ARROW_DOWN)
iMoveNode(*cam, 0,0,-0.1)
EndIf
If iGetMouseEvent(#MOUSE_BUTTON_LEFT)
If flagXDown=0
omx = iGetMouseX()
omy = iGetMouseY()
flagXDown=11
Else
moy = iGetMouseY()-omy
angley=(moy/10.0)
omy= iGetMouseY()
mox = iGetMouseX()-omx
anglex=(mox/10.0)
omx= iGetMouseX()
iTurnNode(*cam, angley, anglex,0)
EndIf
Else
flagXDown=0
EndIf
; if Escape Key, exit
If iGetKeyDown(#KEY_ESCAPE)
Quit=1
EndIf
; ---------------
; Render
; ---------------
iBeginScene(100,100,100)
iDrawScene()
iEndScene()
Until Quit=1
; end
iFreeEngine()
Finally, an important procedure.
ShaderCallback, this procedure call at the each render pass for each node to which we assigned
a shader that link to this proceeding.
it is this area which will provide the data necessary for the shader run.
This procedure (CallBack) allows to update a set of data necessary for the proper
functioning of the shader and before each rendering.
Code: Select all
ProcedureC CallbackShader(*services.IMaterialServices, userData.l)
Protected mvp.iMATRIX
Protected invWorld.iMATRIX
Protected worldViewProj.iMATRIX
Protected pos.iVECTOR3
Protected Dim col.f(3)
Protected world.iMATRIX
iGetWorldTransform(@invWorld)
Matrix_GetInverse( @invWorld, @invWorld)
iVertexShaderConstantNMaterialServices(*services, "mInvWorld", @invWorld, 16)
;set clip matrix
iGetProjectionTransform(@worldViewProj)
iGetViewTransform(@mvp)
Matrix_Mul(@worldViewProj, @worldViewProj, @mvp)
iGetWorldTransform(@mvp)
Matrix_Mul(@worldViewProj, @worldViewProj, @mvp)
iVertexShaderConstantNMaterialServices(*services, "mWorldViewProj", @worldViewProj, 16)
; set camera position
iNodePosition(*cam, @pos)
iVertexShaderConstantNMaterialServices(*services, "mLightPos", @pos, 3)
; set light color
col(0)=0.0
col(1)=1.0
col(2)=1.0
col(3)=0.0
iVertexShaderConstantNMaterialServices(*services, "mLightColor", @col(0), 4)
; set transposed world matrix
iGetWorldTransform(@world)
Matrix_Transpose(@world)
iVertexShaderConstantNMaterialServices(*services, "mTransWorld", @world, 16)
EndProcedure
Well, I hope this clarifies a little better your lantern on the use of shaders by N3xtD and PB.
@chi good code
