windows游戏编程大师技巧源码C++改写DX9改写

额。暂时只是提供了基本表面画线实现其他以后补上。

写完以后顺便改写3D游戏编程大师技巧。

DirectDraw7太老了。

在wind8和wind7老是出现莫名的错误,而且不好调试。

用DX9分装了,就只用了IDirect3DSurface9接口。 

额没有用流水管线。

以后用软件算法实现

纹理其他什么的暂时不想用。只想用软件模拟算法。所以至于速度什么的,你懂的。

献丑了。源码呈上


IDE:VS2012 EXPRESS

/*
		作者:钱启新
		版本:0000 0001	//以便于以后更新方便增加了什么
		只是很简单很简单的封装以后慢慢改写完美化。
*/



#ifndef __T3DLIB2_HEADFILE_H__
#define __T3DLIB2_HEADFILE_H__


#include"T3DlibCommon.h"

#include 
#include 
#include 

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

LRESULT WINAPI WndProc( HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam );



struct cVertex2D{
	float x;
	float y;
};



//Desc:	多边形描述
struct cPolygon2D{
	int state;			//绘制状态		1 = 绘制, 2 = 不绘制
	int num_vertes;		//顶点数量
	int posX, posY;		//绘制坐标
	int xv, yv;			//移动速度
	DWORD color;		//顶点颜色

	cVertex2D* vlist;	//顶点列表

public:
	void Translate( int dx, int dy );
	void Rotate( float angle );
	void Scale( float sx, float sy );

};



class ScreenSys_Win32;
class VisualSys_D3D9;
class SetllaEngine;



//Desc:	win32封装
class ScreenSys_Win32{
	friend class VisualSys_D3D9;
public:
	ScreenSys_Win32();
	virtual ~ScreenSys_Win32();

	HRESULT ScreenSys_InitWin32( HINSTANCE _hInstance, DWORD _width, DWORD _height );
	HRESULT ScreenSys_UnInitWin32( );

	/*
		Desc:	消息循环函数
				void(*BackCallFunc)()	= "你想要循环的函数"
	*/
	HRESULT ScreenSys_ProcessWin32( void(*BackCallFunc)() );

private:
	HWND		m_win32HWND;
	HINSTANCE	m_win32HINSTANCE;
	DWORD		m_win32HEIGHT;
	DWORD		m_win32WIDTH;
	DWORD		m_win32WINDOWSTYLE;
	T3DString	m_strCaptionName;
	T3DString   m_strClassName;
};



//Desc:	DX9简单封装
	//没有加入渲染流水管线
	//为了方便以后软件算法模拟渲染流水管线
class VisualSys_D3D9{
public:
	VisualSys_D3D9( ScreenSys_Win32* _pScreenSysObject );
	virtual ~VisualSys_D3D9();

	HRESULT VisualSys_InitD3D9( DWORD _iswindowed );
	HRESULT VisualSys_UnInitD3D9();

	HRESULT	VisualSys_BeginDrawingBoardD3D9();
	HRESULT VisualSys_EndDrawingBoardD3D9();



	/*
		Desc:	直接将像素绘制到m_pD3D9DrawingBorad中
		Node:	必须在VisualSys_BeginDrawingBoardD3D9()和VisualSys_EndDrawingBoardD3D9()之间进行绘制
		SAMPLE:	
				pOBJECT->VisualSys_BeginDrawingBoardD3D9();
					pOBJECT->VisualSys_DrawPixelToDB( 1, 2, 0 )
				pOBJECT->VisualSys_EndDrawingBoardD3D9();
	*/
	HRESULT VisualSys_DrawPixelToDB( int _x, int _y, DWORD _color );
	
private:
	IDirect3D9*			m_pD3D9;
	IDirect3DDevice9*	m_pD3D9Device;
	IDirect3DSurface9*	m_pD3D9SurfaceBack;
	IDirect3DSurface9*	m_pD3D9DrawingBorad;


	ScreenSys_Win32*	m_pScreenSysWin32_Object;

	DWORD				m_win32IsWindowed;	

	//Desc:	描述m_pD3D9DrawingBorad
		//	获得间距(lPitch)和像素位
	D3DLOCKED_RECT		m_D3D9rc;
	//Desc: m_win32BeginDrawBD = true;	接受像素写入m_pD3D9DrawingBorad中
		//	m_win32BeginDrawBD = false;	拒接像素写入m_pD3D9DrawingBorad中
	DWORD				m_win32BeginDrawBD;	

	//Desc:	当前表面的像素未格式
		//	可传递32 24 16 8	
	DWORD				m_win32BBP;
};



//Desc:	软件模拟2D图形算法
	//	只需要获取线性显存地址
	//	所有软件模拟算法都封装在此地
