Hey guys,
I'm trying to render my scene using a vertex shader,to generate DIFFUSE lighting..
//vertex shadermatrix mat;vector lightPos;struct VS_INPUT{ vector position:POSITION; vector normal:NORMAL; float2 tex:TEXCOORD;};struct VS_OUTPUT{ vector position:POSITION; vector color:COLOR; float2 tex:TEXCOORD;};VS_OUTPUT VS(VS_INPUT input){ VS_OUTPUT output=(VS_OUTPUT)0; output.position=mul(input.position,mat); output.color = saturate(dot(lightPos, input.normal)); output.tex=input.tex; return output;}
and here is my main program,which renders a house and a role.
#include <windows.h>#include <windowsx.h>#include <d3d9.h>#include "SkinMesh.h"#include "Mesh.h"#include "Camera.h"// include the Direct3D Library file#pragma comment (lib, "d3d9.lib")// global declarationsLPDIRECT3D9 d3d; // the pointer to our Direct3D interfaceLPDIRECT3DDEVICE9 d3ddev; // the pointer to the device classCSkinMesh *Role;Mesh *House;CFPCamera *camera;IDirect3DVertexShader9 *shader=NULL;ID3DXConstantTable *constTable=NULL;D3DXHANDLE matHandle;D3DXHANDLE lightPosHANDLE;float m_x=0.0f;float m_y1=-3.0f;float m_y2=2.0f;float m_z1=4.5;float m_z2=0.0f;bool moveable=TRUE;bool Eattack=FALSE;// function prototypesvoid initD3D(HWND hWnd); // sets up and initializes Direct3Dvoid render_frame(void); // renders a single framevoid cleanD3D(void); // closes Direct3D and releases memoryvoid initLight(void);void initRole(void);void initHouse(void);void initCamera(void);BOOL hitTest(ID3DXMesh* pMesh, float XStart,float YStart,float ZStart, float XEnd,float YEnd,float ZEnd,float *Distance);float GetClosestHeight(ID3DXMesh* pMesh,float XPos,float YPos,float ZPos);float GetHeightAbove(ID3DXMesh* pMesh,float XPos,float YPos,float ZPos);float GetHeightBelow(ID3DXMesh* pMesh,float XPos,float YPos,float ZPos);// the WindowProc function prototypeLRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);// the entry point for any Windows programint WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){ HWND hWnd; WNDCLASSEX wc; ZeroMemory(&wc, sizeof(WNDCLASSEX)); wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WindowProc; wc.hInstance = hInstance; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)COLOR_WINDOW; wc.lpszClassName = "WindowClass"; RegisterClassEx(&wc); hWnd = CreateWindowEx(NULL, "WindowClass", "碰检实例-D3DXIntersect()", WS_OVERLAPPEDWINDOW, 0, 0, 1366, 768, NULL, NULL, hInstance, NULL); ShowWindow(hWnd, nCmdShow); // set up and initialize Direct3D initD3D(hWnd); initLight(); initRole(); initHouse(); // enter the main loop: MSG msg; while(TRUE) { while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } if(msg.message == WM_QUIT) break; render_frame(); } // clean up DirectX and COM cleanD3D(); return msg.wParam;}// this is the main message handler for the programLRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ switch(message) { case WM_DESTROY: { PostQuitMessage(0); return 0; } break; } return DefWindowProc (hWnd, message, wParam, lParam);}// this function initializes and prepares Direct3D for usevoid initD3D(HWND hWnd){ d3d = Direct3DCreate9(D3D_SDK_VERSION); // create the Direct3D interface D3DPRESENT_PARAMETERS d3dpp; // create a struct to hold various device information ZeroMemory(&d3dpp, sizeof(d3dpp)); // clear out the struct for use d3dpp.Windowed = TRUE; // program windowed, not fullscreen d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // discard old frames d3dpp.hDeviceWindow = hWnd; // set the window to be used by Direct3D d3dpp.EnableAutoDepthStencil=TRUE; d3dpp.AutoDepthStencilFormat=D3DFMT_D16; // create a device class using this information and the info from the d3dpp stuct d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); ID3DXBuffer* shaderBuf=NULL; ID3DXBuffer* errorBuf=NULL; D3DXCompileShaderFromFile("HLSL.txt", NULL, NULL, "VS", "vs_1_1", D3DXSHADER_DEBUG, &shaderBuf, &errorBuf, &constTable); if(errorBuf){ MessageBox(NULL, (char*)errorBuf->GetBufferPointer(), (char*)errorBuf->GetBufferSize(), MB_OK); } d3ddev->CreateVertexShader((DWORD*)shaderBuf->GetBufferPointer(), &shader); matHandle=constTable->GetConstantByName(0,"mat"); lightPosHANDLE=constTable->GetConstantByName(0,"lightPos"); constTable->SetDefaults(d3ddev); d3ddev->SetRenderState(D3DRS_LIGHTING,FALSE); d3ddev->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE ); d3ddev->SetRenderState( D3DRS_ZWRITEENABLE, TRUE ); d3ddev->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE,TRUE); d3ddev->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS,TRUE); d3ddev->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR); //线性过滤方式 d3ddev->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR); //线性过滤方式 d3ddev->SetSamplerState(0,D3DSAMP_MIPFILTER,D3DTEXF_LINEAR); //线性过滤方式 } // this is the function used to render a single framevoid render_frame(void){ // clear the window to a deep blue d3ddev->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(255, 255, 255), 1.0f, NULL); d3ddev->BeginScene(); // begins the 3D scene // Set up our view matrix. A view matrix can be defined given an eye point, // a point to lookat, and a direction for which way is up. Here, we set the // eye five units back along the z-axis and up three units, look at the // origin, and define "up" to be in the y-direction. D3DXVECTOR3 vEyePt( m_x, m_z1,m_y1 ); D3DXVECTOR3 vLookatPt( m_x, m_z2, m_y2 ); D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f ); D3DXMATRIXA16 matView; D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec ); d3ddev->SetTransform( D3DTS_VIEW, &matView ); // For the projection matrix, we set up a perspective transform (which // transforms geometry from 3D view space to 2D viewport space, with // a perspective divide making objects smaller in the distance). To build // a perpsective transform, we need the field of view (1/4 pi is common), // the aspect ratio, and the near and far clipping planes (which define at // what distances geometry should be no longer be rendered). D3DXMATRIXA16 matProj; D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f ); d3ddev->SetTransform( D3DTS_PROJECTION, &matProj ); D3DXMATRIX matVS; D3DXMATRIX matVieww,matWorldd,matProjj; d3ddev->GetTransform(D3DTS_VIEW,&matVieww); d3ddev->GetTransform(D3DTS_WORLD,&matWorldd); d3ddev->GetTransform(D3DTS_PROJECTION,&matProjj); matVS=matVieww*matWorldd*matProjj; constTable->SetMatrix(d3ddev,matHandle,&matVS); D3DXVECTOR4 lightPos; lightPos=D3DXVECTOR4(1.0f,1.0f,1.0f,0.0f); constTable->SetVector(d3ddev,lightPosHANDLE,&lightPos); d3ddev->SetVertexShader(shader); Role->Render(0.025f); House->render(); // do 3D rendering on the back buffer here if(::GetAsyncKeyState(VK_UP)&0x8000f){ if(moveable){ float YPos=GetClosestHeight(House->GetMesh(), 0.0f, -1.0f, 0.0f); Role->SetAltitude(YPos); if(hitTest(House->pMesh,Role->GetPosition()->x,1.0f, Role->GetPosition()->z, (float)cos(Role->m_fAngle), 1.0f, (float)sin(Role->m_fAngle), NULL) == TRUE) { //发生了碰撞,角色倒退 Role->Back(); } else { Role->m_fElapsedTime=0; Role->SetAnimationIndex(3); Role->WalkFoward(0.05f); m_y1=-4.0f+Role->GetPosition()->z; m_y2=1.0f+Role->GetPosition()->z; m_x=Role->GetPosition()->x; } } } else{ moveable=TRUE; Role->SetAnimationIndex(4); } if(::GetAsyncKeyState(VK_UP)&::GetAsyncKeyState(VK_SHIFT)&0x8000f){ if(moveable){ Role->m_fElapsedTime=0; Role->SetAnimationIndex(2); Role->WalkFoward(0.08f); m_y1=-4.0f+Role->GetPosition()->z; m_y2=1.0f+Role->GetPosition()->z; m_x=Role->GetPosition()->x; } } if(::GetAsyncKeyState(VK_LEFT)&0x8000f){ if(moveable){ Role->Turn(-0.1f); Role->SetAnimationIndex(3); m_x=Role->GetPosition()->x; } } if(::GetAsyncKeyState(VK_RIGHT)&0x8000f){ if(moveable){ Role->Turn(0.1f); Role->SetAnimationIndex(3); m_x=Role->GetPosition()->x; } } d3ddev->EndScene(); // ends the 3D scene d3ddev->Present(NULL, NULL, NULL, NULL); // displays the created frame on the screen}void initLight(){ D3DLIGHT9 d3dLight; ZeroMemory(&d3dLight,sizeof(D3DLIGHT9)); d3dLight.Type = D3DLIGHT_POINT;//D3DLIGHT_POINT,D3DLIGHT_SPOT d3dLight.Range = 1000; D3DCOLORVALUE color; color.a = 1; color.r = 255; color.g = 255; color.b = 255; d3dLight.Position = D3DXVECTOR3(0.0f,10.0f,-20.0f); d3dLight.Diffuse = color; d3dLight.Falloff = 0; d3dLight.Attenuation0 = 0; d3dLight.Attenuation1 = 0.5; d3dLight.Attenuation2 = 0; d3ddev->SetLight(0,&d3dLight); d3ddev->LightEnable(0,TRUE);}void initRole(){ Role=new CSkinMesh(d3ddev); Role->LoadFromXFile("hero.X"); Role->SetScale(0.03f); Role->Turn(0.0f); Role->SetAnimationIndex(4); Role->SetPosition(0.0f,0.0f,0.0); m_y1=-4.0f+Role->GetPosition()->z; m_y2=1.0f+Role->GetPosition()->z; m_x=Role->GetPosition()->x;}void initHouse(){ House=new Mesh("level.x",d3ddev);}void initCamera(){//还未完善}BOOL hitTest(ID3DXMesh* pMesh, float XStart,float YStart,float ZStart, float XEnd,float YEnd,float ZEnd,float *Distance)//碰检{ BOOL hit; float u,v,dist; float XDiff,YDiff,ZDiff,Size; DWORD FaceIndex; D3DXVECTOR3 vecPos; D3DXVECTOR3 vecDir; vecPos=D3DXVECTOR3(XStart,YStart,ZStart); XDiff=XEnd-XStart; YDiff=YEnd-YStart; ZDiff=ZEnd-ZStart; D3DXVec3Normalize(&vecDir,&D3DXVECTOR3(XDiff,YDiff,ZDiff)); D3DXMATRIX m,m_i; d3ddev->GetTransform(D3DTS_WORLD,&m); D3DXMatrixInverse(&m_i,NULL,&m); D3DXVec3TransformCoord(&vecPos,&vecPos,&m_i); D3DXVec3TransformNormal(&vecDir,&vecDir,&m_i); D3DXIntersect(pMesh, &vecPos,&vecDir, &hit,&FaceIndex,&u,&v,&dist, NULL,NULL); if(hit==TRUE){ if(dist<1.3f){ hit=TRUE; } else{ hit=FALSE; } } return hit;}//碰检函数float GetClosestHeight(ID3DXMesh* pMesh,float XPos,float YPos,float ZPos){ D3DXVECTOR3 vecPos=D3DXVECTOR3(XPos,YPos,ZPos); D3DXMATRIX m,m_i; d3ddev->GetTransform(D3DTS_WORLD,&m); D3DXMatrixInverse(&m_i,NULL,&m); D3DXVec3TransformCoord(&vecPos,&vecPos,&m_i); float YBelow,float YAbove; YBelow=GetHeightBelow(pMesh, vecPos.x,vecPos.y,vecPos.z); YAbove=GetHeightAbove(pMesh, vecPos.x,vecPos.y,vecPos.z); if(fabs(YBelow-vecPos.y)<fabs(YAbove-vecPos.y)) return YBelow; return YAbove;}float GetHeightBelow(ID3DXMesh* pMesh,float XPos,float YPos,float ZPos){ BOOL hit; float u,v,dist; DWORD faceIndex; D3DXIntersect(pMesh, &D3DXVECTOR3(XPos,YPos,ZPos), &D3DXVECTOR3(XPos,-1.0f,ZPos), &hit,&faceIndex,&u,&v,&dist,NULL,NULL); if(hit==TRUE) return YPos-dist; return YPos;}float GetHeightAbove(ID3DXMesh* pMesh,float XPos,float YPos,float ZPos){ BOOL hit; float u,v,dist; DWORD faceIndex; D3DXIntersect(pMesh, &D3DXVECTOR3(XPos,YPos,ZPos), &D3DXVECTOR3(XPos,1.0f,ZPos), &hit,&faceIndex,&u,&v,&dist,NULL,NULL); if(hit==TRUE) return YPos+dist; return YPos;}// this is the function that cleans up Direct3D and COMvoid cleanD3D(void){ House->free(); d3ddev->Release(); // close and release the 3D device d3d->Release(); // close and release Direct3D}
I run the program..it's totally a SHIT[sick],The scene's white,and there's a black figure in the scene...I don't know where's wrong..probably the lightPos?
Thanks for any reply[smile][smile][smile]