效果框架(4)

效果框架(4)

由于着色器通常是效果文件中的一个关键部分,所以我们在该例程的效果文件中使用了着色器。

/* ****************************************************************************************
  Cartoon shader in an effect file.
 ****************************************************************************************
*/

matrix  g_world_view;
matrix  g_world_view_proj;

vector  g_color;
vector  g_dir_to_light;
texture g_shader_texture;

struct  sVertexInput
{
    vector position : POSITION;
    vector normal    : NORMAL;
};

struct  sVertexOutput
{
    vector position : POSITION;
    float2 uv        : TEXCOORD;
    vector diffuse  : COLOR;
};

////////////////////////////////////////////////////////////////////////////////////////////////

sVertexOutput main(sVertexInput input)
{
    sVertexOutput output 
=  (sVertexOutput)  0 ;

    
//  transforma vertex position to homogenous clip space
    output.position  =  mul(input.position, g_world_view_proj);

    
//  Transform lights and normals to view space, set w components to zero since we're transforming vectors.
    
//  Assume there are no scalings in the world matrix as well.

    g_dir_to_light.w 
=   0.0f ;
    input.normal.w   
=   0.0f ;

    g_dir_to_light 
=  mul(g_dir_to_light, g_world_view);
    input.normal   
=  mul(input.normal,   g_world_view);

    
//  compute the 1D texture coordinate for catoon rendering

    
float  u  =  dot(g_dir_to_light, input.normal);

    
//  Clamp to zero if u is negative because u negative implies the angle between the light and normal 
    
//  is greater than 90 degrees.  And if that is true then the surface receives no light.
     if (u  <   0.0f )
        u 
=   0.0f ;

    
float  v  =   0.5f ;     //  set other texture coordinate to middle

    output.uv.x 
=  u;
    output.uv.y 
=  v;

    output.diffuse 
=  g_color;     //  save color
    
    
return  output;
}

sampler ShaderSampler 
=  sampler_state
{
    Texture   
=  (g_shader_texture);
    MinFilter 
=  POINT;
    MagFilter 
=  POINT;
    MipFilter 
=  NONE;     //  no filtering for cartoon shading
};

technique CartoonTech
{
    pass pass0
    {
        vertexshader 
=  compile vs_1_1 main();

        Sampler[
0 =  (ShaderSampler);
    }
}

 我们注意到卡通着色器函数被定义在效果文件中,并且我们指定着色器使用一个特定的通道,在通道部分使用语法:vertexshader = compile vs_1_1 main();。在效果文件中的设备状态象通常一样设置。


执行程序:

/* *************************************************************************************************
  Demonstrates cartoon rendering using a vertex shader in an effect file.  You will have to switch to 
  the REF device to run this sample if your hardware does not support shaders.  
  Or you can use software vertex processing: D3DCREATE_SOFTWARE_VERTEXPROCESSING. 
 *************************************************************************************************
*/

#include 
" d3dUtility.h "

#pragma warning(disable : 
4100 )

#define  MESH_TEAPOT        0
#define  MESH_SPHERE        1
#define  MESH_TORUS        2
#define  MESH_CYLINDER    3
#define  NUM_MESH        4

const   int  WIDTH   =   640 ;
const   int  HEIGHT  =   480 ;

IDirect3DDevice9
*         g_device;
ID3DXEffect
*             g_cartoon_effect;
IDirect3DTexture9
*         g_shader_texture;
ID3DXMesh
*                 g_meshes[NUM_MESH];
D3DXMATRIX                g_world_matrices[NUM_MESH];
D3DXVECTOR4                g_mesh_colors[NUM_MESH];
D3DXMATRIX                g_proj_matrix;

D3DXHANDLE                g_world_view_handle;
D3DXHANDLE                g_world_view_proj_handle;
D3DXHANDLE                g_color_handle;
D3DXHANDLE                g_dir_to_light_handle;
D3DXHANDLE                g_shader_texture_handle;
D3DXHANDLE                g_cartoon_tech_handle;

/////////////////////////////////////////////////////////////////////////////////////////////////// /

