Yui的狗窝
Yui的狗窝
Directx9使用网格绘制正方体

通过D3DXCreateMeshFVF创建空网格,并写入顶点以及索引数据,最后调用网格成员函数Drawsubset来达到绘制图形的目的。

//utility.h
#pragma once
#include<d3d9.h>
#include<d3dx9.h>
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         BLUE = D3DCOLOR_XRGB(0, 0, 255);
IDirect3D9              *pd3d;
IDirect3DDevice9        *pd3dDevice;
D3DCAPS9                caps;
int                     iUseProcess;
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 DefWindowProc(hWnd, message, wParam, lParam);
}
bool InitD3d(HINSTANCE hInstance, int cmdShow)
{
    WNDCLASS wc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hInstance = hInstance;
    wc.lpfnWndProc = WndProc;
    wc.lpszClassName = L"fontx";
    wc.lpszMenuName = NULL;
    wc.style = CS_HREDRAW | CS_VREDRAW;
    RegisterClass(&wc);
    HWND hWnd = CreateWindow(L"fontx", L"font", NULL, 200, 200, 800, 600, NULL, NULL, hInstance, 0);
    ShowWindow(hWnd, cmdShow);
    UpdateWindow(hWnd);
    pd3d = Direct3DCreate9(D3D_SDK_VERSION);
    pd3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
    if (caps.Caps&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;
    if (pd3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, iUseProcess, &d3dpp, &pd3dDevice))
        return true;
    return false;
}
D3DMATERIAL9 InitMtrl(D3DXCOLOR ambient, D3DXCOLOR specular, D3DXCOLOR diffuse, D3DXCOLOR emissive, float power)
{
    D3DMATERIAL9 tem;
    tem.Ambient = ambient;
    tem.Specular = specular;
    tem.Diffuse = diffuse;
    tem.Emissive = emissive;
    tem.Power = power;
    return tem;
}
D3DLIGHT9 InitDirLight(D3DXCOLOR ambient, D3DXCOLOR specular, D3DXCOLOR diffuse, D3DXVECTOR3 dir)
{
    D3DLIGHT9 tem;
    ::ZeroMemory(&tem, sizeof(tem));
    tem.Type = D3DLIGHT_DIRECTIONAL;
    tem.Ambient = ambient;
    tem.Specular = specular;
    tem.Diffuse = diffuse;
    tem.Direction = dir;
    return tem;
}
//render.h
#pragma once
#include"utility.h"
#include<iostream>
#include<fstream>
#include<vector>
ID3DXMesh               *cubeMesh;
IDirect3DTexture9*      Texture[3] = { 0,0,0 };//子集的纹理
std::ofstream           OutFile;//将网格转存至文件
const DWORD             numSubsets = 3;
const WORD              FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;
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) {};
};
void Setup(float width, float height);
void Render(float timeDelta);
void dumpVertices(std::ofstream& outFile, ID3DXMesh* mesh);
void dumpIndices(std::ofstream& outFile, ID3DXMesh* mesh);
void dumpAttributeBuffer(std::ofstream& outFile, ID3DXMesh* mesh);
void dumpAdjacencyBuffer(std::ofstream& outFile, ID3DXMesh* mesh);
void dumpAttributeTable(std::ofstream& outFile, ID3DXMesh* mesh);
void dumpVertices(std::ofstream& outFile, ID3DXMesh* mesh)
{
    outFile << "Vertices:" << std::endl;
    outFile << "---------" << std::endl << std::endl;
    Vertex* v = 0;
    cubeMesh->LockVertexBuffer(0, (void**)&v);
    for (int i = 0; i < mesh->GetNumVertices(); i++)
    {
        outFile << "Vertex " << i << ": (";
        outFile << v[i].x << ", " << v[i].y << ", " << v[i].z << ", ";
        outFile << v[i].nx << ", " << v[i].ny << ", " << v[i].nz << ", ";
        outFile << v[i].u << ", " << v[i].v << ")" << std::endl;
    }
    mesh->UnlockVertexBuffer();
    outFile << std::endl << std::endl;
}
void dumpIndices(std::ofstream& outFile, ID3DXMesh* mesh)
{
    outFile << "Indices:" << std::endl;
    outFile << "--------" << std::endl << std::endl;
    WORD* indices;
    cubeMesh->LockIndexBuffer(0, (void**)&indices);
    for (int i = 0; i < mesh->GetNumFaces(); i++)
    {
        outFile << "Triangle " << i << ": ";
        outFile << indices[i * 3] << " ";
        outFile << indices[i * 3 + 1] << " ";
        outFile << indices[i * 3 + 2] << std::endl;
    }
    mesh->UnlockIndexBuffer();
    outFile << std::endl << std::endl;
}
void dumpAttributeBuffer(std::ofstream& outFile, ID3DXMesh* mesh)
{
    outFile << "Attribute Buffer:" << std::endl;
    outFile << "-----------------" << std::endl << std::endl;
    DWORD* attributeBuffer = 0;
    mesh->LockAttributeBuffer(0, &attributeBuffer);
    for (int i = 0; i < mesh->GetNumFaces(); i++)
    {
        outFile << "Triangle lives in subset " << i << ": ";
        outFile << attributeBuffer[i] << std::endl;
    }
    mesh->UnlockAttributeBuffer();
    outFile << std::endl << std::endl;
}
void dumpAdjacencyBuffer(std::ofstream& outFile, ID3DXMesh* mesh)
{
    outFile << "Adjacency Buffer:" << std::endl;
    outFile << "-----------------" << std::endl << std::endl;
    std::vector<dword> adjacencyBuffer(mesh->GetNumFaces() * 3);
    mesh->GenerateAdjacency(0.0f, &adjacencyBuffer[0]);
    for (int i = 0; i < mesh->GetNumFaces(); i++)
    {
        outFile << "Triangle's adjacent to triangle " << i << ": ";
        outFile << adjacencyBuffer[i * 3] << " ";
        outFile << adjacencyBuffer[i * 3 + 1] << " ";
        outFile << adjacencyBuffer[i * 3 + 2] << std::endl;
    }
    outFile << std::endl << std::endl;
}
void dumpAttributeTable(std::ofstream& outFile, ID3DXMesh* mesh)
{
    outFile << "Attribute Table:" << std::endl;
    outFile << "----------------" << std::endl << std::endl;
    DWORD numEntries = 0;
    mesh->GetAttributeTable(0, &numEntries);
    std::vector<d3DXATTRIBUTERANGE> table(numEntries);
    mesh->GetAttributeTable(&table[0], &numEntries);
    for (int i = 0; i < numEntries; i++)
    {
        outFile << "Entry " << i << std::endl;
        outFile << "-----------" << std::endl;
        outFile << "Subset ID:    " << table[i].AttribId << std::endl;
        outFile << "Face Start:   " << table[i].FaceStart << std::endl;
        outFile << "Face Count:   " << table[i].FaceCount << std::endl;
        outFile << "Vertex Start: " << table[i].VertexStart << std::endl;
        outFile << "Vertex Count: " << table[i].VertexCount << std::endl;
        outFile << std::endl;
    }
    outFile << std::endl << std::endl;
}
//render.cpp
#include"render.h"
#include<time.h>
IDirect3DTexture9   *textures[3];
void Setup(float width, float height)
{
    D3DXCreateMeshFVF(12, 24, D3DXMESH_MANAGED, FVF, pd3dDevice, &cubeMesh);//创建空网格
    Vertex *v;
    cubeMesh->LockVertexBuffer(0, (void**)&v);
    //front
    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);
    //back
    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);
    //top
    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);
    //bottom
    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);
    //left
    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);
    //right
    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);
    cubeMesh->UnlockVertexBuffer();
    WORD *i;
    cubeMesh->LockIndexBuffer(0, (void**)&i);
    //front
    i[0] = 0; i[1] = 1; i[2] = 2;
    i[3] = 0; i[4] = 2; i[5] = 3;
    //back
    i[6] = 4; i[7] = 5; i[8] = 6;
    i[9] = 4; i[10] = 6; i[11] = 7;
    //top
    i[12] = 8; i[13] = 9; i[14] = 10;
    i[15] = 8; i[16] = 10; i[17] = 11;
    //bottom
    i[18] = 12; i[19] = 13; i[20] = 14;
    i[21] = 12; i[22] = 14; i[23] = 15;
    //left
    i[24] = 16; i[25] = 17; i[26] = 18;
    i[27] = 16; i[28] = 18; i[29] = 19;
    //right
    i[30] = 20; i[31] = 21; i[32] = 22;
    i[33] = 20; i[34] = 22; i[35] = 23;
    cubeMesh->UnlockIndexBuffer();
    //指定面片所属子集
    DWORD* attributeBuffer;
    cubeMesh->LockAttributeBuffer(0, &attributeBuffer);
    for (int tem = 0; tem < 4; tem++)
        attributeBuffer[tem] = 0;
    for (int tem = 4; tem < 8; tem++)
        attributeBuffer[tem] = 1;
    for (int tem = 8; tem < 12; tem++)
        attributeBuffer[tem] = 2;
    cubeMesh->UnlockAttributeBuffer();
    //网格优化
    //计算邻接网格信息
    std::vector<dword> adjacencyBuffer(cubeMesh->GetNumFaces() * 3);
    cubeMesh->GenerateAdjacency(0.f, &adjacencyBuffer[0]);
    cubeMesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_COMPACT | D3DXMESHOPT_VERTEXCACHE, &adjacencyBuffer[0],
        0, 0, 0);
    //网格数据检查
    OutFile.open("Mesh Dump.txt");
    dumpVertices(OutFile, cubeMesh);
    dumpIndices(OutFile, cubeMesh);
    dumpAttributeTable(OutFile, cubeMesh);
    dumpAttributeBuffer(OutFile, cubeMesh);
    dumpAdjacencyBuffer(OutFile, cubeMesh);
    OutFile.close();
    pd3dDevice->SetRenderState(D3DRS_LIGHTING, false);
    D3DXCreateTextureFromFile(pd3dDevice, L"brick0.jpg", &textures[0]);
    D3DXCreateTextureFromFile(pd3dDevice, L"brick1.jpg", &textures[1]);
    D3DXCreateTextureFromFile(pd3dDevice, L"brick2.jpg", &textures[2]);
    pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    pd3dDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
    D3DXMATRIX cam;
    D3DXVECTOR3 pos{ 0.f,2.f,-5.f };
    D3DXVECTOR3 target{ 0.f,0.f,0.f };
    D3DXVECTOR3 up{ 0.f,1.f,0.f };
    D3DXMatrixLookAtLH(&cam, &pos, &target, &up);
    pd3dDevice->SetTransform(D3DTS_VIEW, &cam);
    D3DXMATRIX proj;
    D3DXMatrixPerspectiveLH(&proj, D3DX_PI*0.5f, width / height, 1.f, 1000.f);
    pd3dDevice->SetTransform(D3DTS_PROJECTION, &proj);
}
void Render(float timeDelta)
{
    if (pd3dDevice)
    {
        static float y = 0.f;
        D3DXMATRIX ry;
        D3DXMatrixRotationY(&ry, y);
        pd3dDevice->SetTransform(D3DTS_WORLD, &ry);
        if (y >= 6.28f)
            y = 0.f;
        y += 0.001f;
        pd3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.f, 0);
        pd3dDevice->BeginScene();
        for (int i = 0; i < 3; i++)
        {
            pd3dDevice->SetTexture(0, textures[i]);
            cubeMesh->DrawSubset(i);
        }
        pd3dDevice->EndScene();
        pd3dDevice->Present(0, 0, 0, 0);
    }
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPWSTR cmdLine, int cmdShow)
{
    InitD3d(hInstance, cmdShow);
    Setup(800, 600);
    MSG msg = { 0 };
    float prev, cur;
    prev = (float)timeGetTime();
    while (msg.message != WM_QUIT)
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        cur = (float)timeGetTime();
        Render((cur - prev)*0.001f);
        prev = cur;
    }
    return 0;
}
没有标签
首页      读书笔记      directx龙书的学习笔记      Directx9使用网格绘制正方体
https://secure.gravatar.com/avatar/d0fe7f1b17d5e9122db921e3a8cc327f?s=256&d=mm&r=g

Suzumiya, Yui

文章作者

发表评论

textsms
account_circle
email

Yui的狗窝

Directx9使用网格绘制正方体
通过D3DXCreateMeshFVF创建空网格,并写入顶点以及索引数据,最后调用网格成员函数Drawsubset来达到绘制图形的目的。 //utility.h #pragma once #include<d3d9.h> #include<d3d…
扫描二维码继续阅读
2018-05-04


没有激活的小工具