25. GameProject3

main.h main.cpp 无变化

define.h

#ifndef _UGP_DEFINES_H_
#define _UGP_DEFINES_H_

#include
<windows.h>

// Boolean values.
#define UGP_INVALID -1
#define UGP_OK 1
#define UGP_FAIL 0

// Light type defines.
#define LIGHT_POINT 1
#define LIGHT_DIRECTIONAL 2
#define LIGHT_SPOT 3

// Window handle (need new way if porting to Mac and OpenGL).
#define WinHWND HWND

// Typedefs and enumerations.
typedef long VertexType;

enum PrimType
{
NULL_TYPE,
POINT_LIST,
TRIANGLE_LIST,
TRIANGLE_STRIP,
TRIANGLE_FAN,
LINE_LIST,
LINE_STRIP
};

// 一些渲染状态
enum RenderState
{
CULL_NONE,
CULL_CW,
CULL_CCW,
DEPTH_NONE,
DEPTH_READONLY,
DEPTH_READWRITE,
SHADE_POINTS,
SHADE_SOLIDTRI,
SHADE_WIRETRI,
SHADE_WIREPOLY,
TRANSPARENCY_NONE,
// 禁用透明度
TRANSPARENCY_ENABLE // 启用透明度
};


// 透明度渲染状态值
enum TransState
{
TRANS_ZERO
= 1,
TRANS_ONE,
TRANS_SRCCOLOR,
TRANS_INVSRCCOLOR,
TRANS_SRCALPHA,
TRANS_INVSRCALPHA,
TRANS_DSTALPHA,
TRANS_INVDSTALPHA,
TRANS_DSTCOLOR,
TRANS_INVDSTCOLOR,
TRANS_SRCALPHASAT,
TRANS_BOTHSRCALPHA,
TRANS_INVBOTHSRCALPHA,
TRANS_BLENDFACTOR,
TRANS_INVBLENDFACTOR
};

// 纹理过滤器的过滤模式
enum TextureState
{
MIN_FILTER,
// 缩小率
MAG_FILTER, // 放大率
MIP_FILTER // mipmap纹理级别
};

// 纹理过滤器类型
enum FilterType
{
POINT_TYPE,
// 最近点采样
LINEAR_TYPE, // 线性纹理过滤
ANISOTROPIC_TYPE // 各向异性纹理过滤
};

// Color defines.
#define UGPCOLOR_ARGB(a,r,g,b) ((unsigned long)((((a)&0xff)<<24)|\
(((r)
&0xff)<<16)|(((g)&0xff)<<8)|\
((b)
&0xff)))

#endif

  

RenderInterface.h

#ifndef _UGP_RENDERINTERFACE_H_
#define _UGP_RENDERINTERFACE_H_

#include
"defines.h"
#include
"material.h"
#include
"light.h"


