Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411363 Posts in 69351 Topics- by 58404 Members - Latest Member: Green Matrix

April 12, 2024, 10:27:25 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
  Show Posts
Pages: 1 ... 21 22 [23] 24 25 ... 28
441  Developer / Technical / Re: Passing functions as template parameters on: May 29, 2010, 01:44:13 PM
Did Average's suggestion about variadic templates work?

Testing on gcc 4.4, the following works:

Code:
#include <iostream>

using std::cout;
using std::endl;

template <typename FuncType, typename... Args>
inline void Call(FuncType funk, Args... args)
{
    funk(args...);
}

void Zero()
{
    cout << "zero\n";
}

void One(int x)
{
    cout << "one: " << x << endl;
}

void Two(int x, int y)
{
    cout << "two: " << x << ' ' << y << endl;
}

int main()
{
    Call(Zero);
    Call(One, 5);
    Call(Two, 3, 10);
}

That's pretty sweet ; )
442  Developer / Technical / Re: Passing functions as template parameters on: May 29, 2010, 12:42:13 PM
Did Average's suggestion about variadic templates work?

I'd love to try variadic templates, unfortunetly VC++ doesn't support them yet.  I decided to go with this solution:

Code:
template <typename T, T& F> void WrapperFunction () { /* stuff */ }
#define Wrap(X) WrapperFunction<decltype(X),X>()

Which works quite well.  Most often I want to do this sort of thing its for optimization, but here I needed the function as a template parameter because I needed it embedded in the type.

I was working on a recursive decent parser, but I wanted everything short of the actual parsing to be done with metaprogramming (mostly as an excuse to learn some new tricks/techniques).  Generally it works along the lines of:

Code:
auto digit = 0 | 1 | 2 | 3;   // ect....
auto num = +digit;
auto if = i >> f;
auto then = t >> h >> e >> n;
auto else = e >> l >> s >> e;
auto end = e >> n >> d;
auto ifelse = if >> expr >> then >> exp >> !(else >> exp) >> end;   // ! = 1 or none, expr defined elsewhere
auto p = SemanticAction(SomeFunc,ifelse);
// ect...

// parse
std::string str("stuff here to be parsed");
std::string::iterator i = str.begin();
Parse(p,i,str.end());

I needed to be able to add a semantic action, a function that would execute when a parser was recognized.  The thing here was, it needed to be a template parameter because all the parsing info is embedded in the type.

All in all it was a fun exercise, much was learned, and its nice to have something usable at the end of it all ; )
443  Developer / Technical / Re: Passing functions as template parameters on: May 28, 2010, 01:54:13 PM
Actually I mentioned I was using C++0x (at least parts of it) in the OP, but no worries if you missed it.  And ya if I wanted run-time linkage I could use std::function, or boost::function, or one of many other options.

After doing more reading, I'm pretty sure what I'm looking for can't be done.  But I'll try to explain it in a bit more detail.

Many times I want to wrap a function in another function.  Either to adjust parameters, modify data, ensure something was called, ect...  Doing this at run-time is easy, but it also has overhead.  For example, imagine you have something like this:

Code:
float FuncA (int i) { /* do stuff and return something */ }
float FuncB (int i) { return FuncA(i+1); }

Its a trivial example granted, but wrapping a function to add/adjust functionality happens all the time.  Most compilers (GCC, intel, MS) will inline the call to FuncA in FuncB (with the appropriate compiler optimizations turned on, even without the inline keyword).

To do the equivalent with say boost::function (and likewise std::function):

Code:
float FuncB (const boost::function<float (int)>& f, int i) { return f(i+1); }

works pretty much the same, but won't necessarily be inlined (haven't tested it out, but would be highly unlikely that it could inline it... I probably should test that sometime).  Same problem with a function pointer:

Code:
float FuncB (float (*f) (int), int i) { return f(i+1); }

Now you can do:

Code:
template <float (&f) (int)> float FuncB (int i) { return f(i+1); }

and this gives you 50% of what I'm looking for.  You get a complile-time wrapper with no more overhead than a hand coded wrapper would give you.  Which is awesome, but it only works if you know the type of the function you want to wrap.

Say I want the type of a function (to adjust/work with parameters, ect...).  I can do:

Code:
template <typename T> float FuncB (const T& f, int i) { return f(i+1); }

