本节教程旨在渲染一个3D模型到一张2D纹理,在把这张2D纹理渲染到背后缓存(屏幕上),先看看本次教程的结构吧,感觉越来越庞大的架构了,有几千行代码了,这次教程的架构如下:
由于框架越来越庞大,我得写个文档大概记录下每个文件的大概作用才行:
(1)WinMain:入口函数,主要是整个函数开始的地方。
(2)SystemClass:包含InputClass,GrapgicsClass,FPSClass,CPUClass四个子模块,里面进行的事情两大件:第一,进行窗口的创建和消息的运行和接受,第二,进行各个子模块的初始化,内存回收,和进行每帧渲染。
(3)InputClass:主要用IDirectInput8,IDirectInputDevice8来创建高效的鼠标消息和键盘消息处理方式。
(4)FPSClass:主要用于计算这个渲染器每秒的绘制画面的帧数。
(5)CPUClass:主要就算CPU运行的平均使用效率。
(6)GraphicsClass:这个是很主要的部分,是针对图形那个部分的,有CameraClass,D3DClass,TextClass,ModelClass,ColorShaderClass等子模块.
(7)CameraClass:主要用于存储相机位置,计算返回相机变换矩阵ViewMatrix和BaseViewMatrix(专门用于文字渲染和2D图片渲染的相机变换矩阵).
(8)D3DClass:用于进行D3D11的各部分基本元素的创建和设置,如ID3D11DeviceI,D3D11DeviceContext,IDXGISwapChainID3D11RenderTargetView,ID3D11DepthStencilState,ID3D11RasterizerState等,特别是ID3D11DeviceI,D3D11DeviceContext这两个经常返回给其它类使用。
(9)DebugWindowClass:提供一张四方形图片的顶点数据和索引数据
(10)Tex2DShaderClass:用于加载Texture2DShader.fx里面的VertexShader和PixelShader,用于绘制2D图片.
(11)LightClass:用于提供给Shader使用的灯光数据,可包括AmbientLight(环境光),DiffuseLight(漫反射光),SpecualrLight(镜面光),LightDirection(光在世界空间的方向).
(12)ModelClass:用于加载3D模型的顶点数据和索引数据,以及纹理数据
(13) TextClass:用于加载"句子"的顶点数据和索引数据,以及字体的纹理数据(一个句子由多个字体组成).
(14)ColorShaderClass:加载ColorShader.fx中的VertexShader和PixelShader,其中该Shader支持功能
支持SpecualLight 支持DiffuseLight 支持SpecularMap 支持NormalMap
(15)TextureArrayClass:加载一组纹理资源(ShaderResource)
(16)FontShaderClass:用于加载“FontShader.fx”,主要用于绘制字体的纹理贴图Font.dss
一,渲染到纹理技术(RTT)的简介。
最后要说的其中RenderModelToTextureClass是关键的类,它先创建一个2D纹理和与2D纹理关联的目标渲染视图,以及与2D纹理关联的ShaderReSouceView,当将渲染地点从”背后缓存“转为”2D纹理“,进行3D立方体的渲染,3D立方体将渲染进2D纹理上,而2D纹理与
ShaderReSouceView关联,就形成了2D纹理资源,之后当将渲染地点从”背后缓存“转为”2D纹理“,送入Texture2DShader.fx里的shader进行最终2D图片的渲染。
当将渲染目的地点从”背后缓存“转为”2D纹理“的函数:
我放出关键类的CPP和H文件代码:
RenderModelToTexure.h
#pragma once
#ifndef _RENDER_MODEL_TO_TEXTURE_H
#define _RENDER_MODEL_TO_TEXTURE_H
#include
#include
#include"Macro.h"
class RenderModelToTextureClass
{
private:
ID3D11Texture2D* mRenderTargetTexture;
ID3D11RenderTargetView* mRenderTargetView;
ID3D11ShaderResourceView* mShaderResourceView;
public:
RenderModelToTextureClass();
RenderModelToTextureClass(const RenderModelToTextureClass&other);
~RenderModelToTextureClass();
bool Initialize(ID3D11Device* d3dDevice,int TextureWidth,int TexureHeight);
void ShutDown();
void SetRenderTarget(ID3D11DeviceContext* deviceContext, ID3D11DepthStencilView* depthStencilView);
void ClearRenderTarget(ID3D11DeviceContext* deviceContext, ID3D11DepthStencilView* depthStencilView, float red, float green, float blue, float alpha);
ID3D11ShaderResourceView* GetShaderResourceView();
};
#endif // !_RENDER_3D_MODEL_TO_TEXTURE_H
RenderModelToTexure.cpp
#include"RenderModelToTexure.h"
RenderModelToTextureClass::RenderModelToTextureClass()
{
mRenderTargetTexture = NULL;
mRenderTargetView = NULL;
}
RenderModelToTextureClass::RenderModelToTextureClass(const RenderModelToTextureClass&other)
{
}
RenderModelToTextureClass::~RenderModelToTextureClass()
{
}
bool RenderModelToTextureClass::Initialize(ID3D11Device* d3dDevice, int TextureWidth, int TexureHeight)
{
//第一,填充2D纹理形容结构体,并创建2D渲染纹理
D3D11_TEXTURE2D_DESC textureDesc;
ZeroMemory(&textureDesc, sizeof(textureDesc));
textureDesc.Width = TextureWidth;
textureDesc.Height = TexureHeight;
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 1;
textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; //纹理像素为12个字节
textureDesc.SampleDesc.Count = 1;
textureDesc.Usage = D3D11_USAGE_DEFAULT;
textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
textureDesc.CPUAccessFlags = 0;
textureDesc.MiscFlags = 0;
HR(d3dDevice->CreateTexture2D(&textureDesc, NULL, &mRenderTargetTexture));
//第二,填充渲染目标视图形容体,并进行创建目标渲染视图
D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
renderTargetViewDesc.Format = textureDesc.Format;
renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
renderTargetViewDesc.Texture2D.MipSlice = 0;
HR(d3dDevice->CreateRenderTargetView(mRenderTargetTexture, &renderTargetViewDesc, &mRenderTargetView));
//第三,填充着色器资源视图形容体,并进行创建着色器资源视图
D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;
shaderResourceViewDesc.Format = textureDesc.Format;
shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
shaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
shaderResourceViewDesc.Texture2D.MipLevels = 1;
HR(d3dDevice->CreateShaderResourceView(mRenderTargetTexture, &shaderResourceViewDesc, &mShaderResourceView));
return true;
}
void RenderModelToTextureClass::ShutDown()
{
ReleaseCOM(mRenderTargetTexture);
ReleaseCOM(mRenderTargetView);
ReleaseCOM(mShaderResourceView);
}
void RenderModelToTextureClass::SetRenderTarget(ID3D11DeviceContext* deviceContext, ID3D11DepthStencilView* depthStencilView)
{
//绑定渲染目标视图和深度模板视图到输出渲染管线,使渲染目的地变为一张纹理资源mShaderResourceView
deviceContext->OMSetRenderTargets(1, &mRenderTargetView, depthStencilView);
}
void RenderModelToTextureClass::ClearRenderTarget(ID3D11DeviceContext* deviceContext, ID3D11DepthStencilView* depthStencilView, float red, float green, float blue, float alpha)
{
//设置清除缓存为的颜色
float color[4];
color[0] = red;
color[1] = green;
color[2] = blue;
color[3] = alpha;
//清除背后缓存
deviceContext->ClearRenderTargetView(mRenderTargetView, color);
//清除深度缓存和模板缓存
deviceContext->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
}
// 将“被渲染模型到纹理的纹理”作为ShaderResourceView资源返回,这个资源将会跟其它的ShaderResourceView资源一样被送入Shader里计算.
ID3D11ShaderResourceView* RenderModelToTextureClass::GetShaderResourceView()
{
return mShaderResourceView;
}
得注意一点:深度缓存的大小以及ViewPort的大小应该是一致的,(渲染到屏幕时,backBuffer,depthBuffer,Viewport的大小应该也是一致的)这里可以参考我的软光栅器实现教程的源码就知道为什么了。
目标又进一步了,加油吧
我的源代码链接如下:
http://download.csdn.net/detail/qq_29523119/9664919