I didn't want to knock the bugs clearing house off the top of the page for a while, so hence the lack of recent updates.

The D3D11 port is now fully up to the old speeds and considerably exceeding them in heavier scenes. Functionally it's nearing completion; fog, coronas and player model colourmapping are left and I think that's more or less it.
I've already taken multiple passes over various parts of the code and cleaned things up a lot, tuned for better performance, quality and stability, and generally improved the whole thing. There are still some outstanding bugs and glitches with various parts of the core code which will need further work before I consider it "done", and then on to future work. I'll talk about that later on, today is for the renderer.
Brush surfaces now share a 100% common code path for absolutely everything (aside from some initial setup). I had made some strides towards that in previous versions and achieved it quite recently. This has resulted in an absolutely huge code reduction - my "d3d_brush.cpp" is down to 535 lines (from 956) with the first 368 of those being loading and object creation. This is a theme I've noticed throughout my use of D3D11 - loading and creating stuff takes a larger amount of code, but actually drawing is a substantial reduction.
Being able to drop the software T&L fallbacks helped a lot here, but the big win has been from treating everything as a texture chain. That doesn't actually need D3D11 but having it certainly helps as it's a much cleaner and tighter API for the actual drawing stuff.
Lightmaps have gone through a few evolutions, with a very early stage (in the experimental engine) being entirely on the GPU, before I decided to push creation and modification back to the CPU for the real port. There are about 3 or 4 different ways to update a lightmap texture, and in the end I went for the one that all the hardware vendors advise is the slowest (UpdateSubresource) - simply because for the Quake lightmap use case it benchmarked as the fastest on all hardware.
I believe that this is because the UpdateSubresource call will manage resource contention automatically for you, attempting to do an asynchronous transfer whereever possible (one of the reasons why D3D doesn't have any equivalent of OpenGL's PBOs is because it doesn't need one), which is where the real bottleneck in Quake lightmaps is. This renderer may not even need GPU lightmaps.
Earlier on I successfully multithreaded the lightmap update, but I've since removed it as it wasn't a performance win and had started piling up complexity. I'd still like to exploit multithreading some in the renderer - especially because D3D11 makes it so easy - but I haven't yet found any case where the tradeoffs are worth it.
Particles are hybrid CPU/GPU. All the info needed to draw and position a particle (set at it's spawn time and never changed) is written into a dynamic vertex buffer at draw time, then velocity and gravity are applied on the GPU and the point is expanded to a quad in a geometry shader. This is something I've longed to do ever since the first implementation of DirectQ in D3D9, and you can see evolutions of the code working around it and trying to emulated it in older sources.
Sprites and the 2D GUI stuff also use geometry shaders, as will coronas.
The underwater warp was most recently done and is quite cool. D3D11 seems to be more fillrate-efficient for render to texture than 9 was, and having none of the BeginScene/EndScene crap (as well as completely generalizing the texture/render target interfaces) makes things a lot cleaner. Otherwise it should look and work much the same way as the old one.
The next steps involve continuing to tune, tweak, and bring on missing functionality.
Aside from that, and following my recent hardware failure, I'm now on AMD graphics for a short while. That's a barrel of laughs - I know that they have a reputation as the "enthusiast's choice" but if being an "enthusiast" means having to constantly struggle with drivers, settings, reinstallations, random weirdnesses, downloading dodgy overclocked drivers from Joe Random on the internet, etc, then I'd rather opt out, ta very much. I think I've spent more time at this stuff than at actually being productive in recent days, and I'm looking forward to getting back to NVIDIA as soon as possible.
Tuesday, February 28, 2012
IN YER FACE!
Posted by
mhquake
at
8:51 PM
5
comments
Tuesday, February 21, 2012
DirectQ 1.9.0 Bugs Clearing House
Just to keep everything together, please post all bugs found with DirectQ 1.9.0 here. If you've already posted on the release comments there's no need to post again; I can pick it up from there. All new bugs should go here.
So far the following have been addressed. If your bug is not on this list it doesn't mean that I'm ignoring it or that I'm refusing to fix it - just that I haven't gotten around to it yet.
Nehahra crash in certain maps
Caused by an assumption in the light code that all static entities would be MDLs. Of course it's possible to have a brush or sprite model as a static entity. Fixed.
Wizard and Knight particle trails display incorrectly
Sigh - I really should have finished that code before releasing it.
oggs can possibly crash/bluescreen and/or play funny
Possibly a codec-related issue; DirectQ just uses whatever codecs are installed on your PC and if you have a codec that's not 100% compatible with DirectSound then Bad Things might happen. As a precaution, music playback is now limited to WAV, MP3 or WMA formats (using the preinstalled codecs). May revisit this.
Buffer read overrun if a map sends a texture with 0 width or height
Nehahra does this. It seemed reasonably benign but it's been fixed anyway.
Some external textures (e.g. mapshots, IQM skins) not loading
External textures off the root gamedir path (i.e. without an explicitly set path) were skipped over by the texture loader because the same condition was used for not bothering to search a directory for BSP textures. Changed condition to something more robust, confirmed fixed (also fixes reported "Saved games no longer display their respective image" bug).
Geometry flickering on quicksave
Can't reproduce this one. Added a safeguard that I think should help prevent it.
Screenshots not working
Can't reproduce this one. Added a safeguard that I think should help prevent it. Removed scr_screenshot_jpeg and scr_screenshot_png cvars as they never worked right, messed things up, and can be handled via scr_screenshotformat anyway.
Posted by
mhquake
at
12:18 AM
32
comments
Monday, February 20, 2012
Even more D3D11
As is by now customary for a DirectQ milestone, here's the Marcher Fortress.

IQMs were done, and they were a sheer pleasure. Finally being able to write directly into constant buffers was awesome, and the performance is extremely good.
Lightmaps are now in a texture array, meaning that a single bind of the lightmap array texture is all that's needed, and everything else gets batched up solely by texture. This has been extremely good for performance - a lot of tedious crap and shuffling through intermediate structures Just Went Away, and I'm now blasting surfaces out with considerably fewer draw calls.
Right now I'm using triangle strips with primitive restart indexes. Previous experience indicates that these are actually slower than fully indexed triangle lists; presumably there is a certain amount of extra triangle setup that the driver and/or hardware has to do with strips but which is already done with lists. I'm going to switch it over to lists and we'll find out. I'm also using the default BSP back-to-front ordering, so changing that to front-to-back will improve things again.
Performance-wise it's slower than before in lighter scenes, but faster in heavier ones; sometimes much faster. I think that's a pretty fair tradeoff, and it indicates that there is some extra to be gained, which is nice.
Overall it's awesome being on an API base where you know that you have certain guaranteed minimum capabilities and you don't have to compromise things for downlevel hardware or write alternate code paths.
Posted by
mhquake
at
9:46 PM
1 comments
More Progress

As you can probably guess, performance isn't fully up to the old DirectQ standards here. I'm doing a fairly rough porting job to begin with - focussing on getting it working rather than making it fast. When the first pass is done I'll work over everything and bring performance up.
Posted by
mhquake
at
6:33 AM
0
comments
Coming on Quite Well

As expected, DirectQ 1.9.0 released with some bugs, so a Release 1.9.1 will be forthcoming shortly. Work is still focussing on the D3D11 port, so the feature list for the 1.9.x series is frozen and it's to be considered in maintenance mode only.
One serious one is in relation to music playback. Previously I've supported any format so long as you have a WMP-compatible codec for it; however it appears as though some codecs are not entirely compatible with DirectShow, causing minor havoc. As a result of this I'm going to roll back format support to MP3, WAV and WMA only. The bottom line is that while I can attempt to ensure the stability of DirectQ itself, I can do absolutely nothing about the stability or quality of codecs on someone's PC. All it takes is one bad codec to cause trouble, so this is a clear case where the alternative is worse. With the more restricted formats I can at least have a reasonable certainty that things will work. In the Wild West of codecland however, I can't.
Posted by
mhquake
at
1:54 AM
2
comments
Sunday, February 19, 2012
D3D11 Porting
The hardest part of any port is right at the beginning. You're ripping apart old code, shoving in new code, and hoping and praying that the two are going to coexist peacefully. You have just so much to do before you can even get some kind of image on the screen that confirms that things are at least working. Those first scary few hours when you get the fear - "am I completely insane to be even thinking about doing this?" - are the worst by far.
Once video startup is done, 2D drawing is always the next thing I pick on because it's simple. There are just two main routines you need to do - Draw_Pic and Draw_Character. You can get away with an ultra-simple texture loader that needn't handle mipmaps or other special cases. Transforms and states needed are simple. There's no dynamic texture updating to fret over. Easy as pie, and at this stage the less you have to worry about the better.
After that I like to move on to the world. It's slightly more complex and involved, but it gives a solid background to build everything else on. So that's where I am right now.

Yes, it's ugly, yes, there is a lot of stuff missing still, but it's an image on the screen that is in line with what I expected, and that's important.
Posted by
mhquake
at
5:04 PM
0
comments
Saturday, February 18, 2012
Saturday 18th February 2012 - the Great D3D11 Move Begins
Now that DirectQ 1.9.0 is out I'm commencing the work on moving the engine to D3D11. Initially this will just consist of some minor tweaks and shuffling stuff around so that things later on will be easier, then I'll be diving head-first into gutting the D3D9 code and replacing it.
So far what I've got done is to bump the version number, rework the renderer so that the engine can run without crashing if a D3D9 Device hasn't been created, and included the D3D11 headers and libs. I've also moved over my D3D11 shutdown code (it doesn't do anything because no D3D11 objects exist yet, but the fact that it's there in the live codebase is good).
That's small beans but it's significant as it means that I can coexist the new code with the old and do a more incremental transition. Of course, anything that depends on the D3D9 renderer just won't draw at all with this setup, but that's infinitely preferable to having to gut absolutely everything before I can move.
The next step is to do video startup and then a minimally functional texture loader. Once they're in place I can do 2D drawing, which will give me a solid baseline to work from.
When porting GLQuake to D3D11 I managed to get the bare minimum done in 3 or 4 days. I expect that this will need a good bit longer, particularly as DirectQ has a lot of extras that I didn't bother doing in the GLQuake port - stuff like external textures, IQMs, additional options, for example. But the initial objective is to get a functional baseline Quake renderer and build from there.
Posted by
mhquake
at
6:05 PM
0
comments
Thursday, February 16, 2012
Awesome Particles of Awesomeness
Real Life caught up with me a bit today so I didn't get to spend much time writing up the next major D3D11 feature I wanted to talk about, which is lightmaps. The executive summary is that I'm maybe 90% certain that at least the first version is going to retain traditional Quake-style lightmapping, rather than doing GPU lightmaps.
I've been experimenting quite some with different ways of handling lightmaps for this engine, and at the moment it's looking as though GPU lightmaps are going to prove unsuitable for use in a general-purpose Quake engine (RMQ has different requirements where the advantages of using them outweigh the disadvantages).
It's probably worth spending some more time talking about this, and the various reasons and thought processes behind it, but that's for another day. Maybe when I begin work on that part of DirectQ's renderer.
Meantime I've been porting the rest of the particle system to the GPU in my experimental engine. I'm going to have an end result that I can pretty much just lift over to DirectQ when done (that's one of the reasons for this; much of the D3D11 renderer already exists and has been well tested).
Roundabout all that's left to do is pointfiles and the colour-mapped explosion. I actually want to change pointfiles to lines rather than particles, as they're quite a bit clearer and easier to see where the trail is actually leading to. I'll probably end up doing some vertex texture fetch for the colour mapped explosion; not totally certain yet so watch this space.
The performance characteristics of this are interesting. Trails turned out to need quite a lot of Draw calls, but what's neat about D3D11 is that Draw calls are incredibly cheap, requiring only 10% of the overhead that D3D9 imposes. At the same time, it's an excuse to experiment some with instancing in order to address this. (Being on a platform where you know that something like instancing is always going to be available and you don't need to worry about writing fallbacks or general case code for downlevel hardware is incredibly liberating.)
All going well the DirectQ 1.9.0 release should happen over the weekend. It was going to be tomorrow but I have a last-minute feature request which I think is worth doing, so I'm holding off on account of this.
Posted by
mhquake
at
1:06 AM
2
comments
Wednesday, February 15, 2012
More GPU Particles
For giggles, I ported my GPU particles code to my experimental D3D11 engine and did a full geometry shader implementation of explosions. This was fun, fast enough to do, and gives me definite confirmation that it's going to work. I also now have a fairly generic implementation of a GPU-based "particle effects" system that can handle almost all other particle types (with the exception of rockettrails which will need some special handling).
So here it is.

If you're thinking "huh, nothing special there, looks more or less like regular particles to me" then it means I've succeeded.
Just to establish exactly what we're looking at here.
This is D3D11, yes. It's currently slower (DirectQ can hit 960 fps in the same scene) because the engine is a relatively straightforward port of GLQuake and lacks most of DirectQ's optimization work. I've also deliberately chosen some slower codepaths for some parts of it as a means of experimentation.
Every single explosion particle you see here is entirely on the GPU. No single particle comes from the CPU. They're all stored in a static vertex buffer as points, expanded to quads in a geometry shader, and the "dot" image is procedurally generated in a pixel shader.
For each explosion (comprising 1024 particles) a few shader constants need to be set: the origin of the explosion, some elapsed times, and a gravity factor. That's the only dynamic data coming from the CPU.
To prevent all explosions from looking the same I generate 2048 points at startup and randomize a start vertex between 0 and 1023, then draw the 1024 points after that.
The other particles you can see here (the smoke trails) are still done the old way, but in a D3D11 style - written to a dynamic vertex buffer as individual points, then expanded to quads in a geometry shader (which just happens to be the same one as is used for the explosions) and procedurally textured (also by the same pixel shader). Smoke trails, incidentally, have a heavy framerate dependency which causes them to bog down the engine badly as speeds get higher. This is already resolved in both DirectQ and RMQ, but I haven't bothered with this engine.
Tomorrow I'll talk some more about plans for the D3D11 port of DirectQ.
Posted by
mhquake
at
2:11 AM
0
comments
Tuesday, February 14, 2012
DirectQ 1.9.0 - Status
I'm still seeing myself as on track for a release later on this week. As previously indicated, this will be the final Direct3D 9 release of DirectQ, at least so far as major versions are concerned. I'll probably fork the code immediately and continue to maintain this version for a short while afterwards in order to deal with any late-breaking bugs, but the future of DirectQ is moving to D3D11.
New features you can expect in this one include IQM support, dynamic lights on moving brush models (incl. BSP models), rewritten video startup (incl. refresh rate support), a new texture loader (incl. textures/mapname support), some GPU particles (EF_BRIGHTFIELD only), BSP2 support, more robust client-side effect handling, etc.
Bugfixes include the dreaded clipping bug, the dreaded startup crash, and alpha brush models now being sorted correctly.
A lot of code has changed behind the scenes, partially to prepare the way for the D3D11 move and partially to clean up certain annoying parts of the original codebase. In order to ease this a few things ended up being removed, so - in case one of these was your favourite feature - it's worth saying a bit about the main ones.
The enhanced particle system went most recently. I've done a certain amount of work on bringing particles on to where I want them to be, and this was just clogging things up. It will be coming back post-D3D11.
Software quake mipmapping went. This is not gl_texturemode - you can still get your chunky pixels. Instead it was a mode which only used the top 4 mip levels of each texture, and didn't mipmap liquid textures. That will also be coming back.
Kurok support went. I believe that Kurok is better served by it's own engine and it will be most likely staying gone.
The ability to load textures out of any path went; I now only support /textures and the other standard paths. A large part of the motivation for this was wanting to support Tenebrae content in /override, but as of now this will be staying gone.
The shape of the D3D11 move is starting to come together nicely, so I'll probably write some about what it's most likely going to look like later on. You have been warned.
Posted by
mhquake
at
9:29 PM
0
comments
GPU Particles
The explosion particles here are coming from a static vertex buffer and are fully animated and updated on the GPU. They're substantially faster than CPU particles and - despite being currently uncoloured - suffer no other tradeoffs.

Unfortunately there's only so far this can go without making use of a geometry shader and vertex texture fetch. Yes, it is possible without these, but it would incur some extra overhead that would wipe out the gains.
In other words a full implementation will need to wait until I move to D3D11, but it's still nice to get this much done by way of a proof of concept.
What this means is that I'm now at the stage where I'm really just fooling around with the engine rather than actually doing anything of any significant importance, and that in turn means that things are warming up for release. Can I say this week? Maybe, maybe.
Posted by
mhquake
at
1:26 AM
5
comments
Wednesday, February 8, 2012
DirectQ Update - 7th February 2012
Worked over the texture loader some today. I've added support for textures loaded from directories called the same as the value(s) of the "wad" worldspawn key (with multiwad support). This is in addition to, not instead of, the "textures/mapname/" convention, so now I support both.
I also added support for the QRP standard (i.e a "_bolt", "_cable", etc suffix on the texture name) in addition to "textures/mapname/".
Two things concern me about supporting all of these external texture paths. One is that the code would turn into a horrendous mess (which the old version had done), but that's now irrelevant as the new code has turned out quite flexible and elegant. Two is the time taken to find external texture files, and is worth talking about some more.
Since I support 7 different image formats, and since I now support two naming conventions and three directory conventions, that all adds up to a huge amount of looking for files each time I go to load a texture. The worst case is when you have no files - it must still look for all of them before it can establish that for real.
That was one of the motivations behind my old texture loader - caching the names of image files on startup so a quick scan through the list could confirm whether or not they existed (rather than attempting to open a file and seeing if it failed).
My new solution involves checking the texture paths that I'm loading from to see if the paths exist, then not bothering to look for textures in any path that doesn't exist. This is a one-time per map operation and is over and done with quite quickly. If you're running with native textures (none of the paths exist) then there is no further overhead - it won't even look for textures to load. If any path exists then it does look in that path for every texture, but that's OK - if you have one external texture then you probably have a full set, so it's what you want to happen. In any event, the overhead of loading an external texture is going to be significantly higher than that of doing the search, so things work out well.
A few other useful things got accomplished.
Beams and Temporary Entities have been worked over and made much cleaner. I guess that I had something of an aversion to using STL when I first moved the engine to C++, but in reality it's OK, and the beam and temp ent lists are now std::vector types. This means that they work in a similar way to the original engine, but without the stupid maximums.
I tracked down the cause of the "static entities in the wrong place" bug in certain RMQ maps. It turned out to be protocol-related - because of the old +/- 4096 map size limit some entity placements wrapped. Setting the correct protocol before running an RMQ map resolves it (DirectQ uses the FitzQuake protocol - which still has this limit - by default), so I need to find some way of determining if the current mod is RMQ and do this automatically.
I also worked over a lot of things relating to client-side dynamic effects (particles and dynamic lights), make much of their behaviour framerate-independent (and user configurable) and killed some more bugs with them.
For doing this I needed to select a framerate for these effects to be simulated at, and I ended up choosing 36 fps as my default (it can be changed via the cl_effectrate cvar). The reason for this is that I have very high doubts if Quake was ever originally tested at the kind of stupidly high framerates DirectQ can get, let alone the default maximum of 72 fps. Really weird things start to happen with these effects at high framerates, including colossal multitudes of particles being spawned, dynamic lights being needlessly updated every frame, odd flickering effects, and so on. It's quite obvious that they were tuned for stability at a much lower rate, so I've put them at what I feel is reasonable.
A nice side effect of this is that I've gained the ability to not bother updating dynamic lighting on a surface if it's not changed since last time it was updated. In practical terms that's not a huge performance gain, but it's good to have and certainly feels right.
I'm also restoring XBox 360 controller support (coded but currently untested) and view pitch drifting (done: I found the bug that caused me to remove it).
Overall the engine is now starting to settle down really well. I'm happy that I decided to take on the main thing that was holding me back from releasing it (the texture loader) a few weeks ago, and I think that it's going to be a much higher quality release in several important respects as a result of that.
Posted by
mhquake
at
1:24 AM
5
comments
Sunday, February 5, 2012
Updates - 4th February 2012
RMQ got GPU animation of IQMs today; it turned out to be hugely simpler than I had originally thought it would be and as a nice bonus it has seamless CPU fallback if the hardware capabilities don't meet the requirements of each individual IQM. Of course this means that the slower case will run on the slower processor, which is generally not what you want, but in this case it's no worse off than we were before.
Fixed a long long long long standing crasher in DirectQ which I suspect is at the root cause of a number of reports I had from folks about it crashing during startup. I was never able to reproduce it at the time, but - while fooling around with the awesome Retro Blazer (highly recommended), and thinking "I wonder if DirectQ can run this?" (it can't) - I got a useful clue to it.
It turns out that I was using a temporary memory pool for caching pointers to names of maps, demos and MP3s so that I could build lists of them for autocompletion and use in the menus, but in at least one case - maps - if (and only if) a map was in a PK3 file, I would go scribble all over that memory while extracting the map to read some info from it and validate that it had an info_player_start. Once that was done I freed some memory that was being pointed to by an entry in the temporary list, but of course - because I had subsequently written all over the memory - the pointer was no longer valid, so it crashed when freeing.
The solution was simple enough - just copy out the list of pointers to somewhere else after the list has been built, and put responsibility on the calling function to free the memory used by that "somewhere else".
I also changed PK3 file handling to not use this temp memory pool so that the whole thing is now a lot safer.
Wow.
If anyone who had such a crasher is reading this, could they confirm if they have any PK3 files with maps, demos or MP3s in them, and - if they temporarily remove those PK3 files from their game directory - does the crash go away?
Posted by
mhquake
at
2:05 AM
4
comments
Friday, February 3, 2012
Of Buffers and Buffoonery
Seems that for the past year and a half I have been reading from a dynamic vertex buffer created with D3DUSAGE_WRITEONLY. Ouch.
What's amazing is that this actually worked. What's even more amazing is that it never seemed to impact performance overmuch. What's most amazing of all is that it never showed up in debug runtime or PIX analysis.
I finally managed to catch it when consolidating some code shared between MDLs and IQMs but that's something that should really have been red-flagged a long time ago. How about the very first time I did it way back in time? Sounds about right.
Ahh, the dangers of abstracting things to too high a level...
Posted by
mhquake
at
5:10 PM
0
comments
Update - 2nd February 2012
A quiet day with not too much done. IQMs got alpha support and torch model animations got fixed up a little (they now use the correct animation intervals from the MDL file, and a missing last frame in each animation was restored). Also fixed up fence textures, so I think - with the exception of the static entities bug I mentioned previously (and which I still haven't a clue about the cause of) - that makes DirectQ more or less ready for RMQ support. There are still some things missing, such as some QC extensions, but while RMQ uses them they're not mandatory.
It is however fair to warn that in it's current state DirectQ is not actually a good engine for RMQ. The main problem is with lightmap handling; while DirectQ is much better at this than GLQuake ever was, it's still too slow for RMQ requirements. That needs to wait until I move to D3D11 and put lightmaps on the GPU. Average performance is quite similar, but when lots of lights start going off DirectQ can become quite jerky owing to delays in uploading new lightmap textures to the GPU (the RMQ engine doesn't need to do this so it doesn't get these delays).
In common with the RMQ engine it also suffers quite badly from a fairly heavyweight and sluggish progs.dat and from Quake formats (in particular the BSP format) just not being built for this kind of heavy load.
Posted by
mhquake
at
2:27 AM
3
comments
Thursday, February 2, 2012
Update - 1st February 2012
Got fog on IQMs and fixed up bounding boxes; I think only alpha is left to do.
Spent some time chasing a few outstanding bugs.
The old clipping weirdness bug is now well and truly fixed. That one was a result of me trying to be too clever for my own good during map loading.
There's a fairly minor static entities bug left that sucked up far too much of my time and ended up not being tracked down (yet, I hope). What it does is leave a few torches floating in mid-air in the wrong location in some maps; so far I've only seen it in one RMQ map, but if it happens once it can happen more than once.
Also spent far too much time playing with matrix code (some of the matrix code that doesn't look like matrix code...)
Oh yeah, IQMs have fully transitioned to D3DXMATRIX now, meaning that I was able to get rid of a lot of unnecessary code from the implementation. This is where C++ operator overloading really shines - want to multiply two matrixes? Just do m1 * m2.
What's fun is the fact that - despite being a D3D implementation - I'm actually using column-major matrixes all the way in this code. Of course any D3D function that generates a matrix will generate a row-major one which needs to be transposed, but there's just a single place where I need to do that.
The code has cleaned up very well as a result of this. There are still a few places where I'd like to move things around a little or split some stuff out into separate functions, but overall I'm getting much happier with it. Shame that the IQM guys didn't just store final joint matrixes in the models instead of having to round-trip through constructing them at load time - storage is cheap, performance isn't.
When this current bout of DirectQ activity winds down I'm planning on starting with a move of IQM animations to the GPU in RMQ. With that I'm likely going to keep the software code as a fallback and/or alternative option for cases where the number of joints overflows the hardware limit.
With DirectQ I don't expect that to become an issue until at least after I move it to D3D11, at which point this limit will be boosted to 256 (which I don't see being exceeded).
Posted by
mhquake
at
12:28 AM
0
comments
Wednesday, February 1, 2012
And here's the IQM Animator
void D3DIQM_AnimateFrame (iqmdata_t *hdr, int currframe, int lastframe, float lerp)
{
// temp memory for building the animation
D3DXMATRIX *outframe = (D3DXMATRIX *) scratchbuf;
D3DXVECTOR4 *outvecs = (D3DXVECTOR4 *) (outframe + hdr->num_joints);
// this memory should never be referenced if there are no frames or poses
D3DXMATRIX *mat1 = (!hdr->num_poses || !hdr->num_frames) ? NULL : &hdr->frames[(lastframe % hdr->num_poses) * hdr->num_joints];
D3DXMATRIX *mat2 = (!hdr->num_poses || !hdr->num_frames) ? NULL : &hdr->frames[(currframe % hdr->num_poses) * hdr->num_joints];
// and build the animation
for (int i = 0; i < hdr->num_joints; i++, outvecs += 3)
{
// the joints were unioned and parent is in the same memory location so this is valid to do
if (!hdr->num_poses || !hdr->num_frames)
D3DXMatrixIdentity (&outframe[i]);
else if (hdr->jointsv2[i].parent >= 0)
outframe[i] = outframe[hdr->jointsv2[i].parent] * (mat1[i] + ((mat2[i] - mat1[i]) * lerp));
else outframe[i] = mat1[i] + ((mat2[i] - mat1[i]) * lerp);
// copy out to 3xvec4 for more space in the constants (otherwise we'd just use a matrix array)
outvecs[0] = D3DXVECTOR4 (outframe[i].m[0]);
outvecs[1] = D3DXVECTOR4 (outframe[i].m[1]);
outvecs[2] = D3DXVECTOR4 (outframe[i].m[2]);
}
D3DHLSL_SetVectorArray ("IQMJoints", (D3DXVECTOR4 *) (outframe + hdr->num_joints), hdr->num_joints * 3);
}This could lose another 4 lines of code if we weren't constrained by constants space. Must experiment with SetVectorArray and see if you can pass it an array index...
Posted by
mhquake
at
3:07 AM
0
comments