纹理贴图案例

vertex.h

 1 #ifndef __vertexH__
 2 #define __vertexH__
 3 
 4 struct Vertex
 5 {
 6     Vertex(){}
 7     Vertex(float x, float y, float z,
 8         float nx, float ny, float nz,
 9         float u, float v)
10     {
11         _x = x; _y = y; _z = z;
12         _nx = nx; _ny = ny; _nz = nz;
13         _u = u; _v = v;
14     }
15     float _x, _y, _z;
16     float _nx, _ny, _nz;
17     float _u, _v;
18 };
19 
20 #define FVF_VERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)
21 
22 #endif
View Code

Cube.h

#ifndef __CubeH__
#define __CubeH__


#include<d3dx9.h>
class Cube
{
public:
    Cube(void);
    Cube(IDirect3DDevice9* device);
    bool draw(D3DXMATRIX* world,D3DMATERIAL9* mtrl,IDirect3DTexture9* tex);
    ~Cube(void);
private:
    IDirect3DDevice9*  _device;
    IDirect3DVertexBuffer9* _vb;
    IDirect3DIndexBuffer9*  _ib;

};

#endif
View Code

d3dUtility.h

//////////////////////////////////////////////////////////////////////////////////////////////////
//
// File: d3dUtility.h
//
// 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.
//
//////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef __d3dUtilityH__
#define __d3dUtilityH__

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

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.

    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 RED(D3DCOLOR_XRGB(255,0,0));
    const D3DXCOLOR WHITE(D3DCOLOR_XRGB(255,255,255));
    const D3DXCOLOR BLACK(D3DCOLOR_XRGB(0,0,0));
    const D3DXCOLOR GREEN(D3DCOLOR_XRGB(0,255,0));
    const D3DXCOLOR BLUE(D3DCOLOR_XRGB(0,0,255));
    const D3DXCOLOR YELLOW(D3DCOLOR_XRGB(255,255,0));
    const D3DXCOLOR CYAN(D3DCOLOR_XRGB(0,255,255));
    const D3DXCOLOR MAGENTA(D3DCOLOR_XRGB(255,0,255));

    D3DMATERIAL9 InitMtrl(D3DXCOLOR a,D3DXCOLOR d,D3DXCOLOR s,D3DXCOLOR e,float p);
        //5.定义材质常量
    const D3DMATERIAL9 RED_MTRL=InitMtrl(d3d::RED,d3d::RED,d3d::RED,d3d::BLACK,2.0f);
    const D3DMATERIAL9 WHITE_MTRL=InitMtrl(WHITE,WHITE,WHITE,BLACK,2.0f);
    const D3DMATERIAL9 GREEN_MTRL=InitMtrl(GREEN,GREEN,GREEN,BLACK,2.0f);
    const D3DMATERIAL9 YELLOW_MTRL=InitMtrl(YELLOW,YELLOW,YELLOW,BLACK,2.0f);
    const D3DMATERIAL9 BLUE_MTRL=InitMtrl(BLUE,BLUE,BLUE,BLACK,2.0f);

    D3DLIGHT9 InitSpotLight(D3DXVECTOR3* position,D3DXVECTOR3* direction,D3DXCOLOR* color);
    D3DLIGHT9 InitDirectionalLight(D3DXVECTOR3* direction,D3DXCOLOR* color);
    D3DLIGHT9 InitPointLight(D3DXVECTOR3* position,D3DXCOLOR* color);
}

#endif // __d3dUtilityH__
View Code

Cube.cpp

#include "Cube.h"
#include "vertex.h"

