额。暂时只是提供了基本表面画线实现其他以后补上。
写完以后顺便改写3D游戏编程大师技巧。
DirectDraw7太老了。
在wind8和wind7老是出现莫名的错误,而且不好调试。
用DX9分装了,就只用了IDirect3DSurface9接口。
额没有用流水管线。
以后用软件算法实现
纹理其他什么的暂时不想用。只想用软件模拟算法。所以至于速度什么的,你懂的。
献丑了。源码呈上
IDE:VS2012 EXPRESS
/*
作者:钱启新
版本:0000 0001 //以便于以后更新方便增加了什么
只是很简单很简单的封装以后慢慢改写完美化。
*/
#ifndef __T3DLIB2_HEADFILE_H__
#define __T3DLIB2_HEADFILE_H__
#include"T3DlibCommon.h"
#include <Windows.h>
#include <d3d9.h>
#include <vector>
#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; }