class VisualSys_Soft2D{
public:
	VisualSys_Soft2D( VisualSys_D3D9* _pObject );
	~VisualSys_Soft2D();

	void VisualSys_DrawLine( int x1, int y1, int x2, int y2, DWORD color );
	void VisualSys_ClipLine( int& x1, int& y1, int& x2, int& y2 );

	//Node:	进行裁剪并且绘制
	void VisualSys_DrawLineEx( int x1, int y1, int x2, int y2, DWORD color );

	//Node:	绘制一个多边形
		//	x1,	y1 = 绘制坐标
	void VisualSys_DrawPolygon2D( const cPolygon2D* _pPolygon );
	

	//Node:	设置最小和最大裁剪范围
		//	最大值不超过窗口最大坐标
		//	最小值不超过窗口最小坐标
	void VisualSys_SetClipRect( int min_x, int min_y, int max_x, int max_y );
	void VisualSys_SetClipRect( RECT* _pRect );
private:
	VisualSys_D3D9*	m_pVisualD3D9SysObject;

	//Node:	每次改变窗口大小的时候应该要及时更新
	//Desc:	裁剪坐标限定
	int m_ClipMinx;
	int m_ClipMiny;
	int m_ClipMaxx;
	int m_ClipMaxy;
};



//Desc:	所有的类的全部实现调用都由该类调用
class SetllaEngine{
public:
	SetllaEngine();
	~SetllaEngine();

	HRESULT Setlla_Init( HINSTANCE _hInstance, DWORD _width, DWORD _height, DWORD _iswindowed );
	HRESULT Setlla_UnInit();

	HRESULT Setlla_Process( void(*_pFunction)() );

	HRESULT Setlla_BeginRender();
	HRESULT Setlla_EndRender();
	HRESULT Setlla_DrawPixel( int _x, int _y, DWORD _color );
	HRESULT Setlla_DrawLine( int x1, int y1, int x2, int y2, DWORD color );
	HRESULT Setlla_DrawLineEx( int x1, int y1, int x2, int y2, DWORD color );
	HRESULT Setlla_DrawPolygon2D( const cPolygon2D* _pPolygon );
private:
	ScreenSys_Win32*	m_pScreenSysObject;
	VisualSys_D3D9*		m_pVisualSysObject;
	VisualSys_Soft2D*	m_pVisualSysSotfObject;
};



#endif
#include "T3Dlib2.h"

LRESULT WINAPI WndProc( HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam ){
	switch(nMsg){
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		break;
	}
	return DefWindowProc( hwnd, nMsg, wParam, lParam );
}


/*----------------------------------------------------------------------------------------------------------------*/
/*------------------------------------------------------ScreenSys_Win32 class-------------------------------------*/
/*----------------------------------------------------------------------------------------------------------------*/
ScreenSys_Win32::ScreenSys_Win32(){
	m_win32HEIGHT = 600;
	m_win32WIDTH  = 800;
	m_win32WINDOWSTYLE = WS_OVERLAPPEDWINDOW;
	m_strCaptionName   = __TEXT( "T3Dlib" );	//调用赋值操作符,非构造函数。可以使用初始化列表调用构造函数
	m_strClassName     = __TEXT( "T3Dlib" );	//同上
}

ScreenSys_Win32::~ScreenSys_Win32(){

	ScreenSys_UnInitWin32();
}



HRESULT ScreenSys_Win32::ScreenSys_InitWin32( HINSTANCE _hInstance, DWORD _width, DWORD _height ){
	m_win32HINSTANCE = _hInstance;
	m_win32HEIGHT = _height;
	m_win32WIDTH  = _width;
	//Node:	填充窗口描述
	WNDCLASSEX wc;
	ZeroMemory( &wc, sizeof(wc) );
	wc.cbSize = sizeof(wc);
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
	wc.hCursor	= LoadCursor( NULL, IDC_ARROW );
	wc.hIcon	= LoadIcon( NULL, IDI_APPLICATION );
	wc.hIconSm	= LoadIcon( NULL, IDI_APPLICATION );
	wc.hInstance= m_win32HINSTANCE;
	wc.lpfnWndProc = ::WndProc;
	wc.lpszClassName = m_strClassName.c_str();
	wc.lpszMenuName  = NULL;

	//Node:	注册窗口
	if( !RegisterClassEx( &wc ) ){
		CTHROW( "ScreenSys_InitWIN32 RegisterClassEx ERROR" );
		return E_FAIL;
	}


	//Node:	创建窗口
	m_win32HWND = CreateWindowEx( NULL, m_strClassName.c_str(), m_strCaptionName.c_str(), WS_OVERLAPPEDWINDOW, 0, 0, _width, _height, NULL, NULL, m_win32HINSTANCE, NULL );
	if( NULL == m_win32HWND ){
		CTHROW( "ScreenSys_InitWIN32 CreateWindowEx ERROR" );
		return E_FAIL;
	}

	
	UpdateWindow( m_win32HWND );
	ShowWindow( m_win32HWND, SW_SHOW );
	return S_OK;
}

HRESULT ScreenSys_Win32::ScreenSys_UnInitWin32( ){
	return S_OK;
}



LRESULT ScreenSys_Win32::ScreenSys_ProcessWin32( void (*BackCallFunc)() ){

	static DWORD LastTime = timeGetTime();

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

			DWORD deltaTime = LastTime - CurrentTime;

			BackCallFunc();

			LastTime = CurrentTime;
		}
	}
	return msg.wParam;
}



/*----------------------------------------------------------------------------------------------------------------*/
/*------------------------------------------------------ScreenSys_Win32 class-------------------------------------*/
/*----------------------------------------------------------------------------------------------------------------*/
VisualSys_D3D9::VisualSys_D3D9( ScreenSys_Win32* _pScreenSysObject ){
	m_pD3D9	= NULL;
	m_pD3D9Device = NULL;
	m_pD3D9SurfaceBack   = NULL;
	m_pD3D9DrawingBorad  = NULL;


	m_pScreenSysWin32_Object = _pScreenSysObject;
	//m_VertexStream.reserve(1024);
	//m_VertexStream.clear();

	m_win32IsWindowed = true;

	m_win32BeginDrawBD = 0;
}
VisualSys_D3D9::~VisualSys_D3D9(){
	VisualSys_UnInitD3D9();
}
HRESULT VisualSys_D3D9::VisualSys_InitD3D9( DWORD _iswindowed ){
	m_win32IsWindowed = _iswindowed;
	HRESULT hr;
	//HWND hwnd = _hwnd;
	//DWORD width = _width;
	//DWORD height= _height;
	//Node:		创建IDirect3D9对象
	if( NULL == (m_pD3D9 = Direct3DCreate9( D3D_SDK_VERSION ) ) ){
		CTHROW( "VisualSys_InitD3D9, Direct3DCreate9 ERROR" );
		return E_FAIL;
	}

	//Node:		获取当前显示模式
	D3DDISPLAYMODE mode;
	ZeroMemory( &mode, sizeof(mode) );
	if( FAILED( hr = m_pD3D9->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &mode ))){
		CTHROW( "VisualSys_InitD3D9, GetAdapterDisplayMode ERROR" );
		return hr;
	}

	if( NULL == m_pScreenSysWin32_Object ){
		CTHROW( "VisualSys_InitD3D9, m_pScreenSysWin32_Object ERROR" );
		return hr;
	}

	//Node: 填写显卡适配器设备信息
	//		以及创建Direct3DDevice9设备
	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory( &d3dpp, sizeof(d3dpp) );
	d3dpp.BackBufferWidth  = m_pScreenSysWin32_Object->m_win32WIDTH; 
	d3dpp.BackBufferHeight = m_pScreenSysWin32_Object->m_win32HEIGHT;
	d3dpp.BackBufferFormat = mode.Format;
	d3dpp.BackBufferCount  = 1;
	d3dpp.Windowed		   = 1;
	d3dpp.hDeviceWindow	   = m_pScreenSysWin32_Object->m_win32HWND;
	d3dpp.EnableAutoDepthStencil = FALSE;
	d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
	d3dpp.MultiSampleType	= D3DMULTISAMPLE_NONE;
	d3dpp.MultiSampleQuality= 0;
	d3dpp.Flags = 0;
	d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
	d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;	//关闭垂直同步
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;					//着个表示表明让Direct3D选择最佳的前后台缓存交换模式


	if( FAILED( m_pD3D9->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,m_pScreenSysWin32_Object->m_win32HWND, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &m_pD3D9Device  ) ) ){
		CTHROW( "VisualSys_InitD3D9, CreateDevice ERROR" );
		return hr;
	}

	//Note:	清理后背表面的颜色
	if( NULL == m_pD3D9Device ){
		CTHROW( "VisualSys_InitD3D9, g_pD3DDevice9 ERROR" );
		return E_FAIL;
	}
	if( FAILED( hr = m_pD3D9Device->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0,0,0 ), 1.0f, 0 ) )){
		CTHROW( "VisualSys_InitD3D9, Clear ERROR" );
		return hr;
	}

	//Note:	获得后背缓存
	if( FAILED( hr = m_pD3D9Device->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &m_pD3D9SurfaceBack ) ) ){
		CTHROW( "VisualSys_InitD3D9, GetBackBuffer ERROR" );
		return hr;
	}

	//Note: 创建画板drawing board
	if( FAILED(  m_pD3D9Device->CreateOffscreenPlainSurface( m_pScreenSysWin32_Object->m_win32WIDTH, m_pScreenSysWin32_Object->m_win32HEIGHT,mode.Format, D3DPOOL_DEFAULT, &m_pD3D9DrawingBorad, NULL ) ) ){
		CTHROW( "VisualSys_InitD3D9, CreateOffscreenPlainSurface ERROR" );
		return hr;
	}

	//Note:	释放IDirect3D接口
	if(FAILED( hr = m_pD3D9->Release() )){
		CTHROW( "VisualSys_InitD3D9, Release ERROR" );
		return hr;
	}
	return S_OK;
}
HRESULT VisualSys_D3D9::VisualSys_UnInitD3D9(){

	if( m_pD3D9DrawingBorad ){
		m_pD3D9DrawingBorad->Release();
		m_pD3D9DrawingBorad = NULL;
	}
	if( m_pD3D9SurfaceBack ){
		m_pD3D9SurfaceBack->Release();
		m_pD3D9SurfaceBack = NULL;
	}
	if( m_pD3D9Device ){
		m_pD3D9Device->Release();
		m_pD3D9Device = NULL;
	}
	return S_OK;
}

