Projection matrix - DX7 or DX9?
BlitzMax Forums/BlitzMax Programming/Projection matrix - DX7 or DX9?
| ||
I'm using projection matrix code which I found on this forum. I've modified it (below) so it works with DStastny's DX9 module. How would I modify this further so that it automatically detects whether the DX7 or DX9 driver is set? I need to do this at runtime - not compile time. My modified version. Credit to original author (whoever it was). Type TVirtualGraphics Global virtualWidth, virtualHeight Global xRatio!, yRatio! Function Set(width=640, height=480, scale#=1) TVirtualGraphics.virtualWidth = width TVirtualGraphics.virtualHeight = height TVirtualGraphics.xRatio! = width / Double(GraphicsWidth()) TVirtualGraphics.yRatio! = height / Double(GraphicsHeight()) ?Win32 Local D3D9Driver:TD3D9Max2DDriver = TD3D9Max2DDriver(_max2dDriver) If D3D9Driver Local matrix#[] = [2.0 / (width / scale#), 0.0, 0.0, 0.0,.. 0.0, -2.0 / (height / scale#), 0.0, 0.0,.. 0.0, 0.0, 1.0, 0.0,.. -1 - (1.0 / width), 1 + (1.0 / height), 1.0, 1.0] ',scale#] D3D9Driver._D3DDevice9.SetTransform(D3DTS_PROJECTION, matrix) Else ? glMatrixMode(GL_PROJECTION) glLoadIdentity() glortho(0, width / scale#, height / scale#, 0, -1, 1) glMatrixMode(GL_MODELVIEW) glLoadIdentity() ?Win32 EndIf ? End Function Function MouseX() Return (BRL.PolledInput.MouseX() * TVirtualGraphics.xRatio!) End Function Function MouseY() Return (BRL.PolledInput.MouseY() * TVirtualGraphics.yRatio!) End Function End Type |
| ||
If you want to find out the DX version on Windows wouldn't this sort of thing be the best way? |
| ||
I think he wants to know if the selected driver is Dx7, Dx9 or GL. I have something around my hard drive that does I think exactly what he wants. I just got home from work I will dig around to see if I can find it. I think it was tied to my playing around with InidePaths subtexture stuff. Doug |
| ||
I think typecast testing is simplest: isdx9=TD3D9Max2DDriver(_max2dDriver)<>null isdx7=TD3D7Max2DDriver(_max2dDriver)<>null |
| ||
Thanks Skid, thats exactly what I was thinking about. Just brain dead after long day. Doug |
| ||
Yep, that's what I wanted - thanks! |
| ||
Just got around to fixing this up. The downside is that you must include the DX9 *and* DX7 modules, otherwise you can't do casting to check which driver has been set. Anyway, if anybody's interested in using DStastny's DX9 module with a projection matrix, here's what I'm currently using. If you don't want to include both DX modules (it makes the EXE bigger), just rip out whichever bits you don't need. Type TVirtualGraphics Global virtualWidth, virtualHeight Global xRatio!, yRatio! Function Set(width=640, height=480, scale#=1) TVirtualGraphics.virtualWidth = width TVirtualGraphics.virtualHeight = height TVirtualGraphics.xRatio! = width / Double(GraphicsWidth()) TVirtualGraphics.yRatio! = height / Double(GraphicsHeight()) ?Win32 Local dxVer:Byte Local D3D7Driver:TD3D7Max2DDriver = TD3D7Max2DDriver(_max2dDriver) Local D3D9Driver:TD3D9Max2DDriver = TD3D9Max2DDriver(_max2dDriver) If TD3D7Max2DDriver(_max2dDriver) <> Null dxVer = 7 EndIf If TD3D9Max2DDriver(_max2dDriver) <> Null dxVer = 9 EndIf If dxVer <> 0 'dx driver was set, otherwise its GL Local matrix#[] = [2.0 / (width / scale#), 0.0, 0.0, 0.0,.. 0.0, -2.0 / (height / scale#), 0.0, 0.0,.. 0.0, 0.0, 1.0, 0.0,.. -1 - (1.0 / width), 1 + (1.0 / height), 1.0, 1.0] ',scale#] Select dxVer Case 7 D3D7Driver.device.SetTransform(D3DTS_PROJECTION, matrix) Case 9 D3D9Driver._D3DDevice9.SetTransform(D3DTS_PROJECTION, matrix) End Select Else ? glMatrixMode(GL_PROJECTION) glLoadIdentity() glOrtho(0, width / scale:Float, height / scale:Float, 0, - 1, 1) glMatrixMode(GL_MODELVIEW) glLoadIdentity() ?Win32 EndIf ? End Function Function MouseX() Return (BRL.PolledInput.MouseX() * TVirtualGraphics.xRatio!) End Function Function MouseY() Return (BRL.PolledInput.MouseY() * TVirtualGraphics.yRatio!) End Function End Type |
| ||
OK, this seems to be working very well Testing testing... :) |
| ||
I wonder if this could ever be included in the main BMax installation? It seems that a great deal of people have a use for it. Is there a reason why it is not I wonder... One thing that I would be interested in knowing, from those that have used this method, is whether there is a performance hit. When I scale a 320x240 game window up from 1:1 to double size (640x480), using the standard SetScale command on all of my game objects, my frames per second drops by half which is understandable. My question is, does this happen when using a projection matrix also? I`m guessing it does but just wanted to ask. It would be handy to know for future reference. Jason. |
| ||
No, it runs at the same speed. I was using SetScale originally, too, until I decided I need to rotate stuff, and that screws the whole thing up. A projection matrix is the only safe way. One note of caution though - and I did start a thread about this somewhere. If I use the above code, run my app and then CTRL/ALT/DEL in Vista, you get the popup screen where you can open Task Manager and stuff. After that, sometimes but not always, the edges of my graphics become visible as feint lines. Even if I reload graphics after that, I still get the same problem, so its my guess that there's a glitch in the matrix (sorry). I didn't write the original code and I'm not clever enough to know how to fix it, or if it can be fixed. I never really got any answers as to why that is. [edit] I'm a big fat liar - I didn't start a thread, I dug up an old one. And it's here. [edit again] Actually, I'll get back to you on that. I just tested a recent-ish build of my game on my laptop and I can't get this glitch to happen any more. Obviously I've installed a lot of Vista updates since then, and also I was using a fliphook before and now I'm not. I'll test more on my main dev PC tomorrow, but I'm 99.9% certain I was getting this problem at least 50% of the time on here too. |
| ||
You'll get the problem if you don't properly handle device lost. You have to rebuild everything in that event. |
| ||
Yes, problem still happens on my dev PC. You'll get the problem if you don't properly handle device lost. Define "properly handle"?I already stated that even newly loaded graphics exhibit the problem. I already reset the projection matrix after focus is lost, too. [edit] When I run in debug mode and this 'problem' happens, I get the following error in d3d7graphics.bmx: DXERROR err=UNKNOWN:-2147467259 16389 The DXASS function is being called from line 491: DXASS _d3ddev7.SetRenderTarget( renderSurf,0 ) I tried reinitialising the graphics mode on receipt of an EVENT_APPRESUME - naturally the graphics object is recreated over and over, as the task itself fires an EVENT_APPRESUME. Presumably I'm not using the correct method of losing/acquiring focus? Help? |
| ||
Right - confirmed this is nothing to do with the projection matrix. I'm going to start a new thread. |
| ||
Is there any way to get GrabImage/GrabPixmap to work with this projection Matrix? Last time I tried it didn't work :( |
| ||
It works but it grabs the scaled version... my suggestion would be to set the projection matrix to a 1:1 ratio before doing any operations of this nature and then switch it back after for renderingStartGraphics(1024,768,0,60) t:TVirtualGraphics=New TVirtualGraphics ' if Projection matrix is the same as above it will work perfectly... but set it to 800,600 and you get the scaled version t.Set(1024,768) i:TImage=CreateImage(64,64,,DYNAMICIMAGE|MASKEDIMAGE) DrawLine 0,0,64,64 DrawLine 64,0,0,64 GrabImage(i,0,0) Cls DrawImage i,0,0 Flip WaitKey() function StartGraphics(width:Int=1024,height:Int=768,depth:Int=0,refresh:Int=60) SetGraphicsDriver GLMax2DDriver() Graphics Width,Height,Depth,Refresh ScreenWidth=width ScreenHeight=height ScreenDepth=depth screenRefresh=refresh End Function Type TVirtualGraphics Global virtualWidth!, virtualHeight! Global xRatio!, yRatio! Function Set(width#=640, height#=480, scale#=1) TVirtualGraphics.virtualWidth = width TVirtualGraphics.virtualHeight = height TVirtualGraphics.xRatio! = width / Double(GraphicsWidth()) TVirtualGraphics.yRatio! = height / Double(GraphicsHeight()) ?Win32 Local dxVer:Byte Local D3D7Driver:TD3D7Max2DDriver = TD3D7Max2DDriver(_max2dDriver) ' Local D3D9Driver:TD3D9Max2DDriver = TD3D9Max2DDriver(_max2dDriver) If TD3D7Max2DDriver(_max2dDriver) <> Null dxVer = 7 EndIf ' If TD3D9Max2DDriver(_max2dDriver) <> Null ' dxVer = 9 ' EndIf If dxVer <> 0 'dx driver was set, otherwise its GL Local matrix#[] = [2.0 / (width / scale#), 0.0, 0.0, 0.0,.. 0.0, -2.0 / (height / scale#), 0.0, 0.0,.. 0.0, 0.0, 1.0, 0.0,.. -1 - (1.0 / width), 1 + (1.0 / height), 1.0, 1.0] ',scale#] Select dxVer Case 7 D3D7Driver.device.SetTransform(D3DTS_PROJECTION, matrix) Case 9 ' D3D9Driver._D3DDevice9.SetTransform(D3DTS_PROJECTION, matrix) End Select Else ? glMatrixMode(GL_PROJECTION) glLoadIdentity() glOrtho(0, width / scale:Float, height / scale:Float, 0, - 1, 1) glMatrixMode(GL_MODELVIEW) glLoadIdentity() ?Win32 EndIf ? End Function Function MouseX:Float() Return (BRL.PolledInput.MouseX() * TVirtualGraphics.xRatio!) End Function Function MouseY:Float() Return (BRL.PolledInput.MouseY() * TVirtualGraphics.yRatio!) End Function End Type |