首先配置好DIrectX11基本环境 创建DirectX11渲染基类
然后创建一个精灵类 用来生成精灵
头文件定义如下:
#pragma once
#ifndef _GAMESPIRT_H_
#define _GAMESPIRT_H_
#include<xnamath.h>
class GameSpirt
{
public:
GameSpirt();
virtual ~GameSpirt();
XMMATRIX GetWorldMatrix();
void SetPosition(XMFLOAT2& position); //position接口函数
void SetRotation(float rotation); //rotation接口函数
void SetScale(XMFLOAT2& scale); //scale接口函数
private:
XMFLOAT2 position_; //精灵的位置
float rotaion_; //精灵的旋转
XMFLOAT2 scale_; //精灵的视距
};
#endif
源文件定义如下:
#include<d3d11.h>
#include<d3dx11.h>
#include "GameSpirt.h"
GameSpirt::GameSpirt()
{
rotaion_ = 0;
scale_.x = scale_.y = 1.0f; //初始值设置为1.0f
}
void GameSpirt::SetPosition(XMFLOAT2& position) {
position_ = position;
}
void GameSpirt::SetRotation(float rotation) {
rotaion_ = rotation;
}
void GameSpirt::SetScale(XMFLOAT2& scale) {
scale_ = scale;
}
XMMATRIX GameSpirt::GetWorldMatrix() {
XMMATRIX translation = XMMatrixTranslation(position_.x, position_.y, 0.0f); //生成移位矩阵
XMMATRIX rotationZ = XMMatrixRotationZ(rotaion_); //生成一个关于Z轴的矩阵
XMMATRIX scale = XMMatrixScaling(scale_.x, scale_.y, 1.0f); //生成视距
return translation * rotationZ * scale; //返回矩阵
}
GameSpirt::~GameSpirt()
{
}
之后渲染场景:
头文件定义如下:
#pragma once
#ifndef _SCENEDEMO_H_
#define _SCENEDEMO_H_
#include "Direct3DBase.h"
#include "GameSpirt.h"
class SceneDemo :public Direct3DBase
{
public:
SceneDemo();
virtual ~SceneDemo();
bool LoadContent();
void UnloadContent();
void Update(float dt);
void Render();
//创建顶点渲染函数
HRESULT CreateVertices(float width, float height);
//创建精灵函数
XMMATRIX SceneDemo::CreateSprite(GameSpirt *spritesA_, const int spritesNums, ID3D11ShaderResourceView * colorMapForSpirt, XMFLOAT2 spritesPos[], const int spritePosNums, XMMATRIX vpMatrix);
//显示精灵函数
void ShowSpirte(GameSpirt *sprites, const int spritesNums,XMMATRIX vpMatrix, ID3D11ShaderResourceView* colorMapForSpirt);
private:
/*基本部分*/
ID3D11VertexShader* solidColorVS_; //顶点着色器
ID3D11PixelShader* solidColorPS_; //像素着色器
ID3D11InputLayout* inputLayout_; //顶点布局
ID3D11Buffer* vertexBuffer_; //缓存器
/*精灵部分*/
const static int SpritesNum = 2;
ID3D11ShaderResourceView* colorMapForSpirtA_; //设定精灵A贴图的颜色表
ID3D11ShaderResourceView* colorMapForSpirtB_; //设定精灵B贴图的颜色表
ID3D11SamplerState* colorMapSampler_; //采样状态变量
ID3D11BlendState* alphaBlendState_;
GameSpirt spritesA_[SpritesNum]; //用来存储精灵A的数组
GameSpirt spritesB_[SpritesNum]; //用来存储精灵B的数组
ID3D11Buffer* mvpCB_; //顶点着色器的常量缓存
XMMATRIX vpMatrixForSpritA_;
XMMATRIX vpMatrixForSpritB_;
};
#endif
加载内容函数设置如下
先设置顶点着色器
/*顶点着色器设置*/
ID3DBlob* vsBuffer = 0;
//编译HLSL标准创建的文本文件
bool compileResult = compileD3DShader("TextureMap.fx", "VS_Main", "vs_4_0", &vsBuffer);
if (compileResult == false) {
DXTRACE_MSG("error loading vertex shader!!");
return false;
}
HRESULT d3dResult; //创建顶点着色器并载入设备
d3dResult = d3dDevice_->CreateVertexShader(vsBuffer->GetBufferPointer(), vsBuffer->GetBufferSize(), 0, &solidColorVS_);
if (FAILED(d3dResult)) {
DXTRACE_MSG("CreateVertexShader failed!!");
if (vsBuffer)
vsBuffer->Release();
return false;
}
FX 文件是使用“高阶着色器语言”(HLSL)标准创建的文本文件。
输入外观设置:
//输入外观设置
//inputLAYOUT用来shader中的数据组成 是最终进入到shader中的数据部分
D3D11_INPUT_ELEMENT_DESC solidColorLayout[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 } //贴图的坐标
};
unsigned int totalColorLayouts = ARRAYSIZE(solidColorLayout);
//创建输入外观并导入设备
d3dResult = d3dDevice_->CreateInputLayout(solidColorLayout, totalColorLayouts, vsBuffer->GetBufferPointer(), vsBuffer->GetBufferSize(), &inputLayout_);
vsBuffer->Release();
if (FAILED(d3dResult)) {
DXTRACE_MSG("CreateLayout failed!!");
return false;
}
像素着色器设置:
/*像素着色器设置*/
ID3DBlob* psBuffer = 0;
//编译HLSL标准文件
compileResult = compileD3DShader("TextureMap.fx", "PS_Main", "ps_4_0", &psBuffer);
if (compileResult == false) {
DXTRACE_MSG("error loading pixel shader!");
return false;
}
创建像素着色器并导入设备:
d3dResult = d3dDevice_->CreatePixelShader(psBuffer->GetBufferPointer(), psBuffer->GetBufferSize(), 0, &solidColorPS_);
psBuffer->Release();
if (FAILED(d3dResult)) {
return false;
}
d3dResult = d3dDevice_->CreatePixelShader(psBuffer->GetBufferPointer(), psBuffer->GetBufferSize(), 0, &solidColorPS_);
psBuffer->Release();
if (FAILED(d3dResult)) {
return false;
}
创建资源视图文件并导入资源贴图
HRESULT d3dResult1, d3dResult2;
d3dResult1 = D3DX11CreateShaderResourceViewFromFile(d3dDevice_, "RBar.dds", 0, 0, &colorMapForSpirtB_, 0); //从文本中导入贴图创建精灵A
d3dResult2 = D3DX11CreateShaderResourceViewFromFile(d3dDevice_, "decal.dds", 0, 0, &colorMapForSpirtA_, 0); //从文本中导入贴图创建精灵B
if (FAILED(d3dResult1) || FAILED(d3dResult2)) {
DXTRACE_MSG("Failed to Create shader from file");
return false;
}
采样设置:
D3D11_SAMPLER_DESC colorMapDesc;
ZeroMemory(&colorMapDesc, sizeof(colorMapDesc)); //清空内存
colorMapDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
colorMapDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
colorMapDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
colorMapDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
colorMapDesc.Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
colorMapDesc.MaxLOD = D3D11_FLOAT32_MAX;
d3dResult = d3dDevice_->CreateSamplerState(&colorMapDesc, &colorMapSampler_);
if (FAILED(d3dResult)) {
DXTRACE_MSG("ERROR loading sampler State");
return false;
}
创建顶点函数:
HRESULT SceneDemo::CreateVertices(float width, float height) {
HRESULT d3dResult;
VertexPos vertices[] = //各个顶点的坐标
{
{ XMFLOAT3(width, height, 1.0f), XMFLOAT2(1.0f, 0.0f) },
{ XMFLOAT3(width, -height, 1.0f), XMFLOAT2(1.0f, 1.0f) },
{ XMFLOAT3(-width, -height, 1.0f), XMFLOAT2(0.0f, 1.0f) },
{ XMFLOAT3(-width, -height, 1.0f), XMFLOAT2(0.0f, 1.0f) },
{ XMFLOAT3(-width, height, 1.0f), XMFLOAT2(0.0f, 0.0f) },
{ XMFLOAT3(width, height, 1.0f), XMFLOAT2(1.0f, 0.0f) },
};
D3D11_BUFFER_DESC vertexDesc; //创建顶点描述
ZeroMemory(&vertexDesc, sizeof(vertexDesc));
vertexDesc.Usage = D3D11_USAGE_DEFAULT;
vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexDesc.ByteWidth = sizeof(VertexPos) * 6; //有几个顶点就乘上几个顶点
D3D11_SUBRESOURCE_DATA resourceData; //资源数据
ZeroMemory(&resourceData, sizeof(resourceData));
resourceData.pSysMem = vertices;
d3dResult = d3dDevice_->CreateBuffer(&vertexDesc, &resourceData, &vertexBuffer_);
return d3dResult;
}
XMMATRIX SceneDemo::CreateSprite(GameSpirt *sprites,const int spritesNums,ID3D11ShaderResourceView * colorMapForSpirt,XMFLOAT2 spritesPos[], const int spritePosNums, XMMATRIX vpMatrix)
{
//设置贴图
ID3D11Resource* colorTex;
HRESULT d3dResult;
colorMapForSpirt->GetResource(&colorTex); //将贴图赋给colorText
D3D11_TEXTURE2D_DESC colorTexDesc;
((ID3D11Texture2D*)colorTex)->GetDesc(&colorTexDesc);
colorTex->Release(); //释放内容
float halfWidth = (float)colorTexDesc.Width / 2.0f;
float halfHeight = (float)colorTexDesc.Height / 2.0f;
//创建顶点缓存
d3dResult = CreateVertices(halfWidth, halfHeight);
if (FAILED(d3dResult)) {
DXTRACE_MSG("Failed to create vertex buffer!");
return false;
}
//缓存描述
D3D11_BUFFER_DESC constDesc;
ZeroMemory(&constDesc, sizeof(constDesc));
constDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
constDesc.ByteWidth = sizeof(XMMATRIX);
constDesc.Usage = D3D11_USAGE_DEFAULT;
d3dResult = d3dDevice_->CreateBuffer(&constDesc, 0, &mvpCB_); //创建缓存
if (FAILED(d3dResult)) {
return false;
}
/*精灵位置操作*/
for (int i = 0; i < spritePosNums; ++i) {
sprites->SetPosition(spritesPos[i]); //设置每一个精灵的位置
sprites = sprites + 1;
}
XMMATRIX view = XMMatrixIdentity();
XMMATRIX projection = XMMatrixOrthographicOffCenterLH(0.0f, 800.0f, 0.0f, 600.0f, 0.1f, 100.0f);
vpMatrix = XMMatrixMultiply(view, projection);
return vpMatrix;
}
之后就可以创建精灵了:
/*创建精灵部分*/
XMFLOAT2 pos[2] = { {300.0f, 200.0f}, {200.0f, 100.0f} }; //设置两个精灵的坐标
vpMatrixForSpritB_ = CreateSprite(spritesA_,ARRAYSIZE(spritesA_), colorMapForSpirtB_, pos, ARRAYSIZE(pos), vpMatrixForSpritB_); //创建精灵成功
XMFLOAT2 pos2[2] = { { 200.0f, 300.0f }, {400.0f, 400.0f} }; //涉恶之两个精灵的坐标
vpMatrixForSpritA_ = CreateSprite(spritesB_, ARRAYSIZE(spritesB_),colorMapForSpirtA_, pos2, ARRAYSIZE(pos2), vpMatrixForSpritA_); //创建精灵成功
混合描述部分:
/*混合描述*/
D3D11_BLEND_DESC blendDesc;
ZeroMemory(&blendDesc, sizeof(blendDesc));
blendDesc.RenderTarget[0].BlendEnable = TRUE;
blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE;
blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO;
blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
blendDesc.RenderTarget[0].RenderTargetWriteMask = 0x0F;
float blendFactor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
d3dDevice_->CreateBlendState(&blendDesc, &alphaBlendState_); //alphaBlendState 设置透明度
d3dContext_->OMSetBlendState(alphaBlendState_, blendFactor, 0xFFFFFFFF);
return true;
之后通过渲染函数将精灵显示到窗体上
显示精灵函数:
void SceneDemo::ShowSpirte(GameSpirt *sprites, const int spritesNums, XMMATRIX vpMatrix, ID3D11ShaderResourceView* colorMapForSpirt) {
d3dContext_->PSSetShaderResources(0, 1, &colorMapForSpirt); //像素着色器设置精灵的贴图
d3dContext_->PSSetSamplers(0, 1, &colorMapSampler_); //采样着色器
for (int i = 0; i < spritesNums; ++i)
{
XMMATRIX world = sprites[i].GetWorldMatrix();
XMMATRIX mvp = XMMatrixMultiply(world, vpMatrix);
mvp = XMMatrixTranspose(mvp);
d3dContext_->UpdateSubresource(mvpCB_, 0, 0, &mvp, 0, 0);
d3dContext_->VSSetConstantBuffers(0, 1, &mvpCB_);
d3dContext_->Draw(6, 0);
}
}
最后渲染函数
/*用于渲染*/
void SceneDemo::Render() {
/*清空缓存*/
float clearColor[4] = { 0.0f, 0.0f, 0.25f, 1.0f };
d3dContext_->ClearRenderTargetView(backBufferTarget_, clearColor);
if (d3dContext_ == 0)
return;
unsigned int stride = sizeof(VertexPos);
unsigned int offset = 0;
d3dContext_->IASetInputLayout(inputLayout_);
d3dContext_->IASetVertexBuffers(0, 1, &vertexBuffer_, &stride, &offset);
d3dContext_->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
d3dContext_->VSSetShader(solidColorVS_, 0, 0);
d3dContext_->PSSetShader(solidColorPS_, 0, 0);
//显示精灵
ShowSpirte(spritesA_, ARRAYSIZE(spritesA_), vpMatrixForSpritA_, colorMapForSpirtA_);
ShowSpirte(spritesB_, ARRAYSIZE(spritesB_), vpMatrixForSpritB_, colorMapForSpirtB_);
swapChain_->Present(0, 0);