D3D中的纹理映射(3)

该例程演示了怎样对一个立方体映射板条纹理。

截图:

vertex.h:

#ifndef __VERTEX_H__
#define __VERTEX_H__
class cTextureVertex
{
public:
float m_x, m_y, m_z;
float m_nx, m_ny, m_nz;
float m_u, m_v; // texture coordinates
    cTextureVertex() { }
    cTextureVertex(float x, float y, float z,
float nx, float ny, float nz,
float u, float v)
    {
        m_x  = x;  m_y  = y;  m_z  = z;
        m_nx = nx; m_ny = ny; m_nz = nz;
        m_u  = u;  m_v  = v;
    }   
};
#define TEXTURE_VERTEX_FVF (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)
#endif

cube.h:

#ifndef __CUBE_H__
#define __CUBE_H__
#include <d3dx9.h>
class cCube
{
public:
    cCube(IDirect3DDevice9* d3d_device);
~cCube();
void draw(const D3DMATRIX* world, const D3DMATERIAL9* material, IDirect3DTexture9* texture);
private:
    IDirect3DDevice9*        m_d3d_device;
    IDirect3DVertexBuffer9*    m_vertex_buffer;
    IDirect3DIndexBuffer9*    m_index_buffer;
};
#endif

cube.cpp:

