Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Community Reputation

1198 Excellent

About Scourage

  • Rank

Personal Information

  • Website
  • Role
    Technical Director
  • Interests


  • Twitter
  • Github

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Scourage

    Any Book Recomendations?

    I'd recommend these books:    -The Art of Game Design: A book of Lenses by Jesse Schell- This is a great book about how to look at game play and understand why its fun/engaging (not really programming) -Game Coding Complete by Mike McShaffrey-This is another great book about what it takes to build a game and the fundamentals that go into it (more programming related, but at a high level)   Why are you waiting to learn a language?   A language is just a tool to express your ideas into something a machine understand.  Whoever advised you not learn other languages is wrong, for any reason.  If you can learn one language, it can make leaning others easier.  If your classes have some made up language for a test, knowing a real language can't hurt, it should be helpful especially if they're trying to teach fundamentals of computers.     Go out and learn C# or Javascript and start experimenting in Unity right now.  It's free, there are great prebuilt assets to keep you moving forward, and it will let you focus on making your game fun vs getting bogged down in trying to  making a game.  It's a great way to get started and prevent stalling out.   BTW, you will never feel ready to start making a game.  There is always one more thing to learn.  Start now and build your experience base, even if it's not the perfect.   cheers,    Bob
  2. Scourage

    Sharing object between 2 threads

    It sounds like your main thread is running the simulation and your auxiliary thread is rendering the entities.  You can probably get away with reading the entity without locking if you make sure that you only read from it.  You need to look at it from a memory contention standpoint.  If you don't lock, you  run the risk of having part of the data change on you while you are reading from it.  It's up to you if that is a bad thing or not.   Double buffering the data may help prevent partial updates, but you need to prevent the buffers from being swapped while somebody is reading from it (again locking).    You might want to consider your threading approach.  Having a separate render thread may not be the best thing in this case.  You might want to have the main thread do an update pass then a render pass but use a worker thread pool to achieve parallelism.  Instead of having a single "coarse grain" thread for rendering, use a bunch of work threads to get "fine grain" threading within a single phase.     For example: In your main game loop, you update your game objects by passing them all off to worker threads to be done in parallel.  Then when they're all done, you go to the render phase.  In your render phase, you do entity visibility culling and build render commands per entity in a bunch of worker threads in parallel.  if you are able to encapsulate the render commands, you can build a list of them in the main thread and then pass the entire list off to a coarse grained rendering thread for execution while your main thread goes back to updating.     cheers,    Bob
  3. So the problem is that you are expecting the elements of the array to be there, but they're not.  You're only allocating the space for the elements in your array, you then need to put something there.   PlanetDetails[] Planet = new PlanetDetails[10]; for(int i=0; i<10;i++) Planet[i]=new PlanetDetails(); Cheers,    Bob
  4. Scourage

    Yeah Me!

    Nickle and dime'd my way over 1000 points.  Only took me 16 years.   Cheers,    Bob
  5. I use CMake for work, but I've been using premake (https://premake.github.io/) for personal projects and have been slowly introducing it at work.  Premake uses Lua as it's configuration language.  I find it much easier to work with than CMake, especially when writing functions to do something complicated.    To answer your original question: when I was looking for alternatives to CMake, I tried bjam, but didn't find it very user friendly.  I had used scons for a long time when working on Blender, so I knew that wasn't what I was looking for.  I stumbled onto premake and it just worked out really well for me.   cheers,    Bob
  6. Scourage

    Engine RPM and wheel angular velocity

      BoredEngineer,    Thanks for the link, that's a good article.    Cheers,    Bob
  7. Scourage

    Engine RPM and wheel angular velocity

    I would make engine RPM be some function of fuel flow or normalized throttle input.  Maybe something linear where 0 throttle = 500rpm (idle) and a throttle of 1.0 = 5000rpm.  You could then convert RPM to torque using some kind of mapping function, maybe use a datafile that defines the graph so you can have different types of engines.  Here's an example image that I found showing RPM -> torque     Once you have a torque value from your rpm value, then you need to apply your "transmission." Based on the current gear, maybe it's in reverse, you get a wheel revolution speed out of it and use that value to move your model.  To implement a clutch, you would have a function before your transmission that could simply either pass through the torque value or pass a 0 when the clutch pedal is pressed.   I'm sure I'm missing a bunch of things, but does that help answer your question?   cheers,    Bob
  8. Scourage

    Embedding Lua in C# with P/Invoke

    So the problem is that in Lua 5.3 lua_pcall is a macro, not a function.  You need to write a function that calls lua_pcallk (notice the K at the end).  I wrote mine like this:          [DllImport(LUA_DLL, EntryPoint = "lua_pcallk", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]       public static extern int lua_pcallk(IntPtr state, int nargs, int nresults, int errfunc, IntPtr ctx, LuaContinuationFunction k);       public static int lua_pcall(IntPtr state, int nargs, int nresults, int errfunc)       {          return lua_pcallk(state, nargs, nresults, errfunc, IntPtr.Zero, null);       } There were quite a few changes in the API from 5.1 to 5.3.   cheers,    Bob
  9. Scourage

    Embedding Lua in C# with P/Invoke

    I'll fill in what I can.   This may not be the best way to do this (and I'm sure there's bugs), but its been working for me so far.     In order to use p/invoke means you need to have a DLL that exports some functions.  Don't worry about the calling convention, the P/Invoke API lets you set that for your DLL you're calling into.  You also don't really need a def file, building your project as a DLL and having the right preprocessor flags set will export the symbols you want to bind to (at least in the Lua source). To build the Lua library as a DLL you simply need to build the lua library with the flag LUA_BUILD_AS_DLL, which if you look in luaconfig.h (line 235) to cause the symbol LUA_API to be defined as __declspec(dllexport).   I didn't change any code and that is all that you need to do to build lua5.3.dll with its symbols exported.     Once you have a dll with symbols (or feel free to take mine, it's a vanilla 64bit Lua dll), you need to write a C# file that can call into it.  I usually create my dll interface as a static class since each of these functions will be static functions.  I simply went through the public Lua header and then copied the functions I want to be able to call to my C# file as comments so I have them there to reference and then started writing out the p/invoke function definition for each of the C functions.          #region state manipulation /* LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); LUA_API void       (lua_close) (lua_State *L); LUA_API lua_State *(lua_newthread) (lua_State *L); LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); */       [DllImport(LUA_DLL, EntryPoint = "lua_newstate", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]       public static extern IntPtr lua_newstate(lua_Alloc f, IntPtr ud);       [DllImport(LUA_DLL, EntryPoint = "lua_close", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]       public static extern void lua_close(IntPtr state);       [DllImport(LUA_DLL, EntryPoint = "lua_newthread", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]       public static extern IntPtr lua_newthread(IntPtr state);       [DllImport(LUA_DLL, EntryPoint = "lua_atpanic", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]       public static extern LuaCSFunction lua_atpanic(IntPtr state, LuaCSFunction panicf);      #endregion Here you can see each of the static functions bind to a function in the C dll.  The DllImport attribute takes the dll filename, the function name as the entry point, the calling convention (see, no need to change how Lua is built, just change how pinvoke calls it), and a flag to suppress unmanaged security features for performance reasons.  Most basic types are handled automatically.  IntPtr is used for the pointer to the lua_State* since that's an opaque object (we don't access anything inside it ever).  If you need to shuffle complex structures between C and C#, you should look into how marshalling and layout is done on the C# side.  For callbacks, you simply need to define a C# delegate, but give it attributes that allow it to be called from C, and respecting the calling convention of your library.  Here's the delegate definition for a typical function pushed into Lua from C#:    //Delegate for functions passed to Lua as function pointers using cdecl vs the standard stdcall    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]    public delegate int LuaCSFunction(IntPtr luaState); You also need to make sure any delegates you pass into Lua from C# don't get garbage collected.  You do this by keeping a reference to the delegate around, maybe as a member of a class (see how I have myPrintFunction as a member of the LuaState below).   The dll filename is where I do something a little different.  Its an idea blatenly stolen from another project (OVR C# bindings I believe).  I preload the dll into the application before pinvoke looks for it.  I can specific the architecture I want (x86 vs x64) by prepending a path to the dll name and then using LoadLibrary to bring that dll into the application space before any p/invoke functions are called. When P/Invoke tries to find the function it looks in the application's loaded dlls first (only by name, not path+name which is why this works), then going to the working directory and looking for dlls with matching names, then if one isn't found there looking in the system path.  Pulling the DLL into the application space first can help prevent the wrong DLL being used (can happen when you have 2 versions of lua in your path, or getting a 32bit DLL  when you need a 64bit DLL).  You don't have to do this, just be sure that the DLL you want is in your application working directory or your path.   As I worked through the lua C api, I occasionally came across a macro that acted like a function, so I just implemented it as a function. Such as this: /*#define luaL_dostring(L, s) \    (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) */       public static int luaL_dostring(IntPtr L, String s)       {          int ret = luaL_loadstring(L, s);          if (ret != 0)          {             return ret;          }          return lua_pcall(L, 0, LUA_MULTRET, 0);       } Once I got through the API (there were a couple of things I either stubbed out or didn't implement, but not many), I started adding some functionality on top of the raw dll calls.  I created a LuaState object that internally has an IntPtr to a lua_State* object that is created from LuaDLL.  This class provides access functions to get/set values by name/index as well as create tables and references to them. The class also provides some nice debug functions such as printing out the lua stack and printing out a lua table to a C# console. public class LuaState    {       LuaCSFunction myPrintFuction;       IntPtr myStatePtr;       LuaObject myGlobalTable;       public LuaState()       {          myStatePtr = LuaDLL.luaL_newstate();          LuaDLL.luaL_openlibs(myStatePtr);          LuaDLL.lua_getglobal(myStatePtr, "_G");          myGlobalTable = new LuaObject(this, -1);          myPrintFuction = new LuaCSFunction(print);          LuaDLL.lua_pushcclosure(myStatePtr, myPrintFuction, 0);          LuaDLL.lua_setglobal(myStatePtr, "print");          printCallback = new PrintCallback(defaultPrint);       } ... } The LuaObject provides an interface to any lua value whether or not it's a number, string, table, or function.  It allows for iterating over a table, retrieving values or calling lua functions.  It's just a nice abstraction.    Let me know if you have any questions.   cheers,    Bob  
  10. Scourage

    Embedding Lua in C# with P/Invoke

    I wanted the same thing a while ago and rolled my own for my game engine.  If you want, please take a look at my Lua bindings for C# at: https://github.com/bholcomb/Lua-  There is a thin layer on top of the pinvoke bindings, which covers about 99% of the Lua API.  I wrote c# functions to implement the macro's in the lua header as well.  If you only want the "pure" C api, then you should only need what is in the LuaDll.cs file.  The LuaState and LuaObject are part of my thin wrapper.    It has the full lua 5.3.2 source built as part of the project, so you should only need to download, then run the build config (premake) then build the project to produce all the dlls you need.  It is expecting lua5.3.dll in a x86 or x64 folder where you run your executable from.  You can change how this works in the dllLoader class in the luaDll.cs file.   There is also a simple test console written in C# that uses the Lua#.dll to verify that it's working.     Please let me know if you find any bugs or have any questions.   cheers,    Bob
  11. Scourage

    Modern OpenGL Transforms, HOW?

    Uniform buffers are much smaller than SSBO's.  My graphics card says it supports a max of 65536 bytes in the buffer (64k).  This is enough for 1024 transform matrix's (mat4).  If you need more, or want to triple buffer so you can update without stalling rendering, then you should look at using SSBO's.  SSBO's will be at least be 16MB in size.     Cheers,    Bob
  12. Scourage

    Modern OpenGL Transforms, HOW?

    You could load up your model and indices into a VBO/IBO and then setup your VAO + shader with them.  You would then create a uniform buffer object that holds the transform matrices  as an array for all your entities and update that every frame.  Then render all the models at once using either instancing or multidraw rendering.  In your shader use the draw_ID to index into the transform matrix array to get that particular model's transform.   If you have multiple models, as long as they use the same shader and have the same vertex format, you could store them all into a single VBO/IBO/VAO and use mulitidraw with different offsets.  You would need to look at putting all the textures in a texture array or using direct state access for the texture data.   Instead of a uniform buffer, you could use a shader storage buffer if you have a lot of data to store per instance (transform, material ids, etc), then index into it using the draw_ID.  If you go the SSBO route, you may want to look at triple buffering it and persistently mapping it so that you don't stall out rendering trying to update it.   cheers,   Bob
  13. Scourage

    SFML - VAO issue

    One thing that sticks out to me is that you are unbinding the VBO before you unbind the VAO.  Try doing that the other way around.     cheers,    Bob
  14. In my rendering architecture, the renderer class owns a series of pipelines which are composed of stages.  A pipeline is for a specific cameraviewport.  Each stage can either cull/sort the renderables in the scene, or take the renderables output of a previous stage to generate render commands from them.  My scene is currently an octree of renderables, but for the longest time was simply an unsorted list.     Here's my current render setup in my game   ShadowMap Pipeline:    -Shadow map stage   Environmental Pipeline:   -Reflection map stage   Main Pipeline:     -skybox stage    -terrain stage    -model stage    -post processing stage    -Debug stage    -GUI stage   cheers,    Bob
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!