Jump to content
  • Advertisement
    1. Past hour
    2. Thank you all very much. I appreciate all of your help to make me step forward and make progress. Few questions to understand the rest: 1- Is OpenGL mainly for creating games? 3D games for both Windows and smartphones platforms? 2- Aren't there any tutorial videos you have watched previously and know they're good for beginners, but in C++.
    3. Hi, I'll quickly just tell you a little bit about myself so you understand the situation. I'm currently studying Games Computing Bsc at the University of Lincoln, I'm in second year and just started C++ programming. I've just finished one of my modules which included creating a game and really got motivated to try and do something myself, I wanted to try and push myself and see what I could learn. This will help me build up my portfolio and help me understand the different aspects of C++ that I might no learn here at university. So the plan is to create a mobile strategy game. Not 100% sure of the type of game its going to be as I haven't done the design stuff yet, all I know is I want it to be a classic mobile strategy game. Some games that are similar to the ones I'm wanting to create is Sid Meier's Civilization games, Tribal Wars, Rise of Civilizations and other games in that area. I know online stuff will be tricky but I'm not entirely sure its going to be online. Basically I need to know which engine will be best for this. I'm used to UE4 and Unity. Are any of these the best way to go? Thank in advance.
    4. Howdy, I have an ARM Cortex A9 CPU, the NXP iMX6, dual core, on which runs a bare bones Linux (kernel 4.1.44). I'm trying to receive data over its Gigabit ethernet interface. goal throughput is ~ 40 MByte/s (320 Mbit/s) my default UDP payload is ~ 1350 bytes, I've experimented with sizes from 300 to 16k Bytes the ARM board is connected, via one Gigabit switch, to my PC nothing else on the switch on the PC runs the UDP client, sending data continuously the ARM runs the server which binds a socket to a port and then basically only does while(true) { poll( socket, ...); recv( socket, ...); } there is some other stuff going on like loop time jitter histogram and crude data integrity check, but commenting that out yields no difference in the problematic behavior I.e. I'm using the socket library as available on Linux. Now, according to what I've read, poll(..) blocks (in a non-busy manner) until there is data. I use it because it has timeout functionality. So from that, I should not be seeing the near maxing out of the CPU (90..99 % for my process) that I unfortunately do. Unless that throughput really is too much for that ARM CPU. But I doubt that, as iperf (2.0.5) eats "only" 50..56% CPU at ~ 40MB/s datarate. I'm not sure what exactly it does, though, looked briefly at the code and saw some fiddling with raw sockets, not sure I want to go that route... I have hardly any experience with network stuff. Also, there was this strange effect of high packet loss, despite this short connection, while a second PC as UDP receiver has no packet loss. I'd get it if the CPU were at 100% all the time, but it's slightly below - and iperf much less, which still can get like 2..4% loss. I then found some Linux settings: net.core.rmem_max and net.core.rmem_default, which I set to 8 MB each via sysctl, instead of some KB it had prior. Then the packet loss went to zero (still around 90+ % CPU load). Today I tried to replicate this, put I have packet loss again. I had also put the cheap plastic switch somewhere else, now I'm suspecting that that thing may be unreliable... yet to test. Can switches be a problem source like that? Any ideas about why the CPU load is so high? Or, in other words, am I doing this totally wrong? What would a proper implementation of relatively high speed UDP reception look like? Regards, - UB
    5. First, pick a GUI toolkit for Java. Swing, or the Eclipse SWT, are popular choices. (You could also pick a game engine with a GUI built-in, if you want to animate in real time or do 3D rendering.) Second, pick a networking technology. It may be as simple as Java object serialization across a java.net.Socket, or as advanced as some custom protocol on top of a message broker like MQTT with very sparse byte-conscious serialization over a TLS connection, to something game-based based on small UDP datagrams. Third, build your client application to make the appropriate requests on top of the protocol, render the result to the GUI toolkit, and collect user input to send new requests to the server. Fourth, develop the actual server to receive requests, process them, and send the appropriate response messages. There's the separate question of "what do I put into my messages" which depends entirely on what your application needs to do, what level of authorization you need, and so forth.
    6. Today
    7. Hello everyone! This challenge! I voted for Doom and Dungeon Crawler and I am really happy with the results of the poll. The main goal will be trying to create something with his own touch. For my last and first challenge I pretty much only tried to meet the basic requirements. This time I want to try to go a little bit further. Basics For this challenge, I want to try to get into 3D again. I actually tried to improve my Blender "skills" over the last couple of weeks. Since I was also excited for the Doom challenge I will also make this an FPS game trying to combine ideas I had for both challenges. I already started working on the main weapon. Sadly I don't have any screenshots on this laptop. The look of the models will be pretty basic since my ability to use Blender is still on a rookie level. Gameplay The game will take place in a high tech robot base that contains a lot of different rooms and hallways. If I have enough time these actually might dynamically change. The art style will be a shiny white look with simple mapping elements in order to keep things simple. The goal of the player is to find and open a portal that leads into the next level. In order to activate the portal, the player has to collect energy crystals that are scattered around each level. Enemies As enemies, I will try to create a couple of different robots that are trying to stop the player from opening the portal. These robots can either be destroyed or the player can try to sneak around them. Destroying these robots will allow the player to collect upgrades in order to improve the stats of the player's robot. Loot The main loot of the game will be the energy crystals which are needed in order to open the portal to the next level. Furthermore, enemies will drop a different sort of crystals that act as energy restoring functions of the robot or adding new abilities to his kit. There will also be other items like maps or stealth devices that help the player to get through each level. The energy of the robot will also be usable in order to purchase upgrades at rare upgrade stations which can be found once in each level. Audio This is a thing I am kinda worried about. Usually, I use a simple piece of software in order to create some retro sound effects very fast. Sadly I think these will not fit the style of this game. If this does not work I will either have to pick up some free sound effects, what I really don't like, or I will have to find a different way. Visual Art I kinda want to achieve a very "clean" and high-tech looking art style. This is kinda hard to explain without showing some visual references. I will talk more about this in my next posts. The reason for this is first, that I think this art style fits the game idea very well and second, that my Blender skills should be good enough to create some models in this style. Project Scope Completing this challenge in time will be pretty hard for me this time. First of all, I am going to try a lot of new stuff that I have not done before. Second, creating 3D Models takes a lot more time than creating simple 2D sprites, at least for me. I actually have a lot of ideas for this project. I kinda would like to implement procedurally generated levels. I don't think I will have enough time for this though. If I still have motivation left after the challenge is completed I might continue this project afterward! Sadly I can not show my current progress of the project since I can not access the project until I am back home on Thursday. Will try to make another post next weekend! Thanks for reading! Good look to everyone who is also going to join this challenge! - Znippy
    8. Bump! Still looking for people!
    9. VirviVR

      To prototype or not to prototype?

      I think prototype
    10. It was my personal experience, whilst going through a similar learning process myself in similar conditions (at about the same time, though luckily I jumped into Java and discovered the Design Patterns book early), that there is a stage when one has learned some Software Design and starts overengineering everything, resulting in such as heavy mass of things that "seem like a good idea" and "just in case it's needed" that it effectively defeats the purpose of the whole OO philosophy. Eventually one starts doing things the KISS way, Refactoring code when the conditions that defined a design decision change, and designing software driven by a "what does this choice delivers and what does it cost now and later" thus producing much more maintainable deliverable functionality (what code delivers matters vastly more than The Code) and faster. Looking back, I would say this transition only properly happened to me about 10 years after I started working as a Software Developer. I reckon this is the point when one transits from Junior Software Designer to Experienced Software Designer. It takes time to get there and I suspect not that many make this transition. There is a similar thing around Software Development Processes, which can be observed in, for example, how so many groups use things like Agile in a recipe-like fashion (and often ditching the most important non-programming bits) rather than elements of it selected based on the tradeoffs of what they deliver to the process versus what they cost (not just money cost, but also things like time, bug rates, flexibility, learning rates, etc) in the context of a specific environment (i.e. the subset of Agile for use in a big non-IT corporation is not at all the same as that for use in an Indie Game House). PS. I think the bit you mentioned about the ignorant spreading their ignorance (and damn, I look at online tutorials and that shit is all over) is basically Dunning-Krugger in action, just like we see all over society and the Internet at the moment: people who have learned just enough to think they know a lot but not yet enough to understand just how much, much more they need to learn, are still very low in terms of knowledge in an area but at the peak of their self-confidence in terms of what they think they know, so they spread their ignorance around as if it's Wisdom, and do so with all the confidence of the trully ignorant. The Original Post in this article is a stunning example of just that, which is probably why all the Old-Seadog Programmers around here seem to have jumped on it.
    11. AM_GameDesignStudent

      Looking for dedicated team

      Hello I am looking for a team that is dedicated in creating a small game. I prefer that the game is already being worked on as that shows determination in terms of completing it. Below is a link to my current resume that has video links on some of the things I have worked on in the past. However, I do have screenshots on various other things I have done and can show. I have some skill in almost everything from Level Design to some C# programming to 3D Modelling. Resume: https://drive.google.com/file/d/14JiFAatvMVfp5NutZ78YeeV_4YYw1t3O/view?usp=drivesdk
    12. 8Observer8

      In Need of direction

      This tutorial about making MMO games: Unity Multiplayer Game Development with Node I can help you to connect your desktop (or WebGL) Unity client with a server on Heroku.You can get 5 applications on Heroku by free. It is a good point to start. I made it. Unity WebGL Client: https://green-game.herokuapp.com/ Unity Desktop Client for Windows: download
    13. Whilst I have not worked in this style, I have designed systems architectures which made heavy use of segregating things into separate services (mostly to facilitate redundancy and scalability) and in my experience there is a significant cost associated with defining proper communications interfaces between services (aka APIs) and - maybe more importantly - changing them when changes of requirements result in changes to multiple "services". In fact, the part of the secret in designing high performance distributed systems was to find a good balance between decoupling and performance (both program performance and software development process performance) and always be aware of fake decoupling (i.e. when things look like decoupled, but they only work as long as certain assumptions - such as, say, no more than X elements are sent - are the same inside the code on all sides). The whole thing as you described it sounds as OO encapsulation but wrapped with a heavy layer that adds quite a lot of performance overhead and a whole new class of problems around things such as failure of request execution and API version mismatch (or even worse problems, if people decide to use networking between "services"), all the while seemingly not delivering anything of value (catering to programmer fashionism and prima-donna behaviours is not value, IMHO). Both in the literature and my experience, the best level to have service APIs at is as self-contained consistent business operations (i.e. ops which must be wholly executed or not executed at all), and I can only imagine how "interesting" things start getting with such high levels of service granularity as you seem to decribe when dealing with things such as Database Transactions.
    14. Hi khawk Great content on Ue4, really helped me through my projects Me and my team are also interested in Visualizations through Unreal engine 4, we provide assets with photorealistic quality and ready to use features. I wonder if you could give us your feedback on how are we doing and you also might grab a few tips here and there. here is our website: https://ue4asset.com Best regards Sina From Ue4assets
    15. The "new" fashion in non-games architecture is "micro-services". In this approach you abstract everything. Even the compiler and the operating system. You get complete freedom of choice over you "art" style. The assumption is: You should never re-use code across teams. A certain programmer/team can re-use their own code. However when something goes wrong and someone has to fix it: You just throw everything away, and let the new programmer start from scratch. You do this by making sure that every little piece of code is completely encapsulated in it's own server. (it even get's compiled separately.) This has performance costs (because the APIs are usually needlessly network based). It has boilerplate development costs (because the APIs are usually needlessly network based). However... The joy of being able to fix a problem by ripping out someone else's code, and then using your favourite framework to solve the problem, is really enticing. After having worked in this style for the past several years, I don't know if I like it or not. However it is a very interesting philosophy when you work on a very large project. Also, I think that the recent improvement in Docker containers makes it very manageable if you do it right. That said, the performance costs probably make it unsustainable for game dev.
    16. Damnwing0405

      Form a team

      Still looking for programmer, if got any one interested please contact me at damnwing0405@gmail.com
    17. Hi Guys. I'm currently working on a puzzle game with the theme elections. You have a board of hexagons with a color which represents the country and the majority of the voters in this part of the country. Your task is, to make the whole country vote your party. The thing I need your help with is the background. We had two Ideas, one was to lay the landscape in the further background an make it blurred out. First Screenshot the other and more useful one was to integrate the hexagons into the landscape to show that they are actually real country borders. Second Screenshot (both pics are rough designs and will be worked out. They are more like sketches of how they could look like) I wanted to know which direction seems better or more appealing for you. Thanks for your help, Luno
    18. Time for the 3AM Roundup! What was I doing all evening??.. hmm.. So, finally, these RocketBoards are ROCKETBoards! No more put-put'n around on the ground, no no no! I've completed the currency circle and now you can exchange your shiny golden rings for some airBoost Fuel! 1ring = 1 second of fuel. You can hold 100 seconds worth at a time, recharge whenever by clicking on the Rocket Shop menu item!(even while playing) This allows you to use your rocket thrusters while in the air, like every true RocketBoard should do. So, now instead of a few hundred meters on a jump from the plateau, I'm reaching 1000+ on a straight shot with lots of speed. It's so much fun. The race courses are a whole other experience like this. (Still no npcs to race with yet, it's next I swear!!) SlingBot Boarding v0.2.2: https://www.kongregate.com/games/WilliamOlyOlson/slingbot-boarding I've also put some significant work into more/better sound effects, spent some time in Audacity making some permanent remixes since I'm having trouble with applying effects in Unity, this way should be better for performance anyhow. Also spent several hours on the UI, fixing things up and making them nicer to look at(hopefully).. haha What else, mmm.. airBoost rockets, UI upgrades, Rocket Shop menu... Testing the last build... fingers crossed!!!! Ahhh Yeah! There's the money shot! Enjoy!
    19. ReyGates


    20. timothyjlaird

      To prototype or not to prototype?

      Speaking to the value of prototyping... In software development it's a necessity, it is a logical progression on the way to test driven development. If you prototype and test your design constantly during development it dramatically lowers the risk of getting weeks or months along and producing crap, or failing. It's silly and trite but our company had to do the marshmallow challenge in small groups no long ago: Every team that didn't prototype and test their design before committing the full time block failed the challenge. The damn thing flopped over. Point: invest the time to prototype, test and redesign constantly so you fail fast when it doesn't cost much instead of failing when your ass is on the line.
    21. OOP and myself, yeah. Its a like and dislike kind of scenario. In 1998 (the saddest year i had so far in my life) i started out programming in borland delphi and was thrown into OOP from the very beginning. I had no one which teached me fundamentals and internet was still too expensive. The Delphi-Helpfile was the only thing which i learned from in the early days. But for some reason, i understood it from the very beginning, classes, inheritance, interfaces, static vs non-static, polymorphism, etc. So i was liking it from the very beginning. For decades i was coding in Delphi, also mixing in other languages like C++/Java, etc. But since i started doing and seeing more and more professional work in the non-game development field, i started to see problems of over-using OOP. There are so many people/experts out there, which abuses OOP to write the worst kind of software you can imagine -> barely working, exceptions everywhere, slow like hell, untestable, impossible to understand or to follow: - Classes which are not classes - Abstractions just for the sake of it - Extendability without a reason - Hiding everything just for the sake of it - Using delegates/callbacks everywhere - Using virtual functions for no reason - Overuse of inheritance - Misuse of polymorphism If they would write it with less OOP´ness, the software would still be garbage - but i could at least understand it. Unfortunatly this kind of shit, you will find all over the place - especially in expensive business software or in the java world. But the main problem is, that those "experts" teach other people. This results in more people writing poor code, which makes me very sad :-( Another problem i often see, is that third party libraries or frameworks may forces you to write bad OOP code, due to its bad api design. I am always surprised, how customers happiely use such software in production environments. Its like a miracle that those things work. But what makes me so angry, that you can actually write good software when you use the proper tools at the right time, but people somehow have forgotten that or simply doesent care. So the conclusion for me is: OOP is totally fine, when well and not over-used. If you easiely can follow the control flow of any kind of source, the chance are much higher that its well written - neitherless of its coding style.
    22. lawnjelly

      VB Skinning

      The method used for hardware skinning is specific to the technique, often there is a matrix palette where e.g. the 4 highest weight bones are used to influence a vertex. This thread (although from 2012) might have some ideas: https://www.gamedev.net/forums/topic/631948-what-is-the-current-trend-for-skinning/
    23. yzwx1

      VB Skinning

      Yes, I do have the source code, I meant to RE the dll. The thing that I don't get about shaders is, how can it only transofrm 3(4) positions at once, while the animations have much more bones. Is the shader just sent multiple times in a draw call? Thanks a lot for the help though, I can't really find any real shader tutorials which explain them deeply anymore, also the game uses it's own APIs for Meshes etc, so I can't really know what is what.
    24. petya-kurochkin

      How to overload a function that receives a lambda?

      Hello, Alberth! Thank you for your response! If I've got you correctly, your answer is around the point, that the compiler can't really understand which function I want to call, because I don't give it enough information. I don't know C++ as well, as you know it, so your statement looks very confusing to me. Could you, please, tell me a bit more about it. I'm confused, because, it seems to be opposite to the information from Wikipedia about SFINAE: So, I have two function overloads and when I want to call one of them, the another one is not compilable. It's easy to check. Let's get this code: template <typename Λ> void call(Λ λ) { static_assert(std::is_same<decltype(λ()), void>::value, "This overload returns void"); λ(); } template <typename Λ> auto call(Λ λ) -> decltype(λ()) { auto result = λ(); static_assert(!std::is_same<decltype(λ()), void>::value, "This overload can return a value of any type"); return λ(); } void main(int argc, char** argv) { call([] {}); } If we comment out the first template, actually, there will be a compile-time error. So I understand it, that, actually I've given all the necessary information to the compiler. The call is not ambiguous, because the second template should not be able to compile. The exact problems are: auto result = λ(); static_assert(...). So, if I got the information from Wikipedia correctly, following SFINAE principle, when one function 'is not good enough to compile' - the compiler should try another overload, instead of just stopping compiling. Also, btw, this code works perfectly fine: int call(function<int(int, int)> f) { return f(1, 2); } int call(function<int(int)> f) { return f(1); } string call(function<string(void)> f) { return f(); } cout << call([](int x, int y) { return x + y; }) << endl; cout << call([](int x) { return x; }) << endl; cout << call([]{ return "It works!"; }) << endl; So, it seems, there should be a way to achive the same goals, but without using std::function or adding unnecessary parameters / changing the functions' names.
    25. lawnjelly

      VB Skinning

      I'm no longer use directX or windows, so I can't really advise on best course of action, but if all else fails you can always do software skinning yourself, then upload the skin each frame as a dynamic vertex buffer. In fact I've always implemented software skinning as a reference implementation before anything else, as a reference implementation and also as a fallback for hardware that may not support a particular method. As for asking how shaders work, that may be a bit vague for a forum question imo, you probably need to google some basics about modern 3d APIs and follow some tutorials. I don't have any special links for software skinning but this might start giving you ideas, software skinning is actually pretty easy once you have loaded the right data. It is more complex to get the bone transforms from an animation system, rather than the skinning itself, I'm kind of assuming you've got this done already in the previous code. This is all assuming you have the source code etc. When you say 'reverse engineer dll', if you are referring to a binary game, that is a whole other story and probably a lot more difficult. This is more like cracking software techniques, and also probably not something people here would advise on unless you had the legal rights to make these modifications (e.g. your own game, permission from rights holders).
    26. Esteban5XG

      What's is the best story game you've played?

      What I like the most of Deus Ex is the RTT part, because it offers me the possibility to include some tactical experiences in the gameplay.
    27. jbadams

      In Need of direction

      You probably don't want CryEngine. It's difficult to work with and not well supported. If you really want to try it out maybe look at Amazon Lumberyard, which is forked from CryEngine but includes some improvements and additions and will likely be better supported (but still isn't very popular). If it's important to you to be able to find help and examples I would probably stay away from both and use the more popular Unreal Engine instead.
    28. Well yes, if you don't give enough hints to the compiler to distinguish both cases at compile time, the decision has to be made at runtime. Computers cannot read your mind yet (probably a good thing for us), they can only act on what you wrote down. Your efforts are about reconstructing information that you lost somewhere on the path to this point. Somewhere you created these lambda functions, and at that point you knew whether or not a function takes parameters. At that same point, or somewhere further down, you perform "call(f)" where you discard knowledge of parameters of "f". Inside "call" you apparently need that information again. It was thus unwise to discard the knowledge about presence of parameters. However, the whole thing looks smelly to me. You don't specify type parameters for the parameterized lambda function, so you can't actually call it at all in that case. This essentially means you don't have 1 function, but rather you have 2 separate functions packed together, and you are using a very weird form of a boolean value to decide which "real" function you want to perform. In any case, the solution is not here, it's higher up in the path. One direction is to give both functions a separate name (call_without_params(f) and call_with_params(f)), and call the right one from a higher level. This also has the advantage you can don't have to drag the "f" parameter into the second case. Another (but equivalent) solution is to add a boolean parameter like "call(func f, bool has_parameters)".
    29. Rutin

      In Need of direction

      Unity is for C#, and it's only "cartoonish" depending on the shader used. It can use PBR just like Unreal can. Unity attracts a different kind of audience which impacts the quality of the overall releases, but it's not a limitation of the engine itself.
    30. Finalspace

      Sick of Javascript bugs, going back to Java

      8 Years ago i was full into javascript business and written 4 years straight mostly pure javascript code and did a ton of cool stuff with it - for business and for myself. Initially i hated the language, because it does things so differently than other languages, but later i started to like it. The language itself is very simple, but still very powerful - especially when you use one of the Jetbrains IDE´s (WebStorm, IntelliJ, etc.). But as i was going more and more away from javascript, i started to realize that working in javascript made me so unhappy: - Making all those shims, just to get IE and other browsers happy was so annoying. - Writing code which works on the server-side (RhinoJS, Node-JS) as well in the client-side (Browser) was pure hell. - All those JS libraries i have worked in that years was mostly pure garbage -> Very bad api design, bad support for client/server JS, tons of dependencies required, some forces you build-systems on and the worst thing: Some wasn´t even working at all. This was the reason why i always have written everything myself and not relied on any library - not even on JQuery, even though i think JQuery was one of the better libraries. Dont get me wrong, i still think the language itself is totally fine. Sure the prototype thing is weird, but you get used to it. But i totally hate the ecosystem around javascript. Every f..... day more JS libraries come out, trying to either replace or extend another libraries, propable based on another library. But years later the library is not supported anymore, or disappears, or crashes on new browsers - so you constantly have to switch from one library to another. It is a total nightmare. Nowadays i am really happy, that i am working on a totally different environment now (C/C++, C#, Desktop applications, Libraries, Backend). I will propably wont going back to javascript and i definitily will never going back to the web development shit i was working for over a decade.
    31. Alberth

      Project file in Code:Blocks

      First thoughts: - Is the file filter on the file selection set correctly? - Are there actually files in that directory which match the file filter? Otherwise, you may get better and faster answers at a dedicated CodeBlocks forum, as there they likely know everything and more about CodeBlocks there.
    32. bigmacmuffin

      In Need of direction

      SFML I would look into that. Currently though Im looking into Unreal, Unity, and Cry engine. Unity seems to be the easiest to get into but the design is cartoonish. Im still debating with myself with Unreal and Cry. Unreal seems to be more widely used but I also wanted to see cry engine because I think it is more stable (remembering the Crysis game).
    33. Rutin

      In Need of direction

      If you're looking at getting into 2D game development I would suggest looking into SFML once you have a good grasp of the language itself. If you would like to start in 3D game development, then the Unreal Engine would be a great start. If you have specific questions with problems you're having, then feel free to post a topic and I'm sure you'll find answers! SFML: https://www.sfml-dev.org/index.php Unreal Engine: https://www.unrealengine.com/en-US/what-is-unreal-engine-4
    34. You're on the wrong forum, "game design" is about how to make a game fun to play. Thread will be moved no doubt. Otherwise, I am missing a question, what is the problem? I have no idea what "League of Legends" does, so there is nothing I can do with that reference. As for your question, I assume the second sentence is the topic. I will invent a few questions, and answer them. If I didn't give the right question, please ask it. - Can it be done? Yes of course it can (probably League of Legends proves it, doesn't it?) - How can it be done?: You write a Java program that performs web queries programmatically. Java has libraries for this. - Who can do it? Only you can, this site is not a service for writing programs, it's about how to write programs (and games in particular).
    35. timothyjlaird

      Game Dev. Laptop

      Thinkpad not a fit then. If they had ported ut3 to Linux I would run a test for you but they never did...but looking at their dev specs it would be constantly pushing that machine to the limit. I have verified it kicks ass with quake era, css and vanilla opengl graphics but I would call it a excellent coding laptop with workable 10 year old graphics and that's it. If you take windows 10 off (that it ships with) and put lubuntu on it it does really well but no miracles
    36. bigmacmuffin

      In Need of direction

      To start of Hello guys Happy Holidays. I am currently venturing game development as a Side project to keep myself busy from being in between jobs. I have adequate knowledge in C++, I should have pursued a career in programming but I went and worked as a Cook (Yes I have been told that the two professions are very far from each other) any how as a kid I always wanted to make my own game and maybe an mmo, but here in the philippines I can hardly find a career in game development that is why I pursued my other hobby which is cooking. Now getting to the direction part. Can I have recommendations on what platforms/compilers/engines/programs/languages I need to kick start this project. I am currently brushing up in my C++ knowledge, and crunching brain muscles in my concept and world creation. Thank you in advance,
    37. Hello! I'm sorry, I'm very new to C++, so the question can be very silly. So, sorry about it, but I failed to answer on my own. So! I have a function that receives a lambda: template <typename Λ> auto call(Λ λ) -> decltype(λ()){ return λ(); } What I want is two have 2 different functions: for lambdas that return a value and for lambdas - that do not. So another overload would look like (pseudocode): template <typename Λ> auto call(Λ λ) -> decltype(λ()) == void{ λ(); } Okay, my the next though - is to use SFINAE to achieve that. Honestly, I've never used SFINAE before, so I failed: template <typename Λ> auto call(Λ λ) -> decltype(λ()) { static_assert(! std::is_same<decltype(λ()), void>(), "This overload can return a value of any type"); return λ(); } template <typename Λ> void call(Λ λ) { static_assert( std::is_same<decltype(λ()), void>(), "This overload returns void"); λ(); } It even compiles! But, let's test it: cout << call([] { return 1; }) << endl; call([] { 2 * 2; }); These two `call` calls are ambiguous (at least, in MS VS). I can't understand why - I'm using static_assert, so the call should not be ambiguous. If you can, please, explain me the situation. Then, I tried another way: template <typename Λ> auto call(Λ λ) -> decltype(λ()){ using namespace std; if (!is_same<decltype(λ()), void>()) { return λ(); } else { cout << "Just do some work!" << endl; } } Suddenly, it works. I understand, that, roughly, it compiles to: void call(Λ λ) { if (false) { return λ(); } else { cout << "Just do some work!" << endl; } } and, for example: int call(Λ λ) { if (true) { return λ(); } else { cout << "Just do some work!" << endl; } } So, everything is correct, though, for some reasons, I don't like this approach. It looks more like a workaround, not like a real solution. But what would you do? Also, I wonder, what should I do, if I need to add overloads, that depend on lambda-parameters. For instance, it works: void call(function<void(int, int) f){ ... } void call(function<void(int) f){ ... } void call(function<void(void) f){ ... } But I don't want to have run-time penalty, because of using std::function!
    38. Super Game Asset is pleased to announce today 10 sets of icons from our original library have been updated, and re-released it in 256x256 resolution format! This will allow our icons to look incredible on almost all platforms and devices. Beginning with the EPIC RPG series, and Fantasy RPG series, the following products have been updated with 256x256 resolution Basic RPG Items Epic RPG Items Epic RPG Equipment Fantasy RPG – Accessories Fantasy RPG – Armour Fantasy RPG - Army Skills Fantasy RPG – Consumable items Fantasy RPG – Hero skills Fantasy RPG – Military ability Fantasy RPG – weapons We are also in the process of updating all our icon library to 256x256 resolution, so check our store often. Super Game Asset 2018
    39. Super Game Asset is pleased to announce today 10 sets of icons from our original library have been updated, and re-released it in 256x256 resolution format! This will allow our icons to look incredible on almost all platforms and devices. Beginning with the EPIC RPG series, and Fantasy RPG series, the following products have been updated with 256x256 resolution Basic RPG Items Epic RPG Items Epic RPG Equipment Fantasy RPG – Accessories Fantasy RPG – Armour Fantasy RPG - Army Skills Fantasy RPG – Consumable items Fantasy RPG – Hero skills Fantasy RPG – Military ability Fantasy RPG – weapons We are also in the process of updating all our icon library to 256x256 resolution, so check our store often. Super Game Asset 2018 View full story
    40. Like League of Legends authetication. Access my server through a desktop icon, and authenticate users that run a java program on a windows machine, rather than through a web browser. Thanks, CE
    41. cfescript

      Game Dev. Laptop

      I would love to be able to have something that can run Unreal. Doesnt have to be able to run games max settings 60fps but just something i can use for game engines.
    42. DexterZ101

      Sick of Javascript bugs, going back to Java

      Oh... JavaScript the language that was written in 10 days; the first version named Mocha, most of JavaScript developer I know personally admits it's one of the terrible programming language ever created and I don't see any problem about it, because even it's creator Brendan Eich, knows there's a lot flaws and drawbacks in the language design. It's sucks but that doesn't mean it's not good to do the job done, there's a lot of hacky and wacky way we can do with this language for small scripting that needs to interact on the DOM elements it's perfectly fine, but for larger application, if the design is not carefully crafted it's a nightmare to debug, hard to managed and maintain in the long run. Enter the JavaScript SuperSet and Transpiler! Even the some big corporations like Google and Microsoft know that JS has too many flaws but it has become the defacto scripting language for the HTML, Google make a transpiler for JS out of DART language and Microsoft has it's own transpiler for JavaScript called TypeScript which is also a superset of JS ( Ok we know Microsoft J# didn't succeed and they trash Silverlight LOL ) and there are other transpiler like Coffescript,ClojureScript,PureScript,Etc.. that can use to minimize bugs and make our life easier than just using plain JavaScript. I choose TypeScript in making my Game Engine for the the web it's pure HTMLT/JS no jquery or whatsoever and I'm loving it The caveat part is combining the web app with the DOM it's too slow the reason I also created my own GUI purely written in JS, Ok shameless plug about my project for the sake of discussion : - D The hardest part in developing web app using Javascript is to make your code compatible on all browser, Chrome,IE,Edge,Firefox,Dolphin,Etc. Imagine you have tweak everything for just a mouse button because different browser has their Javascript engine as in IE9 called Chakra. Does this mean you write your code in notepad? there's a lot of great editor for Javascript, they build this tools to minimize errors in our code most of popular JS editor has an intellisense, compiler warnings, and some form of auto complete with all the parameters and method name; if do it by hand most likely a lots of bugs will occur upon interpretation of the script. My final two cents : C++ and other low level language created so we no longer have to write code in assembly; as JavaScript is the defacto scripting language for the web, poeple created superset and transpiler for it, to make our life easier in building our web application. Stay with JavaScript use a the right tools available that solved if not minimized most the problem by just using plain JS in building web application; EcmaScript with latest specification offers us modern solution that we can't imagine we can do it today on our browser we now have Canvas, WebGL, WebSocket and other great stuff. Cheers ^_^y
    43. _WeirdCat_

      GLSL, Point Sprites, Geometry Shader problem

      Maybe instead using glortho you should go for the shader approach, how can one use glortho and shaders anyway, that seems useless, and you put every sprite in range from -1..1 for both x and y Where -1,-1 is 0,0 position and 1,1 would be 800,600 Or was that 0,600 and 800,0 That depends....
    44. I have the same opinion of JavaScript (Lots of bugs that would be caught in a static library), but it's mostly the same issue I have with all dynamic languages. It's dynamic nature makes it difficult to consume libraries. A lot of is alleviated by heavy use of unit testing, good naming of variables, documentation and including the expected parameter and return type\s in documentation (Oops, why were we using a dynamic language again?).
    45. NikitaSadkov

      Video Game Plot Generator

      Just found a check-list on how to make games like Bioware does. Add following and you got the next Dragon Age!
    46. That is okay, not all people like complex games. But game design involves two fundamental concepts: gaming pieces and space, which are there even in card games. Time is part of the space concept. There are numerous ways to implement the notion of time, and velocities of objects moving through it. And the Final Fantasy Tactics style scheduling appears to be closest to model real time and without making game mechanics overly complex. In my game I'm using the "player moves all his units during his turn" mechanics, but I had to implement numerous complex hack to make fast units receive more actions per turn. In fact, the whole time mechanics takes several A4 pages to describe. Despite the original Final Fantasy Tactics having no multiplayer, its system actually favors multiplayer, because players don't have to wait long before having to move again, but play more like a chess exchanging smaller turns.
    47. Any time you write an application that runs on someones computer, that user has the ability to manipulate it however they want; It's their computer. Though there's some ways you help combat this, having as many things as you can be server-sided is a good approach. This means that all data is stored on the server, and the clients only get to make requests to have data be changed. The server then gets the overall say in whether or not those changes are accepted. As a general rule of thumb, you should not blindly accept any data the client sends the server out-right, it needs to be checked for validity first on the server. Though this wont stop people from making their client, for example, change player positions locally. That's not something you can really stop without an additional client-side anticheat system, but there aren't tools for this with Java, as far as I'm aware. It's higher level, and the JVM that houses your bytecode can always be changed by some exploiter. What server-sided cheat prevention does, is it prevents users who are already exploiting have their exploits affect other users. Certain game types are easier to protect than others. A lot of RTS's have an easy time with cheat prevention, because you can easily make the clients wait 100% on server synchronization (clients just send click requests to the server, server handles literally everything except drawing graphics). This creates a delay in input, which is not optimal for other game-types (see FPS's). First person shooters cannot have this type of synchronization, because the user needs instant feedback of what they're doing or the experience is ruined.
    48. Project Title:SteamFallDescription:The player begins the game in a underground cryogenic lab where he wakes up after 70 years of being cryogenically frozen. The player goes to the surface only to find a desolate wasteland. You must find out what happened.Includes: Post-Apocalyptic & Steampunk atmosphere. Unique Story First person view point. Ambitious in scope. Team Name:Team DATA7 Previous Work:N/A - first title as a team.Talent Required:3D Artist (2+) Ability to export to FBX format. Experience with UE4 toolset a bonus. Expected to create additional props & Hardsurfaces And environments And 3D Characters Expected To Rig & Animate any creature Unreal Engine Programmers (2) Experience with Unreal required. Experience with UE4 toolset a bonus. Expected To Code in-game Systems Must Be Able To Work with and be nice to others Contact:E-mail: Data7games@gmail.com
    49. How do I approach this? Specifically, I know how I would approach this in javascript, but I don't want my images to be moved around and fixed through html/js manipulation. Thanks, CE
    50. timothyjlaird

      Game Dev. Laptop

      Kind of depends on what kind of game development 😋 I have a Lenovo Thinkpad T430 (refurbished) with SSD that fits me great, but I don't do the unity stuff. It's plenty fast to run counter strike source era stuff though. And cheap. $300. Buy a spare battery to go with it and you are set. Bring your desktop to college and stick in your dorm to run the heavy stuff. You can bring this to class. Spill coffee, buy another... https://www.amazon.com/dp/B0733H5YZY/ref=cm_sw_r_cp_awdb_t1_WPegCb5VBZDBS
    51. 3dBookman

      The 3D book

      After a break of several years the 3D book project is back on. A few short words now on what this blog is about. I have to deliver my wife to the bus station in a few minutes, then a week alone so may have the time then to explain things. But the 3D book is something I started in 014 and put several years into, then the break, now on again. A win32 app with a text window and an ogl window. I just remembered I had something written on this so here it is I write to see if anyone in this community of game developers, programmers, enthusiasts, may be interested in a project I have been developing[off and on] for several years now. So follows a short description of this project, which I call the 3D-Book project. The 3D-Format Reader: A new format of media. Imagine opening a book, the left page is conventional formatted text - on the right page a 3D animation of the subject of the text on the left hand page. The text page with user input from mouse and keyboard, the 3D page with user input from a game pad. An anatomy text for a future surgeon, with the a beating heart in 3D animation. A children's story adventure book with a 3D fantasy world to enter on the right page. ... Currently 3D-Format Reader consists of a C++ Windows program: Two "child" windows in a main window frame. Two windows: a text-2D rendering window and a 3D-rendering window. The text-2D window, as its' name implies, displays text and 2D graphics; it is programmed using Microsoft's DirectWrite text formatting API and Microsoft's Direct2D API for 2D graphics. The 3D-rendering window uses the OpenGL API. A 3DE-Book page is formatted in one of two possible modes: DW_MODE or GL_MODE. In GL_MODE both windows are shown; the text-2D rendering window is on the left and the 3D OpenGL window is on the right. In DW_MODE, only the text-2D rendering window is shown, the OpenGL window is hidden (Logically it is still there, it has just been given zero width). The 3D-Format Reader reads text files, which consists of the text of the book, control character for the formatting of text, (bold, underline, ...), display of tables, loading of images(.jpg .png ...), and control of 2D and 3D routines. 3D-Reader programming is based on a Model-View-Controller (MVC) architecture. The MVC design is modular: The Controller component handles user input from the operating system , the Model component processes the input, and the View component sends output back to the user on the display. Typical Parent-Child windows programs have multiple "call back" window procedures(winProcs): One for the parent window and one for child window. The MVC model, simplifies message routing by using a call-back window procedure which receives Windows messages for the main window, the text-2D window and the OGL window. A sample MVC program by Song Ho Ahn was used as a template for the 3DE-Reader. Rushed for time now, so a hasty sign off and thanks for reading. ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 8 - 21 -18 I spent the last few days working on procedural mesh generation. First looking to find a bit of code to do what I had in mind. Which begs the question: What did I have in mind? I just wanted a cube mesh generator such that... Requirements Input: An integer n = units from origin to cube face. Output: The vertices for a unit cube centered on the origin. 8n² triangles per cube face. 3 times 8n² verts in clockwise winding order (from the outside of the cube) ready for the rendering pipeline. Screenshot of some cubes generated with the procedural cube mesh generator. That was about it for the output requirements. I did not want to hand code even a single vertex and did not want to load a mesh file. I was sure the code was out there somewhere, but was not finding it. So, a bit reluctantly at first, I started coding the mesh generator. I started enjoying creating this thing and stopped searching for the "out-there-somewhere" code; although still curious how others did this. Analysis First question: How do we number the verts? It would be great to conceive of some concise algorithm to put out the cube face verts all in clockwise order for the outside faces of the cube directly. That seemed beyond me so I plodded along step by step. I decided to just use a simple nested loop to generate the cube face verts and number them in the order they were produced. The hope(and the presumption) was: The loop code was in some order, running thru the x y and z coordinates in order, from -n to +n, therefore the output would be a recognizable pattern. The simple nested loop vert generator did not let us down: It gave us a recognizable pattern, at least for this face. It turned out (as expected now) that all six faces have similar recognizable patterns. Plotting the first row or two of verts you can easily see how to run the rest of the pattern. Plot of the first(of six) cube faces verts output by the vert generator: Input of n: There are (2n+1)² verts per cube face, or 25 verts for n = 2. This is looking at the x = -n face from the outside of the cube. To simplify the math it helps to define s = 2n. Then there are (s + 1)² verts, or 25 for s = 4 s² cells on the face, or 16 for 4 = 2. We are going divide each cell into 2 triangles, so there are 2s² triangles per face, or 32 for s = 4. Second question: What pattern for the triangles? How to number the 2s² = 32 triangles? What we want in the end is a bit of code such that... for triangles T[0] thru T[2s²-1] or T[0] thru T[31]( for n = 4), we have T[N] = f0(N), f1(N), f2(N). Where f0(N) gives the first vertex of T[N] as a function of N. and f1 and f2 give the second and third verts, all in CW winding order looking into the cube of course. Here the choice is a bit arbitrary, but it would seem to make things easier if we can manage to have the order of triangles follow the order of verts to a degree. Numbering the triangles. And now the problem becomes: Look at the triangle vert list, T0 - T8...T31 in the image, and try to discern some pattern leading us to the sought after functions f0(N), f1(N), f2(N) where N is the number of the triangle, 0 thru 2s²-1. This really is the holy grail of this whole effort; then we have T[N] = f0(N), f1(N), f2(N) and that list of verts can be sent directly to the rendering pipeline. Of course we want these functions to work for all six faces and all 12s² triangles to cover the cube. But first let's see if we can just do this one face, 0 thru 2s²-1.. Thru a bit of trial and error the 32 triangles(T0 - T31) were ordered as shown. Now we have an ordered list of the triangles and the verts from our loop. T0 = 0 5 6 T1 = 6 1 0 T2 = 1 6 7 T3 = 7 2 1 T4 = 2 7 8 T5 = 8 3 2 T6 = 3 8 9 T7 = 9 4 3 T8 = 5 10 11 ... T30 T31. If we can find a pattern in the verts on the right side of this list; we can implement it in an algorithm and the rest is just coding. Pattern recognition: It appears T2 = T0 with 1 added to each component T3 = T1 with 1 added to each component In general T[N+2] = T[N] with 1 added to each component, until we come to T8 at least. Also it is hard to recognize a relation between the even and odd triangles,To see what is happening here it helps to look at an image of the generalized case where n can take on any integer value n > 0. Looking for patterns in this generalized(for any n) vert plot we see... We have defined s = 2n. The 4 corner coordinates(+-n,+-n) of the x = - n cube face, one at each corner (+-n,+-n). There are (s+1)² verts/face numbered (0 thru (s+1)² -1). There are 2s² triangles/face numbered (0 thru 2s² -1). They are indicated in red. It's not as bad as it looks iff you break it down. Let's look at the even triangles only and just the 0th vert of these triangles. For any row we see the number of that first vert of the even triangles just increases by one going down the row. We can even try a relation such as T[N].0 = N/2. Here T[N].0 denotes the 0th vert of th Nth triangle. Which works until we have to jump to the next row. Every time we jump a row we T[N+1].0 = T[N].0 + 2 for the first triangle in the higher row. So we need a corrective term to the T[N].0 = N/2 relation that adds 1 every time we jump a row. We can use computer integer division to generate such a term and N/2s is such a term. It only changes value when we jump rows and we get our first function ... f0(N) = N/2 + N/2s. (even triangles) Remember the integer division will discard any remainder from the terms and check this works for the entire cube face, but only for the even triangles. What about the odd triangles? Going back to the triangle vs vert list for the specific case n = 2, s = 4 for the first row; we see for the odd triangles T[N].0 = T[N-1].0 + s + 2. And adding this term, s + 2 to the formula for the even triangle 0th vert we get f0[N] for the odd triangles. f0(N) = N/2 + N/2s + s + 2. (odd triangles) Continuing this somewhat tedious analysis for the remaining functions f1(N), f2(N) we eventually have these relations for the x = -n cube face triangles. for N = 0 thru N = 2s² - 1. defining m = N/2 + N/2s. T[N] = m, m + s + 1, m + s + 2 T[N] = f0(N), f1(N), f2(N). (even N) T[N] = m + s + 2, m + 1, m T[N] = f0'(N), f1'(N), f2'(N) (odd N) So it turns out we have two sets of functions for the verts, fn(N) for the even triangles and fn'(N) for the odd. To recap here; we now have formulae for all the T[N] verts as functions of N and the input parameter n: Input: An integer n = units from origin to cube face. But this is only for the first face x = -n, we have five more faces to determine. So the question is: Do these formulae work for the other faces? And the answer is no they do not, but going through a similar analysis for the remaining face gives similar T[N] = f0(N), f1(N), f2(N) for them. There is still the choice of how to number the remaining triangles and verts on the remaining five faces, and the f0(N), f1(N), f2(N) will depend on the somewhat arbitrary choice of how we do the numbering. For the particular choice of a numbering scheme I ended up making, it became clear how to determine the f0(N), f1(N), f2(N) for the remaining faces. It required making generalized vert plots for the remaining five face similar to the previous image. Then these relation emerged... For face x = -n T[N] N(0 thru 2²-1) we have the f0(N), f1(N), f2(N), even and odd For face x = n T[N] N(2s² thru 4s²-1) add (s+1)² to the x=-n face components and reverse the winding order For face y = -n T[N] N(4s² thru 6s²-1) add 2(s+1)² to the x=-n face components and reverse the winding order For face y = n T[N] N(6s² thru 8s²-1) add 3(s+1)² to the x=-n face components For face z = -n T[N] N(8s²0 thru 10s²-1) add 4(s+1)² to the x=-n face components For face z = n T[N] N(10s²0 thru 12s²-1) add 5(s+1)² to the x=-n face components and reverse the winding order And these are enough to allow us to write explicit expressions for all 12n² triangles for all 6 faces T[N] and what remains to be done is to implement these expression in code. Which turned out to be a much simpler task than finding the f0(N), f1(N), f2(N) and resulted in a surprisingly short bit of code. Implementation I have attempted to make this C++ snippet of code as generic as possible and have removed any dev-platform specific #includes and the like. GLM, a C++ mathematics library for graphics developed by Christophe Riccio is used. It is a header only library. https://github.com/g-truc/glm/releases/download/ That is the only outside dependency. // Procedural cube face verticies generator #include <vector> #include <glm/gtc/matrix_transform.hpp> struct Triangle { glm::vec3 vert[3]; // the three verts of the triangle }; /* std::vector<Triangle> cube_Faces(int n) Input: integer 'n'; the units from origin to cube face. Output: vector<Triangle> glTriangle; container for the 12*(2*n)² triangles covering the 6 cube faces. */ std::vector<Triangle> cube_Faces(int n){ size_t number_of_triangles(12*(2*n )*(2*n)); size_t number_of_face_verts(6*(2*n +1 )*(2*n+1)); std::vector<glm::vec3> face_verts(number_of_face_verts); std::vector<Triangle> glTriangle(number_of_triangles); // Generate the 6*(2n +1 )² face verts ------------------------------- int l(0); for(int i = 0; i < 6; i++){ for(int j = -n; j <= n; j++){ for(int k = -n; k <= n; k++){ // Below "ifS" strip out all interior cube verts. if( i == 0){ // do yz faces face_verts[l].x = (float)(-n); //x face_verts[l].y = (float)j; //y face_verts[l].z = (float)k;}//z if( i == 1){ // do yz faces face_verts[l].x = (float)(n); //x face_verts[l].y = (float)j; //y face_verts[l].z = (float)k;}//z if( i == 2){ // do zx faces face_verts[l].x = (float)j; //x face_verts[l].y = (float)(-n); //y face_verts[l].z = (float)k;}//z if( i == 3){ // do zx faces face_verts[l].x = (float)j; //x face_verts[l].y = (float)(n); //y face_verts[l].z = (float)k;}//z if( i == 4){ // do xy faces face_verts[l].x = (float)j; //x face_verts[l].y = (float)k; //y face_verts[l].z = (float)(-n);}//z if( i == 5){ // do xy faces face_verts[l].x = (float)j; //x face_verts[l].y = (float)k; //y face_verts[l].z = (float)(n);}//z l++; } } } // Generate the 12*(2*n)² triangles from the face verts ------- int s = 2*n; int q = 2*s*s; int a = (s+1)*(s+1); int f(0); int r(0); int h(0); for( int N=0; N < number_of_triangles; ){ // triangles already in CW winding if( N < q || N < 5*q && N > 3*q - 1 ){ // do the even indicies f= q*(N/q); r = a*(N/q); h = (N-f)/2 + (N-f)/(2*s) + r; glTriangle[N].vert[0] = face_verts[h]; glTriangle[N].vert[1] = face_verts[s + 1 + h]; glTriangle[N].vert[2] = face_verts[s + 2 + h]; N++; f= q*(N/q); r = a*(N/q); h = (N-f)/2 + (N-f)/(2*s) + r; // do the odd indicies glTriangle[N].vert[0] = face_verts[s + 2 + h]; glTriangle[N].vert[1] = face_verts[ 1 + h]; glTriangle[N].vert[2] = face_verts[h]; N++; f= q*(N/q); r = a*(N/q); h = (N-f)/2 + (N-f)/(2*s) + r; } // triangles needing reverse order for CW winding if( N > 5*q - 1 || N < 3*q && N > q - 1 ){ // do the even indicies glTriangle[N].vert[0] = face_verts[s + 2 + h]; glTriangle[N].vert[1] = face_verts[s + 1 + h]; glTriangle[N].vert[2] = face_verts[h]; N++; f= q*(N/q); r = a*(N/q); h = (N-f)/2 + (N-f)/(2*s) + r; // do the odd indicies glTriangle[N].vert[0] = face_verts[h]; glTriangle[N].vert[1] = face_verts[1 + h]; glTriangle[N].vert[2] = face_verts[s + 2 + h]; N++; f= q*(N/q); r = a*(N/q); h = (N-f)/2 + (N-f)/(2*s) + r; } } // Normalize the cube to side = 1 ------------------------------ for(int i = 0; i < number_of_triangles; i++){ glTriangle[i].vert[0].x = glTriangle[i].vert[0].x/(2.0*(float)n); glTriangle[i].vert[0].y = glTriangle[i].vert[0].y/(2.0*(float)n); glTriangle[i].vert[0].z = glTriangle[i].vert[0].z/(2.0*(float)n); glTriangle[i].vert[1].x = glTriangle[i].vert[1].x/(2.0*(float)n); glTriangle[i].vert[1].y = glTriangle[i].vert[1].y/(2.0*(float)n); glTriangle[i].vert[1].z = glTriangle[i].vert[1].z/(2.0*(float)n); glTriangle[i].vert[2].x = glTriangle[i].vert[2].x/(2.0*(float)n); glTriangle[i].vert[2].y = glTriangle[i].vert[2].y/(2.0*(float)n); glTriangle[i].vert[2].z = glTriangle[i].vert[2].z/(2.0*(float)n); }; return glTriangle; } The rendering was done using OpenGl. // OGL render call to the cube mesh generator - PSUEDOCODE int n(2); int cube_triangle_Count = (12*(2*n)*(2*n)); std::vector<Triangle> cube_Triangles(cube_triangle_Count); cube_Triangles = cube_Faces(n); glBindBuffer(GL_ARRAY_BUFFER, uiVBO[0]); glBufferData(GL_ARRAY_BUFFER, cube_Triangles.size()*sizeof(Triangle), &cube_Triangles[0], GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), 0); glEnableVertexAttribArray(0); glDrawArray(GL_TRIANGLES,0,3*cube_triangle_Count); This just gets the position attribute of the cube face triangle verts; for the color and other attributes there are a couple of options: Use separate GL_ARRAY_BUFFERS for the color and other attributes. Or add attributes to the Triangle struct... struct Triangle { glm::vec3 vert[3]; // the three verts of the triangle attribute1; attribute2; ... }; Screenshot of the spherified cube. What's next? Now that we have the cube mesh what we can do with with it practically unlimited. The first thing I did was turn it into a sphere. Playing with tesselating the cube or sphere or stellating it with different patterns; might do. Ended up trying a few matrix transformations on the cube mesh. These are shown in the image below. These shapes are result short bits of code like the code for the column shape below. //Column for(int i = 0; i < number_of_triangles; i++){ for(int j = 0; j < 3; j++){ if( glTriangle[i].vert[j].y < 0.5f && glTriangle[i].vert[j].y > -0.5f ){ float length_of_v = sqrt((glTriangle[i].vert[j].x * glTriangle[i].vert[j].x) + (glTriangle[i].vert[j].z * glTriangle[i].vert[j].z)); glTriangle[i].vert[j].x = 0.5f*glTriangle[i].vert[j].x/length_of_v; glTriangle[i].vert[j].z = 0.5f*glTriangle[i].vert[j].z/length_of_v; } } } Doing this; the blacksmith at his forge analogy soon presents. The mesh is the ingot, hammer matrices stretch, round and bend it against the fixed geometry of the anvil - coordinate system. I am the smith. Tetrahedron The tetrahedron is the platonic solid with the least number of faces(4), edges(6), and verts(4). In antiquity it was associated with the element of fire due to its' sharp vertices. The algorithm for the tetrahedron mesh was developed in a similar way to the cube, but here it seemed simpler to get a routine for just one face - an equilateral triangle - and use matrix translations and rotations to form the complete tetrahedron. So more like origami or tinsmithing than blacksmithing. Procedural tetrahedron screenshot. The n = 4 and the general case To get an routine for the general case, n an integer > 0, a bit of what I think is known as mathematical induction was used. PSUEDO-CODE Algorithm to generate equilateral triangle face with unit side composed of n² "sub-triangle" in the xy plane. std::vector<Triangle> equilateral(int n){ std::vector<Triangle> tri_Angle(n²); // Create the seed triangle in xy plane . // This is triangle "0" in the image above. // This is in the xy(z=0) plane so all the // tri_Angle.vert[0 thrue n -1 ].z = 0. // We just work with the x and y verts. tri_Angle[all].vert[all].z = 0; // The seed triangle tri_Angle[0].vert[0].x = 0; tri_Angle[0].vert[0].y = 0; tri_Angle[0].vert[1].x = 1/2n; tri_Angle[0].vert[1].y = sin(π/3)/n; tri_Angle[0].vert[2].x = 1/n; tri_Angle[0].vert[2].y = 0; // Build the equilateral triangle face. int count(0); for(int row = 0; row < n; row++){ count = 0; Spin = glmRotateMatrix( π/3, zaxis ); // The magic happens here! for(int i = 2*n*row - row*row; i < 2*n*row - row*row + 2*n - 2*row - 1; i++) { if (count % 2 == 0 ) // Triangle is even in the row - just translate { // more magic. x_Lat = glm_Matrix((count + row)/2n, row*sin(π/3)/n, 0.0f); tri_Angle[i].vert[0] = x_Lat* tri_Angle[0].vert[0]; tri_Angle[i].vert[1] = x_Lat* tri_Angle[0].vert[1]; } else // Triangle is odd in the row - rotate then translate { //and more magic. x_Lat = glm_Matrix((count + row + 1)/2n, row*sin(π/3)/n, 0.0f); tri_Angle[i].vert[0] = x_Lat*Spin*tri_Angle[0].vert[0]; tri_Angle[i].vert[1] = x_Lat*Spin*tri_Angle[0].vert[1]; } } count++; } return tri_Angle; } This is the psuedocode version of the routine which generates the verts for the n² triangles in a face. Getting this algorithm was a bit of a brain drain but looking for patterns in the image of the face allowed it to happen. We use a "seed" triangle, which is triangle 0 on the lower left of the figure. The verts of this one triangle are input; the rest of the n² triangles verts are generated by translating and rotating this seed triangle. Notice: There are n rows, every row has 2 less triangles than the row below. If we number the triangles from 0 to 2n - 2*row - 2, where the rows run 0 to n; the even triangles just need to be translated ... in the x direction by (count + row)/2n where count = their position in the row 0 to 2n - 2*row - 2. in the y direction by row*height. height = height of seed triangle. The odd triangles need to be rotated pi/3 = 60 degrees around the z axis then translated ... in the x direction by (count + row + 1)/2n where count = their position in the row 0 to 2n - 2*row - 2. in the y direction by row*height. height = height of seed triangle. Now we have a single face for the tetrahedron, to join the four faces together we need the angle between the faces called the dihedral angle. Dihedral Angle Each of the five platonic solids has a characteristic called the dihedral angle. This is the angle between the faces. For the cube it is 90 degrees or pi/2 radians. For the tetrahedron it is 70.528779° = arccos(1/3) = atan(2*sqrt(2)); The tetrahedron, with just four faces, is the simplest of the platonic solids. The simplest way I can think of to build it: Start with the four face stacked one on another, edges aligned. Imagine the top three faces each hinged to the bottom face along one edge. Then rotate each face around then hinged edge by arccos(1/3), the dihedral angle. That is the method of the bit of code shown below. vector<Triangle> tetrahedron(int N){ std::vector<Triangle> tetra(4n²); tetra[all].vert[all].z = 0; // The seed triangle tetra[0].vert[0].x = 0; tetra[0].vert[0].y = 0; tetra[0].vert[1].x = 1/2n; tetra[0].vert[1].y = sin(π/3)/n; tetra[0].vert[2].x = 1/n; tetra[0].vert[2].y = 0; // ----- The first face ----- // generate the first equilateral triangle face with unit side // composed of n² "sub-triangle" in the xy(z=0) plane. int count(0); for(int row = 0; row < n; row++) { count = 0; Spin = glmRotateMatrix( π/3, zaxis ); for(int i = 2*n*row - row*row; i < 2*n*row - row*row + 2*n - 2*row - 1; i++) { if (count % 2 == 0 ) // Triangle is even in the row - just translate { x_Lat = glm_Matrix((count + row)/2n, row*sin(π/3)/n, 0.0f); tetra[i].vert[0] = x_Lat* tetra[0].vert[0]; tetra[i].vert[1] = x_Lat* tetra[0].vert[1]; } else // Triangle is odd in the row - rotate then translate { x_Lat = glm_Matrix((count + row + 1)/2n, row*sin(π/3)/n, 0.0f); tetra[i].vert[0] = x_Lat*Spin*tetra[0].vert[0]; tetra[i].vert[1] = x_Lat*Spin*tetra[0].vert[1]; } } count++; } // ----- The second face ----- // generate the second equilateral face from the first // by rotating around the X axis by the dihedral angle. float tetra_Dihedral = atan(2*sqrt(2)); Spin = glmRotateMatrix( -tetra_Dihedral, xaxis ); //just rotate for(int i = 0; i < n²; i++) { for(int j = 0; j < 3; j++) { tetra[n² + i].vert[j] = Spin*tetra[i].vert[j]; } } //The rotation gives CCW verts so need need to make them CW again for(int i = n²; i < 2n²; i++) { swap(tetra[i].vert[0] ---- with --- tetra[i].vert[2]; } // ----- The third face ----- // For the second face we rotated the first triangle around its' // base on the X - axis. For the third face we rotate the first // triangle around its' edge along the vector ( 0.5, 0.866025, 0.0 ). Spin = glmRotateMatrix( tetra_Dihedral ,glm::vec3(0.5f,0.866025f,0.0f)); for(int i = 0; i < n²; i++) { for(int j = 0; j < 3; j++) { tetra[2n² + i].vert[j] = Spin*tetra[i].vert[j]; } } //need to make it CW again for(int i = 2n²; i < 3n²; i++) { swap(tetra[i].vert[0] ---- with --- tetra[i].vert[2]; } // ----- The forth face ----- // For the forth face we first translate the original face along the // X axis so it right edge vector (-0.5f, 0.866025f, 0.0f) passes thru the origin. // Then we rotate the first triangle around the that vector by the dihedral angle. x_Lat = glm::translate( glm::vec3(-1.0f, 0.0f, 0.0f)); Spin = glmRotateMatrix( -tetra_Dihedral, glm::vec3(-0.5f,0.866025f,0.0f)); for(int i = 0; i < n²; i++) { for(int j = 0; j < 3; j++) { tetra[3n² + i].vert[j] = Spin*x_Lat*tetra[i].vert[j]; } } //need to make it CW again for(int i = 3n²; i < 4n²; i++) { swap(tetra[i].vert[0] ---- with --- tetra[i].vert[2]; } // We now have the complete tetrahedron, tetra(4n²), but its' base // is not horizontal so let's make is so. // put the base in the xz plane // rotate 90 - dihedral angle around X axis. Spin = glm::rotate( tetra_Dihedral - half_PI, xaxis); for(int i = 0; i < 4n²; i++) { for(int j = 0; j < 3; j++) { tetra[i].vert[j] = Spin*tetra[i].vert[j]; } } // We now have the complete tetrahedron, tetra(4n²), sitting with its' // base on the xz(y=0) plane, let's put its' center at the origin. // For this we need another Platonic Solid attribute: The radius of // the tetrahedrons circumscribed sphere which is sqrt(3/8). So the // center of the tet is this vertical distance down from its' apex. // To put the center at the origin we need to translate down this // distance along the Y axis. We need also to xlat along the Z axis // by 1/2(sqrt(3)) = 0.28867; the distance from the center of a face // to the center of a side. // Finally we need to center along the X axis( xlat -.5) x_Lat = glm::translate( glm::vec3(-0.5f, -sqrt(3/8), sqrt(3)/2); for(int i = 0; i < 4n²; i++) { for(int j = 0; j < 3; j++) { tetra[i].vert[j] = x_Lat*tetra[i].vert[j]; } } return tetra; } Notes: Oops: Left out std::vector<Triangle> tri_Angles(4*n*n); Should be the first line of the function body! Corrections to the corrections: First line of function definition vector<Triangle> tetrahedron(int N){ should be vector<Triangle> tetrahedron(int n){ Those last two for loops could and probably should be combined to do a translate*rotate*triangle in one statement, but I have not tried it. All distances are for a tetrahedron with unit side. The sign of the dihedral angle in the rotations was usually determined by trial and error. I.e.; I tried one sign, compiled the code and rendered the tet. If it was wrong I just reversed the sign. The end result is a tetrahedron with its' center at the origin, its' base in the xz plane, and one edge parallel to the X axis. Of the five platonic solids; three (tetrahedron, octahedron, icosahedron) are composed of equilateral triangle faces. One of square faces (cube). And one of pentagon faces (dodecahedron). Two tetrahedrons fit nicely in a cube. 11-16-18: Corrections to code blocks for equilateral triangle and tetrahedron. 11-18-18: More corrections. Icosahedron Two faces = Icosahedron Petal Five petals in this flower = 10 faces = half of the icosahedron 12-5-18 Understanding the icosahedron's 3d form via 2d images is difficult; we need to make a small, palm sized, 3d model. It takes nineteen paper triangles and some tape. The vertices of five equilateral triangles must come together at each vertex of the icosahedron. The icosahedron has 20 faces and 12 verts, but leaving one face off the model allows us to look in side. Besides; when where done we'll have a neat little icosahedron basket. You don't really need to make a model to code the icosahedron; but it helped me to see some properties which simplified its' construction. Symmetries are important to the mathematician and perhaps even more so to the physicist. They say something has a certain symmetry if you perform a certain operation on it and the world remains unchanged. Unchanged in the sense that you can not even detect something has been done to it. Example: Rotate a square 90 degrees around its center in the plane; the square has that type of rotational symmetry. The square also has an inversion symmetry; if you take every point on the square and invert it through the origin you end up with the same square you started with. Inversion is simply negating all the coordinates. The center must be at the origin of course. This is true for the cube, but not for the tetrahedron. Symmetries simplify the construction (coding) of an object. Going back to the cube; it might have been easier to do three faces and then just invert them thru the origin to get the other three. For the tetrahedron simple inversion is not a symmetry, but I am pretty sure inversion together with a rotation is. If so; we could do two faces and then perform an inversion - rotation on them in one step. And inversion in Cartesian coordinates just means to negate all the verts - easy! Toying with our icosahedron model; holding it gently with our thumb on one vertex and our middle finger on the opposite vertex, lazily twirling it around an imaginary axis through those two vertices; we are struck with a thought: We are toying with our icosahedron model twirling it around an axis through - Eureka! - two opposite vertices: The icosahedron has inversion symmetry. This is great - our work has just been cut in half. We can code half of the icosahedron's verts and just invert(negate) to get the rest. Thank you inversion symmetry. But let's not stop now, we are on a roll (no pun intended); let's see if we can find more symmetries to make our work easier. Looking intently; holding our model as before, but still, not rotating. Then slowly rotating about the axis we see another symmetry. After one fifth of a revolution(2π/5 radians) the universe looks the same as when we started rotating it. The icosahedron has a 2π/5 rotational symmetry. Can we use this to cut our work load? You bet we can. First we need to clear up a few points about something central to our construction efforts: The axis of symmetry. (Sorry, the puns just keep coming.) An axis of symmetry is a line passing thru two opposite vertices and the center of the icosahedron. The icosahedron has six of them: We only need one. We will use the Z axis. Dihedral angle: To be precise, it is the angle between the normals of two adjacent faces. The images: Looking at the images we see a flower shape with five "petals". A petals is just two faces joined along a side. The angle between the two petal faces is the icosa's dihedral angle; arccos(- √5/3) radians. Five petals make a "flower" , which is ten faces, so it is half of the icosahedron. Once we have five petals joined to make this flower, we just copy/invert all its' verts to get the other half: We have our icosahedron. The Plan: Refer to the figures 1.) Make a petal. 2.) Attach one tip of the petal the axis of symmetry. (Oriented properly of course.) 3.) Copy/rotate the petal around the axis of symmetry by 2π/5 radians four times to get five petals = a flower. We are using the 2π/5 radians rotational symmetry here. 4.) Copy/invert( r -> -r ) our five-petal-ten-face flower to get our 20 face icosahedron. Using inversion symmetry here. So just four steps; sounds simple enough. Each step has its own steps of course, but they are mostly intuitive common sense things we must do to get the result. Constants: Before we get to the code we need four constants. 1.) The dihedral angle between two faces, the dihedral_angle. dihedral_angle. = arccos(- √5/3) = 46.06322 radians = 138.18969°. 2.) The angle between the Z axis and the normal of a face of a petal at the vertex. 0.652351 radians 3.) The radius of a circumscribed sphere(A sphere that touches all 12 verts). In other words the distance from the icosahedron center to a vertex. Also called the circumradius. R = sin(2π/5). 4.) The rotational symmetry: 2π/5 radians Let's not do a blow by blow, or should say, a bend by bend, description of the code. If a picture is worth a thousand words, it seems safe to assume an animated 3D image is worth even more. I suggest we compile the code and render to the display step by step. In fact this is how the code was developed; with a projection matrix and a rotation around the Z axis. Compile - Render the first face: F0. " " the first petal: P0 from F0 and F1. " " the second petal P1. " " the third petal P2. " " the fourth petal P3. " " the fifth petal P4. We now have the flower. Compile - Render the inversion of the flower. Done. The icosahedron pseudocode. struct Triangle { glm::vec3 vert[3]; // the three verts of the triangle }; //PSUEDOCODE ICOSAHEDRON /* input: integer n - number of triangles along icosahedron edge. output: std::vector<Triangle> icosahedron - mesh with 20n² triangles. */ std::vector<Triangle> icosahedron( int n ){ const float dihedral_Angle = acos(-(sqrt(5.0f)/3.0f)); const float dihedral_Comp = π - dihedral_Angle; std::vector<Triangle> T_icosahedron(20n²); // Create the seed triangle T. Triangle T; T.vert[0].x = 0; T.vert[0].y = 0; T.vert[0].z = 0; T.vert[1].x = 1/2n; T.vert[1].y = sin(π/3); T.vert[1].z = 0; T.vert[2].x = 1/n; T.vert[2].y = 0; T.vert[2].z = 0; // ----- F0 ----- // Create the first face; "F0" in the xy(z=0) plane // from the seed triangle T. int count(0); for(int row = 0; row < n; row++){ count = 0; for(int i = 2*n*row - row*row; i < 2*n*row - row*row + 2*n - 2*row - 1; i++){ if (count % 2 == 0 ){ // Triangle is even in the row - just translate . x_Lat = glm::translate(count+row)/2n, row*sin(π/3), 0); for(int j = 0; j < 3; j++){ T_icosahedron[i].vert[j] = x_Lat*T.vert[j]; } } else{ // Triangle is odd in the row - rotate then translate. x_Lat = glm::translate( glm::vec3((count+1+row)/2n, row*sin(π/3), 0)); Spin = glm::rotate( π/3, zaxis ); for(int j = 0; j < 3; j++){ T_icosahedron[i].vert[j] = x_Lat*Spin*T.vert[j]; } } count++; } } // At this point comment out the rest of the code, // return T_icosahedron; // Compile and render F0 to the display. // ----- P0 ----- // Create the first petal "P0" in the xy(z=0) plane. glm::vec3 axis(0.5f, sin(π/3), 0.0f); Spin = glm::rotate( π/3, zaxis ); //just rotate Spin2 = glm::rotate( -dihedral_Comp, axis ); for(int i = 0; i < n²; i++){ for(int j = 0; j < 3; j++){ T_icosahedron[n² + i].vert[i] = Spin2*Spin*T_icosahedron[i].vert[j]; } } // xlate P0 by -1.0 along x and bend down by epsilon from the xy plane // epsilon is the angle we want between the Z axis and the normal of F0. // epsilon = 0.6523581f; x_Lat = glm::translate( glm::vec3(-1.0f, 0.0f, 0.0f)); Spin2 = glm::rotate( glm::mat4(1.0), -π/3, zaxis ); Spin = glm::rotate( glm::mat4(1.0), -epsilon, xaxis ); //just rotate for(int i = 0; i < 2n²; i++){ for(int j = 0; j < 3; j++){ T_icosahedron[i].vert[j] = Spin*Spin2**x_Lat*T_icosahedron[i].vert[j]; } } // At this point comment out the rest of the code, // return T_icosahedron; // Compile and render P0 to the display. // Create P1 from the P0 verts, rotate 2π/5 around z then Spin = glm::rotate( 2π/5, zaxis ); //just rotate for(int i = 0; i < 2n²; i++){ for(int j = 0; j < 3; j++){ T_icosahedron[i+2n²].vert[j] = Spin*T_icosahedron[i].vert[j]; } } // At this point comment out the rest of the code, // return T_icosahedron; // Compile and render P0 - P1 to the display. // Create P2 thru P4 from P0 verts: rotate around z: // 2*2π/5 for P2, 3*2π/5 for P3 and finally 4*2π/5 for P4 // P2 Spin = glm::rotate( 2*2π/5, zaxis ); //just rotate for(int i = 0; i < 2n²; i++){ for(int j = 0; j < 3; j++){ T_icosahedron[i+4n²].vert[j] = Spin*T_icosahedron[i].vert[j]; } } // P3 Spin = glm::rotate( 3*2π/5, zaxis ); //just rotate for(int i = 0; i < 2n²; i++){ for(int j = 0; j < 3; j++){ T_icosahedron[i+6n²].vert[j] = tSpin*T_icosahedron[i].vert[j]; } } // P4 Spin = glm::rotate( 4*2π/5, zaxis ); //just rotate for(int i = 0; i < 2n²; i++){ for(int j = 0; j < 3; j++){ T_icosahedron[i+8n²].vert[j] = Spin*T_icosahedron[i].vert[j]; } } // At this point we should have the full flower. // Comment out the rest of the code, // return T_icosahedron; // Compile and render P0 thru P4 to the display. // Move everthing up along z to put the icosahedron center at the origin. // radius of circumscribed sphere = sin(2π/5), for face side = 1. x_Lat = glm::translate( glm::vec3(0, 0, sin(2π/5)); for(int i = 0; i < 10n²; i++){ for(int j = 0; j < 3; j++){ T_icosahedron[i].vert[j] = x_Lat*T_icosahedron[i].vert[j]; } } // invert all the verts and reverse for cw winding // this creates the other half of the icosahedron from the first 10 triangles for(int i = 0; i < 10n²; i++){ for(int j = 0; j < 3; j++){ // invert T_icosahedron[i+10n²].vert[j].x = -T_icosahedron[i].vert[j].x; T_icosahedron[i+10n²].vert[j].y = -T_icosahedron[i].vert[j].y; T_icosahedron[i+10n²].vert[j].z = -T_icosahedron[i].vert[j].z; } // Swap verts 0 and 2 to get back to CW winding. hold = T_icosahedron[i+10n²].vert[0];// reverse T_icosahedron[i+10n²].vert[0] = T_icosahedron[i+10*n²].vert[2]; T_icosahedron[i+10n²].vert[2] = hold; } return T_icosahedron; // Spherify - uncomment the code below to spherify the icosahedron /* for(int i = 0; i < 20n²; i++){ for(int j = 0; j < 3; j++){ float length_of_v = sqrt( (T_icosahedron[i].vert[j].x * T_icosahedron[i].vert[j].x) + (T_icosahedron[i].vert[j].y * T_icosahedron[i].vert[j].y) + (T_icosahedron[i].vert[j].z * T_icosahedron[i].vert[j].z)); T_icosahedron[i].vert[j].x = T_icosahedron[i].vert[j].x/length_of_v; T_icosahedron[i].vert[j].y = T_icosahedron[i].vert[j].y/length_of_v; T_icosahedron[i].vert[j].z = T_icosahedron[i].vert[j].z/length_of_v; } } */ return T_icosahedron; } Screen-shots: First petal P0 and five petal icosahedron flower.
  • 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!