Jump to content
  • Advertisement


  • Content count

  • Joined

  • Last visited

Community Reputation

341 Neutral

About freeworld

  • Rank
    Advanced Member
  1. freeworld

    Just a tease

    Still gotta fix the wall doubling and start forcing the one creature per tile rule, but I've got my basic dungeon generation finished. Now just got ot find some time to do something else ;) For the sake of keeping this short and simple heres a video.
  2. freeworld

    Pre-Visualization Is Important!

    You began by bashing the gamedev community.... not even going to go further. Gotta love a teacher that says, everyone (people who arent me) suck so do what I tell you to cause I'm the $!!!
  3. freeworld

    C++11 Lesson Two: Variables!

    What would you do for console output? I'm referring to my (huge) C++11 book right now .   That scares me coming from the tutorial writer.... are you just copying that book and taking credit for cause it's in your own words?     Not all operators are one character in size.  You have the bit-shift operators << and >>, and the increment and decrement operators ++ and --.   let alone the statement doesnt fall true when it comes to overloading the operators of complex objects, atleast not to a point that I feel would be clear enough for a beginner.
  4. freeworld

    There's monsters in here

    Nothing super spectacular, well actually it is for me, but it doesn't look it.... Found a major bug of sorts in my dungeon generation algorithmn. it refuses to put corridoors were I want them. On top the fact life has been throwing me curve balls left and right, I'm sparse on time. My factory implementations aren't as concrete as I thought they were. Unknown design issues with third party types threw a big wrench into things. I hacked together a quick chunk to get things loading and displaying correctly, but I'm going to need a refactor. Which I think I'll use my next chunk of time to do. Gotta clean things up every once in a while and make sure I'm staying on track with my original goals. I use a sorta factory design to load in templates of everything. Such as a creature factory that loads all the base templates of each creature type. The rest of the program is supposed to then be able to create new creatures from the templates. Unfortunately some of the objects with my objects are sensitive :( . Several implement copy constructors and so forth, but I failed to read about the various variables that don't get copied and must be set through the new objects interface. This made me get sickly dirty to hack together the copying outside of the factory for the video. Till next time happy coding, I'll have a walking player and traversable floors by the next update. *cross my fingers*
  5. freeworld

    More Rouge

    Unfortunately no video, the view component is my next big hurdle though. DUNGEON: I've been putting most my effort into getting the dungeon generator up and running before getting things on the screen. The dungeon is a container the holds a series of floors. Each floor contains a terrain, monsters and items on the floor and other various objects that exist on that floor. The idea is that when the player enters a floor, the game will pull the floor from the dungeon and use it as the active floor. When the player leaves the floor, it gets saved back into the dungeon at its current state. To generate each floors layout I'm using a rough binary space partitioning method. Starting with a starting quad that covers the entire bredth of the floor. I then randomly split the quad in half along with the resulting childs. This splits the floor into a series of neighboring rooms. I then randomly delete some of the rooms, while making sure they are all still connected. For now the generator then randomly places monsters and items throughout the floor. ACTIONS AND EFFECTS: I settled on a list of every action I want to support. I split the actions into different categories based on the data required to perform the action. Combat actions are rather small, but refer to any action that uses the creatures equipped weapon. Equip actions, once again small, refer to ofcourse equipping items. unequipping, dropping and picking up items also fit neatly into this category. Terrain actions for things like moving, opening doors or using stairs. Lastly, consumtion actions are for use items in the inventory. Things like eating food and drinking a potion. I grouped using wands and throwing into this category aswell. it might seem like it makes sense to put those into the combat category, but the data required makes it fit better in the consumable list. Consumables are pretty boring by themselves though. Most if not all will have a related effect. effects can be simple things like "IncreaseHealth" which will increas the targets health by the given amount. Effects are further described with what are valid targets for the effect. Items like a potion of healing might actually use a "IncreseUsersHealth" effect that only allows targeting the user of the action. A wand of healing on the other hand would allow targeting the user and other creatures. This does limit the combinations of item types and the effects that can be associated with them. Such as equipment won't be able to have effects like that of a healing potion. I do want to keep things simple though so no biggy if I can't make crazy items like an amulet that casts fireballs. Next I WILL have the basic view put together with the logic to move the camera around the floors and traverse up and down them. 'Til then happy coding.
  6. freeworld

    Crawling For Fun

    I never could stick with netHack, but its been a few years. it was always the better looking ones in my opinion though. I'm an annoying fanboy when it comes to 2D over 3D, I still think Red Alert 2 has far better graphics than any of the 3d Command and Conquers. I think that's why I've been so hooked on Crawl. It's got the great gameplay that comes with a big rougeLike and the nice interface of traditional 2D games.   I'm aiming for complete mouse support though, so any keyboard shortcuts will be few beyond moving, I think it'll make it a bit easier to manage basically just two buttons. It'll keep the possibility of too many things happening at once out of the picture with the way I laid it out.
  7. freeworld

    Crawling For Fun

    Dungeon Crawl Stone Soup I finally crawled back into the world of RougeLikes, I could never bring myself to play any ASCII version consistantly. I've been hooked on 'Dungeon Crawl Stone Soup'. Which has a graphical version (tiles) aswell and is updated quite alot. The mechanics are similar to D&D rules. You start off as a single guy trying to get to the bottom of a dungeon, steal an orb and get the hell out. Simple as that.... until you play it. My favourite and the most fustrating part of the game is the immense unknown. The first time you die on the first floor cause you drank a potion of poison will make you scream and laugh all the same. You'll quickly learn how fragile you are and that everything in the game can be a deadly threat. The moment you feel strong you're almost gauranteed to slip up and send your hero to the grave. Aslong as you can transition to the "take your time" attitude, you'll find the game easy enough but it could take years to actually beat it. Rough RougeLike A post or two ago I mentioned a random dungeon generator I was messing around with. I figure it's a great jumping point for trying a small RougeLike project of my own. So I put together a simple prototype, just melee combat. I've spent a bit of time working out the base structure of the game, the objects and divisions of the program. Hopefully it's just a matter of coding it all now. The major roadblock I'm trying to decide on first though, turn order and queueing actions. In the prototype, there was only two actions a creature could take, items can't take actions. They either walked, attacked or did nothing. It was pretty easy to queue a simple struct like so;struct ACTION{usertarget;type;} An actionProcessor object would store all the actions in a vector, then when it came time to process the turn. it would sort them all by the users speed and process the actions one by one. I plan to use something similar, but I'm also storing creatures, items and all other objects different then before. Before, the handles to the actors were very loose. The actor could be nonexistant and the handle could still be used. it would just cause the action processor to disregard the action entirely once one of the actors wasn't found. This wasnt a bottle neck what so ever in the prototype, but I wouldn't think so with only 15 actors present. I plan on floors with 200+ objects present all the time, so looking through an entire list of objects everytime I want to find one isn't going to work. I decided to go with a simple quadTree container that will be used to store the actual objects. Then the controllers and actions will use iterators into the sub containers that hold the objects. The actions take pointers to these iterators as aurguments for the user and targets of an action. This means iterators can't be removed until all actions are processed or so voodoo needs to happen to remove actions with iterators that were removed while it's processing, and that just seems wasteful. Simply checking if either is invalid because of death or out of range or etc seems more logical. Now that I'll be using more fragile pointers, and quite alot more actions; also with items being and other objects possibly part of a given action but not all. It makes it a bit more complicated. Hopefully it'll all come clear after I finish my list of every action I want to be possible. I already am thinking I'll have seperate processors for item type with specific functions for the different actions / effects that can occur because of those items. Equipping as simple as it seems is a perfectly good example of an action. // basic action infotype = action_equipuser = selftarget = self// equip specificequipment equipment The action processor can read that its an equip actions which would then pass all the data to equipmentProcessor.actionEquip(....), these could simply be utility functions. I'm thinking of using a base class action that has the basics, user, target, type, but will also have a processor id. This id will simply tell the main action processor which sub processor to pass the action off to. Then that processor will know how to recast it and process the action. My brain is brimming with ideas now... Happy coding, next time I should have a worth video ;)
  8. freeworld

    Prototyping, designing and videos

    [quote name='Giallanon' timestamp='1341562730'] nice guitar playing [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img] [/quote] Thank you, I'm very undisciplined in it though.... bonus points if you can name my two biggest influences. [quote name='szecs' timestamp='1341590569'] Hmm, I've just prototyped my second game idea, it seems is sucks a bit... [/quote] It happens alot. You definitely learned something along the way though. Even if all it was, was learning to code faster. It's still beneficial. And think now you don't have to waste a week writing up a doc, then another couple months of coding a clean product to learn that it really wasn't the great idea you first thought it would be. You can also now look at your idea and say "what was fun about it and what wasn't". Think about what would you do different if you removed everything you don't like in the prototype. What kind of gameplay would you do differently while trying to maintain the parts you did like. I unfortunately tend not to reply to others journals but I do check em out every so often. But I got to say as a life time lover of legos (me and my son build entire cities some times and let godzilla rampage 'em) I'm F$@#$$#@ jealous of the jeep you put together.
  9. A man of few words, but the attention whore inside me has been waiting for over a month now. Here goes Design and learn by prototyping. Prototyping I've found to be a great exercise in teaching myself to pump out better code, faster. If only I could find some time to be less tired and motivated to do more than a 1-2 hour burst of coding. Only one project have I ever wrote or actually developed a fleshed out design or layout of the application. My framework has been the only big enough and intricate enough project to make that worth it. Everything else, I just get an idea and once I have time, I sit down and just code until I can see something on the screen. Then hack in all the other ideas I had with it. If it's looking good, I'll go back and clean it up or actually take the time to design it on paper then re code the whole thing. I still see alot of posts on gamedev that are all along the lines of "What's the best way to do this?". I've come to believe there is never a best way to design and build an application. Sure there maybe a best way to optimize a small operation, such as the best way to sort a list with specific parameters. I'm talking about full fledged applications / games. The best way can only ever be found by coding the project and seeing how your implementation works. Even then, after you've come up with the best way as you see it. Down the road you'll probably think of an even better way to do it as you learn new techniques. That's why prototyping is so great. It lets you see your design ideas in action. You get to actually see how your code interacts as a whole. I still always find so many flaws in my ideas once I've coded them. There is just way to much an project that you'll never be able to plan for everything, and why would you. All the time you spend designing and just thinking about your game, is time you could spend coding and actually seeing if it works. Believe it or not, even after you've got your design down, once you start coding. You're design is going to start changing constantly to fix flaws you can only find by running the actual application. Now I'm talking about the average coders projects, not the next "Skyrim", or projects that take on multiple programmers (which i see over done on such small projects in the help wanted so often). Most average projects at best are on the size of a platformer, or top down shooter. I'd even say a single player rts game falls in this category as well. All of these can be thrown together as a prototype with very little pre planning or designing. *Warning I get rude here* If you have to spend more than a couple hours fleshing out the basics of what you're trying to create with something this size. You really should ask your self, "Do I know enough to finish this project, let alone in a timely fashion?" If you find yourself perusing the internet for solutions or asking how to implement your concepts on the forums every time you sit down to code. You're probably biting off more than you can chew. There is a huge difference between asking "How do I move a sprite in the direction it's facing?" and "How do I add a technology tree to my RTS project?". I see the later style question, asked alot on the internet. If that is you, you should go back to the basics and work on alot simpler projects until you can come up with solutions to these questions on your own. *rudeness hopefully over ;)* Prototyping is also great practice in churning out lot's of code that works. Programming is one of those things that is best learned kinetically, the more you do it, the better you're going to be at it. Code, code, code and code some more. You don't have to prototype a whole game. You want to be prototyping features and ideas. Take for example, the trading card based game I've been working for a while. Everything in it was prototyped by myself, before I ever designed the complete system. This took me through several iterations, were even at one point I ditched the whole idea of using the card mechanics. I prototyped the idea of loading a series of cards as a deck and being able to draw cards into your hand and place them on the game board. I prototyped the interaction of the actual game pieces and how the went from being cards to being an interact able object on the game board. I prototyped the animation system. I eventually even prototyped the idea of using a whole different base engine for the game. Doing so helped me see how the actual concepts fit together, how they might fit better if I did things different. I got to play the game in different ways and which forms were boring and which were fun to me. I found lots of organizational flaws and the bugs they caused. All of which has helped me put together a far more accurate design of the game. One that so far, I have yet to go to implement something in the design and said "Nope that design sucks, how am I going to fix this without breaking the rest?". a couple quick vids to demonstrate a little of what I'm talking bout here. Note this game was originally intended to be a blend of tower defense and trading card games. My first prototype was fleshing out the card system. Loading a deck of cards, and drawing them into your hand then placing them onto the game board. [media][/media] Shortly after a couple more prototypes I put together one that ditched the cards and used a set selection of towers. This eventually felt boring to me and started realize my brain was just copying another famous tower defense game ;) [media][/media] The most recent I threw together a version that uses pathing rather than the row based design. [media][/media] In short what I want to get across to all you beginners, instead of asking how to do make a game. Just start coding the smaller parts of it. then code, code, and code some more till your idea is complete. You can clean the spaghetti mess up later. Happy coding and have fun... Ill leave you with this [media][/media]
  10. I'm just waiting until they introduce the in game lobbies, then you all will know what legendaries are for.... looking fancy of course. I feel 110% the way you do about the game, I have one and only one character I will ever play in D3. Ill wait till theyre is a reliable way to be rushed to lvl 60 act 1 inferno before playing other characters. Since the drab storytelling and repetitive nature of the level designs are already annoying the second time around. I will say, the first time I play'd, and all the way through my first play through on normal. I did it solo and explored every nook and cranny. I loved it. It was until nightmare that I realized that it is the exact same thing almost to a tee, except every number in the game has been doubled. Then in hell, same thing except now they have all been tripled. I play carelessly for 20 minutes every other day, slowly pushing along inferno. And have recently started up a new strafer in d2, and she is 100% more fun than my character in d3. act2 normal she finds charms that would be godly compared to anything I've found in inferno If you've never tried out the eastern sun mod for diablo 2, it is an unbelievable treat for any d2 fan that likes to play solo.
  11. freeworld

    Long time no see, gamedev

    Busy busy this man is. Well as usual I'm very good destroying hardware... but keep it to yourself. rawr, servers beware, the cursed one is here. I actually went computer less for a couple months. Stuck to pen and paper to flush out my ideas and phone for surfing the 1's ad 0's. As I last left off I was working on a little game trying to use trading card game mechanics. At one point I took this to the tower defense genre. It didn't fit very well and when it did, it seemed way too much like a rip off of 'Plants vs Zombies'. So back to the four player version using a game board not unlike a chess board. The basics of the game is each player plays his turn out one at a time. Everything is turn based, each game piece can execute one action a turn. Each turn the player resource pool grows slightly allowing them to play tokens to the battlefield or cast spells from the tokens in hand. To win a player must get his token within reach of the players home squares and attack (move onto) them to deal damage to the player. By moving tokens to a square they consume it, converting it to one their tiles. The point here is that tokens can only be placed on the tiles you own. Your home tiles of course can never be converted or occupied by your opponent. Therefore there is always somewhere to place your tokens. Bolting your tokens straight for a player can be beneficial too, as it lets you play new tokens closer to the enemy's home. I'm still implementing the base structure of the game, and making sure the mechanics work correctly and are fun. The player cant play it at the moment, but I have a rudimentary AI in place to test things out. I also picked up some crack from Blizzard North earlier this month, and boy was I dissapointed. Only time will tell if it was really worth it... so far nah. It did create this itch in me to mess around with procedural generated worlds again though. Spent a couple hours yesterday and through together simple dungeon generator. Only floors and walls at the moment. Each piece of wall is a game object though. Which every object in the game from a breakable barrel to the player will be based off of. I think Ill throw together a simple gauntlet/zelda clone to get my feet wet in component based designs. Right now it uses an inheritance design, as that was a lot easier to throw together for something I was just messing around with. Got an hour or two before work, gonna throw together some code to populate the dungeon with things like barrels, bookcases, candles and other little nick-nacks that will all be interact-able with the player. Oh and both these little projects are using SFML, instead of my homebrew engine. I got to say it's very nifty and fast to get up and running. Though lacks alot of the specialized things I had incorporated into my framework. Losing my hardrive, I lost all the new build of my framework and decided to put the refactoring on hold for now. It has given me some great ideas on how to overcome some of my shortcomings though. and saved me the probably 3 months of recoding to get it were I wanted it. hope you enjoy, and all have a good week.
  12. Pitter patter goes the heart. Something I forget so often, and I've noticed it amongst my peers. Not taking care of my self, no I'm not talking about that you perv. I find my self so caught up in the minds of others, that I don't think about how I feel. It's been almost two, weeks and that's exactly why. Too worried that I'm upsetting others, not realizing I'm not moving forward. So lets all put those demons away, put on a fat smile and walk towards the sun. Not asking for a world of narcissist, but if not for our own lives, what's the point. I'll leave it with my next ink... painful back arm to boot... going to be a great release. "The demons that distract us" Code on dev world!
  13. freeworld


    I was listening to this song earlier and it just had this great verse in it. Cause you You're so calm I don't know where you are from You You're so young I don't care what you've done wrong Too me it screams the essence of childhood, being an adult and whatching children grow up. To not take the world so seriously that you never do anything. Everyone makes mistakes and it's not the end of the world. I constantly find my self reminding my own kids to not worry so much. Seeing how easily people get fustrated these days, it's not what I remmeber as a kid. "Tokyo Police Club - Shoulders and Arms" is the song for anyone interested. Well I started doing a little more remodeling then I thought I was going to. The following snippet is the current and probably old renderList. These lists are the back bone of my renderer and do all the heavy lifting for me. The list stores a struct called drawcall, which is the basic information about what is trying to be drawn and how; position, size, texture, shader, rotation/origin, and diffuse coloring. Which actually isnt the original layout either. The old drawcall, stored the actual vertecies along with the texture, shader and so forth. A year or two ago, I switched to the concept that all I needed was rectangles/quads. Why store all the extra data when I could just translate them later? Since then I've had countless times where a trangle or line would've been so much more helpfull, then trying to aligned a quad textured with the shape just right. If you poked around my last post, you probably remember the DrawQuad function, there did used to be DrawTriangle, DrawLine.... hence why I didn't call it something more associative like DrawSprite. Once all drawcalls have been made for this frame, everything move onto the renderer which mainipulates the render lists and presents them to the screen. Starting at the preFill. Any sorting of the list happens here. I sort all my calls so that transparent textures are at the back, orderer back to front, and opaque textures orderer front to back. Using the z depth of the textures, This allows alot of flexibility in game design. THeres no need to design you code around the fact that certain images have to be drawn at certain times to appear right. Aslong as they're positions are set right, they'' appear correctly. After sorting any render target swapping happens here. This is one aspect that is being remodeled. Currently the renderList only supports one render target per renderlist. This meant I had to hardwire a seperate pipeline for doing lighting, else suffer the fact that Id have to have a seperate renderList withe the exact same data for each buffer required by the lighting system, and relock the vertexbuffer for each list and everything else that has to be done for each list, added up pretty fast. The new list is going to store chains of effects. each link in the chain is simply a renderTarget and shader to be used. This can even be the backbuffer just rendering with different shaders each time. Also each link can have a set of secondary textures that should be included into the stream. Such as passing the gBuffer along with what is being rendered to do lighting. It will be a bit experimental, as honostely some of the functionality I've never used before but always wanted to. Once things are sorted, the rendertarget is set. Fill, lcoks the vertex buffer for the current texture and shader combo. Using the drawcall iterator, fill walks through the drawcall vector, any call that matchs the current state gets translated and placed into the vertexbuffer. If a new state is found, fill stops immediately. This is all to take advantage of the iterator and try to not process any drawcall more than once... ie the pipeline should walk through the list only once. All the translation though is being moved to the point when the drawcall is made, except that or view -> screen translation which happens in the shader using an orthogonal projection. The pipeline uses it's own camera to tranlate the call from world to view space. Cull, then rotate if nessecary. Culling is really generic, I use an oversized view (bigger than the screen), and just do a quick bounds check with the center of the quad and the screen. Aslong as you're not trying to draw a 512x512 or bigger texture it shouldn't have any popping as it leaves the screen. PostFill is pretty much the opposite of prefill. it resets the rendertarget to the back buffer if it was changed, then resets the drawcall iterator so new drawcalls will start by overwriting the old ones before pushing new ones on the stack. namespace ZEGraphics { class RenderList { public: LPDIRECT3DSURFACE9 backBufferCopy; // used to save the backbuffer while a secondary buffer is being used. LPDIRECT3DSURFACE9 tempRenderTarget; IDirect3DVertexBuffer9* vertexBuffer; // dynamic vertexBuffer used by this renderList only. std::vector renderTargets; // list of secondary targets that will get rendered to in order withe the assigned shaders. std::vector drawcalls; std::vector::iterator drawcallIterator; // the iterator is used by the fill process only, to save the readers position inbetween state changes. public: RenderList(); RenderList(ZEGraphics::Device* device); // Basic constrctor, sets iterator and reserves space for 5K drawcalls. ~RenderList(); // releases all data including vertexBuffer, drawcall vector... etc. void Reset(); // resets the drawcallIterator, and other temp settings. /********************************************************************************************** * PreFill - sets up the list for converting to vertexbuffer. Sorts by state change, * resets the iterator and prepares the render target to be used. **********************************************************************************************/ void PreFill(ZEGraphics::Device* device); /********************************************************************************************** * Fill - Enters the vertex data for the drawcalls of the same state. **********************************************************************************************/ void Fill(ZEGraphics::Camera* camera, IDirect3DTexture9*& _texture, DWORD& _shader, UINT& _primitiveCount, bool& _isTransparent, bool& _isEmpty); /********************************************************************************************** * PostFill - Resets the renderTarget and clears the list for re entering new draw calls. **********************************************************************************************/ void PostFill(ZEGraphics::Device* device); /********************************************************************************************** * AddDrawcall - pushs a single drawcall onto the stack. **********************************************************************************************/ void AddDrawcall(ZEGraphics::Drawcall _drawcall); bool Full(); // Return true if the drawcalls have exceeded the vertexBuffer capacity. 100K calls (200K triangles). private: /********************************************************************************************** * helper functions to split the big functions up and make them easier to read and edit, blah blah blah. **********************************************************************************************/ bool NextDrawcall(); // move iterator to next available drawcall. return false if no drawcalls available. void GenerateQuad(ZE::VEC3 pos, ZE::VEC2 size, ZE::VEC3& vert1, ZE::VEC3& vert2, ZE::VEC3& vert3, ZE::VEC3& vert4); void SetVertex(DWORD index, ZEGraphics::Vertex*& vertexData, ZE::VEC3 pos, ZE::VEC3 normals, ZE::VEC2 uv, ZEGraphics::COLOR diffuse); }; }; #endif The new renderList will be moving one from the all in one bucket for every drawcall. I'm also going back to the old way of string vertecies in the drawcall to facilitae the difference between triangles, quads and lines. The later being the only one that is actually a special case. Circles I use a precision variable to determine how many triangles I use to build them. Drawcall buckets, that's what I'll be calling it now. The idea is to store drawcalls in seperate buckets for each state combo. So shader and texture will be stored in the bucket instead of individual drawcalls. No need to check if a drawcall is valid anymore, if it's in the bucket then use it with this state. Shaders migh even be removed to only the renderlist and the render chains. So if a shader is going to be used by a rednerList it's going to apply it to all of them. Off the top of my head I can't think of any time I used a seperate shader within the same renderList. So buckets will probably be sorted just by texture. Render chains will be another big change, already mentioned, a chain is a render target and shader to be applied. it will also have a way of assigning secondary textures to be applied to the stream. Say you build you color buffer, normals and other gBuffer goodies. Then need to render your scene to the screen using all that light data, but you can only use one texture at a time. Makes it kinda impposible right? Well the skeleton is in place and some of the dta types are finished, I still got alot of coding before it's what I want. I am trying to keep the old pipeline untouched though, so all my old projects still work just fine. They just cant use any new features. But now I'm all typed out... good luck and happy coding dev world... YORDLES!
  14. Gotta love how easily kids pass along the sickness. I'm a walking disease today, no work, don't want to hang out in fear I'm may be too far from a bathroom ;) So here I am, clean or code... let's code. While were at it lets toot my horn aswell. Yes there is more than one in this head. Wasn't expecting to start this till tomorrow, but with my situation, I started today anyways. Torn my old render interface a new one and put together the skeleton for the new interface. Be proud of me, I kept the old interface and everything in the engine is still completely intact. There's actually two interface to choose from at the moment. The only thing lacking from the new one, is font and particleSystem support. The old system had a hackish way of using fonts and the particle system was very reliant on the old interface to work properly. Funny I'm looking at the two headers... old header 145 lines ~15 of it comments... the new header 95 lines ~ half of it comments. That's also including that I incorporated the window, input, and frame timer into the new interface aswell. new interface #ifndef _ZECloud_H #define _ZECloud_H #include #include "ZEMath.h" #include "ZESystemWindow.h" #include "ZESystemTimer.h" #include "ZEInputInterface.h" #include #include #include "ZEGraphicsDevice.h" #include "ZEGraphicsTextureCache.h" #include "ZEGraphicsEffectCache.h" #include "ZEGraphicsCamera.h" #include "ZEGraphicsRenderList.h" #include "ZEGraphicsInterfaceParameters.h" /*********************************************************************************** ZoloEngine - Cloud 2/2012 - Corey Marquette ***********************************************************************************/ namespace zecloud { class Cloud { public: /*********************************************************************************** Default Constructor - This constructor should not be used and will popup a warning message if it is. ***********************************************************************************/ Cloud(); /*********************************************************************************** Contructor(...) - This constructor must be used to initialize the engine. It initializes everything based on the data from a config file. ***********************************************************************************/ Cloud(HINSTANCE instance, std::string configFilepath); /*********************************************************************************** Destructor - all cleanup is done here. releasees everything from textures to renderLists. ***********************************************************************************/ ~Cloud(); /*********************************************************************************** Update - calls update on all sub components, and returns false if the engine has shutdown from any errors. If it has shutdown, the engine should not be used. ***********************************************************************************/ bool Update(); /*********************************************************************************** Render - processess all renderLists and present to the screen, use this function after all drawcalls have been made for the frame. ***********************************************************************************/ bool Render(); /*********************************************************************************** These accessors are meant to be used to create resources for the engine to use instead of doubling implementations in the interface. ***********************************************************************************/ ZEGraphics::TextureCache& TextureCache(); ZEGraphics::EffectCache& EffectCache(); /*********************************************************************************** CreateRenderList - adds a new renderList to the queue and gives a pointer back to be used for rendering. ownership of the RL's still remains with the engine interface. RenderList are never released until the engine is. ***********************************************************************************/ bool CreateRenderList(ZEGraphics::Sprite* renderTarget, bool clearTarget, ZEGraphics::RenderList*& renderList); private: ZESystem::Window window; ZEInput::Interface input; ZESystem::Timer frameTimer; // Renderer specific data ZEGraphics::Device device; ZEGraphics::Camera camera; ZEGraphics::TextureCache textureCache; ZEGraphics::EffectCache effectCache; std::vector renderLists; LPDIRECT3DVERTEXDECLARATION9 vertexDecl; }; }; #endif simple, just the way I like it. Starting a new project is as easy as adding a couple directies and creating a winmain file like so. #include #include "ZECloud.h" int WINAPI WinMain(HINSTANCE _instance, HINSTANCE _prevInstance, LPSTR _cmdLine, int _cmdShow) { /********************************************************* Engine initialization *********************************************************/ srand(timeGetTime()); zecloud::Cloud cloud(_instance, "data/config.xml"); /********************************************************* GAME SPECIFIC ASSETS *********************************************************/ /********************************************************* GAME LOOP *********************************************************/ while (cloud.Update()) { cloud.Render(); } return 0; } super simple... me really like. I have the tendency to be creating new projects constantly just to test out new ideas all the time. So having a fast setup proccess is very crucial to me. The old interface took on a master type role... every sub component had a double set of functions in the interface that would call the actual functions in the sub components. Don't know if that would be considered "PIMPL" or not, eitherway it was cumbersome. Anytime I wanted to add new functionaliy, I basically had to do it twice. Then ownership started to get blurry, which brings up the truth behind font rendering and the particle system. because they are seperate from the render interface, and they should be. They required the interface to render anything. This meant any changes to how the DrawQuad function worked, would effect how those system worked aswell. Especially when I added diffuse coloring to allow quickly changing the fonts colors. I had to dig deep into the rendeerlist, then change things in the interface, then had to change thins in how textures were loaded... it was just a mess. This time I've centralize, the act of drawcalls to renderList only. Similar to how XNA uses spriteBatch. The interface is no longer required to draw sprites to the screen. It is instead the point were resources are created, and manages the work flow of the system. It's still a major joint in the system, but should facilitate changes better. The one hurdle I'm still contemplating, is the difference between translated and untranslated coordinates. My camera is run in software, so its simple enough to just skip it when process translated coordinates. ie for things like the UI or other screen aligned sprites. I'm not sure if I want to store a tranlated flag in the drawcall struct or make it global and keep it in the renderList class. The former would allow alot of flexibility, but require an if branch for every drawcall (upwards of ~150K per frame). Keeping it in the renderList would mean only one if branch per renderList, but also means more work for the user (me). Creating seperate renderList for translated and untranslated rendering. I'm leaning towards the later, since I kinda already do this... but not always. and could easily lead to renderlist with only 10-20 calls stored, but requirring that many state changes. Defeating the purpose of batching. This will also problably mean more clutter in the draw function. I've been trying to minimize the require arguments over time, so I really didn't want to add more. Should I just create seperate function for translated and untranslated? Probably not. RenderList.DrawQuad(position, size, sprite, shader, rotation, diffuse, translatedFlag) not too bad I guess. Another big change for me, is moving from only translated coordinates, to using world coordinates then letting the camera translate these. I've been comtemplating letting the engine do all the culling instead of doing it in game logic. Should this be done early at the point when drawQuad is used or later when the renderer starts processing the renderLists? I'm thinking early, but this can have problems. Take for example, we make some drawcalls that get rejected for being outside the camera, but before processing the renderLists, we move the camera and the old calls would be in view now. This would cause were popping, were objects aren't visable for a split second, then suddenly are. But would also keep the RenderLists at resonable sizes. They have always been a bottle neck in the pipeline, so anthing to make them a little quicker is beneficial... it's just the drawbacks are icky. for the weirdos out there, heres the old interface for comparison and a look into my madness. #ifndef _ZEGRAPHICS_INTERFACE_H #define _ZEGRAPHICS_INTERFACE_H #include #include #include #include "ZEGraphicsInterfaceParameters.h" #include "ZEGraphicsTextureCache.h" #include "ZEGraphicsEffectCache.h" #include "ZEGraphicsDevice.h" #include "ZEGraphicsCamera.h" #include "ZEGraphicsRenderList.h" #include "ZEGraphicsSprite.h" #include "ZEGraphicsColor.h" #include "ZEVector3.h" #include "ZEVector2.h" namespace ZEGraphics { /** DEBUG information struct. */ struct DI_Interface { DI_Interface() : drawPrimitiveCalls(0), trianglesDrawn(0), smallestBatch(0), largestBatch(0) { }; void Clear() { drawPrimitiveCalls = 0; trianglesDrawn = 0; smallestBatch = 0; largestBatch = 0; }; DWORD drawPrimitiveCalls; DWORD trianglesDrawn; DWORD smallestBatch; DWORD largestBatch; }; /** Graphics API main Interface. */ class Interface { public: ZEGraphics::Device device; ZEGraphics::Camera* camera; ZEGraphics::TextureCache* textureCache; ZEGraphics::EffectCache* effectCache; std::vector renderLists; IDirect3DVertexBuffer9* vertexBuffer; LPDIRECT3DVERTEXDECLARATION9 vertexDecl; ZEGraphics::DI_Interface dInfo; /** Data used by the deferred lighting pipeline. */ ZEGraphics::Sprite gbNormals; ZEGraphics::Sprite gbPositions; ZEGraphics::Sprite gbColors; DWORD gbShader; DWORD dirLightShader; public: ZEGraphics::InterfaceParameters parameters; Interface() { }; ~Interface() { this->Release(); }; int Create(HWND _windowHandle, ZEGraphics::InterfaceParameters& _paramters); /** Display will process all the renderlists. Internally it will run these lists through the desired pipeline, specified by the renderList. */ void Display(); /** Specific pipeline for rendering the drawcalls. */ void DefaultPipeline(DWORD rl, IDirect3DTexture9* _texture, DWORD _shader, UINT _primitiveCount, bool _isTransparent); /** Release... releases all the allocated resources. */ void Release(); /** Drawing functions for drawing textured primitives. */ void DrawQuad(DWORD _renderList, ZE::VECTOR3 _pos, ZE::VECTOR2 _size, ZEGraphics::Sprite* _sprite, DWORD _shader, ZE::VECTOR3 _rot, ZEGraphics::COLOR _diffuse); void DrawQuad(DWORD _renderList, ZE::VECTOR3 _pos, ZE::VECTOR2 _size, ZEGraphics::Sprite* _sprite, DWORD _shader, float _alpha); /** Texture loaders. */ ZEGraphics::Texture* CreateTexture(std::string _filename, D3DFORMAT _format, bool _transparent); ZEGraphics::Texture* CreateRenderTarget(int _width, int _height, D3DFORMAT _format, bool _transparent); /** Effect Loaders */ bool CreateEffect(std::string _file, DWORD& _index) { if (effectCache == NULL) return false; return effectCache->CreateEffect(device.direct3DDevice, _file, _index); }; /** Deferred Lighting interface. */ bool SetupDeferredLighting(); void BuildGBuffer(LPDIRECT3DTEXTURE9 _texture, UINT& _primitiveCount); void ProcessLights(); /** The renderer stores pointers to a light source, so that it can be moved easly outside the renderer. The renderer won't cull the lights so it's up to the user to remove lights that are no longer visible. */ void AddLight(); void RemoveLight(); void ClearLights(); /** Misc resource loaders. */ DWORD CreateRenderList(ZEGraphics::Sprite* _renderTarget, bool _clearTarget); /** Resource access. */ ZEGraphics::EffectCache* EffectCachePTR() { return effectCache; }; /** Debug info. */ ZEGraphics::DI_Interface& DebugInfo() { return dInfo; }; void ClearDebugInfo() { dInfo.Clear(); }; /** anchors return the screen position at the specified position. */ ZE::VECTOR3 anchorTopLeft(); ZE::VECTOR3 anchorTopCenter(); ZE::VECTOR3 anchorTopRight(); ZE::VECTOR3 anchorCenterLeft(); ZE::VECTOR3 anchorCenter(); ZE::VECTOR3 anchorCenterRight(); ZE::VECTOR3 anchorBottomLeft(); ZE::VECTOR3 anchorBottomCenter(); ZE::VECTOR3 anchorBottomRight(); }; }; #endif Tomorrow I bother you again about the renderLists, the backbone to my renderer... its a yordle, run!
  • Advertisement

Important Information

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

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!