Archived

This topic is now archived and is closed to further replies.

draqza

Help with D3D8 and Lighting (long, with code)

Recommended Posts

I''m in the process of learning D3D8 from a combination of internet sites and the included manual, and now that the first stage of my experimental program is running, I want to try to do two things: First, I would like to add a sweeping light that moves back and forth across the surface of my square, and second, I would like to see if it is possible to port it backwards to DX6 or 7 so some of my friends can see it without having to download DX8. Here is the code I have; sorry it''s so long for the post, but I''m not sure what I could have left out of it:
#include   //standard windows include
#include      //direct3d 8 header
#include     //direct3d x 8
#include "myheader.h" //stuff MS didn''t include

//defines
#define ERRORMSG MB_OK | MB_ICONEXCLAMATION  //flags for error message boxes
#define D3DFVF_CVERTEXTURE (D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_DIFFUSE) //cvertexture fvf

//classes
/*--------------------------------
| Class: CVerTexture
| Purpose: Vertex with texture.
--------------------------------*/
class CVerTexture
{
public:
	//vertices
	float fX,fY,fZ; //x, y, and z coords
	//color
	DWORD dwColor;
	//tex coords
	float fU, fV;
	//function to init the vertex
	void Create(float x, float y, float z, float r, float g, float b, float u, float v)
	{
		fX=x; fY=y, fZ=z;
		dwColor=D3DCOLOR_XRGB((BYTE)r*255, (BYTE)g*255, (BYTE)b*255);
		fU=u; fV=v;
	}
};
//globals

int width=640;   //window width
int height=480;  //window height
bool keys[256];  //keyboard keys
bool done=FALSE; //done with the program?

bool spinY=FALSE;  //spin Y
bool spinX=FALSE; //spin x
bool spinZ=TRUE; //spin z
bool spinNO=FALSE; //no spin

HWND g_hWnd;     //global for window handle
HINSTANCE g_hInst;  //global for instance handle

LPDIRECT3D8 g_pd3d=NULL;  //pointer to the direct3d
LPDIRECT3DDEVICE8 g_pd3dDevice=NULL; //pointer to the d3d device

IDirect3DTexture8 *g_pd3dTexture; //pointer to the TEXTURE

CVerTexture vtex[4];  //textured vertices

//prototypes

LRESULT CALLBACK MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);  //message handler
HRESULT D3D_Init();  //direct 3d init-ializer
void DrawScene();    //draw the scene
void ReleaseD3D();   //release direct3d-related stuff
void setVertex();    //setup vertices
void UpdateScene();  //updates the scene



/*--------------------------------------
|  Function:  MsgProc                  | 
|  Purpose:   Message Handler          |
--------------------------------------*/
LRESULT CALLBACK MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch(msg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		done=TRUE;
		return 0;	
	case WM_CLOSE:
		PostQuitMessage(0);
		done=TRUE;
		return 0;
	case WM_KEYDOWN:
		keys[wParam]=TRUE;
		return 0;
	case WM_KEYUP:
		keys[wParam]=FALSE;
		return 0;
	default:
		return DefWindowProc(hWnd, msg, wParam, lParam);
		break;
	}
}