and now I have T, which is the type of a function, and I can work with it, but its run time, not compile time.

And there-in lies the rub.  I can statically link a function OR I can get its type, but I can't do both.  What I need is something like:

Code:
template <typename T, const T& f> float FuncB (int i) { return f(i+1); }

Except having to supply the function definition is not only tedious, but error prone for complex types.  The closest I've been able to get is by wrapping a function in a class (as has been mentioned above) and using decltype like:

Code:
template <typename T> void FuncB (int i) {
   const auto f = T::FuncA;
   typedef decltype(f) TF;   // get function type
   return f(i+1);
   }

This gets me 90% of the way there, problem is I can't get the function type, till the wrapper function is declared, so I can't define things like return values.

There's also:

Code:
template <typename T, const T& f> float FuncB (int i) { return f(i+1); }
// elsewhere...
FuncB<decltype(FuncA),FuncA>(5);

Which seems about the best option at this point.  A little tedious to write, but it covers the rest of my wish-list.

I just thought I'd post the question as sometimes I make silly mistakes and/or forget obvious things, and I thought maybe in this case there was something I missed or forgot ; )
444  Developer / Technical / Re: Passing functions as template parameters on: May 27, 2010, 08:41:33 PM
So the question is, is there any possible way to pass a function as a template parameter without having to specify the function type by hand?  Something like:
Code:
Call<SomeFunc>();   // not valid C++ code

If I understand what you're doing, I believe the answer is no.

One solution is to use classes with overloaded () operators, and use those as "function wrappers."

Code:
class Funk_1
{
public:
    void operator () ()
    {
        // Do stuff.
    }
};

class Funk_2
{
public:
    void operator () ()
    {
        // Do other stuff.
    }
};

template <typename Type>
void Call()
{
    Type()();
}

int main()
{
    Call<Funk_1>();
    Call<Funk_2>();
}


Ya I tried that too.  You can't use operator() as it can't be static, but you can just use a normal static function (like Function() or whatever).  Problem with that is you can't get the type of the function you are intending to call.
445  Developer / Technical / Re: Passing functions as template parameters on: May 27, 2010, 05:06:13 PM
Well there was a number of situations where I wanted to do it, but had to work around it.  In this particular case I couldn't.  Its the last piece of a simple recursive decent parser.
446  Developer / Technical / Re: What do you make your games with most frequently? on: May 27, 2010, 03:18:55 PM
I use C++ exclusively, with a dabbling of assembly here or there.

I've been working on my own language in the mean-time, but that won't be done for a long time...
447  Developer / Technical / Passing functions as template parameters on: May 27, 2010, 03:17:25 PM
With the new C++0x additions filtering down I've been playing around alot more with template metaprogramming.  The combination of auto, decltype, and lambda functions add alot of interesting possibilities.  There's still one thing I can't seem to be able to do, and that is pass an arbitrary function as a template parameter.

of course I can pass a function at run time like:
Code:
template <typename T> void Call (const T& f) { f(); }
// elsewhere...
Call(SomeFunc);

if I know the type of function I want, I can do something like:
Code:
template <void (&f) (void)> void Call () { f(); }
// elsewhere...
Call<SomeFunc>();

But the only way I can pass an arbitrary function via a template parameter would be something like:
Code:
template <typename T, const T& f> void Call () { f(); }
// elsewhere...
Call<void (void),SomeFunc>();

meaning you would have to supply the function definition prior to the actual function.  For functions that are more than just 1 or 2 parameters (or more complex parameters like embedded iterators) this becomes more than just a chore, and is error prone.

So the question is, is there any possible way to pass a function as a template parameter without having to specify the function type by hand?  Something like:
Code:
Call<SomeFunc>();   // not valid C++ code


448  Player / Games / Re: Talk About Pirates Day - Indie Game Piracy on: May 04, 2010, 02:57:09 PM
For those who are truly interested in more pirate reading material.  Sadly its not some long-lost treasure map, but an interesting Dutch study that wasn't (for once) funded by a company with a self-interest in the results (ie. the data wasn't cherry picked).

http://www.ivir.nl/publications/vaneijk/Communications&Strategies_2010.pdf

A few notable points (which I know I and a few others have mentioned but seemed to be dismissed a bit to quickly IMO):

