Jump to content

klepto2

Developers
  • Posts

    853
  • Joined

  • Last visited

Blog Entries posted by klepto2

  1. klepto2

    Development
    In this post, I want to introduce you to my GitHub repository: https://github.com/klepto2/UltraEngineUtilities
    Currently, there is not that much available, but I am working on adding more utilities and helper classes, which will help to work with UltraEngine.  I had the privilege to be one of the first users of UltraEngine and was able to see the enormous amount of potential right from the beginning. So with the repo, I want to give some of the small or bigger helpers I have developed or made compatible for UltraEngine to the public. 
    Available Features: namepace UltraEngine::Utilities::Shader ShaderCompiler A class which allows you to compile UltraEngines glsl-shaders to SPIRV format from code. ShaderWatcher This class uses the UltraEngine::FileSystemWatcher to watch changes for all available shaders used by your program It parses the ShaderFamilies Keeps track of includes Recompilation of shaders as soon as the shader file changes Automatically reloads shaders when the compilation was succesfully Sample code:
    How To use the Shadercompiler:
    #include "UltraEngine.h" #include "ComponentSystem.h" #include "include\Utilities.h" using namespace UltraEngine; using namespace UltraEngine::Utilities::Shader; int main(int argc, const char* argv[]) { auto compiler = CreateShaderCompiler(); auto result = compiler->Compile("Shaders/GUI/WidgetBlock.frag", "Shaders/GUI/WidgetBlock.frag.spv"); if (result->IsSuccesfull()) { Print("Shader compiled succesfully!"); for (auto f : result->GetIncludedFiles()) { Print("Shader includes: " + f); } } else { Print("Shader compilation failed!"); Print(result->GetError()); } ... } How to use the ShaderWatcher:
    #include "UltraEngine.h" #include "ComponentSystem.h" #include "include\Utilities.h" using namespace UltraEngine; using namespace UltraEngine::Utilities::Shader; int main(int argc, const char* argv[]) { auto watcher = CreateShaderWatcher(); watcher->Start(); ... }  
    Future Features: Multiple Widgets  ContainerWidgets: FlowPanel StackPanel TableLayoutPanel Scintilla Integration plain Scintilla Wrapper  Advanced SyntaxEditor -widget  will encapsulate some advanced features like inlining etc. Vulkan-Utilities: A port and slightly modified Version of Sascha Willems https://github.com/SaschaWillems/Vulkan/blob/master/base/VulkanTools.cpp I am as well working on some more advanced stuff, but there i have to decide how to publish them.
    ComputeShader-Integration Real-time PBR-Environment-Calculations Atmospheric scattering Ocean and Water rendering  
    Here are some Screens and Animations showing some of the above Features:
     



     
  2. klepto2

    Releases
    Hi, 
    I finally managed to build a first release candidate for a SyntaxEditor-Widget. The Widget is using the famous Scintilla TextEditor-Component under the hood and wraps the control into a UAK-Widget.  At this point i only provide binaries (includes and libraries) but i am currently preparing to release the source as well. 
    The source itself is semi-autogenerated with a manual created body and a tool which generates the main part of the Scintilla-Component based of so called iFace files maintained by the Scintilla author (these files contains the definitions of each enum or function you can use with Scintilla).
     
    Downloads:
    Demo (Small sample): Demo.zip
    Libraries and Headers:SyntaxEditor_libinc.zip
    To use the new widget you need to copy the content of the zip into your project and add the "include" directory to  "Additional Include Directories" and add the 
    the path to the Library to "Additional Library Directories" (for Release and Debug configurations).  Finally you need to add the needed lib files to "Additional Dependecies": 
    Imm32.lib
    SyntaxWidget.lib
    Lexilla.lib
    Scintilla.lib
     
    here is screenshot of the small demo app:

    and the code:
    #include "UltraEngine.h" #include "SyntaxWidget.h" #include "ScintillaLexer.hpp" using namespace UltraEngine; int main(int argc, const char* argv[]) { #ifdef _WIN64 auto plugin = LoadPlugin("Plugins/FITextureLoader.*"); #else auto plugin = LoadPlugin("Plugins (x86)/FITextureLoader.*"); #endif if (plugin == NULL) { Print("Failed to load FreeImage plugin."); return 1; } //Get the displays auto displays = GetDisplays(); //Create a window auto window = CreateWindow("Ultra Engine", 0, 0, 800, 600, displays[0], WINDOW_TITLEBAR | WINDOW_RESIZABLE | WINDOW_CENTER); //Create User Interface auto ui = CreateInterface(window); //Create widget auto sz = ui->root->GetSize(); auto toggleVisibility = CreateButton("Visible", 10, 10, 80, 20, ui->root, ButtonStyle::BUTTON_TOGGLE); toggleVisibility->SetState(WidgetState::WIDGETSTATE_SELECTED); auto container = CreatePanel(5, 40, sz.x - 10, sz.y - 45, ui->root, PanelStyle::PANEL_BORDER); sz = container->ClientSize(); container->SetLayout(1, 1, 1, 1); auto syntaxEditor = CreateSyntaxEditor(5, 5, sz.x - 10, sz.y - 10, container); syntaxEditor->SetLayout(1, 1, 1, 1); syntaxEditor->SetFoldFlags(FoldFlag::LineAfterContracted | FoldFlag::LineBeforeContracted); // 16 Draw line below if not expanded //auto lualexer = CreateLexer("lua"); // syntaxEditor->SetILexer(lualexer); auto lexer = CreateLuaLexer(syntaxEditor); syntaxEditor->SetKeyWords(0, "and break do else elseif end for function if in local nil not or repeat return then until while"); syntaxEditor->SetKeyWords(1, "print require"); syntaxEditor->SetProperty("fold", "1"); syntaxEditor->SetProperty("fold.compact", "0"); syntaxEditor->SetAutomaticFold(AutomaticFold::Change | AutomaticFold::Click | AutomaticFold::Show); syntaxEditor->SetMarginSensitiveN(2, 1); auto luasource = R"V0G0N(require("INC_Class.lua") --========================== = cAnimal = setclass("Animal") function cAnimal.methods:init(action, cutename) self.superaction = action self.supercutename = cutename end --========================== cTiger = setclass("Tiger", cAnimal) function cTiger.methods:init(cutename) self : init_super("HUNT (Tiger)", "Zoo Animal (Tiger)") self.action = "ROAR FOR ME!!" self.cutename = cutename function test() end end --========================== Tiger1 = cAnimal:new("HUNT", "Zoo Animal") Tiger2 = cTiger : new("Mr Grumpy") Tiger3 = cTiger : new("Mr Hungry") print("CLASSNAME FOR TIGER1 = ", Tiger1:classname()) print("CLASSNAME FOR TIGER2 = ", Tiger2:classname()) print("CLASSNAME FOR TIGER3 = ", Tiger3:classname()) print("===============") print("SUPER ACTION", Tiger1.superaction) print("SUPER CUTENAME", Tiger1.supercutename) print("ACTION ", Tiger1.action) print("CUTENAME", Tiger1.cutename) print("===============") print("SUPER ACTION", Tiger2.superaction) print("SUPER CUTENAME", Tiger2.supercutename) print("ACTION ", Tiger2.action) print("CUTENAME", Tiger2.cutename) print("===============") print("SUPER ACTION", Tiger3.superaction) print("SUPER CUTENAME", Tiger3.supercutename) print("ACTION ", Tiger3.action) print("CUTENAME", Tiger3.cutename))V0G0N"; String s = luasource; syntaxEditor->SetText(s.c_str()); syntaxEditor->StyleSetBack(STYLE_DEFAULT, RGB(syntaxEditor->color[WIDGETCOLOR_BACKGROUND].r * 255, syntaxEditor->color[WIDGETCOLOR_BACKGROUND].g * 255, syntaxEditor->color[WIDGETCOLOR_BACKGROUND].b * 255)); syntaxEditor->StyleSetFore(STYLE_DEFAULT, RGB(syntaxEditor->color[WIDGETCOLOR_FOREGROUND].r * 255, syntaxEditor->color[WIDGETCOLOR_FOREGROUND].g * 255, syntaxEditor->color[WIDGETCOLOR_FOREGROUND].b * 255)); syntaxEditor->StyleSetFont(STYLE_DEFAULT, "Consolas"); syntaxEditor->StyleSetSize(STYLE_DEFAULT, 11); syntaxEditor->StyleClearAll(); syntaxEditor->SetCaretFore(RGB(syntaxEditor->color[WIDGETCOLOR_FOREGROUND].r * 255, syntaxEditor->color[WIDGETCOLOR_FOREGROUND].g * 255, syntaxEditor->color[WIDGETCOLOR_FOREGROUND].b * 255)); syntaxEditor->SetFoldMarginHiColour(true, RGB(syntaxEditor->color[WIDGETCOLOR_HIGHLIGHT].r * 255, syntaxEditor->color[WIDGETCOLOR_HIGHLIGHT].g * 255, syntaxEditor->color[WIDGETCOLOR_HIGHLIGHT].b * 255)); syntaxEditor->SetFoldMarginColour(true, RGB(syntaxEditor->color[WIDGETCOLOR_HIGHLIGHT].r * 255, syntaxEditor->color[WIDGETCOLOR_HIGHLIGHT].g * 255, syntaxEditor->color[WIDGETCOLOR_HIGHLIGHT].b * 255)); auto textWidth = syntaxEditor->TextWidth(STYLE_LINENUMBER, "_99999"); syntaxEditor->SetMargins(5); syntaxEditor->SetMarginTypeN(0, MarginType::Number); syntaxEditor->SetMarginWidthN(0, textWidth); syntaxEditor->SetMarginTypeN(2, MarginType::Symbol); syntaxEditor->SetMarginMaskN(2, SC_MASK_FOLDERS); syntaxEditor->SetMarginWidthN(2, 16); syntaxEditor->SetMarginLeft(2); syntaxEditor->SetMarginRight(2); syntaxEditor->MarkerDefine(SC_MARKNUM_FOLDER, MarkerSymbol::BoxPlus); syntaxEditor->MarkerDefine(SC_MARKNUM_FOLDEROPEN, MarkerSymbol::BoxMinus); syntaxEditor->MarkerDefine(SC_MARKNUM_FOLDEREND, MarkerSymbol::BoxPlus); syntaxEditor->MarkerDefine(SC_MARKNUM_FOLDERMIDTAIL, MarkerSymbol::TCorner); syntaxEditor->MarkerDefine(SC_MARKNUM_FOLDEROPENMID, MarkerSymbol::BoxMinusConnected); syntaxEditor->MarkerDefine(SC_MARKNUM_FOLDERSUB, MarkerSymbol::VLine); syntaxEditor->MarkerDefine(SC_MARKNUM_FOLDERTAIL, MarkerSymbol::LCornerCurve); for (int i = 25; i <= 31; i++) { syntaxEditor->MarkerSetFore(i, RGB(syntaxEditor->color[WIDGETCOLOR_BACKGROUND].r * 255, syntaxEditor->color[WIDGETCOLOR_BACKGROUND].g * 255, syntaxEditor->color[WIDGETCOLOR_BACKGROUND].b * 255)); syntaxEditor->MarkerSetBack(i, RGB(215, 221, 232)); } syntaxEditor->StyleSetFore(LuaLexer::WORD, RGB(150, 190, 177)); syntaxEditor->StyleSetFore(LuaLexer::WORD2, RGB(220, 220, 170)); syntaxEditor->StyleSetFore(LuaLexer::COMMENT, RGB(87, 160, 61)); syntaxEditor->StyleSetFore(LuaLexer::COMMENTLINE, RGB(87, 160, 61)); syntaxEditor->StyleSetFore(LuaLexer::COMMENTDOC, RGB(87, 160, 61)); syntaxEditor->StyleSetFore(LuaLexer::CHARACTER, RGB(87, 160, 61)); syntaxEditor->StyleSetFore(LuaLexer::STRING, RGB(214, 151, 108)); syntaxEditor->StyleSetBack(STYLE_LINENUMBER, RGB(syntaxEditor->color[WIDGETCOLOR_BACKGROUND].r * 255, syntaxEditor->color[WIDGETCOLOR_BACKGROUND].g * 255, syntaxEditor->color[WIDGETCOLOR_BACKGROUND].b * 255)); syntaxEditor->StyleSetFore(STYLE_LINENUMBER, RGB(43, 145, 175)); syntaxEditor->SetElementColour(Element::ListBack, RGB(syntaxEditor->color[WIDGETCOLOR_BACKGROUND].r * 255, syntaxEditor->color[WIDGETCOLOR_BACKGROUND].g * 255, syntaxEditor->color[WIDGETCOLOR_BACKGROUND].b * 255)); syntaxEditor->SetElementColour(Element::List, RGB(syntaxEditor->color[WIDGETCOLOR_FOREGROUND].r * 255, syntaxEditor->color[WIDGETCOLOR_FOREGROUND].g * 255, syntaxEditor->color[WIDGETCOLOR_FOREGROUND].b * 255)); syntaxEditor->SetElementColour(Element::ListSelected, RGB(syntaxEditor->color[WIDGETCOLOR_SELECTEDTEXT].r * 255, syntaxEditor->color[WIDGETCOLOR_SELECTEDTEXT].g * 255, syntaxEditor->color[WIDGETCOLOR_SELECTEDTEXT].b * 255)); syntaxEditor->SetElementColour(Element::ListSelectedBack, RGB(syntaxEditor->color[WIDGETCOLOR_SELECTION].r * 255, syntaxEditor->color[WIDGETCOLOR_SELECTION].g * 255, syntaxEditor->color[WIDGETCOLOR_SELECTION].b * 255)); auto pixmap = LoadPixmap("Resources/class.png")->Resize(16, 16); syntaxEditor->RGBAImageSetWidth(pixmap->size.x); syntaxEditor->RGBAImageSetHeight(pixmap->size.y); syntaxEditor->RegisterRGBAImage(1, pixmap->pixels->Data()); while (true) { const Event ev = WaitEvent(); if (ev.id == SyntaxEditor::EVENT_CHARADDED) { auto notification = static_cast<TextEditorNotification*>(ev.extra.get()); if (notification->ch == '.' && !syntaxEditor->AutoCActive()) { syntaxEditor->AutoCShow(0, "Entity?1 Window?1 Hello World"); } } switch (ev.id) { case EVENT_WIDGETACTION: if (ev.source == toggleVisibility) { if (toggleVisibility->GetState() == WidgetState::WIDGETSTATE_SELECTED) { toggleVisibility->SetText("Visible"); syntaxEditor->Show(); } else { toggleVisibility->SetText("Hidden"); syntaxEditor->Hide(); } } break; case EVENT_WIDGETSELECT: break; case EVENT_QUIT: case EVENT_WINDOWCLOSE: return 0; break; default: break; } } return 0; }  
    ToDo:
    Publish the source add helper to apply UAK based theming move some Scintilla-Types to UAK-Types (e.g.: Colour to iVec4) I hope you enjoy the release and i look forward for any suggestions and feedback is very welcome.
  3. klepto2

    Basics
    In this first entry I will introduce some basics about the internal structure of the Widget class and what the purpose of some of its members is.
    For the real basics on how to write a custom Widget I suggest reading this https://www.ultraengine.com/learn/CPP/CustomWidgets first.
    Most of the members are self explained, so I will focus in this entry on 4 important methods:
    virtual bool Initialize(const WString& text, const int x, const int y, const int width, const int height, shared_ptr<Widget> parent, const int style); virtual void UpdateLayout(); virtual void Draw(const int x, const int y, const int width, const int height); virtual void Draw__(const int x, const int y, const int width, const int height);  
    The "Initialize" method:
    As the name says, this method initialize the Widget. In this method you can define additional parameters, the block size needed for the drawing etc. This method should always be used in the custom Create-Function and unless really needed it should not be overridden or at least the base method should be called like this:
    bool CustomWidget::Initialize(const WString& text, const int x, const int y, const int width, const int height, shared_ptr<Widget> parent, const int style) { if (Widget::Initialize(text, x, y, width, height, parent, style)) { //your initialisation goes here } } Internally, the "Initialize" method setups the initial size, the parent, style and text. 
     
    The "UpdateLayout" method:
    This method is called everytime the position or the size of the widget changes and can be overridden to support custom layouting. When overridden keep in mind that this method is dependend on the "SetLayout" method, so you should either call the base method to support the current layout settings and update the Clientsizes or you need to calculate it by yourself. In this method you can calculate or maintain a list of visible children which can later be used in the Draw__ method.
     
    The "Draw" method:
    This method is normally the most common one to override as this method defines how the widget is shown on screen and is called everytime the widget is redrawn. The drawing in the UltraAppKit is defined by Blocks, these blocks are drawn in order and for speed you should consider to update the block structure when the layout changes or events need a visual feedback:
    virtual void MouseEnter(const int x, const int y) { hover = true; Redraw(); } //Called each time the widget is redrawn virtual void Draw(const int x, const int y, const int width, const int height) { blocks.clear(); Vec4 color = Vec4(1, 0, 0, 1); if (hover) color = Vec4(0, 1, 0, 1); //Background rectangle AddBlock(iVec2(0), this->size, color); //Foreground text AddBlock(text, iVec2(0), this->size, Vec4(1), TEXT_CENTER | TEXT_MIDDLE); } I will explain the "Draw"-Method with the "Blocks"-Structure in depth in a later entry.
     
    The "Draw__" method:
    This method is not documented and may be subject to change, but this method is very important in case you want to write something which needs more in depth handling over the drawing itself. Like the "Draw"-Method this is called as  well when the widget needs to be redrawn.  From my observations this is the internal main entry point to the Redraw-Chain it is important to at least call the own "Draw"-Method here.  This method also needs to call the Draw__ of each of its kids so that these are drawn as well.  In this method you can limit the children which are drawn on screen when you maintain a visibility list in the UpdateLayout method.
    More on this  in a later entry.
     
    What comes next:
    This is just a short overview from my own observations and some info might be incorrect or change in the future. The following entries will explain more in depth details about writing a custom widget with some hints and tips I came across  I am currently developing a small library of custom widgets myself which will include at least the following:
    Layout:
    FlowLayoutPanel (ready) StackPanel (ready) GridLayoutPanel (in progress) Other:
    ContentPanel (a control host with automatic content scrolling) TextEditor (based on Scintilla, in Progress) and more (you can suggest widgets you might need, and I will see what I can do)  here is a small code sample how the GridLayoutPanel (and a preview of the TextEditor) works and how it looks:

    auto layout = CreateGridLayoutPanel(0, mainmenu->size.y, sz.x, sz.y- mainmenu->size.y, ui->root); layout->SetLayout(1, 1, 1, 1); layout->AddRowDefinition(GridLength::PIXEL, TOOLBARHEIGHT); layout->AddRowDefinition(GridLength::STAR); layout->AddRowDefinition(GridLength::PIXEL, CONSOLEHEIGHT - 28); layout->AddRowDefinition(GridLength::PIXEL, 28); layout->AddRowDefinition(GridLength::PIXEL, STATUSBARHEIGHT); layout->AddColumnDefinition(GridLength::STAR,3); layout->AddColumnDefinition(GridLength::STAR,1); auto toolbar = CreatePanel(0, 0, 0, 0, layout); toolbar->SetColor(1, 1, 0); auto statusbar = CreatePanel(0, 0,0,0, layout); statusbar->SetColor(0, 1, 0); auto mainpanel = CreatePanel(0, 0, 0, 0, layout); mainpanel->SetColor(0, 0, 1); auto sidepanel = CreatePanel(0, 0, 0, 0, layout); sidepanel->SetColor(1, 0, 0); auto consolepanel = CreatePanel(0, 0, 0, 0, layout); consolepanel->SetColor(0.5, 1, 0); auto inputpanel = CreatePanel(0, 0, 0, 0, layout); inputpanel->SetColor(0.3, 1, 0.5); layout->AssignChild(toolbar, 0, 0, 2); //Assign toolbar to grid col 0 and row 0 with a columnspan of 2 layout->AssignChild(statusbar, 0, 4, 2);//Assign statusbar to grid col 0 and row 4 with a columnspan of 2 layout->AssignChild(mainpanel, 0, 1);//Assign mainpanel to grid col 0 and row 1 layout->AssignChild(sidepanel, 1, 1, 1, 3); //Assign sidepanel to grid col 1 and row 1 with a rowspan of 2 layout->AssignChild(consolepanel, 0, 2);//Assign consolepanel to grid col 0 and row 2 layout->AssignChild(inputpanel, 0, 3);//Assign inputpanel to grid col 0 and row 3 layout->UpdateLayout(); auto mpcs = mainpanel->ClientSize(); auto editor = CreateTextEditor(0, 0, mpcs.x, mpcs.y, mainpanel); editor->SetLayout(1, 1, 1, 1); auto textWidth = editor->TextWidth(STYLE_LINENUMBER, "_99999"); editor->SetMargins(5); editor->SetMarginTypeN(0,MarginType::Number); editor->SetMarginWidthN(0,textWidth); editor->SetMarginTypeN( 2, MarginType::Symbol); editor->SetMarginMaskN( 2, SC_MASK_FOLDERS); editor->SetMarginWidthN( 2, 20); editor->MarkerDefine( SC_MARKNUM_FOLDER,MarkerSymbol::BoxPlusConnected); editor->MarkerDefine( SC_MARKNUM_FOLDEROPEN, MarkerSymbol::BoxMinusConnected); editor->MarkerDefine( SC_MARKNUM_FOLDEREND, MarkerSymbol::BoxPlus); editor->MarkerDefine( SC_MARKNUM_FOLDERMIDTAIL, MarkerSymbol::TCorner); editor->MarkerDefine( SC_MARKNUM_FOLDEROPENMID, MarkerSymbol::BoxMinusConnected); editor->MarkerDefine( SC_MARKNUM_FOLDERSUB, MarkerSymbol::VLine); editor->MarkerSetBack(SC_MARKNUM_FOLDERSUB, RGB(128,128,128)); editor->MarkerDefine( SC_MARKNUM_FOLDERTAIL, MarkerSymbol::LCorner); editor->MarkerSetBack(SC_MARKNUM_FOLDERMIDTAIL, RGB(128, 128, 128)); editor->MarkerSetBack(SC_MARKNUM_FOLDERSUB, RGB(128, 128, 128)); editor->MarkerSetBack(SC_MARKNUM_FOLDERTAIL, RGB(128, 128, 128)); editor->SetFoldFlags(FoldFlag::LineAfterContracted); // 16 Draw line below if not expanded auto lualexer = CreateLexer("lua"); editor->SetILexer(lualexer); editor->StyleSetFore(SCE_LUA_WORD, RGB(0,0,255)); editor->StyleSetFore(SCE_LUA_WORD2, RGB(0, 128, 128)); editor->StyleSetFore(SCE_LUA_COMMENT, RGB(0, 255, 0)); editor->StyleSetFore(SCE_LUA_COMMENTLINE, RGB(0, 255, 0)); editor->StyleSetFore(SCE_LUA_COMMENTDOC, RGB(0, 255, 0)); editor->StyleSetFore(SCE_LUA_CHARACTER, RGB(255, 0, 0)); editor->StyleSetFore(SCE_LUA_STRING, RGB(255, 0, 0)); editor->SetKeyWords( 0, "and break do else elseif end for function if in local nil not or repeat return then until while"); editor->SetKeyWords(1, "print require"); editor->SetProperty( "fold", "1"); editor->SetAutomaticFold(AutomaticFold::Change | AutomaticFold::Click | AutomaticFold::Show); editor->SetMarginSensitiveN( 2, 1);  
     
  4. klepto2

    Teaser
    While I am preparing the different parts of the blog i will show you a small summary about the ocean rendering i am using:
    GPU-based FFT waves using Phillipsspectrum Foam rendering (shore and whitecaps) Refraction and Reflection (realtime, ssr compatible) Fast due to Projected grid concept Teaser images:

  5. klepto2
    Hi Folks,
     
    another small progress update I would like to share with you.
     
    While working on extending the exported functionality of the dll i have discussed with some people here in the forum and I came to the conclusion that just extending the dll and program advanced parts in .Net is not really the best for the community. While some extensions will work only for .Net at first (eg Awesomium, full XBOX360 Controller support) most extension will be programmed fully in Blitzmax and exposed through multiple include files for Blitzmax users and an extended engine.dll for all other users.
     
    eg I will convert my Sceneloader to Blitzmax and export the functions via dll.
    For those who haven't seen it yet:
     
    Sceneloading with accurate progress support (the 102% bug is already resolved )


     
    Also I can already show you a temporary state of the reapidly growing function list which are already added to the dll:

    IntPtr CreateCubebuffer(Texture cubemap,Buffer cubemapbuffer) void ActivateCubeBufferFace(Cubebuffer cubebuffer,int face= 0) void DeactivateCubeBuffer(Cubebuffer cubebuffer) IntPtr CreateCubemap(int width,int height) int SetVegetationModel(Terrain terrain,string file,int Index= 0) int SetVegetationDensity(Terrain terrain,float density,int index= 0) float GetVegetationDensity(Terrain terrain,int index=0) int GetVegetationShadowMode(Terrain terrain,int index=0) int SetVegetationRandomTilt(Terrain terrain,float tilt,int index=0) float GetVegetationRandomTilt(Terrain terrain,int index=0) int SetVegetationRandomRotation(Terrain terrain,float rotation,int index=0) int GetVegetationRandomRotation(Terrain terrain,int index=0) int SetVegetationRandomScale(Terrain terrain,float scale,int index= 0) float GetVegetationRandomScale(Terrain terrain,int index=0) int SetVegetationLODDistance(Terrain terrain,float dist,int index=0) float GetVegetationLODDistance(Terrain terrain,int index=0) int SetVegetationViewRange(Terrain terrain,float Range,int index=0) float GetVegetationViewRange(Terrain terrain,int index=0) int SetVegetationAlignment(Terrain terrain,int Mode,int index=0) int GetVegetationAlignment(Terrain terrain,int index=0) int DistributeVegetation(Terrain terrain,int index=0,int aligntoslope=0) void DeleteVegetation(Terrain terrain,int index=0) void GenerateColorMap(Terrain terrain,int resolution) void SetLayerCollisionType(Terrain terrain,int layer,int _type) void SaveVegetation(Terrain terrain,string file,int Index) void LoadVegetation(Terrain terrain,string file,int Index) void AddVegetationInstance(Terrain terrain,float x,float z,int layer,float density,int randrotation,float randscale,int aligntonormal,float tilt) void SetTerrainBaseMap(Terrain terrain,Texture texture) int SetMaterialBlendMode(Material material,int mode) int GetMaterialBlendMode(Material material) int SetMaterialBumpScale(Material material,float Scale) float GetMaterialBumpScale(Material material) int SetMaterialCastShadows(Material material,int enabled) int GetMaterialCastShadows(Material material) int SetMaterialColorMask(Material material,int enabled) int GetMaterialColorMask(Material material) int SetMaterialCullFace(Material material,int enabled) int GetMaterialCullFace(Material material) int SetMaterialDepthMask(Material material,int enabled) int GetMaterialDepthMask(Material material) int SetMaterialDepthTest(Material material,int enabled) int GetMaterialDepthTest(Material material) int SetMaterialGloss(Material material,float gloss) float GetMaterialGloss(Material material) int SetMaterialInvisible(Material material,int enabled) int GetMaterialInvisible(Material material) int SetMaterialOverlay(Material material,int enabled) int GetMaterialOverlay(Material material) int SetMaterialSpecular(Material material,float specular) float GetMaterialSpecular(Material material) int SetMaterialStipple(Material material,int enabled) int GetMaterialStipple(Material material) int SetMaterialZsort(Material material,int enabled) int GetMaterialZsort(Material material)
     
    Total extensions: 54
     
    A lot of functions will be added in the next days and i have a lot of ideas about additional helper functions and additions all Leadwerks user should benefit from.
     
    thx for reading
     
    klepto2
  6. klepto2
    Hi,
     
    this is just a short blog to keep you informed. I have promised to upload a first version last weekend, but unfortunatly I wasn't able to do so.
    I'm currently working on a solution to provide the extended functionality to both .Net Wrappers (LE.Net and Leadwerks.Net) which is more difficult than i thought.
     
    I have already extended the engine.dll with some new functions which already work in both .Net Wrappers and i will hopefully be ready with a small package next week. So no worry about it, I'm still working on it. As a small cookie i have this:
     

     
    Nothing special you think, well maybe you're right, but the shown scene is not loaded via LoadScene not the vegetation is done via the Editor.
    The whole vegetation is done via code (new engine.dll functions, unoffically)
     
    At least I have a small poll to set my priority to the correct Wrapper (both will have the same functionality at the end, but i have to start with one)
     
    thx for reading.
  7. klepto2
    Hi folks,
     
    here is a new relatively short entry to my blog introducing my current side project (which will be the base of my bigger secret project) which I will make public to the community.
     
    I'm calling this project "Leadwerks.Extensions". In detail it is a project which will extend the current LE.Net headers with a set of setalite assemblies which will contain and provide some additional functions to the .Net community. My goal is to release a first set of dlls this weekend containing at least 3 assemblies.


    1. Leadwerks.Extensions.Common
    The basic assembly containing shared functions used by all other assemblies but also providing some helpful functions like enabling rawGL mode, additional engine.dll commands.


    2. Leadwerks.Extensions.Drawing
    Providing a growing library of 2D funtionality like animated images, viewport and scissor commands, and a lot more
     

    3. Leadwerks.Extensions.Awesomium
     

     
    A picture often says more than words
     
    I have a lot of ideas for upcoming extensions (GUI, AI, IK, GameManagement, etc.), but if you have ideas or wishes feel free to post them in the comments.
     
    thx for your attention and more details will follow this weekend.
  8. klepto2
    Hi folks,
     
    while working on my other projects I have started to research why the cubemapping doesn't seem to work in Leadwerks in Realtime.
    I have debugged through the code ( I was using Blitzmax to have access to the full debug output and fields of textures and buffers) and found out that
    it seems you can't create a real Leadwerks buffer for Cubemaps, I have also investigated TylerH' s early approach after the CreateCubemap command was added and from my experience with miniB3D extended I came to the conclusion that something must be wrong in Joshs solution and handling for realtime cubemaps.
     
    In Tylers lua sample he creates 6 buffers for each side of the cubemap, which is not needed when using fbo (Framebuffer objects). With this in mind I have
    integrated my old fbo code from 'miniB3D extended' and stripped it down to just support cubemaps and fit it (maybe a bit messy) into the existing buffer system (no I have no source license). The first result was promising and so i was extending my sample to handle full cubemaps and i was amazed how fast the result was.
     
    This is the result:


     
    The real fps without recording is double as high as it is showing in the video.
     
    Here is my code:

    ' ==================================================================== ' This file was generated by Leadwerks C++/LEO/BlitzMax Project Wizard ' Written by Rimfrost Software ' http://www.rimfrost.com ' ==================================================================== SuperStrict Framework leadwerks.ENGINE Local world:TWorld Local gbuffer:TBuffer Local camera:TCamera Local mesh:TMesh Local light:TLight Local ground:TMesh Local material:TMaterial Local materialfloor:TMaterial 'GCSetMode(2) RegisterAbstractPath( "D:/LESDK232r5/" ) Graphics(800,600) world=CreateWorld() If Not world RuntimeError "Failed to create world." gbuffer=CreateBuffer(GraphicsWidth(),GraphicsHeight(),BUFFER_DEPTH|BUFFER_COLOR0|BUFFER_COLOR1|BUFFER_COLOR2) camera=CreateCamera() PositionEntity camera,[0.0,0.0,-4.0] material=LoadMaterial("abstract::cubemap.mat") materialfloor = LoadMaterial("abstract::cobblestones.mat") mesh = CreateSphere(32) ScaleEntity mesh,[2.0,2.0,2.0] PaintEntity mesh,material light=CreateDirectionalLight() RotateEntity light , [45.0 , 45.0 , 45.0] Local cubemap:TTexture = CreateCubemap(512 , 512) Local cubemapbuffer:TBuffer = CreateBuffer(512 , 512) SetColorBuffer(cubemapbuffer , cubemap , 0) Local cubebuffer:TCubeBuffer = TCubeBuffer.Create(cubemap,cubemapbuffer) SetMaterialTexture( material , cubemap , 0) Local p:TPivot = CreatePivot() Local sp:TMesh = CreateSphere(16,p) MoveEntity sp , [4.0 , 0.0 , 0.0] EntityColor sp,[1.0,0.0,0.0,1.0] Local p1:TPivot = CreatePivot() Local sp1:TMesh = CreateSphere(16,p1) MoveEntity sp1 , [4.0 , 0.0 , 0.0] EntityColor sp1,[0.0,1.0,0.0,1.0] Local p2:TPivot = CreatePivot() Local sp2:TMesh = CreateSphere(16,p2) MoveEntity sp2 , [4.0 , 0.0 , 0.0] EntityColor sp2,[0.0,0.0,1.0,1.0] Local skybox:TMEsh = CreateCube() ScaleMesh skybox , [4.0 , 4.0 , 4.0] FlipMesh skybox EntityShadowMode skybox,0 PaintEntity skybox,LoadMaterial("abstract::FullskiesBlueClear0016_2_L.mat") EntityColor skybox,[1.0,1.0,1.0,1.0] Local frame:Int = 0 Repeat TurnEntity p , [0.0 , AppSpeed() * .5 , 0.0] TurnEntity p1, [0.0,-AppSpeed()*.5,0.0] TurnEntity p2, [0.0,0.0,AppSpeed()*.5] If KeyHit(KEY_ESCAPE) Exit If AppTerminate() Exit UpdateAppTime() UpdateWorld(AppSpeed()) SetBuffer(cubemapbuffer) PositionEntity camera , [0.0 , 0.0 , 0.0] ScaleEntity camera,[1.0 , -1.0 , 1.0] HideEntity mesh Local stage:Int = frame Mod 6 If stage = 0 Then cubebuffer.Set(0) RotateEntity camera,[0.0 , -90.0 , 0.0] RenderWorld() Else If stage = 1 Then cubebuffer.Set(1) RotateEntity camera,[0.0 , 90.0 , 0.0] RenderWorld() Else If stage = 2 Then cubebuffer.Set(2) RotateEntity camera,[-90.0 , 0.0 , 0.0] RenderWorld() Else If stage = 3 Then cubebuffer.Set(3) RotateEntity camera,[90.0 , 0.0 , 0.0] RenderWorld() Else If stage = 4 Then cubebuffer.Set(4) RotateEntity camera,[0.0 , 0.0 , 0.0 ] RenderWorld() Else If stage = 5 Then cubebuffer.Set(5) RotateEntity camera,[0.0 , -180.0 , 0.0] RenderWorld() End If cubebuffer.UnSet() ScaleEntity camera,[1.0 , 1.0 , 1.0] RotateEntity camera,[0.0 , 0.0 , 0.0] PositionEntity camera , [0.0 , 0.0 , - 4.0] ShowEntity mesh SetBuffer(gbuffer) RenderWorld() SetBuffer(BackBuffer()) RenderLights(gbuffer) SetBlend BLEND_ALPHA DrawText(UPS(),0,0) SetBlend 0 Flip(0) frame:+1 GCCollect() Forever gbuffer=Null FreeEntity light GCCollect() End Type TCubeBuffer Field texture:TTexture Field buffer:TBuffer Field rb:Int[1] Field fb:Int[1] Field sb:Int[1] Field db:Int[1] Function Create:TCubeBuffer(texture:TTexture,buffer:TBuffer) Local cb:TCubeBuffer = New TCubeBuffer cb.Texture = texture cb.Buffer = buffer cb._BuildBuffer() cb.Buffer.Framebuffer = cb.fb[0] cb.Buffer.colorbuffer[0] = texture Return cb End Function Method _BuildBuffer() Local w:Int =texture.reference._Width Local h:Int = texture.reference._Height glBindTexture(GL_TEXTURE_CUBE_MAP , texture.reference._index) glTexImage2D GL_TEXTURE_CUBE_MAP_NEGATIVE_X,0,GL_RGBA8 ,w,h,0,GL_RGBA,GL_UNSIGNED_BYTE,Null glTexImage2D GL_TEXTURE_CUBE_MAP_POSITIVE_Z,0,GL_RGBA8 ,w,h,0,GL_RGBA,GL_UNSIGNED_BYTE,Null glTexImage2D GL_TEXTURE_CUBE_MAP_POSITIVE_X,0,GL_RGBA8 ,w,h,0,GL_RGBA,GL_UNSIGNED_BYTE,Null glTexImage2D GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,0,GL_RGBA8 ,w,h,0,GL_RGBA,GL_UNSIGNED_BYTE,Null glTexImage2D GL_TEXTURE_CUBE_MAP_POSITIVE_Y,0,GL_RGBA8 ,w,h,0,GL_RGBA,GL_UNSIGNED_BYTE,Null glTexImage2D GL_TEXTURE_CUBE_MAP_NEGATIVE_Y , 0 , GL_RGBA8 , w , h , 0 , GL_RGBA , GL_UNSIGNED_BYTE , Null glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE) ; glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP , GL_TEXTURE_MIN_FILTER , GL_LINEAR) ; glGenFramebuffersEXT(1, fb ) glGenRenderbuffersEXT(1 , rb) glGenRenderbuffersEXT(1 , sb) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0]) ; glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT , GL_COLOR_ATTACHMENT0_EXT , GL_TEXTURE_CUBE_MAP , texture.reference._index, 0) ; glBindRenderbufferEXT(GL_RENDERBUFFER_EXT , rb[0]) ; glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24 ,W, H); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , rb[0]) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , 0) glBindRenderbufferEXT(GL_RENDERBUFFER_EXT , 0) ; End Method Method Set(cubeface:Int) 'glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0]) SetBuffer(buffer) Select cubeface Case 0 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT , GL_COLOR_ATTACHMENT0_EXT ,GL_TEXTURE_CUBE_MAP_POSITIVE_X,texture.reference._index,0) Case 1 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT , GL_COLOR_ATTACHMENT0_EXT ,GL_TEXTURE_CUBE_MAP_NEGATIVE_X,texture.reference._index,0) Case 2 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT , GL_COLOR_ATTACHMENT0_EXT ,GL_TEXTURE_CUBE_MAP_POSITIVE_Y,texture.reference._index,0) Case 3 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT , GL_COLOR_ATTACHMENT0_EXT ,GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,texture.reference._index,0) Case 4 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT , GL_COLOR_ATTACHMENT0_EXT ,GL_TEXTURE_CUBE_MAP_POSITIVE_Z,texture.reference._index,0) Case 5 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT , GL_COLOR_ATTACHMENT0_EXT ,GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,texture.reference._index,0) End Select 'glgetError() End Method Method Unset() glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , 0) End Method Method CheckFBOStatus:Int(index:Int = 0) Local status:Int = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) Select status Case GL_FRAMEBUFFER_COMPLETE_EXT Print index + ": FBO Complete" Case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT Print index + ": Incomplete attachment" Case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT Print index + ": Missing attachment" Case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT Print index + ": Incomplete dimensions" Case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT Print index + ": Incomplete formats" Case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT Print index + ": Incomplete draw buffer" Case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT Print index + ": Incomplete read buffer" Case GL_FRAMEBUFFER_UNSUPPORTED_EXT Print index + ": Framebufferobjects unsupported" EndSelect Return Status End Method End Type
     
    One downside is that currently I get INVALID_ENUM error in debug mode, but I have no idea why as it is thrown from engine itself. Also this is unfortunatly a Blitzmax only hack as it needs some access to some not provided fields. But maybe Josh can use this code to finally integrate proper support of realtime cubemapping into the engine.
     
    thx for reading
    klepto2
  9. klepto2
    Hi guys,
     
    finally I have some more freetime back and have restarted developing with Leadwerks more intensively in C#. Currently I'm working on multiple extensions for the .NET Wrapper of Leadwerks and I'm also finishing / continuing developing my tools. Later I hope this will all fit in one easy to use framework.
     
    First here is a screen of new nightsky texture used in my lua daynight script (not completely correct scaled) :
     

     
    the texture was made by taking screenshots from the stellarium software ( http://www.stellarium.org ) and building a cubemap out of them.
     
    Also I have started an advanced 2D Library for Leadwerks.Net :
     

     
    This is the current 2D code for the image above:

    public void Render() { Drawing2D.Enabled = true; //Enables Rendering of 2D Elements in native OpenGL Drawing2D.SetViewRotation(m_angle2, 1024f/ 2f, 768f / 2f); //Rotates the complete Viewport around given point Drawing2D.SetBlend(BlendMode.Alpha); // Set differten Blendmodes Drawing2D.SetColor(255, 0, 0, 1.0f); // Set Color for the following drawing calls Drawing2D.DrawLine(0, 0, 1024, 768); // Draws a line Drawing2D.SetColor(0, 255, 0, 0.5f); Drawing2D.DrawLine(0, -100, 1024, 768); Drawing2D.SetColor(0, 0, 255, 0.5f); Drawing2D.DrawLine(0, 100, 1024, 768); Drawing2D.SetColor(255, 0, 255, .5f); // Set the Drawing Handle of the next items to draw //(eg: normally all items are rotated at their local [0,0] coordinate, this function offsets this point by the given point) //values of 10,10 would rotate the following rects around their center. Drawing2D.SetHandle(50, 50); for (int i = 0; i < 150; i++) { if (i % 2 == 0) Drawing2D.SetRotation(m_angle); //Sets current rotation for the following drawings else Drawing2D.SetRotation(-m_angle); Drawing2D.DrawRect(10.24f + i * 10.24f, 7.68f + i * 7.68f, 20, 20); // Draws a rect } m_angle += 0.02f; m_angle2 += 0.04f; Drawing2D.Enabled = false; // Disables raw OpenGL Mode }
     
    The module will have its own Image handling (Leadwerks textures can be used as well) and much more.
     
    This is a brief overview and will be continued...
  10. klepto2
    Hi guys,
     
    I have made some small progress on my gui system the last few days. Nothing fancy, but believe me there where a lot of changes under the hood and
    now I can show you a first skinned screenshot:
     

     
    As you see the base skinning part is done. Well it will develope further with later gadgets, but the base part is done. You can have multiple skins running in one application, so you can have your main gui in your own game style and another like an ingame pc with a WinXP skin.
     
    One other thing which is special about this picture:
    The 2D part isn't using a single part (except Texture loading, which may also change later) from the Leadwerks Engine. OK Buffers are still used as well as Textures, but the whole Drawingpart of images uses my own 2D Framework. A small code can show you how the logo is drawn on the right of the above image:
     

    Local img:TLEImage = TLEImage.Load("abstract::lelogo.dds") ... TLeGui.RenderGui(camera) BeginLE2D() TLe2DHelper.SetBlend(ALPHABLEND) TLEImage.DrawImageRect(img, GraphicsWidth() - 320, GraphicsHeight() - 100, 320, 100) TLEImage.DrawSubImageRect(img, 200, 300, 32, 20, 5, 5, 120, 120) EndLE2D() Flip()
     
    The commands are a bit inspired by Max2D as you may have noticed. Also you see the second DrawImage command, this command draws a subimage of the source image.
     
    Currently my 2D system supports:

    Completely new TLEImage
    Some Primitives
    Transformations (rotation,scaling,...)
    Blendmodes, Colors, and some small other things.

     
    I hope you enjoyed the read.
     
    See ya at my next entry.
  11. klepto2
    Ok, as said in my last post i will make an advanced 2d system and a gui. I have now decided to start with the gui and add 2d Functions on demand.
     
    Here is a first screen, nothing special, but it shows some progress:
     

     
    Note the correct rendering of the window at the cube. I'm using one of my first 2D additions, SetScale , to mirror the rendering correctly for the texture.
     
    What does the renderer currently do: Every control is itself contained in a buffer which is only updated if it is marked as dirty. the rendering goes up the parents tree and each control buffer is renderend into its parents buffer at the desired location. With this technique i only need to draw one Image most of the time to represent a root gui element.
     
    I will keep you informed.
  12. klepto2
    After a forced break from programming with Leadwerks Engine, due to Work and other not 3D related Projects, I have started yesterday to come back to my Leadwerks project.
     
    As I'm continuing my project, I'm developing some extension for my own needs and if they are needed and good enough i will publish standalone addons here.
     
    The first project will be somekind of Leadwerks2D. It will offer a richer 2D function set than the current one. eg: Rotation, scaling, origin handling and new primitives with advanced options. The first project with LE2d will be a small skinnable gui system with the goal to provide an easy and flexible ingame gui system. One feature will be that you can attach a "rendertarget" to the gui and eg have the gui on 3D Objects.
     
    I will keep you informed on any News and post screens etc as soon as something showable is produced.
  13. klepto2
    Well, long time has passed since i have written a new entry.
     
    While I'm still working on the asset manager and Texture Converter (non threading version) I have prototyped a small animation class
    in Blitzmax which can handle multiple animations at once for a single mesh. eg: you can walk and use your sword in the same time.
     
    Everything is handled automatically you just give a root animation a speed factor and a blend factor. Later you can simply add an 'extra'-
    animation to the mesh by using the bonename and an animation name. As you will notice in the video i have not yet synced some values eg:
    when does an once time played animation blend out. But i think the video gives an idea what is possible with Leadwerks Engine.





     
    Here is a small codesnippet from my sample project how animation is handled:

    If JUMP = 0 Then If move = 0 Then scene_helper.playeranimator.SetMainAnimation("Idle") scene_helper.playeranimator.SetAnimSpeed(3) ; Else If Abs(move) >= 1.5 Then scene_helper.playeranimator.SetMainAnimation("run") scene_helper.playeranimator.SetAnimSpeed(Sgn(move) * 2.0) ; Else scene_helper.playeranimator.SetAnimSpeed(Sgn(move) * 3) ; scene_helper.playeranimator.SetMainAnimation("walk w/o sword") End If End If Else scene_helper.playeranimator.SetMainAnimation("jump", ANIMSTYLE_ONCE) scene_helper.playeranimator.SetAnimSpeed(Sgn(move) * 3) ; End If If MouseHit(MOUSE_LEFT) scene_helper.playeranimator.SetExtraAnimation("Bip01_R_UpperArm", "attack combo", ANIMSTYLE_ONCE) End If If MouseHit(MOUSE_RIGHT) scene_helper.playeranimator.SetExtraAnimation("Bip01_L_UpperArm", "pick up", ANIMSTYLE_ONCE) End If
  14. klepto2
    Hi there,
     
    While spending some days in hospital without internet connection I have used the time (not much) to
    revisit my existing code for my tools and I have found some things i will no get on:
     
    First the Batch converter:
     
    I have started to reprogram it, not everything but the whole internal structure will
    change a lot. I have found a lot of design errors which are too heavy to fix and reprogramming
    it with using some old components seems faster and cleaner to me. I believe that a new version will
    be out on Sunday.
     
    Now my assetmanager/builder:
     
    After revisiting my old tool which i mentioned in my first post I have tweaked it a bit and came
    to the conclusion that it is much better than i thought and it works very good with nearly every
    package i have tested. One downside of this tool is that the configuration could not be set per
    model, but this is not really needed as i have found out.
     
    Normally model packages are created with the same size relation so a global scale value can solve
    scaling issues. In short: I will publish the small tool with some additions :
     
    -optional pack creation with password
    -optional filling empty materials with dummy materials
     
    the later one is due the fact that some exporters doesn't seem to export every material
    into the model and without this option you need to reexport these models by hand etc. .
    The option will create a log file which materials are missing in a model with its dummy material file.
    The dummy materials will all have the same structure but can be edited individual. One idea to uniqly name the missing
    materials is the following:
     
    <filename>_<meshname>_<surfacenumber>.mat
     
    Any suggestions are welcome.
  15. klepto2
    After uploading my first lua snippet i'm continuing my task to develope
    useful tools for Leadwerks Engine.
     
    What tools you may ask?
     
    The first, a batch texture converter is ready since a long time, but needs some tweaking here and there.
    A beta was previously published but i want to get this tool out of the beta and will release a finished
    version the next days.
     
    The next one is to finish my milkshape exporter (animations still doesn't work) but the rest
    is faster and less buggy.
     
    The main tool I'm currently developing is a small helper which i call "Asset Helper".
     
    What does this exactly mean?
     
    Well everyone who ever have bought a model pack from one of the modelshops around the web
    may know this problem. You download it and want to play with it in the Leadwerks Editor.
    Unfortunatly in most cases this doesn't work at first.
     
    You need to:


    -convert the model to the gmf format
    -create correct material files
    -create lua scripts
    -give proper names to have a good structures view in the Editor
    -and some things more / depends on the pack

     
    What does my tool do?
     
    In a first version of my tool I tried to do the above steps completely automatically
    with just a parameters given at startup, but this aproach fails as expected.
    It was working with some modelpacks but mostly it fails.
     
    So my new approach is a semi-automatic tool:
    First it will scan and analyse a given directory recursivly and collects all
    needed data like available models, are there already GMF models or do we
    need to convert from fbx. It collects every texture it found and like the GenMat
    tool it will try to find proper texture pairs to build material files.
    In a last prestep it will scan the converted meshes and get the needed materials or
    marks missing materials.
     
    The next step is done by the user:
    Choose which models to pack into the asset library. Assign missing textures, rename them etc. .
    You will also be able to choose a scale value for every single model or choose a
    scale for all models. The analyser will also attach a basic lua file to each model so
    you have proper dialogs in the editor.
     
    The last step will be to choose an asset name, a package name (optional) and a password (also optional).
    After a click on start the whole process will start and you will get a nice pak file or a directory structure
    which you only need to copy into your Game folder.
     
    I hope that I have a small Update next time, maybe a screenshot.
     
    See ya, klepto2
  16. klepto2
    Just a small update and an information why everything is progressing
    so slowly with my tools.
     
    Unfortunatly (well, not really) I'm currently full of work with my daytime job
    (project deadlines, new features, etc.) that I'm currently don't have much time
    to do some private programming. This weekend I have some freetime
    i will spend to fix some bugs with the batch texture converter and coninue with
    my work on the asset builder.
     
    Hopefully I'm able to post some progress soon.
×
×
  • Create New...