Friday, August 26, 2011

New Milestones Reached!

Progress is a wonderful thing and has revealed itself in two ways this week. I've crossed under the 170 pound mark! Next, I've conquered level 14 on the Elliptical! That was thoroughly exhausting, so thoroughly I was too tired to stretch for a good 10 minutes after finishing. Speaking of stretching, yesterday I achieved putting my palms on the ground in the standard toe-touch motion. Massive achievement for my flexibility. A bit of workout restructuring has gone into my workouts of late, too.

I mentioned a few posts ago about changing how I just work out. I've put together a few successful and a few unsuccessful workouts since then. The ineffective workout consisted of rounds of isolation exercises: fly, skull crushers, and shoulder raises...possibly one more.

Absurdly effective works mostly include some variation of pushup, pullup, squat, and situp. One of them was five rounds for time of each exercise, with a time limit of 25 minutes for the whole thing. I finished in 24 minutes after considerable prodding from my trainer. Another effective one was for reps pushups and pullups, again 5 rounds. I got 177 and could barely move after it. Generally speaking, before I start these rounds, I'll generally do some sort of power lift, squat clean or squat snatch. The jury is still out on yesterday's work: squat snatch, then rounds of bench press, pullups, and situps. I think it could have been more effective, but I'll have to play with it a bit more to get it right.

Running technique is still winning. My instructions were to essentially pick my legs up a bit like I was marching highstep and place my foot down, ball first then let the heel touch lightly afterward. Make sure not to keep calf flexed the whole time otherwise you'll end up with the same terribly sore calves that I keep earning myself when I screw up the technique. With all that in mind, I ran again only to have a leg cramp only 12 minutes in. Still, it's a work in progress and hopefully I'll get it figured soon.

Wednesday, August 17, 2011

