[size=150][b]3.0-alpha is here! Finally got it running on the new runtimes via a totally different and (theoretically) more stable architecture! I'll update this post later but for now just go here [url="https://forums.oculus.com/community/discussion/comment/396974/#Comment_396974"]https://forums.oculus.com/community/discussion/comment/396974/#Comment_396974[/url]
TL;DR[/b] here's [url=https://www.youtube.com/watch?v=Zf5mwGdqSJQ]a really bad-quality video[/url] of the game window, which is just the left eye, undistorted, with no timewarp. If I can get oculus mirroring working I'll take a new video with timewarp and both eyes.
[url=https://drive.google.com/file/d/0B9o_WDIukR-sV2E0QWViVWViWms/view?usp=sharing]Version 2.4.2 (fixed texture stretching glitch when FPS counter was turned off)[/url][/size]
[url=https://drive.google.com/file/d/0B9o_WDIukR-sNU5LWnJyc1F4aU0/view?usp=sharing]Version 2.4.1 (fixed positional headtracking)[/url]
[url=https://drive.google.com/file/d/0B9o_WDIukR-sWUp4WWlvRk0tUms/view?usp=sharing]Version 2.4 (camera auto-leveling, fixed flickers, fixed steam overlay)[/url]
[url=https://drive.google.com/file/d/0B9o_WDIukR-sdjhDZkVDS2ZRZ1k/view?usp=sharing]Version 2.3 (timewarp; fixed projection matrix)[/url]
[url=https://drive.google.com/file/d/0B9o_WDIukR-sdFhHd25sZ3l3a0U/view?usp=sharing]Version 2.2 (fixed menus)[/url]
[url=https://drive.google.com/file/d/0B9o_WDIukR-sbDhkQjlxMFk5cTg/view?usp=sharing]Version 2.1 (fixed clipping)[/url]
[url=http://llama.cerberusstudios.net/morrowrift/]Old DK1 version[/url]
[size=150]The DK2 beta files can be dropped on top of a working Morrowind Graphics Extender installation to turn Morrowind VR-native. See [url=https://forums.oculus.com/viewtopic.php?p=323566#p323566]this post[/url] for instructions on creating a separate folder with just vanilla Morrowind, MGE, and Morrowrift for testing purposes.
Pause or Insert to recenter view position and yaw. Add Shift to either of these keys to also recenter Pitch/Roll, though I can't imagine why this would be useful.
I still need to add a configuration file and then fix distantland, the sky being affected by positional tracking, shadows, anti-aliasing, and eventually MGEXE support. Huge thanks to [url=https://forums.oculus.com/viewtopic.php?p=282839#p282839]These Guys[/url] for helping me afford a DK2 so I could make this work!
Also, the rest of this post is REALLY old and just about all of it is outdated, so be forewarned if you choose to read it for some reason... I've only left it for uh, historical purposes or something?[/size]
Ever since I got my Rift, the #1 place I wanted to experience in fully immersive VR has always been Tamriel. Yes, all three modern ES games have been made to work on the rift with varying degrees of success, but they've all (to my knowledge) had some pretty blatant issues that made them very difficult to actually play in VR due to the way they handled menus and hud, plus they required some third-party dll like TriDef 3D. Let me tell you though, as soon as my project is finished, those days will be over at least for Morrowind players. Morrowind has always been my favorite ES game and with MGE and various mods it's still alive and thriving today.
[b]WHAT THIS IS[/b]
Okay so as the title and section imply, this is a work-in-progress fork of the MGE (Morrowind Graphics Extender) source code, modified to support the Oculus Rift without any additional dependencies or third-party drivers. Setting it up is exactly the same as setting up regular MGE, and so far the only thing I've changed is MGE's spoof d3d8.dll. My changes are made all in one cpp file (mwvr.cpp) which requires some lines to be inserted in one of theirs (wrapperclasses.cpp) to be hooked into the rest of the engine. ([i]2016 EDIT: actually now it's just three d3d9 replacers that you extract on top of a working MGE installation.[/i])
I told myself I wouldn't post anything about this project unless I was able to make some real progress, and after about a week of insane hacking and testing and reimagining and all that stuff, I've actually managed to make it work. I'll list each little step/accomplishment I've done so far here, with the tl;dr in bold and if you're actually interested in how I did it, you can read the rest of the paragraph.
[b]DONE -- Apply oculus orientation to view transform[/b] - the first thing I did was just hook MGE's SetTransform proxy to take all view angles and multiply them by the oculus orientation. This worked on 2D as well as 3D objects, leaving the HUD/Menus/Loading Screens in front of the player but moving them away as you turned. This was implemented on day 1 of the project.
[b]DONE -- Locate Morrowind's internal view frustum[/b] -- The transform hack was cool and all, and it worked alright for the main menu, but as soon as I got in-game and started turning my head away from the front of the screen and the hud and menus, I realized that morrowind's occlusion/clipping planes were staying in place while I turned the device, meaning things began to vanish as soon as you look in any direction other than straight forward. MGE couldn't help me-- they had a bunch of nice memory hacks for various other things like increasing haggle prices, but unfortunately they never found the view frustum or bothered to label it in their memory map. This started a week-long hunt for morrowind's view frustum using everything from VC's debugger to IDA to memory-watching on-screen readouts. The thing that eventually found it was code I'd inserted that allowed me to view any 256 bytes of morrowind's memory converted into a float array on-screen, and watch how it changes in real-time.
[b]DONE -- Decipher the view frustum[/b] -- After I found the values, which I confirmed were used for determining visibility by modifying them randomly in realtime and watching everything randomly phase in and out of existence, I had to figure out what they were and how to use them. They were 24 floats long, and at first I thought they were some sort of matrix, but then I noticed they came in 6 groups of 3 tiny floats and 1 large float. Then I noticed that the 3 tiny floats, when I squared them and added them together, always equaled 1 -- and then I realized, what I'd found were morrowind's [i]clipping planes[/i], in normal/distance format. It made perfect sense, after all there were 6 of them (top/bottom/left/right/front/back) and the fourth float per group was a huge number that varied wildly with different orientations.
[b]DONE -- Hack and transform the view frustum[/b] -- Luckily for me, these variables seemed to always be in the same place in memory relative to one of MGE's existing memory map exposures, "eWorldFOV" -- which MGE used for changing the field of view. As far as I can tell, this offset is consistent, though someone might find later on that it differs between Morrowind versions, and I'll have to add some detection for that. Either way, I had access to the memory offset and I mapped them to an array of 6 x,y,z,d structs. I figured out a formula for rotating normal/distance planes around a fixed point, and it seemed to work at first, but I still ran into issues with angles and matrices and all that-- changing the pitch of the camera would mess with the transform, and oculus's Y was morrowind's Z, etc... finally I realized (in the middle of the night of course) that I could just save morrowind's original view transform before applying my rotation to it, and then use that to convert the clipping planes from world space into camera space, then apply the inverse of the same matrix I applied to the camera, then transform it again by the inverse of the original view matrix, back into world space. Once I implemented this (probably the hardest part to figure out next to actually finding the planes in memory), it worked perfectly at last.
[b]DONE -- Fix original view transform... silly accelerometers[/b] -- Now all of this would have been perfect if it weren't for the fact that, now that I could see everything, Oculus's built-in quaternion was giving me very wonky angles that completely messed up roll and flipped around when I tried to look behind me. After quite a bit of effort, I managed to settle on a way to produce accurate angles. The quaternion seemed to transform normals properly, but not coordinates, and no matter how I converted the quaternion into euler angles, the camera was always wrong. What I ended up doing was taking two normals, a forward and a right, and rotating them with the quaternion, then using atan2 and asin to figure out proper pitch/yaw/roll. It works great now, and I feel quite accomplished.
[b]DONE -- Fix the paperdoll and map[/b] -- This turned out to be trivial, greatly to my relief. MGE actually keeps track already of whether the game is trying to render to a texture or not, so all I had to do is disable all my stuff when it's drawing to an RT and viola, the paperdoll and map returned to normal.
[b]DONE -- Hack all the rendering stuff to render in stereo with distortion correction[/b] -- This was quite a headache even if it did only take me two days. Understanding distortion and all the different variables to get the game rendering properly was probably harder than figuring out how to implement them in the wrapper, but it works now and I'm glad it's over with. I literally did give myself a headache working on this because I kept getting the values for IPD and friends wrong just slightly and it took forever to find the right formulas to make it work. The way I ended up doing it is by keeping two rendertargets and zbuffers, one for each eye, at the same resolution as the screen so the game can render "normally" into it. I wrapped various draw calls to direct them to the rendertargets instead of to the screen, then added a function before presenting that drew the two eye textures to the screen using half-screen quads and a vertex/pixel shader that I optimized possibly a little more than I needed to... but again, it works, and it works pretty well.
[b]DONE -- Integrate distant land rendering (2016 EDIT: Just kidding, the DK2 version doesn't have this yet D:)[/b] -- This took a while to work mostly because of a version mismatch-- originally I'd been using my stable 3.8.0 copy of MGE combined with the MWVR d3d8.dll which was built for the latest unstable SVN version of MGE, and they were not getting along well. Once I found the old code for the last version they officially released and modified my stuff to work with it, adding distantland support was as simple as adding my draw macros to a couple of function calls. Unfortunately water reflections don't work still, but if you turn those off then it works fairly well.
[b]CURRENT STATE -- FLAWLESS HEADTRACKING AND STEREO RENDERING (2015 edit: Except nobody still uses their DK1 so the current state might as well be "works on windows 95"), VARIOUS BUGS STILL PRESENT (2015 edit: like, for example, not working on DK2 (2016 edit: just kidding, it works great now. at some point I'm going to completely rewirte this post...))[/b]
So here we are now, with a slightly (2016 EDIT: *extremely) outdated video of basically how it's working currently. I'll get a new video with the beta fairly soon, but for now the old one should work. As you can see in the video, the menu stays in place in front of the player's view (technically there's a slight counter-rotation due to the FOV zoom I added to make the menus more readable, but it's almost kind of helpful rather than harmful except in the case of the crosshair), while the world rotates away as if you were moving your head. The mouse obviously controls where the player is facing, which determines where the hud is rendered (this is the "base" camera position), and the head tracker simply deviates from this value depending on the direction you're looking. This means you can look around while still walking forward-- what better way to enjoy Vvardenfell's wonderful scenery?
Obviously I'm running a lot of mods in this video in addition to my hack, but none of them are required for this to work except for MGE itself.
[size=150]NOTE: scroll down for a beta release of the version seen in this video.[/size]
Here are the old pictures that were up here before I added stereo support, in case you want to see them again:
[url=http://i.imgur.com/JQytPrY.jpg]old pre-stereo picture #1[/url]
[url=http://i.imgur.com/75AtC8r.jpg]old pre-stereo picture #2[/url]
[url=http://i.imgur.com/RpFc0F6.jpg]old pre-stereo picture #3[/url]
[b]WHAT I'LL DO NEXT (2015 edit: well first the DK2 port... then this stuff maybe)[/b]
[b]Fix the crosshair[/b] -- right now, playing through, the single most annoying thing is that the crosshair doesn't actually point forward if you're not looking directly ahead. I'll probably solve this by disabling the built-in crosshair and rendering my own crosshair that turns into an edge-of-screen arrow if you look too far away from it.
[b]Fix clipping update issues[/b] -- currently if you enter or exit an interior cell, everything is invisible until you move the mouse.
[b]Fix shadows being clipped with head movements[/b] -- shadows seem to be unaffected by my frustum hack, and if you turn shadows on, the frustum hack actually stops working on npc's (though it still works with the rest of the world).
[b]Add some sort of configuration[/b] -- I'm assuming not everyone wants their VR working the same way I do, and I'll hopefully add ways for people to change how it works.
[b]Edit MGE's dinput hack to allow for keyholes and other VR control schemes[/b] -- pretty straightforward, I'm sure people have their preferences about how the game should be controlled, so I'll make sure that's customizable too. If I ever get a Hydra I might try and add support for that using the dinput dll as well.
[b]Look into other possible VR-related hacks I could add[/b] -- it takes a lot of work to make a game really VR-compatible, but to make it feel like it was MEANT for VR takes even more effort. I'm sure there are some other features you can all think of that immersion and headtracking might allow, and I might try and add some of those. One thing I thought of is possibly increasing the workable area for the pause menu to a wrap-around cube, so you can put your inventory screen to your left, your magic screen to your right, your map below you, etc. I'm not sure how hard this would be so I can't promise it, but I'm going to try it for sure.
Let's see what you all think of my work so far-- I'm hoping some of the stuff I learn doing this project will help me hack other games in the future to have true VR support. If people REALLY want me to, I might try doing this with oblivion and skyrim, but I'll have to get some pretty crazy support for that to be worth it.