/*------------------------------|
| Function: WinMain             |
| Purpose:  App Entry Point.    |
-------------------------------*/
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	//create a standard window class
	WNDCLASSEX wc;
	wc.cbSize=sizeof(WNDCLASSEX);
	wc.lpfnWndProc=MsgProc;
	wc.cbClsExtra=0;
	wc.cbWndExtra=0;
	wc.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
	wc.hCursor=LoadCursor(NULL, IDC_ARROW);
	wc.hIcon=LoadIcon(NULL, IDI_WINLOGO);
	wc.hIconSm=LoadIcon(NULL, IDI_WINLOGO);
	wc.hInstance=hInstance;
	wc.lpszClassName="Trial";
	wc.lpszMenuName=NULL;
	wc.style=CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
	//and register it
	if(!RegisterClassEx(&wc))  //couldn''t register, give error message and exit
	{
		MessageBox(NULL, "Couldn''t register class.", "Error", ERRORMSG);
		return 0;
	}
    //create a window handle and create the window
	HWND hWnd;
	if(!(hWnd=CreateWindowEx(NULL, "Trial", "Trial Program", WS_OVERLAPPEDWINDOW, 0,0, width, height, NULL, NULL, hInstance, NULL)))
	//couldn''t create window, give error message and quit
	{
		MessageBox(NULL, "Couldn''t create window.", "Error", ERRORMSG);
		return 0;
	}
	//we created the window, now show it
	ShowWindow(hWnd, SW_SHOWNORMAL);
    
	//set globals for handles
	g_hWnd=hWnd;
	g_hInst=hInstance;

	//try to initialize d3d now
	HRESULT hr=D3D_Init();
	if(FAILED(hr))  //if it failed...
	{
		MessageBox(NULL, "Couldn''t initialize a portion of D3D", "Error", ERRORMSG);
		return 0;  //quit
	}

	setVertex();

	MSG msg; //message

	while(!done) //enter the main loop
	{
		//first check and see if there are any relevant messages for us
		if(PeekMessage(&msg, NULL,0,0, PM_REMOVE))
		{   //if so, do something with them
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		//exit on escape key   //
		if(keys[VK_ESCAPE])
			break;
		//and now do the rest of our "real" work
		DrawScene();
	}

	//any cleanup goes here
	ReleaseD3D();


	//and now exit
	return (msg.wParam);
}

/*---------------------------------
| Function: D3D_Init              |
| Purpose:  Initialize Direct3D   |
---------------------------------*/
HRESULT D3D_Init()
{
	HRESULT hr; //this will hold return values for us
	//this tries to get a pointer to Direct3D or returns failed
	if(NULL==(g_pd3d=Direct3DCreate8(D3D_SDK_VERSION)))
	{
		MessageBox(NULL, "Couldn''t start d3d.", "Error", ERRORMSG);
		return E_FAIL;
	}
	
/*  I don''t know if this code is necessary--it was in NeXe but I didn''t
    see it in the DX8 C++ Reference that came with the SDK.
*/	
	//get monitor display mode
	D3DDISPLAYMODE displayMode; // struct to hold it
	hr=g_pd3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode);
	if(FAILED(hr))
	{
		MessageBox(NULL, "Couldn''t get adapter display mode", "Error", ERRORMSG);
		return E_FAIL;
	}

	//parameters for d3d
	D3DPRESENT_PARAMETERS d3dpp;
	memset(&d3dpp,0,sizeof(d3dpp));

	d3dpp.Windowed=TRUE;
	d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferFormat=displayMode.Format;
	d3dpp.BackBufferWidth=displayMode.Width;
	d3dpp.BackBufferHeight=displayMode.Height;

	if(FAILED(g_pd3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice )))
	{
		MessageBox(NULL, "Couldn''t create device", "Error", ERRORMSG);
		return E_FAIL;
	}

	//matrix code, also stolen from NeXe (for now)
	D3DXMATRIX matrix;
	//set up perspective
	D3DXMatrixPerspectiveFovLH(&matrix, D3DX_PI/6, width/height, 1.0, 100.0);
	hr=g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &(D3DXMATRIX)matrix);
	if(FAILED(hr))
	{
		MessageBox(NULL, "Hey stupid, fix your matrix code", "Error", ERRORMSG);
		return E_FAIL;
	}
	//set up Identity Matrix
	D3DXMatrixIdentity(&matrix);
	g_pd3dDevice->SetTransform(D3DTS_WORLD, &(D3DXMATRIX)matrix);
	if(FAILED(hr))
	{
		MessageBox(NULL, "Hey stupid, fix your matrix code", "Error", ERRORMSG);
		return E_FAIL;
	}
	//set up Translation Matrix
	D3DXMatrixTranslation(&matrix, 0, 0, 10.0);
	hr=g_pd3dDevice->SetTransform(D3DTS_VIEW, &matrix);
	if(FAILED(hr))
	{
		MessageBox(NULL, "Hey stupid, fix your matrix code", "Error", ERRORMSG);
		return E_FAIL;
	}

	//set cull mode and lighting mode
	g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
	g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);


	//succeeded
	return S_OK;

}