class CRenderInterface
{
public:
CRenderInterface() : m_screenWidth(
0), m_screenHeight(0), m_near(0), m_far(0) { }
virtual ~CRenderInterface() {}

// 初始化D3D
// @w 窗口的宽度
// @h 窗口的高度
// @mainWin 初始化D3D用到的窗口句柄
// @fullScreen 是否全屏
virtual bool Initialize(int w, int h, WinHWND mainWin, bool fullScreen) = 0;

// 一些可以一次性的设置的D3D渲染状态的初始化操作
virtual void OneTimeInit() = 0;

// 关闭引擎释放资源
virtual void Shutdown() = 0;

// 设置清屏幕用的颜色
virtual void SetClearCol(float r, float g, float b) = 0;

// 开始渲染之前的一些必须操作
// @bColor D3D的Clear是否清空目标缓存
// @bDepth D3D的Clear是否清空深度缓存
// @bStencil D3D的Clear是否清空模板缓存
virtual void StartRender(bool bColor, bool bDepth, bool bStencil) = 0;

// 结束渲染的之前的一些必须操作
// @bColor D3D的Clear是否清空目标缓存
// @bDepth D3D的Clear是否清空深度缓存
// @bStencil D3D的Clear是否清空模板缓存
virtual void ClearBuffers(bool bColor, bool bDepth, bool bStencil) = 0;

// 结束渲染并将渲染结果输出到屏幕
virtual void EndRendering() = 0;

// 应用材质
// @mat 被应用的材质对象指针
virtual void SetMaterial(stMaterial *mat) = 0;

// 开启光照
// @light 被应用的光源对象指针
// @index 指定需要激活的光源的序号值0-7
virtual void SetLight(stLight *light, int index) = 0;

// 禁止光照
virtual void DisableLight(int index) = 0;

// 设置深度测试
virtual void SetDepthTesting(RenderState state) = 0;

// 设置透明度
// @state 正在设置的渲染状态
// @src 源混合操作(源融合因子)
// @dst 目的混合操作(目标融合因子)
virtual void SetTransparency(RenderState state, TransState src, TransState dst) = 0;

// 添加2D纹理
// @file 图像文件名
// @texId 新创建纹理对象的id
virtual int AddTexture2D(char *file, int *texId) = 0;

// 设置纹理过滤器
// @index 纹理采样属性的纹理层ID(0~7)
// @filter 滤波器模式
// @val 滤波器值
virtual void SetTextureFilter(int index, int filter, int val) = 0;

// 设置多纹理贴图
virtual void SetMultiTexture() = 0;

// 应用纹理
// @index 纹理层id 0-7
// @texId 纹理的计数器id
virtual void ApplyTexture(int index, int texId) = 0;

// 保存屏幕截图
virtual void SaveScreenShot(char *file) = 0;

// 启用点状sprite
// @size sprite的尺寸
// @min 最小尺寸
// @a 参数a
// @b 参数b
// @c 参数c
virtual void EnablePointSprites(float size, float min, float a, float b, float c) = 0;

// 禁用点状sprite
virtual void DisablePointSprites() = 0;

// 计算并设置透视投影矩阵
// @fov 摄像机镜头的夹角(在Y轴上的成像角度)
// @n 近平截面的距离
// @f 远平截面的距离
virtual void CalculateProjMatrix(float fov, float n, float f) = 0;

// 计算并设置正交投影矩阵
// @n 近平截面的距离
// @f 远平截面的距离
virtual void CalculateOrthoMatrix(float n, float f) = 0;

// 创建要绘制的静态顶点缓存
// @VertexType
// @PrimType 渲染静态缓存时要用的图元类型
// @totalVerts 顶点个数
// @totalIndices 索引个数
// @stride 单个顶点的尺寸
// @data 存储顶点数据的缓冲区指针
// @indices 存储顶点索引数据的缓冲区指针
// @staticId 返回刚刚创建的顶点缓存的索引id
virtual int CreateStaticBuffer(VertexType, PrimType,
int totalVerts, int totalIndices,
int stride, void **data, unsigned int *indices,
int *staticId) = 0;

// 渲染
// @staticId 渲染函数要使用的顶点缓存的索引id
virtual int Render(int staticId) = 0;

protected:
int m_screenWidth; // 屏幕宽度
int m_screenHeight; // 屏幕高度
bool m_fullscreen; // 是否渲染整个屏幕

WinHWND m_mainHandle;
// D3D初始化函数所需要的窗口句柄

float m_near; // 投影矩阵所需的近距离值
float m_far; // 投影矩阵所需的远距离值
};

#endif

  

D3DRenderer.h

#ifndef _D3D_RENDERER_H_
#define _D3D_RENDERER_H_

#include
<windows.h>
#include
<d3d9.h>
#include
<d3dx9.h>
#include
"RenderInterface.h"

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


struct stD3DStaticBuffer
{
stD3DStaticBuffer() : vbPtr(
0), ibPtr(0), numVerts(0),
numIndices(
0), stride(0), fvf(0),
primType(NULL_TYPE) {}

LPDIRECT3DVERTEXBUFFER9 vbPtr;
// 顶点缓存
LPDIRECT3DINDEXBUFFER9 ibPtr; // 索引缓存
int numVerts; //定点计数器
int numIndices; // 索引计数器
int stride; // 单个顶点的尺寸幅度值
unsigned long fvf; // Direct3D顶点FVF
PrimType primType; // 在渲染静态缓存时要用的图元类型
};

