/***************************************************************************/
/*
*/
/* File: dxdraw.cpp
*/
/* Author: bkenwright@xbdev.net
*/
/* Date:
10-11-2002
*/
/* Image Warping
*/
/*
*/
/***************************************************************************/
LPDIRECT3D8 g_pD3D = NULL;
LPDIRECT3DDEVICE8 g_pD3DDevice = NULL;
#include
<time.h>
// Texture
LPDIRECT3DTEXTURE8 pTex;
LPDIRECT3DVERTEXBUFFER8 g_pVBGrid;
LPDIRECT3DINDEXBUFFER8 g_pIBGrid;
struct
my_vertex
{
FLOAT x, y, z; // D3DFVF_XYZ
DWORD colour; // D3DFVF_DIFFUSE
FLOAT tu, tv; // D3DFVF_TEX1
};
UINT
my_vertex_description = ( D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1 );
int
VERTEX_GRID_DENSITY = 50;
void
init(HWND hWnd)
{
//First of all, create the main D3D object. If it
is created successfully we
//should get a pointer to an IDirect3D8 interface.
g_pD3D = Direct3DCreate8(D3D_SDK_VERSION);
//Get the current display mode
D3DDISPLAYMODE d3ddm;
g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
//Create a structure to hold the settings for our
device
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
//Fill the structure.
//We want our program to be windowed, and set the
back buffer to a format
//that matches our current display mode
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
//For depth buffering (e.g.) the z-buffer
d3dpp.BackBufferCount=1;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.EnableAutoDepthStencil = TRUE;
//Create a Direct3D device
g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice);
//Turn off lighting becuase we are specifying that
our vertices have colour
g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
//Turn on z-buffering
g_pD3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
//Turn on back face culling. This is becuase we
want to hide the back of our polygons
g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
//D3DCULL_CCW);
/*****************Init Image Stuff
Here*************************************/
D3DXCreateTextureFromFile( g_pD3DDevice, "image.bmp", &pTex);
g_pD3DDevice->CreateVertexBuffer( VERTEX_GRID_DENSITY*VERTEX_GRID_DENSITY*sizeof(my_vertex),
0,
my_vertex_description, D3DPOOL_MANAGED, &g_pVBGrid);
g_pD3DDevice->CreateIndexBuffer( VERTEX_GRID_DENSITY*VERTEX_GRID_DENSITY * 3
* 2 * sizeof(WORD),
D3DUSAGE_WRITEONLY, D3DFMT_INDEX16,
D3DPOOL_MANAGED,
&g_pIBGrid);
// We set the vertex buffer once here, as we only
change the positions of the vertices and not
// add or delete any of them.
WORD *pIndices;
g_pIBGrid->Lock( 0, (VERTEX_GRID_DENSITY)*(VERTEX_GRID_DENSITY)*3 * 2 *
sizeof(WORD) , (unsigned
char**)&pIndices, 0);
WORD *pIndex = pIndices;
for(int x=0;
x< VERTEX_GRID_DENSITY-1; x++)
{
for(int
y=0; y< VERTEX_GRID_DENSITY-1; y++)
{
// First Triangle.
*(pIndex++) = ( (y) * VERTEX_GRID_DENSITY) +x;
*(pIndex++) = ( (y) * VERTEX_GRID_DENSITY) +x+1;
*(pIndex++) = ((y+1) * VERTEX_GRID_DENSITY) +x+1;
// Second Triangle.
*(pIndex++) = ((y) * VERTEX_GRID_DENSITY) +x;
*(pIndex++) = ((y+1)* VERTEX_GRID_DENSITY) +x+1;
*(pIndex++) = ((y+1)* VERTEX_GRID_DENSITY) +x;
}
}
g_pIBGrid->Unlock();
srand( time(NULL) );
}
void
de_init()
{
g_pD3DDevice->Release();
g_pD3DDevice = NULL;
g_pD3D->Release();
g_pD3D = NULL;
/*****************De-Init Image Code here
on********************************/
pTex->Release();
g_pVBGrid->Release();
g_pIBGrid->Release();
}
void
set_camera()
{
// [1] D3DTS_VIEW
D3DXMATRIX v;
g_pD3DDevice->SetTransform(D3DTS_VIEW, D3DXMatrixLookAtLH(&v,
&D3DXVECTOR3(0,0,-2),
&D3DXVECTOR3(0,0,0),
&D3DXVECTOR3(0,1,0)));
// [2] D3DTS_PROJECTION
D3DXMATRIX p;
g_pD3DDevice->SetTransform( D3DTS_PROJECTION, D3DXMatrixPerspectiveFovLH(
&p,
D3DX_PI/4, 1.0f,
1.0f, 1000.0f));
};
int
RandomNumber(int iMin,
int iMax)
{
if (iMin == iMax)
return(iMin);
return((rand() % (abs(iMax-iMin)+1))+iMin);
}
// This adjusts our Vertex Buffer, we do it each time in a loop, and use the
Inex buffer to reference it.
void
SetupVertexGrid(LPDIRECT3DVERTEXBUFFER8 pVBGrid,
int iGridWidth, int iGridHeight)
{
my_vertex* pV;
pVBGrid->Lock( 0, iGridWidth*iGridHeight*sizeof(my_vertex),
(BYTE**)&pV, 0);
for( int
x=0; x< iGridWidth; x++)
{
for(
int y=0; y< iGridHeight; y++)
{
// its between 0 and 1, this
makes it to 0 to 2, then subtract 1, so its -1 to 1.
//
|
// x loops from 0 to iGridWidth-1, so
dividing by |
// (iGridwidth-1) scales our
values from 0 to 1. |
//
| |
//
______________|______________ ______|______
//
/ \
/ \
pV[ (y*iGridWidth)+x].x = (((float)x/(float)(iGridWidth-1))
* 2.0f) - 1.0f;
pV[ (y*iGridWidth)+x].y = (((float)(iGridHeight-1-y)/(float)(iGridHeight-1))
* 2.0f) - 1.0f;
//
\_____________________________________________________________/
// |
// As above for the x, but we
start at iGridHeight-1 and work backwards... else if you just use
// y you'll end up with an
upside down image.
pV[(y*iGridWidth)+x].z = 1.0f;
pV[ (y*iGridWidth)+x].colour = 0xff00ff00;
pV[ (y*iGridWidth)+x].tu = (float)x/(float)(iGridWidth-1);
// tex coors between 0 and 1.
pV[ (y*iGridWidth)+x].tv = (float)y/(float)(iGridHeight-1);
// These few lines of code
introduces our image distortion.. if you comment them out you'll
// have the originial image.
float fRandX =
RandomNumber(-75,100)/50.0f;
float fRandY =
RandomNumber(-75,100)/50.0f;
pV[ (y*iGridWidth)+x ].tu += fRandX/(float)(iGridWidth*2);
pV[ (y*iGridWidth)+x ].tv += fRandY/(float)(iGridHeight*2);
}
}
pVBGrid->Unlock();
}
void
Render()
{
if(!g_pD3DDevice)return;
set_camera();
// For this tutorial I just added a few lines of
code.. not the way it should be
// done but introduces a small delay. So the
effect is better.
static float
delay=0.0f;
delay+= 0.08f;
if( delay > 1.0f)
{
SetupVertexGrid(g_pVBGrid, VERTEX_GRID_DENSITY,
VERTEX_GRID_DENSITY);
delay = 0.0f;
};
// Clear the back buffer to a blue color
g_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );
g_pD3DDevice->BeginScene();
g_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
g_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1
);
g_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
g_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
g_pD3DDevice->SetTexture( 0, pTex );
g_pD3DDevice->SetStreamSource( 0, g_pVBGrid, sizeof(my_vertex)
);
g_pD3DDevice->SetIndices(g_pIBGrid, 0);
g_pD3DDevice->SetVertexShader( my_vertex_description );
unsigned int
numTriangless = VERTEX_GRID_DENSITY * VERTEX_GRID_DENSITY * 2;
unsigned int
numVertss = VERTEX_GRID_DENSITY * VERTEX_GRID_DENSITY;
g_pD3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0,
numVertss, 0, numTriangless );
g_pD3DDevice->EndScene();
// After rendering the scene we display it.
g_pD3DDevice->Present( NULL, NULL, NULL, NULL );
} |