Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Community Reputation

527 Good

About speciesUnknown

  • Rank
    Not technically human

Recent Profile Visitors

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

  1. speciesUnknown

    Windchasers still under way...

    I might have given you the lecture before, but anyway, the one thing I can think of is, what will you do to set your game apart from the rest of the crowd? There are plenty of futuristic racers out there - all fairly similar to wipeout: [img]http://upload.wikimedia.org/wikipedia/en/9/9c/PSX_Wipeout.png[/img]# What are you going to do that is "different" as opposed to better (n.b. everybody thinks their game is better) from games such as this? OR these, [url="http://store.steampowered.com/genre/Racing/"]http://store.steampowered.com/genre/Racing/[/url] Think hard about this.
  2. speciesUnknown

    The Importance of Commenting Your Code

    Commenting a return line with a comment that says you are returning a value is not productive. The code in this article is a classic example of pointless comments. Each line in the function is not one step . This is a better example of commenting each step, taken from some real code I wrote not long ago: [CODE] /** * @description find next available entity or return a new one * @return an inactive entity */ ObjectPool.prototype.getNewEntity = function() { // try to find an existing one that is not active for(var i = 0; i < this.entities.length; i++) { if (this.entities[i].bActive == false) return this.entities[i]; } // failing that, insert a new one and return it var newEnt = this.initFunc(this.initData); this.entities.push(newEnt); return newEnt; } [/CODE] WIth your system, this would look like this: [CODE] //////////////////////////////////////////// // find the next available entity //////////////////////////////////////////// ObjectPool.prototype.getNewEntity = function() { // step 1: iterate over all the entities using i as an index for(var i = 0; i < this.entities.length; i++) { // step 2: if the entity at position [i] has the property bActive set to false if (this.entities[i].bActive == false) // return the entity return this.entities[i]; } // step 3: call the init function to create a new entity and pass it the data given in the constructor of this object var newEnt = this.initFunc(this.initData); // step 4: insert it to the end of the list this.entities.push(newEnt); // step 5: return the new entity return newEnt; } [/CODE] Note that in the first case, im using autodoc comments - this is actually useful. If people have to navigate to the file containing the source code to read the documentation for a function call, they are losing valuable time. Commenting every line of a fairly straightforward method is also a waste of time. If somebody does not understand why there is a for loop involved in the process of searching for a thing in a flat list, they have no business reading or changing this code anyway. Furthermore, some methods contain branching (and looping) meaning that numbered steps are meaningless. It is possible that steps 3 and 4 are never executed, in this example; actually thats the common case since an object pool prefers not to allocate new elements. Note also that your version does not communicate the intent of each section of the function, it communicates basic facts about the language. This is also a waste of time.
  3. speciesUnknown

    True, False, FileNotFound

    this is all too common. When the enum starts out its just a replacement for the lack of a boolean data type in C, and its used as a return code; true for success and false for error, but then what always seems to happen is that more error codes are needed; file not found, and so on. THe only real mistake is calling the enum Boolean rather than ErrorCode. To avoid this, always call your true-for-ok/false-for-error enums something like ErrorType and use NO_ERROR or similar. Problem solved.
  4. speciesUnknown

    System Change: Viewing Your Warning Level

    When I first saw this I thought I was somehow being a bad person. I thought I had become a functioning member of society. Glad there is a simple explanation.
  5. speciesUnknown

    Everything burns eventually

    I've made some progress since my last blag post. Here is a recent screen shot: I've done a few thigns; 1) I've put vehicles back in. I took them out while I was refactoring my scene, but its good to be able to speed around and imagine what the finished product will be like. 2) I've added point lights to my render pipeline. These use the traditional deferred render method of drawing spheres for each light with depth testing disabled and back face culling enabled. 3) I've added a crude particle system; I plan to make this component based, with a list of emitters and a list of forces. The current one shown here is just a crude single vector for the force. 4) I've added a scene node which comprises both a light and a particle system, for making things like fire, explosions, and sparks which have both a light (to approximate the colour of the particle system) and the system itself. The image shown above is created using this system; it makes the light flicker from reddish orange to whitish orange, and it has to be seen to be appreciated. I should get fraps or something.
  6. speciesUnknown

    Lights from a render list

    Made some structural changes today to prepare my newly created lighting system for use with the scene. I've got my system gathering spotlights from a render list and drawing as many as possible in a single pass; it performs quite well with around 50 lights per pass. This render list is gathered by the scene (ill detail my scene system in a later post) but atm the lighting is only debug data. My light manager is capable of taking lights from a render list, batching them up into uniforms, and rendering as many as possible with a single pass. This will cut down on the number of fullscreen quads to be rendered. Fillrate is my primary bottleneck right now. I've seen methods which render the AABB of a light system as some kind of volume on screen, which conveniently means projecting it and reducing the number of fragments to render by orders of magnitude, this will likely be a good option. void LightManager::startList(RenderList3D& source){ current_position = source.light_begin(), last_position = source.light_end(); } LightManager::Step LightManager::stepList(int shader_program) { static SpotLight dummy_light; dummy_light.setOn(true); static std::vector pos(3 * available_spotlights); static std::vector dir(3 * available_spotlights); static std::vector colour(3 * available_spotlights); static std::vector radius(available_spotlights); static std::vector cosAngle(available_spotlights); for(int i = 0; i < available_spotlights; i++) { SpotLight * l; if(current_position != last_position) { // apply each light in turn l = ( current_position->light ); current_position++; } else { // fill the remainder of the list with dummy lights l = &dummy_light; } pos[3 * i + 0] = l->pos[0]; pos[3 * i + 1] = l->pos[1]; pos[3 * i + 2] = l->pos[2]; dir[3 * i + 0] = l->dir[0]; dir[3 * i + 1] = l->dir[1]; dir[3 * i + 2] = l->dir[2]; colour[3 * i + 0] = l->rgb[0]; colour[3 * i + 1] = l->rgb[1]; colour[3 * i + 2] = l->rgb[2]; cosAngle = cos(l->angle * 0.0174532925f); radius = l->on ? l->radius : 1e-1f; } GLint location = glGetUniformLocation(shader_program, "uLightPos"); if(location != -1) glUniform3fv(location, available_spotlights, &pos[0]); location = glGetUniformLocation(shader_program, "uLightDir"); if(location != -1) glUniform3fv(location, available_spotlights, &dir[0]); location = glGetUniformLocation(shader_program, "uLightColour"); if(location != -1) glUniform3fv(location, available_spotlights, &colour[0]); location = glGetUniformLocation(shader_program, "uLightRadius"); if(location != -1) glUniform1fv(location, available_spotlights, &radius[0]); location = glGetUniformLocation(shader_program, "uLightCosAngle"); if(location != -1) glUniform1fv(location, available_spotlights, &cosAngle[0]); if(current_position != last_position) { // we are still iterating our spotlights return SPOTLIGHTS; } else { // we have reached the end of the list return FINISHED; } } My next step is to work the way lights are gathered into the scene itself, I've created various code paths for lights in the scene but not integrated this with my 3d editor. that: add point lights to the system.
  7. speciesUnknown

    Multiple passes, deferred lighting

    I've now set up my multiple pass system, using g-buffers for lighting, this means I can render the first pass as a single quad, then use the g-buffers rendered at the same time to perform multiple, far cheaper lighting passes. Here is a screen shot of the result: I still dont have properly sorted translucent geometry, but at least its rendered as part of the whole process; i only wanted translucent geometry for things like shop windows and street lamp glass, so hopefully not too many bits of translucent geometry will be visible. I'll fiddle around with the depth g-buffer and the depth of each translucent fragment to see if I cant figure out some way to do additive blending on translucent geometry without depth testing, while still only rendering it when its in front of the previous pass. Most translucent geometry in reality will be clear (not coloured) glass with a dirt texture so the colouration wont be an issue.
  8. speciesUnknown

    g-buffers and ambient pass

    I wasnt going to go with full blown deferred rendering, so only my lighting pass will be defferred. That is, the first pass (ambient light, sun light / shadow and light / shadow from one or more lightening flashes) will be rendered the old fashioned way; but at the same time as doing this pass, I will generate g-buffers for the second pass to make use of. Here is a screen shot of what I have: The top left image is the first pass; no shadows as yet, only a directional light. You will notice that I have rendered translucent geometry on this pass. In this pass, different materials have a different shader attached, and geometry is sorted in order of shader to avoid too frequent binding of new shaders and uniforms, which can be a bottleneck. The second image is my albedo map; this is only the textures and material properties. You will notice that the translucent geometry doesnt write to this buffer, this allows me to use various tricks to get the translucent geometry into some g-buffers but not others. For example, I write to a specular buffer if need be, but miss out the albedo. I may need to seperate material properties and texture at some point but for now they are together. The bottom two are world space normals, and world space position; by doing things in world space i've been able to simplify the way lights are gathered, I simply need to render all lights which intersect the view frustum. Hopefully by the end of today I'll be able to render many lights using only the g-buffers, and use additive blending to apply them over the first pass.
  9. speciesUnknown

    GDNet V5 Concepts: User Ratings

    There is one effect which you havent mentioned, that the current rating system suffers from; Sometimes, people will "gang up" and "gang rate" a user. This generally happens in the IRC channel #gamedev, and sadly, its usually initiated by highly rated members. Human intervention is pointless, mods cannot stop users from gang rating. Now, I'm not going to mention any names, because its usually the same small number of culprits, not the vast majority; (also, I suspect my own rating will get raped if I name and shame them) but what usually happens is as follows: 1) user says something which is "wrong" 2) one or more of our higher rated members takes offense. Either because its technically inaccurate, or because its the "wrong opinion". Microsoft sympathisers or open source fanatics are usually on the front line. 3) The others in this group then all "gang rate" the user down, and encourage others to follow. This in part explains the "rating submarine" - and no new system which allows one to link to a user's comment or user profile and say "rate this guy down!!!" will function beyond the old one. The solution to this problem is clear; dont allow rating of individual users, instead, allow rating of their posts. Tagging posts instead of rating entire users is definatly the solution. This means that any "gang rating" requires that little bit more effort as this user now has to go around rating down all their posts.
  10. speciesUnknown

    Spot lights and stuff

    Today I expanded my shaders / architecture to support more than 1 light per render pass. Its my plan to implement a multipass, forward renderer with some use of seperate buffers. This is my plan for rendering things: 1) Render the geometry albedo with a single directional light w/ shadow map to represent illuminating objects in the sky. The ambient lighting will be handled in this pass, whereby I can approximate the ambient light in terms of what is coming from the sky (sun, moon / stars, etc). The shadow map here will be very high resolution, and only recalculated occasionally. 2) I render a normal buffer, which will aid in the lighting passes, since each fragment will already have the appropriate normal after this step. I think this should be a nice optimisation, but I might skip it at first. 3) in several passes, I render up to 6 spotlights at once, adding up the results each time. By fiddling with its input params this shader can also render a single point light but with 6 shadow maps all to itself. I do this until there are less than 6 spotlights (or one point light) left over. Then, I use similar shaders optimised for 4, 2 or 1 light until all lights have been processed. 4) I combine the results of 1 and 3 and then apply post process effects. Here is a screen shot of just the scene drawn with some spot lights, without shadow maps or ambient colours; this would be the result of one of the passes in step. Due do my decision to calculate ambient lighting in step 1, you will notive there is no ambient light here; the buffer only tells me how much each fragment is lit by various lights in the scene. Ambient light will depend on the intensity of the main light source (the sun or moon etc) and will be rendered on the first pass. Tomorrow: Get a single directional light, coming from an arbitrary point in the sky, to work. Figure out how to render a depth texture, which would be the first step to getting shadow maps working. If possible: combine the two, so I have a sun / moon shadow effect.
  11. speciesUnknown

    Starting again

    Its been a while since I last made a journal post (over a year I think) mainly because development slowed considerably; also, ive been working on physics rather than graphics, until now, so there wasnt much to show. Here, have some per pixel lighting: However, people keep wanting to see screen shots, so ive decided to work on the renderer for a while. I've set up a nice system for loading / linking shaders, and I've vastly simplified my resource loading system. The previous system relied on loading a single resource, asking it what its dependencies were, and then loading those. This was fun when I was an academic, but now I realise it was overengineered and innefficient. I have a new system, which took me approx. 1 day to write; whereas the previous one took two weeks. My engine is designed to load from two kinds of data; it can load from intermediate files, in which case it must calculate dependencies (I've hacked this up and its slow, but its not critical for loading intermediate files) and then each resource is stored in a table with a string key. Next, I assign each loaded resource an integer ID, and create a vector of references to each resource; this means I can perform an O(1) resource lookup, and I mean proper O(1), not an ammortised one; and its considerably faster than any kind of hash table. I then give each resource links, through these integer ID's, to all their dependencies. This is a slow process, but it does have several advantages; once its done, I can index resources without having to give each object a pointer or reference to its dependencies. I can bind dependencies instantly by directly accessing the pointer. When I serialise my resources into blocks of data, I send the integer ID's along with them; this creates a header file for each block of binary data. I can serialise the entire resource manager, or individual tables. From here on, its the same as my old resource loading system, except without the need for linking resources to each other. Rather than gathering a shopping list, I lazy load every resource, and demand that every resource table provide a suitible fallback resource if a resource that was requested is not currently available. When the game loads from packed blocks, it first loads the headers of each resource table, which is simply the integer ID, the string name (which is still useful) the block they are within, and the start / end point within that block. When a resource is needed, it will load its data and cache it in GPU memory. There is no need to link resources because they also know the integer ID of their dependencies. This should make things simpler, and faster when loading from blocks of data.
  12. speciesUnknown

    Change of plans

    Change in plans Well, after 3 weeks of working on work for uni, and making one of those rediculously long job applications, I've not done anything related to spawning characters. Instead, I spent the last week making a GUI lib. This was a big change in plans, but the mood struck me, and I need a GUI of some kind eventually. Currently implemented are buttons and surfaces to put buttons on. I'm in the middle of creating text box widgets, although for them to be of a production standard I'll need to redo my font rendering system, which currenly draws nicely kerned and antialiased text, but by brute force, with no caching of glyphs. Building this screen took only the following code to do: gui_manager = new GUI::Manager(0, 0, 500, 400); GUI::Button * exit = new GUI::Button("butnExit", "Exit", 100.f, 40.f); exit->setListener(this); cmd_history = new GUI::TextBox("txtdHistory","",20,8); cmd_line = new GUI::TextBox("txtCmd","",20,1); cmd_line->setListener(this); gui_manager->addWidget(0,0,cmd_history); gui_manager->addWidget(0,8*25,cmd_line); gui_manager->addWidget(500 - 110,400 - 50,exit); I'm quite happy with this for a weeks worth of work (less than 10 hours of actual work all told) and am actually surprised at how quick it was to do this. Having done it twice before may have helped. All the widgets are drawn using vector art, generated from within OpenGL. I can customise the colours, but apart from that its pretty fixed. However, there is no reason I can't make other appearences than a coloured border, thanks to my skin system. The round corners are a mesh, and the lines between them are a single quad. I've had a lengthy discussion about alternatives to this method and ive decided that im right and everybody else is wrong... at least for now. I'm hard coding the details of each skin, with some of the properties loaded from a file such as this: SKIN DEFAULT BACKGROUND Colour 0.1 0.1 0.1 0.7 NORMAL Colour 0.0 0.33 0.71 1.0 ACTIVE Colour 0.0 0.63 0.91 1.0 CLICK Colour 0.3 0.4 0.9 1.0 /DEFAULT BUTTON BACKGROUND Colour 0.3 0.3 0.3 1.0 MOUSEOVER Colour 1.0 0.0 0.0 1.0 CLICK Colour 1.0 1.0 1.0 1.0 /BUTTON /SKIN Once again ive decided against XML and am rolling my own. I've also refactored my game once again, removing all traces of the old event system. I'm now using a combination of two event systems; for the GUI communicating back to its owners, I'm using an EventListener system, where the object recieving the events must inherit the interface ButtonListener, TextBoxListener, etc. To recieve the input from that button, I need to override ButtonListener::listenButtonClick, like so: void ZFrenzy::listenButtonClick(GUI::Button * sender, int x, int y, int button) { exit(0); } And there it is, a button that exits the program. Basically this is a cut down version of the observer pattern, since only one observer can be attached to each widget. There is no reason I couldnt make this more than one, but this is just a prototype GUI system, build from previous experience building GUI systems. In the next 3 days I hope to have the font rendering sorted out enough that I can have a decent text input box, and will then create a console; this console will allow me to make interfaces for various parts of the game which are currently hard coded, and form the basics of an in-game editor.
  13. speciesUnknown

    Factory pattern and such

    WASD is what most gamers expect, and the point of having an external file that can be edited is that users of non qwerty keyboards can make their own key map. It's also entirely possible that I could have a bunch of standard setups selectable from the options menu. I could even offer multiple downloads, for different languages, along with a default setup to match that language. I would use the same system for in-game messages rather than hard coding them, so that I can easily put the game into another language just by changing the contents of this file. The format I'm using is my own, but uses the XML principle of /TOKEN to end a section. KEYBOARD MAPPING /KEYBOARD MOUSE MAPPING /MOUSE (Since yesterday I added mouse mappings to the same file) It has no disadvantages that I can see, compared to XML. For a more complex tree, I would use TinyXML.
  14. speciesUnknown

    Factory pattern and such

    as a default layout i think yes, it is most sensible. its what pretty much every game uses and is a de-facto standard. it leaves the left hand and the right spaced in an ergonomic fashion, compared to the arrow keys which put them at an awkward angle. i would be very please if you were to write me a key map file for other keyboards, like your azwerty KB. ;)
  15. speciesUnknown

    Factory pattern and such

    So, did a few things of interest today: wrote a system for loading keymappings from file. The number of config files my game will use is rapidly growing. the file looks like this: KEYBOARD w FORWARD s BACK a LEFT d RIGHT r RELOAD e ACTION1 f ACTION2 1 WEAPON_1 2 WEAPON_2 3 WEAPON_3 4 ITEM_1 5 ITEM_2 6 ITEM_3 7 ITEM_4 8 ITEM_5 SHIFT SPRINT C CREEP /KEYBOARD This lets me have more than one keymapping, and lets users customise their keymappings with little effort from myself. I could provide an in-game interface later if I wish. refactored the system so the world is spawning objects and the scene is only aware of what to draw. Thusly, each entity has different and unrelated data structures within each system, and systems communicate between each other via event queues. This loose coupling makes refactoring easy Created a factory system for spawning a "Thing" from a prototype, just by its name. This loads from a text file like this: PROTOTYPES PROTOTYPE NAME "TV" WEIGHT 35.0 MODEL "TV" SCRIPT "TV" /PROTOTYPE PROTOTYPE NAME "broom" WEIGHT 2.0 MODEL "broom" SCRIPT "broom" /PROTOTYPE PROTOTYPE NAME "safety_stick" WEIGHT 4.0 MODEL "safety_stick" SCRIPT "safety_stick" /PROTOTYPE PROTOTYPE NAME "bench" WEIGHT 150.0 MODEL "bench" SCRIPT "chair3" /PROTOTYPE PROTOTYPE NAME "street lamp" WEIGHT 300.0 MODEL "street lamp" SCRIPT "street lamp" /PROTOTYPE PROTOTYPE NAME "cine_camera" WEIGHT 45.0 MODEL "cine_camera" SCRIPT "cine camera" /PROTOTYPE PROTOTYPE NAME "street lamp 2" INHERIT "street lamp" MODEL "street lamp 2" /PROTOTYPE /PROTOTYPES The advantage here is that some objects will be able to inherit the properties of another object, and then simply override the ones that are different. Note that "street lamp 2" inherits street lamp but has a different model. The rule here is that an object can inherit the properties of an object that appeared above it in the file. Very simple but creates lots of opportunities. I can spawn an object from this system at any time by just having the world send an "this object spawned" event, and the other systems will instantiate the appropriate object within their own ranks to match it. My interpretation of the factory pattern is quite literal; I have an actual object being the factory, and this object creates the prototypes based on the data in a file, such as the one above. Each prototype knows how to instantiate an object with those properties. The factory knows how to spawn only one class of object, so for each type of entity I have a different factory object. Next weeks objective: Have characters spawning from a factory, and moving around the world, represented by a piece of debug geometry.
  • 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!