Direct3D效果框架

news/2025/2/12 22:08:52/

一、概述


   一种绘制效果通常由以下几部分构成:一个顶点着色器、一个像素着色器、一个需要设置的设备状态列表、一条或多条绘制路径。我们希望采用一种低效运行机制针对不同级别的图形硬件的绘制效果(即,在现有硬件条件下,物尽其用,实现与理想效果尽可能接近的效果)。显然,所有的绘制任务都是与某一种效果相关。所以,将这些任务封装到一个单元中是比较符合逻辑的。

         Direct3D效果框架(effects framework)为上述的任务封装提供了一种机制,该机制能够将与绘制效果相关的任务封装到一个效果文件(effect file)中。在效果文件中实现各种效果有诸多优点。其中之一是无需重新编译应用程序的源代码便可改变某种效果的实现。这样就使得效果的更新过程,无论是修正 bug、简单的效果增强或利用最新的 3D 硬件性能都变得更容易。其次,它把与效果相关的所有部件都封装到了一个文件中,这就程序的维护带来了极大的便利。

二、手法与路径


        一个效果文件中包含了一种或多种手法(technique)。手法是绘制某些特效的特定方法。即效果文件为绘制同样的特效提供了一种或多种不同的方式。由于一些硬件可能不支持某种效果的具体实现,所以,很有必要针对不同级别的硬件实现同样效果的不同版本。

         每种手法都包含了一条或多条绘制路径(rendering pass)。绘制路径封装了设备状态、采样器以及(或)用于为该条特定绘制路径绘制几何体的着色器。使用多条路径的原因是由于想要实现某些特效,必须对每条路径,以不同的绘制状态和着色器将同一几何体进行多次绘制。

         效果并不局限于在可编程流水线中使用,例如,效果也可用于固定功能流水线中对设备状态(如光照、材质和纹理等)进行控制

三、效果文件中的设备状态


  通常,要想正确实现某种效果,我们必须对设备状态(例如绘制状态、纹理状态、材质、光照、纹理等)进行设置。为了支持将某一完整的效果封装在一个效果文件中的这种能力,效果框架允许我们在效果文件中对设备状态进行设置。设备状态的设置应位于某一绘制路径的代码中,语法如下所示:

         State = Value;

四、效果文件的使用步骤


  1、创建效果


         HRESULT   D3DXCreateEffectFromFileA(
           LPDIRECT3DDEVICE9               pDevice,
           LPCSTR                          pSrcFile,
           CONST D3DXMACRO*                pDefines,
           LPD3DXINCLUDE                   pInclude,
           DWORD                           Flags,
           LPD3DXEFFECTPOOL                pPool,
           LPD3DXEFFECT*                   ppEffect,
           LPD3DXBUFFER*                   ppCompilationErrors);

 2、效果句柄的获取


       使用某种手法的第一步是获取该手法的D3DXHANDLE句柄,获取方法如下:

       D3DXHANDLE ID3DXEffect ::GetTechniqueByName(LPCSTR  pName);

3、效果的激活


      一旦获取了所要采取的手法的句柄,接下来我们必须激活该手法。方法如下:

      HRESULT  ID3DXEffect ::SetTechnique(D3DXHANDLE  hTechnique);

4、效果的启用


        为了使用某种效果绘制几何体,我们必须将所有的绘制函数调用都写在函数ID3DXEffect::Begin 和ID3DXEffect::End之间。这两个函数实质上分别起到了启用(enable)和禁用(disable)的功能。

        HRESULT  ID3DXEffect::Begin (  UINT*  pPasses, DWORD  Flags);

       ●pPasses   返回当前处于活动状态的手法中的路径数目。
       ●Flags     该参数可取自下列任何标记:
           ◆Zero(0)  指示效果要保存当前设备状态和着色器状态,并在效果完成后(调用IDEDXEffect::End 函数后)恢复这些状态。
           ◆D3DXFX_DONOTSAVESTATE   指示效果不保存也不恢复设备状态(着色器状态除外)。
           ◆D3DXFX_DONOTSAVESHADERSTATE 指示效果不保存也不必恢复着色器状态。

