键盘响应光照效果

(1) 绘制一个球体,通过键盘控制为场景添加不同的光照效果,具体为:按下’a’键,为场景添加方向光;按下’b’键,为场景添加点光源;按下’c’键,为场景添加点聚光灯。

1. d3dUtility.h
#include <d3dx9.h>
#include <string>

#ifndef __d3dUtilityH__
#define __d3dUtilityH__

//定义命名空间 namespace d3d { //绘制窗体 bool InitD3D( HINSTANCE hInstance, // [in] Application instance. //当前应用程序实例的句柄 int width, int height, // [in] Backbuffer dimensions. //窗口宽高 bool windowed, // [in] Windowed (true)or full screen (false). //窗体类型 D3DDEVTYPE deviceType, // [in] HAL or REF //设备的类型 IDirect3DDevice9** device);// [out]The created device. // 设备用接口, 每个 D3D 程序至少有一个设备 //消息循环 int EnterMsgLoop(bool (*ptr_display)(float timeDelta)); //回调函数 //处理窗口消息的函数 LRESULT CALLBACK WndProc(HWND hwnd,UINT msg, WPARAM wParam,LPARAM lParam); //窗口句柄、消息、消息类型 //释放   template<class T> void Release(T t) { if( t ) { t->Release(); t = 0; } } //删除   template<class T> void Delete(T t) { if( t ) { delete t; t = 0; } } const D3DXCOLOR WHITE( D3DCOLOR_XRGB(255, 255, 255) ); const D3DXCOLOR BLACK( D3DCOLOR_XRGB( 0, 0, 0) ); const D3DXCOLOR YELLOW( D3DCOLOR_XRGB(255, 255, 0) ); const D3DXCOLOR CYAN( D3DCOLOR_XRGB( 0, 255, 255) ); const D3DXCOLOR MAGENTA( D3DCOLOR_XRGB(255, 0, 255) ); const D3DXCOLOR RED( D3DCOLOR_XRGB(255, 0, 0) ); const D3DXCOLOR GREEN( D3DCOLOR_XRGB( 0, 255, 0) ); const D3DXCOLOR BLUE( D3DCOLOR_XRGB( 0, 0, 255) ); //D3DCOLOR_XRGB(r,g,b) - Alpha值为1,三个byte分别表示红,绿,蓝 //定义材质 D3DMATERIAL9 InitMtrl(D3DXCOLOR a /*环境光的颜色*/ , D3DXCOLOR d /*漫反射光的颜色*/, D3DXCOLOR s /*镜面光的颜色*/, D3DXCOLOR e /*增强物体的亮度*/, float p /*镜面高光点*/ ); //材质颜色 //白光 const D3DMATERIAL9 WHITE_MTRL = InitMtrl(WHITE, WHITE, WHITE, BLACK, 2.0f); //红光 const D3DMATERIAL9 RED_MTRL = InitMtrl(RED, RED, RED, BLACK, 2.0f); //绿光 const D3DMATERIAL9 GREEN_MTRL = InitMtrl(GREEN, GREEN, GREEN, BLACK, 2.0f); //蓝光 const D3DMATERIAL9 BLUE_MTRL = InitMtrl(BLUE, BLUE, BLUE, BLACK, 2.0f); //黄光 const D3DMATERIAL9 YELLOW_MTRL = InitMtrl(YELLOW, YELLOW, YELLOW, BLACK, 2.0f); //定义光源 //方向光 D3DLIGHT9 InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color); //点光源 D3DLIGHT9 InitPointLight(D3DXVECTOR3* position, D3DXCOLOR* color); //聚光灯 D3DLIGHT9 InitSpotLight(D3DXVECTOR3* position, D3DXVECTOR3* direction, D3DXCOLOR* color); #endif // __d3dUtilityH__
2. d3dUtility.cpp
//////////////////////////////////////////////////////////////////////////////////////////////////
// 
// File: d3dUtility.cpp
// 
// Author: Frank Luna (C) All Rights Reserved
//
// System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0 
//
// Desc: Provides utility functions for simplifying common tasks.
//          
//////////////////////////////////////////////////////////////////////////////////////////////////

