HLSL顶点渲染

//==============================================================
// Desc: 顶点渲染器代码
//==============================================================

//坐标变换矩阵
float4x4 matWorldViewProj;	

//--------------------------------------------------------------
// Desc: 输出结构
//--------------------------------------------------------------
struct VS_OUTPUT
{
   float4 Pos   : POSITION;
   float4 Color : COLOR;
};

//--------------------------------------------------------------
// Desc: 顶点渲染
//--------------------------------------------------------------
VS_OUTPUT VS( float4 Pos: POSITION, float4 Color: COLOR )
{
   VS_OUTPUT Out = (VS_OUTPUT) 0; 
   Out.Pos = mul(Pos, matWorldViewProj);
   Out.Color = Color;
   return Out;
}
#pragma once
#include "stdafx.h"
#include "template.h"
//-----------------------------------------------------------------------------
// 全局变量
//-----------------------------------------------------------------------------
LPDIRECT3D9                g_pD3D       = NULL; //Direct3D对象
LPDIRECT3DDEVICE9          g_pd3dDevice = NULL; //Direct3D设备对象
LPDIRECT3DVERTEXBUFFER9    g_pVB        = NULL;    //顶点缓冲区对象
LPDIRECT3DINDEXBUFFER9     g_pIB        =NULL;     //索引缓冲区对象
LPDIRECT3DTEXTURE9         g_pTexture   = NULL;    //纹理对象

IDirect3DVertexShader9*      g_pVertexShader      = NULL; //顶点渲染器
LPD3DXCONSTANTTABLE          g_pConstantTable_VS  = NULL; //常量表对象
D3DXMATRIXA16                matWorldViewProj;
//-----------------------------------------------------------------------------
// 显示帧率
//-----------------------------------------------------------------------------
ID3DXFont* Font   = 0;
DWORD FrameCnt    = 0;
float TimeElapsed = 0;
float timeDelta   =0;
float FPS         = 0;
TCHAR TFPSString[100];
//-----------------------------------------------------------------------------
// Desc: 顶点结构
//-----------------------------------------------------------------------------

//定义顶点结构和顶点灵活格式
struct CUSTOMVERTEX
{
	D3DXVECTOR3 position;
	DWORD color;
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)

float g_fSpinX = 0.0f;
float g_fSpinY = 0.0f;
float g_fDisZ = 0.0f;
HRESULT InitGeometry(HWND hWnd )
{
	//创建纹理对象
	if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, L"512.jpg", &g_pTexture ) ) )
	{
		MessageBox(NULL, L"创建纹理失败", L"Texture.exe", MB_OK);
		return E_FAIL;
	}

	RECT   clientrc; 
	GetClientRect(hWnd,&clientrc); 
	RECT   windowrc; 
	GetWindowRect(hWnd,&windowrc);
	int borderwidth=(windowrc.right-windowrc.left)-(clientrc.right-clientrc.left);
	int borderheight=(windowrc.bottom-windowrc.top)-(clientrc.bottom-clientrc.top);

	D3DSURFACE_DESC Desc;
	g_pTexture->GetLevelDesc(0, &Desc);
	SetWindowPos(hWnd,NULL,0,0,borderwidth+Desc.Width,borderheight+Desc.Height,SWP_NOZORDER|SWP_NOMOVE);
	

	//创建顶点缓冲区
	g_pd3dDevice->CreateVertexBuffer( 3*sizeof(CUSTOMVERTEX),
		0, D3DFVF_CUSTOMVERTEX,
		D3DPOOL_MANAGED, &g_pVB, NULL );
	//填充顶点缓冲区
	CUSTOMVERTEX* pVertices;
	g_pVB->Lock( 0, 0, (void**)&pVertices, 0 ) ;
	pVertices[0].position = D3DXVECTOR3(-1.5f, -1.5f,  0.0f);
	pVertices[0].color    = 0xffff0000;
	pVertices[1].position = D3DXVECTOR3(1.5f, -1.5f, 0.0f);
	pVertices[1].color    = 0xff00ff00;
	pVertices[2].position = D3DXVECTOR3(0.0f,  1.5f, 0.0f);
	pVertices[2].color    = 0xff00ffff;
	g_pVB->Unlock(); 
	return S_OK;
}
//-----------------------------------------------------------------------------
// Desc: 设置观察矩阵和投影矩阵
//-----------------------------------------------------------------------------
VOID SetWorldMatrix()
{
	static long curTime=0;
	static float elapsetime=0;
	elapsetime = (timeGetTime()-curTime)/1000.0f;
	curTime = timeGetTime();


	D3DXMATRIX matRotation;
	D3DXMATRIX matTranslation;
	D3DXMatrixRotationYawPitchRoll( &matRotation, D3DXToRadian(g_fSpinX), D3DXToRadian(g_fSpinY), 0.0f );
	D3DXMatrixTranslation( &matTranslation, 0.0f, 0.0f, g_fDisZ );
	matWorldViewProj = matRotation * matTranslation;
	g_pConstantTable_VS->SetMatrix( g_pd3dDevice, "matWorldViewProj", &matWorldViewProj );


}
VOID SetupViewandProjMatrices()
{
	//创建并设置观察矩阵
	D3DXVECTOR3 vEyePt( 0.0f, 0.0f, -2 );
	D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
	D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
	D3DXMATRIXA16 matView;
	D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
	g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

	//创建并设置投影矩阵
	D3DXMATRIXA16 matProj;
	D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/2, 1.0f, 0.1f, 100.0f );
	g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}


