| Thursday, August 30, 2007 |
 Of Terrain Implementations & Future Considerations |
Posted - 8/30/2007 2:20:15 PM | In between the number of Counter-Strike: Source games and my reinvigoration with Bioshock (once I got over the mid-game, relatively dull, hump), I've been working on this whole terrain geometry clipmap thing. Right now I'm focusing on getting the entire mesh -- that is, all of the clipmap levels at once -- rendering at once so I can ensure that my overall clipmap "ring" is being handled all sorts of properly.
For those people who aren't completely up-to-snuff on their terrain geoclipmap knowledge, which I assume would be most people, the idea is that the entire terrain mesh can be, essentially, rendered in its entirety using the coarsest clipmap level. That is not usually the desires course (tee-hee) of action, being that the coarsest level of detail is far from being an accurate representation of the terrain dataset, but it's a good start for visualizing the geoclipmap algorithm. The purpose of the algorithm is to use the coarsest clipmap level as the least detailed mesh for what will end up being a nested grid of increasingly detailed clipmap levels, very much like its namesake algorithm in structure. The height data for such a geometrical organization is then handled within the Vertex Shader for the rendering of the mesh; a vertex texture will set the height for a given vertex of a certain clipmap level in the VS (with possible geomorphing handled around that same spot). So, as the user moves around, as I understand it, the active levels will move with the camera to keep a consistent level of detail. But ,yeah, here are some shots from my experiments with the block orientations per level.

