来自龙书上的例程,自己在写的时候发现一点小问题,改了一点代码文件,不多说,看代码。
//source.cpp
#include"header.h"
#include<time.h>
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPWSTR cmdLine, int cmdShow)
{
InitD3d(hInstance, cmdShow);
Setup(800, 600);
MSG msg = {0};
float cur, pre;
pre = (float)timeGetTime();
while (msg.message!=WM_QUIT)
{
if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
cur = (float)timeGetTime();
Display(cur-pre);
}
return 0;
}
//header.h
#pragma once
#include<d3d9.h>
#include<d3dx9.h>
#include<windows.h>
struct Vertex
{
float x, y, z;
float nx, ny, nz;
float u, v;
Vertex(float a, float b, float c, float na, float nb, float nc, float d, float e) :x(a), y(b),
z(c), nx(na), ny(nb), nz(nc), u(d), v(e){};
};
const D3DXCOLOR RED = D3DCOLOR_XRGB(255, 0, 0);
const D3DXCOLOR WHITE = D3DCOLOR_XRGB(255, 255, 255);
const D3DXCOLOR BLACK = D3DCOLOR_XRGB(0, 0, 0);
const WORD FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;
IDirect3D9 *pd3d;
IDirect3DDevice9 *pd3dDevice;
IDirect3DVertexBuffer9 *vb;
D3DCAPS9 caps;
ID3DXMesh *teapotMesh;
IDirect3DTexture9 *bkTexture;
D3DMATERIAL9 bkMtrl;
D3DMATERIAL9 teapotMtrl;
int iUseProcess;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
D3DMATERIAL9 InitMtrl(D3DXCOLOR ambient, D3DXCOLOR diffuse, D3DXCOLOR specular, D3DXCOLOR emissive, float power);
D3DLIGHT9 InitDirLight(D3DXCOLOR ambient, D3DXCOLOR diffuse, D3DXCOLOR specular, D3DXVECTOR3 d);
bool InitD3d(HINSTANCE hInstance, int cmdShow)
{
WNDCLASS wc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = L"blend";
wc.lpszMenuName = NULL;
wc.style = CS_VREDRAW | CS_HREDRAW;
RegisterClass(&wc);
HWND hWnd = CreateWindow(L"blend", L"", WS_POPUP, 500, 200, 800, 600, NULL, NULL, hInstance, NULL);
ShowWindow(hWnd, cmdShow);
UpdateWindow(hWnd);
pd3d = Direct3DCreate9(D3D_SDK_VERSION);
pd3d->GetDeviceCaps(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,&caps);
if (caps.DevCaps&D3DDEVCAPS_HWTRANSFORMANDLIGHT)
iUseProcess = D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
iUseProcess = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
D3DPRESENT_PARAMETERS d3dpp;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
d3dpp.BackBufferCount = 1;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
d3dpp.BackBufferHeight = 600;
d3dpp.BackBufferWidth = 800;
d3dpp.EnableAutoDepthStencil = true;
d3dpp.Flags = 0;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.hDeviceWindow = hWnd;
d3dpp.MultiSampleQuality = 0;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.Windowed = true;
pd3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, iUseProcess, &d3dpp, &pd3dDevice);
return true;
}
void Rel()
{
vb->Release();
pd3dDevice->Release();
pd3d->Release();
}
void Setup(float width,float height)
{
pd3dDevice->CreateVertexBuffer(sizeof(Vertex) * 6, D3DUSAGE_WRITEONLY, FVF, D3DPOOL_MANAGED, &vb, NULL);
Vertex *v;
vb->Lock(0, 0, (void**)&v, NULL);
v[0] = Vertex(-10.0f, -10.0f, 5.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
v[1] = Vertex(-10.0f, 10.0f, 5.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);
v[2] = Vertex(10.0f, 10.0f, 5.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);
v[3] = Vertex(-10.0f, -10.0f, 5.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
v[4] = Vertex(10.0f, 10.0f, 5.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);
v[5] = Vertex(10.0f, -10.0f, 5.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f);
vb->Unlock();
if (FAILED(D3DXCreateTeapot(pd3dDevice, &teapotMesh, 0)))
MessageBox(NULL, L"dd", 0, 0);
bkMtrl = InitMtrl(WHITE, WHITE, WHITE, BLACK, 5.0f);
teapotMtrl = InitMtrl(RED, RED*0.5f, RED, BLACK, 2.0f);
D3DLIGHT9 dir = InitDirLight(D3DXCOLOR(0.8f, 0.8f, 0.8f, 1.0f),
D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f),
D3DXCOLOR(0.2f, 0.2f, 0.2f, 1.0f),
D3DXVECTOR3(0.707f, 0.f, -0.707f));
pd3dDevice->SetLight(0, &dir);
pd3dDevice->LightEnable(0, true);
pd3dDevice->SetRenderState(D3DRS_NORMALIZENORMALS, true);
pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, true);
D3DXCreateTextureFromFile(pd3dDevice, L"wood.dds", &bkTexture);
pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
pd3dDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
//指定alpha来源为材质
pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
//设定混合因子
pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
D3DXMATRIX proj;
D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI*0.5f, width / height, 1.f, 1000.f);
pd3dDevice->SetTransform(D3DTS_PROJECTION, &proj);
D3DXVECTOR3 eye{ 0.f,0.f,-5.f };
D3DXVECTOR3 at{ 0.f,0.f,0.f };
D3DXVECTOR3 up{ 0.f,1.f,0.f };
D3DXMATRIX cam;
D3DXMatrixLookAtLH(&cam, &eye, &at, &up);
pd3dDevice->SetTransform(D3DTS_VIEW, &cam);
}
void Display(float timeDelta)
{
if (pd3dDevice)
{
if (::GetAsyncKeyState('A') & 0x8000f)
teapotMtrl.Diffuse.a += 0.0001f;
if (::GetAsyncKeyState('D') & 0x8000f)
teapotMtrl.Diffuse.a -= 0.0001f;
//限制茶壶材质的alpha值
if (teapotMtrl.Diffuse.a > 1.f)
teapotMtrl.Diffuse.a = 1.f;
if (teapotMtrl.Diffuse.a < 0.f)
teapotMtrl.Diffuse.a = 0.f;
D3DXMATRIX W;
D3DXMatrixIdentity(&W);
pd3dDevice->SetTransform(D3DTS_WORLD, &W);
pd3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.f, 0);
pd3dDevice->BeginScene();
//绘制背景
pd3dDevice->SetFVF(FVF);
pd3dDevice->SetStreamSource(0, vb, 0, sizeof(Vertex));
pd3dDevice->SetTexture(0, bkTexture);
pd3dDevice->SetMaterial(&bkMtrl);
pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
//启用融合计算,准备绘制茶壶
pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
D3DXMatrixScaling(&W, 1.5f, 1.5f, 1.5f);
pd3dDevice->SetTransform(D3DTS_WORLD, &W);
pd3dDevice->SetMaterial(&teapotMtrl);
pd3dDevice->SetTexture(0, 0);
teapotMesh->DrawSubset(0);
//关闭融合计算
pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
pd3dDevice->EndScene();
pd3dDevice->Present(0, 0, 0, 0);
}
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_KEYDOWN:
if (wParam == VK_ESCAPE)
DestroyWindow(hWnd);
break;
}
return DefWindowProcA(hWnd, message, wParam, lParam);
}
D3DMATERIAL9 InitMtrl(D3DXCOLOR ambient, D3DXCOLOR diffuse, D3DXCOLOR specular, D3DXCOLOR emissive,float power)
{
D3DMATERIAL9 mtrl;
mtrl.Ambient = ambient;
mtrl.Diffuse = diffuse;
mtrl.Specular = specular;
mtrl.Emissive = emissive;
mtrl.Power = power;
return mtrl;
}
D3DLIGHT9 InitDirLight(D3DXCOLOR ambient, D3DXCOLOR diffuse, D3DXCOLOR specular,D3DXVECTOR3 d)
{
D3DLIGHT9 dir;
::ZeroMemory(&dir, sizeof(dir));
dir.Type = D3DLIGHT_DIRECTIONAL;
dir.Ambient = ambient;
dir.Diffuse = diffuse;
dir.Specular = specular;
dir.Direction = d;
return dir;
}
加载的纹理文件可以用之前的。
发表评论