/*----------------------------------------
| Function:  ReleaseD3D                  |
| Purpose:   Releases Direct3D pointers. |
----------------------------------------*/
void ReleaseD3D()
{
	if(g_pd3d!=NULL)
	{
		g_pd3d->Release();
		g_pd3d=NULL;
	}
	if(g_pd3dDevice!=NULL)
	{
		g_pd3dDevice->Release();
		g_pd3dDevice=NULL;
	}
}


/*--------------------------------------
| Function: DrawScene()                |
| Purpose: Draws the scene.  Who would |
|  have guessed it?                    |
--------------------------------------*/

void DrawScene()
{
	HRESULT hr;  //holds results
	//clear the screen
	hr=g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0),1.0f, 0);
	if(FAILED(hr))
	{
		MessageBox(NULL, "Couldn''t clear the screen", "Error", ERRORMSG);
		keys[VK_ESCAPE]=TRUE;  //set quit key to true
	}

	//Update the scene
	UpdateScene();
		
	
	//begin the scene
	g_pd3dDevice->BeginScene();
	//fvf for textures
	g_pd3dDevice->SetVertexShader(D3DFVF_CVERTEXTURE);

	//draws the textured square
	g_pd3dDevice->SetTexture(0, g_pd3dTexture);
	g_pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2, vtex,sizeof(CVerTexture));

	//end the scene
	g_pd3dDevice->EndScene();
	//and show the back buffer (where we drew everything)
	g_pd3dDevice->Present(NULL, NULL, NULL, NULL);

}

/*-------------------------------
| Function: setVertex()         |
| Purpose: Defines vertices     |
-------------------------------*/

void setVertex()
{
	//this code creates the quad for the texture
	vtex[0].Create(-1,-1,0,1,1,1,0,1);
	vtex[1].Create(-1,1,0,1,1,1,0,0);
	vtex[2].Create(1,-1,0,1,1,1,1,1);
	vtex[3].Create(1,1,0,1,1,1,1,0);
	//set up the texture, etc.
	g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
	g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
	g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
	//turn off alpha channel
	g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
	//create the texture
	D3DXCreateTextureFromFile(g_pd3dDevice, "utex.bmp", &g_pd3dTexture);
}

/*---------------------------------
| Function: UpdateScene()         |
| Purpose: Updates the scene.     |
---------------------------------*/
void UpdateScene()
{
	//three rotations
	static int iRotationDegreesX=0;
	static int iRotationDegreesY=0;
	static int iRotationDegreesZ=0;
	D3DXMATRIX matRotation;
	//this checks which way we''re spinning
	//the three if statements will alter the spin bool variables
	if(keys[VK_Y])
	{
		spinY=TRUE; spinX=FALSE; spinZ=FALSE;
	}
	if(keys[VK_X])
	{
		spinY=FALSE; spinX=TRUE; spinZ=FALSE;
	}
	if(keys[VK_Z])
	{
		spinY=FALSE; spinX=FALSE; spinZ=TRUE;
	}
	if(keys[VK_S])
	{
		keys[VK_S]=FALSE;
		spinNO=!spinNO; //change spin
	}
	if(spinNO)
	{
		return;
		D3DXMatrixRotationY(&matRotation,D3DXToRadian(0));
	}
	//and these three if statements actually check and spin
	if(spinY)
	{
		D3DXMatrixRotationY(&matRotation, D3DXToRadian(iRotationDegreesY));
		iRotationDegreesY++;
		if(iRotationDegreesY==360)
			iRotationDegreesY=0;
	}
	if(spinX)
	{
		D3DXMatrixRotationX(&matRotation, D3DXToRadian(iRotationDegreesX));
		iRotationDegreesX++;
		if(iRotationDegreesX==360)
			iRotationDegreesX=0;
	}
	if(spinZ)
	{
		D3DXMatrixRotationZ(&matRotation, D3DXToRadian(iRotationDegreesZ));
		iRotationDegreesZ++;
		if(iRotationDegreesZ==360)
			iRotationDegreesZ=0;
	}
	g_pd3dDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX *)&matRotation);//set the world transformation now
}
 
"myheader.h" is simply the hex codes for VK_A through VK_Z, since they aren''t in winuser.h and I didn''t know what header file they might be in.

Share this post


Link to post
Share on other sites