#include "d3dUtility.h"


//初始化D3D
bool d3d::InitD3D(HINSTANCE hInstance,int width, int height,bool windowed,D3DDEVTYPE deviceType,IDirect3DDevice9** device)
                //当前应用程序实例的句柄、窗口宽高、窗台类型、设备类型、设备用接口
{
//************* 第一部分: 创建一个窗口开始 ***************
    //(1)创建程序主窗口
    // Create the main application window.
    //1. 设计一个窗口类
    WNDCLASS wc;

    wc.style         = CS_HREDRAW | CS_VREDRAW;
    //风格样式  当窗口的水平(hredraw)或垂直(vredraw)尺寸发生变化时,窗口将被重绘

    wc.lpfnWndProc   = (WNDPROC)d3d::WndProc; 
    //指定回调函数名(处理窗口产生的消息)的指针
    

    wc.cbClsExtra    = 0;
    //类额外内存
    wc.cbWndExtra    = 0;
    //窗口额外内存

    wc.hInstance     = hInstance;
    //当前应用程序实例的句柄,由 WinMain 传入

    wc.hIcon         = LoadIcon(0, IDI_APPLICATION);
    //图标
    wc.hCursor       = LoadCursor(0, IDC_ARROW);
    //光标

    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    //设置窗口背景色,调用函数GetStockObject设置,需要把返回值强制转换成HBRUSH类型

    wc.lpszMenuName  = 0;
    //菜单名,0 为无菜单


    wc.lpszClassName = L"1704210731_绘制图形";
    // 指向窗口名的指针




    //2. 注册窗口类
    //传入WNDCLASS类型的变量地址
    if( !RegisterClass(&wc) ) 
    {
        ::MessageBoxA(0, "注册窗口失败!", 0, 0);
        return false;
    }
    

    //3. 创建窗口
    HWND hwnd = 0;
    hwnd = ::CreateWindow( L"1704210731_绘制图形", L"1704210731_绘制图形", WS_EX_TOPMOST,0, 0, width, height,0 /*parent hwnd*/, 0 /* menu */, hInstance, 0 /*extra*/); 
    //和 wc.lpszClassName 相同、窗口的显示名称、指定这个窗口是顶部式窗口、表示窗口的横|纵坐标为默认值、表示窗口的宽|高为默认值、当前应用程序实例的句柄


    //窗口创建失败
    if( !hwnd )
    {
        ::MessageBoxA(0, "窗口创建失败!", 0, 0);
        return false;
    }


    //4. 窗口显示
    //传入CreateWindow返回的HWND类型参数
    ::ShowWindow(hwnd, SW_SHOW);
    //显示窗口,用窗口句柄hwnd来指定需要显示的窗口
    //因为还没有写窗口过程的回调函数,所以只能在后台运行


    //5. 窗口更新
    //传入CreateWindow返回的HWND类型参数
    ::UpdateWindow(hwnd);

//************* 第一部分: 创建一个窗口结束 ***************


//************* 第二部分: 初始化 D3D 开始 ***************
    //当显示了一个窗口后,需要继续创建一个Direct3D 9设备,这个设备用于绘制3D场景。
    //(2)初始化 D3D 设备
    // Init D3D: 
    //

    HRESULT hr = 0;
    //COM 要求所有的方法都会返回一个 HRESULT 类型的错误号
// Step 1: Create the IDirect3D9 object. //1. 获取IDirect3D9 接口 IDirect3D9* d3d9 = 0; //(1)创建IDirect3D9 接口,这个接口用于获得物理设备的信息和创建一个IDirect3DDevice接口 d3d9 = Direct3DCreate9(D3D_SDK_VERSION); //(1)在创建一个IDirect3D9 接口对象来显示设备时 //(3)应该先设置该设备接口对象的顶点处理类型(硬件顶点处理类型、软件顶点处理类型) //(2)在这之前需要判断显卡是否支持这个技术类型 //创建失败 if( !d3d9 ) { ::MessageBoxA(0, "创建IDirect3D9接口失败!", 0, 0); return false; } // Step 2: Check for hardware vp. //2. 检测显卡是否支持顶点转换和光照 //D3DCAPS9 保存了设备性能信息(包含顶点处理,纹理,shader等信息) D3DCAPS9 caps; //(2)判断显卡是否支持这个技术类型 //获取设备性能 d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps); //显卡、设备类型(HAL)通过硬件抽象层(HAL,Hardware Abstraction Layer)操作图形设备、返回一个已初始化的D3DCAPS9 结构 //硬件设备( D3DDEVTYPE_HAL ),软件设备(D3DDEVTYPE_REF) //将顶点运算类型用变量vp保存供以后使用 int vp = 0; //设备是否可以使用硬件顶点处理 if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) //硬件顶点处理 vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; else vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING; //软件顶点处理 // Step 3: Fill out the D3DPRESENT_PARAMETERS structure. //初始化一个D3DPRESENT_PARAMETERS结构实例,这个结构包含了许多数据成员允许我们制定将要创建的IDirect3DDevice9接口的特性。 D3DPRESENT_PARAMETERS d3dpp; d3dpp.BackBufferWidth = width; //后备缓冲宽640像素 d3dpp.BackBufferHeight = height; //后备缓冲高480像素 d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; //后备缓冲模式:32 位像素格式 d3dpp.BackBufferCount = 1; //后备缓冲表面的数量 d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; //全屏抗锯齿的类型 d3dpp.MultiSampleQuality = 0; //全屏抗锯齿的质量等级 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; //表面在交换链中是如何被交换的 d3dpp.hDeviceWindow = hwnd; //与设备相关的窗口句柄,在窗口绘制 d3dpp.Windowed = windowed; //窗口模式 d3dpp.EnableAutoDepthStencil = true; //自动创建深度|模版缓冲 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; //深度|模版缓冲的格式 深度值用24位二进制表示,模板8位 d3dpp.Flags = 0; //附加特性 d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; //刷新率 d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; //交换链中后台缓存切换到前台缓存的最大速率,立即交换 // Step 4: Create the device. //假如能支持硬件顶点处理,创建一个基于已经初始化好的D3DPRENSENT_PARAMENTS结构的IDirect3DDevice9对象 hr = d3d9->CreateDevice( D3DADAPTER_DEFAULT, // primary adapter //主显卡 deviceType, // device type //设备类型 hwnd, // window associated with device //窗口句柄 vp, // vertex processing //顶点处理方式 &d3dpp, // present parameters //指定一个已经初始化好的D3DPRESENT _PARAMETERS实例 device); // return created device //返回创建的设备 //创建失败 if( FAILED(hr) ) { // try again using a 16-bit depth buffer //将深度|模版缓冲的格式改为16位的深度缓冲 d3dpp.AutoDepthStencilFormat = D3DFMT_D16; //创建 hr = d3d9->CreateDevice( D3DADAPTER_DEFAULT, deviceType, hwnd, vp, &d3dpp, device); //16位的深度缓冲的对象创建失败 if( FAILED(hr) ) { d3d9->Release(); // done with d3d9 object //释放资源 ::MessageBoxA(0, "创建设备失败!", 0, 0); return false; } } d3d9->Release(); // done with d3d9 object return true; }
//消息循环 int d3d::EnterMsgLoop( bool (*ptr_display)(float timeDelta) ) { MSG msg; ::ZeroMemory(&msg, sizeof(MSG)); static float lastTime = (float)timeGetTime(); while(msg.message != WM_QUIT) { if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } else { float currTime = (float)timeGetTime(); float timeDelta = (currTime - lastTime)*0.001f; ptr_display(timeDelta); lastTime = currTime; } } return msg.wParam; } //3. (1)创建材质 //材质球 //d3dmaterial9 red; //red.diffuse = d3dxcolor(1.0f, 0.0f, 0.0f, 1.0f); // red //red.ambient = d3dxcolor(1.0f, 0.0f, 0.0f, 1.0f); // red //red.specular = d3dxcolor(1.0f, 0.0f, 0.0f, 1.0f); // red //red.emissive = d3dxcolor(0.0f, 0.0f, 0.0f, 1.0f); // no emission //red.power = 5.0f; ////指定当前材质 ////setmaterial(const d3dmaterial9 *pmaterial) //device->setmaterial(&red); //结构体 //typedef struct _D3DMATERIAL9{ // D3DXCOLOR Diffuse /*漫反射*/,Ambient/*环境光*/,Specular/*镜面光*/,Emissive/*增强物体的亮度*/; // float Power/*镜面高光点*/; //}D3DMATERIAL9; //声明函数 D3DMATERIAL9 d3d::InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p) { D3DMATERIAL9 mtrl; mtrl.Ambient = a; mtrl.Diffuse = d; mtrl.Specular = s; mtrl.Emissive = e; mtrl.Power = p; return mtrl; } //4. (1)创建光源 //光源结构体 //typedef struct _D3DLIGHT9 { //直射光 // D3DLIGHTTYPE Type; /*光源类型:点光源、方向光源、聚光灯*/ // //灯光类型,共3种:D3DLIGHT_POINT、D3DLIGHT_DIRECTIONAL(Directional)、D3DLIGHT_SPOT // // //材质光的颜色 // D3DCOLORVALUE Diffuse; /*光源发出的漫反射光颜色*/ // D3DCOLORVALUE Specular; /*镜面光的颜色*/ // D3DCOLORVALUE Ambient; /*环境光的颜色*/ // // D3DVECTOR Position; //位置(点光源没有方向有位置),用向量表示的光源世界坐标位置(对方向光无效) // D3DVECTOR Direction; //方向(方向光有方向没有位置没有角度),用向量表示的光源世界坐标照射方向(对点光源无效) // float Range; //角度,灯光能够传播的最大范围(对方向光无效) // float Falloff; //衰弱,灯光从内圆锥到外圆锥之间的强度衰减(仅对聚光灯有效),该值通常设为1.0f。 // // //灯光衰减变量,用来定义灯光强度的传播距离衰减(对方向光无效) // float Attenuation0; /*定义恒定衰减*/ // float Attenuation1; /*定义线性衰减*/ // float Attenuation2; /*定义二次衰减*/ // /*Attenuation0通常为 0.0f,Attenuation1通常为1.0f,Attenuation2通常为0.0f。*/ // // float Theta; /*指定灯光内圆锥的角度(仅对聚光灯有效),单位是弧度*/ // float Phi; /*指定外圆锥的角度(仅对聚光灯有效),单位是弧度*/ //} D3DLIGHT9; //(3)设置光源 //D3DLIGHT9 light; //::ZeroMemory(&light, sizeof(light)); //light.Type = D3DLIGHT_DIRECTIONAL; //light.Ambient = d3d::RED; //light.Diffuse = d3d::RED * 0.3f; //light.Specular = d3d::RED * 0.6f; ////方向光:下面到上面 //light.Direction = D3DXVECTOR3(0.0f,-1.0f,0.0f);s D3DLIGHT9 d3d::InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color) { D3DLIGHT9 light; ::ZeroMemory(&light, sizeof(light)); light.Type = D3DLIGHT_DIRECTIONAL; light.Ambient = *color * 0.6f; light.Diffuse = *color; light.Specular = *color * 0.6f; light.Direction = *direction; return light; } D3DLIGHT9 d3d::InitPointLight(D3DXVECTOR3* position, D3DXCOLOR* color) { D3DLIGHT9 light; ::ZeroMemory(&light, sizeof(light)); light.Type = D3DLIGHT_POINT; light.Ambient = *color * 0.6f; light.Diffuse = *color; light.Specular = *color * 0.6f; light.Position = *position; light.Range = 1000.0f; light.Falloff = 1.0f; light.Attenuation0 = 1.0f; light.Attenuation1 = 0.0f; light.Attenuation2 = 0.0f; return light; } D3DLIGHT9 d3d::InitSpotLight(D3DXVECTOR3* position, D3DXVECTOR3* direction, D3DXCOLOR* color) { D3DLIGHT9 light; ::ZeroMemory(&light, sizeof(light)); light.Type = D3DLIGHT_SPOT; light.Ambient = *color * 0.0f; light.Diffuse = *color; light.Specular = *color * 0.6f; light.Position = *position; light.Direction = *direction; light.Range = 1000.0f; light.Falloff = 1.0f; light.Attenuation0 = 1.0f; light.Attenuation1 = 0.0f; light.Attenuation2 = 0.0f; light.Theta = 0.4f; light.Phi = 0.9f; return light; }
 3. d3dinit.cpp

////////////////////////////////////////////////////////////////////////////////////////////////////

// File: d3dinit.cp

// Author: Frank Luna (C) All Rights Reserved
//
// System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0 
//
// Desc: Demonstrates how to initialize Direct3D, how to use the book's framework
//       functions, and how to clear the screen to black.  Note that the Direct3D
//       initialization code is in the d3dUtility.h/.cpp files.
//          
//////////////////////////////////////////////////////////////////////////////////////////////////

#include "d3dUtility.h"
// Globals

const int Width = 640; const int Height = 480;

//设备接口初始化 IDirect3DDevice9* Device = 0; //球体网格对象 ID3DXMesh* sphere; //材质对象 D3DMATERIAL9 mtrl;

//光照对象
D3DLIGHT9 light;
//光照颜色 
D3DXCOLOR c = d3d::YELLOW;

// Framework Functions //定义带法向量的顶点结构体 struct Vertex { Vertex(){} //构造函数(初始化) Vertex(float x, float y, float z, float nx, float ny, float nz) { //顶点信息 _x = x; _y = y; _z = z; //法向量的信息 _nx = nx; _ny = ny ; _nz = nz; } //成员变量 float _x, _y, _z; //成员变量(法线) float _nx, _ny, _nz; //静态成员(顶点结构) static const DWORD FVF; }; //顶点格式 //让顶点信息包含法向量D3DFVF_NORMAL的信息 const DWORD Vertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL; //设置 bool Setup() { //1. 创建球体对象 D3DXCreateSphere(Device,1.0f,20,20,&sphere,0); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //2. (1)材质颜色 mtrl = d3d:: WHITE_MTRL; // (2)设置材质 Device->SetMaterial(& mtrl); ////////////////////////////////////////////////////////////////////////// //3. 设置取景变换和投影变换、视口变换 //取景变换 D3DXVECTOR3 position(0.0f, 0.0f, -3.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); //投影变换 //观察坐标系 -> 投影坐标 //创建一个投影矩阵 D3DXMATRIX proj; D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI * 0.5f, float(640)/float(480),1.0f, 1000.0f); //获得的投影矩阵 、 y轴向上的视角(直角)、前裁剪面的高宽比 、最近的平面(前裁剪面距离) 、最远的平面(后裁剪面距离) Device->SetTransform(D3DTS_PROJECTION, &proj); //投影变换 //视口变换 D3DVIEWPORT9 vp={0,0,Width,Height,0,1}; //左上角为原点(0,0)、屏幕宽|高、最小|最大深度缓冲值 Device->SetViewport(&vp); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //4. 改变渲染状态 //开启规范化法向量 //使用了自定义的顶点格式中有使用法向量的需要开启 Device->SetRenderState(D3DRS_NORMALIZENORMALS, true); //开启光源 //要为每个顶点设定法线,只有设置了法线,灯光才会起作用 Device->SetRenderState(D3DRS_LIGHTING, true); //镜面光 Device->SetRenderState(D3DRS_SPECULARENABLE, false); //使用顶点颜色进行渲染,如果不禁用的话,将会看到一个黑色的多边形 //Device->SetRenderState(D3DRS_LIGHTING, FALSE); //因为使用顶点颜色渲染,所以要禁用光照处理 //线模式 //Device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); //允许渲染背面 //消隐模式,按照三角形单元的顶点绕序进行背面消隐 //关闭“挑选”功能,允许渲染背面 Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); return true; } //释放存储空间 void Cleanup() { d3d::Release<ID3DXMesh*>(sphere); } bool Display(float timeDelta) { if( Device ) // Only use Device methods if we have a valid device. { Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ffffff, 1.0f, 0); //绘制目标表面(后台缓存)|深度缓存 白色 深度缓存值为1.0 //对表面执行清除操作 //开始绘制 Device->BeginScene(); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //(6) 设置0号光 Device->SetLight(0,&light); //(7) 开启0号光 Device->LightEnable(0,true); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //5. 绘制子集 sphere->DrawSubset(0); //6. 旋转90度 /*D3DXMATRIX Rx; D3DXMatrixRotationX(&Rx, 3.14/2); Device->SetTransform(D3DTS_WORLD, &Rx);*/ //世界变换 D3DXMATRIX W; D3DXMatrixTranslation(&W,0.0f,-1.0f,0.0f); //Device->SetTransform(D3DTS_WORLD, &W); //旋转45度 D3DXMATRIX Rx; D3DXMatrixRotationX(&Rx,3.14/4); //Device->SetTransform(D3DTS_WORLD, &Rx); ////绕Y轴连续旋转 D3DXMATRIX Ry; static float y = 0.0f; D3DXMatrixRotationY(&Ry, y); //Device->SetTransform(D3DTS_WORLD, &Ry); y+=timeDelta; //超过一圈360度 if(y >= 6.28){ y = 0.0f; } ////实现变换 D3DXMATRIX P; P = W * Rx * Ry; Device->SetTransform(D3DTS_WORLD, &P); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //结束绘制 Device->EndScene(); // Swap the back and front buffers. Device->Present(0, 0, 0, 0); } return true; } // WndProc //回调函数 WnProc 的函数体 //处理窗口消息的函数 LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) //创建的窗口、接受的消息、w表示word,l表示long,对于32为系统来说,分别是无符号整数(unsigned int)和长整型(long),都是32位整数。 //WndProc的第三个参数类型被定义为WORD,表示一个16位的无符号短整型,而第四个参数被定义为LONG,表示一个32的位有符号长整型,“PARAM”前缀“W”和“L”正是由此而来。 //wParam&MK_SHIFT或MK_CTRL //wParam参数指明移动或者单击鼠标键的非客户区位置 { //参数 msg 的键值判断消息的类型 switch( msg ) { // 如果是关闭窗口的消息,则用 PostQuitMessage() 来退出消息循环 case WM_DESTROY: ::PostQuitMessage(0); break; //如果按下键盘任意一个键 case WM_KEYDOWN: // 如果是 ESC 键则关闭窗口 if( wParam == VK_ESCAPE ) ::DestroyWindow(hwnd);

//3. 控制光源类型
A或a键虚拟码:0x41

B或b键虚拟码:0x42

C或c键虚拟码:0x43
        if(wParam == 0x41)
        {
            D3DXVECTOR3 direction(1.0f,0.0f,0.0f);
            light = d3d::InitDirectionalLight(&direction, &c);
        }

        if(wParam == 0x42)
        {
            D3DXVECTOR3 position(0.0f,0.0f,-1.0f);
            light = d3d::InitPointLight(&position, &c);
        }

        if(wParam == 0x43)
        {
            D3DXVECTOR3 position(0.0f,0.0f,-1.0f);
            D3DXVECTOR3 direction(0.0f,0.0f,1.0f);
            light = d3d::InitSpotLight(&position, &direction,&c);
        }

        break;

    // 如果按下鼠标左键则弹出消息框,这里 WM_LBUTTONDOWN 是鼠标左键的键值
    case WM_LBUTTONDOWN:
        // L"Hello, World" 是消息框中显示的内容
        // L"Hello" 是所在父窗口的指针
        // MB_OK 表示消息框显示 “确定” 按钮
        ::MessageBox(0, L"Hello, World", L"Hello", MB_OK);
       break;
    }

    return ::DefWindowProc(hwnd, msg, wParam, lParam);
    //用 DefWindowProc 处理一些默认的消息,比如窗口的最大化、最小化、调整尺寸等
}


// WinMain
//入口(初始化、维护消息循环、窗口的注册、创建和显示)
int WINAPI WinMain(HINSTANCE hinstance,HINSTANCE prevInstance, PSTR cmdLine,int showCmd)
                //当前实例的句柄、不使用该参数,Win32 该参数始终为 NULL、用于运行程序的命令行参数字符串、指定窗口的显示方式
{
    // 调用窗口初始化函数,如果调用成功则进入消息循环,否则弹出一个对话框
    if(!d3d::InitD3D(hinstance,640, 480, true, D3DDEVTYPE_HAL, &Device))
        //当前应用程序实例的句柄、窗口宽640、高480、窗台类型(windowed)、设备类型(HAL)、设备用接口
    {
        ::MessageBoxA(0, "初始化失败!", 0, 0);
        return 0;
    }


    //顶点缓存创建失败
    if(!Setup())
    {
        ::MessageBoxA(0, "创建失败!", 0, 0);
        return 0;
    }

//进入消息循环 -- 函数名调用 d3d::EnterMsgLoop( Display ); Cleanup(); Device->Release(); return 0; }
A键按下:(方向光)(从左往右照射)
(从右往左)
if(wParam == 0x41) {   D3DXVECTOR3 direction(-1.0f,0.0f,0.0f);
  light = d3d::InitDirectionalLight(&direction, &c); }

 

A键按下:(方向光)(从前往后照射)
if(wParam == 0x41)
{   /*D3DXVECTOR3 direction(1.0f,0.0f,0.0f);*/    D3DXVECTOR3 direction(0.0f,0.0f,1.0f);    light = d3d::InitDirectionalLight(&direction, &c); }

A键按下:(方向光)(从后往前照射)
if(wParam == 0x41)
{
  /*D3DXVECTOR3 direction(1.0f,0.0f,0.0f);*/
   D3DXVECTOR3 direction(0.0f,0.0f,-1.0f);
   light = d3d::InitDirectionalLight(&direction, &c);
}

A键按下:(方向光)(从下往上照射)
if(wParam == 0x41) {   D3DXVECTOR3 direction(0.0f,1.0f,0.0f);   light = d3d::InitDirectionalLight(&direction, &c); }

A键按下:(方向光)(从上往下照射)
if(wParam == 0x41) {   D3DXVECTOR3 direction(0.0f,-1.0f,0.0f);   light = d3d::InitDirectionalLight(&direction, &c); }

光照未开启是黑色

按下B键(点光源:由一个点向四周发射)(点光源与物体在世界坐标原点重合、旋转90度)
if(wParam == 0x42) {   D3DXVECTOR3 position(0.0f,0.0f,-1.0f);   light = d3d::InitPointLight(&position, &c); }

按下C键(聚光灯)

if(wParam == 0x43)
{
    //左边
    D3DXVECTOR3 position(-1.0f,0.0f,0.0f);
    //从左往右
    D3DXVECTOR3 direction(1.0f,0.0f,0.0f); 
    light = d3d::InitSpotLight(&position, &direction,&c);
}    

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

const int Width  = 640;
const int Height = 480;
原文地址:https://www.cnblogs.com/sjslove/p/12775412.html