• Welcome to Dark Bit Factory & Gravity.
 

letterboxing in directx

Started by Meduusa, June 13, 2008

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Meduusa

How can I achieve letterboxing in directx so that my graphics wont get stretched with differet aspect ratios?

Shockwave

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
Shockwave ^ Codigos
Challenge Trophies Won:

Meduusa

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

Motorherp

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.

Meduusa

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?

Jim

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
Challenge Trophies Won:

Meduusa

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?

Jim

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
Challenge Trophies Won:

ferris

#8
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.
http://iamferris.com/
http://youth-uprising.com/

Where the fun's at.
Challenge Trophies Won: