额。暂时只是提供了基本表面画线实现其他以后补上。
写完以后顺便改写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;
}