Sunday, June 19, 2011

Tastes Like Chicken.

My fried brains, that is.
/Plug for Aston Kutcher's new show... Tazed'
I had what felt like an epic two-day wrestling (or wrass-lin' depending upon your location in the good ol' US) match with my camera object class.  My Goal?  To be able to re-size my camera, have different dimensions, and be able to have multiple camera's running at once.

Wrass-lin'!
The Good news: After two days I have locked down what were relatively simple bugs and have cleaned them out for good!
The Bad news: I'm not done yet.
I still need to find a way to account for rotation.

So let me give you (y'all?) some background on the situation.  XNA, being the lovely system that it is, allows me to draw textures using some lovely built in functions, namely the SpriteBatch method Draw().

I hope you are not THIS confused by the following paragraphs...
SpriteBatch is XNA doing two things: Making life easier by eliminating the need for me to work directly with buffers, and making life harder by eliminating the flexibility that comes from working directly with buffers.  Confused?  Well then hold on to your britches and kiss your buttocks goodbye, and for your sake I hope you wiped last time you used the restroom.

All jokes aside, buffers are simply how the computer draws.  All the images that are to be drawn in the next frame are sent to what is called the back buffer, and upon the next cycle of the program's main loop the back buffer and front buffer (the display area) are "flipped," the front buffer is cleared, the elements on the back buffer are sent to the front and a new back buffer is set up.  Essentially a computer draws every frame twice, at least from my understanding.

The disclaimer to this blog is that I could very easily be completely wrong, but from the limited experience I've had working with buffers this is my understanding of their functionality.  If you know more about buffers (As in, you actually know about buffers and not I-looked-these-up-on-wiki-peida-and-I-want-to-look-smrat*) please, contact me and teach me!
*smrat: Close to smart, but obviously not.  If you do something like this, then I will send my robot minions after you.

Anyway, Getting back to my original point...
 SpriteBatch's draw function takes the following parameters in order to draw your images (or this is the function I use)
Draw( Texture, Position, SourceRectangle, Color Tint, Rotation Factor (Radians), Origin (Center), Scale Factor, SpriteEffects (this is irrelevant), and finally Depth)

Now relax, calm down, and take a breather, this is all pseudo-code, you haven't caught Nerd-Cooties, your coolness factor remains the same.  Just the same, maybe if you are worried about such things, don't tell your cool friends that you read my blog.

I swear I'm (almost) done with the jokes.  Back to the point, Texture is simply the 2D image that we want to draw, and Position is where to draw this image, after that it gets pretty tricky.  SourceRectangle is the hard part, but also the great part of the Draw function.  It asks for a rectangle area in the 2D image to draw. 

This is really cool because it allows me to take one big image full what seems to be a jumble of drawings or art assets, and divide them into pieces or frames that can then be cycled through to create animation.

This really sucks  because it makes me specify a rectangle, which as awesome of a shape as it is, has its drawbacks.
Namely the fact that AFTER I specify my rectangle, I specify my Rotation (which is measured in Radians, and not those pesky degrees).

This doesn't appear to be a problem (I thought nothing of it at first) until you realize it rotates the rectangle as well.  Now what happens if you take a square or a rectangle and turn it 45 degrees?  It looks more like, well a diamond now.

Which, when I go back to my Camera class I'm working on, if I want my camera only to display within a certain area on my screen, instead of on the entire screen, I need all of my images to have vertical/horizontal cut-off lines.  If I rotate my images... well then no dice, I end up with a diamond-shaped (or worse) image that juts out beyond my camera boundaries.

...But that's not all! (Shout-out to Professor Ash at DePaul.  And none of you will ever get this reference)  If you look back to the pseudo-code, after rotation then the origin is given, and the Scaling factor is given.  Which means AFTER rotation then we also scale the image.  This normally isn't a problem, but in terms of the Camera when half of an image is cut off, I only want to display half of the normal frame of that image, so for the SourceRectangle I only grab half, but the position and the origin (center) are that of the full image, which means when the scaling happens, the entire image scales towards the co-ordinate (0,0) which in programming terms is towards the top-left of the screen.

Long story short, when I scale half of my original frame, it also changes the "actual" position of the image.

exactly
What does this all mean?

Well it means I had to account for the change in position that takes place while scaling ahead of time.  I had to do this by giving the Draw function the modified position ahead of the actual scaling.  WHAAAAAT?!

That's some crazy stuff, yo.

But as of yet I haven't figured out how to anticipate the rotation of my image ahead of time too.  That is the final 10% of my camera object that remains to be finished off.  And then probably handed to David who is gonna fly out to CA just to slap me for the mess I hand him.

And if you are wondering: I have little to no idea how I'd ever get the rotation to work, considering no matter how many ways you try it, I have to assign the rectangle ahead of time, and THEN rotate it, and a rectangle rotated 45 degrees will always be a diamond.
I'm this much screwed.

And my cat wanted to be in a blog, apparently.
World: here is Toffee, hear him meow?
Ninja cat? Who doesn't like camera-flash.
- Kev

No comments:

Post a Comment