C++小项目:directx11图形程序(八):particleSysclass
粒子系统类,粒子系统是游戏里细小元素的控制系统,虽然感觉上它对游戏的影响不大,但是其实有了它能给游戏增色不少。粒子系统控制着细小元素的生死,运动,纹理。对它的编写让我知道,游戏里的这一片从天空飘落的雪花其实是之前那一朵已经融化在地上的雪花。
这个类我还没有编写完整,因为我发现如果要真正实现那种很美的效果我还要多加学习啊。使用广告版技术让人觉得它真的是个粒子,开启alpha通道能让粒子与背景融为一体,开启光照能让粒子煜煜生辉,给纹理混合上颜色才能让粒子真正的变幻幻幻(不是打错字)起来。
particleSysclass.h
#pragma once
#include <d3d11.h>
#include <d3dcompiler.h>
#include <D3DX11.h>
#include <xnamath.h>
#include<time.h>
#pragma comment(lib,"d3dx11.lib")
#pragma comment(lib,"d3d11.lib")
#pragma comment(lib,"d3dcompiler.lib")
class particleSysclass
{
public:
particleSysclass();
~particleSysclass(); private:
ID3D11ShaderResourceView* m_texture;
struct vertex
{
XMFLOAT3 pos;
XMFLOAT2 tex;
};
struct particle
{
XMFLOAT3 pos;
float size;
bool alive;
};
struct constantBuffer
{
XMMATRIX world;
XMMATRIX view;
XMMATRIX pro;
}; vertex *m_vertexarray;
particle *m_particlearray;
int m_particlecountMAX;
int m_particlecountCUR;
XMFLOAT3 m_sourcepos; ID3D11Buffer *m_vertexBuffer, *m_indexBuffer;
ID3D11Buffer *m_constantBuffer;
int m_vertexCount, m_indexCount;
ID3D11SamplerState *m_samplerstate;
XMMATRIX m_worldMatrix; public:
bool Initialize(ID3D11Device* device, LPCWSTR texture, int maxcount);
void Render(ID3D11DeviceContext* context, XMMATRIX& viewmatrix, XMMATRIX& pro,
ID3D11VertexShader* vertexshader, ID3D11PixelShader* pixelshader);
void Shutdown(); private:
void Emitparticle();
void Killparticle();
void Updatebuffer(ID3D11DeviceContext* context);
void ChangeparticlePos();
bool Initbuffer(ID3D11Device* device);
void Loadtexture(ID3D11Device* device,LPCWSTR texture);
};
可以看到,粒子系统类与之前的模型类非常相像只是多了:
- 粒子数据结构,粒子数组指针,粒子最大数量,粒子当前数量(m_particlecountCUR)
- 私有方法:生成粒子,粒子湮灭,更新缓存,改变例子位置(运动),初始化缓存
particleSysclass.cpp
#include "particleSysclass.h" particleSysclass::particleSysclass()
{
m_worldMatrix = XMMatrixIdentity();
} particleSysclass::~particleSysclass()
{
} bool particleSysclass::Initialize(ID3D11Device* device, LPCWSTR texture, int maxcount)
{
m_particlecountMAX = maxcount; Loadtexture(device,texture); Initbuffer(device); m_particlearray = new particle[m_particlecountMAX]; srand((unsigned)time(NULL));
for (int i = ; i < m_particlecountMAX; i++)
{
m_particlearray[i].alive = true;
m_particlearray[i].pos.x = (((float)rand() - (float)rand()) / RAND_MAX) * ;
m_particlearray[i].pos.y = (((float)rand() - (float)rand()) / RAND_MAX) * ;
m_particlearray[i].pos.z = (((float)rand() - (float)rand()) / RAND_MAX) * ; m_particlearray[i].size = 0.05;
} return false;
} void particleSysclass::Shutdown()
{
if (m_particlearray)
{
delete m_particlearray;
}
if (m_samplerstate)
{
m_samplerstate->Release();
}
if (m_constantBuffer)
{
m_constantBuffer->Release();
}
if (m_indexBuffer)
{
m_indexBuffer->Release();
}
if (m_vertexBuffer)
{
m_vertexBuffer->Release();
}
if (m_vertexarray)
{
delete[] m_vertexarray;
}
if (m_texture)
{
m_texture->Release();
}
} void particleSysclass::Emitparticle()
{ } void particleSysclass::Killparticle()
{
} void particleSysclass::Updatebuffer(ID3D11DeviceContext* context)
{
HRESULT hr = S_OK; memset(m_vertexarray, , sizeof(vertex)*m_particlecountMAX*);
for (int i = ; i < m_particlecountMAX; i++)
{
m_vertexarray[i * ].pos.x = m_particlearray[i].pos.x - m_particlearray[i].size;
m_vertexarray[i * ].pos.y = m_particlearray[i].pos.y - m_particlearray[i].size;
m_vertexarray[i * ].pos.z = m_particlearray[i].pos.z;
m_vertexarray[i * ].tex.x = ;
m_vertexarray[i * ].tex.y = ; m_vertexarray[i * + ].pos.x = m_particlearray[i].pos.x - m_particlearray[i].size;
m_vertexarray[i * + ].pos.y = m_particlearray[i].pos.y + m_particlearray[i].size;
m_vertexarray[i * + ].pos.z = m_particlearray[i].pos.z;
m_vertexarray[i * + ].tex.x = ;
m_vertexarray[i * + ].tex.y = ; m_vertexarray[i * + ].pos.x = m_particlearray[i].pos.x + m_particlearray[i].size;
m_vertexarray[i * + ].pos.y = m_particlearray[i].pos.y - m_particlearray[i].size;
m_vertexarray[i * + ].pos.z = m_particlearray[i].pos.z;
m_vertexarray[i * + ].tex.x = ;
m_vertexarray[i * + ].tex.y = ; m_vertexarray[i * + ].pos.x = m_particlearray[i].pos.x - m_particlearray[i].size;
m_vertexarray[i * + ].pos.y = m_particlearray[i].pos.y + m_particlearray[i].size;
m_vertexarray[i * + ].pos.z = m_particlearray[i].pos.z;
m_vertexarray[i * + ].tex.x = ;
m_vertexarray[i * + ].tex.y = ; m_vertexarray[i * + ].pos.x = m_particlearray[i].pos.x + m_particlearray[i].size;
m_vertexarray[i * + ].pos.y = m_particlearray[i].pos.y + m_particlearray[i].size;
m_vertexarray[i * + ].pos.z = m_particlearray[i].pos.z;
m_vertexarray[i * + ].tex.x = ;
m_vertexarray[i * + ].tex.y = ; m_vertexarray[i * + ].pos.x = m_particlearray[i].pos.x + m_particlearray[i].size;
m_vertexarray[i * + ].pos.y = m_particlearray[i].pos.y - m_particlearray[i].size;
m_vertexarray[i * + ].pos.z = m_particlearray[i].pos.z;
m_vertexarray[i * + ].tex.x = ;
m_vertexarray[i * + ].tex.y = ;
} D3D11_MAPPED_SUBRESOURCE mappedResource; hr = context->Map(m_vertexBuffer, , D3D11_MAP_WRITE_DISCARD, , &mappedResource);
if (FAILED(hr))
{
return;
} vertex* verticesPtr = (vertex*)mappedResource.pData; memcpy(verticesPtr, (void*)m_vertexarray, (sizeof(vertex)* m_vertexCount)); context->Unmap(m_vertexBuffer, );
} void particleSysclass::ChangeparticlePos()
{ for (int i = ; i < m_particlecountMAX; i++)
{
static bool flag = true;
if (m_particlearray[i].pos.y < -)
{
flag = true;
}
if (m_particlearray[i].pos.y > )
{
flag = false;
}
if (flag)
{
m_particlearray[i].pos.y += 0.0001;
}
else
{
m_particlearray[i].pos.y -= 0.0001;
}
}
} void particleSysclass::Render(ID3D11DeviceContext* context, XMMATRIX& viewmatrix, XMMATRIX& pro,
ID3D11VertexShader* vertexshader, ID3D11PixelShader* pixelshader)
{ Killparticle(); Emitparticle(); Updatebuffer(context); ChangeparticlePos(); UINT stride = sizeof(vertex);
UINT offset = ;
context->IASetVertexBuffers(, , &m_vertexBuffer, &stride, &offset);
context->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R16_UINT, );
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); context->VSSetShader(vertexshader, NULL, ); D3D11_MAPPED_SUBRESOURCE mappedResource;
HRESULT hr = S_OK; hr = context->Map(m_constantBuffer, , D3D11_MAP_WRITE_DISCARD, , &mappedResource);
if (FAILED(hr))
{
return;
}
constantBuffer* dataPtr = (constantBuffer*)mappedResource.pData; XMMATRIX worldmatrix = m_worldMatrix;
XMMATRIX promatrix = pro;
dataPtr->world = XMMatrixTranspose(worldmatrix);
dataPtr->view = XMMatrixTranspose(viewmatrix);
dataPtr->pro = XMMatrixTranspose(promatrix); context->Unmap(m_constantBuffer, ); context->VSSetConstantBuffers(, , &m_constantBuffer);
context->PSSetShader(pixelshader, NULL, );
context->PSSetShaderResources(, , &m_texture);
context->PSSetSamplers(, , &m_samplerstate);
context->DrawIndexed(m_vertexCount, , );
} bool particleSysclass::Initbuffer(ID3D11Device* device)
{
m_vertexCount = m_indexCount = m_particlecountMAX * ; m_vertexarray = new vertex[m_vertexCount]; WORD *indices = new WORD[m_indexCount];
for (int i = ; i < m_indexCount; i++)
{
indices[i] = i;
} D3D11_BUFFER_DESC vertexbd, indexbd, constantbd;
D3D11_SUBRESOURCE_DATA vertexdata, indexdata;
HRESULT hr = S_OK; vertexbd.Usage = D3D11_USAGE_DYNAMIC;
vertexbd.ByteWidth = sizeof(vertex)* m_vertexCount;
vertexbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
vertexbd.MiscFlags = ;
vertexbd.StructureByteStride = ; vertexdata.pSysMem = m_vertexarray;
vertexdata.SysMemPitch = ;
vertexdata.SysMemSlicePitch = ; hr = device->CreateBuffer(&vertexbd, &vertexdata, &m_vertexBuffer);
if (FAILED(hr))
{
return false;
} indexbd.Usage = D3D11_USAGE_DEFAULT;
indexbd.ByteWidth = sizeof(WORD)* m_indexCount;
indexbd.BindFlags = D3D11_BIND_INDEX_BUFFER;
indexbd.CPUAccessFlags = ;
indexbd.MiscFlags = ;
indexbd.StructureByteStride = ; indexdata.pSysMem = indices;
indexdata.SysMemPitch = ;
indexdata.SysMemSlicePitch = ; hr = device->CreateBuffer(&indexbd, &indexdata, &m_indexBuffer);
if (FAILED(hr))
{
return false;
} constantbd.Usage = D3D11_USAGE_DYNAMIC;
constantbd.ByteWidth = sizeof(constantBuffer);
constantbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
constantbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
constantbd.MiscFlags = ;
constantbd.StructureByteStride = ;
hr = device->CreateBuffer(&constantbd, NULL, &m_constantBuffer);
if (FAILED(hr))
{
return false;
} D3D11_SAMPLER_DESC sampDesc;
ZeroMemory(&sampDesc, sizeof(sampDesc));
sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
sampDesc.MinLOD = ;
sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
device->CreateSamplerState(&sampDesc, &m_samplerstate); delete[] indices;
indices = ; return false;
} void particleSysclass::Loadtexture(ID3D11Device*device, LPCWSTR texture)
{
D3DX11CreateShaderResourceViewFromFile(device, texture, NULL, NULL, &m_texture, NULL);
}
Initialize(): 与前不同,这里创建缓存的工作交给了私有方法Initbuffer(),从参数获得最大粒子数量,创建并随机给他们设置位置和大小
Emitparticle(),Killparticle():偷懒还没写、、
Updatebuffer():根据粒子位置,粒子大小更改顶点的位置纹理坐标,更改好后再更新到顶点缓存里
ChangeparticlePos():更改粒子位置,即使粒子做运动,对每个粒子做位置判断,使之在-5<y<5的范围内移动,如果到了边界就往回移动
Render():渲染,与之前的model类的渲染函数类似
- 产生粒子
- 杀死粒子
- 更改顶点缓存
- 更改粒子位置
- 设置顶点缓存
- 设置索引缓存
- 设置绘制方式
- 设置顶点着色器
- 更改常量缓存,这里需要使用动态的更改方式
- 设置常量缓存
- 设置像素着色器
- 设置纹理源
- 设置取样器取样方式
- 绘制各个顶点
Initbuffer():其实这才是与之前model类最为不一样的地方,他创建的顶点缓存,常量缓存都是动态的
- 填充顶点描述结构,usage字段设置为D3D11_USAGE_DYNAMIC,CPUAccessFlags字段设置为D3D11_CPU_ACCESS_WRITE,创建顶点缓存
- 填充索引描述结构,创建索引缓存
- 填充常量缓存描述结构,usage字段设置为D3D11_USAGE_DYNAMIC,CPUAccessFlags字段设置为D3D11_CPU_ACCESS_WRITE,创建常量缓存
- 填充取样器描述,创建取样器状态。
这就是粒子系统的实现方式了,总的来说是根据1个粒子位置设置6个顶点(两个三角形)位置,更新顶点缓存,再像渲染模型一样渲染就好了。我们其实也很容易想到,粒子就是微小的、结构更加简单、数量更为庞大的模型。不过虽说如此,要实现非常漂亮的图形学程序,还是需要对高级着色语言,directx的各种功能做深入的了解。
C++小项目:directx11图形程序(八):particleSysclass的更多相关文章
- C++小项目:directx11图形程序(一):主框架
最近在学习DIRECTX11,在学习过程中编写了一个程序,到现在发现这个程序也有几行代码了,结构还算整齐,就想把这个程序分享出来,其中涉及到了C++程序的架构,windows窗口程序编写,和Direc ...
- C++小项目:directx11图形程序(四):d3dclass
主菜终于来了.这个d3dclass主要做的工作是dx11图形程序的初始化工作,它将创建显示表面交换链,d3d设备,d3d设备上下文,渲染目标表面,深度模板缓存:设置视口,生成投影矩阵. D3D设备:可 ...
- C++小项目:directx11图形程序(九):总结
整篇文章中对于directx11的知识的介绍并不多,我也不知道怎么介绍,也应该说对于directx,它有它自己的部分,比如设备(device),设备上下文(devicecontext),顶点缓存,索引 ...
- C++小项目:directx11图形程序(三):graphicsclass
这是框架的第三层graphicsclass,这个类才真正可以说是整个程序的框架,因为它组织了后面所有的成员. 代码: graphicsclass.h #pragma once #include< ...
- C++小项目:directx11图形程序(七):modelclass
模型类是世界空间中的表示物体的类,那么他的所做的事就是加载模型,移动模型,渲染模型 modelclass.h #pragma once #include <d3d11.h> #includ ...
- C++小项目:directx11图形程序(二):systemclass
先上代码: systemclass.h #pragma once #include"graphicsclass.h" const bool FULLSCREEN = true; c ...
- C++小项目:directx11图形程序(六):cameraclass
cameraclass是一个相机类,它的作用是生成非常重要的观察矩阵.本小节涉及到一点数学知识,相对前面需要只是填充,调用,算是比较有趣的吧. cameraclass.h #pragma once # ...
- C++小项目:directx11图形程序(五):shadersclass
这个类是用来创建着色器并设置输入布局的. 这个类比较特殊,它创建的着色器与Effect文件有关,effect文件是用高级着色语言(hlsl)编写的. shadersclass.h #pragma on ...
- Android小项目之七 应用程序的更新安装
------- 源自梦想.永远是你IT事业的好友.只是勇敢地说出我学到! ---------- 按惯例,写在前面的:可能在学习Android的过程中,大家会和我一样,学习过大量的基础知识,很多的知识点 ...
随机推荐
- eclipse加载maven工程提示pom.xml无法解析org.apache.maven.plugins:maven-resources-plugin:2.4.3解决方案
pom文件提示信息: Failure to transfer org.apache.maven.plugins:maven-resources-plugin:pom:2.4.3 from http:/ ...
- Docker常见问题解决
一.Docker中运行ubuntu容器,字体颜色太深导致无法看清 解决方案: 1. 利用dircolors命令,查看我们的系统当前的文件名称显示颜色的值,然后利用管道重定向到用户目录下的任意一个文件( ...
- [python]python中,使用traceback处理异常信息
近来编写一个程序,该程序可以在设定时间内,获取指定文件夹更新的文件夹和文件列表,并根据获取到的更新列表,做一些操作.由于所写程序是放在服务器上运行,为了保证程序在运行的过程中,不时不时跳出些异常信息出 ...
- 个人psp
排球计分程序 1.计划 通过对用户故事估计这个任务需要3~5d天. 2.开发 2.1需求分析 作为一个观众,我希望了解每场比赛的比分,以便了解比赛的情况. 作为一个观众,我希望输入球队名称查询球队比分 ...
- mybatis+oracle添加一条数据并返回所添加数据的主键问题
最近做mybatis+oracle项目的时候解决添加一条数据并返回所添加数据的主键问题 controller层 @RequestMapping("/addplan") public ...
- ssh 登录
一.ssh登录过程 在实际开发中,经常使用ssh进行远程登录.ssh 登录到远程主机的过程包括: 版本号协商 密钥和算法协商 认证 交互 1.1 版本号协商阶段 (1) 服务端打开22端口(也可以为了 ...
- html小知识点汇总(浏览器导航上显示图标、div无高度时试着清除浮动、文字环绕图片、字体加粗、div按百分比分、已有的不合适的class,针对特定的标签进行修改)
1.新点击的网页,在浏览器导航上显示图标: 像这种效果: <head> <meta charset="UTF-8"> <meta name=" ...
- c++11的右值引用、移动语义
对于c++11来说移动语义是一个重要的概念,一直以来我对这个概念都似懂非懂.最近翻翻资料感觉突然开窍,因此记下.其实搞懂之后就会发现这个概念很简单,并无什么高深的地方. 先说说右值引用.右值一般指的是 ...
- jq获取屏幕高度和宽度(盒子模型)
$(window).width(); //浏览器可视窗口宽度 $(window).height(); //浏览器可视窗口高度 $(document).width();//body的宽度 $(docum ...
- UnsupportedClassVersionError 错误解决办法
偶然遇到关于版本问题的错误,为了以后查找方便记录下来.有更好的办法欢迎大家更正. 错误内容: Exception in thread "main" java.lang.Unsupp ...