bool  setup()
{    
    D3DXCreateTeapot(g_device, 
& g_meshes[MESH_TEAPOT], NULL);
    D3DXCreateSphere(g_device, 
1.0f 20 20 & g_meshes[MESH_SPHERE], NULL);
    D3DXCreateTorus(g_device, 
0.5f 1.0f 20 20 & g_meshes[MESH_TORUS], NULL);
    D3DXCreateCylinder(g_device, 
0.5f 0.5f 2.0f 20 20 & g_meshes[MESH_CYLINDER], NULL);

    D3DXMatrixTranslation(
& g_world_matrices[MESH_TEAPOT],     0.0f ,    2.0f 0.0f );
    D3DXMatrixTranslation(
& g_world_matrices[MESH_SPHERE],     0.0f ,   - 2.0f 0.0f );
    D3DXMatrixTranslation(
& g_world_matrices[MESH_TORUS],     - 3.0f ,    0.0f 0.0f );
    D3DXMatrixTranslation(
& g_world_matrices[MESH_CYLINDER],   3.0f ,    0.0f 0.0f );

    g_mesh_colors[MESH_TEAPOT]   
=  D3DXVECTOR4( 1.0f 0.0f 0.0f 1.0f );
    g_mesh_colors[MESH_SPHERE]   
=  D3DXVECTOR4( 0.0f 1.0f 0.0f 1.0f );
    g_mesh_colors[MESH_TORUS]    
=  D3DXVECTOR4( 0.0f 0.0f 1.0f 1.0f );
    g_mesh_colors[MESH_CYLINDER] 
=  D3DXVECTOR4( 1.0f 1.0f 0.0f 1.0f );

    
//  create effects
    
    ID3DXBuffer
*     error_buffer;

    HRESULT hr 
=  D3DXCreateEffectFromFile(g_device,  " CartoonShader.cxx " , NULL, NULL,        
                    D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY, NULL, 
& g_cartoon_effect,  & error_buffer);

    
//  output any error messages
     if (error_buffer)
    {
        MessageBox(NULL, (
char * )error_buffer -> GetBufferPointer(),  " ERROR " , MB_OK);
        safe_release
< ID3DXBuffer *> (error_buffer);
    }

    
if (FAILED(hr))
    {
        MessageBox(NULL, 
" D3DXCreateEffectFromFile() - FAILED " " ERROR " , MB_OK);
        
return   false ;
    }

    
//  save frequently accessed parameter handles
    g_cartoon_tech_handle      =  g_cartoon_effect -> GetTechniqueByName( " CartoonTech " );
    g_shader_texture_handle  
=  g_cartoon_effect -> GetParameterByName(NULL,  " g_shader_texture " );
    g_world_view_handle         
=  g_cartoon_effect -> GetParameterByName(NULL,  " g_world_view " );
    g_world_view_proj_handle 
=  g_cartoon_effect -> GetParameterByName(NULL,  " g_world_view_proj " );
    g_color_handle             
=  g_cartoon_effect -> GetParameterByName(NULL,  " g_color " );
    g_dir_to_light_handle     
=  g_cartoon_effect -> GetParameterByName(NULL,  " g_dir_to_light " );

    
//  projection
    D3DXMatrixPerspectiveFovLH( & g_proj_matrix, D3DX_PI / 4.0f , ( float )WIDTH / HEIGHT,  1.0f 1000.0f );

    
//
    
//  set effect paramters
    
//

    
//  light direction
    D3DXVECTOR4 dir_to_light( - 0.57f 0.57f - 0.57f 0.0f );
    g_cartoon_effect
-> SetVector(g_dir_to_light_handle,  & dir_to_light);

    
//  set texture
    IDirect3DTexture9 *  texture;
    D3DXCreateTextureFromFile(g_device, 
" toonshade.bmp " & texture);
    g_cartoon_effect
-> SetTexture(g_shader_texture_handle, texture);
    safe_release
< IDirect3DTexture9 *> (texture);
    
    
// g_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
    
    
return   true ;
}

////////////////////////////////////////////////////////////////////////////////////////////////////// /

void  cleanup()
{    
    
for ( int  i  =   0 ; i  <  NUM_MESH; i ++ )
        safe_release
< ID3DXMesh *> (g_meshes[i]);

    safe_release
< IDirect3DTexture9 *> (g_shader_texture);    
    safe_release
< ID3DXEffect *> (g_cartoon_effect);    
}

