求助关于深度测试的两个问题!
代码如下:
- C/C++ code
#pragma comment(lib,"d3d9.lib")#pragma comment(lib,"d3dx9.lib")#pragma comment(lib,"winmm.lib")#include <d3dx9.h>#include <d3d9.h>#include <mmsystem.h>#include <math.h>LPDIRECT3D9 gpD3D =NULL; //D3D对象LPDIRECT3DDEVICE9 gpDevice =NULL; //D3D设备对象LPDIRECT3DVERTEXBUFFER9 gpVb0 =NULL; //顶点缓冲区对象LPDIRECT3DVERTEXBUFFER9 gpVb1 =NULL; //顶点缓冲区对象HWND gpW =NULL; //句柄 用于视口的设置用RECT rect; //用于视口参数的设置D3DRECT gpC; FLOAT fA = 0; //中间变量 用于sin cos 的变量 struct CUSTOMVERTEX //顶点结构{ D3DXVECTOR3 position; DWORD color;};#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE) //顶点格式 */#define NUMBERDIAN 3 //顶点数量#define NUMBERDUO 1 //顶点绘制的三角形的个数#define RED 0xffff0000 //红色#define BLUE 0x0000ffff //浅蓝色#define YELLOW 0X00ffff00 //黄色#define OTHER 0xff0000ff //深蓝色#define BLACK 0x00000000 //黑色#define WHITE 0xffffffff //白色VOID SetupWorldMatrix() //设置世界矩阵{ D3DXMATRIX matWorld; //UINT iTime = timeGetTime() % 1000; fA += 0.0004f; D3DXMatrixIdentity(&matWorld); //单位化 D3DXMatrixRotationY(&matWorld,fA); gpDevice->SetTransform(D3DTS_WORLD,&matWorld); //世界矩阵} VOID SetupViewandProjMatrices() //设置观察矩阵和投影矩阵{ fA += 0.02f; float s = 0, c = 0; s = sinf(fA)*2; c = cosf(fA)*2; //fA += 0.005f; //建立并设置观察矩阵 //D3DXVECTOR3 vE( 0.0f, s, c ); //摄像机在世界空间的坐标 D3DXVECTOR3 vE( 0.0F, 0.0F, 1.0F ); D3DXVECTOR3 vL( 0.0f, 0.0F, 0.0f ); //摄像机观察的那个点(在世界坐标系),和摄像机坐标vE一起确定摄像机的方向 D3DXVECTOR3 vU( 0.0f, 1.0f, 0.0f ); //摄像机的向上方向 在世界坐标系里面 D3DXMATRIX matView; D3DXMatrixLookAtLH( &matView, &vE, &vL, &vU ); gpDevice->SetTransform( D3DTS_VIEW, &matView ); //观察矩阵 //fA += 0.002f; D3DXMATRIX matProj; //建立并设置投影矩阵 正交投影 D3DXMatrixOrthoLH( &matProj, 2.0f, 1.5f, 0.0f, 2.0F ); // w,h ,znear,zfar大小也是相对于世界坐标??? gpDevice->SetTransform(D3DTS_PROJECTION, &matProj); //投影矩阵 */} VOID SetViewPort( HWND hWnd ) //设置视区{ //RECT rect; gpW = hWnd; GetClientRect( gpW, &rect ); D3DVIEWPORT9 vp; vp.X =0; vp.Y =0; vp.Width = rect.right; vp.Height = rect.bottom; vp.MinZ = 0.0f; vp.MaxZ = 1.0f; gpDevice->SetViewport(&vp);} HRESULT InitGeometry() //创建场景图像{ CUSTOMVERTEX vex0[NUMBERDIAN]; vex0[0].position = D3DXVECTOR3( 0.25f, -0.25f, -0.25f ); //1 vex0[0].color = WHITE; vex0[1].position = D3DXVECTOR3( 0.25f, 0.25f, -0.25f ); //2 vex0[1].color = WHITE; vex0[2].position = D3DXVECTOR3( -0.25f, -0.25f, -0.25f ); //3 vex0[2].color = WHITE; CUSTOMVERTEX vex1[NUMBERDIAN]; vex1[0].position = D3DXVECTOR3( 0.25f, -0.25f, 0.25f ); //2 vex1[0].color = BLACK; vex1[1].position = D3DXVECTOR3( 0.25f, 0.25f, 0.25f ); //3 vex1[1].color = BLACK; vex1[2].position = D3DXVECTOR3( -0.25f, -0.25f, 0.25f ); //4 vex1[2].color = BLACK; if( FAILED( gpDevice->CreateVertexBuffer( NUMBERDIAN*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &gpVb0, NULL ) ) ) //创建顶点缓冲区 { return E_FAIL; } CUSTOMVERTEX* pVer0; //填充顶点缓冲区 if( FAILED( gpVb0->Lock( 0, 0, (void**)&pVer0, 0))) return E_FAIL; memcpy( pVer0, vex0, sizeof(vex0) ); gpVb0->Unlock(); if( FAILED( gpDevice->CreateVertexBuffer( NUMBERDIAN*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &gpVb1, NULL ) ) ) //创建顶点缓冲区 { return E_FAIL; } CUSTOMVERTEX* pVer1; //填充顶点缓冲区 if( FAILED( gpVb1->Lock( 0, 0, (void**)&pVer1, 0))) return E_FAIL; memcpy( pVer1, vex1, sizeof(vex1) ); gpVb1->Unlock(); return S_OK;} // */HRESULT InitD3D(HWND hWnd) //初始化Direct3D{ if( NULL == ( gpD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) ) //创—3D对象 return E_FAIL; D3DPRESENT_PARAMETERS d3dpp; ZeroMemory( &d3dpp, sizeof(d3dpp) ); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; ///* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; // */ if( FAILED( gpD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &gpDevice ) ) ) //创—3D设备对象 { return E_FAIL; }// /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX gpDevice->SetRenderState( D3DRS_ZENABLE, TRUE ); gpDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_GREATER ); gpDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE ); // */// gpDevice->SetRenderState(D3DRS_AMBIENT, 0xFF00BB00); gpDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); gpDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); SetupViewandProjMatrices(); //设置观察和投影矩阵 SetViewPort( hWnd ); //设置视区 return S_OK;}VOID Render() //渲染图形{ gpDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 45, 50, 170), 1.0f, 0 ); //清空后台缓冲区 if( SUCCEEDED( gpDevice->BeginScene() ) ) { SetupViewandProjMatrices(); SetupWorldMatrix(); //设置世界矩阵 gpDevice->SetStreamSource( 0, gpVb0, 0, sizeof(CUSTOMVERTEX) ); //在后台缓冲区绘制图形 gpDevice->SetFVF( D3DFVF_CUSTOMVERTEX ); gpDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, NUMBERDUO ); SetupWorldMatrix(); //设置世界矩阵 gpDevice->SetStreamSource( 0, gpVb1, 0, sizeof(CUSTOMVERTEX) ); //在后台缓冲区绘制图形 gpDevice->SetFVF( D3DFVF_CUSTOMVERTEX ); gpDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, NUMBERDUO ); gpDevice->EndScene(); //结束在后台缓冲区绘制图形 } gpDevice->Present( NULL, NULL, NULL, NULL );}VOID Cleanup() //释放创建对象{ if( gpVb0 != NULL) gpVb0->Release(); //释放顶点缓冲区 if( gpVb1 != NULL) gpVb1->Release(); //释放顶点缓冲区 if( gpDevice != NULL) gpDevice->Release(); //释放D3D设备对象 if( gpD3D != NULL) gpD3D->Release(); //释放D3DD对象}LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParm, LPARAM lParam ) //消息处理函数{ switch( msg ) { case WM_DESTROY: Cleanup(); PostQuitMessage( 0 ); return 0; } return DefWindowProc( hWnd, msg, wParm, lParam );}INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT) //main函数{ WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, "ClassName",NULL}; RegisterClassEx( &wc ); //注册窗口类 HWND hWnd = CreateWindow( "ClassName", "zuijiandande3D", WS_OVERLAPPEDWINDOW, 200, 100, 600, 450, NULL, NULL, wc.hInstance, NULL ); //创建窗口 hWnd为窗口句柄 if( SUCCEEDED( InitD3D( hWnd ) ) ) { if( SUCCEEDED( InitGeometry() ) ) //创建场景图形 { ShowWindow( hWnd, SW_SHOWDEFAULT ); //显示窗口 UpdateWindow( hWnd ); MSG msg; //进入消息循环 ZeroMemory( &msg, sizeof(msg) ); while( msg.message != WM_QUIT ) { if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } else { Render(); } } } } UnregisterClass( "ClassName", wc.hInstance ); return 0;}
问题一:
当没有开启深度测试时为什么黑的三角形一直在白色三角形前面?
图片如下:
[img=http://C:\Documents and Settings\Administrator\
桌面\QQ截图20120502155145.jpg][/img]
[img=http://C:\Documents and Settings\Administrator\
桌面\QQ截图20120502155211.jpg][/img]
问题二:
当开启深度测试(将代码处有XXXXXX的两处地方取消注释)
时为什么显示不了正确的结果?我的结果如下:
[img=http://C:\Documents and Settings\Administrator\
桌面\QQ截图20120502155433.jpg][/img]
[解决办法]
错了,错了,后渲染黑的,所以黑的应该在前面