简单修改一下也能变成玻璃效果,天上掉玻璃了
主文件
- //
- // 文件: main.cpp
- // 作者:CYM
- // *雾特效,旋转的立方体,底面!~简单演示
- // *方向键控制摄像头
- // *shift使摄像头向上ctrl使摄像头向下
- //
- #include "D3DFrame.h"
- #include "Box.h"
- #include "Ground.h"
- #include "Drawtext.h"
- #include "Sprite.h"
- #include <d3d9.h>
- #include <d3dx9.h>
- void SetFogEffects(D3DCAPS9 caps,bool isFogEnable); //设置雾效果函数声明
- //
- // 全局设置
- //
- IDirect3DDevice9* Device = 0; //定义设备对象
- IDirect3DTexture9* Texture1; //立方体纹理
- IDirect3DTexture9* Texture2; //地面地图纹理
- IDirect3DTexture9* Texture3; //简单的粒子文理纹理
- LPD3DXFONT Font; //定义字体
- CD3DFrame Frame; //定义框架类
- CGround* Ground=0; //定义场地类
- CBox* Box1 = 0; //定义Box对象
- CBox* Box2 = 0;
- CDrawtext* Text=0; //定义文字绘制对象
- CSprite* Point; //定义sprite点对象
- D3DMATERIAL9 material;
- D3DXMATRIX Map; //地图矩阵
- D3DXMATRIX V; //视图矩阵
- D3DXVECTOR3 Txyz1(-3,2,-3); //矩阵平移坐标
- D3DXVECTOR3 Rxyz1(0,0,0); //矩阵旋转坐标
- const int Width = 640; //窗口的宽高
- const int Height = 480;
- static RECT FontRect={0,0,Width,Height}; //绘制文字的矩形
- static D3DXVECTOR3 position( 0.0f, 3.0f, 3.0f ); //摄像机位置
- static D3DXVECTOR3 target(0.0f, 0.0f, 0.0f); //摄像机观察目标
- static D3DXVECTOR3 up(0.0f, 1.0f, 0.0f); //摄像机高度
- //static D3DXVECTOR3 SpritePos(10.0f,10.0f,-10.0f); //Sprite点的坐标
- D3DCAPS9 caps; //设备功能支持的结构体
- bool isFogEnable=true; //判断雾效果是否开启
- static float timeConversion=0.1f; //时间转换(速度同步)数值
- //
- // 框架函数
- //
- bool Setup()
- {
- //创造对象
- Box1 = new CBox(Device);
- Box2 = new CBox(Device);
- Ground = new CGround(Device);
- Text = new CDrawtext(Device,Font);
- Point = new CSprite(Device);
- Device->GetDeviceCaps(&caps); //获取设备功能支持信息的结构体
- //设置纹理
- //D3DMATERIAL9 material;
- ::ZeroMemory(&material, sizeof(material));
- material.Ambient=D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
- material.Diffuse=D3DXCOLOR(1.0f, 1.0f, 0.1f, 1.0f);
- material.Emissive=D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
- material.Power=0.1f;
- material.Specular=D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f);
- //设置平行光
- D3DLIGHT9 light;
- ::ZeroMemory(&light, sizeof(light));
- light.Type = D3DLIGHT_DIRECTIONAL;
- light.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
- light.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
- light.Specular = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
- light.Direction = D3DXVECTOR3(1.0f, -1.0f, 0.0f);
- Device->SetLight(0, &light);
- Device->LightEnable(0, true);
- //设置平行光
- D3DLIGHT9 light2;
- ::ZeroMemory(&light2, sizeof(light2));
- light2.Type = D3DLIGHT_DIRECTIONAL;
- light2.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
- light2.Diffuse = D3DXCOLOR(0.1f, 0.5f, 0.4f, 1.0f);
- light2.Specular = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
- light2.Direction = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
- Device->SetLight(1, &light2);
- Device->LightEnable(1, true);
- Device->SetRenderState(D3DRS_NORMALIZENORMALS, true); //正常的渲染等级
- Device->SetRenderState(D3DRS_SPECULARENABLE, true); //镜面高光
- D3DXMatrixLookAtLH(&V, &position, &target, &up); //设置摄像机
- Device->SetTransform(D3DTS_VIEW, &V); //视图转换
- //
- // Create texture.
- //
- //载入立方体纹理
- D3DXCreateTextureFromFile(
- Device,
- "crate.jpg",
- &Texture1);
- //载入地面纹理
- D3DXCreateTextureFromFile(
- Device,
- "河流.jpg",
- &Texture2);
- D3DXCreateTextureFromFile(
- Device,
- "雪球.tga",
- &Texture3);
- //
- // Set Texture Filter States.
- //
- Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
- Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
- Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
- Device->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
- Device->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
- Device->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
- Device->SetSamplerState(3, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
- Device->SetSamplerState(3, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
- Device->SetSamplerState(3, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
- //
- // Set the projection matrix.
- //
- D3DXMATRIX proj;
- D3DXMatrixPerspectiveFovLH(
- &proj,
- D3DX_PI * 0.5f, // 90 - degree
- (float)Width / (float)Height,
- 1.0f,
- 1000.0f);
- Device->SetTransform(D3DTS_PROJECTION, &proj);
- //设置雾效果
- SetFogEffects(caps,true);
- Device->SetRenderState(D3DRS_LIGHTING,true);
- Device->SetRenderState(D3DRS_AMBIENT,D3DXCOLOR(0.3f,0.4f,0.5f,1.0f));
- Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); // 不剔除任何面
- return true;
- }
- void Cleanup()
- {
- Frame.Delete<CSprite*>(Point);
- Frame.Delete<CBox*>(Box2);
- Frame.Delete<CBox*>(Box1);
- Frame.Delete<CGround*>(Ground);
- Frame.Delete<CDrawtext*>(Text);
- Frame.Release<LPD3DXFONT>(Font);
- Frame.Release<IDirect3DTexture9*>(Texture3);
- Frame.Release<IDirect3DTexture9*>(Texture2);
- Frame.Release<IDirect3DTexture9*>(Texture1);
- }
- //设置摄像机函数
- void SetMatrixLookAt(D3DXMATRIX* V, D3DXVECTOR3* position, D3DXVECTOR3* target, D3DXVECTOR3* up)
- {
- D3DXMatrixLookAtLH(V, position, target, up); //设置摄像机
- Device->SetTransform(D3DTS_VIEW, V); //视图转换
- }
- //设置雾特效函数
- void SetFogEffects(D3DCAPS9 caps,bool isFogEnable)
- {
- // 雾特效的开始和结束距离数值
- float start = 12, end = 15;
- // 设置雾的相关属性
- Device->SetRenderState(D3DRS_FOGENABLE, isFogEnable); // 启用雾效果
- // 设置要渲染的雾的期望颜色(这里为灰色)
- Device->SetRenderState(D3DRS_FOGCOLOR,D3DCOLOR_XRGB(128, 128, 128));
- // 使用顶点雾
- Device->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
- // 指定雾的开始距离和终点距离
- Device->SetRenderState(D3DRS_FOGSTART, *(DWORD*)(&start));
- Device->SetRenderState(D3DRS_FOGEND, *(DWORD*)(&end));
- // Pixel Fog 像素雾
- //Device->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
- // 如果支持,则启用基于距离的雾
- if(caps.RasterCaps & D3DPRASTERCAPS_FOGRANGE)
- Device->SetRenderState(D3DRS_RANGEFOGENABLE, true);
- }
- //数值计算函数
- bool Calculation(void)
- {
- //*start:立方体1(箱子)的矩阵变化数值计算
- Rxyz1.x+=0.005f;
- Rxyz1.y+=0.005f;
- Rxyz1.z+=0.005f;
- if( Rxyz1.x>=2*D3DX_PI) //当角度达到360时,赋值为零
- Rxyz1.x=0.0f;
- if( Rxyz1.y>=2*D3DX_PI) //当角度达到360时,赋值为零
- Rxyz1.y=0.0f;
- if( Rxyz1.z>=2*D3DX_PI) //当角度达到360时,赋值为零
- Rxyz1.z=0.0f;
- //end:立方体1(箱子)数值计算;
- //*start:文字绘制矩形区域数值变化
- timeConversion+=0.1f; //速度同步数值累加
- if(timeConversion>=2.0f) //timeConversion累加到2.0f是,执行文字矩形框的数值计算
- {
- timeConversion=0.1f; //重置初始值
- FontRect.left+=1;
- FontRect.top+=1;
- FontRect.right-=1;
- FontRect.bottom-=1;
- if(FontRect.left>=Width/2) //当矩形left大于100是重置为零
- FontRect.left=0;
- if(FontRect.top>=Height/2) //当矩形top大于100是重置为零
- FontRect.top=0;
- if(FontRect.right<=Width/2) //当矩形right小于400是重置为Width(窗口宽度)
- FontRect.right=Width;
- if(FontRect.bottom<=Height/2) //当矩形bottom小于200是重置为Height(窗口高度)
- FontRect.bottom=Height;
- }
- return true;
- }
- bool Display(float timeDelta)
- {
- if( Device ) //如果设备对象不为空
- {
- //数值计算;
- Calculation();
- Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(00,00,00), 1.0f, 0);
- //开始渲染
- Device->BeginScene();
- Device->SetTransform(D3DTS_VIEW,&V);
- //绘制立方体
- Box1->SetCalculation(Txyz1,Rxyz1); //设置数值计算后的值
- Box1->Draw(&material,Texture1); //绘制最终立方体
- Box2->SetCalculation(D3DXVECTOR3(3,2,-3),D3DXVECTOR3(0,0,0));
- Box2->Draw(&material,Texture1); //绘制最终立方体
- Ground->DrawGround(&Map,&material,Texture2); //绘制地形(地图)
- //显示文字
- Text->DrawTextA(NULL,"雾特效,旋转的立方体,河流底面,雪花飘!~简单演示~",
- -1,&FontRect,DT_CENTER,D3DCOLOR_XRGB(255,255,255));
- //绘制sprite点
- Point->Draw(Texture3);
- //结束渲染
- Device->EndScene();
- Device->Present(0, 0, 0, 0);
- }
- return true;
- }
- //
- // 消息处理
- //
- LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- switch( msg )
- {
- case WM_DESTROY:
- ::PostQuitMessage(0);
- break;
- case WM_KEYDOWN:
- switch(wParam)
- {
- case VK_ESCAPE:
- ::DestroyWindow(hwnd);
- break;
- case VK_LEFT:
- target.x+=0.2f; //摄像机观察目标向左移动
- position.x+=0.2f; //摄像机位置向左移动
- SetMatrixLookAt( &V,&position, &target,&up); //设置摄像机函数
- break;
- case VK_RIGHT:
- target.x-=0.2f; //摄像机观察目标向右移动
- position.x-=0.2f; //摄像机位置向右移动
- SetMatrixLookAt( &V,&position, &target,&up); //设置摄像机函数
- break;
- case VK_UP:
- target.z-=0.2f; //摄像机观察目标向前移动
- position.z-=0.2f; //摄像机向前移动
- SetMatrixLookAt( &V,&position, &target,&up); //设置摄像机函数
- break;
- case VK_DOWN:
- target.z+=0.2f; //摄像机观察目标向后移动
- position.z+=0.2f; //摄像机位置向后移动
- SetMatrixLookAt( &V,&position, &target,&up); //设置摄像机函数
- break;
- case VK_SHIFT:
- position.y+=0.2f; //摄像机位置向上移动
- SetMatrixLookAt( &V,&position, &target,&up); //设置摄像机函数
- break;
- case VK_CONTROL:
- position.y-=0.2f; //摄像机位置向下移动
- SetMatrixLookAt( &V,&position, &target,&up); //设置摄像机函数
- break;
- case VK_SPACE:
- isFogEnable=(isFogEnable==1?0:1); //启动或关闭雾效果
- SetFogEffects(caps,isFogEnable);
- break;
- }
- }
- return ::DefWindowProc(hwnd, msg, wParam, lParam);
- }
- //
- // 入口函数
- //
- int WINAPI WinMain(HINSTANCE hinstance,
- HINSTANCE prevInstance,
- PSTR cmdLine,
- int showCmd)
- {
- WNDCLASS wc;
- wc.style = CS_HREDRAW | CS_VREDRAW;
- wc.lpfnWndProc = (WNDPROC)WndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hinstance;
- wc.hIcon = LoadIcon(0, IDI_APPLICATION);
- wc.hCursor = LoadCursor(0, IDC_ARROW);
- wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
- wc.lpszMenuName = 0;
- wc.lpszClassName = "Direct3D9App";
- if( !RegisterClass(&wc) )
- {
- ::MessageBox(0, "RegisterClass() - FAILED", 0, 0);
- return false;
- }
- //初始化D3D
- if(!Frame.InitD3D(hinstance,
- 640, 480, true, D3DDEVTYPE_HAL, &Device))
- {
- ::MessageBox(0, "InitD3D() - FAILED", 0, 0);
- return 0;
- }
- if(!Setup())
- {
- ::MessageBox(0, "Setup() - FAILED", 0, 0);
- return 0;
- }
- //进入游戏循环
- Frame.EnterMsgLoop( Display );
- Cleanup();
- Device->Release();
- return 0;
- }
两个粒子系统文件
- //
- // 文件: Sprite.cpp
- // 作者:CYM
- // *简单的粒子类
- //
- #pragma once
- #include <d3d9.h>
- #include <d3dx9.h>
- #include "Vertex.h"
- #define count 1000
- struct SPRITE
- {
- D3DXVECTOR3 pos; //位置
- float speed; //粒子速度
- };
- class CSprite
- {
- public:
- CSprite(IDirect3DDevice9* device);
- ~CSprite(void);
- public:
- void Draw(IDirect3DTexture9* texture); //显示图像函数
- protected:
- void Update(void); //[内]更新数据函数
- inline unsigned long FtoDW(float v); //[内]数值转换函数
- public:
- IDirect3DDevice9* _device; //定义D3D设备
- IDirect3DVertexBuffer9* _vb; //定义顶点缓存
- IDirect3DTexture9* _texture; //定义文理
- protected:
- //sprite属性
- SPRITE _sprite[count]; //定义1000个粒子
- //int _count; //粒子数量
- unsigned long _col; //颜色
- //D3DXMATRIX* matrix; //移动矩阵
- };
- #include "Sprite.h"
- CSprite::CSprite(IDirect3DDevice9* device)
- {
- _device=device; //获取设备对象
- _col=D3DCOLOR_XRGB(255,00,00); //初始化颜色
- for(int i=0;i<=count;i++)
- {
- //初始化位置坐标和速度
- _sprite[i].pos=D3DXVECTOR3(0.0f,-1.0f,0.0f);
- _sprite[i].speed=0.0f;
- }
- _device->CreateVertexBuffer(
- count * sizeof(Vertex3),
- D3DUSAGE_WRITEONLY,
- FVF_VERTEX3,
- D3DPOOL_MANAGED,
- &_vb,
- 0);
- }
- CSprite::~CSprite(void)
- {
- if(_vb){_vb->Release(); _vb = 0;}
- }
- //数值转换函数
- unsigned long CSprite::FtoDW(float v)
- {
- return *((unsigned long*)&v);
- }
- //显示图像函数
- void CSprite::Draw(IDirect3DTexture9* texture)
- {
- _texture=texture;
- _device->SetTexture(0,_texture);
- Update(); //更新数据
- // 启用点状sprite
- _device->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
- // 启用点状sprite的比例
- _device->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE);
- //开启混合因子
- _device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
- //设置目标混合因子
- _device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
- // 设置sprite的尺寸
- _device->SetRenderState(D3DRS_POINTSIZE, FtoDW(0.1f));
- // 设置点状sprite的最小尺寸
- _device->SetRenderState(D3DRS_POINTSIZE_MIN,FtoDW(0.0f));
- // 根据距离更改点状sprite的形状
- _device->SetRenderState(D3DRS_POINTSCALE_A, FtoDW(0.0f));
- // 根据距离更改点状sprite的形状
- _device->SetRenderState(D3DRS_POINTSCALE_B, FtoDW(0.0f));
- // 根据距离更改点状sprite的形状
- _device->SetRenderState(D3DRS_POINTSCALE_C, FtoDW(1.0f));
- _device->SetFVF(FVF_VERTEX3);
- _device->SetStreamSource(0, _vb,0, sizeof(Vertex3));
- _device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0,count);
- _device->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
- _device->SetRenderState(D3DRS_POINTSCALEENABLE, FALSE);
- _device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
- }
- //更新数据函数
- void CSprite::Update()
- {
- Vertex3* v; //顶点
- _vb->Lock(0, 0, (void**)&v, 0);
- // 填充数据X正半轴,Z负半轴粒子顶点缓存数据
- for(int i=0;i<count/4;i++)
- {
- _sprite[i].pos.y-=0.01f*_sprite[i].speed;
- if(_sprite[i].pos.y<0.0f)
- {
- ::ZeroMemory(&v[i], sizeof(v[i])); //清空数据
- ::ZeroMemory(&_sprite[i], sizeof(_sprite[i])); //清空数据
- ::ZeroMemory(&_sprite[i].speed, sizeof(_sprite[i].speed)); //清空数据
- _sprite[i].speed=((rand()%20)*0.1f);
- _sprite[i].pos.x=((rand()%100)*0.1f); //随机获得x轴坐标
- _sprite[i].pos.y=5; //获得固定高度5
- _sprite[i].pos.z=((rand()%100)*-0.1f); //随机获得z轴坐标
- }
- v[i] = Vertex3(_sprite[i].pos.x, _sprite[i].pos.y,_sprite[i].pos.z,D3DCOLOR_XRGB(255,255,255));
- }
- // 填充数据X负半轴,Z负半轴粒子顶点缓存数据
- for(int i=count/4;i<count/2;i++)
- {
- _sprite[i].pos.y-=0.01f*_sprite[i].speed;
- if(_sprite[i].pos.y<0.0f)
- {
- ::ZeroMemory(&v[i], sizeof(v[i])); //清空数据
- ::ZeroMemory(&_sprite[i], sizeof(_sprite[i])); //清空数据
- ::ZeroMemory(&_sprite[i].speed, sizeof(_sprite[i].speed)); //清空数据
- _sprite[i].speed=((rand()%20)*0.1f);
- _sprite[i].pos.x=((rand()%100)*-0.1f); //随机获得x轴坐标
- _sprite[i].pos.y=5.0f; //获得固定高度5
- _sprite[i].pos.z=((rand()%100)*-0.1f); //随机获得z轴坐标
- }
- v[i] = Vertex3(_sprite[i].pos.x, _sprite[i].pos.y,_sprite[i].pos.z,D3DCOLOR_XRGB(255,255,255));
- }
- // 填充数据X正半轴,Z正半轴粒子顶点缓存数据
- for(int i=count/2;i<count*3/4;i++)
- {
- _sprite[i].pos.y-=0.01f*_sprite[i].speed;
- if(_sprite[i].pos.y<0.0f)
- {
- ::ZeroMemory(&v[i], sizeof(v[i])); //清空数据
- ::ZeroMemory(&_sprite[i], sizeof(_sprite[i])); //清空数据
- ::ZeroMemory(&_sprite[i].speed, sizeof(_sprite[i].speed)); //清空数据
- _sprite[i].speed=((rand()%20)*0.1f);
- _sprite[i].pos.x=((rand()%100)*0.1f); //随机获得x轴坐标
- _sprite[i].pos.y=5.0f; //获得固定高度5
- _sprite[i].pos.z=((rand()%100)*0.1f); //随机获得z轴坐标
- }
- v[i] = Vertex3(_sprite[i].pos.x, _sprite[i].pos.y,_sprite[i].pos.z,D3DCOLOR_XRGB(255,255,255));
- }
- // 填充数据X负半轴,Z正半轴粒子顶点缓存数据
- for(int i=count*3/4;i<=count;i++)
- {
- _sprite[i].pos.y-=0.01f*_sprite[i].speed;
- if(_sprite[i].pos.y<0.0f)
- {
- ::ZeroMemory(&v[i], sizeof(v[i])); //清空数据
- ::ZeroMemory(&_sprite[i], sizeof(_sprite[i])); //清空数据
- ::ZeroMemory(&_sprite[i].speed, sizeof(_sprite[i].speed)); //清空数据
- _sprite[i].speed=((rand()%20)*0.1f);
- _sprite[i].pos.x=((rand()%100)*-0.1f); //随机获得x轴坐标
- _sprite[i].pos.y=5.0f; //获得固定高度5
- _sprite[i].pos.z=((rand()%100)*0.1f); //随机获得z轴坐标
- }
- v[i] = Vertex3(_sprite[i].pos.x, _sprite[i].pos.y,_sprite[i].pos.z,D3DCOLOR_XRGB(255,255,255));
- }
- _vb->Unlock();
- }
这个代码有点重复,但也不修改了,只是测试一下,还是有漏洞