<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF
	xmlns="http://purl.org/rss/1.0/"
	xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
	xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel rdf:about="http://feeds.garagegames.com/rss/blogs/developer/370/">
		<title>Blog for Pat Wilson at GarageGames.com</title>
		<description>Blog feeds for Gamers and Developers in the GarageGames community.</description>
		<link>http://www.garagegames.com/</link>
		<image rdf:resource="http://www.garagegames.com/images/GarageGames_logo_small_w.gif" />
		<dc:date>2008-11-21T14:37:27+00:00</dc:date>
		<items>
			<rdf:Seq>
				<rdf:li rdf:resource="http://www.garagegames.com/blogs/370/15340"/>
				<rdf:li rdf:resource="http://www.garagegames.com/blogs/370/14899"/>
				<rdf:li rdf:resource="http://www.garagegames.com/blogs/370/11090"/>
				<rdf:li rdf:resource="http://www.garagegames.com/blogs/370/9769"/>
				<rdf:li rdf:resource="http://www.garagegames.com/blogs/370/8235"/>
				<rdf:li rdf:resource="http://www.garagegames.com/blogs/370/8011"/>
				<rdf:li rdf:resource="http://www.garagegames.com/blogs/370/7725"/>
				<rdf:li rdf:resource="http://www.garagegames.com/blogs/370/7367"/>
				<rdf:li rdf:resource="http://www.garagegames.com/blogs/370/7072"/>
				<rdf:li rdf:resource="http://www.garagegames.com/blogs/370/7014"/>
			</rdf:Seq>
		</items>
	</channel>
	<item rdf:about="http://www.garagegames.com/blogs/370/15340">
		<dc:format>text/html</dc:format>
		<dc:date>2008-08-28T18:25:12+00:00</dc:date>
		<dc:creator>Pat Wilson</dc:creator>
		<title>G-Buffer Normals and Trig Lookup Textures</title>
		<link>http://www.garagegames.com/blogs/370/15340</link>
		<description>&lt;img src='http://farm4.static.flickr.com/3013/2804711424_dcb8c53f67_o.png'  align=right hspace=3 vspace=3 border=0 alt=&quot;&quot;&gt;(Cross posted from personal blog. Hopefully someone has a rockin' idea about this.) &lt;br&gt;&lt;br&gt;I've switched to using spherical co-ordinates to encode world-space G-buffer normals. This has a lot of advantages to it, especially for 8:8:8:8 G-buffers. You can now store [Theta, Phi, DepthHi, DepthLo] in the 8:8:8:8 target. Bumping the format to 16:16:16:16 not only gives greater precision, but (depending on the depth resolution you need) you can get an extra channel for information storage. (Mmmm virtual texture bitfield?)&lt;br&gt;&lt;br&gt;There are a few problems with this, though. The first is the atan2 function. On good hardware, this will not be an issue. My GeForce 8800 chews through any shader I throw at it. My Radeon x1300...not so much. Of course it's easy to make things run fast on good hardware. The challenge is making it run decently on lower end hardware. This is how I am encoding/decoding G-buffer normals:&lt;br&gt;&lt;br&gt;&lt;div class='codeblock'&gt;&lt;pre&gt;inline float2 cartesianToSpGPU( in float3 normalizedVec )&lt;br&gt;{&lt;br&gt;   float atanYX = atan2( normalizedVec.y, normalizedVec.x );&lt;br&gt;   float2 ret = float2( atanYX / PI, normalizedVec.z );&lt;br&gt;&lt;br&gt;   return POS_NEG_ENCODE( ret );&lt;br&gt;}&lt;br&gt;&lt;br&gt;inline float3 spGPUToCartesian( in float2 spGPUAngles )&lt;br&gt;{&lt;br&gt;   float2 expSpGPUAngles = POS_NEG_DECODE( spGPUAngles );&lt;br&gt;   float2 scTheta;&lt;br&gt;&lt;br&gt;   sincos( expSpGPUAngles.x * PI, scTheta.x, scTheta.y );&lt;br&gt;   float2 scPhi = float2( sqrt( 1.0 - expSpGPUAngles.y * expSpGPUAngles.y ), expSpGPUAngles.y );&lt;br&gt;&lt;br&gt;   // Renormalization not needed&lt;br&gt;   return float3( scTheta.y * scPhi.x, scTheta.x * scPhi.x, scPhi.y );&lt;br&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;Storing normal.z instead of acos( normal.z ) saves a decent chunk of encode/decode.&lt;br&gt;&lt;br&gt;So I decided to try to use a lookup texture instead of calling atan2 to encode the normals. I made a 256x256 A8 texture and filled it with atan2 values. The texture can be seen, to the right. This is the code for generating the texture:&lt;br&gt;&lt;br&gt;&lt;div class='codeblock'&gt;&lt;pre&gt;GFXTexHandle *RenderPrePassMgr::getAtan2Texture()&lt;br&gt;{&lt;br&gt;   if( mAtan2Handle.isNull() )&lt;br&gt;   {&lt;br&gt;      // Create a lookup texture to output a normalized atan2 result&lt;br&gt;      const U32 cLookupTexSz = 256;&lt;br&gt;&lt;br&gt;      mAtan2Handle.set( cLookupTexSz, cLookupTexSz, GFXFormatA8, &amp;amp;GFXLookupTextureProfile, 1 );&lt;br&gt;      GFXLockedRect *atan2Mem = mAtan2Handle.lock();&lt;br&gt;&lt;br&gt;      for( int y = 0; y &amp;lt; cLookupTexSz; y++ )&lt;br&gt;      {&lt;br&gt;         for( int x = 0; x &amp;lt; cLookupTexSz; x++ )&lt;br&gt;         {&lt;br&gt;            F32 xval = ( ( x / F32(cLookupTexSz) ) * 2.0f - 1.0f );&lt;br&gt;            F32 yval = ( ( y / F32(cLookupTexSz) ) * 2.0f - 1.0f );&lt;br&gt;&lt;br&gt;            U8 &amp;amp;outU8 = atan2Mem-&amp;gt;bits[y * cLookupTexSz + x];&lt;br&gt;&lt;br&gt;            F32 atanRes = ( atan2( yval, xval ) + M_PI_F ) / M_2PI_F;&lt;br&gt;            U8 u8Res = mFloor( atanRes * 255.0f );&lt;br&gt;            outU8 = u8Res;&lt;br&gt;         }&lt;br&gt;      }&lt;br&gt;&lt;br&gt;      mAtan2Handle.unlock();&lt;br&gt;   }&lt;br&gt;&lt;br&gt;   return &amp;amp;mAtan2Handle;&lt;br&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;There is a possible discontinuity when V is near 0.5 and U &amp;lt; 0.5. So if normal.y is near 0.0, and normal.x &amp;lt; 0.0 than you get some artifacts that won't occur if you actually call atan2. The A8 format isn't the issue (I don't think) because even if you use the actual function, you are still encoding the result to an 8-bit value. The resolution of the texture could be an issue, but doubling the resolution did not effect the error rate, in my tests.&lt;br&gt;&lt;br&gt;I haven't quite figured out what to do with this yet. A G-buffer shader is going to be heavy on math, light on texture operations (Well this depends on how you are doing deferred shading. See upcoming ShaderX7!) and doing the atan2 as a texture sample can save a lot of instructions and cycles, depending on the hardware.</description>
	</item>
	<item rdf:about="http://www.garagegames.com/blogs/370/14899">
		<dc:format>text/html</dc:format>
		<dc:date>2008-06-17T17:52:19+00:00</dc:date>
		<dc:creator>Pat Wilson</dc:creator>
		<title>Multi-Threaded Mesh Skinning Showing Promise</title>
		<link>http://www.garagegames.com/blogs/370/14899</link>
		<description>It's been almost 2 years since my last blog post, so I guess it was about time.&lt;br&gt;&lt;br&gt;Rokkitball is a bad case for mesh skinning. The maximum game size, right now, is 8 players. These players are all in a small arena, the camera is 3rd person, and so you are frequently skinning high LOD meshes, and lots of them. While there are still some art things that we can do to reduce the load on the CPU, I decided to re-visit a problem which had previously frustrated me: optimizing mesh skinning.&lt;br&gt;&lt;br&gt;This time through, I decided that the way to go was to multi-thread the skinning code. Mesh skinning happens as a part of the rendering of an object, take a look at TSSkinMesh::render(). It calles UpdateSkin(), and then calls up to the Parent::render(), which creates render instances. While the vertex buffer is created, it is not used immediately. This parallels discussions I had previously with Mark Frohnmayer about the idea of using a 'Promise' for things which aren't ready right away, but will be eventually. Like many network cases, and also, like skinned meshes.&lt;br&gt;&lt;br&gt;So I've already written too much without pasting any code. I like code.&lt;br&gt;&lt;br&gt;&lt;div class='codeblock'&gt;&lt;pre&gt;#ifndef _PROMISE_H_&lt;br&gt;#define _PROMISE_H_&lt;br&gt;&lt;br&gt;// This is a rough draft&lt;br&gt;&lt;br&gt;template&amp;lt;typename T&amp;gt;&lt;br&gt;class Promise&lt;br&gt;{&lt;br&gt;protected:&lt;br&gt;   /// Return the promised data. Undefined results if isReady() is false.&lt;br&gt;   virtual T *get() = 0;&lt;br&gt;&lt;br&gt;public:&lt;br&gt;   virtual ~Promise() { }&lt;br&gt;&lt;br&gt;   /// Returns true if the promised data is ready.&lt;br&gt;   virtual bool isReady() const = 0;&lt;br&gt;&lt;br&gt;   /// Blocks until the promised data is ready, and returns it.&lt;br&gt;   virtual T *resolve() { while( !isReady() ); return get(); }&lt;br&gt;};&lt;br&gt;&lt;br&gt;#endif&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;Pretty simple. So after that I changed render instances to store Promise&amp;lt;GFXVertexBufferHandleBase&amp;gt;* instead of a vertex buffer pointer, and put in proper methods to GFXDevice so that calling resolve() on a promise would be delayed until the last possible second; in updateStates(). After that I needed to test it, so I wrote this class:&lt;br&gt;&lt;br&gt;&lt;div class='codeblock'&gt;&lt;pre&gt;#ifndef _SIMPLE_PROMISE_H_&lt;br&gt;#define _SIMPLE_PROMISE_H_&lt;br&gt;&lt;br&gt;#include &amp;quot;core/promise.h&amp;quot;&lt;br&gt;&lt;br&gt;template&amp;lt;typename T&amp;gt;&lt;br&gt;class SimplePromise : public Promise&amp;lt;T&amp;gt;&lt;br&gt;{&lt;br&gt;protected:&lt;br&gt;   T *mPtr;&lt;br&gt;   virtual T *get() { return mPtr; }&lt;br&gt;&lt;br&gt;public:&lt;br&gt;   SimplePromise( T *ptr ) : mPtr( ptr ) {}&lt;br&gt;&lt;br&gt;   virtual bool isReady() const { return true; }&lt;br&gt;&lt;br&gt;   virtual void set( T *ptr ) { mPtr = ptr; }&lt;br&gt;};&lt;br&gt;&lt;br&gt;#endif&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;This worked fine and dandy, so it was time to thread the promise fulfillment. The ThreadedPromise class is not nearly as simple as the above class, so pasting it would just make a wall-o-text, but the concept should be apparent: a ThreadedPromise is created and will, at some point, be serviced by a thread, fulfilling the promise.&lt;br&gt;&lt;br&gt;The way I chose to approach this was to create a PromiseFulfillerThread class, which would operate on a provided list of ThreadedPromises. This was implemented, intially, using a VectorPtr with a mutex on it. These were the initial results run on a Core2 Quad. Each mesh was 3k+ polys, and had no LODs.&lt;br&gt;&lt;img src='http://spreadsheets.google.com/pub?key=pzUp1A26JGMqsOmSNZr-fZA&amp;amp;oid=5&amp;amp;output=image'  alt=&quot;&quot;&gt;&lt;br&gt;Well that's pretty cool, but as you can see, by the orange bar, one additional thread did not provide much of an improvement at all. Since the target was a Core 2, not a quad, this wasn't good enough.&lt;br&gt;&lt;br&gt;The next step I took was to remove the mutex. Locking, and unlocking a mutex takes time, and it really isn't very appropriate to the simple manipulation of a worklist. So I revisited something I'd been meaning to look at for a while: interlocked operations. I re-wrote the ThreadedPromise to use a lockless linked list. This provided a noticeable speed increase, but it still wasn't what I was looking for. What I found was that, with 2 cores, the main thread would batch up all the render instances, start drawing, and then sit and spin the first time it ran into a promise that wasn't ready. I suspected that, if the main thread could &amp;quot;take&amp;quot; promises back and fulfill them as it needed them, it would provide the speed increases that were needed, as well as provide flexibility for future improvements.&lt;br&gt;&lt;br&gt;This turned out to be true, and the metrics proved it. These are metrics dumped to the console.log from a 2-core AMD:&lt;br&gt;&lt;br&gt;&lt;div class='codeblock'&gt;&lt;pre&gt;TSSkinBatcher -- Threaded Skin Promise Metrics&lt;br&gt;   - Promises batched to threads: 134050&lt;br&gt;   - Fulfilled before resolve: 91382&lt;br&gt;   - Promises blocked on resolve: 42668 [31.83%]&lt;br&gt;      + Worker thread processed 15065 [35.31%]&lt;br&gt;      + Main thread processed 27603 [64.69%]&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;So out of 134k skin requests, 91k of them got processed by worker threads before the main thread even asked for them. There were still 42k promises that the main thread had to block on. Of those 42k, 15k were being processed by the worker threads when the main thread tried to resolve() them, so the main thread had to sit and spin, but 27k of them hadn't been started on the worker threads yet, so the main thread processed them, while letting the worker threads continue on other promises.&lt;br&gt;&lt;br&gt;This was a very good return on work done. I have been seeing a ~20% framerate improvement on 2 core systems, for about 3.5 days of work, including the re-write of the skinning loop, and creating the TSSkinBatcher. The really surprising thing was how the implementation just fell into place once I wrote that tiny, abstract, 4-method class.&lt;br&gt;&lt;br&gt;And now, the wrap-up!&lt;br&gt;&lt;br&gt;Promises are really useful, and powerful constructs. They are not a substitute for proper architecture, but they are a tool in the toolbox. They are useful for more than threading and networking. Although I haven't coded it yet, one could easily make a deferred function-call promise which could be returned by a method which has many callers. The execution of the function could be delayed until the value was actually used, and then, once computed, the value could be stored and returned back to subsequent calls, until it was reset.&lt;br&gt;&lt;br&gt;So, yet another tool to throw into the toolbox for optimization! Next blog entry will probably be about deferred rendering.</description>
	</item>
	<item rdf:about="http://www.garagegames.com/blogs/370/11090">
		<dc:format>text/html</dc:format>
		<dc:date>2006-08-14T17:27:24+00:00</dc:date>
		<dc:creator>Pat Wilson</dc:creator>
		<title>Torque X and Microsoft</title>
		<link>http://www.garagegames.com/blogs/370/11090</link>
		<description>I wanted to post a quick blog post to address some of the things I've seen come up in the forums. Besides, I haven't done a GG blog post in a while.&lt;br&gt;&lt;br&gt;Our working closely with Microsoft on this project does not mean that we have any intention of dropping cross platform support, reducing cross platform support or anything like that. I know this has been said before. I wanted to say it again. XNA is another platform. It turns out that it's a very important platform. I've had some things to say about C# in the past, and I honestly still prefer C++. However, like I said in a thread recently, there comes a point when thebenefits of a technology outweigh it's costs, and it must be considered seriously otherwise it's just elitism. (I will be the first to admit I suffer from elitism.)&lt;br&gt;&lt;br&gt;I said this to the associates a while back, and I wanted to say this to the community:&lt;br&gt;&lt;br&gt;There will be things about this platform that you may not like. Such as: Why should I have to move my code to a new engine, why C#, why we gotta pay money etc, etc. The most important thing about XNA is the concept, and it's goal: Let indies make console games without dev kits. It is critical to this goal which we all share (making games, and further, making games on consoles) that this effort succeed, and I have no doubt in my mind that it will. The best way that we, as developers (and I speak for myself as well, because I fully intend to use XNA even though there is a dev kit sitting on my desk. We eat our own dog food.) can do to try to get our agenda pushed forward is to help this project succeed.&lt;br&gt;&lt;br&gt;People have asked questions like: Well is this going to be like the PS2 Linux kit where the only people who can play it are other developers? Will we be able to make money off our games or will they only be free? and so on...&lt;br&gt;&lt;br&gt;Well there's your answer! Help this project be a success. You can use TorqueX, you can write your engine from scratch, whatever. The important thing, again, is the concept. If you want to see more support for XNA on the 360, than help make it so. Make games. Make the game that Microsoft says, &amp;quot;Damn if people are going to keep doing that, we need to let them sell their games!&amp;quot; or, &amp;quot;We need to make it so people can share games ASAP!&amp;quot;&lt;br&gt;&lt;br&gt;Microsoft is committed to making XNA a success. GarageGames is committed to making XNA a success. So I am asking the community to help out as well.</description>
	</item>
	<item rdf:about="http://www.garagegames.com/blogs/370/9769">
		<dc:format>text/html</dc:format>
		<dc:date>2006-02-11T11:46:41+00:00</dc:date>
		<dc:creator>Pat Wilson</dc:creator>
		<title>10th Most Popular Game on Live</title>
		<link>http://www.garagegames.com/blogs/370/9769</link>
		<description>&lt;a href='http://www.majornelson.com/2006/02/10/marble-blast-rolls-into-the-top-xbox-live-games-list/' target=_blank&gt;As blogged by Major Nelson&lt;/a&gt;:&lt;br&gt;&lt;blockquote&gt;&lt;font size=1&gt;Quote:&lt;br&gt;&lt;hr height=1 noshade&gt;&lt;br&gt;Marble Blast rolls into the top Xbox Live games list&lt;br&gt;Posted: February 10, 2006 @ 9:08 pm (6 hours, 28 minutes ago) By: Major Nelson&lt;br&gt;&lt;br&gt;Here are the most popular games on Xbox Live last week*&lt;br&gt;&lt;br&gt;1 Halo 2&lt;br&gt;2 Call of Duty 2&lt;br&gt;3 DEAD OR ALIVE 4&lt;br&gt;4 Perfect Dark Zero&lt;br&gt;5 PGR3&lt;br&gt;6 Need for Speed Most Wanted&lt;br&gt;7 Battlefield 2: MC&lt;br&gt;8 Madden NFL 06&lt;br&gt;9 Full Auto Demo&lt;br&gt;10 Marble Blast Ultra&lt;br&gt;&lt;br&gt;*Based on users logged on.&lt;br&gt;&lt;hr height=1 noshade&gt;&lt;/font&gt;&lt;/blockquote&gt;&lt;br&gt;Good heavens I think I am glowing. I am gonna turn off the lights to check...&lt;br&gt;&lt;br&gt;Yep...&lt;br&gt;&lt;br&gt;To the extreme!&lt;br&gt;&lt;br&gt;(Bonus points for picking up on the reference!)</description>
	</item>
	<item rdf:about="http://www.garagegames.com/blogs/370/8235">
		<dc:format>text/html</dc:format>
		<dc:date>2005-07-13T00:12:18+00:00</dc:date>
		<dc:creator>Pat Wilson</dc:creator>
		<title>Development of TSE360</title>
		<link>http://www.garagegames.com/blogs/370/8235</link>
		<description>&lt;b&gt;Development progress of TSE360!&lt;/b&gt;&lt;br&gt;(Note: All images are under my Flickr phototag 'tse360'. You can find them: &lt;a href='http://www.flickr.com/photos/killerbunny/tags/tse360/' target=_blank&gt;HERE&lt;/a&gt;).&lt;br&gt;&lt;br&gt;&lt;img src='http://photos23.flickr.com/25558154_39998f5d34_m.jpg'  align=left vspace=3 hspace=3 alt=&quot;&quot;&gt;I am around 2 months into TSE360 development and since there has already been a bit of noise about this in Mark Frohnmayer's last .plan and such I thought I'd let a little more of the cat out of the bag and let it kind of run around on the floor while dragging the bag behind it with it's front paws. The end is in sight...or to put it differently: The Xbox 360 insurgency is in it's last throws! Most of this .plan is going to consist of strange pictures (that are only really exciting to me when I was in the first stages of development) and discussion of some of the compatibility features of TSE and TSE360, specifically.&lt;br&gt;&lt;br&gt;The goal for TSE360 development continues along with the goal I had in mind 2 years ago when I started writing the TSE graphics layer: You write the code on one platform, and it works on the rest (to the limits of realistic expectations). This is an ambitious goal, to be sure, but I always felt that it was realistic. This goal is realized pretty well in Torque right now. I'm sure teams will be happy to tell you about how it took them 5 hours to have a Mac port. Or some more specialized teams could tell you it took them 10 minutes to have Torque building on the x86 Apple computers. Yes, Torque is portable, and we want to carry this to the next level with TSE. &lt;br&gt;&lt;br&gt;This isn't a pure technology project that I am on right now, we have a game to ship, and a very aggressive schedule. The team isn't screaming while we code yet, and when we have meetings we say things like, &amp;quot;This should  be done by...&amp;quot; and, &amp;quot;...barring any unforeseen...&amp;quot; so it's not exactly aggressive like a bulldog on a steak-flavored chewtoy or anything. It's more like a passive-aggressive bulldog who ran out of Zoloft or something. It's not very pretty, but the further we get on the project, the tighter the platform layer and GFX device for the Xbox 360 will get...and the more bug fixes will get back to TSE!&lt;br&gt;&lt;br&gt;&lt;img src='http://photos21.flickr.com/25558225_fac7fb08a2_m.jpg'  align=right vspace=3 hspace=3 alt=&quot;&quot;&gt;Until recently we only had one development kit and so, unless measure were taken to address compatibility, it would be very difficult to get development started. This was my first task. The first thing I did was to create a GFX device for the Xbox360. Those of you who have, and know, TSE will know what I mean by a GFX device. For those who don't, GFX is a graphics layer which will let you write API-abstracted rendering code. (For example, the same calls will do the same things on PC DirectX 9, or OpenGL 1.5, or the Xbox 360.) &lt;br&gt;&lt;img src='http://photos23.flickr.com/25558166_92c20f153f_m.jpg'  align=left vspace=3 hspace=3 alt=&quot;&quot;&gt;This let development progress on the PC and the 360 at the same time, off the same codebase. There were, of course, two, separate project files, but other than that it was pretty seamless. The next thing was to get controller input working, on the PC, exactly the way it does on the Xbox. This was a simple task, and it allowed us to write GUIs designed for controler use and prototype them on the PC, as well as test things like gameplay on the PC as well!&lt;br&gt;Next I put focus onto the GUI editor. I set the resolutions for TSE to be the same resolutions that are supported by the Xbox360, and changed the GUI editor to have preview selections for those resolutions. This way the team could start making GUI's that would look the same on PC as they would on the Xbox. So now things looked the same on the PC as they did on the Xbox in the GUI. The GUI navigation was the same, if you used an Xbox controller plugged into a PC, or you could use the keyboard with the 'a' key acting the same as the 'a' button, etc. That was the easy part...the next task was 3d rendering.&lt;br&gt;&lt;br&gt;&lt;img src='http://photos23.flickr.com/25576111_a12545fdf5_o.jpg'  align=right vspace=3 hspace=3 alt=&quot;&quot;&gt;For reasons that are very NDA, I can't discuss specifics of what had to be changed in the TSE GFX device, however I can say that, under the circumstances, the GFX layer held up very well. A lot of the things which I had to now consider didn't even enter into my thinking two years ago when the code was written for GFX. TSE handled these new restrictions and expanded abilities quite well, and I finally got to fix some lame-brained things that I did back then too. (You'll notice, if it's in CVS yet, that there is now an enum-translation table that will help greatly for the move to OpenGL as well.) As you'll see from the pictures scattered throughout this plan, it wasn't an easy process. &lt;br&gt;&lt;br&gt;Work progressed steadily. &lt;br&gt;&lt;br&gt;As you can see by these images it went first to getting polygons rendering correctly, then getting texturing working correctly. &lt;br&gt;&lt;br&gt;You'll see that I am using a test map so I can see what is doing with the texture coordinates and such (and it's doing them correctly). &lt;br&gt;&lt;br&gt;Then next was to get it using the right textures, then get it working in three space (that first one is the glow buffer, actually). &lt;br&gt;&lt;br&gt;There were some problems with mip mapping, but those got sorted out. &lt;br&gt;&lt;br&gt;Then you'll see the TSE material test cube, on a lovely pink background and then the hallway there with messed up lighmaps on the DIFs. &lt;br&gt;&lt;br&gt;As of right now, the team is working on PC and Xbox 360 in full development of a game on TSE, the HEAD revision, with updated code for Xbox 360. There is now an internal SVN repository for TSE360 that is being kept in synch with the latest TSE developments so the two are always in step with eachother. Already there have been a significant number of inquiries regarding TSE and the Xbox 360 so I thought that I'd let everyone know what was going on at the desk with the &amp;quot;Tribes: Vengeance Beta Play Disk&amp;quot; coaster here at GarageGames. If you are lucky, you could catch development challenges, rants, or maybe Tribes videos on &lt;a href='http://angrydev.blogspot.com' target=_blank&gt;my (totally unofficial) blog&lt;/a&gt;.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;img src='http://photos22.flickr.com/25558207_718ab91c17.jpg'  valign=5 halign=5 alt=&quot;&quot;&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;img src='http://photos22.flickr.com/25579024_efa72a8b30.jpg'  align=centervspace=3 hspace=3 valign=center alt=&quot;&quot;&gt;A little slice of my desk...I told you so...</description>
	</item>
	<item rdf:about="http://www.garagegames.com/blogs/370/8011">
		<dc:format>text/html</dc:format>
		<dc:date>2005-06-09T01:40:21+00:00</dc:date>
		<dc:creator>Pat Wilson</dc:creator>
		<title>Recovery Time</title>
		<link>http://www.garagegames.com/blogs/370/8011</link>
		<description>I realize I haven't done a .plan in forever. My project is still under wraps so nothing on that yet. I think the game will be welcomed by fans old and new. There is a lot of cool TSE tech that I am getting to develop, and this is going to be a very exciting year for GarageGames.&lt;br&gt;&lt;br&gt;In other news, though, I just got out of the hospital today after having my knee surgery to rebuild my ACL and repair some damage to the cartalage. I tore myself up pretty badly at a soccer game a few months ago and so now I'll finally start getting better. I'll be chilling in bed with my super-awesome, liquid-cooled knee sleeve (not gonna overclock the knee this time, though) and my yummy, yummy drugs while I work on some project stuff, some non-project stuff, and some sleeping. As always my full write-up is on my &lt;a href='http://angrydev.blogspot.com/' target=_blank&gt;non-GG blog&lt;/a&gt;.</description>
	</item>
	<item rdf:about="http://www.garagegames.com/blogs/370/7725">
		<dc:format>text/html</dc:format>
		<dc:date>2005-04-30T20:54:48+00:00</dc:date>
		<dc:creator>Pat Wilson</dc:creator>
		<title>FrameTemp template class and COM in Torque</title>
		<link>http://www.garagegames.com/blogs/370/7725</link>
		<description>Yikes, it's been way over a month since my last .plan. The last one, I think, broke some records as far as the ratio between the length of the .plan and the number of comments.&lt;br&gt;&lt;br&gt;What have I been up to? Well yesterday Marble Blast Xbox passed Xbox compliance testing and is going on to functional testing. I'm saving the serious celibration until I see the game up for download, but I do have the cover page of the compliance report with &amp;quot;PASS&amp;quot; circled in hi-lighter. With any luck the game will be out on Xbox Live Arcade before our next exciting announcment.&lt;br&gt;&lt;br&gt;I can't talk at all about what I'm working on right now, unfortunatly, but it is a good thing for GarageGames and a good thing for indies. So instead I'll just ramble on about other things so I don't have a pathetic .plan length. Announcements will be made pretty soon with any luck. Here's a little teaser though...&lt;br&gt;&lt;img src='http://public.garagegames.com/patw/omgwtfbbq.jpg'  alt=&quot;&quot;&gt;&lt;br&gt;&lt;br&gt;I've been adding to TDN so that when the doors open on it there will be articles already there. Thismorning I added one on the FrameAllocator, so you all can look forward to that when TDN opens. I also added a new support-class to the FrameAllocator. It's called FrameTemp and it's a templatized class. You use it like this:&lt;br&gt;&lt;br&gt;&lt;div class='codeblock'&gt;&lt;pre&gt;FrameTemp&amp;lt;char&amp;gt; foo(32);&lt;br&gt;dStrcpy( foo, &amp;quot;Foo!&amp;quot; );&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;Which is the same as doing...&lt;br&gt;&lt;br&gt;&lt;div class='codeblock'&gt;&lt;pre&gt;char *foo = new char[32];&lt;br&gt;dStrcpy( foo, &amp;quot;Foo!&amp;quot; );&lt;br&gt;delete [] foo;&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;The cool thing about the FrameTemp class (like the FrameAllocatorMarker) is that it will manage the watermark on the FrameAllocator by using scoping. It's really useful. I added it to support another class I wrote...&lt;br&gt;&lt;br&gt;The other thing I started working on a bit is called ComConsoleObject. I'm not sure how familiar any of you are with Win32 COM, but it's a TorqueScript wrapper for COM objects. You can actually get an instance of a COM object, list the methods, call methods on it, etc...all from script!! So for example I can type:&lt;br&gt;&lt;br&gt;&lt;div class='codeblock'&gt;&lt;pre&gt;new ComConsoleObject( itunes, &amp;quot;{0xDC0C2640,0x1415,0x4644,{0x87,0x5C,0x6F,0x4D,0x76,0x98,0x39,0xBA}}&amp;quot;, &amp;quot;{0x9DD6680B,0x3EDC,0x40db,{0xA7,0x71,0xE6,0xFE,0x48,0x32,0xE3,0x4A}}&amp;quot; );&lt;br&gt;itunes.invokeMethod( &amp;quot;pause&amp;quot; );&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;And iTunes will pause! It's pretty sweet. (If you are wondering what that huge hex string is, it is the CLSID and IID of the iTunes COM object. Yes it is ugly.) Right now you can't pass arguments to functions (hehe) but I'm going to tinker with it, and maybe at some point you will be able to. Why do this? Why not provide scripters with the ability to tap into something like iTunes in Game Mods? I mean, hell, that's all I wanted to do was control iTunes while inside World of Warcraft. So now, in Torque, after I make it a bit more feature-complete, I could easily make, with 100% scripts, a little GUI window that would control iTunes. How cool is that?&lt;br&gt;&lt;br&gt;Alright so you may be thinking, &amp;quot;You have too much free time,&amp;quot; well, it's true. I got hurt playing soccer and I won't be able to do yoga or soccer or bike or (cry) dance at 80s night for a good long while I think. So until then, though, I'm going to go back to swimming, which I used to compete in when I was little (and not as engulfed by evil) and program silly things, and work on my Ultramarines. Anyway, enough about non tech stuff. If you want more of that you can always visit my &lt;a href='http://angrydev.blogspot.com/' target=_blank&gt;blog&lt;/a&gt; for the latest in non-GarageGames, and innappropriate things.</description>
	</item>
	<item rdf:about="http://www.garagegames.com/blogs/370/7367">
		<dc:format>text/html</dc:format>
		<dc:date>2005-03-16T18:16:06+00:00</dc:date>
		<dc:creator>Pat Wilson</dc:creator>
		<title>Wednesday Mar 16 18:16</title>
		<link>http://www.garagegames.com/blogs/370/7367</link>
		<description>An open letter to Fender.&lt;br /&gt;&lt;br /&gt;Dear Fender,&lt;br&gt;I recently purchased one of your guitars, an American made Stratocaster (It was red, I like red.) so that me and some friends could make a band. We use Craigs garage because it's the biggest, and since his brother has a drum kit, we figured it would be easier to bring guitars there instead of bringing drums to my place. Anyway, to the point, I am very dissapointed in this guitar because when we tried to play, no loud music came out. Then we learned that we have to buy amps. We can't afford amps, and think that they should be included with the guitar. &lt;br&gt;&lt;br&gt;This brings me to my second point. We decided that we'd write some music while we waited to get our amps sent to us. Our music is going to be the best ever. Think 50-Cent, mixed with Green Day...only sung like Destiny's Child. We're going to do a remake of &amp;quot;Panama&amp;quot; by Van Halen...only it'll be better. While trying to write the music, we learned that we need to learn how to play chords. This seems like an aweful lot to learn just to make a band. Someone suggested that we start by getting a chord book and doing something easy, but that's stupid because we don't want to play stuff that sounds like that.&lt;br&gt;&lt;br&gt;Anyway, please get us the amps as soon as possible. We are going to plan out our song, and when we get the amps it will be the best song EVER. Thank you for your time,&lt;br&gt;-Pat</description>
	</item>
	<item rdf:about="http://www.garagegames.com/blogs/370/7072">
		<dc:format>text/html</dc:format>
		<dc:date>2005-01-27T19:59:41+00:00</dc:date>
		<dc:creator>Pat Wilson</dc:creator>
		<title>Thursday Jan 27 19:59</title>
		<link>http://www.garagegames.com/blogs/370/7072</link>
		<description>&lt;b&gt;---+Roadblocks Galore&lt;/b&gt;&lt;br&gt;I seem to be running into roadblocks on all of my shiny projects lately. I have two projects which I have labled &amp;quot;shiny&amp;quot; because they were shiny objects which I started chasing after giggling regardless of weather or not they were technically useful. (Although, as my &lt;a href='http://www.garagegames.com/index.php?sec=mg&amp;amp;mod=resource&amp;amp;page=view&amp;amp;qid=7014'&gt;last .plan&lt;/a&gt; showed they can lead to good things)&lt;br&gt;&lt;br&gt;&lt;b&gt;---++Torque Effect Canvas&lt;/b&gt;&lt;br&gt;The last .plan was the beginning of the GuiEffectCanvas class, the first task was to make GuiCanvas behave well if subclassed which turned out to be just some minor changes regarding buffer swapping, adding 'virtual' to the methods etc. I'm not 100% happy with the changes regarding buffer swapping. I think I may put my brain together with the &lt;a href='http://www.garagegames.com/my/home/view.profile.php?qid=8863'&gt;Almighty Garney&lt;/a&gt; and figure out a slightly cleaner way to do this. I have some ideas. Anyway, this lets you make a canvas which, any time setContent is called, it will transition from the current content, to the next content in various cool ways.&lt;br&gt;&lt;br&gt;&lt;b&gt;---++The World of Warcraft iTunes Plugin&lt;/b&gt;&lt;br&gt;The whole goal of this project was to be able to, from within World of Warcraft (or any fullscreen 3d program for that matter) to be able to hit a key, and see a display, and type in a regular expression, and have iTunes build a playlist from that and play it. This quickly exploded into a full-blown library for hijacking a Direct3D device.&lt;br&gt;&lt;br&gt;&lt;b&gt;---+++Direct3D Device Hijacking&lt;/b&gt;&lt;br&gt;My other project if you have been reading my &lt;a href='http://angrydev.blogspot.com/' target=_blank&gt;blog&lt;/a&gt; is two part. One part is a Windows DLL that will hook in and hijack a &lt;a href='http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/d3d/interfaces/idirect3ddevice9/_idirect3ddevice9.asp' target=_blank&gt;Direct3D device&lt;/a&gt; from any D3D9 application, without having to copy a DLL into the directory or anything. This is nothing new, of course, people have been using it for &lt;a href='http://en.wikipedia.org/wiki/Wallhack' target=_blank&gt;wallhacks&lt;/a&gt; for a while. The new thing is that I can then render to this context from a DIFFERENT process. See, the way DLL memory sharing works is that a pointer which is valid in one process is not valid in another process. General memory security type thing which can probably be hacked around, but this is a much more elegant solution. The bottom line is, if I want to render to a context, it has to be in the process that created that context. My solution was to take the RPC stuff from &lt;a href='http://www.garagegames.com/pg/product/view.php?id=27'&gt;TNL&lt;/a&gt; and use that to make calls in one process and execute them in another. Right now it actually uses TNL, in the future it will just use the call marshalling (I couldn't find a good link on this) stuff and use some kind of shared data buffer. It pretty much goes like this.&lt;br&gt;Start Loader Application (All this does is load my DLL into memory, think of this as the server)&lt;br&gt;Start D3D9 Application (This is now getting it's calls routed through an instance of my DLL, so I can see and hijack them all, think of each D3D9 app as a client)&lt;br&gt;When &lt;a href='http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/d3d/interfaces/idirect3ddevice9/Present.asp' target=_blank&gt;Present &lt;/a&gt; is called, it will say to the server:&lt;br&gt;&lt;blockquote&gt;&lt;font size=1&gt;Quote:&lt;br&gt;&lt;hr height=1 noshade&gt;&lt;br&gt;Ok I am about to swap buffers, render to me. &lt;br&gt;&lt;hr height=1 noshade&gt;&lt;/font&gt;&lt;/blockquote&gt;&lt;br&gt;It then will sit and block on the Present call until the 'server' is done rendering to it.&lt;br&gt;&lt;br&gt;This is, in essence, the start of the main loop for the code which uses the hijacked device, and it does it's rendering and whatnot. It then says back to the client:&lt;br&gt;&lt;blockquote&gt;&lt;font size=1&gt;Quote:&lt;br&gt;&lt;hr height=1 noshade&gt;&lt;br&gt;I am done rendering, continue execution.&lt;br&gt;&lt;hr height=1 noshade&gt;&lt;/font&gt;&lt;/blockquote&gt;&lt;br&gt;And present is allowed to resume, and lo-and-behold, you have graphics rendered from one process onto another processes hijacked D3D9 device. &lt;br&gt;&lt;br&gt;This will work with OpenGL as well, I just haven't gotten to it. This development is currently slightly stalled while I mull over the inter-process communication interface. I originally wanted to make it a &lt;a href='http://www.garagegames.com/docs/tse/general/ch02.php'&gt;GFXDevice&lt;/a&gt; but I eventually decided GFX was too heavyweight, so I went with an API I did for a CS project called NinjaSquid, and I am thinking now that that was too heavyweight. The goal is to release this on another, exciting, unannounced section of GarageGames to use in whatever they want. I realize this will be the ultimate Wallhack creation tool, and I don't really support this, unless you are wallhacking in Americas Army, then it's ok. Just watch out though cuz aparantly, &lt;a href='http://angrydev.blogspot.com/2005/01/we-are-so-fucking-badass-omg.html' target=_blank&gt;&amp;quot;The Army is angry, and we're coming for you.&amp;quot;&lt;/a&gt; Yeah, whatever guys.&lt;br&gt;&lt;br&gt;&lt;b&gt;---+++Windows COM&lt;/b&gt;&lt;br&gt;The functional half of the plugin is to use the &lt;a href='http://developer.apple.com/sdk/itunescomsdk.html' target=_blank&gt;COM interface&lt;/a&gt; that Apple supplied for iTunes (I added a layer of abstraction so it can be ported to the Mac easily, don't worry) and wire that up to a nonexclusive, background DirectInput keyboard device so that it could sit and listen to keystrokes and detect when I wanted it to start parsing a regex. So I started just using the handy 'std::cin' and quickly was able to do stuff like type 'play', 'next' etc into a console and have it work. Sweet! Well then I came to using the IITLibraryPlaylist::Search function. I got out of memory returned. Huh, that's wierd. So I tried using it in a WSH with a Jscript. That worked fine. Try back in C++ it was trying to allocate 0xF786A1A6 bytes of memory...almost 4 gigs of memory. I have no idea what I did wrong, but since it is (in theory) instantiating the same code from Jscript as I am in C++, I can only assume that I did something very wrong with my COM usage in C++, so at 1AM last night I gave up on that and decided I'd get my ass off Ben's couch and go home.&lt;br&gt;&lt;br&gt;&lt;b&gt;---++Mostly Unrelated Rant&lt;/b&gt;&lt;br&gt;On a side note. What is it with SVN and having troubles if a file exists that is the same as one one in the repository. Here's the setup. &lt;a href='http://www.garagegames.com/my/home/view.profile.php?qid=1449'&gt;Joe Maruschak&lt;/a&gt; set me up with a very useful test map texture (It's got the texture coordinates on it and it's a B&amp;amp;W checker grid. These artists have all these useful things! It's great!) for use with testing the texture coordinate distortion thing for the vector fields. So I had a non-versioned copy of TestMap.jpg in common. When I got home I realized I needed that, so I re-downloaded it, and added it to common, then added it to the SVN repo. When I got to work and tried to update, I got an error because a 'file of the same name exists'. Well DUH, try running a damn CRC check on it and see if it's the same damn file. Treat it like any other file, give me a DIFF if it's an ASCII file. Grrrr. It seems like we've come so far from CVS but we can't get anything that's competent unless we shell out for PerForce. &lt;br&gt;&lt;br&gt;&lt;b&gt;---++What's up with this formatting!?&lt;/b&gt;&lt;br&gt;You may have noticed there are an aweful lot of &lt;a href='http://en.wikipedia.org/wiki/Hyperlink' target=_blank&gt;hyperlinks&lt;/a&gt; in this .plan and I seem to be adding strange formatting things. Why would I do such a thing? It's a secret that I will leave to the &lt;a href='http://www.garagegames.com/my/home/view.profile.php?qid=8863'&gt;Almighty Garney&lt;/a&gt; to unveil at the proper time.&lt;br&gt;&lt;br&gt;Wow that was a hell of a .plan. Lets see how many comments are on this one. I've noticed an inverse relationship between the length of my .plan and the number of comments. For those of you in the audience that are following along, all this development took place over 5 days, along with work on Marble Blast and Zap. I don't think that any of us at GarageGames ever &amp;quot;go home&amp;quot; with our brains.</description>
	</item>
	<item rdf:about="http://www.garagegames.com/blogs/370/7014">
		<dc:format>text/html</dc:format>
		<dc:date>2005-01-19T08:44:45+00:00</dc:date>
		<dc:creator>Pat Wilson</dc:creator>
		<title>Wednesday Jan 19 8:44</title>
		<link>http://www.garagegames.com/blogs/370/7014</link>
		<description>What in the name of all that is good left in the world are you DOING!?&lt;br /&gt;&lt;br /&gt;&lt;img src='http://public.garagegames.com/patw/vectorfield.jpg'  alt=&quot;&quot;&gt;&lt;br&gt;&lt;br&gt;With the advent of panic mode on Marble Blast for the Xbox (there was some miscommunication going on and so a lot of things need to be done) I have had to move my &amp;quot;cool stuff in Torque&amp;quot; development home, and this is what I am working on. As you can see, that is a picture of one of the GuiControls I am working on. In the screenshot it is rendering a warped version of the orc (which is actually in a dynamic texture, more on that later) and it is rendering the vector-field visualization over the top of that. Though it's tough to see, the grid represents the polygons the texture is being drawn on, red dots are the vertices, green lines are the vectors which indicate how the texture coordinates are being deformed.&lt;br&gt;&lt;br&gt;The DynamicTexture object is also new for 1.4, it lets you create textures and update them from either GuiControls or just screen grabs. This lets you do things like render Gui's to off-screen buffers and put them in game, like Doom 3. (I did have this idea about a year and a half ago, and I have the GarageGames resource to prove it.) I have expanded the code that I wrote back in 2003 and made it a bit more generalized for the next Torque release.&lt;br&gt;&lt;br&gt;The VectorField object is new for 1.4. It is...well a vector field. It lets you do that cool warping stuff with texture coordinates. The object itself basically just holds the texture coordinate info and is used to render the quad-strips of the field. You have to set the texture on it, and tell it to use, or not use, texturing. This can probably be optimized because right now it uses one quad-strip per row, but I really don't think it's going to matter at all because the driver probably converts it to one triangle strip anyway, and even if it's not, the least of your worries when using vector-field deformation with feedback textures is batching considerations.&lt;br&gt;&lt;br&gt;One of the most exciting new things I'm working on is GuiTickCtrl. This is a Gui control that works a lot like the GameBase tick processing. It is a pure virtual class that lets your control get updates every 32ms, interpolate between ticks, etc. I am using it for another new Gui control that uses the VectorField deformation stuff, because I want the warps to be at a consistent rate, not based on frame-rate.&lt;br&gt;&lt;br&gt;For those of you who keep up with my Blog, sorry for the duplicate information.&lt;br&gt;&lt;br&gt;Lets see if we can get GG .plans working with Technorati!&lt;br&gt;&lt;a href='http://www.technorati.com/claim/mfz4zqrxmk' target=_blank&gt;Technorati Profile&lt;/a&gt;</description>
	</item>
</rdf:RDF>
