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.注意事项。

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

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

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

时间: 2024-08-30 05:24:22

D3D 光照和材料 小样例的相关文章

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 { D3DXV

SpringMVC+Spring+Hibernate的小样例

Strusts2+Spring+Hibernate尽管是主流的WEB开发框架,可是SpringMVC有越来越多的人使用了.确实也很好用.用得爽! 这里实现了一个SpringMVC+Spring+Hibernate的小样例.凝视都在代码里面. 项目各包的结构例如以下图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcWlhbnR1amF2YQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve

C Tips:显示点阵汉字的小样例

非常简陋的一段小程序,演示怎样显示点阵字库.有时间的时候再详解. #include <stdio.h> #include <stdlib.h> struct HzkInfoStruct { int HzkSelect; int HzkSquare; char * fileName; FILE * file; int martixBytesCount; unsigned char *pMatrix; }; typedef struct HzkInfoStruct HzkInfo; v

OpenGL中的光照与材料

在OpenGL光照模型中,除非一个物体自己会发光,否则它将受到3种不同类型的光的照射,这3种不同类型的光分别是:环境光(ambient).散射光(diffuse)和镜面光(specular).作为现实世界中光照的抽象,这3种类型的光允许我们模拟和控制光照在物体表面上所产生的效果. 环境光(ambient) 环境光并不来自任何特定的方向.由环境光所照射的物体在所有方向的表面都是均匀照亮的.在OpenGL中,这种光照类型实际上模拟了环境中源自所有光源的散光. 散射光(diffuse) OpenGL中

D3D 线列 小样例

画两条线 #pragma once #pragma comment(lib,"d3d9.lib") #pragma comment(lib,"d3dx9.lib") #include<d3d9.h> #include<d3dx9.h> //TODO: -1 custom vertex struct CUSTOMVERTEX { float x; float y; float z; float rhw; }; #define D3DFVF_CU

简单的ADO.NET连接数据小样例

ADO.NET连接数据库的样例如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Data.SqlClient; using System.Confi

用两个小样例来解释单例模式中的“双重锁定”

学习单例模式时,好多人都不太理解双重锁定. 学完后突然想到一个非常有趣的样例. 单例模式结构图: 代码: Singleton类 class Singleton { private static Singleton instance; private static readonly object syncRoot = new object(); //程序执行时创建一个静态仅仅读的进程辅助对象 private Singleton() { } //用private修饰构造方法,防止外界利用new创建此

android:json解析的两个工具:Gson和Jackson的使用小样例

1.简单介绍 json是android与server通信过程中经常使用的数据格式,比如.例如以下是一个json格式的字符串: {"address":"Nanjing","name":"NUPT","students":[{"name":"stu1","id":"10000","age":20},{"

时间戳转化为时间小样例

        NSString *[email protected]"1439965800";//时间戳         /*因为时间差问题所以要加8个小时==28800sec*/         NSTimeInterval time=[str doubleValue]+28800;         NSDate *detailDate=[NSDate dateWithTimeIntervalSince1970:time];         NSLog(@"detailD