// 纹理信息结构
struct stD3DTexture
{
stD3DTexture() : fileName(
0), image(0), width(0), height(0) {}

char *fileName;
int width, height;
LPDIRECT3DTEXTURE9 image;
};


class CD3DRenderer : public CRenderInterface
{
public:
CD3DRenderer();
~CD3DRenderer();

bool Initialize(int w, int h, WinHWND mainWin,
bool fullScreen);
void Shutdown();

void SetClearCol(float r, float g, float b);
void StartRender(bool bColor, bool bDepth, bool bStencil);
void ClearBuffers(bool bColor, bool bDepth, bool bStencil);
void EndRendering();

void SetMaterial(stMaterial *mat);

void SetLight(stLight *light, int index);

void DisableLight(int index);

void SetDepthTesting(RenderState state);

void SetTransparency(RenderState state, TransState src, TransState dst);

int AddTexture2D(char *file, int *texId);

void SetTextureFilter(int index, int filter, int val);

void SetMultiTexture();

void ApplyTexture(int index, int texId);

void SaveScreenShot(char *file);

void EnablePointSprites(float size, float min, float a, float b, float c);

void DisablePointSprites();

void CalculateProjMatrix(float fov, float n, float f);
void CalculateOrthoMatrix(float n, float f);

int CreateStaticBuffer(VertexType, PrimType,
int totalVerts, int totalIndices,
int stride, void **data, unsigned int *indices,
int *staticId);

int Render(int staticId);

private:
void OneTimeInit();


private:
D3DCOLOR m_Color;
LPDIRECT3D9 m_Direct3D;
LPDIRECT3DDEVICE9 m_Device;
bool m_renderingScene;

stD3DStaticBuffer
*m_staticBufferList; // 静态顶点缓存列表的头指针
int m_numStaticBuffers; // 顶点缓存个数
int m_activeStaticBuffer; // 当前活动的顶点缓存的索引id

stD3DTexture
*m_textureList; //纹理对象列表,这里将存储所有的纹理对象,并使用ID访问它们
int m_numTextures; // 纹理对象计数器
};

bool CreateD3DRenderer(CRenderInterface **pObj);

#endif

  

D3DRenderer.cpp

#include"D3DRenderer.h"

inline unsigned long FtoDW(float val)

{

return *((unsigned long*)&val);

}

bool CreateD3DRenderer(CRenderInterface **pObj)

{

if(!*pObj) *pObj = new CD3DRenderer;

else return false;

return true;

}

unsigned long CreateD3DFVF(int flags)

{

unsigned long fvf = 0;

return fvf;

}

CD3DRenderer::CD3DRenderer()

{

m_Direct3D = NULL;

m_Device = NULL;

m_renderingScene = false;

m_numStaticBuffers = 0;

m_activeStaticBuffer = UGP_INVALID;

m_staticBufferList = NULL;

m_textureList = NULL;

m_numTextures = 0;

}

CD3DRenderer::~CD3DRenderer()

{

Shutdown();

}

bool CD3DRenderer::Initialize(int w, int h, WinHWND mainWin,

 bool fullScreen)

{

Shutdown();

m_mainHandle = mainWin;

if(!m_mainHandle) return false;

m_fullscreen = fullScreen;

D3DDISPLAYMODE mode;

D3DCAPS9 caps;

D3DPRESENT_PARAMETERS Params;

ZeroMemory(&Params, sizeof(Params));

m_Direct3D = Direct3DCreate9(D3D_SDK_VERSION);

if(!m_Direct3D) return false;

if(FAILED(m_Direct3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,

&mode))) return false;

if(FAILED(m_Direct3D->GetDeviceCaps(D3DADAPTER_DEFAULT,

D3DDEVTYPE_HAL, &caps))) return false;

DWORD processing = 0;

if(caps.VertexProcessingCaps != 0)

processing = D3DCREATE_HARDWARE_VERTEXPROCESSING |

D3DCREATE_PUREDEVICE;

else

processing = D3DCREATE_SOFTWARE_VERTEXPROCESSING;