/****************************************************************************
  Provides an interface to create and render a cube.
****************************************************************************/
#include "cube.h"
#include "vertex.h"
cCube::cCube(IDirect3DDevice9* d3d_device)
{
    m_d3d_device = d3d_device;
    m_d3d_device->CreateVertexBuffer(24 * sizeof(cTextureVertex), D3DUSAGE_WRITEONLY, TEXTURE_VERTEX_FVF,
        D3DPOOL_MANAGED, &m_vertex_buffer, NULL);
    cTextureVertex* v;
    m_vertex_buffer->Lock(0, 0, (void**)&v, 0);
// build box
// fill in the front face vertex data
    v[0] = cTextureVertex(-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);
    v[1] = cTextureVertex(-1.0f,  1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
    v[2] = cTextureVertex( 1.0f,  1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f);
    v[3] = cTextureVertex( 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] = cTextureVertex(-1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
    v[5] = cTextureVertex( 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f);
    v[6] = cTextureVertex( 1.0f,  1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f);
    v[7] = cTextureVertex(-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]  = cTextureVertex(-1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
    v[9]  = cTextureVertex(-1.0f, 1.0f,  1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f);
    v[10] = cTextureVertex( 1.0f, 1.0f,  1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f);
    v[11] = cTextureVertex( 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] = cTextureVertex(-1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f);
    v[13] = cTextureVertex( 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f);
    v[14] = cTextureVertex( 1.0f, -1.0f,  1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f);
    v[15] = cTextureVertex(-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] = cTextureVertex(-1.0f, -1.0f,  1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f);
    v[17] = cTextureVertex(-1.0f,  1.0f,  1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
    v[18] = cTextureVertex(-1.0f,  1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f);
    v[19] = cTextureVertex(-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] = cTextureVertex( 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f);
    v[21] = cTextureVertex( 1.0f,  1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
    v[22] = cTextureVertex( 1.0f,  1.0f,  1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f);
    v[23] = cTextureVertex( 1.0f, -1.0f,  1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f);
    m_vertex_buffer->Unlock();
    m_d3d_device->CreateIndexBuffer(36 * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED,
&m_index_buffer, NULL);
    WORD* index_ptr = NULL;
    m_index_buffer->Lock(0, 0, (void**)&index_ptr, 0);
// fill in the front face index data
    index_ptr[0] = 0; index_ptr[1] = 1; index_ptr[2] = 2;
    index_ptr[3] = 0; index_ptr[4] = 2; index_ptr[5] = 3;
// fill in the back face index data
    index_ptr[6] = 4; index_ptr[7]  = 5; index_ptr[8]  = 6;
    index_ptr[9] = 4; index_ptr[10] = 6; index_ptr[11] = 7;
// fill in the top face index data
    index_ptr[12] = 8; index_ptr[13] = 9; index_ptr[14] = 10;
    index_ptr[15] = 8; index_ptr[16] = 10; index_ptr[17] = 11;
// fill in the bottom face index data
    index_ptr[18] = 12; index_ptr[19] = 13; index_ptr[20] = 14;
    index_ptr[21] = 12; index_ptr[22] = 14; index_ptr[23] = 15;
// fill in the left face index data
    index_ptr[24] = 16; index_ptr[25] = 17; index_ptr[26] = 18;
    index_ptr[27] = 16; index_ptr[28] = 18; index_ptr[29] = 19;
// fill in the right face index data
    index_ptr[30] = 20; index_ptr[31] = 21; index_ptr[32] = 22;
    index_ptr[33] = 20; index_ptr[34] = 22; index_ptr[35] = 23;
    m_index_buffer->Unlock();
}
cCube::~cCube()
{
if(m_vertex_buffer)
    {
        m_vertex_buffer->Release();
        m_vertex_buffer = NULL;
    }
if(m_index_buffer)
    {
        m_index_buffer->Release();
        m_index_buffer = NULL;
    }
}
void cCube::draw(const D3DMATRIX* world, const D3DMATERIAL9* material, IDirect3DTexture9* texture)
{
if(world)
        m_d3d_device->SetTransform(D3DTS_WORLD, world);
if(material)
        m_d3d_device->SetMaterial(material);
if(texture)
        m_d3d_device->SetTexture(0, texture);
    m_d3d_device->SetStreamSource(0, m_vertex_buffer, 0, sizeof(cTextureVertex));
    m_d3d_device->SetIndices(m_index_buffer);
    m_d3d_device->SetFVF(TEXTURE_VERTEX_FVF);
    m_d3d_device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 24, 0, 12);
}

TexCube.cpp:

/**************************************************************************************
  Renders a textured cube.  Demonstrates creating a texture, setting texture filters,
  enabling a texture, and texture coordinates.  Use the arrow keys to orbit the scene.
**************************************************************************************/
#include "d3dUtility.h"
#include "cube.h"
#include "vertex.h"
#pragma warning(disable : 4100)
const int WIDTH  = 640;
const int HEIGHT = 480;
IDirect3DDevice9*        g_d3d_device;
cCube*                    g_cube;
IDirect3DTexture9*        g_d3d_texture;
////////////////////////////////////////////////////////////////////////////////////////////////////
bool setup()
{   
    g_cube = new cCube(g_d3d_device);
// set a directional light
    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);
// set and enable the light
    g_d3d_device->SetLight(0, &light);
    g_d3d_device->LightEnable(0, TRUE);
// turn off specular lighting and instruct Direct3D to renormalize normals
    g_d3d_device->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE);
    g_d3d_device->SetRenderState(D3DRS_SPECULARENABLE, TRUE);
    D3DXCreateTextureFromFile(g_d3d_device, "crate.jpg", &g_d3d_texture);
// set texture filter states
    g_d3d_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    g_d3d_device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    g_d3d_device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
// set the projection matrix
    D3DXMATRIX proj;
    D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI * 0.5f, (float)WIDTH/HEIGHT, 1.0f, 1000.0f);
    g_d3d_device->SetTransform(D3DTS_PROJECTION, &proj);
return true;
}
void cleanup()
{
    safe_delete<cCube*>(g_cube);
    safe_release<IDirect3DTexture9*>(g_d3d_texture);
}
bool display(float time_delta)
{
// update the scene: update camera position
static float angle = (3.0f * D3DX_PI) / 2.0f;
static float height = 2.0f;
if(GetAsyncKeyState(VK_LEFT) & 0x8000f)
        angle -= 0.5f * time_delta;
if(GetAsyncKeyState(VK_RIGHT) & 0x8000f)
        angle += 0.5f * time_delta;
if(GetAsyncKeyState(VK_UP) & 0x8000f)
        height += 5.0f * time_delta;
if(GetAsyncKeyState(VK_DOWN) & 0x8000f)
        height -= 5.0f * time_delta;
    D3DXVECTOR3 position(cosf(angle) * 3.0f, height, sinf(angle) * 3.0f);
    D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
    D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
    D3DXMATRIX view_matrix;
    D3DXMatrixLookAtLH(&view_matrix, &position, &target, &up);
    g_d3d_device->SetTransform(D3DTS_VIEW, &view_matrix);
// draw the scene
    g_d3d_device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
    g_d3d_device->BeginScene();
    g_cube->draw(NULL, &WHITE_MATERIAL, g_d3d_texture);       
    g_d3d_device->EndScene();
    g_d3d_device->Present(NULL, NULL, NULL, NULL);
return true;
}
LRESULT CALLBACK wnd_proc(HWND hwnd, UINT msg, WPARAM word_param, LPARAM long_param)
{
switch(msg)
    {
case WM_DESTROY:
        PostQuitMessage(0);
break;
case WM_KEYDOWN:
if(word_param == VK_ESCAPE)
            DestroyWindow(hwnd);
break;
    }
return DefWindowProc(hwnd, msg, word_param, long_param);
}
int WINAPI WinMain(HINSTANCE inst, HINSTANCE, PSTR cmd_line, int cmd_show)
{
if(! init_d3d(inst, WIDTH, HEIGHT, true, D3DDEVTYPE_HAL, &g_d3d_device))
    {
        MessageBox(NULL, "init_d3d() - failed.", 0, MB_OK);
return 0;
    }
if(! setup())
    {
        MessageBox(NULL, "Steup() - failed.", 0, MB_OK);
return 0;
    }
    enter_msg_loop(display);
    cleanup();
    g_d3d_device->Release();
return 0;
}

下载源程序

posted @ 2008-03-20 21:21  至尊王者  阅读(878)  评论(0编辑  收藏  举报