Common::Plane Transform_Plane_By_Mat44(const Plane& plane, const Matrix44& mat) { Vector4 v(plane.n, plane.d); // To transform normal, we can not use the matrix directly // See: http://www.songho.ca/opengl/gl_normaltransform.html Matrix44 matInvTranspose = mat.Inverse(); matInvTranspose.Transpose(); v = Common::Transform_Vec4_By_Mat44(v, matInvTranspose); Plane ret; ret.n = v.GetVec3(); ret.d = v.w / ret.n.Normalize(); return ret; }
void GetRay(int sx, int sy, Vector3 &orig, Vector3 &dir) { const float x = ( (sx * 2.0F / WINSIZE_X ) - 1.0F ); const float y = -( (sy * 2.0F / WINSIZE_Y) - 1.0F ); Vector3 v; v.x = x / g_matProj._11; v.y = y / g_matProj._22; v.z = 1.0F; Matrix44 m = g_matView.Inverse(); dir.x = v.x * m._11 + v.y * m._21 + v.z * m._31; dir.y = v.x * m._12 + v.y * m._22 + v.z * m._32; dir.z = v.x * m._13 + v.y * m._23 + v.z * m._33; orig.x = m._41; orig.y = m._42; orig.z = m._43; }
//-----------------------------------------------------------------------------// // 카메라(view) * 프로젝션(projection)행렬을 입력받아 6개의 평면을 만든다. //-----------------------------------------------------------------------------// bool cFrustum::Create(cRenderer &renderer, const Matrix44 &matViewProj) { // 투영행렬까지 거치면 모든 3차원 월드좌표의 점은 (-1,-1,0) ~ (1,1,1)사이의 값으로 바뀐다. SetCube(renderer, Vector3(-1,-1,0), Vector3(1,1,1) ); // view * proj의 역행렬을 구한다. Matrix44 matInv = matViewProj.Inverse(); // Vertex_최종 = Vertex_local * Matrix_world * Matrix_view * Matrix_Proj 인데, // Vertex_world = Vertex_local * Matrix_world이므로, // Vertex_최종 = Vertex_world * Matrix_view * Matrix_Proj 이다. // Vertex_최종 = Vertex_world * ( Matrix_view * Matrix_Proj ) 에서 // 역행렬( Matrix_view * Matrix_Proj )^-1를 양변에 곱하면 // Vertex_최종 * 역행렬( Matrix_view * Matrix_Proj )^-1 = Vertex_World 가 된다. // 그러므로, m_Vtx * matInv = Vertex_world가 되어, 월드좌표계의 프러스텀 좌표를 얻을 수 있다. sVertexDiffuse *vertices = (sVertexDiffuse*)m_vtxBuff.Lock(); RETV(!vertices, false); m_fullCheck = false; for (int i = 0; i < 8; i++) vertices[ i].p *= matInv; // 2번과 5번은 프러스텀중 near평면의 좌측상단과 우측하단이므로, 둘의 좌표를 더해서 2로 나누면 // 카메라의 좌표를 얻을 수 있다.(정확히 일치하는 것은 아니다.) m_pos = ( vertices[2].p + vertices[5].p ) / 2.0f; // 얻어진 월드좌표로 프러스텀 평면을 만든다 // 벡터가 프러스텀 안쪽에서 바깥쪽으로 나가는 평면들이다. m_plane[3].Init( vertices[ 4].p, vertices[ 5].p, vertices[ 6].p ); // 원 평면(far) m_plane[4].Init( vertices[ 0].p, vertices[ 2].p, vertices[ 6].p ); // 좌 평면(left) m_plane[5].Init( vertices[ 1].p, vertices[ 5].p, vertices[ 7].p ); // 우 평면(right) m_vtxBuff.Unlock(); return TRUE; }
void cMesh::RenderShadow(cRenderer &renderer, cShader &shader, const Matrix44 &parentTm) { RET(!IsRender()); RET(!m_buffers); if (m_buffers->GetAttributes().empty()) { const Matrix44 tm = m_localTM * m_aniTM * m_TM * parentTm; shader.SetMatrix("mWorld", tm); Matrix44 wit = tm.Inverse(); wit.Transpose(); shader.SetMatrix("mWIT", wit); //const Matrix44 tm = m_localTM * m_aniTM * m_TM * parentTm; //shader.SetMatrix("mWorld", tm); //Matrix44 wit = tm.Inverse(); //wit.Transpose(); //shader.SetMatrix("mWIT", wit); //if (!m_mtrls.empty()) // m_mtrls[ 0].Bind(shader); //if (!m_textures.empty()) // m_textures[ 0]->Bind(shader, "colorMapTexture"); m_buffers->Bind(renderer); shader.Begin(); shader.BeginPass(); renderer.GetDevice()->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, m_buffers->GetVertexBuffer().GetVertexCount(), 0, m_buffers->GetIndexBuffer().GetFaceCount()); shader.End(); shader.EndPass(); } else { const Matrix44 tm = m_localTM * m_aniTM * m_TM * parentTm; shader.SetMatrix("mWorld", tm); Matrix44 wit = tm.Inverse(); wit.Transpose(); shader.SetMatrix("mWIT", wit); //const Matrix44 tm = m_localTM * m_aniTM * m_TM * parentTm; //shader.SetMatrix("mWorld", tm); //Matrix44 wit = tm.Inverse(); //wit.Transpose(); //shader.SetMatrix("mWIT", wit); shader.Begin(); m_buffers->Bind(renderer); //m_vtxBuff.Bind(); //m_idxBuff.Bind(); for (u_int i=0; i < m_buffers->GetAttributes().size(); ++i) { const int mtrlId = m_buffers->GetAttributes()[ i].attribId; if ((int)m_mtrls.size() <= mtrlId) continue; //m_mtrls[ mtrlId].Bind(shader); //if (m_textures[ mtrlId]) // m_textures[ mtrlId]->Bind(shader, "colorMapTexture"); shader.BeginPass(); renderer.GetDevice()->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, m_buffers->GetVertexBuffer().GetVertexCount(), m_buffers->GetAttributes()[ i].faceStart*3, m_buffers->GetAttributes()[ i].faceCount); shader.EndPass(); } shader.End(); } }
// 그림자 출력. void cMesh::RenderShadow(cRenderer &renderer, const Matrix44 &viewProj, const Vector3 &lightPos, const Vector3 &lightDir, const Matrix44 &parentTm) { RET(!IsRender()); RET(!m_shader); RET(!m_buffers); const cLight &mainLight = cLightManager::Get()->GetMainLight(); mainLight.Bind(*m_shader); m_shader->SetMatrix( "mVP", viewProj); m_shader->SetVector( "vEyePos", lightPos); if (m_buffers->GetAttributes().empty()) { const Matrix44 tm = m_localTM * m_aniTM * m_TM * parentTm; m_shader->SetMatrix("mWorld", tm); Matrix44 wit = tm.Inverse(); wit.Transpose(); m_shader->SetMatrix("mWIT", wit); m_buffers->Bind(renderer); m_shader->Begin(); m_shader->BeginPass(1); renderer.GetDevice()->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, m_buffers->GetVertexBuffer().GetVertexCount(), 0, m_buffers->GetIndexBuffer().GetFaceCount()); m_shader->End(); m_shader->EndPass(); } else { const Matrix44 tm = m_localTM * m_aniTM * m_TM * parentTm; m_shader->SetMatrix("mWorld", tm); Matrix44 wit = tm.Inverse(); wit.Transpose(); m_shader->SetMatrix("mWIT", wit); m_shader->Begin(); m_buffers->Bind(renderer); for (u_int i=0; i < m_buffers->GetAttributes().size(); ++i) { const int mtrlId = m_buffers->GetAttributes()[ i].attribId; if ((int)m_mtrls.size() <= mtrlId) continue; m_shader->BeginPass(1); renderer.GetDevice()->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, m_buffers->GetVertexBuffer().GetVertexCount(), m_buffers->GetAttributes()[ i].faceStart*3, m_buffers->GetAttributes()[ i].faceCount); m_shader->EndPass(); } m_shader->End(); } }
// 셰이더를 통해 화면을 그린다. void cMesh::RenderShader(cRenderer &renderer, cShader &shader, const Matrix44 &parentTm) { RET(!IsRender()); RET(!m_buffers); const cLight &mainLight = cLightManager::Get()->GetMainLight(); mainLight.Bind(shader); shader.SetMatrix( "mVP", cMainCamera::Get()->GetViewProjectionMatrix()); shader.SetVector( "vEyePos", cMainCamera::Get()->GetEyePos()); if (m_buffers->GetAttributes().empty()) { const Matrix44 tm = m_localTM * m_aniTM * m_TM * parentTm; shader.SetMatrix("mWorld", tm); Matrix44 wit = tm.Inverse(); wit.Transpose(); shader.SetMatrix("mWIT", wit); const bool isNormalMapping = (!m_normalMap.empty()) && (m_normalMap[ 0] && m_normalMap[ 0]->GetTexture()); const bool isSpecularMapping = (!m_specularMap.empty()) && (m_specularMap[ 0] && m_specularMap[ 0]->GetTexture()); const bool isSelfIllumMapping = (!m_selfIllumMap.empty()) && (m_selfIllumMap[ 0] && m_selfIllumMap[ 0]->GetTexture()); if (!m_mtrls.empty()) m_mtrls[ 0].Bind(shader); if (!m_colorMap.empty()) m_colorMap[ 0]->Bind(shader, "colorMapTexture"); if (isNormalMapping) m_normalMap[ 0]->Bind(shader, "normalMapTexture"); if (isSpecularMapping) m_specularMap[ 0]->Bind(shader, "specularMapTexture"); if (isSelfIllumMapping) m_selfIllumMap[ 0]->Bind(shader, "selfIllumMapTexture"); shader.SetRenderPass(isNormalMapping? 4 : 0); m_buffers->Bind(renderer); shader.Begin(); shader.BeginPass(); renderer.GetDevice()->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, m_buffers->GetVertexBuffer().GetVertexCount(), 0, m_buffers->GetIndexBuffer().GetFaceCount()); shader.End(); shader.EndPass(); } else { const Matrix44 tm = m_localTM * m_aniTM * m_TM * parentTm; shader.SetMatrix("mWorld", tm); Matrix44 wit = tm.Inverse(); wit.Transpose(); shader.SetMatrix("mWIT", wit); shader.Begin(); m_buffers->Bind(renderer); for (u_int i=0; i < m_buffers->GetAttributes().size(); ++i) { const int mtrlId = m_buffers->GetAttributes()[ i].attribId; if ((int)m_mtrls.size() <= mtrlId) continue; const bool isNormalMapping = m_normalMap[ mtrlId] && m_normalMap[ mtrlId]->GetTexture(); const bool isSpecularMapping = m_specularMap[ mtrlId] && m_specularMap[ mtrlId]->GetTexture(); const bool isSelfIllumMapping = m_selfIllumMap[ mtrlId] && m_selfIllumMap[ mtrlId]->GetTexture(); m_mtrls[ mtrlId].Bind(shader); if (m_colorMap[ mtrlId]) m_colorMap[ mtrlId]->Bind(shader, "colorMapTexture"); if (isNormalMapping) m_normalMap[ mtrlId]->Bind(shader, "normalMapTexture"); if (isSpecularMapping) m_specularMap[ mtrlId]->Bind(shader, "specularMapTexture"); if (isSelfIllumMapping) m_selfIllumMap[ mtrlId]->Bind(shader, "selfIllumMapTexture"); shader.SetRenderPass(isNormalMapping? 4 : 0); shader.BeginPass(); renderer.GetDevice()->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, m_buffers->GetVertexBuffer().GetVertexCount(), m_buffers->GetAttributes()[ i].faceStart*3, m_buffers->GetAttributes()[ i].faceCount); shader.EndPass(); } shader.End(); } }