if(m_fullscreen)

{

Params.FullScreen_RefreshRateInHz = mode.RefreshRate;

Params.PresentationInterval = D3DPRESENT_INTERVAL_ONE;

}

else

Params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

Params.Windowed = !m_fullscreen;

Params.BackBufferWidth = w;

Params.BackBufferHeight = h;

Params.hDeviceWindow = m_mainHandle;

Params.SwapEffect = D3DSWAPEFFECT_DISCARD;

Params.BackBufferFormat = mode.Format;

Params.BackBufferCount = 1;

Params.EnableAutoDepthStencil = TRUE;

Params.AutoDepthStencilFormat = D3DFMT_D16;

m_screenWidth = w;

m_screenHeight = h;

if(FAILED(m_Direct3D->CreateDevice(D3DADAPTER_DEFAULT,

D3DDEVTYPE_HAL, m_mainHandle, processing,

&Params, &m_Device))) return false;

if(m_Device == NULL) return false;

OneTimeInit();

return true;

}

void CD3DRenderer::OneTimeInit()

{

if(!m_Device) return;

m_Device->SetRenderState(D3DRS_LIGHTING, FALSE);

m_Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

SetTextureFilter(0, MAG_FILTER, ANISOTROPIC_TYPE);

SetTextureFilter(0, MIN_FILTER, ANISOTROPIC_TYPE);

SetTextureFilter(0, MIP_FILTER, ANISOTROPIC_TYPE);

CalculateProjMatrix(D3DX_PI / 4, 0.1f, 1000);

}

void CD3DRenderer::Shutdown()

{

for(int s = 0; s < m_numStaticBuffers; s++)

{

if(m_staticBufferList[s].vbPtr)

{

m_staticBufferList[s].vbPtr->Release();

m_staticBufferList[s].vbPtr = NULL;

}

if(m_staticBufferList[s].ibPtr)

{

m_staticBufferList[s].ibPtr->Release();

m_staticBufferList[s].ibPtr = NULL;

}

}

m_numStaticBuffers = 0;

if(m_staticBufferList) delete[] m_staticBufferList;

m_staticBufferList = NULL;

for(int s = 0; s < m_numTextures; s++)

{

if(m_textureList[s].fileName)

{

delete[] m_textureList[s].fileName;

m_textureList[s].fileName = NULL;

}

if(m_textureList[s].image)

{

m_textureList[s].image->Release();

m_textureList[s].image = NULL;

}

}

m_numTextures = 0;

if(m_textureList) delete[] m_textureList;

m_textureList = NULL;

if(m_Device) m_Device->Release();

if(m_Direct3D) m_Direct3D->Release();

m_Device = NULL;

m_Direct3D = NULL;

}

void CD3DRenderer::SetClearCol(float r, float g, float b)

{

m_Color = D3DCOLOR_COLORVALUE(r, g, b, 1.0f);

}

void CD3DRenderer::StartRender(bool bColor, bool bDepth,

  bool bStencil)

{

if(!m_Device) return;

unsigned int buffers = 0;

if(bColor) buffers |= D3DCLEAR_TARGET;

if(bDepth) buffers |= D3DCLEAR_ZBUFFER;

if(bStencil) buffers |= D3DCLEAR_STENCIL;

if(FAILED(m_Device->Clear(0, NULL, buffers, m_Color, 1, 0)))

return;

if(FAILED(m_Device->BeginScene())) return;

m_renderingScene = true;

}

void CD3DRenderer::ClearBuffers(bool bColor, bool bDepth,

bool bStencil)

{

if(!m_Device) return;

unsigned int buffers = 0;

if(bColor) buffers |= D3DCLEAR_TARGET;

if(bDepth) buffers |= D3DCLEAR_ZBUFFER;

if(bStencil) buffers |= D3DCLEAR_STENCIL;

if(m_renderingScene) m_Device->EndScene();

if(FAILED(m_Device->Clear(0, NULL, buffers, m_Color, 1, 0)))

return;

if(m_renderingScene)

if(FAILED(m_Device->BeginScene())) return;

}

void CD3DRenderer::EndRendering()

