J'ai réalisé un éditeur de map 2D et un début d'éditeur de scène (ou map c'est un peu pareil) 3D.
Voici un code que j'ai fait pour un éditeur de Shader (que je ne peux pas encore terminé car il manque la mise à jour des matériaux en pure, mais je le terminerai dés que ce sera ajouté) :
Code : Tout sélectionner
;{ Infos
; Pure Material Editor
; To create and /or modify a *.material and see the result in real time
; a simple viewer of object3D (mesh) and material/shader for PureOgre (ogre in purebasic ^^)
; date : 30 april 2012
; author : blendman
; pb : 4.61b2 win xp x32
;}
;{ constantes, enumeration
; Les constantes pour l'interface, les gadgets, etc...
; UI
#WindowMain = 0
#statusbar= 0
#MainMenu=0
Enumeration ; gadget window
;{ panel lieft
#PanelLeft
; Material
#MaterialLoad
#TextureInSameDir
#MaterialName
#MaterialCastShadow
; panel Bank
#panelBank
#gadget_bank_List
#gadget_bank_Theme
#gadget_bank_Group
;}
;{ panel right
#PanelRight
#Gadget_WorldShadow
#Gadget_ViewZoom
#cameraLookAt
#Gadget_SizeMesh
;}
EndEnumeration
;{ constantes pour la 3D
#Camera=0
#CameraSpeed = 5
#MeshSphere =0
#Entity=0
#material =0
#texture = 0
Enumeration ; light
#light1
#light2
#light3
EndEnumeration
;}
;}
;{ structures
Structure Stcamera
lookat.a : ViewZoom.a
SizeMesh.a : typeobj.a
EndStructure
Global camera.Stcamera ; j'ai utilisé une variable, mais on pourrait utilisé un pointeur
camera\ViewZoom = 1
camera\SizeMesh = 10
;}
;{ les variables, utilisés pour définir la taille des panneaux, de l'écran, etc..
VersionNum.s{6} = StrD(#pb_Editor_CompileCount/10000+0.1) : Version$ = VersionNum
PanelParameterH.w = 400 : PanelTexture.a= 200 : BottomSpace=60
Global PanelParameter.a = 200 ,TopSpace.a = 35
Global ScreenHeight.w,ScreenWidth.w,inscreen.a
;}
;{ declare : on déclare les procédures qu'on va utiliser ensuite.
Declare Error(message$)
Declare EventKeyboard() : Declare GestionMouse()
Declare ChangeObject(mode=0)
Declare.a Screen3DEvents()
;}
;{ initialisation : on doit initialiser tout ce qui est nécessaire.
If InitEngine3D() = 0 Or InitSprite()=0 Or InitKeyboard()=0 Or InitMouse() = 0
Error("Unable To initialize DirectX")
Else
; ensuite, on ajoute les chemins vers les archives.
; ici, tu dois créer un dossier dans lequel tu mettras tes dossiers :
; Models : tes models en .mesh
; Textures : tes textures (jpg, png, tga)
; Material : tes materials (*.material) : ce sont des fichiers qu'utilisent ogre pour définir les shaders/materiaux qu'il va utiliser sur tes meshs.
Add3DArchive("Data/Models", #PB_3DArchive_FileSystem)
Add3DArchive("Data/Textures", #PB_3DArchive_FileSystem)
Add3DArchive("Data/Material", #PB_3DArchive_FileSystem)
Parse3DScripts() ; on lui dit de tout faire automatiquement
EndIf
;}
;{ window : on ouvre la fenêtre
;{ openWindow
If ExamineDesktops() ; on examine le bureau, la taille, etc..
ScreenX = DesktopWidth(0) : ScreenY = DesktopHeight(0)-32
ScreenD = DesktopDepth(0) : ScreenF = DesktopFrequency(0)
EndIf
; on définit la fenêtre puis on l'ouvre
flag= #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MaximizeGadget|#PB_Window_MinimizeGadget|#PB_Window_Maximize
If OpenWindow(#WindowMain, 0, 0, ScreenX, ScreenY, "Pure Shader Editor (Version "+Version$+")", flag)=0
Error("Unable To open a Window")
Else
;}
;{ on créé le menu
If CreateMenu(#MainMenu, WindowID(#WindowMain))
MenuTitle("File"); 0 -> 40
MenuItem(1,"New Material")
MenuBar()
MenuItem(2,"Open Material (.material)")
MenuItem(3,"Import Material")
MenuBar()
MenuItem(4,"Save Material")
MenuItem(5,"Save Material as ...")
MenuBar()
MenuItem(0, "Quit")
MenuTitle("Object");301-> 350
MenuItem(304, "Sphere"+Chr(9)+"(S)")
MenuItem(302, "Cube"+Chr(9)+"(C)")
MenuItem(303, "Plane"+Chr(9)+"(P)")
MenuItem(301, "Load Object"+Chr(9)+"(A)")
MenuItem(305, "Suzanne"+Chr(9)+"(Z)")
MenuBar()
MenuTitle("World");401-> 440
MenuItem(401,"Ambient Color")
MenuTitle("Help");81-> 120
MenuItem(81, "About")
MenuItem(82, "Informations")
EndIf
;}
;{ ajout des shortcuts
AddKeyboardShortcut(#WindowMain,#PB_Shortcut_A,301)
AddKeyboardShortcut(#WindowMain,#PB_Shortcut_C,302)
AddKeyboardShortcut(#WindowMain,#PB_Shortcut_P,303)
AddKeyboardShortcut(#WindowMain,#PB_Shortcut_S,304)
AddKeyboardShortcut(#WindowMain,#PB_Shortcut_Z,305)
;}
;{ create the status bar : on créé la statusbar (en bas)
If CreateStatusBar(#statusbar,WindowID(#WindowMain))
AddStatusBarField(50)
AddStatusBarField(200)
AddStatusBarField(400)
EndIf
;}
;{ the gadget : on ajoute les gadgets (voir les gadgets dans l'aide)
If PanelGadget(#PanelLeft,5,30,PanelParameter+5,PanelParameterH)
AddGadgetItem(#PanelLeft,0,"Material")
CheckBoxGadget(#TextureInSameDir,5,5,130,20,"Same Dir for texture")
ButtonGadget(#MaterialLoad,5,25,60,20,"Load Mat")
AddGadgetItem(#PanelLeft,1,"Texture")
; vide pour l'instant
CloseGadgetList()
EndIf
If PanelGadget(#PanelRight,DesktopWidth(0)-5-PanelTexture,30,PanelTexture+5,PanelParameterH)
AddGadgetItem(#PanelRight,0,"Shader")
; vide
AddGadgetItem(#PanelRight,1,"Option")
CheckBoxGadget(#cameraLookAt,5,5,140,20,"Camera Look At Object")
SpinGadget(#Gadget_ViewZoom,5,25,30,20,1,500,#PB_Spin_Numeric)
GadgetToolTip(#Gadget_ViewZoom,"View Zoom")
SetGadgetState(#Gadget_ViewZoom,camera\ViewZoom)
SpinGadget(#Gadget_SizeMesh,5,50,30,20,1,500,#PB_Spin_Numeric)
GadgetToolTip(#Gadget_SizeMesh,"Size of the Mesh")
SetGadgetState(#Gadget_SizeMesh,camera\SizeMesh)
CloseGadgetList()
EndIf
;}
;{ open a screen : on ouvre un écran, on va l'utiliser pour afficher et update le monde 3D en suite;
ScreenWidth = ScreenX - PanelParameter - PanelTexture -30
ScreenHeight = ScreenY - MenuHeight() - StatusBarHeight(#statusbar)-TopSpace-BottomSpace
If OpenWindowedScreen(WindowID(#WindowMain),PanelParameter+15, TopSpace, ScreenWidth, ScreenHeight, 0, 0, 0)=0
Error("Unable To open a Screen")
EndIf
;}
;{ others things
ShowCursor_(1) ; window only : on affiche le curseur de la souris.
;}
EndIf
;{ engine 3D - world, camera. : on définit l'engine 3D, c'est ogre.
;{ world : le world du "jeu"
AmbientColor(RGB(80,80,80)); couleur ambient
;}.
;{ camera
CreateCamera(#Camera, 0, 0, 100, 100)
CameraLocate(#Camera, 70, 100, 230)
RotateCamera(#Camera, -15, 15, -100)
CameraLookAt(#camera,0,0,0)
CameraBackColor(#Camera, RGB(125,125,125))
;}
;{ entity to test the shader/material : c'est pour ajouter une "entité" (un objet 3D qu'on va utiliser).
LoadTexture(#Texture,"PERLREFL.JPG") ; ajoute une texture dans ton dossier Texture et change le nom en PERLREFL.jpg ou change sur cette ligne avec le nom de ta texture. C'est la texture par défaut.
CreateMaterial(#material,TextureID(#texture)); on créé le matériel pour l'objet 3D (entity)
ChangeObject(); je lance la procédure pour changer cet objet (voir la procédure plus bas)
;}
;{ light : les lumières
CreateLight(#light1,RGB(255,255,255),50,0,0) ; on la créé
LightSpecularColor(#light1,RGB(255,255,255)); on change la lumière spéculaire
;}
;}
;}
;{ loop : la boucle principale
Repeat
quit = Screen3DEvents(); la procédure Screen3DEvents() peut renvoyer 1 , donc, si ça renvoit 1, on quitte.
;{ keyboard : les évènements claviers
EventKeyboard()
If KeyboardReleased(#PB_Any)
MouseX=0
MouseY=0
KeyX = 0
KeyZ = 0
KeyY = 0
EndIf
If KeyboardPushed(#PB_Key_Right)
RotateEntity(#entity,0,1,0,#PB_Relative)
EndIf
If KeyboardPushed(#PB_Key_Left)
RotateEntity(#entity,0,-1,0,#PB_Relative)
EndIf
If KeyboardPushed(#PB_Key_Up)
RotateEntity(#entity,0,0,1,#PB_Relative)
EndIf
If KeyboardPushed(#PB_Key_Down)
RotateEntity(#entity,0,0,-1,#PB_Relative)
EndIf
;}
;{ mouse : évènements souris
If ExamineMouse()
If Not KeyboardPushed(#PB_Key_LeftShift) ;And KeyboardPushed(#PB_Key_LeftAlt))
If KeyboardPushed(#PB_Key_LeftAlt)
If MouseButton(#PB_MouseButton_Left)
MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
Else
MouseX = 0
MouseY = 0
EndIf
KeyZ = -MouseWheel()*#CameraSpeed * camera\ViewZoom ; zoom camera
EndIf
KeyZ = -MouseWheel()*#CameraSpeed * camera\ViewZoom
Else
If MouseButton(#PB_MouseButton_Left)
KeyY = MouseDeltaY() * #CameraSpeed * 0.4
KeyX = -MouseDeltaX() * #CameraSpeed * 0.4
Else
KeyY = 0
KeyX = 0
EndIf
KeyZ = -MouseWheel()*#CameraSpeed * camera\ViewZoom
EndIf
EndIf
;}
;{ update the scene :mise à jour de la scène/du monde. Ici juste un objet et le shader.
If camera\lookat=1 And IsEntity(#entity)
MoveCamera (#Camera, KeyX, KeyY, KeyZ)
CameraLookAt(#Camera,EntityX(#entity),EntityY(#entity),EntityZ(#entity))
Else
RotateCamera(#Camera, MouseY, MouseX, 0,#PB_Relative)
MoveCamera (#Camera, KeyX, KeyY, KeyZ)
EndIf
RenderWorld() ; on dessine le monde
FlipBuffers() ; on flippe le buffer
;}
GestionMouse()
Until quit = 1
;}
;{ Les procedures
Procedure Error(message$)
MessageRequester("Error",message$,1)
End
EndProcedure
;{ keyboard
Procedure EventKeyboard()
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Escape)
End
EndIf
EndProcedure
;}
;{ mouse
Procedure GestionMouse()
; ça c'est utile pour ne pas rester bloquer dans le screen, sinon, la souris y reste bloquée
If inscreen = 1
If (MouseX()<2 XOr MouseX()>(ScreenWidth-14)) Or (MouseY()>ScreenHeight-4 XOr MouseY()<1+TopSpace)
inscreen = 0 ; on n'est plus dans l'écran
ReleaseMouse(1); on libère la souris pour les menus
EndIf
Else
mx = WindowMouseX(0)-PanelParameter-10 : my = WindowMouseY(0)-TopSpace-3
If (mx>PanelParameter+10 And mx <ScreenWidth-14 And my>3+TopSpace And my<ScreenHeight-4)
ReleaseMouse(0) ; on est dans la vue 3D
MouseLocate(mx,my)
EndIf
inscreen = 1
EndIf
StatusBarText(#StatusBar,1, Str(WindowMouseX(0))+"/"+Str(WindowMouseY(0))+" - "+Str(MouseX())+"/"+Str(MouseY()))
StatusBarText(#StatusBar,2, "Triangles : "+Str(CountRenderedTriangles()))
EndProcedure
;}
;{ procédures : 3D world
Procedure ChangeObject(mode=0) ; pour modifier un objet (je n'ai qu'un objet dans ma scène, mais je peux le changer)
FreeMesh(#MeshSphere)
FreeEntity(#Entity)
Select mode
Case 0
CreateSphere(#MeshSphere,10,32,32)
CreateEntity(#Entity,MeshID(#MeshSphere),#PB_Material_None)
ScaleEntity(#entity,3,3,3)
EntityLocate(#Entity,0,0,0)
Case 1
CreateCube(#MeshSphere,15)
CreateEntity(#Entity,MeshID(#MeshSphere),#PB_Material_None)
ScaleEntity(#entity,3,3,3)
EntityLocate(#Entity,0,0,0)
Case 2
CreatePlane(#MeshSphere,10,10,10,10,1,1)
CreateEntity(#Entity,MeshID(#MeshSphere),#PB_Material_None)
ScaleEntity(#entity,8,8,8)
RotateEntity(#entity,90,0,0)
EntityLocate(#Entity,0,0,0)
Case 3 ; suzanne
LoadMesh(#MeshSphere,"Suzanne.mesh")
CreateEntity(#Entity,MeshID(#MeshSphere),#PB_Material_None)
ScaleEntity(#entity,30,30,30)
EntityLocate(#Entity,0,0,0)
Case 4 ; our object
mesh$=OpenFileRequester("Open Your Mesh","","*.mesh",0)
If mesh$ <>"" And GetExtensionPart(mesh$)="mesh"
mesh$=GetFilePart(mesh$)
If LoadMesh(#MeshSphere,mesh$)
CreateEntity(#Entity,MeshID(#MeshSphere),#PB_Material_None)
ScaleEntity(#entity,camera\SizeMesh,camera\SizeMesh,camera\SizeMesh)
EntityLocate(#Entity,0,0,0)
Else
MessageRequester("Error","Your File must to be a valid *.mesh.")
EndIf
EndIf
EndSelect
EndProcedure
Procedure MaterialLoad() ; pour changer de material sur mon objet
mat$=OpenFileRequester("Get a Material","","*.material",0)
If mat$ <>"" And GetExtensionPart(mat$)="material"
mat$=RemoveString(GetFilePart(mat$),".material")
GetScriptMaterial(#material,mat$)
SetEntityMaterial(#Entity,MaterialID(#material))
Else
MessageRequester("Error","Please, select a valid *.material")
EndIf
EndProcedure
;}
Procedure.a Screen3DEvents() ; procédure des évènements gadget et menu (et autre comme clic sur la croix rouge)
Repeat
Event = WindowEvent() ; on contrôle les évent généraux de la fenêtre
Select Event; en fonction de chaque event, on va faire certaines choses (menu, gadget...)
Case #PB_Event_Menu
Select EventMenu()
Case 301 ; load object
camera\typeObj = 4
ChangeObject(4)
Case 302 ; cube
camera\typeObj = 1
ChangeObject(1)
Case 303 ; plane
camera\typeObj = 2
ChangeObject(2)
Case 304 ; sphere
camera\typeObj = 0
ChangeObject(0)
Case 305 ; suzanne blender
camera\typeObj = 3
ChangeObject(3)
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
;{ panel left
Case #MaterialLoad
MaterialLoad()
;}
Case #cameraLookAt
camera\lookat = 1-camera\lookat
Case #Gadget_ViewZoom
camera\ViewZoom = GetGadgetState(#Gadget_ViewZoom)
Case #Gadget_SizeMesh
camera\SizeMesh = GetGadgetState(#Gadget_SizeMesh)
ResizeEntity(#entity,camera\SizeMesh,camera\SizeMesh,camera\SizeMesh)
EndSelect
Case #PB_Event_CloseWindow
Quit = 1
EndSelect
If Quit = 1 : ProcedureReturn Quit : EndIf ; Quit the app immediately
Until Event = 0
EndProcedure
;}
.
Bien sûr, il faut connaitre les bases : variables, condition, boucle, etc..