void SetLight()
{

}
bool SetFont()
{
	D3DXFONT_DESC df;
	ZeroMemory(&df, sizeof(D3DXFONT_DESC));
	df.Height         = 12;    // in logical units
	df.Width          = 12;    // in logical units 
	df.Weight         = 500;   // boldness, range 0(light) - 1000(bold)
	df.Italic         = false;      
	df.CharSet        = GB2312_CHARSET;
	df.OutputPrecision   = 0;                    
	df.Quality        = 0;           
	df.PitchAndFamily = 0;           
	wcscpy(df.FaceName, L"Times New Roman"); // font style

	if(FAILED(D3DXCreateFontIndirect(g_pd3dDevice, &df, &Font)))
	{
		::MessageBox(0, L"D3DXCreateFontIndirect() - FAILED", 0, 0);
		::PostQuitMessage(0);
	}
	return true;
}
//-----------------------------------------------------------------------------
// Desc: 初始化Direct3D
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
	if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
		return E_FAIL;

	D3DDISPLAYMODE d3ddm;

	if( FAILED( g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
	{
		// TO DO: Respond to failure of GetAdapterDisplayMode
		return E_FAIL;
	}

	HRESULT hr;

	if( FAILED( hr = g_pD3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, 
		d3ddm.Format, D3DUSAGE_DEPTHSTENCIL,
		D3DRTYPE_SURFACE, D3DFMT_D16 ) ) )
	{
		if( hr == D3DERR_NOTAVAILABLE )
			// POTENTIAL PROBLEM: We need at least a 16-bit z-buffer!
			return E_FAIL;
	}

	//
	// Do we support hardware vertex processing? if so, use it. 
	// If not, downgrade to software.
	//

	D3DCAPS9 d3dCaps;

	if( FAILED( g_pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT, 
		D3DDEVTYPE_HAL, &d3dCaps ) ) )
	{
		// TO DO: Respond to failure of GetDeviceCaps
		return E_FAIL;
	}

	//检查当前设备支持的顶点渲染版本是否低于2.0
	if( d3dCaps.VertexShaderVersion < D3DVS_VERSION(2,0) )
		AfxMessageBox(L"D3DDEVTYPE_REF");

	DWORD dwBehaviorFlags = 0;

	if( d3dCaps.VertexProcessingCaps != 0 )
		dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
	else
		dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;

	//
	// Everything checks out - create a simple, windowed device.
	//

	D3DPRESENT_PARAMETERS d3dpp;
	memset(&d3dpp, 0, sizeof(d3dpp));

	d3dpp.BackBufferFormat       = d3ddm.Format;
	d3dpp.SwapEffect             = D3DSWAPEFFECT_DISCARD;
	d3dpp.Windowed               = TRUE;
	d3dpp.EnableAutoDepthStencil = TRUE;
	d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
	d3dpp.PresentationInterval   = D3DPRESENT_INTERVAL_IMMEDIATE;

	if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
		dwBehaviorFlags, &d3dpp, &g_pd3dDevice ) ) )
	{
		// TO DO: Respond to failure of CreateDevice
		return E_FAIL;
	}

	//禁用照明效果
	g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); 

	//设置剔出模式为不剔出任何面
	g_pd3dDevice->SetRenderState(D3DRS_CULLMODE,  D3DCULL_NONE);

	//g_pd3dDevice->SetRenderState ( D3DRS_FILLMODE, D3DFILL_WIREFRAME );


	//编译顶点渲染器代码
	LPD3DXBUFFER pCode_VS;
	DWORD dwShaderFlags = D3DXSHADER_SKIPOPTIMIZATION|D3DXSHADER_DEBUG;
	D3DXCompileShaderFromFile( L"HLSLTransform.vsh", NULL, NULL, "VS",
		"vs_2_0", dwShaderFlags, &pCode_VS,
		NULL, &g_pConstantTable_VS);

	//创建顶点渲染器
	g_pd3dDevice->CreateVertexShader((DWORD*)pCode_VS->GetBufferPointer(),
		&g_pVertexShader );
	pCode_VS->Release();


	//设置变换矩阵
	SetupViewandProjMatrices();


	SetLight();
	SetFont();
	return S_OK;
}
//-----------------------------------------------------------------------------
// Desc: 释放创建对象
//-----------------------------------------------------------------------------
VOID Cleanup()
{

	if( g_pVertexShader != NULL )
		g_pVertexShader->Release();
	if( g_pConstantTable_VS != NULL )
		g_pConstantTable_VS->Release();


	//释放纹理对象
	if( g_pTexture != NULL )
		g_pTexture->Release();

	//释放顶点缓冲区对象
	if( g_pVB != NULL )        
		g_pVB->Release();

	//释放索引缓冲区对象
	if( g_pIB != NULL )        
		g_pIB->Release();

	//释放Direct3D设备对象
	if( g_pd3dDevice != NULL) 
		g_pd3dDevice->Release();

	//释放Direct3D对象
	if( g_pD3D != NULL)
		g_pD3D->Release();
}