{

if(!m_Device) return;

m_Device->EndScene();

m_Device->Present(NULL, NULL, NULL, NULL);

m_renderingScene = false;

}

void CD3DRenderer::SetMaterial(stMaterial *mat)

{

if(!mat || !m_Device) return;

D3DMATERIAL9 m = { mat->diffuseR, mat->diffuseG,

mat->diffuseB, mat->diffuseA,

mat->ambientR, mat->ambientG,

mat->ambientB, mat->ambientA,

mat->specularR, mat->specularG,

mat->specularB, mat->specularA,

mat->emissiveR, mat->emissiveG,

mat->emissiveB, mat->emissiveA,

mat->power

};

m_Device->SetMaterial(&m);

}

void CD3DRenderer::SetLight(stLight *light, int index)

{

if(!light || !m_Device || index < 0) return;

D3DLIGHT9 l;

l.Ambient.a = light->ambientA;

l.Ambient.r = light->ambientR;

l.Ambient.g = light->ambientG;

l.Ambient.b = light->ambientB;

l.Attenuation0 = light->attenuation0;

l.Attenuation1 = light->attenuation1;

l.Attenuation2 = light->attenuation2;

l.Diffuse.a = light->diffuseA;

l.Diffuse.r = light->diffuseR;

l.Diffuse.g = light->diffuseG;

l.Diffuse.b = light->diffuseB;

l.Direction.x = light->dirX;

l.Direction.y = light->dirY;

l.Direction.z = light->dirZ;

l.Falloff = light->falloff;

l.Phi = light->phi;

l.Position.x = light->posX;

l.Position.y = light->posY;

l.Position.z = light->posZ;

l.Range = light->range;

l.Specular.a = light->specularA;

l.Specular.r = light->specularR;

l.Specular.g = light->specularG;

l.Specular.b = light->specularB;

l.Theta = light->theta;

if(light->type == LIGHT_POINT) l.Type = D3DLIGHT_POINT;

else if (light->type == LIGHT_SPOT) l.Type = D3DLIGHT_SPOT;

else l.Type = D3DLIGHT_DIRECTIONAL;

m_Device->SetLight(index, &l);

m_Device->LightEnable(index, TRUE);

}

void CD3DRenderer::DisableLight(int index)

{

if(!m_Device) return;

m_Device->LightEnable(index, FALSE);

}

void CD3DRenderer::SetDepthTesting(RenderState state)

{

if(!m_Device) return;

if(state == DEPTH_NONE)

{

m_Device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);

m_Device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);

}

else if(state == DEPTH_READONLY)

{

m_Device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);

m_Device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);

}

else if(state == DEPTH_READWRITE)

{

m_Device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);

m_Device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);

}

}

void CD3DRenderer::SetTransparency(RenderState state, TransState src, TransState dst)

{

if(!m_Device) return;

// 若状态标识符相符,则禁用透明度

if(state == TRANSPARENCY_NONE)

{

m_Device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);

return;

}

// 若状态标识符相符,启用透明度

if(state == TRANSPARENCY_ENABLE)

{

m_Device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);

switch(src)

{

case TRANS_ZERO:

m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);

break;

case TRANS_ONE:

m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);

break;

case TRANS_SRCCOLOR:

m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR);

break;

case TRANS_INVSRCCOLOR:

m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVSRCCOLOR);

break;

case TRANS_SRCALPHA:

m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);

break;

case TRANS_INVSRCALPHA:

m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVSRCALPHA);

break;

case TRANS_DSTALPHA:

m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);

break;

case TRANS_INVDSTALPHA:

m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVDESTALPHA);

break;

case TRANS_DSTCOLOR:

m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR);

break;

case TRANS_INVDSTCOLOR:

m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVDESTCOLOR);

break;

case TRANS_SRCALPHASAT:

m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHASAT);

break;

case TRANS_BOTHSRCALPHA:

m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_BOTHSRCALPHA);

break;

case TRANS_INVBOTHSRCALPHA:

m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_BOTHINVSRCALPHA);

break;

case TRANS_BLENDFACTOR:

m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_BLENDFACTOR);

break;                  

