刚写的一个小程序用HLSL渲染简单三角形,代码如下:
frame.fx
float4x4 matWorldViewProj : WVP;
struct vertexshader_input
{
float4 position : POSITION;
float4 diffuse : COLOR0;
};
struct vertexshader_output
{
float4 position : POSITION;
float4 diffuse : COLOR0;
};
//定义一个VertexShader函数作为入口,并定义返回值的语义为POSITION
vertexshader_output vs_main( vertexshader_input IN )
{
vertexshader_output OUT;
OUT.position = mul( IN.position, matWorldViewProj );
OUT.diffuse = IN.diffuse;
return OUT;
}
//定义一个PixelShader函数作为入口,并定义语义为COLOR0
float4 ps_main( vertexshader_output IN ) : COLOR0
{
return IN.diffuse;
}
//开始定义technique
technique test
{
//一个pass
pass p0
{
//将VertexShader的版本设为1.1,并将执行函数设为vs_main
VertexShader = compile vs_1_1 vs_main();
//同理将PixelShader的版本也设为1.1,并将执行函数设为ps_main
PixelShader = compile ps_2_0 ps_main();
}
}
Geometry.h
#ifndef __GEOMETRY_H__
#define __GEOMETRY_H__
#pragma once
#include "Common.h"
/** 几何体类
*/
class CGeometry
{
public:
CGeometry( LPDIRECT3DDEVICE9 pDevice );
~CGeometry();
HRESULT Init();
HRESULT InitVB(); //初始化顶点缓冲区
void Update();
void Render();
void CleanUp();
protected:
private:
LPDIRECT3DDEVICE9 m_pd3dDevice; //D3D设备
LPDIRECT3DVERTEXBUFFER9 m_pVBPos; //顶点坐标缓冲区
LPDIRECT3DVERTEXBUFFER9 m_pVBCol; //顶点颜色缓冲区
LPDIRECT3DVERTEXDECLARATION9 m_pVertexDecl;
LPD3DXEFFECT m_pEffect; //ID3DXEffect对象指针
LPD3DXBUFFER m_pErrors; //返回的错误信息
};
#endif //__GEOMETRY_H__
Geometry.cpp
#include "Geometry.h"
CGeometry::CGeometry( LPDIRECT3DDEVICE9 pDevice ) :
m_pd3dDevice( pDevice ),
m_pVBPos( NULL ),
m_pVBCol( NULL ),
m_pVertexDecl(NULL)
{
}
CGeometry::~CGeometry()
{
}
HRESULT CGeometry::Init()
{
if ( FAILED( InitVB() ) )
return E_FAIL;
//从HLSL代码文件中创建ID3DXEffect对象
if ( FAILED( D3DXCreateEffectFromFile(
m_pd3dDevice,
".//frame.fx",
NULL,
NULL,
0,
NULL,
&m_pEffect,
&m_pErrors ) ) )
{
//获得错误信息
LPCTSTR pErrorMsg = (LPCTSTR)m_pErrors->GetBufferPointer();
MessageBox( NULL, pErrorMsg, "HLSLError", MB_OK );
return E_FAIL;
}
return S_OK;
}
HRESULT CGeometry::InitVB()
{
D3DVERTEXELEMENT9 shaderDecl[] =
{
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
{ 0xFF, 0, D3DDECLTYPE_UNUSED, 0, 0, 0 }
};
D3DVECTOR Positions[] =
{
{ -1.0f, -1.0f, 0.0f },
{ 0.0f, 1.0f, 0.0f },
{ 1.0f, -1.0f, 0.0f }
};
D3DCOLOR Colors[] =
{
D3DCOLOR_XRGB(255, 0, 0),
D3DCOLOR_XRGB(0, 255, 0),
D3DCOLOR_XRGB(0, 0, 255)
};
m_pd3dDevice->CreateVertexBuffer( 3 * sizeof(D3DVECTOR), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,
0, D3DPOOL_DEFAULT, &m_pVBPos, NULL );
m_pd3dDevice->CreateVertexBuffer( 3 * sizeof(D3DCOLOR), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,
0, D3DPOOL_DEFAULT, &m_pVBCol, NULL );
m_pd3dDevice->CreateVertexDeclaration( shaderDecl, &m_pVertexDecl );
void* pPositions;
m_pVBPos->Lock( 0, 0, &pPositions, 0 );
memcpy( pPositions, Positions, sizeof(Positions) );
m_pVBPos->Unlock();
void* pColor;
m_pVBCol->Lock( 0, 0, &pColor, 0 );
memcpy( pColor, Colors, sizeof(Colors) );
m_pVBCol->Unlock();
return S_OK;
}
void CGeometry::Update()
{
}
void CGeometry::Render()
{
m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
m_pd3dDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
m_pd3dDevice->SetVertexDeclaration( m_pVertexDecl );
m_pd3dDevice->SetStreamSource( 0, m_pVBPos, 0, sizeof(D3DVECTOR) );
m_pd3dDevice->SetStreamSource( 1, m_pVBCol, 0, sizeof(D3DCOLOR) );
D3DXHANDLE handle;
D3DXMATRIX matWorldViewProj;
D3DXMATRIX matWorld, matView, matProj;
D3DXMatrixIdentity( &matWorld );
m_pd3dDevice->GetTransform( D3DTS_VIEW, &matView );
m_pd3dDevice->GetTransform( D3DTS_PROJECTION, &matProj );
D3DXMatrixMultiply( &matWorldViewProj, &matWorld, &matView );
D3DXMatrixMultiply( &matWorldViewProj, &matWorldViewProj, &matProj );
handle = m_pEffect->GetParameterBySemantic( NULL, "WVP" );
if ( !handle )
{
OutputDebugString( "获得组合矩阵失败!" );
return;
}
m_pEffect->SetMatrix( handle, &matWorldViewProj );
handle = m_pEffect->GetTechniqueByName( "test" );
if ( !handle )
{
OutputDebugString( "获取technique失败!/n" );
return;
}
m_pEffect->SetTechnique( handle );
UINT passes;
m_pEffect->Begin( &passes, 0 );
for ( UINT i=0; iGetPass( handle, i );
if ( !handle )
{
OutputDebugString( "获取pass失败!/n" );
return;
}
m_pEffect->BeginPass( i );
m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 );
m_pEffect->EndPass();
}
m_pEffect->End();
m_pd3dDevice->SetStreamSource(0, NULL, 0, sizeof(D3DVECTOR));
m_pd3dDevice->SetStreamSource(1, NULL, 0, sizeof(D3DCOLOR));
}
void CGeometry::CleanUp()
{
SAFE_RELEASE(m_pEffect);
SAFE_RELEASE(m_pVertexDecl);
SAFE_RELEASE(m_pVBCol);
SAFE_RELEASE(m_pVBPos);
}
调用部分:
CGeometry* m_pGeometry;
m_pGeometry = new CGeometry( m_pDevice );
if ( !m_pGeometry )
return E_FAIL;
if ( FAILED( m_pGeometry->Init() ) )
return E_FAIL;
//清除后缓冲的内容,设置背景为黑
m_pDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
//开始渲染
m_pDevice->BeginScene();
//图形渲染操作
m_pGeometry->Render();
//结束渲染
m_pDevice->EndScene();
//翻转
m_pDevice->Present(NULL, NULL, NULL, NULL);