D3D回收站没有了怎么办办

您是访问本站的第位客人
&DirectX 10 教程22:绘制到纹理
DirectX 10 教程22:绘制到纹理
原文地址:。
源代码下载:。
本教程介绍如何实现绘制到纹理,代码基于教程7绘制3D模型和教程11绘制2D图像。
绘制到纹理可以将场景绘制到纹理中而不是通常的后备缓存中,然后你就可以使用这张纹理实现许多效果。例如,你可以从相机的不同角度绘制场景,然后将绘制的纹理作为一个镜像或小屏幕。你也可以对这张纹理进行后期处理或使用shader进行绘制获取独特的效果。利用绘制到纹理所能达到的效果几乎是无限的,因此它也几乎是DirectX 10中威力最大的工具。
但是,因为你将场景绘制了多遍,所以绘制到纹理开销也是巨大的。3D引擎往往在这个阶段开始速度降低,但是相比于它能达到的效果还是物有所值的。
本教程中我们首先将一个旋转的立方体绘制到纹理中,然后将这张纹理绘制到屏幕左上角。立方体也会绘制到屏幕上。纹理的背景设为蓝色。首先看一下更新过的框架。
框架中新添了RenderTextureClass和DebugWindowClass。RenderTextureClass封装了DirectX 10中绘制到纹理的功能。DebugWindowClass只是前面教程中BitmapClass类修改个名称而已,但是没有包含纹理,因为我们需要将绘制的纹理作为参数传递到这个类中。我将它命名为DebugWindowClass的原因是我经常使用这个类帮助我调试shader的效果,它可以帮助我看到shader每个阶段的效果。
Rendertextureclass.h
RenderTextureClass将渲染目标设置到纹理而不是常规的后备缓存,还可以从这个类获取以ID3D10ShaderResourceView形式.得到的纹理数据。
////////////////////////////////////////////////////////////////////////////////
// Filename: rendertextureclass.h
////////////////////////////////////////////////////////////////////////////////
#ifndef _RENDERTEXTURECLASS_H_
#define _RENDERTEXTURECLASS_H_
//////////////
// INCLUDES //
//////////////
#include &d3d10.h&
////////////////////////////////////////////////////////////////////////////////
// Class name: RenderTextureClass
////////////////////////////////////////////////////////////////////////////////
class RenderTextureClass
RenderTextureClass();
RenderTextureClass(const RenderTextureClass&);
~RenderTextureClass();
bool Initialize(ID3D10Device*, int, int);
void Shutdown();
void SetRenderTarget(ID3D10Device*, ID3D10DepthStencilView*);
void ClearRenderTarget(ID3D10Device*, ID3D10DepthStencilView*, float, float, float, float);
ID3D10ShaderResourceView* GetShaderResourceView();
ID3D10Texture2D* m_renderTargetT
ID3D10RenderTargetView* m_renderTargetV
ID3D10ShaderResourceView* m_shaderResourceV
Rendertextureclass.cpp
////////////////////////////////////////////////////////////////////////////////
// Filename: rendertextureclass.cpp
////////////////////////////////////////////////////////////////////////////////
#include "rendertextureclass.h"
构造函数中将私有指针初始化为null。
RenderTextureClass::RenderTextureClass()
m_renderTargetTexture = 0;
m_renderTargetView = 0;
m_shaderResourceView = 0;
RenderTextureClass::RenderTextureClass(const RenderTextureClass& other)
RenderTextureClass::~RenderTextureClass()
Initialize方法的参数width和height表示要绘制的纹理的大小。注意:如果绘制的是整个屏幕,必须将渲染目标的长宽比设置得和屏幕一样,否则图像会变形。
首先设置纹理描述创建一个渲染目标纹理,然后使用这张纹理创建一个渲染目标视图,这样这张纹理就会以渲染目标的形式进行绘制。最后创建纹理的shader资源视图,这样调用对象就可以访问到这个数据了。
bool RenderTextureClass::Initialize(ID3D10Device* device, int textureWidth, int textureHeight)
D3D10_TEXTURE2D_DESC textureD
D3D10_RENDER_TARGET_VIEW_DESC renderTargetViewD
D3D10_SHADER_RESOURCE_VIEW_DESC shaderResourceViewD
// Initialize the render target texture description.
ZeroMemory(&textureDesc, sizeof(textureDesc));
// Setup the render target texture description.
textureDesc.Width = textureW
textureDesc.Height = textureH
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 1;
textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
textureDesc.SampleDesc.Count = 1;
textureDesc.Usage = D3D10_USAGE_DEFAULT;
textureDesc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
textureDesc.CPUAccessFlags = 0;
textureDesc.MiscFlags = 0;
// Create the render target texture.
result = device->CreateTexture2D(&textureDesc, NULL, &m_renderTargetTexture);
if(FAILED(result))
// Setup the description of the render target view.
renderTargetViewDesc.Format = textureDesc.F
renderTargetViewDesc.ViewDimension = D3D10_RTV_DIMENSION_TEXTURE2D;
renderTargetViewDesc.Texture2D.MipSlice = 0;
// Create the render target view.
result = device->CreateRenderTargetView(m_renderTargetTexture, &renderTargetViewDesc, &m_renderTargetView);
if(FAILED(result))
// Setup the description of the shader resource view.
shaderResourceViewDesc.Format = textureDesc.F
shaderResourceViewDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
shaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
shaderResourceViewDesc.Texture2D.MipLevels = 1;
// Create the shader resource view.
result = device->CreateShaderResourceView(m_renderTargetTexture, &shaderResourceViewDesc, &m_shaderResourceView);
if(FAILED(result))
Shutdown释放创建的三个接口。
void RenderTextureClass::Shutdown()
if(m_shaderResourceView)
m_shaderResourceView->Release();
m_shaderResourceView = 0;
if(m_renderTargetView)
m_renderTargetView->Release();
m_renderTargetView = 0;
if(m_renderTargetTexture)
m_renderTargetTexture->Release();
m_renderTargetTexture = 0;
SetRenderTarget方法将这个类中的渲染目标视图作为当前所有图形绘制的目标。
void RenderTextureClass::SetRenderTarget(ID3D10Device* device, ID3D10DepthStencilView* depthStencilView)
// Bind the render target view and depth stencil buffer to the output render pipeline.
device->OMSetRenderTargets(1, &m_renderTargetView, depthStencilView);
ClearRenderTarget类似于D3DClass::BeginScene方法,只不过它操作的对象是这个类中的渲染目标视图,这个方法每帧都需要在绘制到渲染目标前进行调用。
void RenderTextureClass::ClearRenderTarget(ID3D10Device* device, ID3D10DepthStencilView* depthStencilView,
float red, float green, float blue, float alpha)
float color[4];
// Setup the color to clear the buffer to.
color[0] =
color[1] =
color[2] =
color[3] =
// Clear the back buffer.
device->ClearRenderTargetView(m_renderTargetView, color);
// Clear the depth buffer.
device->ClearDepthStencilView(depthStencilView, D3D10_CLEAR_DEPTH, 1.0f, 0);
GetShaderResourceView方法以shader资源视图的方式返回绘制到纹理的数据,这样绘制到渲染目标视图的数据就可以作为一张纹理被其他shader使用。你通常会直接将一张纹理传递到shader中,但现在可以调用这个方法达到同样的效果。
ID3D10ShaderResourceView* RenderTextureClass::GetShaderResourceView()
return m_shaderResourceV
Debugwindowclass.h
DebugWindowClass几乎就是BitmapClass,但没有了TextureClass类。代码和前面教程中的BitmapClass几乎一样,所以这个类的详细解释可参见前面的教程。
////////////////////////////////////////////////////////////////////////////////
// Filename: debugwindowclass.h
////////////////////////////////////////////////////////////////////////////////
#ifndef _DEBUGWINDOWCLASS_H_
#define _DEBUGWINDOWCLASS_H_
//////////////
// INCLUDES //
//////////////
#include &d3d10.h&
#include &d3dx10.h&
////////////////////////////////////////////////////////////////////////////////
// Class name: DebugWindowClass
////////////////////////////////////////////////////////////////////////////////
class DebugWindowClass
struct VertexType
D3DXVECTOR3
D3DXVECTOR2
DebugWindowClass();
DebugWindowClass(const DebugWindowClass&);
~DebugWindowClass();
bool Initialize(ID3D10Device*, int, int, int, int);
void Shutdown();
bool Render(ID3D10Device*, int, int);
int GetIndexCount();
bool InitializeBuffers(ID3D10Device*);
void ShutdownBuffers();
bool UpdateBuffers(int, int);
void RenderBuffers(ID3D10Device*);
ID3D10Buffer *m_vertexBuffer, *m_indexB
int m_vertexCount, m_indexC
int m_screenWidth, m_screenH
int m_bitmapWidth, m_bitmapH
int m_previousPosX, m_previousPosY;
Debugwindowclass.cpp
////////////////////////////////////////////////////////////////////////////////
// Filename: debugwindowclass.cpp
////////////////////////////////////////////////////////////////////////////////
#include "debugwindowclass.h"
DebugWindowClass::DebugWindowClass()
m_vertexBuffer = 0;
m_indexBuffer = 0;
DebugWindowClass::DebugWindowClass(const DebugWindowClass& other)
DebugWindowClass::~DebugWindowClass()
bool DebugWindowClass::Initialize(ID3D10Device* device, int screenWidth, int screenHeight, int bitmapWidth, int bitmapHeight)
// Store the screen size.
m_screenWidth = screenW
m_screenHeight = screenH
// Store the size in pixels that this bitmap should be rendered at.
m_bitmapWidth = bitmapW
m_bitmapHeight = bitmapH
// Initialize the previous rendering position to zero.
m_previousPosX = 0;
m_previousPosY = 0;
// Initialize the vertex and index buffer that hold the geometry for the triangle.
result = InitializeBuffers(device);
if(!result)
void DebugWindowClass::Shutdown()
// Release the vertex and index buffers.
ShutdownBuffers();
bool DebugWindowClass::Render(ID3D10Device* device, int positionX, int positionY)
// Re-build the dynamic vertex buffer for rendering to possibly a different location on the screen.
result = UpdateBuffers(positionX, positionY);
if(!result)
// Put the vertex and index buffers on the graphics pipeline to prepare them for drawing.
RenderBuffers(device);
int DebugWindowClass::GetIndexCount()
return m_indexC
bool DebugWindowClass::InitializeBuffers(ID3D10Device* device)
VertexType*
unsigned long*
D3D10_BUFFER_DESC vertexBufferDesc, indexBufferD
D3D10_SUBRESOURCE_DATA vertexData, indexD
// Set the number of vertices in the vertex array.
m_vertexCount = 6;
// Set the number of indices in the index array.
m_indexCount = m_vertexC
// Create the vertex array.
vertices = new VertexType[m_vertexCount];
if(!vertices)
// Create the index array.
indices = new unsigned long[m_indexCount];
if(!indices)
// Initialize vertex array to zeros at first.
memset(vertices, 0, (sizeof(VertexType) * m_vertexCount));
// Load the index array with data.
for(i=0; i&m_indexC i++)
indices[i] =
// Set up the description of the dynamic vertex buffer.
vertexBufferDesc.Usage = D3D10_USAGE_DYNAMIC;
vertexBufferDesc.ByteWidth = sizeof(VertexType) * m_vertexC
vertexBufferDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
vertexBufferDesc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
vertexBufferDesc.MiscFlags = 0;
// Give the subresource structure a pointer to the vertex data.
vertexData.pSysMem =
// Now finally create the vertex buffer.
result = device->CreateBuffer(&vertexBufferDesc, &vertexData, &m_vertexBuffer);
if(FAILED(result))
// Set up the description of the index buffer.
indexBufferDesc.Usage = D3D10_USAGE_DEFAULT;
indexBufferDesc.ByteWidth = sizeof(unsigned long) * m_indexC
indexBufferDesc.BindFlags = D3D10_BIND_INDEX_BUFFER;
indexBufferDesc.CPUAccessFlags = 0;
indexBufferDesc.MiscFlags = 0;
// Give the subresource structure a pointer to the index data.
indexData.pSysMem =
// Create the index buffer.
result = device->CreateBuffer(&indexBufferDesc, &indexData, &m_indexBuffer);
if(FAILED(result))
// Release the arrays now that the vertex and index buffers have been created and loaded.
vertices = 0;
indices = 0;
void DebugWindowClass::ShutdownBuffers()
// Release the index buffer.
if(m_indexBuffer)
m_indexBuffer->Release();
m_indexBuffer = 0;
// Release the vertex buffer.
if(m_vertexBuffer)
m_vertexBuffer->Release();
m_vertexBuffer = 0;
bool DebugWindowClass::UpdateBuffers(int positionX, int positionY)
float left, right, top,
VertexType*
void* verticesP
// If the position we are rendering this bitmap to has not changed then don't update the vertex buffer since it
// currently has the correct parameters.
if((positionX == m_previousPosX) && (positionY == m_previousPosY))
// If it has changed then update the position it is being rendered to.
m_previousPosX = positionX;
m_previousPosY = positionY;
// Calculate the screen coordinates of the left side of the bitmap.
left = (float)((m_screenWidth / 2) * -1) + (float)positionX;
// Calculate the screen coordinates of the right side of the bitmap.
right = left + (float)m_bitmapW
// Calculate the screen coordinates of the top of the bitmap.
top = (float)(m_screenHeight / 2) - (float)positionY;
// Calculate the screen coordinates of the bottom of the bitmap.
bottom = top - (float)m_bitmapH
// Create the vertex array.
vertices = new VertexType[m_vertexCount];
if(!vertices)
// Load the vertex array with data.
// First triangle.
vertices[0].position = D3DXVECTOR3(left, top, 0.0f);
// Top left.
vertices[0].texture = D3DXVECTOR2(0.0f, 0.0f);
vertices[1].position = D3DXVECTOR3(right, bottom, 0.0f);
// Bottom right.
vertices[1].texture = D3DXVECTOR2(1.0f, 1.0f);
vertices[2].position = D3DXVECTOR3(left, bottom, 0.0f);
// Bottom left.
vertices[2].texture = D3DXVECTOR2(0.0f, 1.0f);
// Second triangle.
vertices[3].position = D3DXVECTOR3(left, top, 0.0f);
// Top left.
vertices[3].texture = D3DXVECTOR2(0.0f, 0.0f);
vertices[4].position = D3DXVECTOR3(right, top, 0.0f);
// Top right.
vertices[4].texture = D3DXVECTOR2(1.0f, 0.0f);
vertices[5].position = D3DXVECTOR3(right, bottom, 0.0f);
// Bottom right.
vertices[5].texture = D3DXVECTOR2(1.0f, 1.0f);
// Initialize the vertex buffer pointer to null first.
verticesPtr = 0;
// Lock the vertex buffer.
result = m_vertexBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&verticesPtr);
if(FAILED(result))
// Copy the data into the vertex buffer.
memcpy(verticesPtr, (void*)vertices, (sizeof(VertexType) * m_vertexCount));
// Unlock the vertex buffer.
m_vertexBuffer->Unmap();
// Release the vertex array as it is no longer needed.
vertices = 0;
void DebugWindowClass::RenderBuffers(ID3D10Device* device)
// Set vertex buffer stride and offset.
stride = sizeof(VertexType);
offset = 0;
// Set the vertex buffer to active in the input assembler so it can be rendered.
device->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &offset);
// Set the index buffer to active in the input assembler so it can be rendered.
device->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R32_UINT, 0);
// Set the type of primitive that should be rendered from this vertex buffer, in this case triangles.
device->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
D3dclass.h
D3Dclass的变化很小。
////////////////////////////////////////////////////////////////////////////////
// Filename: d3dclass.h
////////////////////////////////////////////////////////////////////////////////
#ifndef _D3DCLASS_H_
#define _D3DCLASS_H_
/////////////
// LINKING //
/////////////
#pragma comment(lib, "d3d10.lib")
#pragma comment(lib, "d3dx10.lib")
#pragma comment(lib, "dxgi.lib")
//////////////
// INCLUDES //
//////////////
////////////////////////////////////////////////////////////////////////////////
// Class name: D3DClass
////////////////////////////////////////////////////////////////////////////////
class D3DClass
D3DClass();
D3DClass(const D3DClass&);
~D3DClass();
bool Initialize(int, int, bool, HWND, bool, float, float);
void Shutdown();
void BeginScene(float, float, float, float);
void EndScene();
ID3D10Device* GetDevice();
添加一个新方法用于访问深度模板视图。
ID3D10DepthStencilView* GetDepthStencilView();
void GetProjectionMatrix(D3DXMATRIX&);
void GetWorldMatrix(D3DXMATRIX&);
void GetOrthoMatrix(D3DXMATRIX&);
void TurnZBufferOn();
void TurnZBufferOff();
新添了一个方法用于设置渲染目标。
void SetBackBufferRenderTarget();
bool m_vsync_
ID3D10Device* m_
IDXGISwapChain* m_swapC
ID3D10RenderTargetView* m_renderTargetV
ID3D10Texture2D* m_depthStencilB
ID3D10DepthStencilState* m_depthStencilS
ID3D10DepthStencilView* m_depthStencilV
ID3D10RasterizerState* m_rasterS
D3DXMATRIX m_projectionM
D3DXMATRIX m_worldM
D3DXMATRIX m_orthoM
ID3D10DepthStencilState* m_depthDisabledStencilS
D3dclass.cpp
下面的代码只包含与上一个教程不同的部分。
////////////////////////////////////////////////////////////////////////////////
// Filename: d3dclass.cpp
////////////////////////////////////////////////////////////////////////////////
#include "d3dclass.h"
GetDepthStencilView让调用对象可以访问深度模板视图。
ID3D10DepthStencilView* D3DClass::GetDepthStencilView()
return m_depthStencilV
SetBackBufferRenderTarget方法会将这个类中的后备缓存作为当前的渲染目标,这个方法通常在绘制到纹理完成后进行,此时我们需要重新将场景绘制到后备缓存中。
void D3DClass::SetBackBufferRenderTarget()
// Bind the render target view and depth stencil buffer to the output render pipeline.
m_device->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView);
Graphicsclass.h
////////////////////////////////////////////////////////////////////////////////
// Filename: graphicsclass.h
////////////////////////////////////////////////////////////////////////////////
#ifndef _GRAPHICSCLASS_H_
#define _GRAPHICSCLASS_H_
/////////////
// GLOBALS //
/////////////
const bool FULL_SCREEN =
const bool VSYNC_ENABLED =
const float SCREEN_DEPTH = 1000.0f;
const float SCREEN_NEAR = 0.1f;
///////////////////////
// MY CLASS INCLUDES //
///////////////////////
#include "d3dclass.h"
#include "cameraclass.h"
#include "modelclass.h"
#include "lightshaderclass.h"
#include "lightclass.h"
#include "rendertextureclass.h"
#include "debugwindowclass.h"
#include "textureshaderclass.h"
////////////////////////////////////////////////////////////////////////////////
// Class name: GraphicsClass
////////////////////////////////////////////////////////////////////////////////
class GraphicsClass
GraphicsClass();
GraphicsClass(const GraphicsClass&);
~GraphicsClass();
bool Initialize(int, int, HWND);
void Shutdown();
bool Frame();
bool Render();
新添了两个私有方法,我们需要将绘制分成两个pass(一次绘制到纹理,一次普通绘制)。
void RenderToTexture();
void RenderScene();
D3DClass* m_D3D;
CameraClass* m_C
ModelClass* m_M
LightShaderClass* m_LightS
LightClass* m_L
RenderTextureClass* m_RenderT
DebugWindowClass* m_DebugW
TextureShaderClass* m_TextureS
Graphicsclass.cpp
下面的代码只包含与上一个教程不同的部分。
////////////////////////////////////////////////////////////////////////////////
// Filename: graphicsclass.cpp
////////////////////////////////////////////////////////////////////////////////
#include "graphicsclass.h"
在构造函数中将私有变量初始化为null。
GraphicsClass::GraphicsClass()
m_D3D = 0;
m_Camera = 0;
m_Model = 0;
m_LightShader = 0;
m_Light = 0;
m_RenderTexture = 0;
m_DebugWindow = 0;
m_TextureShader = 0;
GraphicsClass::GraphicsClass(const GraphicsClass& other)
GraphicsClass::~GraphicsClass()
bool GraphicsClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
// Create the Direct3D object.
m_D3D = new D3DC
if(!m_D3D)
// Initialize the Direct3D object.
result = m_D3D->Initialize(screenWidth, screenHeight, VSYNC_ENABLED, hwnd, FULL_SCREEN, SCREEN_DEPTH, SCREEN_NEAR);
if(!result)
MessageBox(hwnd, L"Could not initialize Direct3D.", L"Error", MB_OK);
// Create the camera object.
m_Camera = new CameraC
if(!m_Camera)
// Create the model object.
m_Model = new ModelC
if(!m_Model)
// Initialize the model object.
result = m_Model->Initialize(m_D3D->GetDevice(), L"../Engine/data/seafloor.dds", "../Engine/data/cube.txt");
if(!result)
MessageBox(hwnd, L"Could not initialize the model object.", L"Error", MB_OK);
// Create the light shader object.
m_LightShader = new LightShaderC
if(!m_LightShader)
// Initialize the light shader object.
result = m_LightShader->Initialize(m_D3D->GetDevice(), hwnd);
if(!result)
MessageBox(hwnd, L"Could not initialize the light shader object.", L"Error", MB_OK);
// Create the light object.
m_Light = new LightC
if(!m_Light)
// Initialize the light object.
m_Light->SetDiffuseColor(1.0f, 1.0f, 1.0f, 1.0f);
m_Light->SetDirection(0.0f, 0.0f, 1.0f);
创建并初始化render to texture对象。初始化的参数中纹理的大小我使用的是屏幕的大小,表示我想将整个屏幕的画面绘制到相同大小的纹理中。
// Create the render to texture object.
m_RenderTexture = new RenderTextureC
if(!m_RenderTexture)
// Initialize the render to texture object.
result = m_RenderTexture->Initialize(m_D3D->GetDevice(), screenWidth, screenHeight);
if(!result)
创建并初始化debug window对象。注意我将窗口大小设置为100x100,显然这样做会使图像变形,想要不变形,你只需将上述大小的长宽比设置得和屏幕的长宽比一致即可。
// Create the debug window object.
m_DebugWindow = new DebugWindowC
if(!m_DebugWindow)
// Initialize the debug window object.
result = m_DebugWindow->Initialize(m_D3D->GetDevice(), screenWidth, screenHeight, 100, 100);
if(!result)
MessageBox(hwnd, L"Could not initialize the debug window object.", L"Error", MB_OK);
// Create the texture shader object.
m_TextureShader = new TextureShaderC
if(!m_TextureShader)
// Initialize the texture shader object.
result = m_TextureShader->Initialize(m_D3D->GetDevice(), hwnd);
if(!result)
MessageBox(hwnd, L"Could not initialize the texture shader object.", L"Error", MB_OK);
void GraphicsClass::Shutdown()
// Release the texture shader object.
if(m_TextureShader)
m_TextureShader->Shutdown();
delete m_TextureS
m_TextureShader = 0;
在Shutdown方法中释放DebugWindowClass和RenderTextureClass对象。
// Release the debug window object.
if(m_DebugWindow)
m_DebugWindow->Shutdown();
delete m_DebugW
m_DebugWindow = 0;
// Release the render to texture object.
if(m_RenderTexture)
m_RenderTexture->Shutdown();
delete m_RenderT
m_RenderTexture = 0;
// Release the light object.
if(m_Light)
delete m_L
m_Light = 0;
// Release the light shader object.
if(m_LightShader)
m_LightShader->Shutdown();
delete m_LightS
m_LightShader = 0;
// Release the model object.
if(m_Model)
m_Model->Shutdown();
delete m_M
m_Model = 0;
// Release the camera object.
if(m_Camera)
delete m_C
m_Camera = 0;
// Release the Direct3D object.
m_D3D->Shutdown();
delete m_D3D;
m_D3D = 0;
bool GraphicsClass::Frame()
// Set the position of the camera.
m_Camera->SetPosition(0.0f, 0.0f, -5.0f);
bool GraphicsClass::Render()
D3DXMATRIX worldMatrix, viewMatrix, orthoM
第一个pass绘制到纹理。
// Render the entire scene to the texture first.
RenderToTexture();
第二个pass进行普通的绘制。
// Clear the buffers to begin the scene.
m_D3D->BeginScene(0.0f, 0.0f, 0.0f, 1.0f);
// Render the scene as normal to the back buffer.
RenderScene();
绘制完成后将debug window作为2D图像绘制在屏幕50x50的位置。
// Turn off the Z buffer to begin all 2D rendering.
m_D3D->TurnZBufferOff();
// Get the world, view, and ortho matrices from the camera and d3d objects.
m_D3D->GetWorldMatrix(worldMatrix);
m_Camera->GetViewMatrix(viewMatrix);
m_D3D->GetOrthoMatrix(orthoMatrix);
// Put the debug window vertex and index buffers on the graphics pipeline to prepare them for drawing.
result = m_DebugWindow->Render(m_D3D->GetDevice(), 50, 50);
if(!result)
// Render the debug window using the texture shader.
m_TextureShader->Render(m_D3D->GetDevice(), m_DebugWindow->GetIndexCount(), worldMatrix, viewMatrix, orthoMatrix,
m_RenderTexture->GetShaderResourceView());
// Turn the Z buffer back on now that all 2D rendering has completed.
m_D3D->TurnZBufferOn();
// Present the rendered scene to the screen.
m_D3D->EndScene();
RenderToTexture方法将渲染目标视图作为当前的渲染目标,绘制完毕后使用D3Dclass对象将渲染目标重新设置为后备缓存。
void GraphicsClass::RenderToTexture()
// Set the render target to be the render to texture.
m_RenderTexture->SetRenderTarget(m_D3D->GetDevice(), m_D3D->GetDepthStencilView());
将渲染纹理的背景清除为蓝色,这样我们就可以把它与常规的场景绘制区分开来。
// Clear the render to texture.
m_RenderTexture->ClearRenderTarget(m_D3D->GetDevice(), m_D3D->GetDepthStencilView(), 0.0f, 0.0f, 1.0f, 1.0f);
// Render the scene now and it will draw to the render to texture instead of the back buffer.
RenderScene();
// Reset the render target back to the original back buffer and not the render to texture anymore.
m_D3D->SetBackBufferRenderTarget();
RenderScene方法绘制整个场景。本教程中我们在RenderToTexture中调用它一次,将场景绘制到一张纹理中。然后再Render方法中再调用一次将场景绘制到常规的后备缓存中。
void GraphicsClass::RenderScene()
D3DXMATRIX worldMatrix, viewMatrix, projectionM
static float rotation = 0.0f;
// Generate the view matrix based on the camera's position.
m_Camera->Render();
// Get the world, view, and projection matrices from the camera and d3d objects.
m_D3D->GetWorldMatrix(worldMatrix);
m_Camera->GetViewMatrix(viewMatrix);
m_D3D->GetProjectionMatrix(projectionMatrix);
// Update the rotation variable each frame.
rotation += (float)D3DX_PI * 0.005f;
if(rotation > 360.0f)
rotation -= 360.0f;
D3DXMatrixRotationY(&worldMatrix, rotation);
// Put the model vertex and index buffers on the graphics pipeline to prepare them for drawing.
m_Model->Render(m_D3D->GetDevice());
// Render the model using the light shader.
m_LightShader->Render(m_D3D->GetDevice(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix,
m_Model->GetTexture(), m_Light->GetDirection(), m_Light->GetDiffuseColor());
现在你理解了绘制到纹理的基本方法。
1.编译并运行程序,你会看到一个旋转的立方体,并且在屏幕左上角显示一个蓝色背景的小立方体,这是绘制到纹理的效果。
2.修改debug window,使它的长宽比与屏幕的长宽比相同。
3.修改3D场景,确认也能正确地绘制到纹理。
4.修改相机的观察角度观察效果。
5.使用这个纹理作为你自己的shader的输入并改变输出结果(例如添加噪点、扫描行等效果)。
发布时间: 0:28:54&nbsp&nbsp 阅读次数:4413
Copyright &
上海市第八中学,推荐分辨率以上,推荐浏览器IE9.0及以上

我要回帖

更多关于 回收站没有了怎么办 的文章

 

随机推荐