HRESULT VisualSys_D3D9::VisualSys_DrawPixelToDB( int _x, int _y, DWORD _color ){

	if( 0 == m_win32BeginDrawBD ){
		return E_FAIL;
	}

	//Node: Pitch表示一个表面上一行像素的长度 
	int linePixel = 0;

	WORD*	pBits16 = NULL;
	DWORD*	pBits32 = NULL;


	//等下再修改这个
	switch( 32 ){
	case 16:
		linePixel = m_D3D9rc.Pitch / sizeof(WORD);
		pBits16 = (WORD*)m_D3D9rc.pBits;
		//Note: 填充像素
		pBits16[_y*linePixel +_x] = (WORD)_color;
		break;
	case 32:
		linePixel = m_D3D9rc.Pitch / sizeof(DWORD);
		pBits32 = (DWORD*)m_D3D9rc.pBits;
		pBits32[_y*linePixel +_x] = _color;		
		break;
	default:
		break;
	}
    return S_OK;
}

HRESULT	VisualSys_D3D9::VisualSys_BeginDrawingBoardD3D9(){
	HRESULT hr;

	//Node:	将定点数据流填入画板
	if( NULL == m_pD3D9Device ){
		
		return E_FAIL;
	}

	//
	if( FAILED( hr = m_pD3D9Device->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0,0,0 ), 1.0f, 0 ) )){
		CTHROW( "VisualSys_InitD3D9, Clear ERROR" );
		return hr;
	}

	if( 0 == m_win32BeginDrawBD ){
		ZeroMemory(&m_D3D9rc,sizeof(m_D3D9rc)); 
		if( FAILED( hr = m_pD3D9DrawingBorad->LockRect( &m_D3D9rc, NULL, D3DLOCK_DISCARD ) ) ){
 			CTHROW( "VisualSys_BeginDrawingBoard LockRect ERROR" );
			return hr;
		}
	}

	m_win32BeginDrawBD = 1;

	return S_OK;
}
HRESULT VisualSys_D3D9::VisualSys_EndDrawingBoardD3D9(){
	HRESULT hr;

	//Node: 解锁表面
	if( 1 == m_win32BeginDrawBD ){
		if( FAILED( hr = m_pD3D9DrawingBorad->UnlockRect() ) ){
			 CTHROW( "VisualSys_BeginDrawingBoard UnlockRect ERROR" );
			return hr;
		}
	}

	if( FAILED( hr = m_pD3D9Device->StretchRect( m_pD3D9DrawingBorad, 0, m_pD3D9SurfaceBack, 0, D3DTEXF_NONE ) ) ){
		CTHROW( "VisualSys_EndDrawingBoard StretchRect ERROR" );
		return hr;
	}

	//执行切换
	if( FAILED( hr = m_pD3D9Device->Present(0, 0, 0, 0) ) ){
		CTHROW( "VisualSys_EndDrawingBoard Present ERROR" );
		return hr;
	}

	//清除画板内容
	if( FAILED( hr = m_pD3D9Device->ColorFill( m_pD3D9DrawingBorad, NULL, D3DCOLOR_ARGB( 0, 0, 0, 0 ) ) ) ){
		CTHROW( "VisualSys_EndDrawingBoard ColorFill ERROR" );
		return hr;
	}

	m_win32BeginDrawBD = 0;

	return S_OK;
}
/*----------------------------------------------------------------------------------------------------------------*/
/*------------------------------------------------------VisualSys_Soft2D class------------------------------------*/
/*----------------------------------------------------------------------------------------------------------------*/
VisualSys_Soft2D::VisualSys_Soft2D( VisualSys_D3D9* _pObject ){
	m_pVisualD3D9SysObject = _pObject;
}
VisualSys_Soft2D::~VisualSys_Soft2D(){
	delete m_pVisualD3D9SysObject;
	m_pVisualD3D9SysObject = NULL;
}