Cube::Cube(void)
{
}
Cube::Cube(IDirect3DDevice9* device)
{
    _device = device;
        _device->CreateVertexBuffer(24 * sizeof(Vertex),//24个顶点,6个面*4个点
        D3DUSAGE_WRITEONLY,
        FVF_VERTEX,
        D3DPOOL_MANAGED,
        &_vb,
        0);
    Vertex* v;
    _vb->Lock(0,0,(void**)&v,0);

    // fill in the front face vertex data
    v[0] = Vertex(-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);//顶点坐标,法线坐标,纹理坐标
    v[1] = Vertex(-1.0f,  1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
    v[2] = Vertex( 1.0f,  1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f);
    v[3] = Vertex( 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);

    // fill in the back face vertex data
    v[4] = Vertex(-1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
    v[5] = Vertex( 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f);
    v[6] = Vertex( 1.0f,  1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f);
    v[7] = Vertex(-1.0f,  1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f);

    // fill in the top face vertex data
    v[8]  = Vertex(-1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
    v[9]  = Vertex(-1.0f, 1.0f,  1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f);
    v[10] = Vertex( 1.0f, 1.0f,  1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f);
    v[11] = Vertex( 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f);

    // fill in the bottom face vertex data
    v[12] = Vertex(-1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f);
    v[13] = Vertex( 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f);
    v[14] = Vertex( 1.0f, -1.0f,  1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f);
    v[15] = Vertex(-1.0f, -1.0f,  1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f);

    // fill in the left face vertex data
    v[16] = Vertex(-1.0f, -1.0f,  1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f);
    v[17] = Vertex(-1.0f,  1.0f,  1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
    v[18] = Vertex(-1.0f,  1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f);
    v[19] = Vertex(-1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f);

    // fill in the right face vertex data
    v[20] = Vertex( 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f);
    v[21] = Vertex( 1.0f,  1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
    v[22] = Vertex( 1.0f,  1.0f,  1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f);
    v[23] = Vertex( 1.0f, -1.0f,  1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f);

    _vb->Unlock();
//创建索引缓存
    _device->CreateIndexBuffer(36*sizeof(WORD),//每个面两个三角形,6个面*2个三角形*3个顶点
        D3DUSAGE_WRITEONLY,
        D3DFMT_INDEX16,
        D3DPOOL_MANAGED,
        &_ib,
        0);
    WORD* i=0;
    _ib->Lock(0,0,(void**)&i,0);

    // fill in the front face index data
    i[0] = 0; i[1] = 1; i[2] = 2;
    i[3] = 0; i[4] = 2; i[5] = 3;

    // fill in the back face index data
    i[6] = 4; i[7]  = 5; i[8]  = 6;
    i[9] = 4; i[10] = 6; i[11] = 7;

    // fill in the top face index data
    i[12] = 8; i[13] =  9; i[14] = 10;
    i[15] = 8; i[16] = 10; i[17] = 11;

    // fill in the bottom face index data
    i[18] = 12; i[19] = 13; i[20] = 14;
    i[21] = 12; i[22] = 14; i[23] = 15;

    // fill in the left face index data
    i[24] = 16; i[25] = 17; i[26] = 18;
    i[27] = 16; i[28] = 18; i[29] = 19;

    // fill in the right face index data
    i[30] = 20; i[31] = 21; i[32] = 22;
    i[33] = 20; i[34] = 22; i[35] = 23;

    _ib->Unlock();
}


Cube::~Cube(void)
{
}


bool Cube::draw(D3DXMATRIX* world, D3DMATERIAL9* mtrl, IDirect3DTexture9* tex)
{    if(world)
        _device->SetTransform(D3DTS_WORLD, world);
if(mtrl)
        _device->SetMaterial(mtrl);
    if(tex)
        _device->SetTexture(0,tex);
    _device->SetStreamSource(0,_vb,0,sizeof(Vertex));
    _device->SetIndices(_ib);
    _device->SetFVF(FVF_VERTEX);
    _device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,24,0,12);
    return true;
}
View Code

d3dInit.cpp

//////////////////////////////////////////////////////////////////////////////////////////////////
//
// File: d3dinit.cpp
//
// 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"
#pragma  comment(lib, "d3d9.lib")
#pragma  comment(lib, "d3dx9.lib")
#pragma  comment(lib, "winmm.lib")
//
// Globals
//
#include "Cube.h"
IDirect3DDevice9* Device = 0;

//
// Framework Functions
//
const int Width=640;
const int Height=480;

float angle=0.0f;

Cube* Box = 0;

IDirect3DTexture9* Tex = 0;

bool Setup()
{
    Box = new Cube(Device);
    
    
        //灯光
    D3DLIGHT9 light;
    ::ZeroMemory(&light,sizeof(light));
    light.Type = D3DLIGHT_DIRECTIONAL;
    light.Ambient = D3DXCOLOR(0.8f, 0.8f, 0.8f, 1.0f);
    light.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
    light.Specular = D3DXCOLOR(0.2f, 0.2f, 0.2f, 1.0f);
    light.Direction = D3DXVECTOR3(1.0f,-1.0f,0.0f);
    Device->SetLight(0,&light);
    Device->LightEnable(0,true);

    Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);
    Device->SetRenderState(D3DRS_SPECULARENABLE, true);
    

    D3DXCreateTextureFromFile(
            Device,
        L"crate.jpg",
        &Tex);
    Device->SetSamplerState(0,D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    Device->SetSamplerState(0,D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    Device->SetSamplerState(0,D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
        //摄像机的位置和角度
    D3DXVECTOR3 position(0.0f,2.0f,-5.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)Width/(float)Height,
        1.0f,
        1000.0f);
    Device->SetTransform(D3DTS_PROJECTION,&proj);
    //Device->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);
    
    
    //Device->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);

    return true;
}

void Cleanup()
{
        d3d::Delete<Cube*>(Box);
    d3d::Release<IDirect3DTexture9*>(Tex);
}

bool Display(float timeDelta)
{
    if( Device ) // Only use Device methods if we have a valid device.
    {
    D3DXMATRIX yRot;
    angle+=0.001f;
    D3DXMatrixRotationY(&yRot,angle);
    
    
    Device->SetTransform(D3DTS_WORLD, &yRot);

    
        Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
      
        Device->BeginScene();
        Device->SetMaterial(&d3d::WHITE_MTRL);
        Device->SetTexture(0,Tex);
        Box->draw(0,0,0);
        Device->EndScene();

        Device->Present(0, 0, 0, 0);
    }
    return true;
}

//
// WndProc
//
LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch( msg )
    {
    case WM_DESTROY:
        ::PostQuitMessage(0);
        break;

    case WM_KEYDOWN:
        if( wParam == VK_ESCAPE )
            ::DestroyWindow(hwnd);
        break;
    }
    return ::DefWindowProc(hwnd, msg, wParam, lParam);
}

//
// WinMain
//
int WINAPI WinMain(HINSTANCE hinstance,
                   HINSTANCE prevInstance,
                   PSTR cmdLine,
                   int showCmd)
{
    if(!d3d::InitD3D(hinstance,
        640, 480, true, D3DDEVTYPE_HAL, &Device))
    {
        ::MessageBox(0, L"InitD3D() - FAILED", 0, 0);
        return 0;
    }

    if(!Setup())
    {
        ::MessageBox(0, L"Setup() - FAILED", 0, 0);
        return 0;
    }

    d3d::EnterMsgLoop( Display );

    Cleanup();

    Device->Release();

    return 0;
}
View Code

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"

bool d3d::InitD3D(
    HINSTANCE hInstance,
    int width, int height,
    bool windowed,
    D3DDEVTYPE deviceType,
    IDirect3DDevice9** device)
{
    //
    // Create the main application window.
    //

    WNDCLASS wc;

    wc.style         = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc   = (WNDPROC)d3d::WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(0, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(0, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName  = 0;
    wc.lpszClassName = L"Direct3D9App";

    if( !RegisterClass(&wc) )
    {
        ::MessageBox(0, L"RegisterClass() - FAILED", 0, 0);
        return false;
    }

    HWND hwnd = 0;
    hwnd = ::CreateWindow(L"Direct3D9App", L"Direct3D9App",
        WS_EX_TOPMOST,
        0, 0, width, height,
        0 /*parent hwnd*/, 0 /* menu */, hInstance, 0 /*extra*/);

    if( !hwnd )
    {
        ::MessageBox(0, L"CreateWindow() - FAILED", 0, 0);
        return false;
    }

    ::MoveWindow(hwnd,2250,80,640, 480,true);
    ::ShowWindow(hwnd, SW_SHOW);
    ::UpdateWindow(hwnd);

    //
    // Init D3D:
    //

    HRESULT hr = 0;

    // Step 1: Create the IDirect3D9 object.

    IDirect3D9* d3d9 = 0;
    d3d9 = Direct3DCreate9(D3D_SDK_VERSION);

    if( !d3d9 )
    {
        ::MessageBox(0, L"Direct3DCreate9() - FAILED", 0, 0);
        return false;
    }

    // Step 2: Check for hardware vp.

    D3DCAPS9 caps;
    d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps);

    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 d3dpp;
    d3dpp.BackBufferWidth            = width;
    d3dpp.BackBufferHeight           = height;
    d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
    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;
    d3dpp.Flags                      = 0;
    d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
    d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;

    // Step 4: Create the device.

    hr = d3d9->CreateDevice(
        D3DADAPTER_DEFAULT, // primary adapter
        deviceType,         // device type
        hwnd,               // window associated with device
        vp,                 // vertex processing
        &d3dpp,             // present parameters
        device);            // return created device

    if( FAILED(hr) )
    {
        // try again using a 16-bit depth buffer
        d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

        hr = d3d9->CreateDevice(
            D3DADAPTER_DEFAULT,
            deviceType,
            hwnd,
            vp,
            &d3dpp,
            device);

        if( FAILED(hr) )
        {
            d3d9->Release(); // done with d3d9 object
            ::MessageBox(0, L"CreateDevice() - FAILED", 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;
}

//4.定义材质函数,具体的函数实现在d3dUtility.cpp源文件中
D3DMATERIAL9 d3d::InitMtrl(D3DXCOLOR a,D3DXCOLOR d,D3DXCOLOR s,D3DXCOLOR e,float p)
    {
        D3DMATERIAL9 mtrl;
      //剪切聚光灯.cpp文件的相应材质定义语句
      /*Mtrls[0].Ambient=d3d::RED;
    Mtrls[0].Diffuse=d3d::RED;
    Mtrls[0].Specular=d3d::RED;
    Mtrls[0].Power=2.0f;
    Mtrls[0].Emissive=d3d::BLACK;*/
      //要做相应修改,数组改成局部变量,后面的符号常量,在这里改成参数
        mtrl.Ambient=a;
        mtrl.Diffuse=d;
        mtrl.Specular=s;
        mtrl.Power=p;
        mtrl.Emissive=e;
        return mtrl;
    }

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;
}


D3DLIGHT9 d3d::InitDirectionalLight(D3DXVECTOR3* direction,D3DXCOLOR *color)
    {
    D3DLIGHT9 light;
    ::ZeroMemory(&light,sizeof(light));//用Windows函数先清零
    light.Type=D3DLIGHT_DIRECTIONAL;
    light.Ambient=*color*0.6f;//环境光,就使用方法给它乘以0.6
    light.Diffuse=*color;//漫射光
    light.Specular=*color*0.6f;//镜面光,高亮度数是0.6倍
    light.Direction=*direction;
    
    return light;
    }

D3DLIGHT9 d3d::InitPointLight(D3DXVECTOR3* position,D3DXCOLOR *color)
    {
    D3DLIGHT9 light;
    ::ZeroMemory(&light,sizeof(light));//用Windows函数先清零
    light.Type=D3DLIGHT_POINT;
    light.Ambient=*color*0.6f;//没有环境光,就使用方法给它乘以0.6
    light.Diffuse=*color;//漫射光
    light.Specular=*color*0.6f;//镜面光,高亮度数是0.6倍
    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;
    }
View Code

扩展:实现三个箱子在空中旋转

posted @ 2022-04-24 11:41  szmtjs10  阅读(300)  评论(0编辑  收藏  举报