基于Direct3D11的光照模型展示

来源:互联网 发布:linux crm 编辑:程序博客网 时间:2024/04/30 19:59

环境:WIN7+VS2012+Direct3D11

//***************************************************************************************// CrateDemo.cpp by Frank Luna (C) 2011 All Rights Reserved.//// Demonstrates texturing a box.//// Controls://Hold the left mouse button down and move the mouse to rotate.//      Hold the right mouse button down to zoom in and out.////***************************************************************************************#include <iostream>#include "d3dApp.h"#include "d3dx11Effect.h"#include "GeometryGenerator.h"#include "MathHelper.h"#include "LightHelper.h"#include "Effects.h"#include "Vertex.h"#include "xnamath.h"class CrateApp : public D3DApp{public:CrateApp(HINSTANCE hInstance);~CrateApp();//初始化bool Init();void OnResize();void UpdateScene(float dt);//绘制场景void DrawScene(); //鼠标事件void OnMouseDown(WPARAM btnState, int x, int y);void OnMouseUp(WPARAM btnState, int x, int y);void OnMouseMove(WPARAM btnState, int x, int y);private:void BuildGeometryBuffers();private:ID3D11Buffer* mBoxVB;ID3D11Buffer* mBoxIB;ID3D11ShaderResourceView* mDiffuseMapSRV;//灯光DirectionalLight mDirLights[3];//材质Material mBoxMat[9];int num_Sphere;//画圆的个数XMFLOAT4X4 mTexTransform;//贴图变换矩阵XMFLOAT4X4 mBoxWorld[9];//立方体世界坐标XMMATRIX Move[9];XMFLOAT4X4 mView;//视点矩阵XMFLOAT4X4 mProj;int mBoxVertexOffset;UINT mBoxIndexOffset;UINT mBoxIndexCount;XMFLOAT3 mEyePosW;//摄像机位置float mTheta;float mPhi;float mRadius;float light_Ambient;float light_Diffuse;float light_Specular;POINT mLastMousePos;//鼠标的最后位置坐标};int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance,   PSTR cmdLine, int showCmd){// Enable run-time memory check for debug builds.#if defined(DEBUG) | defined(_DEBUG)_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );#endifCrateApp theApp(hInstance);if( !theApp.Init() )return 0;return theApp.Run();} CrateApp::CrateApp(HINSTANCE hInstance): D3DApp(hInstance), mBoxVB(0), mBoxIB(0), mDiffuseMapSRV(0), mEyePosW(0.0f, 0.0f, 0.0f),   mTheta(1.3f*MathHelper::Pi), mPhi(0.4f*MathHelper::Pi), mRadius(2.5f){mMainWndCaption = L"hp的创建模板";mLastMousePos.x = 0;mLastMousePos.y = 0;XMMATRIX I = XMMatrixIdentity();num_Sphere=9;//圆形的个数float pos_x[9]={ -1.5f ,  0.0f ,  1.5f , -1.5f ,  0.0f ,  1.5f , -1.5f ,  0.0f ,  1.5f ,};float pos_y[9]={  1.0f ,  1.0f ,  1.0f ,  0.0f ,  0.0f ,  0.0f , -1.0f , -1.0f , -1.0f ,};UINT i2;//临时变量,用于查看指定球的位置for(UINT i=0; i<9; ++i){i2 = i ;Move[i]=XMMatrixTranslation(pos_x[i2] , pos_y[i2] , 0.0f );        //几何体的平移变换,指定三个方向的平移量XMStoreFloat4x4(&mBoxWorld[i], Move[i]);}//XMStoreFloat4x4(&mBoxWorld[0], I);XMStoreFloat4x4(&mTexTransform, I);XMStoreFloat4x4(&mView, I);XMStoreFloat4x4(&mProj, I);light_Ambient=0.3f;light_Diffuse=0.8f;light_Specular=0.2f;//定义光源mDirLights[0].Ambient  = XMFLOAT4(light_Ambient, light_Ambient, light_Ambient, 1.0f);//默认0.3fmDirLights[0].Diffuse  = XMFLOAT4(light_Diffuse, light_Diffuse, light_Diffuse, 1.0f);//默认0.8fmDirLights[0].Specular = XMFLOAT4(light_Specular, light_Specular, light_Specular, 16.0f);//默认0.6fmDirLights[0].Direction = XMFLOAT3(0.707f, -0.707f, 0.0f); mDirLights[1].Ambient  = XMFLOAT4(0.2f, 0.2f, 0.2f, 1.0f);mDirLights[1].Diffuse  = XMFLOAT4(1.4f, 1.4f, 1.4f, 1.0f);mDirLights[1].Specular = XMFLOAT4(0.3f, 0.3f, 0.3f, 16.0f);mDirLights[1].Direction = XMFLOAT3(-0.707f, 0.0f, 0.707f);/*9种不同材质设置【0】 Lambert【1】 Phong【2】 Blinn-phong【3】 Torrance-Sparrow model【4】 Cook-Torrance model【5】 Ward's anisotropic model【6】 Oren-Nayar model*///                           0     1     2     3     4     5     6     7     8float mat_Ambient[9]  = { 0.5 , 0.5 , 0.5 , 0.5 , 0.5 , 0.5 , 0.5 , 0.5 , 0.5 };//环境float mat_Diffuse[9]  = { 0.2 , 0.3 , 0.4 , 0.5 , 0.6 , 0.7 , 0.8 , 0.9 , 1.0 };//漫反射float mat_Specular[9] = { 0.2 , 0.3 , 0.4 , 0.5 , 0.6 , 0.7 , 0.8 , 0.9 , 1.0 };//镜面//定义材质for(UINT i=0; i<num_Sphere; ++i){mBoxMat[i].Ambient  = XMFLOAT4(mat_Ambient[i], mat_Ambient[i], mat_Ambient[i], 1.0f);//环境mBoxMat[i].Diffuse  = XMFLOAT4(mat_Diffuse[i], mat_Diffuse[i], mat_Diffuse[i], 1.0f);//漫反射mBoxMat[i].Specular = XMFLOAT4(mat_Specular[i], mat_Specular[i], mat_Specular[i], 16.0f);//镜面}/*//定义材质mBoxMat.Ambient  = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);mBoxMat.Diffuse  = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);mBoxMat.Specular = XMFLOAT4(0.6f, 0.6f, 0.6f, 16.0f);*/}CrateApp::~CrateApp(){ReleaseCOM(mBoxVB);ReleaseCOM(mBoxIB);ReleaseCOM(mDiffuseMapSRV);Effects::DestroyAll();InputLayouts::DestroyAll();}bool CrateApp::Init()//初始化{if(!D3DApp::Init())return false;// Must init Effects first since InputLayouts depend on shader signatures.Effects::InitAll(md3dDevice);InputLayouts::InitAll(md3dDevice);//HR(D3DX11CreateShaderResourceViewFromFile(md3dDevice,L"Textures/WoodCrate01.dds", 0, 0, &mDiffuseMapSRV, 0 ));//贴图路径 HR(D3DX11CreateShaderResourceViewFromFile(md3dDevice,L"Textures/山东大学校徽.bmp", 0, 0, &mDiffuseMapSRV, 0 ));//贴图路径BuildGeometryBuffers();return true;}void CrateApp::OnResize()//重置尺寸,窗口大小变化时候调用{D3DApp::OnResize();XMMATRIX P = XMMatrixPerspectiveFovLH(0.25f*MathHelper::Pi, AspectRatio(), 1.0f, 1000.0f);XMStoreFloat4x4(&mProj, P);}void CrateApp::UpdateScene(float dt)//更新场景,每一帧调用,负责更新参数{// Convert Spherical to Cartesian coordinates./*float x = mRadius*sinf(mPhi)*cosf(mTheta);float z = mRadius*sinf(mPhi)*sinf(mTheta);float y = mRadius*cosf(mPhi);*/float x = 0.0f;float z = -4.0f;float y = 0.0f;mEyePosW = XMFLOAT3(x, y, z);//运动视角// Build the view matrix.XMVECTOR pos    = XMVectorSet(x, y, z, 1.0f);XMVECTOR target = XMVectorZero();XMVECTOR up     = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);XMMATRIX V = XMMatrixLookAtLH(pos, target, up);XMStoreFloat4x4(&mView, V);}void CrateApp::DrawScene()//绘制场景,每一帧调用,负责绘制{md3dImmediateContext->ClearRenderTargetView(mRenderTargetView, reinterpret_cast<const float*>(&Colors::LightSteelBlue));md3dImmediateContext->ClearDepthStencilView(mDepthStencilView, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 0);md3dImmediateContext->IASetInputLayout(InputLayouts::Basic32);    md3dImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); UINT stride = sizeof(Vertex::Basic32);    UINT offset = 0; XMMATRIX view  = XMLoadFloat4x4(&mView);XMMATRIX proj  = XMLoadFloat4x4(&mProj);XMMATRIX viewProj = view*proj;// Set per frame constants.Effects::BasicFX->SetDirLights(mDirLights);Effects::BasicFX->SetEyePosW(mEyePosW); ID3DX11EffectTechnique* activeTech = Effects::BasicFX->Light2TexTech;    D3DX11_TECHNIQUE_DESC techDesc;activeTech->GetDesc( &techDesc );    for(UINT p = 0; p < techDesc.Passes; ++p)    {md3dImmediateContext->IASetVertexBuffers(0, 1, &mBoxVB, &stride, &offset);md3dImmediateContext->IASetIndexBuffer(mBoxIB, DXGI_FORMAT_R32_UINT, 0);// Draw the box.画几何图形//画出num_Sphere个球体for(UINT i=0; i<num_Sphere; ++i){XMMATRIX world = XMLoadFloat4x4(&mBoxWorld[i]);XMMATRIX worldInvTranspose = MathHelper::InverseTranspose(world);XMMATRIX worldViewProj = world*view*proj;Effects::BasicFX->SetWorld(world);Effects::BasicFX->SetWorldInvTranspose(worldInvTranspose);Effects::BasicFX->SetWorldViewProj(worldViewProj);Effects::BasicFX->SetTexTransform(XMLoadFloat4x4(&mTexTransform));Effects::BasicFX->SetMaterial(mBoxMat[i]);//设置材质Effects::BasicFX->SetDiffuseMap(mDiffuseMapSRV);activeTech->GetPassByIndex(p)->Apply(0, md3dImmediateContext);md3dImmediateContext->DrawIndexed(mBoxIndexCount, mBoxIndexOffset, mBoxVertexOffset);}    }HR(mSwapChain->Present(0, 0));//贴图}void CrateApp::OnMouseDown(WPARAM btnState, int x, int y)//鼠标按下事件{mLastMousePos.x = x;mLastMousePos.y = y;SetCapture(mhMainWnd);}void CrateApp::OnMouseUp(WPARAM btnState, int x, int y)//鼠标抬起事件{ReleaseCapture();}void CrateApp::OnMouseMove(WPARAM btnState, int x, int y)//鼠标移动事件{if( (btnState & MK_LBUTTON) != 0 ){// Make each pixel correspond to a quarter of a degree.float dx = XMConvertToRadians(0.25f*static_cast<float>(x - mLastMousePos.x));float dy = XMConvertToRadians(0.25f*static_cast<float>(y - mLastMousePos.y));// Update angles based on input to orbit camera around box.mTheta += dx;mPhi   += dy;// Restrict the angle mPhi.mPhi = MathHelper::Clamp(mPhi, 0.1f, MathHelper::Pi-0.1f);}else if( (btnState & MK_RBUTTON) != 0 ){// Make each pixel correspond to 0.01 unit in the scene.float dx = 0.01f*static_cast<float>(x - mLastMousePos.x);float dy = 0.01f*static_cast<float>(y - mLastMousePos.y);// Update the camera radius based on input.mRadius += dx - dy;// Restrict the radius.mRadius = MathHelper::Clamp(mRadius, 1.0f, 15.0f);}mLastMousePos.x = x;mLastMousePos.y = y;}void CrateApp::BuildGeometryBuffers()//创建图元缓存{GeometryGenerator::MeshData box;GeometryGenerator geoGen;//geoGen.CreateBox(1.0f, 1.0f, 1.0f, box);//画盒子geoGen.CreateSphere(0.4f,40,40,box);//画圆,半径、上下极点间细分数、圆周细分数、网格信息// Cache the vertex offsets to each object in the concatenated vertex buffer.mBoxVertexOffset      = 0;// Cache the index count of each object.mBoxIndexCount      = box.Indices.size();// Cache the starting index for each object in the concatenated index buffer.mBoxIndexOffset      = 0;UINT totalVertexCount = box.Vertices.size();UINT totalIndexCount = mBoxIndexCount;//// Extract the vertex elements we are interested in and pack the// vertices of all the meshes into one vertex buffer.//std::vector<Vertex::Basic32> vertices(totalVertexCount);UINT k = 0;for(size_t i = 0; i < box.Vertices.size(); ++i, ++k){vertices[k].Pos    = box.Vertices[i].Position;vertices[k].Normal = box.Vertices[i].Normal;vertices[k].Tex    = box.Vertices[i].TexC;}    D3D11_BUFFER_DESC vbd;    vbd.Usage = D3D11_USAGE_IMMUTABLE;    vbd.ByteWidth = sizeof(Vertex::Basic32) * totalVertexCount;    vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;    vbd.CPUAccessFlags = 0;    vbd.MiscFlags = 0;    D3D11_SUBRESOURCE_DATA vinitData;    vinitData.pSysMem = &vertices[0];    HR(md3dDevice->CreateBuffer(&vbd, &vinitData, &mBoxVB));//// Pack the indices of all the meshes into one index buffer.//std::vector<UINT> indices;indices.insert(indices.end(), box.Indices.begin(), box.Indices.end());D3D11_BUFFER_DESC ibd;    ibd.Usage = D3D11_USAGE_IMMUTABLE;    ibd.ByteWidth = sizeof(UINT) * totalIndexCount;    ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;    ibd.CPUAccessFlags = 0;    ibd.MiscFlags = 0;    D3D11_SUBRESOURCE_DATA iinitData;    iinitData.pSysMem = &indices[0];    HR(md3dDevice->CreateBuffer(&ibd, &iinitData, &mBoxIB));} 



0 0