void VisualSys_Soft2D::VisualSys_DrawLine( int x1, int y1, int x2, int y2, DWORD color ){

	//Node:	开始绘制起点
	int beginPosX = x1;
	int beginPosY = y1;
	//Node: 增加判断值
	int error = 0;

	//Node:	距离
	int dx = x2 - x1;
	int dy = y2 - y1;

	//Node:	增长方式
	int x_inc = 0;
	int y_inc = 0;

	if( dx > 0 ){
		//Node:	正方向增长
		x_inc = 1;
	}else{
		//Node:	负方向增长
		x_inc = -1;
		dx = -dx;	//取得绝对值
	}

	if( dy > 0 ){
		y_inc = 1;
	}else{
		y_inc = -1;
		dy = -dy;
	}


	//误差减小
	int dx2 = dx * 2;
	int dy2 = dy * 2;

	if( dx > dy ){
		//Node:	小于45度斜角
		error = dy2 - dx;

		for( int index = 0; index < dx; ++index  ){
			//Node:	开始增加
			if( error >= 0 ){

				//Node:	error重置掉
				error -= dx;
				beginPosY+=y_inc;
			}
			//Node:	
			error += dy;
			beginPosX+=x_inc;
			m_pVisualD3D9SysObject->VisualSys_DrawPixelToDB( beginPosX, beginPosY, color );
		}
	}else{
		//Node: 大于45度斜角
		error = dx2 - dy;

		for( int index = 0; index < dy; ++index  ){
			//Node:	开始增加
			if( error >= 0 ){

				//Node:	error重置掉
				error -= dy;
				beginPosX+=x_inc;
			}
			//Node:	
			error += dx;
			beginPosY+=y_inc;
			m_pVisualD3D9SysObject->VisualSys_DrawPixelToDB( beginPosX, beginPosY, color );
		}

	}
}
void VisualSys_Soft2D::VisualSys_DrawLineEx( int x1, int y1, int x2, int y2, DWORD color ){
	int _x1 = x1;
	int _y1 = y1;
	int _x2 = x2;
	int _y2 = y2;

	VisualSys_ClipLine( _x1, _y1, _x2, _y2 );
	VisualSys_DrawLine( _x1, _y1, _x2, _y2, color );
}


