Dark Bit Factory & Gravity
PROGRAMMING => General coding questions => Topic started by: Meduusa on June 13, 2008
-
How can I achieve letterboxing in directx so that my graphics wont get stretched with differet aspect ratios?
-
Like this?
//45 degree field of view
float field_of_view = (float)Math.PI / 4.0f;
//Typical aspect ratio is approximately 1.333...
float aspect_ratio = (float)ClientSize.Width / ClientSize.Height;
m_device.Transform.Projection = Matrix.PerspectiveFovLH(field_of_view,
aspect_ratio,
1.0f, //ZNear
100.0f);
Found it here;
http://www.drunkenhyena.com/cgi-bin/view_net_article.pl?chapter=2;article=27 (http://www.drunkenhyena.com/cgi-bin/view_net_article.pl?chapter=2;article=27)
-
I dont understand source code of those examples since they are c# and vb and i would prefere c++ or c sample
but looking at those they wont still add black lines to top and bottom if I would scale window
-
You should be able to use the above code to at least render to the correct dimensions for the inner letter box bit without distorting your image. Probably what you'll want to do is render that to an off screen target, then clear the screen to black and render the saved target to a billboard placed in the middle of the screen. Alternatively but somewhat wasteful you could render your scene to the back buffer as normal then turn of the depth buffer and render two black quads at the top and bottom ;p.
-
Mayby I can explain myselve a litte better. If I design a program to use a 1280x720 resolution (aspec ratio 16:9) but I give user an opportunity to run a program in 1024x768 (aspect ratio 4:3). I still want to forse users to use 16:9 aspect ratio in 1024x768 mode and i can do that by adding borders to tom and bottomm but how do I add them?
-
There's no automatic setting for doing it. You have to build a projection matrix like the one Shockwave pasted (C# code is almost identical to C++). To get the sums right you need to know if you are already on a 16:9 screen, and then set the aspect ratio to 16/9. If you want 16:9 on a 4:3, then it'd be 1024 x (1024*9/16) = 1024x576 with 96pixel high black bars top and bottom.
Jim
-
Am I doing this right
first I create a window like
hWnd = CreateWindowEx(NULL, L"WindowClass", L"test",
WS_OVERLAPPED, 0, 0, 1024, 768,
NULL, NULL, hInstance, NULL);
Then I create device like
d3d = Direct3DCreate9(D3D_SDK_VERSION);
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = true;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferWidth = 1024;
d3dpp.BackBufferHeight = 768;
d3d->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&d3ddev);
And i have
D3DXMATRIX matRotateY;
static float index = 0.0f; index+=0.05f;
D3DXMatrixRotationY(&matRotateY, index);
d3ddev->SetTransform(D3DTS_WORLD, &matRotateY);
D3DXMATRIX matView;
D3DXMatrixLookAtLH(&matView,
&D3DXVECTOR3 (0.0f, 0.0f, 10.0f),
&D3DXVECTOR3 (0.0f, 0.0f, 0.0f),
&D3DXVECTOR3 (0.0f, 1.0f, 0.0f));
d3ddev->SetTransform(D3DTS_VIEW, &matView);
D3DXMATRIX matProjection;
D3DXMatrixPerspectiveFovLH(&matProjection,
D3DXToRadian(45),
589824.0f, //is this right?
1.0f,
100.0f);
d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection);
How do I add black lines since they dont come automatically?
-
Set the view to 2d (orthographic, width x height - it's another d3dx function), which should give you pixel coordinates, and draw a 1024x96 black quad top and bottom. Or, blank the screen out each frame and just set the viewport to the widescreen rectangle.
Jim
-
How I do it is this (it's opengl, but the function names are self-explanatory and this method should still work with direct3d):
gluPerspective(45.0,16.0 / 9.0,.2,1000.0); // FOV angle, aspect ratio (fixed), near clipping plane, far clipping plane
int bh = (getscrh() - (int) ((getaspectratio() * 9.0 / 16.0) * (float) getscrh()));
glViewport(0,bh >> 1,getscrw(),getscrh() - bh); // start x, start y, width, height
getscrw() and getscrh() are the screen width and height, and getaspectratio() is the desired aspect ratio. As you can see, how this works is, there's a regular opengl window that is fullscreen and can be any resolution. I do my whole demo in a 16:9 viewport (box where the stuff is drawn); the letterbox effect is just blank space where my opengl viewport isn't covering. Since monitors with different aspect ratios will stretch the screen horizontally (and my viewport since it's always the same width as the screen), to compensate these calculations stretch my viewport to make it taller.
I think this is what Jim was trying to explain, actually. And if you want to see a good example of this, check out Gamma by Outracks ( http://www.pouet.net/prod.php?which=30223 ) and run it windowed with different aspect ratios.