• D3D 光照和材料 小样例


    1.实现一个旋转的圆柱体,体现d3d光照效果

    2.程序实现

    #pragma once
    
    #pragma comment(lib,"winmm.lib")
    
    #pragma comment(lib,"d3d9.lib")
    #pragma comment(lib,"d3dx9.lib")
    
    #include<d3d9.h>
    #include<d3dx9.h>
    
    //自己定义顶点格式
    struct CUSTOMVERTEX
    {
    	D3DXVECTOR3 postion;
    	D3DXVECTOR3 normal;
    };
    
    //坐标和法向量。
    #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL)
    
    //函数声明
    LRESULT CALLBACK MsgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
    void Render();
    HRESULT InitD3D(HWND hWnd);
    HRESULT InitGeometry();
    void CleanUp();
    void SetupMatrices();
    void SetupLights();
    
    //全局变量
    LPDIRECT3D9 g_pd3d=NULL;
    LPDIRECT3DDEVICE9 g_pd3dDevice=NULL;
    LPDIRECT3DVERTEXBUFFER9 g_d3dVertexBuffer=NULL;
    
    //主函数入口。
    INT WINAPI wWinMain(HINSTANCE,HINSTANCE,LPWSTR,INT)
    {
    	//注冊窗体类。
    	WNDCLASSEX wcex;
    	ZeroMemory(&wcex,sizeof(wcex));
    	wcex.cbSize=sizeof(wcex);
    	wcex.hInstance=GetModuleHandle(NULL);
    	wcex.lpfnWndProc=MsgProc;
    	wcex.lpszClassName=L"Self001";
    	wcex.style=CS_CLASSDC;
    
    	RegisterClassEx(&wcex);
    
    	//创建窗体。
    	HWND hWnd=CreateWindowEx(
    		WS_EX_OVERLAPPEDWINDOW,
    		L"Self001",
    		L"Self001 Window",
    		WS_OVERLAPPEDWINDOW,
    		100,
    		100,
    		300,
    		300,
    		NULL,
    		NULL,
    		wcex.hInstance,
    		NULL);
    	
    	//显示窗体。
    	ShowWindow(hWnd,SW_SHOWDEFAULT);
    	UpdateWindow(hWnd);
    
    	//初始化d3d对象。
    	if(SUCCEEDED(InitD3D(hWnd)))
    	{
    		if(SUCCEEDED(InitGeometry()))
    		{
    			//消息循环。
    			MSG msg;
    			ZeroMemory(&msg,sizeof(msg));
    			while(msg.message != WM_QUIT)
    			{
    				if(PeekMessage(&msg,hWnd,0,0,PM_REMOVE))
    				{
    					TranslateMessage(&msg);
    					DispatchMessage(&msg);
    				}
    				else
    				{
    					Render();
    				}
    			}
    		}
    	}
    
    	//注销窗体类。
    	UnregisterClass(L"Self001",wcex.hInstance);
    
    	return 0;
    }
    
    //窗体回调函数。
    LRESULT CALLBACK 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 Render()
    {
    	//清除目标。
    	g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,255),1.0f,0);
    
    	if(SUCCEEDED(g_pd3dDevice->BeginScene()))
    	{
    		SetupLights();
    		SetupMatrices();
    
    		g_pd3dDevice->SetStreamSource(0,g_d3dVertexBuffer,0,sizeof(CUSTOMVERTEX));
    		g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
    		//绘制图元
    		g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2*50-2);
    
    		g_pd3dDevice->EndScene();
    	}
    
    	g_pd3dDevice->Present(NULL,NULL,NULL,NULL);
    }
    
    //初始化d3d对象
    HRESULT InitD3D(HWND hWnd)
    {
    	//创建d3d
    	g_pd3d=Direct3DCreate9(D3D_SDK_VERSION);
    	if(g_pd3d == NULL)
    	{
    		return E_FAIL;
    	}
    
    	//初始化d3d呈现參数。
    	D3DPRESENT_PARAMETERS d3dpp;
    	ZeroMemory(&d3dpp,sizeof(d3dpp));
    	d3dpp.Windowed=TRUE;
    	d3dpp.hDeviceWindow=hWnd;
    	d3dpp.BackBufferFormat=D3DFMT_UNKNOWN;
    	d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
    	d3dpp.EnableAutoDepthStencil=TRUE;
    	d3dpp.AutoDepthStencilFormat=D3DFMT_D16;
    
    	//创建设备。
    	if(FAILED(g_pd3d->CreateDevice(
    		D3DADAPTER_DEFAULT,
    		D3DDEVTYPE_HAL,
    		hWnd,
    		D3DCREATE_SOFTWARE_VERTEXPROCESSING,
    		&d3dpp,
    		&g_pd3dDevice)))
    	{
    		return E_FAIL;
    	}
    
    	//设置背面剔除和z 缓冲
    	g_pd3dDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);
    	g_pd3dDevice->SetRenderState(D3DRS_ZENABLE,TRUE);
    
    	return S_OK;
    }
    
    //清除d3d对象。
    void CleanUp()
    {
    	//顶点缓冲。
    	if(g_d3dVertexBuffer != NULL)
    	{
    		g_d3dVertexBuffer->Release();
    	}
    
    	//设备。
    	if(g_pd3dDevice != NULL)
    	{
    		g_pd3dDevice->Release();
    	}
    
    	//d3d。
    	if(g_pd3d != NULL)
    	{
    		g_pd3d->Release();
    	}
    }
    
    //设置变换矩阵。
    void SetupMatrices()
    {
    	//世界变换矩阵。
    	D3DXMATRIXA16 matWorld;
    	D3DXMatrixIdentity(&matWorld);
    	D3DXMatrixRotationX(&matWorld,timeGetTime()/500.0f);
    	g_pd3dDevice->SetTransform(D3DTS_WORLD,&matWorld);
    
    	//视野变换矩阵。
    	D3DXMATRIXA16 matView;
    	D3DXVECTOR3 vEye(0.0f,3.0f,-5.0f);
    	D3DXVECTOR3 vLookAt(0.0f,0.0f,0.0f);
    	D3DXVECTOR3 vUp(0.0f,1.0f,0.0f);
    	D3DXMatrixLookAtLH(&matView,&vEye,&vLookAt,&vUp);
    	g_pd3dDevice->SetTransform(D3DTS_VIEW,&matView);
    
    	//投影变换矩阵。
    	D3DXMATRIXA16 matProj;
    	D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,1.0f,1.0f,100.0f);
    	g_pd3dDevice->SetTransform(D3DTS_PROJECTION,&matProj);
    }
    
    //初始化几何图元。
    HRESULT InitGeometry()
    {
    	//创建顶点缓冲。
    	if(FAILED(g_pd3dDevice->CreateVertexBuffer(
    		sizeof(CUSTOMVERTEX)*2*50,
    		0,
    		D3DFVF_CUSTOMVERTEX,
    		D3DPOOL_DEFAULT,
    		&g_d3dVertexBuffer,
    		NULL)))
    	{
    		return E_FAIL;
    	}
    
    	//坐标设定。
    	CUSTOMVERTEX* pVertices=NULL;
    	if(FAILED(g_d3dVertexBuffer->Lock(0,0,(void**)&pVertices,0)))
    	{
    		return E_FAIL;
    	}
    
    	for(DWORD i=0;i<50;i++)
    	{
    		FLOAT theta=(2*D3DX_PI*i)/(50-1);
    		pVertices[2*i+0].postion=D3DXVECTOR3(cosf(theta),-1,sinf(theta));
    		pVertices[2*i+0].normal=D3DXVECTOR3(cosf(theta),0,sinf(theta));
    		pVertices[2*i+1].postion=D3DXVECTOR3(cosf(theta),1,sinf(theta));
    		pVertices[2*i+1].normal=D3DXVECTOR3(cosf(theta),0,sinf(theta));
    	}
    
    	g_d3dVertexBuffer->Unlock();
    
    	return S_OK;
    }
    
    //设置材料和光照。
    void SetupLights()
    {
    	//材料
    	D3DMATERIAL9 mtrl;
    	ZeroMemory(&mtrl,sizeof(mtrl));
    	mtrl.Ambient.r=mtrl.Diffuse.r=1.0f;
    	mtrl.Ambient.g=mtrl.Diffuse.g=1.0f;
    	mtrl.Ambient.b=mtrl.Diffuse.b=0.0f;
    	mtrl.Ambient.a=mtrl.Diffuse.a=1.0f;
    	g_pd3dDevice->SetMaterial(&mtrl);
    
    	//光照
    	D3DLIGHT9 light;
    	ZeroMemory(&light,sizeof(light));
    	light.Type=D3DLIGHT_DIRECTIONAL;
    	light.Diffuse.r=1.0f;
    	light.Diffuse.g=1.0f;
    	light.Diffuse.b=1.0f;
    	D3DXVECTOR3 normVec=D3DXVECTOR3(0.0f,0.0f,1.0f);
    	D3DXVec3Normalize((D3DXVECTOR3*)&light.Direction,&normVec);
    	light.Range=1000.0f;
    
    	//环境
    	g_pd3dDevice->SetLight(0,&light);
    	g_pd3dDevice->LightEnable(0,TRUE);
    	g_pd3dDevice->SetRenderState(D3DRS_LIGHTING,TRUE);
    	g_pd3dDevice->SetRenderState(D3DRS_AMBIENT,D3DCOLOR_XRGB(10,0,0));
    }
    

    3.程序执行结果

    4.注意事项。

       理解材料是什么东西,尤其材料的漫射光和环境光。

       理解光照是什么东西,尤其设置參数。

       练习多了,慢慢的就熟悉了。

  • 相关阅读:
    HBase 使用与原理总结
    Java8 的一些使用总结
    对Redis的一些理解
    BERT模型源码解析 -- 转载
    BERT原理解析 -- 转载
    SQL 多表查询之 where和INNER JOIN
    Spark 数据处理相关代码
    Sql实战 1.单表复用进行比较排名
    LeetCode 47.括号生成 DFS递归
    LeetCode 46.机器人的运动范围
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4506331.html
Copyright © 2020-2023  润新知