void VisualSys_Soft2D::VisualSys_ClipLine( int& x1, int& y1, int& x2, int& y2 ){

	//Node:	裁剪标记
	static const unsigned int CLIP_CODE_C = 0x00000000;	//不需要裁剪
	static const unsigned int CLIP_CODE_N = 0x00000008;	//裁剪最小y值	上北
	static const unsigned int CLIP_CODE_S = 0x00000004;	//裁剪最大y值	下南
	static const unsigned int CLIP_CODE_W = 0x00000001;	//裁剪最小x值	左西
	static const unsigned int CLIP_CODE_E = 0x00000002;	//裁剪最大x值	右东

	static const unsigned int CLIP_CODE_NE = 0x0000000A;	//裁剪最小y值,最大x值	东北 0x0000000A = 0x00000008(北) + 0x00000002(东);
	static const unsigned int CLIP_CODE_SE = 0x00000006;	//裁剪最大x值,最大y值	东南 0x00000006 = 0x00000004(南) + 0x00000002(东);
	static const unsigned int CLIP_CODE_SW = 0x00000005;	//裁剪最小x值,最大y值	西南 0x00000005 = 0x00000004(南) + 0x00000001(西);
	static const unsigned int CLIP_CODE_NW = 0x00000009;	//裁剪最小x值,最小y值	西北 0x00000009 = 0x00000008(北) + 0x00000001(西);

	int xc1  = x1;	
	int yc1	 = y1;	
	int xc2  = x2;	
	int yc2  = y2;	

	unsigned int p1_code = 0;	//裁剪标记1	用于坐标1 (x1,y1)
	unsigned int p2_code = 0;	//裁剪标记2	用于坐标2 (x2,y2)

	//裁剪y1
	if( y1 < m_ClipMiny )
		p1_code |= CLIP_CODE_N;
	else if( y1 > m_ClipMaxy )
		p1_code |= CLIP_CODE_S;
	//裁剪x1
	if( x1 < m_ClipMinx )
		p1_code |= CLIP_CODE_W;
	else if( x1 > m_ClipMaxx )
		p1_code |= CLIP_CODE_E;

	//裁剪y2
	if( y2 < m_ClipMiny )
		p2_code |= CLIP_CODE_N;
	else if( y2 > m_ClipMaxy )
		p2_code |= CLIP_CODE_S;
	//裁剪x2
	if( x2 < m_ClipMinx )
		p2_code |= CLIP_CODE_W;
	else if( x2 > m_ClipMaxx )
		p2_code |= CLIP_CODE_E;

	//Node:	不需要裁剪没有超出裁剪范围
	if( CLIP_CODE_C == p1_code && CLIP_CODE_C == p2_code )
		return;

	//Node:	裁剪使用的是直线两点式公式
		//	(( y - y1 ) / ( x - x1 )) = (( y2 - y1 ) / ( x2 - x1 ))
	//Node:	需要裁剪坐标1 (x1,y1)
	switch( p1_code ){

	case CLIP_CODE_C:
		//无需裁剪
		break;
	case CLIP_CODE_N:
		//Node:	获得最小y值后,求x值
		yc1 = m_ClipMiny;
		//(xc1 - x1) / ( m_ClipMiny - y1 ) = ( x2 - x1 ) / ( y2 - y1 );
		xc1 = (x2 - x1)/(y2 - y1) * ( m_ClipMiny - y1 ) + x1 + 0.5;		//+0.5减少精度的缺失
		break;
	case CLIP_CODE_S:
		//Node:	获得最大y值后,求x值
		yc1 = m_ClipMaxy;
		//(xc1 - x1) / ( m_ClipMaxy - y1 ) = ( x2 - x1 ) / ( y2 - y1 );
		xc1 = (x2 - x1)/(y2 - y1) * ( m_ClipMaxy - y1 ) + x1 + 0.5;
		break;
	case CLIP_CODE_W:
		//Node:	获得最小x值后,求y值
		xc1 = m_ClipMinx;
		//( yc1 - y1 )/( m_ClipMinx - x1 ) = ( y2 - y1 ) / ( x2 - x1 );
		yc1 = ( y2 - y1 ) / ( x2 - x1 ) * ( m_ClipMinx - x1 ) + y1 + 0.5;
		break;
	case CLIP_CODE_E:
		//Node:	获得最大x值后,求y值
		xc1 = m_ClipMaxx;
		//( yc1 - y1 )/( m_ClipMinx - x1 ) = ( y2 - y1 ) / ( x2 - x1 );
		yc1 = ( y2 - y1 ) / ( x2 - x1 ) * ( m_ClipMaxx - x1 ) + y1 + 0.5;
		break;
	case CLIP_CODE_NE:
		yc1 = m_ClipMiny;
		xc1 = (x2 - x1)/(y2 - y1) * ( m_ClipMiny - y1 ) + x1 + 0.5;

		if( xc1 < m_ClipMinx || xc1 > m_ClipMaxx ){
			xc1 = m_ClipMaxx;
			yc1 = ( y2 - y1 ) / ( x2 - x1 ) * ( m_ClipMaxx - x1 ) + y1 + 0.5;
		}
		break;
	case CLIP_CODE_SE:
		yc1 = m_ClipMaxy;
		xc1 = (x2 - x1)/(y2 - y1) * ( m_ClipMaxy - y1 ) + x1 + 0.5;
		if( xc1 < m_ClipMinx || xc1 > m_ClipMaxx ){
			xc1 = m_ClipMaxx;
			yc1 = ( y2 - y1 ) / ( x2 - x1 ) * ( m_ClipMaxx - x1 ) + y1 + 0.5;
		}
		break;
	case CLIP_CODE_SW:
		yc1 = m_ClipMaxy;
		xc1 = (x2 - x1)/(y2 - y1) * ( m_ClipMaxy - y1 ) + x1 + 0.5;
		if( xc1 < m_ClipMinx || xc2 > m_ClipMaxx ){
			xc1 = m_ClipMinx;
			yc1 = ( y2 - y1 ) / ( x2 - x1 ) * ( m_ClipMinx - x1 ) + y1 + 0.5;
		}
		break;
	case CLIP_CODE_NW:
		yc1 = m_ClipMiny;
		xc1 = (x2 - x1)/(y2 - y1) * ( m_ClipMiny - y1 ) + x1 + 0.5;
		if( xc1 < m_ClipMinx || xc1 > m_ClipMaxx ){
			xc1 = m_ClipMinx;
			yc1 = ( y2 - y1 ) / ( x2 - x1 ) * ( m_ClipMinx - x1 ) + y1 + 0.5;
		}
		break;
	}
	switch(p2_code){

	case CLIP_CODE_C: 
		break;
	case CLIP_CODE_N:
		yc2 = m_ClipMiny;
		xc2 = x2 + (m_ClipMiny-y2)*(x1-x2)/(y1-y2);
		break;
	case CLIP_CODE_S:
		yc2 = m_ClipMaxy;
		xc2 = x2 + (m_ClipMaxy-y2)*(x1-x2)/(y1-y2);
		break;
	case CLIP_CODE_W:
		xc2 = m_ClipMinx;
		yc2 = y2 + (m_ClipMinx-x2)*(y1-y2)/(x1-x2);
		break;
	case CLIP_CODE_E:
		xc2 = m_ClipMaxx;
		yc2 = y2 + (m_ClipMaxx-x2)*(y1-y2)/(x1-x2);
		break;
	case CLIP_CODE_NE:
		yc2 = m_ClipMiny;
		xc2 = x2 + 0.5+(m_ClipMiny-y2)*(x1-x2)/(y1-y2);
		if (xc2 < m_ClipMinx || xc2 > m_ClipMaxx){
			xc2 = m_ClipMaxx;
			yc2 = y2 + 0.5+(m_ClipMaxx-x2)*(y1-y2)/(x1-x2);
		}
		break;
	  
	case CLIP_CODE_SE:
		yc2 = m_ClipMaxy;
		xc2 = x2 + 0.5+(m_ClipMaxy-y2)*(x1-x2)/(y1-y2);	
		if (xc2 < m_ClipMinx || xc2 > m_ClipMaxx){
			xc2 = m_ClipMaxx;
			yc2 = y2 + 0.5+(m_ClipMaxx-x2)*(y1-y2)/(x1-x2);
		}
		break;
	case CLIP_CODE_NW: 
		yc2 = m_ClipMiny;
		xc2 = x2 + 0.5+(m_ClipMiny-y2)*(x1-x2)/(y1-y2);
		if (xc2 < m_ClipMinx || xc2 > m_ClipMaxx){
			xc2 = m_ClipMinx;
		    yc2 = y2 + 0.5+(m_ClipMinx-x2)*(y1-y2)/(x1-x2);	
		} 
		break;
	case CLIP_CODE_SW:
		yc2 = m_ClipMaxy;
		xc2 = x2 + 0.5+(m_ClipMaxy-y2)*(x1-x2)/(y1-y2);	
		if (xc2 < m_ClipMinx || xc2 > m_ClipMaxx){
			xc2 = m_ClipMinx;
		    yc2 = y2 + 0.5+(m_ClipMinx-x2)*(y1-y2)/(x1-x2);	
		}
		break;
	
	default:
		  break;

	}


	if( (xc1 < m_ClipMinx) || (xc1 > m_ClipMaxx) ||
		(yc1 < m_ClipMiny) || (yc1 > m_ClipMaxy) ||
		(xc2 < m_ClipMinx) || (xc2 > m_ClipMaxx) ||
		(yc2 < m_ClipMiny) || (yc2 > m_ClipMaxy) ){
		return;
	} 

	x1 = xc1;
	y1 = yc1;
	x2 = xc2;
	y2 = yc2;

}
void VisualSys_Soft2D::VisualSys_SetClipRect( int min_x, int min_y, int max_x, int max_y ){
	m_ClipMinx = min_x;
	m_ClipMiny = min_y;
	m_ClipMaxx = max_x;
	m_ClipMaxy = max_y;
}
void VisualSys_Soft2D::VisualSys_SetClipRect( RECT* _pRect ){
	m_ClipMinx = _pRect->left;
	m_ClipMiny = _pRect->top;
	m_ClipMaxx = _pRect->right;
	m_ClipMaxy = _pRect->bottom;
}