One of the things that I began wondering while I was trying to organize the basic geometry structure sprung out of the fact that I accidentally had Fraps running since I had just played Bioshock (it seemed to be the only screenshot utility capable of handling DirectX 10 apps). Here I was, rendering all of the clipmap levels in full at once in this program trying to see what the blocks looked like under my recently-implemented calculations, and Fraps was telling me that, with all of the polygons in view, I was getting about 120-200fps. Each of these blocks takes up varying amounts of world space, based on their vertex scaling, but every block regardless of scale contains about 7,800 triangles all sent to the GPU via a triangle list in Direct3D 10 (I'm running on a 640MB nVidia 8800GTS). Every clipmap level has, at least, twelve of these blocks which make it up -- and given the algorithm specifications, most levels will have additional geometry for detail with cracks and level differences along block edges. So, for every level, we're talking about 94,000 polygons, give or take. I have six levels right now, so for all but the finest level, that's a total of 470,000 polygons, and add in the poly-count for the finest level (which has sixteen blocks) and that raises the total polygon count per frame to about roughly 600,000 polygons -- and even taking the minimum framerate I was getting while running my demo with all these polygons in the scene (including my MD5 mesh), that adds up to about 71,135,600 MTris/second. I have a great deal of difficulties believing that I'm really sending 600,000 polygons per frame to my GPU and still getting a framerate in the 100+ range. I'm also currently doing one draw-call per blocks, so that's 76 instances of ID3D10Device::DrawIndexed per frame -- so this is, basically, completely unoptimized repeated renderings of a static vertex and index buffer.
These vertices are composed solely of two floating-point values, and the polygons are still, as of yet, untextured, so I can rely on the fact that numerous textures applied to this grid in whatever manner I end up using will slow things down a bit, but all of this still begs the question: why would I waste what should end up being two to three weeks in development (other than weekends I only end up getting one-to-two hours of development in depending on if there's a game I feel like playing any given night) implementing a terrain rendering algorithm if I could easily come up with an advancement to my tried-and-true geomipmapping algorithm that I could implement in a couple days. The quick answer to this is: well, there's really no need to. For me, this is just an exercise and, given my current tasks at my job, I need something complex to wrap my head around in my spare time. For most practical implementations, though, unless a particularly large dataset is necessary, I think I could come up with an algorithm with similar tech requirements as the geoclipmapping algorithm, but with a far more simplistic implementation; same concept of relying on vertex textures for height values for the grid, but with a more straightforward mesh structure.
When I wrote my book on the matter of terrain rendering, I was continually asked by friends of the developer persuasion "Why not just use a brute force method of rendering?" Back then, there was a compelling argument for clever management of the mesh for frustum culling reasons but that would be the extent of the implementation; and it's a good argument, and one that is even more true today with graphics cards that are exponentially better than the ones we had access to back in 2002. For game developers, I think the days of algorithms like geometry clipmapping and ROAM 2.0 are few and will be of use for only the most specialized of games. The complexity of an implementation of these algorithms simply does not warrant the results they will give.
This entry got a bit longer than I was expecting, so I'll cut it off for now.
| |
 Of Bioshock and MxM Blocks |
Posted - 8/28/2007 1:43:43 PM | Well, it's been a couple weeks, but I'm now fairly established in the new apartment and it's absolutely fantastic. Though, aside from the move, the main other reason for the lack updates has, of course, been Bioshock, which is far and away the best game I've played in recent months
The Bioshock thing brings me to my first point. I think that the one of the reasons that the game is as good as it is and is getting such a massive number of glowing reviews is that Bioshock has such a well-defined atmosphere. Sure, the graphics are great, the audio is fantastic, and the gameplay is good, but the thing that puts Bioshock ahead of the competition is that Irrational2k Boston has used the engine to really flesh out the world of Rapture. The stuck-in-time mood in Bioshock is handled well; the music that plays on jukeboxes and in bars throughout the game has a very 40's-50's scratchy record sound to it, the basic weapons are a six-shooter, a Tommy gun, and a big, bulky shotgun, the monitors throughout Rapture are all fuzzy black-and-white, and the list of things goes on. The atmosphere created in-game is, in my opinion, the reason for the game's critical success thus far.
Anyway, that was my little bit about Bioshock in, what I have no doubt is, a completely incomprehensible little paragraph. This is what happens when I try writing things in between build times.
As far as the progress on Rawr, things are going slowly -- I started up development again a couple days ago and have just been working on the framework for the terrain implementation that I started a couple weeks ago. Once I'm done with the terrain implementation, which I assume I will be able to make some very nice headway on over the course of the extended weekend, I think I'm going to resume work on some more framework-critical components; the terrain implementation is primarily a way to get a good visual representation of what a full scene should look like (as opposed to basing my visual results on nothing but an anorexic mesh). So far, this idea has already proven useful when I got the basic MxM vertex block rendering in-game (below); I realized that the reason my camera had been giving me such time had nothing to do with the actual camera code, but the fact that the model that I thought was positioned up-right was, in fact, titled 90 degrees along the X-plane. So, yeah, I went through four camera code iterations thinking that it wasn't handling FPS-like movement the way I wanted when, in fact, it was doing fine, my sense of orientation was just screwy. Yay.

| |
| Wednesday, August 15, 2007 |
 A First Step in a Terrain Rendering Implementation |
Posted - 8/15/2007 12:11:02 AM | My first real order of business once I returned from my weekend-long trip to the Michigan hinterlands where my permahouse resides was to start researching a decent terrain rendering algorithm for which my programming efforts would be focused upon for the next week or so. This was a process which I was firmly expecting to result in some sort of "bastard algorithm" based heavily on Thatcher Ulrich's Chunked LOD while drawing from my own experiences with ROAM 2.0 and Geomipmapping which I detailed in my article in Graphics Programming Methods. Much to my surprise, though, I had some well-respected graphics programming folks like ViLiO recommend Hugues Hoppe's research into terrain rendering with geometry clipmaps. The reason this is surprising to me is not because I felt Ulrich's Chunked LOD ideas were fantastic beyond improvement, though I did like his work, but I do feel it required a great deal of work just to implement and left a lot of room for improvement to get executed properly without much CPU intervention... But because I remember reading Hoppe's work into terrain rendering with geometry clipmaps back in his 1994 paper on the topic.
What I was not aware of was that Hoppe also wrote an absolutely fantastic article with Arul Asirvatham which discussed this same terrain rendering with a very heavy emphasis on practical use of the GPU using shader model 3.0 (namely, the use of vertex textures). After skimming this GPU Gems 2 article I was firmly convinced that I need to implement the algorithm as soon as I could get around to it. So, over the course of the last couple days I've read over the GPU Gems 2 article along with the original whitepaper upon which it was based several times each and also skimmed over the basic implementation done by FilouGK and I think I have come to pretty decent understanding of the algorithm.
One of the first things I usually do before undertaking any sort of non-trivial programming is to "sketch" (ie, write the code for) the class definition first. This is clearly a revolutionary first step, so take a moment to regain your composure at my genius.
But, yeah, I generally find that to be the only prerequisite for me when starting any project. I don't, as a rule, draw an excessive amount of pictures and diagram, I don't write pseudocode to detail the routines that I will, then, actually code, and I don't draw up unnecessary UML diagrams to detail how various data structures will interact with one another. Once I can look at a class definition and think "Yup," I just start coding and don't stop until I get something displaying on the screen which is, more or less, what I'm aiming for. Of course, that "first step" of getting things on the screen is far from a final product -- I program in a very incremental sort of process.
So, I apologize for the excessively dry nature of this dev journal entry. It has to do with a combination of my ridiculously tired state coupled with the fact that this is a journal entry was meant to lay the ground work for this terrain implementation which, I hope, will prove a decent tutorial on the topic as I go on. Anyhoo, here's the class definition as I have it so far.
class CTerrainNode : public ISceneNode
{
public:
~CTerrainNode( );
virtual HRESULT Create( CScene *pScene );
virtual void Release( );
HRESULT Init( CScene *pScene );
virtual HRESULT Update( float fTimestep );
virtual HRESULT Prerender( CScene *pScene );
virtual HRESULT Render( CScene *pScene );
virtual HRESULT Postrender( CScene *pScene );
void SetWorldViewProjMatrix( D3DXMATRIX matrixWorld );
protected:
CTerrainNode( );
private:
struct Clipmap
{
CTextureWrapper* m_pHeightMap;
CTextureWrapper* m_pNormalMap;
ID3D10EffectShaderResourceVariable* m_pHeightTextureVar;
ID3D10EffectShaderResourceVariable* m_pNormalTextureVar;
};
private:
Clipmap* m_pClipmaps;
D3DXVECTOR3 m_v3ViewerPos;
unsigned long m_ulLevels;
unsigned long m_ulGridSize;
unsigned long m_ulBlockVertexRes;
unsigned long m_ulBlockNumVertices;
unsigned long m_ulBlockNumTriangles;
unsigned long m_ulRingNumVertices;
unsigned long m_ulRingNumTriangles;
unsigned long m_ulTrimNumVertices;
unsigned long m_ulTrimNumTriangles;
unsigned long m_ulDTNumVertices;
unsigned long m_ulDTNumTriangles;
D3DXMATRIX m_matWorldViewProj;
D3DXVECTOR3 m_v3LightDir;
D3DXVECTOR4 m_v4FineTextureOrigin;
D3DXVECTOR2 m_v2AlphaOffset;
D3DXVECTOR4 m_v4ScaleFactor;
float m_fZScaleFactor;
float m_fOneOverWidth;
CInputDescWrapper* m_pInputLayout;
CVertexBufferWrapper* m_pBlockVB;
CVertexBufferWrapper* m_pRingVB[TERRAIN_LRING_COUNT];
CVertexBufferWrapper* m_pTrimVB;
CVertexBufferWrapper* m_pDegenerateTriVB;
CIndexBufferWrapper* m_pBlockIB;
CIndexBufferWrapper* m_pRingIB;
CTextureWrapper* m_pDiffuseTexture;
ID3D10Effect* m_pEffect;
ID3D10EffectTechnique* m_pRenderTechnique;
ID3D10EffectTechnique* m_pUpsampleTechnique;
ID3D10EffectTechnique* m_pNormalCalcTechnique;
ID3D10EffectMatrixVariable* m_pViewVariable;
ID3D10EffectMatrixVariable* m_pProjectionVariable;
ID3D10EffectMatrixVariable* m_pWorldViewProjVar;
ID3D10EffectVectorVariable* m_pViewerPositionVar;
ID3D10EffectVectorVariable* m_pLightDirVar;
ID3D10EffectVectorVariable* m_pFineTextureOriginVar;
ID3D10EffectVectorVariable* m_pAlphaOffsetVar;
ID3D10EffectVectorVariable* m_pScaleFactorVar;
ID3D10EffectScalarVariable* m_pZScaleFactorVar;
ID3D10EffectScalarVariable* m_pOneOverWidthVar;
static const LPCTSTR TERRAINNODE_INPUTLAYOUTWRAPPER_NAME;
static const LPCTSTR TERRAINNODE_BLOCK_VBWRAPPER_NAME;
static const LPCTSTR TERRAINNODE_RING_VBWRAPPER_NAME;
static const LPCTSTR TERRAINNODE_TRIM_VBWRAPPER_NAME;
static const LPCTSTR TERRAINNODE_DEGENTRI_VBWRAPPER_NAME;
static const LPCTSTR TERRAINNODE_BLOCK_IBWRAPPER_NAME;
static const LPCTSTR TERRAINNODE_RING_IBWRAPPER_NAME;
static const LPCTSTR TERRAINNODE_EFFECT_FILENAME;
static const LPCSTR TERRAINNODE_EFFECT_SHADERPROFILE;
static const unsigned long TERRAINNODE_GRIDSIZE_DEFAULT;
friend class CSceneNodeManager;
};
I probably won't be able to write another entry until Sunday or Monday, as I'm moving into a new apartment on Friday, so I'll pick this up again once I get settled.
| |
 . |
Posted - 8/10/2007 3:14:22 PM | Last night I got some more work done on this god forsaken camera class that I've been working on writing for Rawr. I'm sure, at this point, that there's something wonky going on outside of the actual calculations I've been writing for the Camera. I made this revelation and then, of course, kept tweaking away at it because I like to get things as close to perfect as I can before moving on. Finally, as 1:00am approached, I decided just to hack the camera into proper working order so I could continue work on something new (either a shader postprocessor system or a terrain using geometry clipmaps implementation) when I get back on Sunday night.
At work yesterday I was working on a bunch of tweaks (I'll be very glad when I can actually start discussing some of the things I'm doing for this game) for some stuff. It was not, as I'd like to think, challenging work. So since my brain wasn't required to be at full algorithm-writing capacity, I thought I'd listen to some of the ShackNews ShackCasts, since I absolutely love the site and I think that the Shacknews staff is comprised of some of the most talented journalists I've found as far as gaming journalism is concerned. I had never listened to a podcast before, so this was all new ground for me, but after listening to the four episodes they have available (which took me well over seven hours to do), I was enthralled. They were entertaining, informative, and generally just good listening.
Now, of course, I really want to be involved in an actual podcast. I know I could easily talk about games for days upon days at a time. As a game developer, I actually, in a way, pride myself on the fact that despite the immersion to which I am engufled in on an daily basis for a work I still manage to be a very active "gamer." I think developers tend to lose sight of what's important when game development becomes just a job -- something very understandable, as the job is an all-encompassing one -- rather than a paid way to work on an aspect of the entertainment industry that, for me, defined a great deal of my childhood. I had no plans on how to actually end this spiel. TL;DR - I want to do a podcast about gaming/development real, real bad.
Here's Boney from his new, upright, hackish angle.

| |
| Wednesday, August 8, 2007 |
 A New Angle |
Posted - 8/8/2007 11:58:54 PM | With last night's changes to the Win32 mouse handling code working surprisingly well -- other than the fact that, for some reason, decrementing ::ShowCursor until 0 does not seem to be doing a lick to actually hide the cursor (which is a very low priority to get working) -- I went back to my ripped off DXUT camera code to rewrite that so I could get a well-working free-fly FPS camera well in order early in the framework development. I figured it'd be the sort of thing that would be helpful. Or something. I got through most of it, but I ran into difficulties near the end. Everything seems to be working as one might hope a first-person camera with no real sense of boundaries (it's basically a sixteen-year-old girl, as cameras are wont to be) but there was a bit of an issue with the yaw-based rotations not quite, uh, rotating like they should be. I wfigure it'll either take a bit of tweaking or a total rewrite -- it could go either way at this point.
Which brings me to my other pointvertex. I decided the other day that I'd really like like to brush up on my multivar calculus, 3D theory, and the math behind all such things. I took Linear Algebra this past semester with the goal of getting a good handle on that flavor of calculation, but I ended up in a class centered entirely around the ability to write proofs to demonstrate the knowledge of the subject -- there was, at most, about five-ten minutes spent on the practices involved and then from there on out it was a memorization process integrated with the ability to write decent proofs (which is a technique I learned more about in Discrete Math than anything else, really). So, back on topic, I picked up Mathematics for 3D Game Programming and Computer Graphics with the putting-into-practice of this goal in mind. It arrived today and, thumbing through it, the books seems surprisingly well-done. I was expecting a volume filled with list-after-list of unreadable equations written using some sort of mathematical notation that I haven't seen outside the serendipitous scrawls of a drunken three-year-old. But, come the moving-in of my new apartment in a couple weeks, I think I'll make it a point to study this, along with some more linear algebra and calc 3, a little bit every couple days.
That's how much of a nerd I am. Here's Boney from a new, non-yawed, angle.

| |
 Still With the Every Dev-Day Thing |
Posted - 8/7/2007 11:12:49 PM | I'm still going with the dev journal entry for every day of actual development I do on this little project affectionately titled Rawr. Today was a sad day. Why was today a sad day, you may ask. Well, today was a sad day because I spent three hours struggling with that goddamn mouse. At first, the goal was to capture the mouse/stylus for the window (::SetCapture( HWND )), because it seemed like the right way to go about dealing with continuous movement. The beginning of this capture was set off whenever the left mouse button was held down and then released whenever the left mouse button was caught in a non-down state.
If you've ever actually tried organizing this inside of a message handler in the scheme of what seems like a "Good Design," then I'm sure you understand the problem here. The problem being that, at least in my case, the actual code which processed (relied on, dealt with, so on) was not, in fact, in the message handler. So there was this flood of input being gathered and the app had nothing much to do with it. It was around this point, which took far longer than it really should have to arrive at, that I realized I might have to violate the original design a bit to include some functionality for capturing the mouse in a window and holding the cursor to the center of the screen. I ended up with a "fake capture" -- so I'll still send the framework-wide flag that the mouse had been captured and various components could do their thing, the cursor graphic would be hidden by the OS, and the cursor position would continually be set to the center of the window after I nabbed the delta position from the frame prior.
I know I've done all this stuff before. At least, I think I have. In retrospect, I may have just looked at example programs and thought "Oh. Hey. This works. I'll just liberate this snippet." Such a course of action is, of course, not acceptable under my current coding laws for Rawr.
None of this stuff makes for a good screenshot and the camera code I'm working on isn't to the point where I can actually move around a scene in a "correct" free-fly first-person camera fashion, so here's a comparison shot between an MD5 mesh from DOOM 3 being lit by vertex normals (on the left) and by a normal map (on the non-left):

| |
 Struggles With Mice |
Posted - 8/6/2007 10:36:03 PM | I vaguely remember the last time I wrote my own demo framework entirely from scratch -- as in, I didn't base things off of old code, I didn't code off a third-party engine/framework, and I didn't just base a program on a skeleton template for simplistic. The memory based in such conditions is one wrought with sadness, pain, and, uh, more sadness. Sadness squared is probably a good way of putting it.
But this time, since I figured I'll start having a great deal more free-time on week nights and weekends, I figure that if I'm going to start nestling in for a long year's hobby development that I sure as hell better have a good framework. And, so far, this idea has been treating me well. As I said in one of yesterday's trio of posts, the last few days I've been working on replacing all of the DXUT functionality that I have come to rely on. This, too, has been treating me well. And then I finally bit the bullet and wrote the mouse input and camera code (my lease favorite things I've had to write so far). Writing a camera is actually kind of fun so long as you have well-working input routines and the rest of your framework isn't straight out of the womb. But writing a decent camera with mouse code that you haven't properly tweaked to work well within a window, what with capturing and such, is the opposite of fun. The antifun. The thing that sheeps hear and run away ba-ba-ba-ing in pain and agony kind of antifun.
I did, though, manage to get the stuff working to the point where I could, with a bit of difficulty, move up from zombiegroin to see Boney's normal-mapped face:

So that's that. I'm also not entirely sure about the overall design of the Input class. At the time it seemed like a good idea, since it was something that actually screamed for program-wide instance. But I know people like Josh and Washu lash out against singletons. So this was my horrible idea for a class design:
class CWin32Input
{
public:
static void Activate( );
static void Deactivate( );
static void HandleKeyboardMessage( UINT uiMsg, WPARAM wParam, LPARAM lParam );
static inline bool IsKeyboardActive( ) { return( m_bActiveKeyboard ); }
static inline bool IsKeyDown( long lChar ) { return( m_bKeyboardState[lChar] ); }
static inline bool IsKeyUp( long lChar ) { return( !m_bKeyboardState[lChar] ); }
static void SetKeyState( long lChar, bool isKeyDown );
static inline bool IsMouseActive( ) { return( m_bActiveMouse ); }
static void SetMouseClip( bool bClip, long lLeft = -1, long lTop = -1, long lRight = -1, long lBottom = -1 );
static void SetMouseButtonState( unsigned long ulMouseButton, bool isButtonDown );
static void SetMousePos( LPARAM lParam );
static void SetMouseWheel( WPARAM wParam );
static void HoldMouse( bool bHold, bool bHideCursor = false );
static inline void GetMousePos( long &x, long &y ) { x = m_lMousePosX; y = m_lMousePosY; }
static inline void GetMouseDelta( long &dx, long &dy ) { dx = m_lMouseDeltaX; dy = m_lMouseDeltaY; }
static bool IsMouseButtonDown( long lButton );
static bool IsMouseButtonUp( long lButton );
private:
CWin32Input( );
~CWin32Input( );
private:
static bool m_bKeyboardState[WIN32INPUT_NUM_KEYBOARD_STATES];
static long m_lKeyModifiers;
static bool m_bActiveKeyboard;
static bool m_bMouseButtonState[MOUSE_BUTTON_COUNT];
static long m_lMousePosX, m_lMousePosY;
static long m_lMousePosXPrev, m_lMousePosYPrev;
static long m_lMouseDeltaX, m_lMouseDeltaY;
static long m_lMouseWheelDelta;
static bool m_bActiveMouse;
static RECT m_rectMouseClip;
static bool m_bClipMouse;
};
I'm very willing to change this, as it's getting fairly unwieldy in practice, but I need good reason to motivate my need-for-a-rewrite brain portions.
| |
 The Beginnings of the Rawr Framework |
Posted - 8/5/2007 9:32:27 PM | On Friday night I made the decision that I would stop using the DXUT routines for my little Direct3D 10 sandbox that was beginning to evolve into a legitimate code toolset for me. And any legitimate code toolset -- well, even a lot of the illegitimate code bases -- does not touch DXUT with a ten-foot electrified pole. DXUT is like an e-mail from an a spammer claiming to be an ex-girlfriend which, upon opening of this byteified letter, actually gives you, the user, a sexually transmitted disease.
Anyway, it took a couple of days, but I coded up and rewrote sections of the code base which I had been working off of lately. As of now, on Sunday night, I am a tweaked camera-class away from being exactly where I was on Thursday. So whoo. It's called Rawr (a name spawned from Drilian's fantastic suggestion). And this is the first thing I was greeted with after I finished a draft of the camera class (greatly influenced by the DXUT first-person class).

Did I mention that I can't manipulate any aspect of the camera yet for some reason? Because I can't. So thanks for the visuals, id. I hate you.
| |
 On Direct3D10 vs. Direct3D9 |
Posted - 8/5/2007 2:53:12 PM | Confused Direct3D 10 Menfolks.
So, I've seen a whole bunch of posts railing against Direct3D 10 - specifically in regards with skepticism to the difference in visual quality between DirectX 9 and DirectX 10. So here's a bit of information from what little tidbits I've gathered here and there in my little Direct3D 10 experiments.
First of all, I believe John Carmack is completely correct when he believes that the potential in Direct3D 9 has yet to be maxed out. Also, I believe that the current belief amongst developers is that there is, at this point in time, very little Direct3D 10 can do that Direct3d 9 can not do. I fully believe that the kinds of DirectX 10-only features that you'll be seeing in games like Company of Heroes, World in Conflict, Crysis, Hellgate: London, and other games are completely do-able in Direct3D 9.
This all said, Direct3D 10 is an API that has been completely overhauled from its predecessor. As a developer, it is taking me a bit more time than I'd care to admit to adapt the syntactical differences present in the DirectX 10 SDK. The TL;DR version of the differences between the two APIs are as follows: DirectX 10 has, for all intents and purposes, completely ditches the fixed-function pipeline. In lay man's terms, this means that Shaders Are King. Instead of having a fairly strict graphic pipeline (think a "one size fits all" approach to graphics rendering), things are now completely programmable. A slightly inaccurate, though simplistic, look at things is that geometry first goes through a Vertex Shader (which performs operations on a per-vertex basis), then through a Geometry Shader (a DirectX 10/Shader Model 4.0 exclusive feature) which performs operations on a polygon/triangle level. Then, the data is rasterized to a pixel form where Pixel Shader performs its operations (things like bloom, depth of field, blurring are done here). After those major three steps, you see the result on your monitor. With Direct3D 10 (and, to a lesser and not guaranteed extent, Direct3D 9) the developer has complete control over what occurs during these steps, as opposed to it being dictated by the API.
Another couple important consideration is that, with D3D10, the graphics device is viewed as a shared system resource -- Direct3D does not have a monopoly over its use. The best example of this point is the Windows Vista Aero theme, which relies on DirectX for its rendering. When you launch a game, you may see the game disable the "pretty Aero" (because it has that capability) through the duration of its lifetime; when the game ends, the "pretty Aero" will pop back up, and this all occurs through the API. The game isn't doing anything dirty like modifying your OS settings or anything.
My personal favorite feature of Direct3D 10, though, is that there is a guaranteed set of functionality which the programmer can exploit so long as the end user's computer is capable of using D3D10. With previous versions of Direct3D, the programmer had to query various aspects of the graphics card through the D3DCAPS system. The CAPS system would tell the developer if, say, the graphics card supported dynamic textures, if it could create shareable resources, if it could automatically generate mipmaps, and so on. It was a pain in the ass. With D3D10, though, there's always that guaranteed layer of functionality.
So, basically, while the difference in visual quality difference between DirectX 9 and DirectX 10 may be near-nothing right now -- and I believe that the games which heavily market the differences in their 9/10 renderers is pure hypespeak -- the point to remember is that D3D10 is an overhauled API from DX9 for a reason. This reason is that it brings a far more powerful, safe, and guaranteed set of features to the developer for the developer to go nuts with.
Carmacks Quakecon 2007 Keynote: http://www.quakeunity.com/file=2513
For More: An Overview of Microsoft's Direct3D 10 API.
| |
 Meet Boney. He's from DOOM. |
Posted - 8/5/2007 10:50:44 AM | I'm going to start a new sort of idea for my dev journal. Whenever I can do it, I'm just going to post a screenshot, do a bit of a write-up of its significance in the scheme of things, and then so on. I'll try this for a couple weeks unless I find that it's not nearly as fun an idea as I had envisioned.

So, this is Boney from DOOM 3. Which means I got the MD5 Mesh Loader working in a non-animated capacity. As you can see from the evolution, there was a bit of trouble getting the vertex position correctly calculated (joints, weights, and such). But it got done.
| |
The entries in this journal have all been posted, along with many more, at mittens' personal site at www.polycat.net.
|
| S | M | T | W | T | F | S | | | | 1 | 2 | 3 | 4 | | | | | 9 | | 11 | 12 | 13 | | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | | 29 | | | |
OPTIONS
Track this Journal
ARCHIVES
August, 2009
July, 2009
June, 2009
May, 2009
April, 2009
March, 2009
February, 2009
January, 2009
December, 2008
November, 2008
October, 2008
September, 2008
August, 2008
July, 2008
June, 2008
May, 2008
April, 2008
March, 2008
February, 2008
January, 2008
December, 2007
November, 2007
September, 2007
August, 2007
July, 2007
December, 2006
July, 2006
June, 2006
May, 2006
April, 2006
March, 2006
February, 2006
January, 2006
November, 2005
September, 2005
August, 2005
July, 2005
|