Scaling our Square with Direct3D

Back to Direct3D Tutorial Index

Welcome to the next in my line of Direct 3D tutorials. Here you will learn how
to scale an object. The method of scaling is to stretch an object along a
specified axis. It is possible to scale an object on any of the 3 axis, at
any time, with the ability to scale on more than one axis at once.

-------------------------------------------------------------------------------
Section 1: Headers, Libraries and Global Variables

This tutorial does not need any added header files, libraries or global variables.
Just keep the standard ones we have been using for the last few tutorials.

-------------------------------------------------------------------------------
Section 2: Scaling

I have placed all of our scaling code into the one folder to show you it
without any other garbage in the way. I have called this function: Scaling
void Scaling (void)
{

For this we need to create a Direct 3D matrix which I have called mWorld.
D3DXMATRIXA16 mWorld;

Next we call the function: D3DXMatrixScaling which will take the parameters
to do our scaling. The first parameter is our Direct 3D matrix which we
set up just before. The next 3 take our x, y and z axis. Eace of these
3 variables determines how much to stretch our axis. A setting of 1, will
leave the object how it looks. So having my second and first parameters, which
are the x and z axis, will remain the same. The third has a setting of 2, which
means that it will be scaled to twice of its original time.
D3DXMatrixScaling(&mWorld, 1,2,1);

Next we tell our rendering device to transform our world in accordance to our
mWorld variable, which now holds our scaled world data.
g_pd3dDevice->SetTransform( D3DTS_WORLD, &mWorld );
}

------------------------------------------------------------------------------
Section 3: Rendering

Finally we need to call our Scaling function, which is done from within our
Render function, although if you have your objects created from inside another
function and then linking to them from your Render function, then there is no
problem calling our Scaling function from within those other functions.

So just before your code to create your object, I have added the line:
Scaling();

-----------------------------------------------------------------------------
So there it is. You are now able to scale your object.

If you have any queries about this tutorial, please email me at swiftless@gmail.com

#include <dx/d3dx9.h>
#include <dx/d3d9.h>

#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")

LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;

struct CUSTOMVERTEX
{
float x, y, z;
DWORD color;
};

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)

void init( HWND hWnd )
{

g_pD3D = Direct3DCreate9( D3D_SDK_VERSION );

D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice );

g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );

}

void initVBuffer (void)
{
CUSTOMVERTEX Square[] =
{
{ -1, 1, 0, D3DCOLOR_XRGB(255,0,0), },
{ -1, -1, 0, D3DCOLOR_XRGB(0,0,255), },

{ 1, 1, 0, D3DCOLOR_XRGB(255,255,0), },
{ 1, -1, 0, 0xff00ff00, },
};

g_pd3dDevice->CreateVertexBuffer( 4*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL );

void* pVertices;
g_pVB->Lock( 0, sizeof(Square), (void**)&pVertices, 0 );

memcpy( pVertices, Square, sizeof(Square) );

g_pVB->Unlock();
}

void Scaling (void)
{
D3DXMATRIXA16 matWorld;

D3DXMatrixScaling(&matWorld, 1,2,1);

g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
}

void Eye (void)
{
D3DXVECTOR3 EyePoint( 0, 0,-5 );
D3DXVECTOR3 LookatPoint( 0, 0, 0 );
D3DXVECTOR3 UpVector( 0, 1, 0 );

D3DXMATRIXA16 mView;
D3DXMatrixLookAtLH( &mView, &EyePoint, &LookatPoint, &UpVector );
g_pd3dDevice->SetTransform( D3DTS_VIEW, &mView );
}

void Perspective (void)
{
D3DXMATRIXA16 mProjection;
D3DXMatrixPerspectiveFovLH( &mProjection, D3DX_PI/4, 1, 0.1, 100 );
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &mProjection );
}

void Cleanup (void)
{

if( g_pVB != NULL )
{
g_pVB->Release();
}

if( g_pd3dDevice != NULL)
{
g_pd3dDevice->Release();
}

if( g_pD3D != NULL)
{
g_pD3D->Release();
}
}

void Render (void)
{
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1, 0 );

g_pd3dDevice->BeginScene();

Eye();

Perspective();

Scaling();

g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );

g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );

g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );

g_pd3dDevice->EndScene();

g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}

LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_DESTROY:
Cleanup();
PostQuitMessage( 0 );
return 0;

case WM_PAINT:
Render();
ValidateRect( hWnd, NULL );
return 0;
}

return DefWindowProc( hWnd, msg, wParam, lParam );
}

INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, "A Basic Window", NULL };
RegisterClassEx( &wc );

HWND hWnd = CreateWindow( "A Basic Window", "A Basic Window", WS_OVERLAPPEDWINDOW, 100, 100, 500, 500, NULL, NULL, wc.hInstance, NULL );

init( hWnd );

initVBuffer();

ShowWindow( hWnd, SW_SHOWDEFAULT );
UpdateWindow( hWnd );

MSG msg;
ZeroMemory( &msg, sizeof(msg) );
while( msg.message!=WM_QUIT )
{
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
Render();
}

UnregisterClass( "A Basic Window", wc.hInstance );
return 0;
}

Download C++ Source Code for this Tutorial

     

 

Copyright 2008, Donald Urquhart
Proudly supported by http://www.cdadc.com