void VisualSys_Soft2D::VisualSys_DrawPolygon2D( const cPolygon2D* _pPolygon ){
	int index = 0;
	if( _pPolygon->state ){
		//Node:	进行绘制

		//Node:	绘制从第一个点到最后一个点
		for( ; index < (_pPolygon->num_vertes - 1); ++index ){
			VisualSys_DrawLineEx( _pPolygon->vlist[index].x+_pPolygon->posX, _pPolygon->vlist[index].y+_pPolygon->posY, 
								  _pPolygon->vlist[index+1].x+_pPolygon->posX, _pPolygon->vlist[index+1].y+_pPolygon->posY, _pPolygon->color );
		}

		//Node:	将第一个点和最后一个点连接起来
		VisualSys_DrawLineEx( _pPolygon->vlist[0].x+_pPolygon->posX, _pPolygon->vlist[0].y+_pPolygon->posY, 
							  _pPolygon->vlist[index].x+_pPolygon->posX, _pPolygon->vlist[index].y+_pPolygon->posY, _pPolygon->color );

	}else{
		//Node:	不绘制
		return;
	}
	return;
}



/*----------------------------------------------------------------------------------------------------------------*/
/*------------------------------------------------------ScreenSys_Win32 class-------------------------------------*/
/*----------------------------------------------------------------------------------------------------------------*/
void cPolygon2D::Translate( int dx, int dy ){
	posX+=dx; 
	posY+=dy;
}
void cPolygon2D::Rotate( float angle ){
	//Node:	旋转
	//Node:	利用三角公式-和差化积公式
	//sin( angle1 + angle2 ) = sin( angle1 )*cos( angle2 ) + cos( angle1 )* sin( angle1 )
	//sin( angle1 - angle2 ) = sin( angle1 )*cos( angle2 ) - cos( angle1 )* sin( angle1 )
	//cos( angle1 + angle2 ) = cos( angle1 )*cos( angle2 ) - sin( angle1 )* sin( angle2 )
	//cos( angle1 - angle2 ) = cos( angle1 )*cos( angle2 ) + sin( angle1 )* sin( angle2 )

	//化简下
	//xr = r * cos( angle1 + angle2 ) = "展开略去" = x*cos( angle2 ) + y*sin( angle2 )
	//yr = r * sin( angle1 + angle2 ) = "展开略去" = x*sin( angle2 ) + y*cos( angle2 )


	for( int index = 0; index < num_vertes; ++index ){
		float xr = vlist[index].x*cos(angle) - vlist[index].y*sin(angle);
		float yr = vlist[index].x*sin(angle) - vlist[index].y*cos(angle);

		//覆盖旧坐标
		vlist[index].x = xr;
		vlist[index].y = yr;
	}
}
void cPolygon2D::Scale( float sx, float sy ){
	for( int index = 0; index < num_vertes; ++index ){
		vlist[index].x *= sx;
		vlist[index].y *= sy;
	}
}

