ich arbeite gerade mit der 3D Engine unter Linux, dazu wollte ich mir "mal eben" einen "kleinen" Shader-"Editor" basteln. Hier bin ich aber auf mehrere Probleme gestossen, die gerade akuten möchte ich hier gerne schildern:
1. alle Keyboardshortcuts die ich hinzufüge funktionieren nicht
2. die EditorGadgets sind nicht editierbar, obwohl ich die Anweisung #PB_Editor_ReadOnly nicht beim erstellen der Gadgets benutze.
Hier der Code damit ihr das selber ausprobieren könnt:
Code: Alles auswählen
;- Shader Tester
EnableExplicit
#AppName = "Purebasic Shader Tester"
#AppData = "data"
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
CompilerIf Not Subsystem("OpenGL")
MessageRequester(#AppName, "You must compile with the OpenGL subsystem!")
End
CompilerEndIf
#DD = "\"
#EditFontName = "Courier New"
#EditFontSize = 10
#EditFontID = 0
CompilerElseIf #PB_Compiler_OS = #PB_OS_Linux
#DD = "/"
#EditFontName = "Free Mono"
#EditFontSize = 10
#EditFontID = 0
CompilerElse
End
CompilerEndIf
Enumeration
#Camera
#Light
#LightMarker
#Entity
#Sprite
EndEnumeration
Enumeration
#MainWindow
#MainMenu
EndEnumeration
Enumeration
#Menu_File
#Menu_File_New
#Menu_File_Open
#Menu_File_Save
#Menu_File_SaveAs
#Menu_File_Quit
#Menu_Edit
#Menu_Edit_Undo
#Menu_Edit_Redo
#Menu_Edit_Copy
#Menu_Edit_Cut
#Menu_Edit_Paste
#Menu_Edit_SelectAll
#Menu_Edit_Goto
#Menu_Material
#Menu_Material_Compile
EndEnumeration
Enumeration
#Frm_3D
#Frm_2D
#Edt_Material
#Edt_Vertex
#Edt_Fragment
#Txt_Mesh
#Cmb_Mesh
#Chk_LightRotate
#Txt_LightColor
#Btn_LightColor
#Img_LightColor
#Chk_Sync
#Txt_Material
#Cmb_Material
#Btn_Compile
EndEnumeration
Declare.b Initialize()
Declare.b ProcessWindowEvent(WindowEvent.i)
Declare ShowFPSSprite()
If Initialize()
Repeat
Delay(1)
RenderWorld()
ShowFPSSprite()
FlipBuffers()
Until ProcessWindowEvent(WaitWindowEvent(10)) = #True
EndIf
End
Macro ErrMsg(Text)
MessageRequester("Error", Text)
End
EndMacro
Macro TranslateViewport(x, y, z)
MoveCamera(#Camera, x, y, z, #PB_Absolute)
MoveLight(#Light, CameraX(#Camera), CameraY(#Camera), CameraZ(#Camera), #PB_Absolute)
MoveEntity(#LightMarker, CameraX(#Camera), CameraY(#Camera), CameraZ(#Camera), #PB_Absolute)
CameraLookAt(#Camera, 0, 0, 0)
EntityLookAt(#LightMarker, 0, 0, 0)
EndMacro
Macro TranslateLight(x, y, z)
MoveLight(#Light, x, y, z, #PB_Absolute)
MoveEntity(#LightMarker, LightX(#Light), LightY(#Light), LightZ(#Light), #PB_Absolute)
EntityLookAt(#LightMarker, 0, 0, 0)
EndMacro
Procedure SelectNewMesh(MeshType.l, MaterialName.s)
Static.i material, mesh
If IsMaterial(material) And MaterialName <> ""
FreeMaterial(material)
EndIf
If MaterialName <> ""
material = GetScriptMaterial(#PB_Any, MaterialName)
EndIf
If IsMaterial(material)
If MeshType >= 0
If IsMesh(mesh)
FreeMesh(mesh)
EndIf
Select MeshType
Case 0
mesh = CreatePlane(#PB_Any, 50, 50, 1, 1, 1, 1)
Case 1
mesh = CreateCube(#PB_Any, 50)
Default
mesh = CreateSphere(#PB_Any, 25, 32, 16)
EndSelect
EndIf
If IsMesh(mesh)
If IsEntity(#Entity)
FreeEntity(#Entity)
EndIf
CreateEntity(#Entity, MeshID(mesh), MaterialID(material), 0, 0, 0)
If MeshType = 0
RotateEntity(#Entity, 90, 0, 0)
EndIf
EndIf
EndIf
If Not IsEntity(#Entity)
ErrMsg("Can not create an entity with mesh type " + Str(MeshType) + " and material " + MaterialName)
EndIf
EndProcedure
Procedure.l SelectNewLightColor(Color.l)
Protected.i tempTexture, tempMaterial
Protected.f x, y, z
If IsLight(#Light) And Color > 0
x = LightX(#Light)
y = LightY(#Light)
z = LightZ(#Light)
FreeLight(#Light)
EndIf
CreateLight(#Light, Color, x, y, z, #PB_Light_Point)
SetLightColor(#Light, #PB_Light_DiffuseColor, Color)
SetLightColor(#Light, #PB_Light_SpecularColor, Color)
LightAttenuation(#Light, 100, 1)
If IsEntity(#LightMarker)
tempTexture = CreateTexture(#PB_Any, 16, 16)
StartDrawing(TextureOutput(tempTexture))
Box(0, 0, 16, 16, Color)
StopDrawing()
tempMaterial = CreateMaterial(#PB_Any, TextureID(tempTexture))
DisableMaterialLighting(tempMaterial, #True)
SetMaterialColor(tempMaterial, #PB_Material_AmbientColor, Color)
SetMaterialColor(tempMaterial, #PB_Material_DiffuseColor, Color)
SetEntityMaterial(#LightMarker, MaterialID(tempMaterial))
FreeMaterial(tempMaterial)
FreeTexture(tempTexture)
EndIf
If IsImage(#Img_LightColor)
FreeImage(#Img_LightColor)
EndIf
CreateImage(#Img_LightColor, 100, 30)
StartDrawing(ImageOutput(#Img_LightColor))
Box(0, 0, 100, 30, Color)
StopDrawing()
If IsGadget(#Btn_LightColor) And IsImage(#Img_LightColor)
SetGadgetAttribute(#Btn_LightColor, #PB_Button_Image, ImageID(#Img_LightColor))
EndIf
EndProcedure
Procedure.b Initialize()
Protected.l windowWidth, windowHeight, screenOffsetX, screenOffsetY, screenWidth, screenHeight, lightColor
Protected.i tempMesh, hFile
Protected.s tab = Chr(9)
screenOffsetX = 5
screenOffsetY = 5
screenWidth = 640
screenHeight = 480
windowWidth = 1200
windowHeight = 600
lightColor = RGB(255, 255, 231)
If InitEngine3D(#PB_Engine3D_DebugLog)
If InitSprite()
If OpenWindow(#MainWindow, #PB_Ignore, #PB_Ignore, windowWidth, windowHeight, #AppName, #PB_Window_SystemMenu|#PB_Window_Invisible)
AddKeyboardShortcut(#MainWindow, #PB_Shortcut_Control | #PB_Shortcut_N, #Menu_File_New)
AddKeyboardShortcut(#MainWindow, #PB_Shortcut_Control | #PB_Shortcut_O, #Menu_File_Open)
AddKeyboardShortcut(#MainWindow, #PB_Shortcut_Control | #PB_Shortcut_S, #Menu_File_Save)
AddKeyboardShortcut(#MainWindow, #PB_Shortcut_Control | #PB_Shortcut_Q, #Menu_File_Quit)
AddKeyboardShortcut(#MainWindow, #PB_Shortcut_Control | #PB_Shortcut_Y, #Menu_Edit_Undo)
AddKeyboardShortcut(#MainWindow, #PB_Shortcut_Control | #PB_Shortcut_Z, #Menu_Edit_Redo)
AddKeyboardShortcut(#MainWindow, #PB_Shortcut_Control | #PB_Shortcut_X, #Menu_Edit_Cut)
AddKeyboardShortcut(#MainWindow, #PB_Shortcut_Control | #PB_Shortcut_C, #Menu_Edit_Copy)
AddKeyboardShortcut(#MainWindow, #PB_Shortcut_Control | #PB_Shortcut_V, #Menu_Edit_Paste)
AddKeyboardShortcut(#MainWindow, #PB_Shortcut_Control | #PB_Shortcut_A, #Menu_Edit_SelectAll)
AddKeyboardShortcut(#MainWindow, #PB_Shortcut_Control | #PB_Shortcut_G, #Menu_Edit_Goto)
AddKeyboardShortcut(#MainWindow, #PB_Shortcut_F5, #Menu_Material_Compile)
If CreateMenu(#MainMenu, WindowID(#MainWindow))
MenuTitle("File")
MenuItem(#Menu_File_New, "New" + tab + "CTRL+N")
MenuBar()
MenuItem(#Menu_File_Open, "Open ..." + tab + "CTRL+O")
MenuBar()
MenuItem(#Menu_File_Save, "Save" + tab + "CTRL+S")
MenuItem(#Menu_File_SaveAs, "Save as ..." + tab + "")
MenuBar()
MenuItem(#Menu_File_Quit, "Quit" + tab + "CTRL+Q")
MenuTitle("Edit")
MenuItem(#Menu_Edit_Undo, "Undo" + tab + "CTRL+Y")
MenuItem(#Menu_Edit_Redo, "Redo" + tab + "CTRL+Z")
MenuBar()
MenuItem(#Menu_Edit_Cut, "Cut" + tab + "CTRL+X")
MenuItem(#Menu_Edit_Copy, "Copy" + tab + "CTRL+C")
MenuItem(#menu_edit_Paste, "Paste" + tab + "CTRL+V")
MenuBar()
MenuItem(#Menu_Edit_SelectAll, "Select all" + tab + "CTRL+A")
MenuBar()
MenuItem(#Menu_Edit_Goto, "Goto ..." + tab + "CTRL+G")
MenuTitle("Material")
MenuItem(#Menu_Material_Compile, "Compile material script" + tab + "F5")
EndIf
If FrameGadget(#Frm_3D, screenOffsetX, screenOffsetY * 2 + screenHeight, screenWidth, windowHeight - MenuHeight() - screenOffsetY * 2 - screenHeight, "3D Options")
TextGadget(#Txt_Mesh, 10, GadgetY(#Frm_3D) + 20, 100, 20, "Current Mesh:")
ComboBoxGadget(#Cmb_Mesh, 10, GadgetY(#Frm_3D) + 40, 100, 30)
AddGadgetItem(#Cmb_Mesh, -1, "Plane")
AddGadgetItem(#Cmb_Mesh, -1, "Cube")
AddGadgetItem(#Cmb_Mesh, -1, "Sphere")
SetGadgetState(#Cmb_Mesh, 2)
TextGadget(#Txt_LightColor, 150, GadgetY(#Frm_3D) + 30, 100, 20, "Light Color:")
ButtonImageGadget(#Btn_LightColor, 220, GadgetY(#Frm_3D) + 20, 100, 30, 0)
CheckBoxGadget(#Chk_LightRotate, 150, GadgetY(#Frm_3D) + 60, 100, 20, "rotate Light ?")
SetGadgetState(#Chk_LightRotate, #True)
TextGadget(#Txt_Material, 350, GadgetY(#Frm_3D) + 20, 200, 20, "Current Material:")
ComboBoxGadget(#Cmb_Material, 350, GadgetY(#Frm_3D) + 40, 200, 30)
ButtonGadget(#Btn_Compile, 570, GadgetY(#Frm_3D) + 15, 60, 60, "Compile" + Chr(13) + "Material")
EndIf
If PanelGadget(#Frm_2D, screenOffsetX * 2 + screenWidth, screenOffsetY, windowWidth - screenOffsetX * 3 - screenWidth, windowHeight - MenuHeight() - screenOffsetY)
LoadFont(#EditFontID, #EditFontName, #EditFontSize)
AddGadgetItem(#Frm_2D, 0, "Material Script")
EditorGadget(#Edt_Material, 2, 2, GadgetWidth(#Frm_2D) - 10, GadgetHeight(#Frm_2D) - 40)
SetGadgetFont(#Edt_Material, FontID(#EditFontID))
gtk_text_view_set_editable_(GadgetID(#Edt_Material), #True)
AddGadgetItem(#Frm_2D, 1, "Vertex Shader")
EditorGadget(#Edt_Vertex, 2, 2, GadgetWidth(#Frm_2D) - 10, GadgetHeight(#Frm_2D) - 40)
SetGadgetFont(#Edt_Vertex, FontID(#EditFontID))
AddGadgetItem(#Frm_2D, 2, "Fragment Shader")
EditorGadget(#Edt_Fragment, 2, 2, GadgetWidth(#Frm_2D) - 10, GadgetHeight(#Frm_2D) - 40)
SetGadgetFont(#Edt_Fragment, FontID(#EditFontID))
CloseGadgetList()
hFile = ReadFile(#PB_Any, #AppData + #DD + "default.material")
If IsFile(hFile)
While Eof(hFile) = 0
AddGadgetItem(#Edt_Material, -1, ReadString(hFile))
Wend
CloseFile(hFile)
SetGadgetItemText(#Frm_2D, 0, "default.material")
AddGadgetItem(#Cmb_Material, -1, "default.material")
SetGadgetState(#Cmb_Material, 0)
EndIf
EndIf
If OpenWindowedScreen(WindowID(#MainWindow), screenOffsetX, screenOffsetY, screenWidth, screenHeight, #False, 555, 115, #PB_Screen_WaitSynchronization)
Add3DArchive(#AppData, #PB_3DArchive_FileSystem)
Parse3DScripts()
CreateCamera(#Camera, 0, 0, 100, 100)
tempMesh = CreateCube(#PB_Any, 10)
CreateEntity(#LightMarker, MeshID(tempMesh), #PB_Material_None)
EntityRenderMode(#LightMarker, 0)
SelectNewLightColor(lightColor)
TranslateViewport(0, 0, 100)
FreeMesh(tempMesh)
SelectNewMesh(3, "default")
Else
ErrMsg("Can not open a graphic screen in the main window!")
EndIf
HideWindow(#MainWindow, #False)
Else
ErrMsg("Can not open OS window!")
EndIf
Else
ErrMsg("Can not init graphic environment (sprite & screen)!")
EndIf
Else
ErrMsg("Can not load 3D engine!")
EndIf
ProcedureReturn #True
EndProcedure
Macro LoadFileToEditBox(fileName, editGadget)
If fileName <> ""
If FileSize(fileName) > 0
hFile = ReadFile(#PB_Any, fileName)
If IsFile(hFile)
ClearGadgetItems(editGadget)
While Eof(hFile) = 0
AddGadgetItem(editGadget, -1, ReadString(hFile))
Wend
CloseFile(hFile)
EndIf
EndIf
EndIf
EndMacro
Macro SaveFileFromEditBox(fileName, editGadget)
If fileName <> ""
hFile = CreateFile(#PB_Any, #AppData + #DD + fileName)
If IsFile(hFile)
For n = 0 To CountGadgetItems(editGadget)-1
WriteStringN(hFile, GetGadgetItemText(editGadget, n), #PB_Ascii)
Next
CloseFile(hFile)
EndIf
EndIf
EndMacro
Procedure.b ProcessWindowEvent(WindowEvent.i)
Static.b init, rotateLight
Static.i lightColor
Static.f degree
Static.s materialFile, vertexFile, fragmentFile
Protected.b exitProgram, foundVertexEntry, foundFragmentEntry
Protected.i evtGadget, evtMenu, hFile, tempMaterial, n
Protected.f x, z
Protected.s pattern, fileName, line
Protected *editData
NewList material.s()
If init = #False
materialFile = "default.material"
vertexFile = ""
fragmentFile = ""
lightColor = RGB(255, 255, 231)
degree = 180.0
rotateLight = #True
init = #True
EndIf
evtGadget = EventGadget()
evtMenu = EventMenu()
Select WindowEvent
Case #PB_Event_CloseWindow
exitProgram = #True
Case #PB_Event_Gadget
Select evtGadget
Case #Chk_LightRotate
rotateLight = GetGadgetState(#Chk_LightRotate)
Case #Cmb_Mesh
SelectNewMesh(GetGadgetState(#Cmb_Mesh), "")
Case #Btn_LightColor
lightColor = ColorRequester(lightColor)
SelectNewLightColor(lightColor)
Case #Cmb_Material
tempMaterial = GetScriptMaterial(#PB_Any, GetGadgetItemText(#Cmb_Material, GetGadgetState(#Cmb_Material)))
SetEntityMaterial(#Entity, MaterialID(tempMaterial))
FreeMaterial(tempMaterial)
Case #Btn_Compile
EndSelect
Case #PB_Event_Menu
Select evtMenu
Case #Menu_File_New
materialFile = ""
vertexFile = ""
fragmentFile = ""
ClearGadgetItems(#Edt_Material)
ClearGadgetItems(#Edt_Vertex)
ClearGadgetItems(#Edt_Fragment)
ClearGadgetItems(#Cmb_Material)
SetGadgetItemText(#Frm_2D, 0, "Material Script")
SetGadgetItemText(#Frm_2D, 1, "Vertex Shader")
SetGadgetItemText(#Frm_2D, 2, "Fragment Shader")
Case #Menu_File_Open
pattern = "Material File (*.material)|*.material"
fileName = OpenFileRequester("Select file", #AppData + #DD + "*", pattern, 0)
If fileName <> "" And FileSize(fileName) >= 0
hFile = ReadFile(#PB_Any, fileName)
If IsFile(hFile)
ClearGadgetItems(#Edt_Material)
ClearGadgetItems(#Cmb_Material)
materialFile = GetFilePart(fileName)
vertexFile = ""
fragmentFile = ""
While Eof(hFile) = 0
line = ReadString(hFile)
AddGadgetItem(#Edt_Material, -1, line)
If FindString(LCase(line), "vertex_program")
foundVertexEntry = #True
EndIf
If FindString(LCase(line), "fragment_program")
foundFragmentEntry = #True
EndIf
If FindString(LCase(line), "source")
If foundVertexEntry
vertexFile = Trim(ReplaceString(line, "source", ""))
foundVertexEntry = #False
EndIf
If foundFragmentEntry
fragmentFile = Trim(ReplaceString(line, "source", ""))
foundFragmentEntry = #False
EndIf
EndIf
If FindString(LCase(line), "material")
AddElement(material())
material() = Trim(ReplaceString(line, "material", ""))
If FindString(material(), ":")
material() = Trim(StringField(material(), 1,":"))
EndIf
AddGadgetItem(#Cmb_Material, -1, material())
EndIf
Wend
CloseFile(hFile)
SetGadgetItemText(#Frm_2D, 0, materialFile)
SetGadgetState(#Cmb_Material, 0)
EndIf
If vertexFile <> ""
LoadFileToEditBox(GetPathPart(fileName) + vertexFile, #Edt_Vertex)
SetGadgetItemText(#Frm_2D, 1, vertexFile)
Else
MessageRequester(#AppName, "Material script doesn't contain a vertex script")
EndIf
If fragmentFile <> ""
LoadFileToEditBox(GetPathPart(fileName) + fragmentFile, #Edt_Fragment)
SetGadgetItemText(#Frm_2D, 2, fragmentFile)
Else
MessageRequester(#AppName, "Material script doesn't contain a fragment script")
EndIf
ForEach material()
ReloadMaterial(material(), materialFile, #True)
Next
FirstElement(material())
tempMaterial = GetScriptMaterial(#PB_Any, material())
SetEntityMaterial(#Entity, MaterialID(tempMaterial))
FreeMaterial(tempMaterial)
EndIf
Case #Menu_File_Save
SaveFileFromEditBox(materialFile, #Edt_Material)
SaveFileFromEditBox(vertexFile, #Edt_Vertex)
SaveFileFromEditBox(fragmentFile, #Edt_Fragment)
Case #Menu_File_SaveAs
Case #Menu_File_Quit
exitProgram = #True
Case #Menu_Edit_Cut
Select GetGadgetState(#Frm_2D)
Case 0
*editData = gtk_text_view_get_buffer_(GadgetID(#Edt_Material))
Case 1
*editData = gtk_text_view_get_buffer_(GadgetID(#Edt_Vertex))
Case 2
*editData = gtk_text_view_get_buffer_(GadgetID(#Edt_Fragment))
EndSelect
gtk_text_buffer_cut_clipboard_(*editData, gtk_clipboard_get_(#GDK_NONE), #True)
Case #Menu_Edit_Copy
Select GetGadgetState(#Frm_2D)
Case 0
*editData = gtk_text_view_get_buffer_(GadgetID(#Edt_Material))
Case 1
*editData = gtk_text_view_get_buffer_(GadgetID(#Edt_Vertex))
Case 2
*editData = gtk_text_view_get_buffer_(GadgetID(#Edt_Fragment))
EndSelect
gtk_text_buffer_copy_clipboard_(*editData, gtk_clipboard_get_(#GDK_NONE))
Case #Menu_Edit_Paste
Select GetGadgetState(#Frm_2D)
Case 0
*editData = gtk_text_view_get_buffer_(GadgetID(#Edt_Material))
Case 1
*editData = gtk_text_view_get_buffer_(GadgetID(#Edt_Vertex))
Case 2
*editData = gtk_text_view_get_buffer_(GadgetID(#Edt_Fragment))
EndSelect
gtk_text_buffer_paste_clipboard_(*editData, gtk_clipboard_get_(#GDK_NONE), #Null, #True)
Case #Menu_Material_Compile
Debug "Yeah!"
EndSelect
EndSelect
If rotateLight
degree + 1
If degree > 360
degree - 360
EndIf
x = (CameraZ(#Camera)+10) * Cos(Radian(degree))
z = (CameraZ(#Camera)+10) * Sin(Radian(degree))
TranslateLight(x, 0, z)
EndIf
ProcedureReturn exitProgram
EndProcedure
Procedure ShowFPSSprite()
Static.i hFont
If Not IsSprite(#Sprite)
CreateSprite(#Sprite, 100, 20, #PB_Sprite_AlphaBlending)
EndIf
If Not IsFont(hFont)
hFont = LoadFont(#PB_Any, "Free Sans", 10, #PB_Font_HighQuality)
EndIf
StartDrawing(SpriteOutput(#Sprite))
DrawingMode(#PB_2DDrawing_AllChannels)
DrawingFont(FontID(hFont))
Box(0, 0, 100, 20, 0)
DrawText(1, 1, StrF(Engine3DFrameRate(#PB_Engine3D_Current), 1) + " fps")
StopDrawing()
DisplayTransparentSprite(#Sprite, 0, 0)
EndProcedure
Code: Alles auswählen
material default
{
technique
{
pass
{
ambient 1.0 1.0 1.0 1.0
diffuse 1.0 1.0 1.0 1.0
}
}
}