Jump to content


  • Content Count

  • Joined

  • Last visited

Community Reputation

22 Excellent

About IgorBgz90

  • Rank
    Advanced Member
  • Birthday 09/07/1990

Profile Information

  • Gender
  • Location

Recent Profile Visitors

4,465 profile views
  1. Adobe Fuse CC && https://www.mixamo.com/ The easiest way👍
  2. 🔨Update "Texture Atlas" blog, ✔️added check for empty frames.

  3. IgorBgz90

    UTF8 Support!

    Hello again. Implemented UTF8 support for LE4. Works fine🙃. context->SetBlendMode(Blend::Alpha); context->DrawText(u8"Привет мир! Hello world!", 25.0f, 25.0f); context->SetBlendMode(Blend::Solid); Add yours symbols to "familychars" and make own "family" in Font.cpp if (family==Font::English) { familychars = L"abcdefghijklmnopqrstuvwxyzабвгдеёжзийклмнопрстуфхцчшщъыьэюя АБВГДЕЁЖЗИКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-=!@#$%^&*()_+[]\\{}|;':\",./<>? `~"; } Update: #include <codecvt> std::string WideStringToString(const std::wstring & str) { std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv; return myconv.to_bytes(str); } std::wstring StringToWideString(const std::string & str) { std::wstring_convert<std::codecvt_utf8<wchar_t>> convert; return convert.from_bytes(str); } Gud luck🖐️! FontSrc.zip
  4. Hello community, long time no see. I am working on my own graphical user interface, for my super duper rpg game :). The use separate textures for each button state, etc. I consider it not effective! It is better to load the texture with the atlas of the whole GUI once. And use her. In order to draw a texture from the atlas, we need to slightly modify the standard shader (drawimage), and save it under a different name (drawimagerect). Shader #version 400 uniform vec4 drawcolor; uniform sampler2D texture0; uniform vec4 rect; in vec2 vTexCoords0; out vec4 fragData0; void main(void) { ivec2 ts = textureSize(texture0, 0); vec4 coord = vec4(rect.x / ts.x, rect.y / ts.y, rect.z / ts.x, rect.w / ts.y); vec2 uv = coord.xy + (vTexCoords0 * coord.zw); fragData0 = drawcolor * texture(texture0,uv); } Now we can draw a texture from the atlas: void drawImageRect(Texture* texture, float x, float y, Vec4 rect) { Context* context = Context::GetCurrent(); context->SetShader(Shader::Load("Shaders/Drawing/drawimagerect.shader")); context->GetShader()->SetVec4("rect", rect); context->DrawImage(texture, x, y, rect.z, rect.w); context->SetShader(NULL); } void drawImageRect(Texture* texture, float x, float y, float width, float height, Vec4 rect) { Context* context = Context::GetCurrent(); context->SetShader(Shader::Load("Shaders/Drawing/drawimagerect.shader")); context->GetShader()->SetVec4("rect", rect); context->DrawImage(texture, x, y, width, height); context->SetShader(NULL); } Animation To play the animation we need to get the coordinates of all the frames in the atlas. Naturally, we won't do this manually, will write a small algorithm. bool isEmptyFrame(char* pixels, int textureWidth, iVec2 position, iVec2 frameSize, const bool alpha=true, const iVec3 colorBg=iVec3()) { unsigned char r, g, b, a; int level = 0; for (int y = position.y; y < position.y + frameSize.y; y++) { for (int x = position.x; x < position.x + frameSize.x; x++) { int p = (y * textureWidth + x) * 4; memcpy(&r, pixels + p + 0, 1); memcpy(&g, pixels + p + 1, 1); memcpy(&b, pixels + p + 2, 1); memcpy(&a, pixels + p + 3, 1); if (!alpha) { if ((int)r == colorBg.r && (int)g == colorBg.g && (int)b == colorBg.b) { level++; } else { return false; } } else { if ((int)a == 0) { level++; } else { return false; } } } } float percent = (float)((float)level / (float)(frameSize.x * frameSize.y)) * 100.0f; if (percent >= 100.0f) { return true; } return false; } void getFrames(Texture* texture, iVec2 framesize, std::vector<Vec4> &frames) { if (texture == nullptr) return; int horizontLine = texture->GetWidth() / framesize.x; int verticalLine = texture->GetHeight() / framesize.y; int frameCount = horizontLine * verticalLine; int currentHorizont = 0; int currentVertical = 0; iVec2 framePosition = iVec2(); iVec2 frameSize = framesize; char* pixels = (char*)malloc(texture->GetMipmapSize(0) * 8); texture->GetPixels(pixels); System::Print((std::string)"Get frames from texture atlas \"" + texture->GetPath() + "\"..."); // Push first frame int skipCount = 0; if (!isEmptyFrame(pixels, texture->GetWidth(), framePosition, frameSize)) { frames.push_back(Vec4((float)framePosition.x, (float)framePosition.y, (float)frameSize.x, (float)frameSize.y)); } else { skipCount++; System::Print((std::string)"Frame #0" + " is empty. (skip)"); } for (int i = 1; i < frameCount; i++) { if (currentHorizont < horizontLine - 1) { currentHorizont++; framePosition.x = frameSize.x * currentHorizont; } else { if (currentVertical < verticalLine - 1) { currentVertical++; framePosition.x = 0; framePosition.y = frameSize.y * currentVertical; currentHorizont = 0; } } if (!isEmptyFrame(pixels, texture->GetWidth(), framePosition, frameSize)) { frames.push_back(Vec4((float)framePosition.x, (float)framePosition.y, (float)frameSize.x, (float)frameSize.y)); } else { skipCount++; System::Print((std::string)"Frame #" + std::to_string(i) + " is empty. (skip)"); } } System::Print((std::string)"Frame count: " + std::to_string(frames.size()) + ", skip: " + std::to_string(skipCount)); free(pixels); } Now that we have all the frames, we can play the animation. Texture* atlas = Texture::Load("Textures/atlas.tex"); std::vector<Vec4> frames; getFrames(atlas, iVec2(96, 96), frames); float frame = 0.0f; float frameend = frames.size(); float framebegin = 0.0f; float speed = 0.1f; //Loop frame += Time::GetSpeed() * speed; frame = fmodf(frame, frameend - framebegin) + framebegin; //Draw drawImageRect(atlas, 25.0f, 25.0f, frames[(int)frame]); Updates: [04.04.2020] [+] Added check for empty frames.
  5. IgorBgz90

    Leadwerks and C#

    It turns out that there is no need to export functions, they already exist in the file "Leadwerks.dll"?)
  6. IgorBgz90

    Leadwerks and C#

    Thanks! As it did not pay attention to him 🙂
  7. IgorBgz90

    Leadwerks and C#

    Thanks. But keep in mind that there is only the initialization of the rendering engine, and that's all. If you want more, you will have to export other engine functions😎
  8. IgorBgz90

    Leadwerks and C#

    Oh yeah! Not the best option, but the other I do not know🤔
  9. IgorBgz90

    Leadwerks and C#

    What do you mean? C# uses functions from the dynamic library, and she does not need to compile engine functions. Update: Compile time is equal to the size of your C# project🙂
  10. IgorBgz90

    Leadwerks and C#

    Thanks. In fact, everything is very simple😏
  11. IgorBgz90

    Leadwerks and C#

    Actually it is very simple. As usual, we need to export the functions we are interested in to the Dynamic Library (DLL), and then import them into our C# program. Let's start. C++ DLL The first thing we need is to create a project in C++ for our future DLL, and of course configure it for the Leadwerks engine Configuration for Release Right-click on the project and select Property. In the window that appears, go to the tab "С/C++" / "General". Copy and Paste to a "Additional Include Directories" this: $(LeadwerksHeaderPath)\Libraries\NewtonDynamics\sdk\dgCore;$(LeadwerksHeaderPath)\Libraries\NewtonDynamics\sdk\dgNewton;$(LeadwerksHeaderPath)\Libraries\libvorbis\include;$(LeadwerksHeaderPath)\Libraries\libogg\include;$(LeadwerksHeaderPath)\Libraries\openssl\include;$(LeadwerksHeaderPath);$(LeadwerksHeaderPath)\Libraries\VHACD\src\VHACD_Lib\inc;$(LeadwerksHeaderPath)\Libraries\glslang;$(LeadwerksHeaderPath)\Libraries\freetype-2.4.7\include;$(LeadwerksHeaderPath)\Libraries\OpenAL\include;$(LeadwerksHeaderPath)\Libraries\NewtonDynamics\sdk\dMath;$(LeadwerksHeaderPath)\Libraries\NewtonDynamics\sdk\dgTimeTracker;$(LeadwerksHeaderPath)\Libraries\NewtonDynamics\sdk\dContainers;$(LeadwerksHeaderPath)\Libraries\NewtonDynamics\sdk\dCustomJoints;$(LeadwerksHeaderPath)\Libraries\RecastNavigation\RecastDemo\Include;$(LeadwerksHeaderPath)\Libraries\RecastNavigation\DetourCrowd\Include;$(LeadwerksHeaderPath)\Libraries\RecastNavigation\DetourTileCache\Include;$(LeadwerksHeaderPath)\Libraries\RecastNavigation\DebugUtils\Include;$(LeadwerksHeaderPath)\Libraries\RecastNavigation\Recast\Include;$(LeadwerksHeaderPath)\Libraries\RecastNavigation\Detour\Include;$(LeadwerksHeaderPath)\Libraries\tolua++-1.0.93\include;$(LeadwerksHeaderPath)\Libraries/lua-5.1.4;$(LeadwerksHeaderPath)\Libraries/glew-1.6.0/include/GL;$(LeadwerksHeaderPath)\Libraries\glew-1.6.0\include;$(LeadwerksHeaderPath)\Libraries\enet-1.3.1\include;$(LeadwerksHeaderPath)\Libraries\zlib-1.2.5;$(LeadwerksHeaderPath)\Libraries\freetype-2.4.3\include;%(AdditionalIncludeDirectories) Go to "Preprocessor", in "Preprocessor Definitions" copy and paste this: WIN32;NDEBUG;LEADWERKS_EXPORTS;_WINDOWS;_USRDLL;PSAPI_VERSION=1;__STEAM__;_CUSTOM_JOINTS_STATIC_LIB;FT2_BUILD_LIBRARY;LEADWERKS_3_1;DG_DISABLE_ASSERT;WINDOWS;OS_WINDOWS;OPENGL;PLATFORM_WINDOWS;_WIN_32_VER;_NEWTON_USE_LIB;PTW32_STATIC_LIB;PTW32_BUILD;_NEWTON_STATIC_LIB;_LIB;DG_USE_NORMAL_PRIORITY_THREAD;GLEW_STATIC;_STATICLIB;%(PreprocessorDefinitions) Go to "Code Generation". Set these values: Enable Minimal Rebuild = Yes(/Gm) Runtime Library = Multi-threaded (/MT) Enable Function-Level-Linking = Yes (/Gy) Go to "Precompiled Header" and set: "Not Using Precompiled Headers" Now go to the "Linker" / "General" tab, then in "Additional Library Directories" copy and paste this: $(LeadwerksLibPath)\Windows\x86;$(LeadwerksLibPath)\Windows\x86\Release;C:/Leadwerks\Engine\Source\Libraries\OpenAL/libs/Win32/EFX-Util_MT;C:/Leadwerks\Engine\Source\Libraries\OpenAL/libs/Win32;%(AdditionalLibraryDirectories) Go to "Input", in "Additional Dependencies" copy and paste this: newton.lib;dContainers.lib;dCustomJoints.lib;libcryptoMT.lib;libsslMT.lib;Rpcrt4.lib;crypt32.lib;libcurl.lib;Leadwerks.lib;msimg32.lib;lua51.lib;steam_api.lib;OpenAL32.lib;ws2_32.lib;libovr.lib;newton.lib;dContainers.lib;dCustomJoints.lib;OpenGL32.lib;Glu32.lib;winmm.lib;Psapi.lib;%(AdditionalDependencies) Propery Sheet Right-click on the project and select "Add \ New Item \ Property Sheets \ Property Sheet" click Add button. Open it and paste this text: Warning! Keep in mind that the paths may be different, check them out. <?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ImportGroup Label="PropertySheets" /> <PropertyGroup Label="UserMacros"> <LeadwerksHeaderPath>C:/Program Files (x86)/Steam/steamapps/common/Leadwerks\Include</LeadwerksHeaderPath> <LeadwerksLibPath>C:/Program Files (x86)/Steam/steamapps/common/Leadwerks\Library</LeadwerksLibPath> </PropertyGroup> <PropertyGroup /> <ItemDefinitionGroup /> <ItemGroup> <BuildMacro Include="LeadwerksHeaderPath"> <Value>$(LeadwerksHeaderPath)</Value> <EnvironmentVariable>true</EnvironmentVariable> </BuildMacro> <BuildMacro Include="LeadwerksLibPath"> <Value>$(LeadwerksLibPath)</Value> <EnvironmentVariable>true</EnvironmentVariable> </BuildMacro> </ItemGroup> </Project> If all the paths match, you can import it into the project. Go to menu "VIEW / Other Windows / Property Manager" Click button "Add Existing Property Sheet". On this with the project settings everything =). Now we can go directly to the code. This is part of the functions required for a simple program; you can add other functions yourself. // Leadwerks.cpp : Defines the exported functions for the DLL application. // #include "Leadwerks.h" using namespace Leadwerks; #define EXPORT extern "C" __declspec(dllexport) // ---------------------------------------------------------------------------------- // SYSTEM // ---------------------------------------------------------------------------------- EXPORT void LE_System_Initialize() { System::Initialize(); } EXPORT void LE_System_Shutdown() { System::Shutdown(); } EXPORT void LE_System_SetAppName(const char* name) { System::AppName = name; } EXPORT void LE_System_SetAppPath(const char* path) { System::AppPath = path; } // ---------------------------------------------------------------------------------- // WINDOW // ---------------------------------------------------------------------------------- EXPORT Window* LE_Window_Create(HWND hwnd) { return Window::Create(hwnd); } EXPORT void LE_Window_Free(Window* window) { delete window; } EXPORT bool LE_Window_Closed(Window* window) { return window->Closed(); } EXPORT bool LE_Window_KeyHit(Window* window, int keycode) { return window->KeyHit(keycode); } // ---------------------------------------------------------------------------------- // CONTEXT // ---------------------------------------------------------------------------------- EXPORT Context* LE_Context_Create(Window* window) { return Context::Create(window); } EXPORT void LE_Context_Free(Context* context) { delete context; } EXPORT void LE_Context_Sync(Context* context, bool sync) { context->Sync(sync); } // ---------------------------------------------------------------------------------- // WORLD // ---------------------------------------------------------------------------------- EXPORT World* LE_World_Create() { return World::Create(); } EXPORT void LE_World_Free(World* world) { delete world; } EXPORT void LE_World_Update(World* world) { world->Update(); } EXPORT void LE_World_Render(World* world) { world->Render(); } // ---------------------------------------------------------------------------------- // CAMERA // ---------------------------------------------------------------------------------- EXPORT Camera* LE_Camera_Create() { return Camera::Create(); } EXPORT void LE_Camera_SetClearColor(Camera* camera, float r, float g, float b, float a) { camera->SetClearColor(r, g, b, a); } Press "Ctrl+Shift+B" C# After a successful build, let's move on to C#. Let's create a new project "Windows Forms App" Here is the program code for an example: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace LETest { public partial class Form1 : Form { const string LEDLL = "Leadwerks.dll"; [DllImport(LEDLL)] public static extern void LE_System_Initialize(); [DllImport(LEDLL)] public static extern void LE_System_Shutdown(); [DllImport(LEDLL)] public static extern void LE_System_SetAppName(String name); [DllImport(LEDLL)] public static extern void LE_System_SetAppPath(String path); IntPtr window; [DllImport(LEDLL)] public static extern IntPtr LE_Window_Create(IntPtr hwnd); [DllImport(LEDLL)] public static extern void LE_Window_Free(IntPtr window); IntPtr context; [DllImport(LEDLL)] public static extern IntPtr LE_Context_Create(IntPtr window); [DllImport(LEDLL)] public static extern void LE_Context_Free(IntPtr context); [DllImport(LEDLL)] public static extern void LE_Context_Sync(IntPtr context, bool sync); IntPtr world; [DllImport(LEDLL)] public static extern IntPtr LE_World_Create(); [DllImport(LEDLL)] public static extern void LE_World_Free(IntPtr world); [DllImport(LEDLL)] public static extern void LE_World_Update(IntPtr world); [DllImport(LEDLL)] public static extern void LE_World_Render(IntPtr world); IntPtr camera; [DllImport(LEDLL)] public static extern IntPtr LE_Camera_Create(); [DllImport(LEDLL)] public static extern void LE_Camera_SetClearColor(IntPtr camera, float r, float g, float b, float a); Thread loopThread; bool isAppWork; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { isAppWork = true; loopThread = new Thread(EngineUpdate); loopThread.IsBackground = true; loopThread.Start(); } private void EngineUpdate() { //Initialize LE_System_Initialize(); window = LE_Window_Create(panel1.Handle); context = LE_Context_Create(window); world = LE_World_Create(); camera = LE_Camera_Create(); LE_Camera_SetClearColor(camera, 0.0f, 0.0f, 1.0f, 1.0f); //Main loop while (isAppWork) { LE_World_Update(world); LE_World_Render(world); LE_Context_Sync(context, true); } //Free LE_World_Free(world); LE_Context_Free(context); LE_Window_Free(window); LE_System_Shutdown(); } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { //isAppWork = false; loopThread.Abort(); loopThread = null; } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { isAppWork = false; } } } Copy you'r "DLL" to bin folder. UPDATE: Copy these file from you'r leadwekrs project to c# bin folder: Shaders folder dContainers.dll dContainers_d.dll dCustomJoints.dll dCustomJoints_d.dll libcurl.dll lua51.dll newton.dll newton_d.dll openvr_api.dll steam_api.dll
  12. @Iris3D Games Tried it already make on Hinge Joints, nothing good came of it). EnableLimit=true (0.0) Spring=1.0 Relaxation==1.0 Damping=0.1 Objects are shaking, flying into space - the program crashes.
  13. Maybe somehow attach to the quadratic Bezier points?
  14. Tell me how to get a similar result, for bending fishing rods under load?
  15. Hi! Vehicle Physics It would be cool to add Joint:Wheel! Or give the ability to set the speed separately, for each of the wheels (example SetAcceleration(gas,tireIndex)). Аnd to individually rotate each of the wheels (example SetSteering(steering, tireIndex))! Sorry for my bad English(
  • Create New...