zoukankan      html  css  js  c++  java
  • 顶点着色器例子——Diffuse Lighting(《龙书》)

    #include "d3dUtility.h"
    
    //
    // Globals
    //
    
    IDirect3DDevice9* Device = 0; 
    
    const int Width  = 640;
    const int Height = 480;
    
    IDirect3DVertexShader9* DiffuseShader = 0;			//顶点着色器
    ID3DXConstantTable* DiffuseConstTable = 0;			//shader的常量表
    
    ID3DXMesh* Teapot            = 0;
    
    //常量表中shader变量句柄,用于设置shader中对应变量的值
    D3DXHANDLE ViewMatrixHandle     = 0;
    D3DXHANDLE ViewProjMatrixHandle = 0;
    D3DXHANDLE AmbientMtrlHandle    = 0;
    D3DXHANDLE DiffuseMtrlHandle    = 0;
    D3DXHANDLE LightDirHandle       = 0;
    
    D3DXMATRIX Proj;
    
    //
    // Framework functions
    //
    bool Setup()
    {
    	HRESULT hr = 0;
    
    	//
    	// Create geometry:
    	//
    
    	D3DXCreateTeapot(Device, &Teapot, 0);
    
    	//
    	// 编译着色器
    	//
    
    	ID3DXBuffer* shader      = 0;
    	ID3DXBuffer* errorBuffer = 0;
    
    	hr = D3DXCompileShaderFromFile(
    		"diffuse.txt",//shader文件名
    		0,
    		0,
    		"Main", // entry point function name
    		"vs_1_1",
    		D3DXSHADER_DEBUG | D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY, 
    		&shader,//编译后的着色器代码
    		&errorBuffer,//存储错误代码
    		&DiffuseConstTable);//获取常量表
    
    	// output any error messages
    	if( errorBuffer )
    	{
    		::MessageBox(0, (char*)errorBuffer->GetBufferPointer(), 0, 0);
    		d3d::Release<ID3DXBuffer*>(errorBuffer);
    	}
    
    	if(FAILED(hr))
    	{
    		::MessageBox(0, "D3DXCompileShaderFromFile() - FAILED", 0, 0);
    		return false;
    	}
    
    	//
    	// 创建着色器
    	//
    
    	hr = Device->CreateVertexShader(
    		(DWORD*)shader->GetBufferPointer(),//前面得到的编译后的着色器代码
    		&DiffuseShader);//创建的着色器
    
    	if(FAILED(hr))
    	{
    		::MessageBox(0, "CreateVertexShader - FAILED", 0, 0);
    		return false;
    	}
    
    	d3d::Release<ID3DXBuffer*>(shader);
    
    
    	// 
    	// Get Handles,根据shader变量名获取句柄(关联变量,以便于外部设置shader变量的值)
    	//
    
    	ViewMatrixHandle    = DiffuseConstTable->GetConstantByName(0, "ViewMatrix");
    	ViewProjMatrixHandle= DiffuseConstTable->GetConstantByName(0, "ViewProjMatrix");
    	AmbientMtrlHandle   = DiffuseConstTable->GetConstantByName(0, "AmbientMtrl");
    	DiffuseMtrlHandle   = DiffuseConstTable->GetConstantByName(0, "DiffuseMtrl");
    	LightDirHandle      = DiffuseConstTable->GetConstantByName(0, "LightDirection");
    
    	//
    	// Set shader constants:(设置shader变量的值,有些shader变量需要在C++代码中初始化,即外部初始化)
    	//
    
    	// Light direction:
    	D3DXVECTOR4 directionToLight(-0.57f, 0.57f, -0.57f, 0.0f);
    	DiffuseConstTable->SetVector(Device, LightDirHandle, &directionToLight);
    
    	// Materials:
    	D3DXVECTOR4 ambientMtrl(0.0f, 0.0f, 1.0f, 1.0f);
    	D3DXVECTOR4 diffuseMtrl(0.0f, 0.0f, 1.0f, 1.0f);
    
    	DiffuseConstTable->SetVector(Device,AmbientMtrlHandle,&ambientMtrl);
    	DiffuseConstTable->SetVector(Device,DiffuseMtrlHandle,&diffuseMtrl);
    	DiffuseConstTable->SetDefaults(Device);				//此方法在应用程序的设置用应调用一次,设置常量的默认值
    
    	// Compute projection matrix.计算投影矩阵
    	D3DXMatrixPerspectiveFovLH(
    		&Proj,	D3DX_PI * 0.25f, 
    		(float)Width / (float)Height, 1.0f, 1000.0f);
    	//固定管线:Device->SetTransform(D3DTS_PROJECTION, &Proj);
    
    
    	return true;
    }
    
    void Cleanup()
    {
    	d3d::Release<ID3DXMesh*>(Teapot);
    	d3d::Release<IDirect3DVertexShader9*>(DiffuseShader);
    	d3d::Release<ID3DXConstantTable*>(DiffuseConstTable);
    }
    
    bool Display(float timeDelta)
    {
    	if( Device )
    	{
    		// 
    		// Update the scene: Allow user to rotate around scene.
    		//
    		
    		static float angle  = (3.0f * D3DX_PI) / 2.0f;
    		static float height = 3.0f;
    	
    		if( ::GetAsyncKeyState(VK_LEFT) & 0x8000f )
    			angle -= 0.5f * timeDelta;
    
    		if( ::GetAsyncKeyState(VK_RIGHT) & 0x8000f )
    			angle += 0.5f * timeDelta;
    
    		if( ::GetAsyncKeyState(VK_UP) & 0x8000f )
    			height += 5.0f * timeDelta;
    
    		if( ::GetAsyncKeyState(VK_DOWN) & 0x8000f )
    			height -= 5.0f * timeDelta;
    
    		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 V;
    		D3DXMatrixLookAtLH(&V, &position, &target, &up);
    		//固定管线:Device->SetTransform(D3DTS_VIEW, &V);//设置照相机的位置
    
    		DiffuseConstTable->SetMatrix(Device, ViewMatrixHandle, &V);
    
    		D3DXMATRIX ViewProj = V * Proj;
    		DiffuseConstTable->SetMatrix(Device, ViewProjMatrixHandle, &ViewProj);
    
    		//
    		// Render
    		//
    
    		Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
    		Device->BeginScene();
    
    		//启用定点着色器
    		//Device->SetVertexShader(DiffuseShader);
    
    		Teapot->DrawSubset(0);
    		
    		Device->EndScene();
    		Device->Present(0, 0, 0, 0);
    	}
    	return true;
    }
    
    //
    // WndProc
    //
    LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	switch( msg )
    	{
    	case WM_DESTROY:
    		::PostQuitMessage(0);
    		break;
    		
    	case WM_KEYDOWN:
    		if( wParam == VK_ESCAPE )
    			::DestroyWindow(hwnd);
    
    		break;
    	}
    	return ::DefWindowProc(hwnd, msg, wParam, lParam);
    }
    
    //
    // WinMain
    //
    int WINAPI WinMain(HINSTANCE hinstance,
    				   HINSTANCE prevInstance, 
    				   PSTR cmdLine,
    				   int showCmd)
    {
    	if(!d3d::InitD3D(hinstance,
    		Width, Height, true, D3DDEVTYPE_HAL, &Device))
    	{
    		::MessageBox(0, "InitD3D() - FAILED", 0, 0);
    		return 0;
    	}
    		
    	if(!Setup())
    	{
    		::MessageBox(0, "Setup() - FAILED", 0, 0);
    		return 0;
    	}
    
    	d3d::EnterMsgLoop( Display );
    
    	Cleanup();
    
    	Device->Release();
    
    	return 0;
    }
    
    
    

    // File: diffuse.txt
    matrix ViewMatrix;

    matrix ViewProjMatrix;

    vector AmbientMtrl;

    vector DiffuseMtrl

    vector LightDirection;

    vector DiffuseLightIntensity = {0.0f, 0.0f, 1.0f, 1.0f};

    vector AmbientLightIntensity = {0.0f, 0.0f, 0.2f, 1.0f};

    struct VS_INPUT

    {   

       vector position : POSITION;   

       vector normal   : NORMAL;

    };
    struct VS_OUTPUT

    {    

      vector position : POSITION;  

      vector diffuse  : COLOR;

    };


    VS_OUTPUT Main(VS_INPUT input)

    {   

       VS_OUTPUT output = (VS_OUTPUT)0;

      // Transform position to homogeneous clip space(齐次裁剪空间)   

      // and store in the output.position member.     

      output.position = mul(input.position, ViewProjMatrix);


      // Transform lights and normals to view space(视口空间).  Set w    

      // componentes to zero since we're transforming vectors     

      // here and not points.        

      LightDirection.w = 0.0f;   

      input.normal.w   = 0.0f;    

      LightDirection   = mul(LightDirection, ViewMatrix);    

      input.normal     = mul(input.normal,   ViewMatrix);

      // Compute cosine of the angle between light and normal.     

      float s = dot(LightDirection, input.normal);

      if( s < 0.0f )        

        s = 0.0f;

      
        output.diffuse = (AmbientMtrl * AmbientLightIntensity) + (s * (DiffuseLightIntensity * DiffuseMtrl)); 

      return output;

    }

  • 相关阅读:
    [Azure][PowerShell][ASM][03]Cloud Service
    linux ssh连接自动断开问题
    NTP服务器实现
    xshell使用小技巧
    elasticsearch集群部署
    redis集群部署
    积分排名查看
    linux centos7.2系统升级python后yum不能使用的问题
    Python生成器generator之next和send运行流程
    python文件操作
  • 原文地址:https://www.cnblogs.com/sifenkesi/p/1949652.html
Copyright © 2011-2022 走看看