case TRANS_INVBLENDFACTOR:

m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVBLENDFACTOR);

break;

default:

m_Device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);

return;

break;

}

switch(dst)

{

case TRANS_ZERO:

m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);

break;

case TRANS_ONE:

m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);

break;

case TRANS_SRCCOLOR:

m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR);

break;

case TRANS_INVSRCCOLOR:

m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR);

break;

case TRANS_SRCALPHA:

m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCALPHA);

break;

case TRANS_INVSRCALPHA:

m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

break;

case TRANS_DSTALPHA:

m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);

break;

case TRANS_INVDSTALPHA:

m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);

break;

case TRANS_DSTCOLOR:

m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTCOLOR);

break;

case TRANS_INVDSTCOLOR:

m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVDESTCOLOR);

break;

case TRANS_SRCALPHASAT:

m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCALPHASAT);

break;

case TRANS_BOTHSRCALPHA:

m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_BOTHSRCALPHA);

break;

case TRANS_INVBOTHSRCALPHA:

m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_BOTHINVSRCALPHA);

break;

case TRANS_BLENDFACTOR:

m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_BLENDFACTOR);

break;                  

case TRANS_INVBLENDFACTOR:

m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVBLENDFACTOR);

break;

default:

m_Device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);

break;

}

}

}

int CD3DRenderer::AddTexture2D(char *file, int *texId)

{

if(!file || !m_Device) return UGP_FAIL;

int len = strlen(file);

if(!len) return UGP_FAIL;

int index = m_numTextures;

if(!m_textureList)

{

m_textureList = new stD3DTexture[1];

if(!m_textureList) return UGP_FAIL;

}

else

{

stD3DTexture *temp;

temp = new stD3DTexture[m_numTextures + 1];

memcpy(temp, m_textureList, sizeof(stD3DTexture) * m_numTextures);

delete[] m_textureList;

m_textureList = temp;

}

m_textureList[index].fileName = new char[len];

memcpy(m_textureList[index].fileName, file, len);

D3DCOLOR colorkey = 0xff000000;

D3DXIMAGE_INFO info;

if(D3DXCreateTextureFromFileEx(m_Device, file, 0, 0, 0, 0,

D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT,

D3DX_DEFAULT,  colorkey, &info, NULL,

&m_textureList[index].image) != D3D_OK) return false;

m_textureList[index].image->SetAutoGenFilterType(D3DTEXF_LINEAR);

m_textureList[index].image->GenerateMipSubLevels();

m_textureList[index].width = info.Width;

m_textureList[index].height = info.Height;

*texId = m_numTextures;

m_numTextures++;

return UGP_OK;

}

void CD3DRenderer::SetTextureFilter(int index, int filter, int val)

{

if(!m_Device || index < 0) return;

D3DSAMPLERSTATETYPE fil = D3DSAMP_MINFILTER;

int v = D3DTEXF_POINT;

if(filter == MIN_FILTER) fil = D3DSAMP_MINFILTER;

if(filter == MAG_FILTER) fil = D3DSAMP_MAGFILTER;

if(filter == MIP_FILTER) fil = D3DSAMP_MIPFILTER;

if(val == POINT_TYPE) v = D3DTEXF_POINT;

if(val == LINEAR_TYPE) v = D3DTEXF_LINEAR;

if(val == ANISOTROPIC_TYPE) v = D3DTEXF_ANISOTROPIC;

m_Device->SetSamplerState(index, fil, v);

}

void CD3DRenderer::SetMultiTexture()

{

if(!m_Device) return;

/* 设置纹理的渲染状态

HRESULT  SetTextureStageState(      

DWORD Stage,                   //当前设置的多级纹理的索引

D3DTEXTURESTAGESTATETYPE Type, //纹理渲染状态的类型

DWORD Value                    //纹理渲染状态的值,与类型相对应

);

*/

m_Device->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);

m_Device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);

m_Device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);

m_Device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);

m_Device->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);

m_Device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);

m_Device->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);

m_Device->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);

}

void CD3DRenderer::ApplyTexture(int index, int texId)