//-----------------------------------------------------------------------------
// Desc: 渲染图形
//-----------------------------------------------------------------------------
VOID Render(float timeDelta)
{
	FrameCnt++;

	TimeElapsed += timeDelta;

	if(TimeElapsed >= 1.0f)
	{
		char FPSString[100];
		FPS = (float)FrameCnt / TimeElapsed;
		D3DCAPS9 d3dCaps;
		g_pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, &d3dCaps );
		if( d3dCaps.VertexProcessingCaps != 0 )
			sprintf(FPSString, "D3D9 %.2ffps HAL(hw vp)", FPS);
		else
			sprintf(FPSString, "D3D9 %.2ffps REF(simulate hw vp) ", FPS);

		int nLen = strlen(FPSString) + 1;  
		FPSString[nLen] = '\0'; // mark end of string
		int nwLen = MultiByteToWideChar(CP_ACP, 0, FPSString, nLen, NULL, 0);   
		MultiByteToWideChar(CP_ACP, 0, FPSString, nLen, TFPSString, nwLen); 
		TimeElapsed = 0.0f;
		FrameCnt    = 0;
	}
	//清空后台缓冲区
	g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(45, 50, 170), 1.0f, 0 );

	SetWorldMatrix();

	//开始在后台缓冲区绘制图形
	if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
	{
		RECT rect = {0, 0, 600, 500};
		Font->DrawText(0,TFPSString,-1,&rect,DT_TOP | DT_LEFT, 0xffffff00);

		
		
		g_pd3dDevice->SetVertexShader( g_pVertexShader );

		g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(Vertex));
		g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );
		g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
		g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 1 );

		g_pd3dDevice->EndScene();
	}
	//将在后台缓冲区绘制的图形提交到前台缓冲区显示
	g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}

