Jump to content

Josh

Staff
  • Posts

    23,235
  • Joined

  • Last visited

Everything posted by Josh

  1. Yes, it works on Mac. I have not yet successfully got the deferred rendering working on Lion, but the OpenGL 2 renderer does work, along with the editor.
  2. I like how they run for cover. You'll get more long-term views if you post your video here: http://www.leadwerks.com/werkspace/page/videos/_/le2
  3. I'll fix this in a new build...
  4. Josh

    The Last Chapter

    To avoid tunneling, you might try doing a greater number of physics updates, in smaller incrementations. You don't have much physics going on, so it seems like you could do that with no bad effects.
  5. Josh

    C++ Threads

    With Windows threads at least, they are supposed to use this type of entry point: DWORD WINAPI EntryPoint( LPVOID lpParam ) I see 32 bits in and 32 bits out, so is it okay to replace it with this?: (LPTHREAD_START_ROUTINE)(Object* EntryPoint(Object* o))
  6. And that works with precompiled third party libraries? B)
  7. Josh

    Field Trip

    I'm sure they're programmatically altering the texture's pixels, since character rendering is relatively expensive.
  8. Ah, here is the working code. TypeDef is evil: unsigned long GetMemoryUsage() { unsigned long result = 0; #ifdef WINDOWS PROCESS_MEMORY_COUNTERS process_memory_counters; if (GetProcessMemoryInfo(GetCurrentProcess(),&process_memory_counters,sizeof(process_memory_counters))) { result = process_memory_counters.WorkingSetSize; } #endif return result; }
  9. I am using "->" because the compiler complains if I use ".". No idea why. This code causes a buffer overrun: unsigned long GetMemoryUsage() { #ifdef WINDOWS PPROCESS_MEMORY_COUNTERS process_memory_counters; Print(String(sizeof(process_memory_counters))); if (GetProcessMemoryInfo(GetCurrentProcess(),process_memory_counters,process_memory_counters->cb)) { return process_memory_counters->WorkingSetSize; } else { Print(String(GetLastError())); return 0; } #endif return 0; }
  10. Josh

    Field Trip

    Wow, that is nice.
  11. Vertical sync is enabled by default, so the maximum framerate is 60 FPS. You can change this in the editor options.
  12. Josh

    C++ Threads

    Does it actually work, on OSX, Windows, Android, and iOS?
  13. What do you mean by trivial, in this context? I only normally hear that term used regarding the complexity of an implementation.
  14. Josh

    The Last Chapter

    I think you can set the light quality setting higher, it seems like there is very little edge filtering on the shadows. I also felt the controller needed more friction with the ground. It slides quite a bit which can make some jumps tricky, like that really hard part in level 3. You have basically as many lights as you want, at no cost, so I would use them! A side scroller with awesome graphics is a niche, but it has little competition, so I would push the graphics to their full extent. I could definitely see this on Steam. Can't wait to see what you do with this next.
  15. There is a section for community tutorials here, and you can upload attachments with your post: http://www.leadwerks.com/werkspace/page/Documentation/LE2/tutorials
  16. Josh

    C++ Threads

    In all seriousness, I want the lowest-level thread access possible so I can understand what is happening on all platforms completely. I also don't like compiling more libs into the engine because almost every time I do there is some little thing I have to fix. I take it I can just start calling pthread commands on Mac, iOS, and Android?: https://computing.llnl.gov/tutorials/pthreads/#CreatingThreads
  17. I wasn't thinking about this too much yet, but I don't know. We have some pretty challenging requests for the terrain system, and it will be a big chunk of work just to figure out how it should work. People want really really big terrains, so this might fit into that design.
  18. Leadwerks Engine 2 is single-threaded. The engine performs one task at a time. The engine updates physics, then performs some other tasks, then renders the scene, waiting until each task if finished before moving onto the next one: I have experience programming threads in BlitzMax, and it works pretty much the same way in C++. Leadwerks3D is taking full advantage of threads and multicore CPUs, splitting off any expensive tasks that can be run on separate threads. Multithread programming is a little different than linear programming, and you just have to design things carefully. It's okay for two threads to read a variable at the same time, but if they both try to write to the same variable, or one writes while another reads, you will have major problems. This is made harder by the unrestricted nature of Leadwerks, because the end user might call any function at any given time, and I don't want to make arbitrary rules like "You can't modify surfaces during the main game loop". Mutexes (short for mutually exclusive) are a way around this, as they lock sections of the code to prevent multiple threads from accessing them at the same time, but I try to avoid using them. It's extremely difficult to find all the parts of your code that might need a mutex locked. Also, when you start using mutexes liberally, you lose all the benefits of concurrency, because the threads have to stop and wait for each other. I prefer a design where you gather data for a thread, run the thread without interacting with any other parts of the program, and then get the results a few frames later, or whenever the thread finishes processing. Multithreading has some big benefits for the new engine. Physics Physics in Leadwerks3D are asynchronous, meaning that while the engine renders the scene and executes your game code, it's already calculating the next frame of physics on a separate thread! The diagram below shows how the physics get split off onto its own thread, then split into many threads by the solver, and the two threads meet again the next frame. (It's actually more complicated than that, the engine just keeps running until 16.667 milliseconds have passed, then it waits for the physics thread to finish, if it hasn't already.) Let's say our ideal framerate is 60 FPS, which means our target frame time is 16.667 milliseconds (=1000/60). Whereas before a physics processing time on a single thread of 10 milliseconds would eat up 2/3 of your ideal frame time, now you can have physics that take up to 16 milliseconds, and have no performance cost for a program that is otherwise running at 60 FPS. Below you can see 5000 bodies falling at near real-time speeds: NavMeshes Navmesh generation is a slow process. However, it does not need to be instantaneous. This makes navmesh recalculation perfect for multithreading. As you can see in this video, the obstacles can move around and the AI navigation will react dynamically to the environment. I've never seen a game with dynamic environments like this, so we are breaking totally new ground. As CPU core counts rise the engine will be able to use those cores to handle more complex maps and greater numbers of characters. In the meantime, it will perform well on any dual-core mobile device! Rendering Rendering in Leadwerks3D will split culling up among threads to take advantage of multiple CPU cores. This is not yet implemented, but it's a little easier than physics and navmesh threading, since it doesn't run concurrently to the main engine thread. Below is a diagram showing the complete threading design for the engine: Multithreading in Leadwerks3D is all done automatically behind the scenes, so you can still program however you want, without fear of interfering with other threads.
  19. Josh

    The Last Chapter

    I didn't even realize you could wall-jump until the second time I played it: 39:7
  20. Josh

    The Last Chapter

    The default controls were very awkward, Space or up arrow key should be jump. Control should be shoot. Enter should be push or whatever that third thing was. I really liked when 3D details in the foreground came up out of the screen, it felt almost like it was popping out of the monitor.
  21. Josh

    C++ Threads

    Because I am part of a vast conspiracy to keep Linux from becoming popular. Every little bit helps.
  22. Josh

    C++ Threads

    Eh, I got it figured out. Here's a nice little thread class if you need it: #include "../le3.h" #ifdef WINDOWS namespace win32 { #include <windows.h> } #endif namespace le3 { const int THREAD_RUNNING = 1; const int THREAD_FINISHED = 0; const int THREAD_PAUSED = 2; const int THREAD_READY = 3; class Thread { public: Object* result; #ifdef WINDOWS HANDLE id; int state; #endif Thread(); ~Thread(); virtual void Wait(); virtual bool Resume(); virtual bool Pause(); virtual int GetState(); virtual Object* GetResult(); }; Thread* CreateThread_(Object* EntryPoint(Object* o), Object* o=NULL); } #include "../le3.h" namespace le3 { Thread::Thread() : result(NULL) { #ifdef WINDOWS id = 0; state = THREAD_PAUSED; #endif } Thread::~Thread() { #ifdef WINDOWS if (GetState()!=THREAD_FINISHED) { TerminateThread(id,0); } #endif } bool Thread::Pause() { #ifdef WINDOWS if (SuspendThread(id)!=-1) { state = THREAD_PAUSED; return true; } else { return false; } #endif } bool Thread::Resume() { #ifdef WINDOWS if (ResumeThread(id)!=-1) { state = THREAD_RUNNING; return true; } else { return false; } #endif } int Thread::GetState() { #ifdef WINDOWS if (state==THREAD_RUNNING) { DWORD lpExitCode; if (GetExitCodeThread(id,&lpExitCode)==0) { //Function fails return THREAD_RUNNING; } else { if (lpExitCode==STILL_ACTIVE) { return THREAD_RUNNING; } else { return THREAD_FINISHED; } } } else { return state; } #endif return 0; } void Thread::Wait() { while (GetState()!=THREAD_FINISHED) { //win32::sleep(1); } } Object* Thread::GetResult() { if (GetState()!=THREAD_FINISHED) return NULL; return result; } Thread* CreateThread_(Object* EntryPoint(Object* o),Object* o) { Thread* thread = new Thread; #ifdef WINDOWS thread->id = CreateThread(NULL,4,(LPTHREAD_START_ROUTINE)EntryPoint,o,CREATE_SUSPENDED,NULL); if (!thread->id) { delete thread; return NULL; } #endif return thread; } }
  23. Josh

    C++ Threads

    I got started with win32 threads. I think I'd rather use my own class and just use macros to control the different behavior than to use something like Boost. How can I check the status of a thread? I need to be able to tell if a thread is still running. See Thread::GetState(): Thread.h #include "../le3.h" #ifdef WINDOWS namespace win32 { #include <windows.h> } #endif namespace le3 { const int THREAD_RUNNING = 1; const int THREAD_FINISHED = 0; const int THREAD_PAUSED = 2; const int THREAD_READY = 3; class Thread { public: Object* result; #ifdef WINDOWS HANDLE id; #endif Thread(); ~Thread(); virtual bool Resume(); virtual bool Pause(); virtual int GetState(); virtual Object* GetResult(); }; Thread* CreateThread_(Object* EntryPoint(Object* o), Object* o=NULL); } Thread.cpp #include "../le3.h" namespace le3 { Thread::Thread() : result(NULL) { #ifdef WINDOWS id = 0; #endif } Thread::~Thread() { #ifdef WINDOWS if (GetState()!=THREAD_FINISHED) { TerminateThread(id,0); } #endif } bool Thread::Pause() { #ifdef WINDOWS if (SuspendThread(id)!=-1) return true; #endif } bool Thread::Resume() { #ifdef WINDOWS if (ResumeThread(id)!=-1) return true; #endif } int Thread::GetState() { #ifdef WINDOWS #endif return 0; } Object* Thread::GetResult() { if (GetState()!=THREAD_FINISHED) return NULL; return result; } Thread* CreateThread_(Object* EntryPoint(Object* o),Object* o) { Thread* thread = new Thread; #ifdef WINDOWS thread->id = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)EntryPoint,NULL,CREATE_SUSPENDED,NULL); if (!thread->id) { delete thread; return NULL; } #endif return thread; } }
  24. Josh

    C++ Threads

    I am not new to multithread programming, but I have never done it in C++. I want to create a thread to execute a function, and be able to tell when the thread is finished. The code should run on Windows and OSX. If it can run on Android and iOS, that's great, but I don't expect it to. Where can I find a simple example that shows how to do this?
×
×
  • Create New...