{

if(!m_Device) return;

if(index < 0 || texId < 0)

m_Device->SetTexture(0, NULL);

else

m_Device->SetTexture(0, m_textureList[texId].image);

}

void CD3DRenderer::SaveScreenShot(char *file)

{

if(!file) return;

LPDIRECT3DSURFACE9 surface = NULL;

D3DDISPLAYMODE disp;

m_Device->GetDisplayMode(0, &disp);

m_Device->CreateOffscreenPlainSurface(disp.Width, disp.Height,

D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface, NULL);

m_Device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);

D3DXSaveSurfaceToFile(file, D3DXIFF_JPG, surface, NULL, NULL);

if(surface != NULL) 

surface->Release();

surface = NULL;

}

void CD3DRenderer::EnablePointSprites(float size, float min,

 float a, float b, float c)

{

if(!m_Device) return;

m_Device->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);

m_Device->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE);

m_Device->SetRenderState(D3DRS_POINTSIZE, FtoDW(size));

m_Device->SetRenderState(D3DRS_POINTSIZE_MIN, FtoDW(min));

m_Device->SetRenderState(D3DRS_POINTSCALE_A, FtoDW(a));

m_Device->SetRenderState(D3DRS_POINTSCALE_B, FtoDW(b));

m_Device->SetRenderState(D3DRS_POINTSCALE_C, FtoDW(c));

}

void CD3DRenderer::DisablePointSprites()

{

m_Device->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);

m_Device->SetRenderState(D3DRS_POINTSCALEENABLE, FALSE);

}

void CD3DRenderer::CalculateProjMatrix(float fov, float n, float f)

{

if(!m_Device) return;

D3DXMATRIX projection;

D3DXMatrixPerspectiveFovLH(&projection, fov,

(float)m_screenWidth/(float)m_screenHeight, n, f);

m_Device->SetTransform(D3DTS_PROJECTION, &projection);

}

void CD3DRenderer::CalculateOrthoMatrix(float n, float f)

{

if(!m_Device) return;

D3DXMATRIX ortho;

D3DXMatrixOrthoLH(&ortho, (float)m_screenWidth,

(float)m_screenHeight, n, f);

m_Device->SetTransform(D3DTS_PROJECTION, &ortho);

}

int CD3DRenderer::CreateStaticBuffer(VertexType vType,

PrimType primType, int totalVerts,

int totalIndices, int stride, void **data,

unsigned int *indices, int *staticId)

{

void *ptr;

int index = m_numStaticBuffers;

if(!m_staticBufferList)

{

m_staticBufferList = new stD3DStaticBuffer[1];

if(!m_staticBufferList) return UGP_FAIL;

}

else

{

stD3DStaticBuffer *temp;

temp = new stD3DStaticBuffer[m_numStaticBuffers + 1];

memcpy(temp, m_staticBufferList,

sizeof(stD3DStaticBuffer) * m_numStaticBuffers);

delete[] m_staticBufferList;

m_staticBufferList = temp;

}

m_staticBufferList[index].numVerts = totalVerts;

m_staticBufferList[index].numIndices = totalIndices;

m_staticBufferList[index].primType = primType;

m_staticBufferList[index].stride = stride;

m_staticBufferList[index].fvf = CreateD3DFVF(vType);

if(totalIndices > 0)

{

if(FAILED(m_Device->CreateIndexBuffer(sizeof(unsigned int) *

totalIndices, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16,

D3DPOOL_DEFAULT,

&m_staticBufferList[index].ibPtr,

NULL))) return UGP_FAIL;

if(FAILED(m_staticBufferList[index].ibPtr->Lock(0, 0,

(void**)&ptr, 0))) return UGP_FAIL;

memcpy(ptr, indices, sizeof(unsigned int) * totalIndices);

m_staticBufferList[index].ibPtr->Unlock();

}

else

{

m_staticBufferList[index].ibPtr = NULL;

}

if(FAILED(m_Device->CreateVertexBuffer(totalVerts * stride,

D3DUSAGE_WRITEONLY, m_staticBufferList[index].fvf,

D3DPOOL_DEFAULT, &m_staticBufferList[index].vbPtr,

NULL))) return UGP_FAIL;

if(FAILED(m_staticBufferList[index].vbPtr->Lock(0, 0,

(void**)&ptr, 0))) return UGP_FAIL;

memcpy(ptr, data, totalVerts * stride);

m_staticBufferList[index].vbPtr->Unlock();

*staticId = m_numStaticBuffers;

m_numStaticBuffers++;

return UGP_OK;

}