5、当前绘制路径的设置


         在我们使用一种效果绘制任何几何体之前,我们必须指定所要使用的绘制路径。指定方法为:在绘制几何体之前,应首先调用 ID3DXEffect::BeginPass 方法,该方法接受一个标识了当前活动路径的参数,几何体绘制完毕后,还必须调用 ID3DXEffect::EndPass 方法来终止当前活动路径。即 ID3DXEffect::BeginPass 方法和 ID3DXEffect::EndPass 方法必须成对出现,完成实际绘制的代码应该放在这两个函数之间,而且这两个函数必须位于函数对  ID3DXEffect::Begin 和 ID3DXEffect::End 之间。

6、效果的终止


      最终,当在每条路径中绘制完几何体后,我们应调用函数  ID3DXEffect::End 来禁用或终止该效果。

五、源代码

1、效果文件

// Globals
matrix ViewProjMatrix;// Structures
struct VS_INPUT
{vector position  : POSITION;vector color : COLOR;
};struct VS_OUTPUT
{vector position : POSITION;vector diffuse  : COLOR;
};struct PS_INPUT
{vector color : COLOR;
};struct PS_OUTPUT
{vector diffuse  : COLOR;
};VS_OUTPUT vshader(VS_INPUT input)
{VS_OUTPUT output = (VS_OUTPUT)0;output.position = mul(input.position, ViewProjMatrix);output.diffuse = input.color;return output;
}PS_OUTPUT pshader(PS_INPUT input)
{// zero out members of outputPS_OUTPUT output = (PS_OUTPUT)0;output.diffuse = input.color;return output;
}sampler ShadeSampler = sampler_state
{MinFilter = POINT;MagFilter = POINT;MipFilter = NONE;
};technique MEFFECT
{pass P0{vertexShader = compile vs_1_1 vshader();pixelShader = compile ps_2_0 pshader();Sampler[0] = (ShadeSampler);}
}

2、程序代码