Video Capture with MultiSampling in DirectX for Mortals (C#)

For the last 10 days, I've been tasked with fixing the company graphics engine's video capture component. I have enough DirectX experience to know that it exists, what it is, and what it looks like. But I have enough programming experience to be able to decipher just about any code in a language I can read. Thanks to Google, my former co-worker, Brendon, and my Italian heritage for getting me through this. Now, let me show you what might help you along this path.

There are a few things that should be mentioned before we get started: Fraps is an awesome tool that does this exact thing most likely better than I did it; We could not use Fraps in this case because the requirements for the video were that it have a constant, predefined frame rate; and the Direct X documentation is horrible in some cases. Also, I'm going to assume you can get a frame rendered. If you can't do that much, start somewhere else, then come back once you have that down.

So, Direct X has your RenderTarget and you want to save that info. And all you really want is for the InvalidCallExceptions to quit popping up and ruining your day with the message, "There is an error in your application." The technique I used was a combination of threading and copying the RenderTarget to an OffScreenPlainSurface in system memory.

I created an object called SurfaceCollector to handle collecting copying the surface into system memory and getting the GraphicsStream from its data. For every frame that came into my capture object, I copied the surface to that OffScreenPlainSurface and then queued the operation, SurfaceLoader.SaveToStream to run in its own thread. This allowed for the renderer to start working on the next frame while this was being stored to the video. I had another thread running to take the ready-to-use streams and save them to the video.

Copying proved difficult because I made the mistake of following Direct X's documentation. Since we're multisampling, you can't copy it directly. You have to create another RenderTarget without multisampling. Call StretchRectangle to copy data to the non-multisampled RenderTarget, but you must pass in a Rectangle that is the size of your surface; the documentation says you can pass in null, but C# won't allow structs to be null... Then you can call GetRenderTargetData to get the non-multisampled data into your surface in system memory.

The relevant code (slightly modified from my original to make it more relevant):

Create a Queue of the following object:

private class SurfaceCollector
{
    private        Surface        surface = null;
    private        Boolean        done = false;
    private        GraphicsStream stream = null;
    private static Rectangle      screenRect = Rectangle.Empty;

    public SurfaceCollector(Surface s)
    {
        //Set the screen rectangle if it's not already
        if (screenRect == Rectangle.Empty)
        {
            screenRect = new Rectangle(0, 0, s.Description.Width, s.Description.Height);
        }
        Copy(s);
    }

    /// 
    /// Copies the rendered surface to a non-multisampled surface
    /// then to an OffScreenPlainSurface in system memory.
    /// 
    /// 
    private void Copy(Surface s)
    {
        Surface tempSurface = Device.CreateRenderTarget(
            s.Description.Width,
            s.Description.Height,
            s.Description.Format,
            MultiSampleType.None,
            0,
            false
            );

        Device.StretchRectangle(s, screenRect, tempSurface, screenRect, TextureFilter.None);

        surface = Engine.Instance.Device.CreateOffscreenPlainSurface(
            s.Description.Width,
            s.Description.Height,
            s.Description.Format,
            Pool.SystemMemory
            );

        Device.GetRenderTargetData(tempSurface, surface);

        tempSurface.Dispose();
        tempSurface = null;
    }

    /// 
    /// Retrieves a GraphicsStream from the surface, call this method before accessing the Stream property.
    /// 
    public void GetStream()
    {
        try
        {
            stream = SurfaceLoader.SaveToStream(ImageFileFormat.Bmp, surface);
        }
        catch (Exception e)
        {
            //Handle your errors gracefully
        }
        done = true;
    }

    /// 
    /// Signals if the thread is done retrieving the stream
    /// 
    public Boolean Done
    {
        get { return done; }
    }

    /// 
    /// If a successful call to GetStream() has occured, return that stream,
    /// otherwise return null.
    /// 
    public GraphicsStream Stream
    {
        get
        {
            if (done)
                return stream;
            return null;
        }
    }

    /// 
    /// Frees all resources used by this object.
    /// 
    public void CleanUp()
    {
        if (surface != null && !surface.Disposed)
        {
            surface.Dispose();
            surface = null;
        }
        if (stream != null)
        {
            stream.Close();
            stream.Dispose();
            stream = null;
        }
    }
}
  

And the QueueProcessor Thread

private void ProcessQueue()
{
    while (true)
    {
        //Thread is done, break the loop
        if (waitingToClose && queue.Count == 0)
            break;
        while (queue.Count == 0 || !queue.Peek().Done)
        {
            //To prevent deadlock, check to see if we're waiting to finish
            if (waitingToClose)
                break;
            Thread.Sleep(25);
        }
        //To prevent deadlock, if we've left the previous loop and the queue is empty, we're done.
        if (queue.Count == 0)
            break;

        SurfaceCollector collector = queue.Dequeue();
        try
        {
            CaptureFrameFromGraphicsStream(collector.Stream);
        }
        catch (Direct3D.Direct3DXException ex)
        {
            //Handle your errors gracefully
        }
        finally
        {
            collector.CleanUp();
            collector = null;
            GC.Collect();
        }
    }
}
  

CreateFrameFromGraphicsStream() is a little too tied to the code base for me to put it here, but there are techniques all over the web for that part. It calls another method, AddFrame(). The technique for this is also all over the web.

I really hope this helps you in your endeavors.

Thursday, August 11, 2011

Another "Your Doin' it Rong!" and a killer workout

If I hadn't established such a pattern of it, it would've been surprising when I screwed up squats again... But yesterday, personal training day, I decided what I really wanted was for the trainer to give me a good workout. It was way, way, way, way, way too good.

Tip

For a proper squat, go down just past parallel, no more than that!

Before I get to the workout, I want to address squats, again. As any regular reader of this blog knows (and I don't know if such a thing exists), I've been having trouble with squats since switching shoes. It could have been happening the whole time, the shoe switch definitely triggered something. Yesterday, during the workout, Dean told me I was going down too far in my squats and that once I got down there is where I was losing my balance. Interesting. Why did that never occur to me? So I had him call out when it was time to go back up. Result: didn't fall over at all, and only once was there even a bit of concern.

On to the killer workout. This will take up to 30 minutes, but if you last that long I commend you. The workout: 5 rounds, for time of:

  1. 7 Heavy Front Squats
  2. 0.5 Mile Bike ride
  3. 12* Sit-up Slams
*though the real workout calls for 15

The heavy front squat is just that, a weight you can really only do 7 or so of in a set. The half mile bike ride, also self-explanatory, but go as fast as you can. Sit-up Slams take a bit of explanation. All it requires is a bit of flat ground and a medicine ball, preferably one that won't hold it's shape upon impact. Start out by laying down on the floor with your legs straight and your arms straight behind your head with the medicine ball in your hands. Essentially, you'll be in the shape of a lower case 'i.' From there, bring the medicine ball over yourself like you're trying to throw it at your feet (don't let go yet) while simultaneously bringing your feet in quickly to stand up. This needs to be a quick motion, otherwise you'll fall backward and have to try again. The real objective of this motion is to go from laying down to standing with the medicine ball. Once you're steady on your feet, raise the medicine ball over your head and slam it into the ground as hard as you can.

As mentioned, the goal of this is to go for time. You do 5 rounds as fast as you can. I made it, literally, through 2 rounds and had to stop for a long while to recover. Ugh. But hey, not bad for getting lifting and cardio out of the way in like 12 minutes or so, huh? If you try this routine, let me know how it goes, and if I was just being a wuss for stopping after 2 rounds ;)

Monday, August 8, 2011

Week 32 update

Quick update on progress. We're in the home stretch now. 5.75 pounds to go. Even some of my new pants are getting a bit loose :) In case you're wondering, though, the temptations for both recreational eating and overeating are still there. I'll probably have to work on these two things for a long time to get them under control.

On the falling-on-my-butt front, those stretches I mentioned a few posts ago are really helping, but only if I do them before I attempt squats. I even managed to land a few squat snatches. The bruise on my butt is there to remind me that not only did I not land some, I fell in a spectacular way! Seriously, I was really just attempting to get the form down so I was using the bar plus the 10-pound bumpers. The deadlift portion went fine, but when I pulled for the snatch, the bar went way out in front of me. So when it arrived overhead, it wanted to keep going. I stopped it, but the force required to stop it sent forward at a fairly alarming rate. Also, conservation of momentum kicked in and backwards I went. I fell, I slid, I rolled, and then I laughed at just how loud that crash was. Ego bruised, I took a bit of a break before trying again. More technical issues to fix...

If you're doing those lifts, or any for that matter, tighten those abs. I'm terrible about that, but it helps with stability.

Other ways to work out

If you've not heard of Cross Fit, they have an interesting take on exercise. It's rather similar to the P90X commercials you've probably seen on TV. They have a rotating schedule of exercise and rest days that seems to number in the dozens; each day is something different. The problem I have with Cross Fit is nothing with their philosophy, which I think is sound, but their price. To be a Cross Fit member, one must pay a bunch of money (read: single class college tuition). It has its benefits, naturally: They have instructors, facilities, and even competitions between members. I have a gym membership, a trainer, and I fairly often compete with myself, so what from Cross Fit to apply to my own workouts?

Checking out their "Workout of the Day" (WOD), they do a lot of different exercises and measure it a lot of different ways. Sometimes, it's the usual max reps at a given weight, or max weight. Other times it's for time, or count how many rounds you can do of a small circuit of just a few exercises. Now we're on to something.

Usually, I've simply gone for completing my circuit at the cost of time. Ask my wife, my workouts have been getting longer and longer. Sadly, I've only added one exercise to the mix, but it has to be separate from the others. Also, those stretches that I mentioned a post or two back take a lot of time. As fun as it is to be at the gym for 2 hours a day, it's a bit time consuming. So, if I continue to do roughly 30 to 40 minutes of cardio and 20 minutes of stretching, that leaves a large window to get done in under 2 hours.

I've decided to change up my routine a bit to be more accommodating of this goal. Do 3 rounds of my routine, 1 set per exercise, with a rest period in between, and go for time. If I'm not actively seeking to better some metric, it won't get better. Previously, it's just been for completing the sets at the heavier weight. Maybe this new method will get me done in the gym quicker, getting just as much work done in a shorter time.

I see no problem with mimicking good ideas. We'll see how this works for me.

Tuesday, August 2, 2011

Do or do not, there is no try ~ Yoda

A nicely quotable bit of wisdom, but it's only true in binary outcomes, such as Pass/Fail, or Win/Lose. Only a portion of what we do, when broken way down, comes to a binary outcome. Thankfully, the rest of the world measures degree of effort/success. That is what I want to address today: How hard are you willing to try at something?

For me, if it's something that I can compete at, my philosophy is: I will try harder than you. You may beat me with natural talent, better skill, or whatever, but I will try harder than you. I know that regardless of outcome, I did everything I knew how to do to accomplish the task including asking for help. For example: in one of my math classes in college, I literally got another corresponding textbook and did all homework problems from both it and the class's textbook to ensure I got a good grade. Another: yesterday at work was an over-lunch meeting, which I attended and watched everyone eat pizza knowing that my food was waiting for me in the fridge. I happened to be sitting next to one of the people that complained about how easy it is for me to lose weight compared to her. She had pizza...and complimented my diligence.

The majority of my dieting/getting fit experience has been a test of how hard I am willing to try. Am I willing to barely finish my cardio every single time thanks to increasing the resistance/speed/etc.? Am I willing to stretch for 20 minutes after workout? Am I willing to workout even if I'm tired? As it turns out, yes. It's absolutely exhausting, painful, blister-inducing, and working. It's working without the need for "miracle" pills, trendy diets, or more elaborate means. It's working and satisfying because I know my efforts have led to this success.

Of course, sometimes efforts fail, even when you try your hardest. If you're willing to try your best, you have to accept that sometimes it is just not meant to be and learn from it. I learned in school that my future will never be in algorithm research and development. I studied, I read, I did the homework, but no matter what I did, I just couldn't wrap my head around it. I did "so well" at it I got the unfortunate honor of repeating the class. I kept trying; I passed the class; but did not further pursue algorithms in my course work. I learned one of my limitations, so all that effort was not wasted. It just pointed me in a different direction.

Lastly, if you're not willing to try hard, then accept that diminished effort for what it is. Only lament a failure for the fact that you weren't willing to try, not because you failed at it. That's a lesson I have to relearn from time to time. Did I try my best at X? No? Then how can I justify being upset by it? So then I get to explore the wildly more informative question: Why didn't I try my best? Oh, Mr. Achilles Heel. Nice to see you again. Why am I always surprised when you show up?

Next time you think about what you want to accomplish, ask yourself how hard are you willing to try to do it?