void Matrix4x4::ArbAxisRotation(Vertex &rotVert, int degrees) { float radians = degrees * (float(PI)/180); rotVert.Normalize(); float xy = rotVert._x * rotVert._y; float xz = rotVert._x * rotVert._z; float yz = rotVert._y * rotVert._z; float xSq = rotVert._x * rotVert._x; float ySq = rotVert._y * rotVert._y; float zSq = rotVert._z * rotVert._z; float oneMincos = (1-cos(radians)); Matrix4x4 matRotate; matRotate.Identity(); matRotate._11 = xSq * oneMincos + cos(radians); matRotate._12 = xy * oneMincos + rotVert._z * sin(radians); matRotate._13 = xz * oneMincos - rotVert._y * sin(radians); matRotate._21 = xy * oneMincos - rotVert._z * sin(radians); matRotate._22 = ySq * oneMincos + cos(radians); matRotate._23 = yz * oneMincos + rotVert._x * sin(radians); matRotate._31 = xz * oneMincos + rotVert._y * sin(radians); matRotate._32 = yz * oneMincos - rotVert._x * sin(radians); matRotate._33 = zSq * oneMincos + cos(radians); Transformation(matRotate); }
bool InitResourceDX9(void) { g_orient_matrix.Identity(); LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); if ( !ReInitResourceDX9() ) return false; g_pPostEffect = GutLoadFXShaderDX9("../../shaders/Posteffect.fx"); if ( NULL==g_pPostEffect ) return false; g_pWaterEffect = GutLoadFXShaderDX9("../../shaders/Watereffect.fx"); if ( NULL==g_pWaterEffect ) return false; g_pWaterTexture = GutLoadTexture_DX9("../../textures/lena.tga"); if ( NULL==g_pWaterTexture ) return false; g_Model_DX9.ConvertToDX9Model(&g_Model); return true; }
Matrix4x4 View( Vector3 viewerPosition, Vector3 viewerDirection, Vector3 upVector ) { Matrix4x4 result; Vector3 zAxis( viewerDirection - viewerPosition ); zAxis.Normalise(); Vector3 xAxis( CrossProduct( upVector, zAxis ) ); xAxis.Normalise(); Vector3 yAxis( CrossProduct( zAxis, xAxis ) ); result.Identity(); result.m[0][0] = xAxis.x; result.m[1][0] = yAxis.x; result.m[2][0] = zAxis.x; result.m[0][1] = xAxis.y; result.m[1][1] = yAxis.y; result.m[2][1] = zAxis.y; result.m[0][2] = xAxis.z; result.m[1][2] = yAxis.z; result.m[2][2] = zAxis.z; result.m[0][3] = -DotProduct( xAxis, viewerPosition ); result.m[1][3] = -DotProduct( yAxis, viewerPosition ); result.m[2][3] = -DotProduct( zAxis, viewerPosition ); result.m[3][3] = 1; return result; }
static void AddImpulse(void) { static Vector4 vPosition(0.0f, 0.0f, 0.0f, 0.0f); //Vector4 vDiff = vPosition - g_vPosition; Vector4 vDiff = g_vPosition - vPosition; Vector4 vLength = vDiff.Length(); if ( vLength[0]<2.0f ) return; Vector4 vDir = vDiff / vLength; Vector4 vVec0(vDir[1],-vDir[0], 0.0f, 0.0f); Vector4 vVec1(vDir[0], vDir[1], 0.0f, 0.0f); vPosition = g_vPosition; Vector4 vVec0_old = g_orient_matrix[0]; Vector4 vVec1_old = g_orient_matrix[1]; Vector4 vVec0_new = VectorLerp(vVec0_old, vVec0, 0.2f); Vector4 vVec1_new = VectorLerp(vVec1_old, vVec1, 0.2f); vVec0_new.Normalize(); vVec1_new.Normalize(); Vector4 vVec2_new = Vector3CrossProduct(vVec0_new, vVec1_new); g_orient_matrix.Identity(); g_orient_matrix[0] = vVec0_new; g_orient_matrix[1] = vVec1_new; g_orient_matrix[2] = vVec2_new; LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); device->SetRenderTarget(0, g_pSurfaces[TEX_HEIGHT1]); device->SetDepthStencilSurface(NULL); Matrix4x4 view_matrix = g_Control.GetViewMatrix(); Matrix4x4 world_matrix; world_matrix.Scale_Replace(g_fRippleSize, g_fRippleSize, 1.0f); world_matrix[3] = g_vPosition; Matrix4x4 wvp_matrix = g_orient_matrix * world_matrix * view_matrix * g_proj_matrix; D3DXHANDLE shader = g_pWaterEffect->GetTechniqueByName("AddImpulse"); D3DXHANDLE wvp_matrix_var = g_pWaterEffect->GetParameterByName(NULL, "wvp_matrix"); D3DXHANDLE force_var = g_pWaterEffect->GetParameterByName(NULL, "fForce"); g_pWaterEffect->SetTechnique(shader); g_pWaterEffect->SetMatrix(wvp_matrix_var, (D3DXMATRIX *)&wvp_matrix); g_pWaterEffect->SetFloat(force_var, 0.05f); g_pWaterEffect->Begin(NULL, 0); g_pWaterEffect->BeginPass(0); g_Model_DX9.Render(0); g_pWaterEffect->EndPass(); g_pWaterEffect->End(); vPosition = g_vPosition; }
Matrix4x4 Position( float x, float y, float z ) { Matrix4x4 result; result.Identity(); result.m[0][3] = x; result.m[1][3] = y; result.m[2][3] = z; return result; }
Matrix4x4 Roll( float roll ) { Matrix4x4 result; result.Identity(); result.m[0][0] = result.m[1][1] = cosf( roll ); result.m[1][0] = -sinf( roll ); result.m[0][1] = sinf( roll ); result.m[2][2] = result.m[3][3] = 1; return result; }
Matrix4x4 Yaw( float yaw ) { Matrix4x4 result; result.Identity(); result.m[0][0] = result.m[2][2] = cosf( yaw ); result.m[2][0] = -sinf( yaw ); result.m[0][2] = sinf( yaw ); result.m[1][1] = result.m[3][3] = 1; return result; }
Matrix4x4 Pitch( float pitch ) { Matrix4x4 result; result.Identity(); result.m[1][1] = result.m[2][2] = cosf( pitch ); result.m[1][2] = -sinf( pitch ); result.m[2][1] = sinf( pitch ); result.m[0][0] = result.m[3][3] = 1; return result; }
void Matrix4x4::YAxisRotation(float degrees) { float radians = degrees * (float(PI)/180); Matrix4x4 matRotate; matRotate.Identity(); matRotate.SetMatrix(cos(radians), 0.0f, -sin(radians), 0.0f, 1.0f, 0.0f, sin(radians), 0, cos(radians)); Transformation(matRotate); }
void ModelViewerRender::RenderAttachments() { for(uint32 i=0;i<m_pModelMF1->m_Header.m_iNumAttc;++i) { Matrix4x4 matrix; uint32 nBoneCount=m_pModelMF1->m_iNumBones; uint32 boneID=m_pModelMF1->m_pAttachTags[i].m_iAttachBoneID; if(m_pDynamicModel!=NULL) { if(boneID>=nBoneCount) continue; float* pBuffer=m_pDynamicModel->getBonesMatrix(); Matrix4x4 boneMatrix; boneMatrix.Identity(); boneMatrix._11=pBuffer[12*boneID]; boneMatrix._21=pBuffer[12*boneID+1]; boneMatrix._31=pBuffer[12*boneID+2]; boneMatrix._41=pBuffer[12*boneID+3]; boneMatrix._12=pBuffer[12*boneID+4]; boneMatrix._22=pBuffer[12*boneID+5]; boneMatrix._32=pBuffer[12*boneID+6]; boneMatrix._42=pBuffer[12*boneID+7]; boneMatrix._13=pBuffer[12*boneID+8]; boneMatrix._23=pBuffer[12*boneID+9]; boneMatrix._33=pBuffer[12*boneID+10]; boneMatrix._43=pBuffer[12*boneID+11]; matrix=m_pModelMF1->m_pAttachTags[i].m_InitMatTag*boneMatrix*m_pDynamicModel->getModelMatrix(); } if(m_pStaticModel!=NULL) { matrix=m_pModelMF1->m_pAttachTags[i].m_InitMatTag*m_pStaticModel->getModelMatrix(); } if(m_pStaticModel!=NULL||m_pDynamicModel!=NULL) { AABBox aabox=m_pModelMF1->m_MeshAABBox; float length=(aabox.vcMax-aabox.vcMin).GetLength(); length/=100.0f; AABBox box; box.vcCenter.x=matrix._41; box.vcCenter.y=matrix._42; box.vcCenter.z=matrix._43; box.vcMin.x=box.vcCenter.x-length; box.vcMin.y=box.vcCenter.y-length; box.vcMin.z=box.vcCenter.z-length; box.vcMax.x=box.vcCenter.x+length; box.vcMax.y=box.vcCenter.y+length; box.vcMax.z=box.vcCenter.z+length; m_pRenderDevice->GetVertexCacheManager()->RenderBox(box,Colour(0,255,0)); // m_pRenderDevice->GetVertexCacheManager()->RenderDetailSphere(Vector3D(matrix._41,matrix._42,matrix._43),length/100.0f,5,5,Colour(255,255,0)); } } }
// 使用DirectX 9來繪圖 void RenderFrameDX9(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); // 開始下繪圖指令 device->BeginScene(); // 設定資料格式 device->SetFVF(D3DFVF_XYZ|D3DFVF_TEX1); //device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x0, 1.0f, 0); { Matrix4x4 IdentityMatrix; IdentityMatrix.Identity(); device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *) &IdentityMatrix); device->SetTransform(D3DTS_VIEW, (D3DMATRIX *) &IdentityMatrix); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &IdentityMatrix); device->SetTexture(0, g_pTexture0); // ZBuffer測試條件設為永遠成立 device->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); // 畫出矩形, 同時會清除ZBuffer device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, g_FullScreenQuad, sizeof(Vertex_VT)); // ZBuffer測試條件設為小於 device->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS); } { device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *) &g_projection_matrix); // 鏡頭座標系轉換矩陣 Matrix4x4 view_matrix = GutMatrixLookAtRH(g_eye, g_lookat, g_up); device->SetTransform(D3DTS_VIEW, (D3DMATRIX *) &view_matrix); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &g_world_matrix); device->SetTexture(0, g_pTexture1); // 開啟混色功能 device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); // source_blend_factor = 1 device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); // dest_blend_factor = 1 device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); // 混色公式 = source_color * 1 + dest_color * 1 // 畫出矩形 device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, g_Quad, sizeof(Vertex_VT)); // 關閉Alpha Test功能 device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); } // 宣告所有的繪圖指令都下完了 device->EndScene(); // 把背景backbuffer的畫面呈現出來 device->Present( NULL, NULL, NULL, NULL ); }
Matrix4x4 Perspective( float fov, float aspectRatio, float fNear, float fFar ) { Matrix4x4 result; float yScale = ( 1 / tan( fov / 2 ) ); // cot( fov / 2 ) float xScale = yScale / aspectRatio; result.Identity(); result.m[0][0] = xScale; result.m[1][1] = yScale; result.m[2][2] = fFar / ( fFar - fNear ); result.m[2][3] = ( -fNear * fFar) / ( fFar - fNear ); result.m[3][2] = 1; result.m[3][3] = 0; return result; }
void ModelViewerRender::RenderParticleEmitter() { for(uint32 i=0;i<m_pModelMF1->m_Header.m_iNumParticles;++i) { Matrix4x4 matrix; uint32 nBoneCount=m_pModelMF1->m_iNumBones; uint32 boneID=m_pModelMF1->m_pParticleEmitter[i].m_iAttachBoneID; // if(boneID>=nBoneCount) continue; if(m_pDynamicModel!=NULL) { float* pBuffer=m_pDynamicModel->getBonesMatrix(); Matrix4x4 boneMatrix; boneMatrix.Identity(); boneMatrix._11=pBuffer[12*boneID]; boneMatrix._21=pBuffer[12*boneID+1]; boneMatrix._31=pBuffer[12*boneID+2]; boneMatrix._41=pBuffer[12*boneID+3]; boneMatrix._12=pBuffer[12*boneID+4]; boneMatrix._22=pBuffer[12*boneID+5]; boneMatrix._32=pBuffer[12*boneID+6]; boneMatrix._42=pBuffer[12*boneID+7]; boneMatrix._13=pBuffer[12*boneID+8]; boneMatrix._23=pBuffer[12*boneID+9]; boneMatrix._33=pBuffer[12*boneID+10]; boneMatrix._43=pBuffer[12*boneID+11]; matrix=m_pModelMF1->m_pParticleEmitter[i].m_AbsoluteMatrix*boneMatrix*m_pDynamicModel->getModelMatrix(); } if(m_pStaticModel!=NULL) { matrix=m_pModelMF1->m_pParticleEmitter[i].m_AbsoluteMatrix*m_pStaticModel->getModelMatrix(); } if(m_pStaticModel!=NULL||m_pDynamicModel!=NULL) { AABBox aabox=m_pModelMF1->m_MeshAABBox; float length=(aabox.vcMax-aabox.vcMin).GetLength(); length*=0.02f; if((int)(i+1)==ModelViewerConfig::GetInstance()->m_nCurrSelParticle) m_pRenderDevice->GetVertexCacheManager()->RenderCone(matrix,length,-length,4,Colour(255,0,0)); else m_pRenderDevice->GetVertexCacheManager()->RenderCone(matrix,length,-length,4,Colour(255,255,255)); } } }
Matrix4x4 Matrix4x4::ConstructCameraView(const Vector& vecPosition, const Vector& vecDirection, const Vector& vecUp) { Matrix4x4 m; m.Identity(); TAssertNoMsg(fabs(vecDirection.LengthSqr()-1) < 0.0001f); Vector vecCamSide = vecDirection.Cross(vecUp).Normalized(); Vector vecCamUp = vecCamSide.Cross(vecDirection); m.SetForwardVector(Vector(vecCamSide.x, vecCamUp.x, -vecDirection.x)); m.SetLeftVector(Vector(vecCamSide.y, vecCamUp.y, -vecDirection.y)); m.SetUpVector(Vector(vecCamSide.z, vecCamUp.z, -vecDirection.z)); m.AddTranslation(-vecPosition); return m; }
Matrix4x4 Matrix4x4::ProjectOrthographic(float flLeft, float flRight, float flBottom, float flTop, float flNear, float flFar) { Matrix4x4 m; m.Identity(); float flXD = flRight - flLeft; float flYD = flTop - flBottom; float flZD = flFar - flNear; m.m[0][0] = 2.0f / flXD; m.m[1][1] = 2.0f / flYD; m.m[2][2] = -2.0f / flZD; m.m[3][0] = -(flRight + flLeft) / flXD; m.m[3][1] = -(flTop + flBottom) / flYD; m.m[3][2] = -(flFar + flNear) / flZD; return m; }
Matrix4x4 Matrix4x4::ProjectFrustum(float flLeft, float flRight, float flBottom, float flTop, float flNear, float flFar) { Matrix4x4 m; m.Identity(); float flXD = flRight - flLeft; float flYD = flTop - flBottom; float flZD = flFar - flNear; m.m[0][0] = (2 * flNear) / flXD; m.m[1][1] = (2 * flNear) / flYD; m.m[2][0] = (flRight + flLeft) / flXD; m.m[2][1] = (flTop + flBottom) / flYD; m.m[2][2] = -(flFar + flNear) / flZD; m.m[2][3] = -1; m.m[3][2] = -(2 * flFar * flNear) / flZD; m.m[3][3] = 0; return m; }
Matrix4x4 ConvertToMatrix4x4( Quaternion &a ) { Matrix4x4 result; result.Identity(); result.m[0][0] = 1 - 2 * a.y * a.y - 2 * a.z * a.z; result.m[1][0] = 2 * a.x * a.y + 2 * a.z * a.w; result.m[2][0] = 2 * a.x * a.z - 2 * a.y * a.w; //result.m[3][0] = 0; result.m[0][1] = 2 * a.x * a.y - 2 * a.z * a.w; result.m[1][1] = 1 - 2 * a.x * a.x - 2 * a.z * a.z; result.m[2][1] = 2 * a.y * a.z + 2 * a.x * a.w; //result.m[3][1] = 0; result.m[0][2] = 2 * a.x * a.z + 2 * a.y * a.w; result.m[1][2] = 2 * a.y * a.z - 2 * a.x * a.w; result.m[2][2] = 1 - 2 * a.x * a.x - 2 * a.y * a.y; //result.m[3][2] = 0; //result.m[0][3] = 0; //result.m[1][3] = 0; //result.m[2][3] = 0; //result.m[3][3] = 0; return result; }
void COpenGLES2GrassRenderer::render(CSGPGrass* pGrass) { SGPVertex_GRASS_GLES2 tempData; if( m_GrassClusterInstanceArray.size() > 0 ) { COpenGLES2GrassRenderer::Sorter CompareGrassInstance(m_pRenderDevice); m_GrassClusterInstanceArray.sort(CompareGrassInstance); uint32 nGrassClusterNum = jmin(m_GrassClusterInstanceArray.size(), INIT_GRASSCLUSTERINSTANCE_NUM); uint32 nSizeData = sizeof(SGPVertex_GRASS_GLES2) * nGrassClusterNum * (4*3); uint32 nVBOffset = (m_GrassClusterInstanceArray.size() <= INIT_GRASSCLUSTERINSTANCE_NUM) ? 0 : m_GrassClusterInstanceArray.size() - INIT_GRASSCLUSTERINSTANCE_NUM; SGPVertex_GRASS_Cluster* pGrassClusterSrc = m_GrassClusterInstanceArray.getRawDataPointer() + nVBOffset; // update Dynamic Grass Instance Buffer glBindBuffer(GL_ARRAY_BUFFER, m_nGrassClusterVBOID); glBufferData(GL_ARRAY_BUFFER, nSizeData, NULL, GL_STREAM_DRAW); SGPVertex_GRASS_GLES2* pGrassVertex = (SGPVertex_GRASS_GLES2*)m_pRenderDevice->extGlMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES); for( uint32 i=0; i<nGrassClusterNum; i++ ) { tempData.vNormal[0] = ( pGrassClusterSrc[i].vPackedNormal[0] / 255.0f - 0.5f ) * 2.0f; tempData.vNormal[1] = ( pGrassClusterSrc[i].vPackedNormal[1] / 255.0f - 0.5f ) * 2.0f; tempData.vNormal[2] = ( pGrassClusterSrc[i].vPackedNormal[2] / 255.0f - 0.5f ) * 2.0f; tempData.vNormal[3] = pGrassClusterSrc[i].vPackedNormal[3] / 255.0f; tempData.vColor[0] = pGrassClusterSrc[i].vColor[0]; tempData.vColor[1] = pGrassClusterSrc[i].vColor[1]; tempData.vColor[2] = pGrassClusterSrc[i].vColor[2]; tempData.vColor[3] = pGrassClusterSrc[i].vColor[3]; tempData.LMtu = pGrassClusterSrc[i].vPosition[0] / m_pRenderDevice->GetWorldSystemManager()->getTerrain()->GetTerrainWidth(); tempData.LMtv = 1.0f - pGrassClusterSrc[i].vPosition[2] / m_pRenderDevice->GetWorldSystemManager()->getTerrain()->GetTerrainWidth(); Matrix4x4 RotMatrix; RotMatrix.Identity(); if( pGrassClusterSrc[i].vPackedNormal[1] < 250 ) { Vector3D vTerrainNormal(tempData.vNormal[0], tempData.vNormal[1], tempData.vNormal[2]); vTerrainNormal.Normalize(); float cost = tempData.vNormal[1]; Vector3D v; v.Cross( Vector3D(0,1,0), vTerrainNormal ); v.Normalize(); float sint = std::sqrt(1-cost*cost); float one_sub_cost = 1 - cost; RotMatrix._11 = v.x * v.x * one_sub_cost + cost; RotMatrix._12 = v.x * v.y * one_sub_cost + v.z * sint; RotMatrix._13 = v.x * v.z * one_sub_cost - v.y * sint; RotMatrix._21 = v.x * v.y * one_sub_cost - v.z * sint; RotMatrix._22 = v.y * v.y * one_sub_cost + cost; RotMatrix._23 = v.y * v.z * one_sub_cost + v.x * sint; RotMatrix._31 = v.x * v.z * one_sub_cost + v.y * sint; RotMatrix._32 = v.y * v.z * one_sub_cost - v.x * sint; RotMatrix._33 = v.z * v.z * one_sub_cost + cost; } for( uint32 j=0; j<4*3; j++ ) { tempData.tu = m_grassVertex[j].tu; tempData.tv = m_grassVertex[j].tv; Vector3D modelPos = Vector3D(m_grassVertex[j].x, m_grassVertex[j].y, m_grassVertex[j].z) * tempData.vNormal[3] * RotMatrix; modelPos += Vector3D(pGrassClusterSrc[i].vPosition[0], pGrassClusterSrc[i].vPosition[1], pGrassClusterSrc[i].vPosition[2]); float windAngle = m_vTimeParams.x * m_vTimeParams.y * Vector3D(pGrassClusterSrc[i].vPosition[0], pGrassClusterSrc[i].vPosition[1], pGrassClusterSrc[i].vPosition[2]).GetLength(); Vector3D vCosSin = Vector3D( std::cos(windAngle), 0, std::sin(windAngle) ); Vector3D vOffset( pGrassClusterSrc[i].vWindParams[0] * m_vWindDirForce.x * m_vWindDirForce.w, pGrassClusterSrc[i].vWindParams[1] * m_vWindDirForce.y * m_vWindDirForce.w, pGrassClusterSrc[i].vWindParams[2] * m_vWindDirForce.z * m_vWindDirForce.w ); vOffset.x += vCosSin.x * pGrassClusterSrc[i].vWindParams[0] * m_vWindDirForce.w; vOffset.y += vCosSin.y * pGrassClusterSrc[i].vWindParams[1] * m_vWindDirForce.w; vOffset.z += vCosSin.z * pGrassClusterSrc[i].vWindParams[2] * m_vWindDirForce.w; Vector3D vv = Vector3D(tempData.vNormal[0], tempData.vNormal[1], tempData.vNormal[2]) + vOffset; vv.Normalize(); modelPos += vv * tempData.vNormal[3] * (1.0f - tempData.tv); tempData.vPosition[0] = modelPos.x; tempData.vPosition[1] = modelPos.y; tempData.vPosition[2] = modelPos.z; tempData.vPosition[3] = pGrassClusterSrc[i].vPosition[3]; (*pGrassVertex) = tempData; pGrassVertex++; } } m_pRenderDevice->extGlUnmapBuffer(GL_ARRAY_BUFFER); } m_vTextureAtlas.Set( pGrass->m_fTextureAtlasNbX, pGrass->m_fTextureAtlasNbY, pGrass->m_fTextureAtlasW, pGrass->m_fTextureAtlasH ); }
void RenderFrameDX10(void) { Vector4 vClearColor(0.4f, 0.4f, 0.4f, 1.0f); // frame buffer ID3D10RenderTargetView *pRenderTargetView = GutGetDX10RenderTargetView(); // depth/stencil buffer ID3D10DepthStencilView *pDepthStencilView = GutGetDX10DepthStencilView(); // front/back buffer IDXGISwapChain *pSwapChain = GutGetDX10SwapChain(); // `清除顏色` g_pDevice->ClearRenderTargetView(pRenderTargetView, (float *)&vClearColor); // `清除`Depth/Stencil buffer g_pDevice->ClearDepthStencilView(pDepthStencilView, D3D10_CLEAR_DEPTH | D3D10_CLEAR_STENCIL, 1.0f, 0); Vector4 camera_lookat(0.0f, 0.0f, 0.0f); int w, h; GutGetWindowSize(w, h); Matrix4x4 view_matrix; Matrix4x4 ortho_proj = GutMatrixOrthoRH_DirectX(20.0f, 20.0f, 0.1f, 100.0f); // `前視圖` { D3D10_VIEWPORT vp = {0, 0, w/2, h/2, 0.0f, 1.0f}; g_pDevice->RSSetViewports(1, &vp); // view matrix Vector4 camera_pos(0.0f, -20.0f, 0.0f); Vector4 camera_up(0.0f, 0.0f, 1.0f); view_matrix = GutMatrixLookAtRH(camera_pos, camera_lookat, camera_up); // render objects RenderSolarSystemDX10(view_matrix, ortho_proj); } // `上視圖` { D3D10_VIEWPORT vp = {w/2, 0, w/2, h/2, 0.0f, 1.0f}; g_pDevice->RSSetViewports(1, &vp); // view matrix Vector4 camera_pos(0.0f, 0.0f, 20.0f); Vector4 camera_up(0.0f, 1.0f, 0.0f); view_matrix = GutMatrixLookAtRH(camera_pos, camera_lookat, camera_up); // render objects RenderSolarSystemDX10(view_matrix, ortho_proj); } // `右視圖` { D3D10_VIEWPORT vp = {0, h/2, w/2, h/2, 0.0f, 1.0f}; g_pDevice->RSSetViewports(1, &vp); // view matrix Vector4 camera_pos(20.0f, 0.0f, 0.0f); Vector4 camera_up(0.0f, 0.0f, 1.0f); view_matrix = GutMatrixLookAtRH(camera_pos, camera_lookat, camera_up); // render objects RenderSolarSystemDX10(view_matrix, ortho_proj); } // `使用者視角` { D3D10_VIEWPORT vp = {w/2, h/2, w/2, h/2, 0.0f, 1.0f}; g_pDevice->RSSetViewports(1, &vp); // view matrix Matrix4x4 view_matrix = g_Control.GetViewMatrix(); Matrix4x4 object_matrix = g_Control.GetObjectMatrix(); view_matrix = object_matrix * view_matrix; // render objects RenderSolarSystemDX10(view_matrix, g_proj_matrix); } // `畫邊線` { UINT stride = sizeof(Vertex_VC); UINT offset = 0; D3D10_VIEWPORT vp = {0, 0, w, h, 0.0f, 1.0f}; g_pDevice->RSSetViewports(1, &vp); // `設定`vertex shader g_pDevice->VSSetShader(g_pVertexShader); // `設定`pixel shader g_pDevice->PSSetShader(g_pPixelShader); // `設定vertex shader讀取參數的記憶體位置` g_pDevice->VSSetConstantBuffers(0, 1, &g_pConstantBuffer); Matrix4x4 *pConstData; g_pConstantBuffer->Map( D3D10_MAP_WRITE_DISCARD, NULL, (void **) &pConstData ); pConstData->Identity(); g_pConstantBuffer->Unmap(); g_pDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_LINELIST); g_pDevice->IASetVertexBuffers(0, 1, &g_pBorderVertexBuffer, &stride, &offset); g_pDevice->Draw(4, 0); } // `等待硬體掃結束, 然後才更新畫面.` pSwapChain->Present(1, 0); }
void RenderFrameDX10(void) { Vector4 vClearColor(0.0f, 0.0f, 0.0f, 0.0f); float fDummy[4] = {0,0,0,0}; UINT stride = sizeof(Vertex_VT); UINT offset = 0; //frame buffer ID3D10RenderTargetView *pRenderTargetView = GutGetDX10RenderTargetView(); //depth/stencil buffer ID3D10DepthStencilView *pDepthStencilView = GutGetDX10DepthStencilView(); // front/back buffer chain IDXGISwapChain *pSwapChain = GutGetDX10SwapChain(); // 清除顏色 g_pDevice->ClearRenderTargetView(pRenderTargetView, (float *)&vClearColor); // 清除Depth/Stencil buffer g_pDevice->ClearDepthStencilView(pDepthStencilView, D3D10_CLEAR_DEPTH | D3D10_CLEAR_STENCIL, 1.0f, 0); // 設定vertex shader g_pDevice->VSSetShader(g_pVertexShader); // 設定pixel shader g_pDevice->PSSetShader(g_pPixelShader); // 設定vertex shader讀取參數的記憶體位罝 g_pDevice->VSSetConstantBuffers(0, 1, &g_pConstantBuffer); // 設定vertex資料格式 g_pDevice->IASetInputLayout(g_pVertexLayout); // 設定vertex buffer g_pDevice->IASetVertexBuffers(0, 1, &g_pVertexBuffer, &stride, &offset); // 設定三角形頂點索引值資料排列是triangle strip g_pDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); // 畫墻壁 { Matrix4x4 IdentityMatrix; IdentityMatrix.Identity(); // 更新shader參數 Matrix4x4 *pConstData; g_pConstantBuffer->Map( D3D10_MAP_WRITE_DISCARD, NULL, (void **) &pConstData ); *pConstData = IdentityMatrix; g_pConstantBuffer->Unmap(); // 把混色關閉 g_pDevice->OMSetBlendState(NULL, fDummy, 0xff); // 把墻壁所填充的像素 Stencil 值設定 1, 最後一個參數是 Stencil 參考值. g_pDevice->OMSetDepthStencilState(g_pStencilState_Replace, 1); // 套用貼圖 g_pDevice->PSSetShaderResources(0, 1, &g_pTexture0); // 畫出墻壁 g_pDevice->Draw(4, 0); } // 畫手電筒光源 { // 計算矩陣 //Matrix4x4 view_proj_matrix = g_view_matrix * g_proj_matrix; Matrix4x4 world_view_proj_matrix = g_world_matrix * g_view_matrix * g_proj_matrix; // 更新shader參數 Matrix4x4 *pConstData; g_pConstantBuffer->Map( D3D10_MAP_WRITE_DISCARD, NULL, (void **) &pConstData ); *pConstData = world_view_proj_matrix; g_pConstantBuffer->Unmap(); // 使用加色混色 g_pDevice->OMSetBlendState(g_pBlendState, fDummy, 0xff); // 把墻壁所填充的像素Stencil值設定1 if ( g_bStencil ) g_pDevice->OMSetDepthStencilState(g_pStencilState_Test, 1); else g_pDevice->OMSetDepthStencilState(NULL, 1); // 套用貼圖 g_pDevice->PSSetShaderResources(0, 1, &g_pTexture1); // 畫出光點 g_pDevice->Draw(4, 0); } // 等待硬體掃結束, 然後才更新畫面. pSwapChain->Present(1, 0); }
// 使用DirectX 9來繪圖 void RenderFrameDX9(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); Vector4 vPlane(0.0f, 0.0f, 1.0f, -g_mirror_z); // 開始下繪圖指令 device->BeginScene(); { LPDIRECT3DSURFACE9 pFrameBufferBackup, pDepthBufferBackup; device->GetRenderTarget(0, &pFrameBufferBackup); pFrameBufferBackup->Release(); device->GetDepthStencilSurface(&pDepthBufferBackup); pDepthBufferBackup->Release(); LPDIRECT3DSURFACE9 pSurface; g_pTexture->GetSurfaceLevel(0, &pSurface); device->SetRenderTarget(0, pSurface); device->SetDepthStencilSurface(g_pDepthStencil); device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(0, 0, 200, 255), 1.0f, 0); RenderModelDX9(true, &vPlane); pSurface->Release(); device->SetRenderTarget(0, pFrameBufferBackup); device->SetDepthStencilSurface(pDepthBufferBackup); } // 把上一個步驟的結果當成貼圖來使用 { // 消除畫面 device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(0, 0, 150, 255), 1.0f, 0); RenderModelDX9(false, NULL); Matrix4x4 identMat; identMat.Identity(); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &identMat); sModelMaterial_DX9 material; material.m_pTextures[0] = g_pTexture; material.Submit(); device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); device->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); device->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); device->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_NONE); Matrix4x4 uv_offset_matrix; uv_offset_matrix.Scale_Replace(0.5f, -0.5f, 1.0f); uv_offset_matrix[3].Set(0.5f, 0.5f, 0.5f, 1.0f); Matrix4x4 inv_view_matrix = g_Control.GetViewMatrix(); inv_view_matrix.FastInvert(); Matrix4x4 texture_matrix = inv_view_matrix * g_mirror_view_matrix * g_projection_matrix * uv_offset_matrix; device->SetTransform(D3DTS_TEXTURE0, (D3DMATRIX *) &texture_matrix); device->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); // D3DTTFF_PROJECTED告知direct3d裝置texcoord需要除以w device->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED); float v[12]; for ( int i=0; i<4; i++ ) { g_Quad[i].m_Position.StoreXYZ(&v[i*3]); } // 畫出矩形 device->SetFVF(D3DFVF_XYZ); //device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, g_Quad, sizeof(Vertex_V)); device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, 12); } // 宣告所有的繪圖指令都下完了 device->EndScene(); // 把背景backbuffer的畫面呈現出來 device->Present( NULL, NULL, NULL, NULL ); }
void ModelViewerRender::RenderBones() { if(m_pModelMF1==NULL) return ; // const float boneOffset[3]={0.05f,0.05f,0.05f}; const float boneOffset[3]={0.0f,0.0f,0.0f}; uint32 nBoneCount=m_pModelMF1->m_iNumBones; SGPMF1Bone* pBones=m_pModelMF1->m_pBones; float* pBoneMatrixs=m_pDynamicModel->getBonesMatrix(); SGPVertex_UPOS_VERTEXCOLOR vertex[2]; SetVertexColor(vertex[0],1.0f,1.0f,1.0f,1.0f); SetVertexColor(vertex[1],1.0f,1.0f,1.0f,1.0f); for(uint32 i=0;i<nBoneCount;++i) { uint32 childCount=pBones[i].m_iNumChildId; if(childCount!=0) { Matrix4x4 matFrame0; matFrame0.InverseOf(pBones[i].m_matFrame0Inv); Matrix4x4 matAnimation; matAnimation.Identity(); matAnimation._11=pBoneMatrixs[12*i]; matAnimation._21=pBoneMatrixs[12*i+1]; matAnimation._31=pBoneMatrixs[12*i+2]; matAnimation._41=pBoneMatrixs[12*i+3]; matAnimation._12=pBoneMatrixs[12*i+4]; matAnimation._22=pBoneMatrixs[12*i+5]; matAnimation._32=pBoneMatrixs[12*i+6]; matAnimation._42=pBoneMatrixs[12*i+7]; matAnimation._13=pBoneMatrixs[12*i+8]; matAnimation._23=pBoneMatrixs[12*i+9]; matAnimation._33=pBoneMatrixs[12*i+10]; matAnimation._43=pBoneMatrixs[12*i+11]; Matrix4x4 matOrigin=matFrame0*matAnimation*m_pDynamicModel->getModelMatrix(); // SetVertexPos(vertex[0],matOrigin._41+0.05f,matOrigin._42+0.05f,matOrigin._43+0.05f); SetVertexPos(vertex[0],matOrigin._41+boneOffset[0],matOrigin._42+boneOffset[1],matOrigin._43+boneOffset[2]); if(pBones[i].m_sParentID==0xFFFF) { AABBox aabox=m_pModelMF1->m_MeshAABBox; float length=(aabox.vcMax-aabox.vcMin).GetLength()/150.0f; m_pRenderDevice->GetVertexCacheManager()->RenderDetailSphere(Vector3D(matOrigin._41+boneOffset[0],\ matOrigin._42+boneOffset[1],matOrigin._43+boneOffset[2]),length,5,5,Colour(255,255,255)); } for(uint32 j=0;j<childCount;++j) { uint16 index=pBones[i].m_ChildIds[j]; matFrame0.InverseOf(pBones[index].m_matFrame0Inv); matAnimation.Identity(); matAnimation._11=pBoneMatrixs[12*index]; matAnimation._21=pBoneMatrixs[12*index+1]; matAnimation._31=pBoneMatrixs[12*index+2]; matAnimation._41=pBoneMatrixs[12*index+3]; matAnimation._12=pBoneMatrixs[12*index+4]; matAnimation._22=pBoneMatrixs[12*index+5]; matAnimation._32=pBoneMatrixs[12*index+6]; matAnimation._42=pBoneMatrixs[12*index+7]; matAnimation._13=pBoneMatrixs[12*index+8]; matAnimation._23=pBoneMatrixs[12*index+9]; matAnimation._33=pBoneMatrixs[12*index+10]; matAnimation._43=pBoneMatrixs[12*index+11]; matOrigin=matFrame0*matAnimation*m_pDynamicModel->getModelMatrix(); SetVertexPos(vertex[1],matOrigin._41+boneOffset[0],matOrigin._42+boneOffset[1],matOrigin._43+boneOffset[2]); m_pRenderDevice->GetVertexCacheManager()->RenderLines(2,vertex,false); } } else if(pBones[i].m_sParentID==0xFFFF)//the bone don't have children { Matrix4x4 matFrame0; matFrame0.InverseOf(pBones[i].m_matFrame0Inv); Matrix4x4 matAnimation; matAnimation.Identity(); matAnimation._11=pBoneMatrixs[12*i]; matAnimation._21=pBoneMatrixs[12*i+1]; matAnimation._31=pBoneMatrixs[12*i+2]; matAnimation._41=pBoneMatrixs[12*i+3]; matAnimation._12=pBoneMatrixs[12*i+4]; matAnimation._22=pBoneMatrixs[12*i+5]; matAnimation._32=pBoneMatrixs[12*i+6]; matAnimation._42=pBoneMatrixs[12*i+7]; matAnimation._13=pBoneMatrixs[12*i+8]; matAnimation._23=pBoneMatrixs[12*i+9]; matAnimation._33=pBoneMatrixs[12*i+10]; matAnimation._43=pBoneMatrixs[12*i+11]; Matrix4x4 matOrigin=matFrame0*matAnimation*m_pDynamicModel->getModelMatrix(); AABBox aabox=m_pModelMF1->m_MeshAABBox; float length=(aabox.vcMax-aabox.vcMin).GetLength()/150.0f; m_pRenderDevice->GetVertexCacheManager()->RenderDetailSphere(Vector3D(matOrigin._41+boneOffset[0],\ matOrigin._42+boneOffset[1],matOrigin._43+boneOffset[2]),length,5,5,Colour(255,255,255)); } } }