#include <Windows.h>
#include <mmsystem.h>
#include <d3dx9.h>
#pragma warning( disable : 4996 ) // disable deprecated warning 
#include <strsafe.h>
#pragma warning( default : 4996 )
#include <d3dx9math.h>LPDIRECT3D9             g_pD3D = NULL; 
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; 
LPDIRECT3DVERTEXDECLARATION9 VertexDecl = NULL;
ID3DXEffect* m_Effect    = NULL;
D3DXHANDLE m_TechHandle      = NULL;
D3DXHANDLE ViewProjMatrixHandle = NULL;struct CUSTOMVERTEX
{FLOAT x, y, z;DWORD color;
};bool Effect()
{ID3DXBuffer* errorBuffer = 0;HRESULT hr = D3DXCreateEffectFromFile(g_pd3dDevice,           // associated device"shade.txt", // effect filename0,                // no preprocessor definitions0,                // no ID3DXInclude interfaceD3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY, // compile flags0,                // don't share parameters&m_Effect,      // return effect&errorBuffer);    // return error messages// output any error messagesif( errorBuffer ){::MessageBox(0, (char*)errorBuffer->GetBufferPointer(), 0, 0);errorBuffer->Release();}if(FAILED(hr)){::MessageBox(0, "D3DXCreateEffectFromFile() - FAILED", 0, 0);return false;}return true;
}bool VertexBuffer()
{if(g_pVB)return true;g_pd3dDevice->CreateVertexBuffer(3 * sizeof(CUSTOMVERTEX), 0,0,D3DPOOL_MANAGED,&g_pVB,0);CUSTOMVERTEX* v;g_pVB->Lock(0, 0, (void**)&v, 0);v[0].x = -1, v[0].y = -1, v[0].z = 0, v[0].color = D3DCOLOR_XRGB(255, 0, 0);v[1].x = 0, v[1].y = 1, v[1].z = 0, v[1].color = D3DCOLOR_XRGB(0, 255, 0);v[2].x = 1, v[2].y = -1, v[2].z = 0, v[2].color = D3DCOLOR_XRGB(0, 0, 255);g_pVB->Unlock();return true;
}bool VertexDeclaration()
{if(VertexDecl)return true;D3DVERTEXELEMENT9 decl[] = {{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},{0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},D3DDECL_END()};g_pd3dDevice->CreateVertexDeclaration(decl, &VertexDecl);g_pd3dDevice->SetVertexDeclaration(VertexDecl);return true;
}bool GetHandles()
{if(m_TechHandle)return true;m_TechHandle = m_Effect->GetTechniqueByName("MEFFECT");ViewProjMatrixHandle = m_Effect->GetParameterByName(0, "ViewProjMatrix");return true;
}HRESULT InitD3D(HWND hWnd)
{if (NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))return E_FAIL;// Set up the structure used to create the D3DDeviceD3DPRESENT_PARAMETERS d3dpp;ZeroMemory(&d3dpp, sizeof(d3dpp));d3dpp.Windowed = TRUE;d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;d3dpp.EnableAutoDepthStencil = TRUE;d3dpp.AutoDepthStencilFormat = D3DFMT_D16;// Create the D3DDeviceif (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp, &g_pd3dDevice))){return E_FAIL;}return S_OK;
}VOID SetupMatrices()
{D3DXVECTOR3 vEyePt(0.0f, 0.0f, -5);D3DXVECTOR3 vLookatPt(0.0f, 0.0f, 0.0f);D3DXVECTOR3 vUpVec(0.0f, 1.0f, 0.0f);D3DXMATRIXA16 matView;D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUpVec);//D3DXMatrixPerspectiveFovLH()函数中的最远、最近距离为相对于视点的距离(即vEyePt中的距离)D3DXMATRIXA16 matProj;D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 4, 1.0f, 1.0f, 200.0f);D3DXMATRIX ViewProjMatrix = matView * matProj;m_Effect->SetMatrix(ViewProjMatrixHandle, &ViewProjMatrix);
}VOID Cleanup()
{if (g_pVB != NULL)g_pVB->Release();if (g_pd3dDevice != NULL)g_pd3dDevice->Release();if (g_pD3D != NULL)g_pD3D->Release();if (VertexDecl != NULL)VertexDecl->Release();if (m_Effect != NULL)m_Effect->Release();}int Render()
{g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(255, 255, 255), 1.0f, 0);if (SUCCEEDED(g_pd3dDevice->BeginScene())){m_Effect->SetTechnique( m_TechHandle );UINT numPasses = 0;m_Effect->Begin(&numPasses, 0);for(int i = 0; i < numPasses; i++){m_Effect->BeginPass(i);g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));g_pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1);m_Effect->EndPass();}m_Effect->End();g_pd3dDevice->EndScene();}g_pd3dDevice->Present(NULL, NULL, NULL, NULL);return 0;
}LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{switch (msg){case WM_DESTROY:Cleanup();PostQuitMessage(0);return 0;}return DefWindowProc(hWnd, msg, wParam, lParam);
}void InitShader()
{VertexBuffer();VertexDeclaration();Effect();GetHandles();SetupMatrices();
}INT WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, INT)
{UNREFERENCED_PARAMETER(hInst);// Register the window classWNDCLASSEX wc ={sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,GetModuleHandle(NULL), NULL, NULL, NULL, NULL,"D3D Tutorial", NULL};RegisterClassEx(&wc);// Create the application's windowHWND hWnd = CreateWindow("D3D Tutorial", "D3D: Effect with shader",WS_OVERLAPPEDWINDOW, 100, 100, 700, 700,NULL, NULL, wc.hInstance, NULL);if (SUCCEEDED(InitD3D(hWnd))){ShowWindow(hWnd, SW_SHOWDEFAULT);UpdateWindow(hWnd);InitShader();MSG msg;ZeroMemory(&msg, sizeof(msg));while (msg.message != WM_QUIT){if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)){TranslateMessage(&msg);DispatchMessage(&msg);}elseRender();}}UnregisterClass("D3D Tutorial", wc.hInstance);return 0;
}


