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

本节教程旨在渲染一个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;
}


得注意一点:深度缓存的大小以及ViewPort的大小应该是一致的,(渲染到屏幕时,backBuffer,depthBuffer,Viewport的大小应该也是一致的)这里可以参考我的软光栅器实现教程的源码就知道为什么了。



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


目标又进一步了,加油吧


我的源代码链接如下:

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


  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值