D3D11教程十四之RenderToTexture(RTT技术)

来源:互联网 发布:腾讯新闻无法连接网络 编辑:程序博客网 时间:2024/05/21 12:46

本节教程旨在渲染一个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)的简介。

(1)渲染到纹理技术也就是把一个3D模型渲染到2D纹理,在把2D纹理作为一张长方形图片渲染到背后缓存(屏幕的技术),这个技术方便查看调试shader的效果,UE4游戏引擎那些好像就是有这种技术,如图红色圈部分:



(2)渲染到纹理技术也用于制造反射纹理和折射纹理(反射镜像在反射面上投影得到的纹理称为反射纹理),用来制作水面的反射现象和折射现象
如图:下面看到水面下的墙是反射纹理和水面混合的效果,看到水下面的浴室的底面为折射纹理和水面混合的效果。




最后要说的其中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<Windows.h>#include<D3D11.h>#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){//绑定渲染目标视图和深度模板视图到输出渲染管线,使渲染目的地变为一张纹理资源<span style="font-size: 13.3333px; font-family: Arial, Helvetica, sans-serif;">mShaderResourceView</span>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;}





最终放上我的程序运行图:


目标又进一步了,加油吧


我的源代码链接如下:

http://download.csdn.net/detail/qq_29523119/9664919


0 0
原创粉丝点击