int CD3DRenderer::Render(int staticId)

{

if(staticId >= m_numStaticBuffers) return UGP_FAIL;

if(m_activeStaticBuffer != staticId)

{

if(m_staticBufferList[staticId].ibPtr != NULL)

m_Device->SetIndices(m_staticBufferList[staticId].ibPtr); //使用的索引缓冲区指针

m_Device->SetStreamSource(0,

m_staticBufferList[staticId].vbPtr, 0,

m_staticBufferList[staticId].stride);

m_Device->SetFVF(m_staticBufferList[staticId].fvf);

m_activeStaticBuffer = staticId;

}

if(m_staticBufferList[staticId].ibPtr != NULL)

{

switch(m_staticBufferList[staticId].primType)

{

case POINT_LIST:

if(FAILED(m_Device->DrawPrimitive(D3DPT_POINTLIST,

0, m_staticBufferList[staticId].numVerts)))

return UGP_FAIL;

break;

case TRIANGLE_LIST:

if(FAILED(m_Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0,

0, m_staticBufferList[staticId].numVerts / 3,

0, m_staticBufferList[staticId].numIndices)))

return UGP_FAIL;

break;

case TRIANGLE_STRIP:

if(FAILED(m_Device->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0,

0, m_staticBufferList[staticId].numVerts / 2,

0, m_staticBufferList[staticId].numIndices)))

return UGP_FAIL;

break;

case TRIANGLE_FAN:

if(FAILED(m_Device->DrawIndexedPrimitive(D3DPT_TRIANGLEFAN, 0,

0, m_staticBufferList[staticId].numVerts / 2,

0, m_staticBufferList[staticId].numIndices)))

return UGP_FAIL;

break;

case LINE_LIST:

if(FAILED(m_Device->DrawIndexedPrimitive(D3DPT_LINELIST, 0,

0, m_staticBufferList[staticId].numVerts / 2,

0, m_staticBufferList[staticId].numIndices)))

return UGP_FAIL;

break;

case LINE_STRIP:

if(FAILED(m_Device->DrawIndexedPrimitive(D3DPT_LINESTRIP, 0,

0, m_staticBufferList[staticId].numVerts,

0, m_staticBufferList[staticId].numIndices)))

return UGP_FAIL;

break;

default:

return UGP_FAIL;

}

}

else

{

switch(m_staticBufferList[staticId].primType)

{

case POINT_LIST:

if(FAILED(m_Device->DrawPrimitive(D3DPT_POINTLIST,

0, m_staticBufferList[staticId].numVerts)))

return UGP_FAIL;

break;

case TRIANGLE_LIST:

if(FAILED(m_Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0,

(int)(m_staticBufferList[staticId].numVerts / 3))))

return UGP_FAIL;

break;

case TRIANGLE_STRIP:

if(FAILED(m_Device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0,

(int)(m_staticBufferList[staticId].numVerts / 2))))

return UGP_FAIL;

break;

case TRIANGLE_FAN:

if(FAILED(m_Device->DrawPrimitive(D3DPT_TRIANGLEFAN, 0,

(int)(m_staticBufferList[staticId].numVerts / 2))))

return UGP_FAIL;

break;

case LINE_LIST:

if(FAILED(m_Device->DrawPrimitive(D3DPT_LINELIST, 0,

m_staticBufferList[staticId].numVerts / 2)))

return UGP_FAIL;

break;

case LINE_STRIP:

if(FAILED(m_Device->DrawPrimitive(D3DPT_LINESTRIP, 0,

m_staticBufferList[staticId].numVerts)))

return UGP_FAIL;

break;

default:

return UGP_FAIL;

}

}

return UGP_OK;

}

原文地址:https://www.cnblogs.com/kex1n/p/2159354.html