const Matrix4& Camera::GetProjMatrix( void ) { if (!m_projMatrixDirty) { return m_projMatrix; } MakeProjectionMatrix(m_projMatrix, m_nearClipDistance, m_farClipDistance, m_verticalFov, m_aspect); m_projMatrixDirty = false; return m_projMatrix; }
//--------------------------------------------------- void PrepareFor3DDrawing( IDirect3DDevice9 *pDevice, int viewport_width, int viewport_height, float fov_in_degrees, float near_clip, float far_clip, D3DXVECTOR3* pvEye, D3DXVECTOR3* pvLookat, D3DXVECTOR3* pvUp ) { // This function sets up DirectX up for 3D rendering. // Only call it once per frame, as it is VERY slow. // INPUTS: // pDevice a pointer to the D3D device // viewport_width the width of the client area of the window // viewport_height the height of the client area of the window // fov_in_degrees the field of view, in degrees // near_clip the distance to the near clip plane; should be > 0! // far_clip the distance to the far clip plane // eye the eyepoint coordinates, in world space // lookat the point toward which the eye is looking, in world space // up a vector indicating which dir. is up; usually <0,1,0> // // What this function does NOT do: // 1. set the current texture (SetTexture) // 2. set up the texture stages for texturing (SetTextureStageState) // 3. set the current vertex format (SetVertexShader) // 4. set up the world matrix (SetTransform(D3DTS_WORLD, &my_world_matrix)) // set up render state to some nice defaults: { // some defaults pDevice->SetRenderState( D3DRS_ZENABLE, TRUE ); pDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE ); pDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESSEQUAL ); pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); pDevice->SetRenderState( D3DRS_CLIPPING, TRUE ); pDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); pDevice->SetRenderState( D3DRS_COLORVERTEX, TRUE ); pDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD ); pDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID ); pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE ); // turn fog off pDevice->SetRenderState( D3DRS_FOGENABLE, FALSE ); pDevice->SetRenderState( D3DRS_RANGEFOGENABLE, FALSE ); // turn on high-quality bilinear interpolations pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); pDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); pDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); pDevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); pDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); pDevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); } // set up view & projection matrices (but not the world matrix!) { // if the window is not square, instead of distorting the scene, // clip it so that the longer dimension of the window has the // regular FOV, and the shorter dimension has a reduced FOV. float fov_x = fov_in_degrees * 3.1415927f/180.0f; float fov_y = fov_in_degrees * 3.1415927f/180.0f; float aspect = (float)viewport_height / (float)viewport_width; if (aspect < 1) fov_y *= aspect; else fov_x /= aspect; if (near_clip < 0.1f) near_clip = 0.1f; if (far_clip < near_clip + 1.0f) far_clip = near_clip + 1.0f; D3DXMATRIX proj; MakeProjectionMatrix(&proj, near_clip, far_clip, fov_x, fov_y); pDevice->SetTransform(D3DTS_PROJECTION, &proj); D3DXMATRIX view; pMatrixLookAtLH(&view, pvEye, pvLookat, pvUp); pDevice->SetTransform(D3DTS_VIEW, &view); // Optimization note: "You can minimize the number of required calculations // by concatenating your world and view matrices into a world-view matrix // that you set as the world matrix, and then setting the view matrix // to the identity." //D3DXMatrixMultiply(&world, &world, &view); //D3DXMatrixIdentity(&view); } }