Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 15 Jun 2006
Offline Last Active Yesterday, 07:57 AM

#4991849 What to know in order to write a mesh parser?

Posted by on 19 October 2012 - 12:08 PM

People don't do this. Work out what you need from your mesh data. Design a file format to hold it. It can be in denormalised formats, laid out in a nice easy to handle way for your renderer.

You then do one of two things -- you write an exporter from something like Blender which saves to your files. Or you write a translator which goes from a well known file format into your file format. Which can be quick, hacky and written in something like Perl or Python.

#4986700 Efficient GUI clipping on the GPU

Posted by on 04 October 2012 - 03:23 AM

You may be solving the wrong problem.

Generally, UI code solves this problem by just drawing the windows in order, front to back (omitting only completely obscured windows). Why? Because that's actually faster than faffing about...

Yes, it generates some overdraw, but that's still usually easier than trying to clip -- UI pixels are often fairly cheap (being things like flat or shade fills of rectangles).

If you're actually running this on a 3D card, then the obvious answer is just to use the Z buffer to sort this problem out for you. Which would be the second approach I'd try, but only if the overdrawing method proved slow.

Go for the simplest approach until you really find it won't work.

#4985489 Class to store different uniforms (variant like)

Posted by on 30 September 2012 - 03:18 PM

OK, so the usual trick about storing different types in a map is to go at it like this;

You create an envelope class which implements your interface and in turn delegates the work to an interface pointer. You create a suitable templated class into that interface pointer.

Like this;

class Inner
  virtual void doStuff(<params>)=0;
  virtual Inner *cloneAt(void *address)=0;