Quote
Buying and file sharing turn out to go hand in hand. Music sharers are as
equally likely to buy music as other people: 68% of file sharers also
purchase music. File sharers buy as much music as non-file sharers.
However, file sharers spend more money on merchandise and go to
concerts significantly more frequently.

As for films, file sharers turn out to buy significantly more DVDs than nonfile
sharers. On average, file sharers and non-file sharers go to the cinema
equally often.

Game sharers also buy games, and significantly more frequently too:
67% of file sharers are buyers as well. And if they buy, they buy significantly
more games than non-file sharers.

A chart on page 10 shows (the rest of the chart is interesting, but not game related):

Quote
File sharers buy more often (61% vs 57%) and File sharers buy more (4.2 vs 2.7 games)

and last of all:

Quote
All in all, these figures show that there is no sharp divide between file
sharers and others in their buying behaviour. On the contrary, when it comes
to attending concerts, and expenses on DVDs and games, file sharers are
the industry's largest customers
. Note that no causal relationship is implied
here. Aficionados of music, games or films will typically buy more, get into
related products more but also download more.

Granted its only 1 study, and I'd like to see many more like it.  But I think it does a good job of showing the correlation between copying and purchasing.  Pirating a game won't necessarily translate to a sale of that game every time, but the money always follows the community.  People spend their money on that which they love, and if they're playing games (or music, or movies) they'll be spending money on games.  I'm not saying the piracy should be legal, but I will say that the draconian DRM that PC game makers have saddled their products with has done far more harm to themselves and the industry as a whole than file sharing has.

Whether or not you agree with me, the paper is well written, concise, and refreshingly forthcoming on their data and any errors, omissions, and/or inadequacies (something that I find most studies/papers seem to 'gloss over'); and I'd suggest at least a cursory glace, as it covers many of the same questions that have been discussed in this thread.

In particular the section on "Causal mechanisms how file sharing may relate to sales" I found quite interesting.
449  Player / General / Re: Starcraft 2 Beta on: April 29, 2010, 11:45:32 AM
artosis has mentioned that, about remembering names -- he's ranked as the best player on the US server (rank 1 in platinum since day 1) and plays it at least 8 hours a day (crazy). he said that due to the random nature of match-ups most players on the US servers (as opposed to the asian servers) use BO1 strategies: strategies that will win them 'best of 1' games, but wouldn't work in 'best of 3' or 'best of 5', because they'd expect it the next time. in professional starcraft, players are more famous: everyone can watch all your past games and know what you tend to do, so cheese is less useful, it's a BO1 strategy, not a BO5 strategy. so maybe we'll see fewer of those in tournaments as opposed to random BO1 matchups.

I hope so, but for the rest of the non pro-gamer masses, it doesn't sound too promising.
450  Developer / Technical / Re: The happy programmer room on: April 29, 2010, 11:27:01 AM
LLVM is quite easy to use.  They have support for both JIT and static compilation.  And if your looking for an easy to use parser, check out the Spirit parser (comes with boost).  Its not as fast as say Lex and Yacc (or flex and bison if you prefer), but its a lot easier to use.
451  Player / General / Re: Starcraft 2 Beta on: April 29, 2010, 11:17:21 AM
Guardian shield, psi storm, fungal growth.

Guardian shield is a must, but it won't stop maruaders.  Psi storm... Never saw a single toss build a HT vs terran, ever.  Maybe its different in the other brackets, but in platinum, vs terran, toss techs to robotics ASAP.  Only immortals can save you vs maruaders.  The only thing I found that consistently stops MMM is immortals with FF abuse.  And by abuse I mean all the dirty FF stuff that shouldn't be in the game (like completely sealing off chokes).

Stalkers, although I've no idea how to deal with cloak... Cannons?

I don't know really.  Fast banshee's won me so many games its silly.  Toss a few vikings in the mix to handle observers and its pretty much GG.  You can't go pheonix, as vikings are cheaper, stronger, and build faster.  Stalkers will get mowed down by banshees, and as soon as an observer gets in range, just scan, ur vikings with their 9 range will 1 shot it, and then its back to destroying stalkers.

Or they could just make a single warp prism, or have made a proxy pylon somewhere earlier. Here's an idea, build a pylon next to your ramp. Then you can just warp in units on the low ground within the powered area with warp gate tech... Which you should be getting anyway.