//-----------------------------------------------------------------------------
// Desc: 消息处理
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	static POINT ptLastMousePosit;
	static POINT ptCurrentMousePosit;
	static bool bMousing;


	switch( msg )
	{
	case WM_KEYDOWN:
		switch(wParam)
		{
			case VK_F1:
				D3DSURFACE_DESC Desc;
				g_pTexture->GetLevelDesc(0, &Desc);
				D3DLOCKED_RECT lockedRect;
				if(SUCCEEDED(g_pTexture->LockRect(0, &lockedRect, NULL, 0 )))
				{
					unsigned char* imageData = (unsigned char*)lockedRect.pBits;   
					for(UINT i=0;i<Desc.Height;i++)
					{
						for (UINT j=0;j<Desc.Width;j++)
						{

							int index = i * lockedRect.Pitch + j;
							if(imageData[index]<10)
								imageData[index]=0;
							else
								imageData[index] = imageData[index]-10;
							

						}
					}
					g_pTexture-> UnlockRect(0); 
				}
				break;
		}
		break;
	case WM_LBUTTONDOWN:
		{
			ptLastMousePosit.x = ptCurrentMousePosit.x = LOWORD (lParam);
			ptLastMousePosit.y = ptCurrentMousePosit.y = HIWORD (lParam);
			bMousing = true;
		}
		break;

	case WM_LBUTTONUP:
		{
			bMousing = false;
		}
		break;
	
	case WM_MOUSEMOVE:
		{
			ptCurrentMousePosit.x = LOWORD (lParam);
			ptCurrentMousePosit.y = HIWORD (lParam);

			if( bMousing )
			{
				g_fSpinX -= (ptCurrentMousePosit.x - ptLastMousePosit.x);
				g_fSpinY -= (ptCurrentMousePosit.y - ptLastMousePosit.y);
			}

			ptLastMousePosit.x = ptCurrentMousePosit.x;
			ptLastMousePosit.y = ptCurrentMousePosit.y;
		}
		break;
	
	case WM_MOUSEWHEEL:
		{
			g_fDisZ +=(short)HIWORD (wParam)*0.00005;
		}
		break;
	case WM_DESTROY:
		Cleanup();
		PostQuitMessage( 0 );
		return 0;
	case WM_PAINT:
		Render(timeDelta);
		ValidateRect( hWnd, NULL );
		return 0;
	}

	return DefWindowProc( hWnd, msg, wParam, lParam );
}


//-----------------------------------------------------------------------------
// Desc: 程序入口
//-----------------------------------------------------------------------------
int APIENTRY _tWinMain(HINSTANCE hInstance,
					   HINSTANCE hPrevInstance,
					   LPTSTR    lpCmdLine,
					   int       nCmdShow)
{
	WNDCLASSEX winClass;
	MSG        uMsg;

	memset(&uMsg,0,sizeof(uMsg));

	winClass.lpszClassName = L"MY_WINDOWS_CLASS";
	winClass.cbSize        = sizeof(WNDCLASSEX);
	winClass.style         = CS_HREDRAW | CS_VREDRAW;
	winClass.lpfnWndProc   = MsgProc;
	winClass.hInstance     = hInstance;
	winClass.hIcon	       = LoadIcon(hInstance, (LPCTSTR)IDI_DIRECTX_ICON);
	winClass.hIconSm	   = LoadIcon(hInstance, (LPCTSTR)IDI_DIRECTX_ICON);
	winClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
	winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	winClass.lpszMenuName  = NULL;
	winClass.cbClsExtra    = 0;
	winClass.cbWndExtra    = 0;

	if( !RegisterClassEx(&winClass) )
		return E_FAIL;

	HWND hWnd = CreateWindowEx( NULL, L"MY_WINDOWS_CLASS", 
		L"Direct3D (DX9) - Initialization",
		WS_OVERLAPPEDWINDOW | WS_VISIBLE,
		CW_USEDEFAULT, CW_USEDEFAULT, 640, 460, NULL, NULL, hInstance, NULL );

	//初始化Direct3D
	if( SUCCEEDED( InitD3D( hWnd ) ) )
	{ 
		if( SUCCEEDED(InitGeometry(hWnd)))
		{
			//显示主窗口
			ShowWindow( hWnd, SW_SHOWDEFAULT );
			UpdateWindow( hWnd );

			static float lastTime = (float)timeGetTime(); 
			//进入消息循环
			MSG msg;
			ZeroMemory( &msg, sizeof(msg) );
			while( msg.message!=WM_QUIT )
			{
				if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
				{
					TranslateMessage( &msg );
					DispatchMessage( &msg );
				}
				else
				{
					float currTime  = (float)timeGetTime();
					float timeDelta = (currTime - lastTime)*0.001f;
					Render(timeDelta);  //渲染图形
					lastTime = currTime;
				}
			}
		}
	}

	UnregisterClass( L"ClassName", hInstance);
	return 0;
}


只实现了最简单的HLSL顶点渲染,实现了坐标变换。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值