/*----------------------------------------------------------------------------------------------------------------*/
/*------------------------------------------------------SetllaEngine class----------------------------------------*/
/*----------------------------------------------------------------------------------------------------------------*/
SetllaEngine::SetllaEngine(){
	m_pScreenSysObject = new ScreenSys_Win32();
	m_pVisualSysObject = new VisualSys_D3D9( m_pScreenSysObject );
	m_pVisualSysSotfObject = new VisualSys_Soft2D( m_pVisualSysObject );
}
SetllaEngine::~SetllaEngine(){
	delete m_pScreenSysObject;
	m_pScreenSysObject = NULL;
	delete m_pVisualSysObject;
	m_pVisualSysObject = NULL;
	delete m_pVisualSysSotfObject;
	m_pVisualSysSotfObject = NULL;
}

HRESULT SetllaEngine::Setlla_Init( HINSTANCE _hInstance, DWORD _width, DWORD _height, DWORD _iswindowed ){
	m_pScreenSysObject->ScreenSys_InitWin32( _hInstance, _width, _height );
	m_pVisualSysObject->VisualSys_InitD3D9( _iswindowed );
	m_pVisualSysSotfObject->VisualSys_SetClipRect( 0, 0,_width, _height  );
	return S_OK;
}
HRESULT SetllaEngine::Setlla_UnInit(){
	m_pScreenSysObject->ScreenSys_UnInitWin32();
	m_pVisualSysObject->VisualSys_UnInitD3D9();
	return S_OK;
}

HRESULT SetllaEngine::Setlla_Process( void(*_pFunction)() ){
	m_pScreenSysObject->ScreenSys_ProcessWin32( _pFunction );
	return S_OK;
}

HRESULT SetllaEngine::Setlla_BeginRender(){
	m_pVisualSysObject->VisualSys_BeginDrawingBoardD3D9();
	return S_OK;
}
HRESULT SetllaEngine::Setlla_EndRender(){
	m_pVisualSysObject->VisualSys_EndDrawingBoardD3D9();
	return S_OK;
}
HRESULT SetllaEngine::Setlla_DrawPixel( int _x, int _y, DWORD _color ){
	m_pVisualSysObject->VisualSys_DrawPixelToDB( _x, _y, _color );
	return S_OK;
}
HRESULT SetllaEngine::Setlla_DrawLine( int x1, int y1, int x2, int y2, DWORD color ){
	m_pVisualSysSotfObject->VisualSys_DrawLine( x1, y1, x2, y2, color );
	return S_OK;
}
HRESULT SetllaEngine::Setlla_DrawLineEx( int x1, int y1, int x2, int y2, DWORD color ){
	m_pVisualSysSotfObject->VisualSys_DrawLineEx( x1, y1, x2, y2, color );
	return S_OK;
}
HRESULT SetllaEngine::Setlla_DrawPolygon2D( const cPolygon2D* _pPolygon ){
	m_pVisualSysSotfObject->VisualSys_DrawPolygon2D( _pPolygon );
	return S_OK;
}


 
  

你可能感兴趣的:(游戏引擎)