• [direct3D 9.0] 程序二 纹理立方体


    这个程序是基于上个程序修改而来,为每一个面贴图。但是之前一直有问题,纹理一直不能正确显示

    1.不显示纹理。如下图所示

    经排查,问题出在Render函数里面设置顶点格式d3dDevice->SetFVF(D3DFVF_XYZ).然后我就修改成了自定义的格式Vertex::FVF。

    2.上面修改完成后,纹理显示不正常,并不是每个面分别一个贴图。而是贴图混乱。如下图所示:

    最后参考了http://blog.csdn.net/poem_qianmo/article/details/8523341这篇博文,发现自定义的顶点格式有问题

    const DWORD Vertex::FVF=D3DFVF_XYZ  | D3DFVF_TEX1 | D3DFVF_NORMAL;

    去掉D3DFVF_NORMAL程序运行就正常了。如下图所示

    至于原因,我google了一下,D3DFVF_NORMAL的定义是这样的:

    还是不明白为什么它影响纹理贴图。

    下面是源代码

      1 #include <Windows.h>
      2 #include <d3d9.h>
      3 #include <D3DX9math.h>
      4 #include <strsafe.h>
      5 #include <d3dx9tex.h>
      6 //全局变量 
      7 
      8 LPDIRECT3D9 d3D9 = NULL;                                         // IDirect3D9接口指针,用于获得物理设备信息和创建IDirect3DDeivce9接口。
      9 LPDIRECT3DDEVICE9 d3dDevice = NULL;                    // 代表显示3d图形的物理设备的C++对象。
     10 LPDIRECT3DVERTEXBUFFER9 vertexBuffer = NULL;   // 顶点缓存,用于存储顶点坐标。
     11 LPDIRECT3DINDEXBUFFER9 indexBuffer = NULL;     // 索引缓存,用于存储组成各个三角形的顶点的索引
     12 LPDIRECT3DTEXTURE9 tex = NULL;   // 材质
     13 struct Vertex  // 三维中顶点结构
     14 {
     15     float x, y, z;
     16     float _u, _v; //texture coordinates 
     17     static const DWORD FVF;
     18 };
     19 const DWORD Vertex::FVF=D3DFVF_XYZ  | D3DFVF_TEX1;
     20 
     21 //初始化 Direct3D
     22 BOOL InitD3D(HWND hwnd)
     23 {
     24     if( NULL == (d3D9 = Direct3DCreate9(D3D_SDK_VERSION))) //  该初始化函数保证应用程序通过正确的头文件被生成。
     25         return E_FAIL;  
     26 
     27 
     28 
     29     D3DCAPS9 caps;                            //device capabilitites
     30     d3D9->GetDeviceCaps(                 // 获取设备信息
     31         D3DADAPTER_DEFAULT,            //Adapter 指定获取哪个显示适配器的特性
     32         D3DDEVTYPE_HAL,                   // 设备类型 硬件设备:D3DDEVTYPE_HAL 软件设备:D3DDEVTYPE_REF
     33         &caps);                                    //返回填充后的D3DCAPS9结构。
     34 
     35     int vp = 0;                               //代表是否支持硬件顶点处理
     36     if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)  //显卡是否支持硬件几何转换和光源计算
     37     {
     38         vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; //支持,硬件方式处理顶点
     39     }
     40     else
     41     {
     42         vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;  //软件方式处理顶点
     43     }
     44 
     45     D3DPRESENT_PARAMETERS d3dparam;   // 这个结构用于设定我们将要创建的IDirect3DDevice9对象的一些特性
     46     ZeroMemory(&d3dparam, sizeof(d3dparam));
     47     d3dparam.BackBufferWidth = 800;                   //后备缓冲表面的宽度
     48     d3dparam.BackBufferHeight = 600;                    //后备缓冲表面的高度
     49     d3dparam.BackBufferFormat = D3DFMT_A8R8G8B8;  //后备缓冲表面的像素格式
     50     d3dparam.BackBufferCount = 1;                                 // 后备表面的个数
     51     d3dparam.MultiSampleType = D3DMULTISAMPLE_NONE;  //全屏抗锯齿的类型
     52     d3dparam.MultiSampleQuality = 0;                                   //全屏抗锯齿的质量等级
     53     d3dparam.SwapEffect = D3DSWAPEFFECT_DISCARD;            // 指定表面在交换链中是如何被交换的
     54     d3dparam.hDeviceWindow = hwnd;                          // 窗口句柄
     55     d3dparam.Windowed = true;                      //是否窗口模式
     56     d3dparam.EnableAutoDepthStencil = true;                // 深度/模板缓冲
     57     d3dparam.AutoDepthStencilFormat = D3DFMT_D24S8;            //深度/模板缓冲的等级
     58     d3dparam.Flags = 0;    // 一些附加特性
     59     d3dparam.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;    //刷新率
     60     d3dparam.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;  //属于D3DPRESENT 成员,又有两个常用标志,其余请查SDK:
     61     
     62     //创建IDirect3DDevcie9对象
     63     if(FAILED(d3D9->CreateDevice(        
     64         D3DADAPTER_DEFAULT,            //adapter
     65         D3DDEVTYPE_HAL,             //设备类型
     66         hwnd,                             //窗口句柄
     67         vp,                                 //顶点处理方式
     68         &d3dparam, &d3dDevice)))
     69     {
     70         return E_FAIL;
     71     }
     72     return true;
     73 }
     74  
     75 // 创建顶点缓存
     76 bool InitVertexBuffer()
     77 {
     78 
     79     // 初始化正方体的24顶点
     80     Vertex vertex[] = 
     81     {  //正面
     82         {-1.0f, 1.0f, -1.0f,    0.0f, 0.0f},
     83         {1.0f,  1.0f, -1.0f, 1.0f, 0.0f},
     84         {1.0f, -1.0f, -1.0f, 1.0f, 1.0f},
     85         {-1.0f, -1.0f, -1.0f, 0.0f, 1.0f},
     86         //背面
     87         {1.0f, 1.0f, 1.0f,0.0f, 0.0f},
     88         {-1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
     89         {-1.0f, -1.0f, 1.0f, 1.0f, 1.0f},
     90         {1.0f, -1.0f, 1.0f, 0.0f, 1.0f},
     91         //左面
     92         {-1.0f, 1.0f, 1.0f, 0.0f, 0.0f},
     93         {-1.0f, 1.0f, -1.0f,1.0f, 0.0f},
     94         {-1.0f, -1.0f, -1.0f, 1.0f, 1.0f},
     95         {-1.0f,  -1.0f, 1.0f, 0.0f, 1.0f},
     96         //右面
     97         {1.0f, 1.0f, -1.0f, 0.0f, 0.0f},
     98         {1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
     99         {1.0f, -1.0f, 1.0f, 1.0f, 1.0f},
    100         {1.0f, -1.0f, -1.0f, 0.0f, 1.0f},
    101         //底面
    102         {-1.0f, -1.0f, -1.0f,    0.0f, 0.0f},
    103         {1.0f, -1.0f, -1.0f, 1.0f, 0.0f},
    104         {1.0f, -1.0f, 1.0f, 1.0f, 1.0f},
    105         {-1.0f, -1.0f, 1.0f, 0.0f, 1.0f},
    106         //上面
    107         {-1.0f,  1.0f, 1.0f, 0.0f, 0.0f},
    108         {1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
    109         {1.0f, 1.0f, -1.0f, 1.0f, 1.0f},
    110         {-1.0f, 1.0f, -1.0f, 0.0f, 1.0f}
    111 
    112     };
    113     if(FAILED(d3dDevice->CreateVertexBuffer(          //创建顶点缓存
    114         24*sizeof(Vertex),           // 分配给缓存的字节大小         
    115         0,                                 //指定关于怎样使用缓存的额外信息
    116         Vertex::FVF,               // 存储杂牌缓存中的顶点格式
    117         D3DPOOL_DEFAULT,      //缓存放置在哪一个内存池中
    118         &vertexBuffer,                //返回创建好的顶点缓存的指针
    119         NULL)))                          // 没有使用
    120     {
    121         return false;
    122     }
    123     Vertex *vetices;
    124     vertexBuffer->Lock(0, 0, (void**)&vetices, 0);          //锁存整个缓存
    125     memcpy(vetices, vertex, sizeof(vertex));                   //想缓存里写顶点
    126     vertexBuffer->Unlock();                                         //解锁缓存
    127     return true;
    128 }
    129 
    130 //设置照相机和投影
    131 void SetupMatrices()
    132 {
    133     D3DXMATRIX matWorld, Rx, Ry, Rz;  
    134     D3DXMatrixIdentity(&matWorld);                  // 单位化世界矩阵  
    135     D3DXMatrixRotationX(&Rx, D3DX_PI *(::timeGetTime() / 1000.0f));    // 绕X轴旋转  
    136     D3DXMatrixRotationY(&Ry, D3DX_PI *( ::timeGetTime() / 1000.0f/2));    // 绕Y轴旋转  
    137     D3DXMatrixRotationZ(&Rz, D3DX_PI *( ::timeGetTime() / 1000.0f/3));   // 绕Z轴旋转  
    138     matWorld = Rx * Ry * Rz * matWorld;             // 得到最终的组合矩阵  
    139     d3dDevice->SetTransform(D3DTS_WORLD, &matWorld);  //设置世界变换矩阵  
    140 
    141     D3DXVECTOR3 position(3.0f, 3.0f, 3.0f);            //虚拟照相机坐标
    142     D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);                 // 目标物体坐标
    143     D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);                        //正上方坐标
    144     D3DXMATRIX v;                                                          
    145     D3DXMatrixLookAtLH(&v, &position, &target, &up);      //计算视图坐标系的变换矩阵   
    146 
    147     d3dDevice->SetTransform(D3DTS_VIEW, &v);    //视图坐标系变换
    148 
    149     D3DXMATRIX proj;                 //投影矩阵
    150     //计算投影矩阵
    151     D3DXMatrixPerspectiveFovLH(&proj,               
    152         D3DX_PI*0.5f,         //视野角度
    153         800.0/600.0,            //宽高比
    154         1.0f,                       //前裁剪面距离
    155         1000.0f);                   //后裁剪面距离
    156     d3dDevice->SetTransform(D3DTS_PROJECTION, &proj);        //设置投影变换
    157 
    158 }
    159 
    160 void InitTexture() 
    161 {
    162     D3DXCreateTextureFromFile(d3dDevice, L"texture.bmp", &tex);   // 创建纹理
    163     d3dDevice->SetTexture(0, tex);
    164 
    165     //设置过滤器
    166     d3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    167     d3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    168     d3dDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
    169 
    170     d3dDevice->SetRenderState(D3DRS_LIGHTING, false);  //关闭灯光
    171 }
    172 //初始化索引缓存
    173 bool InitIntextBuffer()
    174 {
    175     d3dDevice->CreateIndexBuffer(36*sizeof(WORD),        
    176         D3DUSAGE_WRITEONLY, 
    177         D3DFMT_INDEX16,                     //指定索引的大小
    178         D3DPOOL_MANAGED, 
    179         &indexBuffer, 
    180         0);
    181     WORD* indices = 0;
    182     indexBuffer->Lock(0, 0, (void**)&indices, 0);
    183     //前面
    184     indices[0] = 0; indices[1] = 1; indices[2] = 2;
    185     indices[3] = 0; indices[4] = 2; indices[5] = 3;
    186     // 背面
    187     indices[6] = 4; indices[7] = 5; indices[8] = 6;
    188     indices[9] = 4; indices[10] = 6; indices[11] = 7;
    189     // 左面
    190     indices[12] =8; indices[13] =9; indices[14] = 10;
    191     indices[15] = 8; indices[16] = 10; indices[17] = 11;
    192     // 右面
    193     indices[18] = 12; indices[19] = 13; indices[20] =14;
    194     indices[21] = 12; indices[22] = 14; indices[23] =15;
    195     //底面
    196     indices[24] = 16; indices[25] = 17; indices[26] =18;
    197     indices[27] = 16; indices[28] = 18; indices[29] = 19;
    198     //顶面
    199     indices[30] =20; indices[31] = 21; indices[32] =22;
    200     indices[33] = 20; indices[34] = 22; indices[35] = 23;
    201 
    202     indexBuffer->Unlock();
    203     return true;
    204 }
    205 //释放COM资源
    206 bool CleanUp()
    207 {
    208     if(indexBuffer != NULL)
    209         indexBuffer->Release();
    210     if(vertexBuffer != NULL)
    211         vertexBuffer->Release();
    212     if(d3dDevice != NULL)
    213         d3dDevice->Release();
    214     if(d3D9 != NULL)
    215         d3D9->Release();
    216     return true;
    217 }
    218 //渲染
    219 bool Render()         
    220 {
    221     d3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
    222     if(SUCCEEDED(d3dDevice->BeginScene()))        //开始场景绘制
    223     {
    224         SetupMatrices();    //设置照相机和投影
    225 
    226         // 设置资源流与一个顶点缓存挂钩
    227         d3dDevice->SetStreamSource(0, vertexBuffer, 0, sizeof(Vertex));
    228         d3dDevice->SetIndices(indexBuffer);           //设置索引缓存
    229         d3dDevice->SetFVF(Vertex::FVF);               //设置顶点格式
    230 
    231          //使用索引来绘制图元
    232         d3dDevice->DrawIndexedPrimitive(
    233             D3DPT_TRIANGLELIST,         //图元类型 
    234             0,                                         //一个基本数字,在调用中用它去加上索引
    235             0,                                         //将被引用的最小索引值
    236             24,                                         //顶点数
    237             0,                                         //开始渲染的开始索引点 
    238             12);                                       //绘制图元的个数
    239         d3dDevice->EndScene();             //结束场景绘制
    240     }
    241     d3dDevice->Present(NULL, NULL, NULL, NULL);        //翻转表面
    242     return true;
    243 }
    244 //消息处理函数
    245 LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    246 {
    247     switch( msg )
    248     {
    249     case WM_DESTROY:
    250         CleanUp();
    251         PostQuitMessage( 0 );
    252         return 0;
    253     }
    254     return DefWindowProc( hwnd, msg, wParam, lParam );
    255 }
    256 
    257 //main函数
    258 INT WINAPI wWinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in LPWSTR lpCmdLine, __in int nShowCmd )
    259 {
    260     UNREFERENCED_PARAMETER(hInstance);
    261     WNDCLASSEX wc = {
    262         sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, 
    263         GetModuleHandle(NULL), NULL, NULL, NULL, NULL, 
    264         L"Cubedemo", NULL
    265     };
    266     RegisterClassEx(&wc);
    267     
    268     HWND hwnd = CreateWindow(L"CubeDemo", L"CubeDemo", 
    269         WS_OVERLAPPEDWINDOW, 100, 100, 800, 600, NULL, NULL, hInstance, NULL);
    270 
    271     if(InitD3D(hwnd))
    272     {
    273         if(InitVertexBuffer() && InitIntextBuffer())
    274         {
    275             InitTexture();
    276             ShowWindow(hwnd, SW_SHOWDEFAULT);
    277             UpdateWindow(hwnd);
    278             MSG msg;
    279             ZeroMemory(&msg, sizeof(msg));
    280             while(msg.message != WM_QUIT)
    281             {
    282                 if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
    283                 {
    284                     TranslateMessage(&msg);
    285                     DispatchMessage(&msg);
    286                 }
    287                 else
    288                 {
    289                     Render();
    290                 }    
    291             }
    292 
    293         }
    294     }
    295     UnregisterClass(L"CubeDemo", wc.hInstance);
    296     return 0;
    297 
    298 }
  • 相关阅读:
    如何在Mac终端中进入含空格文件名的文件夹
    redis测试常用工具及方法
    Spark3.0 Standalone模式部署
    使用Quorum Journal Manager(QJM)的HDFS NameNode高可用配置
    任务-实业-化工:王永庆
    节日-传统节日:排灯节
    葡萄科:乌蔹梅
    植物界:蕨类植物门
    修辞手法-汉语-词语:明喻
    修辞手法-汉语-词语:隐喻
  • 原文地址:https://www.cnblogs.com/wangke1020/p/3696159.html
Copyright © 2020-2023  润新知