////////////////////////////////////////////////////////////////////////////////////////////////////// /

bool  display( float  time_delta)
{    
    
static   float  angle   =  ( 3.0f   *  D3DX_PI)  /   2.0f ;
    
static   float  height  =   5.0f ;

    
if (GetAsyncKeyState(VK_LEFT)  &   0x8000f )
        angle 
-=   0.5f   *  time_delta;

    
if (GetAsyncKeyState(VK_RIGHT)  &   0x8000f )
        angle 
+=   0.5f   *  time_delta;

    
if (GetAsyncKeyState(VK_UP)  &   0x8000f )
        height 
+=   5.0f   *  time_delta;

    
if (GetAsyncKeyState(VK_DOWN)  &   0x8000f )
        height 
-=   5.0f   *  time_delta;

    D3DXVECTOR3 position(cosf(angle) 
*   7.0f , height, sinf(angle)  *   7.0f );
    D3DXVECTOR3 target(
0.0f 0.0f 0.0f );
    D3DXVECTOR3 up(
0.0f 1.0f 0.0f );

    D3DXMATRIX view_matrix;
    D3DXMatrixLookAtLH(
& view_matrix,  & position,  & target,  & up);    
    
    
//  activate the technique and render

    g_device
-> Clear( 0 , NULL, D3DCLEAR_TARGET  |  D3DCLEAR_ZBUFFER,  0xFF333333 1.0f 0 );

    g_device
-> BeginScene();

    g_cartoon_effect
-> SetTechnique(g_cartoon_tech_handle);

    UINT num_passes;
    g_cartoon_effect
-> Begin( & num_passes,  0 );

    D3DXMATRIX world_view, world_view_proj;

    
for (UINT i  =   0 ; i  <  num_passes; i ++ )
    {
        g_cartoon_effect
-> BeginPass(i);

        
for ( int  j  =   0 ; j  <  NUM_MESH; j ++ )
        {
            world_view        
=  g_world_matrices[j]  *  view_matrix;
            world_view_proj 
=  g_world_matrices[j]  *  view_matrix  *  g_proj_matrix;

            g_cartoon_effect
-> SetMatrix(g_world_view_handle,         & world_view);
            g_cartoon_effect
-> SetMatrix(g_world_view_proj_handle,     & world_view_proj);
            g_cartoon_effect
-> SetVector(g_color_handle,                 & g_mesh_colors[j]);

            g_cartoon_effect
-> CommitChanges();

            g_meshes[j]
-> DrawSubset( 0 );
        }    

        g_cartoon_effect
-> EndPass();
    }    
    
    g_cartoon_effect
-> End();
    g_device
-> EndScene();

    g_device
-> Present(NULL, NULL, NULL, NULL);

    
return   true ;
}

////////////////////////////////////////////////////////////////////////////////////////////////////// /

LRESULT CALLBACK wnd_proc(HWND hwnd, UINT msg, WPARAM word_param, LPARAM long_param)
{
    
switch (msg)
    {
    
case  WM_DESTROY:
        PostQuitMessage(
0 );
        
break ;

    
case  WM_KEYDOWN:
        
if (word_param  ==  VK_ESCAPE)
            DestroyWindow(hwnd);

        
break ;
    }

    
return  DefWindowProc(hwnd, msg, word_param, long_param);
}

////////////////////////////////////////////////////////////////////////////////////////////////////// /

int  WINAPI WinMain(HINSTANCE inst, HINSTANCE, PSTR cmd_line,  int  cmd_show)
{
    
if ( !  init_d3d(inst, WIDTH, HEIGHT,  true , D3DDEVTYPE_HAL,  & g_device))
    {
        MessageBox(NULL, 
" init_d3d() - failed. " 0 , MB_OK);
        
return   0 ;
    }

    
if ( !  setup())
    {
        MessageBox(NULL, 
" Steup() - failed. " 0 , MB_OK);
        
return   0 ;
    }

    enter_msg_loop(display);

    cleanup();
    g_device
-> Release();

    
return   0 ;
}


程序截图:

效果框架(4)_第1张图片

 

下载源程序


你可能感兴趣的:(效果框架(4))