template<class DATA>
class InnerTempl
  DATA data;
  virtual void doStuff(<params>) { // in here you can use 'data' to work on it, and it has the right type. }

  InnerTempl(const DATA &d):data(d) {}
  virtual Inner *cloneAt(void *address)
     return new(address) InnerTempl(data);

class Outer
  Inner *pInner;
  void doStuff(<params>) { pInner->doStuff(<params>); }

  template <class X> assign(const X &x) { pInner=new InnerTempl<X>(x); }

So far, so good.

You can store Outers in a map. There's some issues about memory management and you'll need to flesh those out into real classes.

Avoiding the memory management can be done reasonably neatly if you're careful.
Start with this;

class Outer
  Inner *pInner;
  unsigned char space[32]; // you'll need to pick a size here that's big enough for your purposes.
  void doStuff(<params>) { pInner->doStuff(<params>); }
  template <class X> assign(const X &x) { pInner=new(space) InnerTempl<X>(x); } 
  template <class X> operator=(const X &x) { pInner=new(space) InnerTempl<X>(x); }

Now you don't need a separate inner object, so there's one less memory alloc and no loose pointers. It's a bit hacky and relies on picking a size that's 'big enough' but games development is ~1% genius and 99% hacking that genius to work practically.

STL mandates objects in maps must be copyable. And this then, is why we implemented cloneAt. Note that it needs the virtual dispatching to end up in a function which knows what type DATA really is.

Add to Outer an assignment operator.

Outer &operator=(const Outer &other) { pInner = other.pInner->cloneAt(space); }

Likewise, implement a copy constructor.

STL mandates objects in maps must have a null constructor. Make it have a null pInner to start with & add all the exception handling to cope with that and you're done.

Now you can store arbitrary types in the map by just assigning to them and iterate through them calling doStuff() on each one.

typedef map<string,Outer> MYMAP;
MYMAP mymap;

Job done.

Then in this case, doStuff() probably takes an integer slot and then calls an overloaded glUniform() function passing "data" in.

Mine looks like this;

void glUniform(int slot,int value)		  { glUniform1i (slot,value);}
void glUniform(int slot,unsigned int value) { glUniform1i (slot,value);}
void glUniform(int slot,float value)	    { glUniform1f (slot,value);}
void glUniform(int slot,const vec2 &value)  {glUniform2fv(slot,1,value.ptr());}
void glUniform(int slot,const vec3 &value)  { glUniform3fv(slot,1,value.ptr());}
void glUniform(int slot,const vec4 &value)  { glUniform4fv(slot,1,value.ptr());}
void glUniform(int slot,const ivec2 &value) { glUniform2iv(slot,1,value.ptr());}
void glUniform(int slot,const ivec3 &value) { glUniform3iv(slot,1,value.ptr());}
void glUniform(int slot,const ivec4 &value) { glUniform4iv(slot,1,value.ptr());}
void glUniform(int slot,const matrix &value){ glUniformMatrix4fv(slot,1,GL_FALSE,value.ptr());}

// I have my CPU vector classes named to match the GLSL ones because I got bored of accidentally using the wrong ones all the time.
// generally ptr() gets a base pointer to real data in the classes.

#4984878 Class to store different uniforms (variant like)

Posted by on 28 September 2012 - 04:02 PM

The trick with stuff like this is to first off, write a bunch of overloaded version of glUniformXYZ() which takes C++ types and a slot and sets the uniform.

Then you can write templated setter classes which you can store in the map.

Then you can write a simple interface to the uniforms map which takes a string and an arbitrary type and puts a setter into the map.

Then you just iterate over the map calling the setter through an interface.

If you do this neatly, BTW, you can arrange to store either a value or a reference into the map. So you can express "Set this uniform to integer 7, but set that one to the value of this integer over here" in the same uniforms group.

If you make the setters a PIMPL interface with a templated inner class constructed inplace into a convenient array of spare memory and set up copy operators properly, then the setters are plain value objects and hence can be stored directly in the map. All this avoids nasty casts and will properly type-check things at compile time. (Because if you try and store an X and there ultimately isn't a suitable glUniformXYZ then the code won't build). And you can hotwire it to use your own vector/matrix classes and write them into the GLSL versions.

I've probably got some code somewhere if that doesn't make sense.

#4971820 Realistic Encouragement vs Trolling Tear-down

Posted by on 21 August 2012 - 07:37 AM

There's the rule of 10,000 hours as well. Some of us really are actually really good developers; but we've spent years and years working to get to this place. People who've read a book and written a ten-liner just aren't going to build stuff. Not without going through that 10,000 hour learning curve. Now, there's no reason why your dream game isn't at the end of that process for you, but it's a painful way to do things and you'll probably end up hating it long before 10k hours.

A lot of people show up with concepts for the game they want to play. But the news is that you ain't ever playing it. Even if you write it, you'll spend the rest of your time *running* it. I went to movie writing class once. It's a pain of a course to get onto -- turns out those of us on the year long writing course get priority. Week 1 is always scheduled in this huge lecture room. 50 seater room for the 20 people subscribed because people bring their friends, people show up on spec... this guy walks in carrying a HUGE folder of notes and talks for two solid hours about three-act structures, plot-point systems and so on. For those of us who are there to learn to write movies it's BRILLIANT. For the people who just want to have written a killer movie without going through the intervening hard work places... well, lets just say that weeks 2 onwards of the course are apparently habitually scheduled in much smaller rooms. I think four of us completed the course in the end (by submitting a pitch, a plot outline and at least 30 pages of a properly formed movie script).

{It was even harder for me, because I lost my temper with the text editors to hand and had to write a tool for typesetting movie scripts in C++ before doing much of the writing...}

Too many people want to have written a cool game, whereas generally successful game devs are interested in the actual writing of games process and the cool, if it happens at all, happens by accident.

#4932030 Send more data to the GPU vs more operations

Posted by on 16 April 2012 - 11:52 PM

In general the memory transactions will happen in the background. They're also very fast, don't pollute the CPU cache, don't cause cacheline fighting and can happen while your 3D card is busy doing something else; as the CPU can be doing.

The CPU is pretty fast at doing tight operations loops, but there will still be tons of branches, cache misses, hyperbus communications and other assorted friction. In addition it can't parallelise the work. Mapping more of the GPU memory, doing simple writes into it and then leaving both devices to get on with more work while other (specialised and faster) parts of the computer hardware deal with the shifting around of memory is definitely the way to go on desktop systems.

If some of the data is constant or not updated often, consider using two buffers -- a frequent and an infrequently changing and use two accesses in the shaders to combine the data. This will reduce the amount of memory which needs to be moved between the devices across the memory busses[1]. This is usually less of a problem in the shaders because the shader cores will each have memory controllers (often one for each buffer), and you're still processing the vertices in linear order so you'll still get good cache read-ahead on them.

[1] An example would be a skinned model. The texture posn/colour at each vertex will typically not change, it's just the vertex posn that gets updated, so by using two buffers, the memory transmission size can easily be reduced by 2/3.

#4921063 2D OpenGL ES wrapper with emulation on Windows?

Posted by on 11 March 2012 - 01:37 AM

ARM ship a GLES emulation layer which will run on NVidia or AMD cards on Windows and Linux which is free for non-commercial use; see http://www.malideveloper.com/developer-resources/tools/opengl-es-20-emulator.php

The last time I talked to the devs, they were working on a Mac version so it's on the way. It's pretty easy to use -- link against the library, run your application. Shader code should be re-written on the fly, API entry points bounce through and have the right restrictions to match the ES spec.

{Disclaimer; I worked for ARM in the same group which produces this.}

#4916748 RTS-AI built on potentialfields

Posted by on 26 February 2012 - 11:24 AM

I did some work like this a while back; my environments were large and open with relatively few obstructions, so it made a reasonable amount of sense to do micro-routing like this. You're right in saying that static solutions are better for larger scale routing. It's *possible* to get the field systems to (say) find the bridge over the river, but it's not as good a solution as a better macro scale system. For example, we used potential fields to get units onto the road network, and they would then drive the road network (which is modelled as a graph) until they get close to their destination, at which point they get off the road again. Road driving uses an attractor which moved ahead of them to tow them down the road. It means that if they come across a partial blockage, they'll simply drive around it, and then regain their correct route. It actually produce very "realistic" looking movement.

We got quite good results with "formed" infantry moving through woods/obstructions etc, but back then it all had to run on the CPU and it was actually quite expensive to run. (These days it might run nicely as a GPU job). The other issue was that it meant it was difficult to predict arrival times at destinations/waypoints along the route, because the local field-movement system might add arbitrary distance to the actual movement at the macro level. Never did work out what to do about that really.

"Your unit may well halt at a distance where it can be fired upon, but not fire itself."

This problem can (sort of) be solved by using scalings on the potential attractors/repellers. Conveniently they can be hooked up to "fuzzy logic" outputs for things like "How much do I want to seek cover" vs "how much do I want to obey instructions" although one needs to be careful to order the scalings properly and that's the part which gets difficult if there are many scalings.

#4895104 Which Country Should I Move To?

Posted by on 18 December 2011 - 04:21 PM

"I don't see that I am giving off such a vibe."

Yeah. Sorry. You are. Your post is all ranty and foamy.

Just as an example; "It is exactly such misunderstandings by the politicos of some very fundamental aspects of how modern monetary systems actually work"

You're blessed with knowledge that the entire political leadership of the western world has either stupidly spurned or just never bothered to learn? And the absolute assertion that MMT is a definitive description of the world's monetary system? Posted by someone on a games development site? Yep. That comes across as ever so very slightly looney.

"their emotional commitment to irrational ideology."

Good job none of that is happening round here.

#4892559 Best computer science schools in Europe?

Posted by on 10 December 2011 - 11:12 AM

Actually Cambridge (and other English unis) tutition is UKP3.3k a year for all UK/EU resident students -- call it 10k for the course.


Cambridge is widely recognised as being world class. Warwick, Bristol and Southampton have good reputations with employers within the UK and Europe. Imperial, as previously mentioned, is world known.

List here; http://www.thecompleteuniversityguide.co.uk/league-tables/rankings?s=Computer%20Science

#4887734 Speedup OpenGL at some Opperations

Posted by on 25 November 2011 - 04:26 PM

"Use google a hole bunch of hours to get something that dosent work is anoing."

Since that is largely what software engineering consists of these days, I'd suggest finding a new line of work then.

#4887733 Compiling Lite Versions for Android

Posted by on 25 November 2011 - 04:25 PM

"Does some-one know a short-cut I can take?"




Personally, I tend to write bash/sed scripts for this sort of thing.

#4887732 Why is it that game designers should not have emotions for their ideas?

Posted by on 25 November 2011 - 04:21 PM

Writers refer to this as "Be willing to kill your children."

You must be ruthless. You must be objective. You may think it's a neat idea, but *YOUR* opinion is not important. Your readers are the important ones. If it's not the very neatest idea, then it's not a neat idea at all and it must go.

Without that ruthlessness -- that willingness to kill ANY of your ideas in the service of the greater story, you will be self-indulgent and great writing is never self-indulgent.

#4884524 AOP .... who uses it?

Posted by on 16 November 2011 - 04:52 AM

" logging is not an important problem to solve. It's quite irrelevant and trivial and the goals that loggers are after are not about how to log as many actions as possible with as few lines of code as possible."

Logging isn't unimportant. Logging is mindbendingly important, particularly in large service infrastructures such as the sort of place where Java gets used. Finding out where, in hundreds of supposedly co-operating components running on scores of machines in dozens of datacentres, something happened to something inside your process takes up the majority of large systems maintenance. Fixing any single problem is usually relatively trivial compared to the painful, painful weeks of trying to find out why 1 per 10,000 download activations never complete successfully because something somewhere on the network is placing a lock on something that we're not expecting.

Logging is problem that is rarely solved well and yet is VITAL to most infrastructures.

#4883517 Use a Pixel Shader or Make More Textures?

Posted by on 13 November 2011 - 02:30 PM

One thing to bear in mind when making these decisions is whether your GPU has sufficient bandwidth to access the textures. Spritesheets, in particular, tend to be large and randomly accessed and this can cause texture cache thrashing. Adding mip-map levels to entire sheets can make that worse.

In some circumstances, (particularly mobile) maths operations on simpler pixel data can be cheaper than extra texture lookups because GPU <-> memory bandwidth is often constrained by power requirements (driving the offchip memory controllers at higher frequencies would use too much power) while maths operations are relatively power cheaper (because they take place entirely on-chip) and hence more available.