3、运行效果




http://www.ppmy.cn/news/388590.html

相关文章

Direct3D中的纹理映射

一、概要 为了使渲染的图形看起来更真实&#xff0c;Direct3D提供了在物体表面绘制纹理的功能。一般来说&#xff0c;纹理是表示物体表面细节的一幅或几幅二维图形&#xff0c;也称纹理贴图。借助纹理映射技术&#xff0c;我们可将图像数据映射到三角形单元中&#xff0c;这种功…

Direct3D中的光照

一、概述 为了增强所绘制场景的真实感&#xff0c;我们可以为场景增加光照。光照也有助于描述实体形状和立体感。使用光照时&#xff0c;我们无需自行指定顶点的颜色值&#xff1a;Direct3D会将顶点送入光照计算引擎&#xff0c;依据光源类型、材质以及物体表面相对于光源的朝向…

Direct3D初始化例程

看过Direct3D初始化之后&#xff0c;我们来总体的串一下&#xff0c;搞出个示例&#xff0c;方便学习。 我们现在要做的就是实现Direct3D的初始化&#xff0c;并将背景设置为红色。 在下面的例子中&#xff0c;我们使用了d3dUtility.h/cpp&#xff0c;这两个文件中就是实现每…

Direct3D基础——Direct3D的初始化

首先概述一下Direct初始化的大概步骤&#xff08;稍后我们会详细说明&#xff09;&#xff1a; 1、获取接口IDirect3D9 的指针。该接口用于获取系统物理硬件设备的信息并创建接口&#xff1a;IDirect3DDevice9&#xff0c;接口可以看是一个C对象&#xff0c;代表了我们用来显示…

从 Direct3D 9 到 Direct3D 11 的重要更改

本主题介绍 DirectX 9 和 DirectX 11 之间更高级别的差异。 从根本上说&#xff0c;Direct3D 11 与 Direct3D 9 是同类型的 API - 一种到图形硬件的低级别虚拟化接口。它还允许你在各种硬件实现上执行图形绘制操作。自 Direct3D 9 起&#xff0c;图形 API 的布局已更改&#xf…

初始化Direct3D

一、Direct3D概述 DirectX是微软公司开发的一套功能丰富的底层API&#xff0c;其功能涵盖了&#xff1a; 2D/3D图形加速的支持、 各种输入设备的控制、 声音和音乐输出的混音和采样、 多玩家网络游戏的控制、 各种多媒体流媒体模式的控制等。 DirectX在体系结构上很突出的优点是…

Direct3D播放RGB(通过Texture)

&#xfeff;&#xfeff; 本文接着上一篇文章继续记录Direct3D&#xff08;简称D3D&#xff09;播放视频的技术。上一篇文章中已经记录了使用Direct3D中的Surface渲染视频的技术。本文记录一种稍微复杂但是更加灵活的渲染视频的方式&#xff1a;使用Direct3D中的Texture&#…

Main.obj : error LNK2019: 无法解析的外部符号 _Direct3DCreate9@4,该符号在函数 long __cdecl InitD3D(struct HWND__ *)

错误问题&#xff1a; Main.obj : error LNK2019: 无法解析的外部符号 _Direct3DCreate94&#xff0c;该符号在函数 "long __cdecl InitD3D(struct HWND__ *)" (?InitD3DYAJPAUHWND__Z) 中被引用 1>G:\Visual_studio\Project\MyD3D_1\Debug\MyD3D_1.exe : fatal …