So the enemy can pick em off 1 at a time as they warp in?  I've had it done to me, and done it to others.  You park your army at their choke with a few sentries.  Every time they attempt to engage you FF and only let 1 or 2 make it down the ramp.  Your smaller army makes mincemeat of the the 2-3 stragglers, FF wears off, rinse-and-repeat.  They will never get past that ramp short of going air (or perhaps mass colossi).  Even works vs zerg (but not quite as well).  3 sentries + choke = gg.

You ever notice how most top toss v toss games, both armies kinda just dance around in the open ground?  I guess those that haven't played and only watched youtube videos you wouldn't (they play hundreds of games to find the 1 or 2 that weren't just 2-3 min cheese fests).  But in toss vs toss, as soon as you try to fight past a choke, 1 bad FF and its game over.  If your army gets split its gg, and with the range on FF it will.

I've won so many games with FF cheese its not even funny.  One notable one was vs a zerg who had 2 expansions, had a TON of roaches, hydras, even banelings.  Probably 150 supply vs my 70 or so.  But I had about 10 sentries.  I engaged at his expansion and FF'd between his hatchery and the walls.  A handful of immortals and the sentries wiped out the entire force and his expansion.  I'm all for micro, but the level of cheese you can do with that 1 ability is just silly.

If you see the terran putting down gas early (or spot the barracks with the tech lab), it's a reaper rush. All you need is to scout it and chrono-boost a stalker out.

Chrono boost a stalker?  You'll be chrono boosting a zealot if your lucky.  I can have that 1st reaper in your base before your cyber is even warped in.  What's even funnier (aka cheesier) is that single scv that I used to proxy barracks, will also be building a bunker in your base as your single zealot gets kited by the marauder.  Ever tried to drop a bunker with a reaper in it?  You can beat the crappy players who attempt this with quick/smart probe micro, but the good ones, you can't stop them.

You can just sacrifice one overlord (usually the one you initially send over) to scout out your opponent's base, which is what the pro players do currently. Also, queens are pretty decent early-game AA, though they probably won't stand against an all-in bancheese rush.

1 queen will go down to 1 banshee or void ray with still having hp left to do damage.  A single void ray can tear through a lair (not hatchery) in less time than it takes to build a queen, or even hatch hydras even if you have the hydra building already made.  And overlords are useless for scouting prior to tier 2, they move far too slow, they'll be dead long before they see anything of use.

But here's the kicker, if you spent the extra 150 minerals on an extra queen, you won't the minerals to either early tech, or get a 2nd hatchery.  Without either, its gg vs an opponent who didn't rush air.

The only consistent method of countering a fast void/banshee rush, was to remember the names of the people who would attempt it, and build to counter when I played them again.  There was no other realistically viable strat.
452  Player / General / Re: Starcraft 2 Beta on: April 29, 2010, 12:11:56 AM
Well I hit top 10 platinum (best was 3rd) through numerous ladder resets...

Terran, just MMM and u'll win 90% of the games, marauders are pretty much unstoppable.  You don't even need to really micro them, just make sure they don't get stuck on a ramp and ur set.  If they get immortals, get a ghost or 2, and if they get collossi get 2 or 3 vikings and laugh at the fact blizzard thinks 9 range on the viking is 'balanced'.

Against zerg you can change it up and go hellions + thor if ur really feeling like u wanna completely own the zerg.  Its pretty much unstoppable.  Hellions own lings, thors tear roachs, hydras (lol 1 shot hydras), infestors, ultras, and mutas apart so bad its a complete joke.  Just bring a few scvs and u'll never lose a thor.  So pretty much for zerg its broodlords or bust, which never works because they cost too much gas.

Also banshee rush is pretty hard to beat as toss.

As toss you can pretty much mass sentries and immortals.  A few zealots are ok for fodder (and pray they don't go air, toss AA is a joke).

Some funny things (read complete utter cheese) to do is...  

Sentry abuse.  3 Sentries can wall off a ramp permenantly, its funny walling off urs, its hillarious walling off someone else's.  Its funny forcing a protoss to tech to carriers with nothing more than 3 tier 1 units.

Fast/proxy reaper is pretty much unstoppable unless they build specifically to counter it.

Fast banshee and/or void ray is always effective, even up in platinum vs zerg.  Since zerg have no viable AA till tier 2, and no way to scout till tier 2.

You can use hallucinate to 'build' units you don't have.  So you can chrono boost a hallucinated void ray out or colossi and make zerg have a fit.

Point is, theres an answer to everything and scouting is key.  The reason Terran seem strong right now is that MMM is easy to pull off but you cant get by with it at the higher level.  I dont think anyone is really overpowered right now.

Actually there isn't 'an answer to everything'.  At least not at the platinum level. 

Take zerg for example, if you waste gold on aa (2-3 spores, an extra queen) in preparation for banshees or void rush, you can't afford the extra hatchery which you NEED to fend off a MM or zealot/sentry rush.  But neither can you scout.  Vs terran 1 depot and a barracks later and you have no idea what to build till you hit tier 2, which by that time its too late.  Like wise once that 2nd zealot pops out, you have no scouting till tier 2 (you can micro around the 1st), but that doesn't tell you anything, even if they're massing zealots or teching to voids or fast colossi, the builds all pretty much the same.

And that's probably my biggest complaint of SC2 (beyond even the massive cheese fest that is PvP), is that neither toss nor zerg have viable early scouting.  Probe/drone scouting is necessary, but after about 2 min (vs anyone remotely competent) that worker is dead and you have no idea what to build to counter, and if you tech to scout, by the time you can its too late.  So what do people do?  Pick a strat, take a guess, and pray for the best.  There's nothing else you can do.

Which is why there's no strategy in SC2.  You pick a build and roll the dice and hope ur opponent didn't build a counter build.  But neither he nor you had any way of knowing.  And its not that there aren't options.  I could name a few, there's been a ton on the forums, blizz just doesn't care.  Beta isn't about balancing, as far as they're concerned the game is done and this is just free marketing.
453  Developer / Technical / Re: D3D9 problem (for you DirectX gurus out there) on: April 27, 2010, 09:05:47 AM
Ok it seems after turning up the debug warning level on DirectX (ty will Smiley I was setting my viewport wrong.  It was such a silly error...
454  Developer / Technical / Re: D3D9 problem (for you DirectX gurus out there) on: April 27, 2010, 08:29:39 AM
Thx for the ideas.  I tried with the reference rasterizer and it works.  So I'm guessing its just something to do with the nvidia drivers (tried it on 3 different cards, but they were all nvidia)??  Any idea where this sort of weird errata might be documented?
455  Developer / Technical / D3D9 problem (for you DirectX gurus out there) on: April 26, 2010, 10:04:39 PM
I've been playing around with D3D9 and came across a peculiar problem. I was rendering a very simple test scene that was working fine, till I enabled z-buffering. With z buffering enabled the app refused to draw anything (but the device->Clear(...) seems to go through).

I loaded up PIX to see what was going on. Funny thing is, in PIX the render output is showing what I would expect to see. All device states are as they should be, all render calls/resources/ect... all work/are there, depth buffer is showing accurate depth values. In fact according to PIX it should work perfectly.

I googled everything I could think of in relation to z buffers and/or PIX and found nothing useful.

So my questions are, 1st is it normal for PIX output to differ from actual on-screen output? And any ideas what could cause enabling of z buffering to cause a model not to draw (a depth stencil surface was created, EnableAutoDepthStencil in D3DPRESENT_PARAMETERS is true, D3DRS_ZENABLE set to D3DZB_TRUE, D3DRS_ZFUNC set to D3DCMP_ALWAYS, double checked all device capabilities, viewport is set)?
456  Developer / Technical / Re: The happy programmer room on: April 18, 2010, 11:19:41 AM
Since a matrix is just an array of numbers, it is A-okay to call that a matrix, even if you don't happen to be using standard matrix multiplication.

True, but to say 'multiply matrix A by matrix B' and assume people understand its component-wise as opposed to standard matrix multiplication, is misleading.  I'd go so far as to argue, if you use none of the properties or operations of matrices, why call it a matrix?  A matrix implies more than a 2d array of numbers, even if fundamentally thats all it is.
457  Developer / Technical / Re: The happy programmer room on: April 18, 2010, 09:44:40 AM
Thanks for sharing your knowledge! My lecturer was in a rush and explained it pretty losely. So I'm glad you took the time and explained it Grin . Can't believe how much image data can be compressed this way...

I need to initiate a JPG cult or create atleast a shrine.

My pleasure. 

I find too much time is spent looking at the math end of it, and rarely do they explain where or why those chose to do something.  Stuff like, why is it called a quantinization 'matrix' when its not really a matrix (we're just doing component-wise division/multiplication).  Or why did they chose the DCT, is 8x8 blocks a necessity, ect...

There are actually much more interesting transforms than the DCT.  Jpeg 2000 uses a wavelet transform, which is how it gets better compression.  There are some really awesome wavelet transforms with all sorts of properties for almost any application.  Heavily asymetrical bi-orthogonal wavelets are my favorite ; )  They're designed for very high compression ratios and either very fast compression or decompression (you can pick) with the tradeoff being the corresponding decompression or compression takes much longer.  So for situations where you compress once, and use many times, taking a bit longer to compress is ok if decompression is much faster (perhaps even in real-time in a pixel shader ; ).
458  Developer / Technical / Re: The happy programmer room on: April 18, 2010, 08:37:36 AM
I'm happy because I realized how amazingly simple the concept behind JPG images is. They're awesome.

Not counting how the frequency sine thing works you need to create compressable data series.
I've always wanted to write a JPG loader, but I just assumed it would be more complex than I want to deal with.  My naive guess is that it involves converting to frequency space and throwing out high-frequency noise above a variable threshold.  But it's probably a little more complicated than that. Shrug
This one. What I understand was that they basicly calculate the average brightness (if I remember correctly) of every 8x8 block and do then create a matrix consisting of the difference between the avarage each pixel's offset. Next step is to apply the transformation for each pixel to create as much redundant values as possible. Why redundancy? You can compress them very well using RLE. That's the secret behind JPG compression. Also, there are two "layers" in a JPG file: one for colors (size-reduced) and the compressed one for brightness/grey values.

It's a great concept and like lots of other techniques, too, it comes from the very basic land of communication electronics. Too bad they don't often work together like when they created the JPG alghorithms... And too bad, too, that computer scientist like to forget the good old technologies from the past. In the worst case they insist on having no old technology in there PCs while NOT knowing that almost every piece of software relies on so simple elementary code they wish to abandon.

Hm, maybe I confused technology with software and scientist with someone else. However, feel free the replace it with whatever words you like.

Perhaps I can clear it up a bit.  When compressing a jpeg there are 3 main steps (a 4th is optional).

The 1st (optional) is the color space conversion.  You convert from your standard RGB to something else more suitable (not necessary, but its often done).  Something like YCbCr, but there are others.  But regardless of your choice of color space, when ur done any conversions, u compress each channel independently, so conceptually you can kinda ignore this step.

The 2nd step is the transform step.  There are TONS of different transforms you can do (wavelets, DCT, fourier transforms, ect...) but the one JPEG uses is the discrete cosine transform (called the DCT).  Its actually pretty simple to visualize what it does...

Image a sound wave.  If you were to graph it, you'd have the time along the x-axis, and amplitude along the y-axis (I'm sure we've all see a sound file in like goldwave or whatever you use to edit sound files in).  You're in basically time-amplitude domain (domain is probably not the proper term, but it'll do for now).  It'll tell you how loud something is, or when a particular sound occurs, but it won't tell you things like, 'is there alot of base?' or 'how can I clear up the treble?'.  So we can convert it, we'll use the DCT, and what we get out is the EXACT SAME wave in a different domain.  This is the frequency amplitude domain.  So frequency runs along the x-axis, amplitude the y-axis.  This now tells you things like, how much base there is, what frequencies (and their amount) are found in that clip.  What it can't tell you is WHEN things occur.  And thats what the DCT (and its inverse) does, it converts from time amplitude, to frequency amplitude, and back.  Its the same sound, just by converting it your looking at the same data differently.  Its like converting from cartesian coordinates to spherical.  Nothing's changed, we're just looking at the same data from a different 'angle'.

Ok so we take the input channel, and break it into 8x8 blocks (it could be any size, 8x8 was chosen to keep memory and computation requirements down, JPG is quite old, but u can have a 10x10 DCT, 100x100, whatever you want).  We apply the DCT, which changes us from 'time' amplitude (in this case its not time in the normal sense, but same idea) to frequency amplitude.  We're also using a 2D transform not a 1D, but its pretty much the same thing.  Now we're left with the exact same image, but in a different domain.  Data in the top left corner of the 8x8 block represents the low spatial frequencies (important features) and data in the bottom right high spacial frequencies (often noise).

3rd step is quantinization, this is where the 'lossy' is introduced.  You want to throw away some data (that's how jpeg gets such high compression vs lossless compression like TGA or gif, it literally discards data), but you want the data to be data that won't be missed.  You want the major features of the image to stay, and throw away stuff thats hard to notice.  What you'll notice is that our image data (after the DCT) tells us just that.  The numbers that are high in our transformed image will correspond to an important frequency, which will correspond do an important feature of the image (say the edge of a hand or a face, or a nose) while low numbers in the transformed image will correspond to features that aren't as important (maybe noise, or a subtle gradient in the background).  So what do we do?  We throw away the low numbers.  We do that by dividing each pixel in our transformed 8x8 block by a number.  These numbers are grouped into a matix, and are called a qunatinization matrix, but really have nothing to do with linear algebra or any of the usual uses for matrices.  Its probably better to think of them as a 2d array.  The numbers were chosen experimentally, and shown to produce good results (there's no inherit mathematical reason behind their choice other than they work well), and both the compressor and decompressor use the same agreed upon numbers/matrix.

The 4th step is encoding.  After you have divided each pixel in the transform image by its corresponding number from the quantinization matrix, your left with ALOT of zero's, and a few large numbers here or there.  And when you have alot of zero's in your data, its very easy to compress.  Encoding is done in a zig-zag pattern starting from the top left and zig-zagging to the bottom right.  The pattern was chosen because most often data will be clustered into the top left corner, after qunantinization its quite rare for data to be found in the bottom right.  After you apply the zig-zag pattern your left with essentially a 'list' of 64 values, most of which are zero.  So each non-zero value is encoded along with the number of preceeding zero's.  This is encoded using entropy encoding (I'm not explaining that here, that's its own topic, but basically the smaller the number the fewer bits needed to store it).  At some point the rest of the block is all zero's and so a special 'end of block' marker is used.

And voila, its compressed.  To uncompress you just go backwards.  You un-encode the data into 64-value blocks.  Un-zig-zag that into 8x8 blocks.  You multiple each pixel by its quantinization value.  You perform the inverse DCT on the 8x8 blocks.  You perform any inverse color space conversions that are required, and your back to your original data (minus the bit that was thrown out).

Hope that makes it a bit more clear Wink

*edit: forgot to add, between steps 1 & 2, the data is centered around 0.  So if your input is between 0 and 255, you would subtract 128, so 0 maps to -128, 255 maps to 127.
459  Developer / Technical / Re: The happy programmer room on: April 12, 2010, 08:39:45 PM
... and I'm also compiling Boost again at this very moment.

Boost, such an awesome library, but it can be such a PITA to build...
460  Player / Games / Re: Talk About Pirates Day - Indie Game Piracy on: April 07, 2010, 01:10:55 AM
I didn't read through all of this but I read through a fair bit.  One thing I'd like to mention that is often overlooked is:

- a pirated game is not necessarily a sale, and sometimes not necessarily a non-sale
- the people that pirate the most, are also the ones who spend the most on media in general

Until you can effectively quantify how much you are actually loosing due to piracy, IMHO its hard to justify getting all worked up over it.

I think a better metric is to consider the target market, audience, and determine the amount they spend on a certain type of media, and then gauge from there.  Quite often, the money follows the community, regardless of how that community is built.

I'm not trying to justify piracy, but I rarely see these important points brought up.  You can go on all day about how many billions (trillions depending on who's data you want to believe) are theoretically lost due to piracy, but if kids these days aren't spending any less on media than previously, is that much really being lost?  For example, if piracy is bringing more people into gaming from other forms of entertainment, it'll eventually lead to more game sales down the road.

Granted there needs to be a balance, but media is not the same as physical products, and can't be accurately measured with the same 'stick'.  Piracy and stealing are different things.

To be honest, if we had 100% unbreakable DRM (ie. eleminated piracy), I'd be surprised if there was a significant increase in sales industry wide.  In fact I imagine it would actually be less.  People only have so much to spend on entertainment, and for the most part would just play less games.
Pages: 1 ... 21 22 [23] 24 25 ... 28
Theme orange-lt created by panic