CMatrix4::CMatrix4(const Vector4& v1, const Vector4& v2, const Vector4& v3, const Vector4& v4) #if 0 : m{ v1.GetX(), v1.GetY(), v1.GetZ(), v1.GetW(), v2.GetX(), v2.GetY(), v2.GetZ(), v2.GetW(), v3.GetX(), v3.GetY(), v3.GetZ(), v3.GetW(), v4.GetX(), v4.GetY(), v4.GetZ(), v4.GetW() } { #else { constexpr std::size_t bytes = sizeof(float) * 4; std::memcpy(static_cast<void*>(&m[0]), static_cast<const float*>(v1), bytes); std::memcpy(static_cast<void*>(&m[4]), static_cast<const float*>(v2), bytes); std::memcpy(static_cast<void*>(&m[8]), static_cast<const float*>(v3), bytes); std::memcpy(static_cast<void*>(&m[12]), static_cast<const float*>(v4), bytes); #endif } CMatrix4::CMatrix4(const Array& m) : m(m) { } void CMatrix4::SetRow(std::int32_t row, const Vector4& v) { HASENPFOTE_ASSERT_MSG((row >= 0) && (row < order), "Row index out of bounds."); m[offset<order>(row, 0)] = v.GetX(); m[offset<order>(row, 1)] = v.GetY(); m[offset<order>(row, 2)] = v.GetZ(); m[offset<order>(row, 3)] = v.GetW(); }
// `計算點光源, 它和頂點位置, 頂點面向, 光源位置, 光源方向, 光柱交角有關.` void CalculateSpotLight(Vertex_VCN *pVertices, int num_vertices) { float fSpotLightCutoffCos = FastMath::Cos( FastMath::DegreeToRadian(g_fSpotLightCutoff) ); for ( int i=0; i<num_vertices; i++ ) { // `求出轉換後在世界座標系的頂點位置` Vector4 vPosition = pVertices[i].m_Position * g_world_matrix; // `求出轉換後在世界座標系的頂點面向, RotateVector函式只做旋轉, 忽略位移.` Vector4 vNormal = g_world_matrix.RotateVector(pVertices[i].m_Normal); // `計算出頂點位置到光源的方向跟長度` Vector4 vVertex_to_Light = g_vLightPosition - vPosition; float light_distance = vVertex_to_Light.NormalizeAndGetLength(); // `頂點面向跟光線方向的交角, 可以決定反射光的強度.` Vector4 vCosine = Vector3Dot(g_vLightDirection, vVertex_to_Light); // `把vCosine局限在永遠大於0的范圍` vCosine.Clamp_to_0(); float fCosine = vCosine.GetX(); if ( fCosine >= fSpotLightCutoffCos ) { // `頂點跟光線的交角小於fSpotightCutoffCos時, 才落在光柱范圍內.` Vector4 vDistance(1.0f, light_distance, light_distance * light_distance); // `g_vLightAttenuation里記錄了計算衰減公式1/(a + b*d + c*d^2)里的(a,b,c)` // `Vector3Dot(vDistance, g_vLightAttenuation) = (a,b,c) dot (1,d,d^2) = (a + b*d + c*d^2)` Vector4 vAttenuation = Vector3Dot(vDistance, g_vLightAttenuation); // `比較靠近光柱外圍部分的頂點, 光線會衰減.` float fFalloff = pow(fCosine, g_fSpotLightExponent); Vector4 vIntensity = Vector3Dot(vNormal, vVertex_to_Light); pVertices[i].m_Color += fFalloff * vIntensity * g_vLightColor / vAttenuation; pVertices[i].m_Color.Clamp_to_1(); } } }
void ShapeRectangle::Render() const { Vector4 bottomLeft = m_transformComponent->Transformation(m_bottomLeft); Vector4 bottomRight = m_transformComponent->Transformation(m_bottomRight); Vector4 topLeft = m_transformComponent->Transformation(m_topLeft); Vector4 topRight = m_transformComponent->Transformation(m_topRight); glBegin(GL_TRIANGLE_STRIP); glColor3ub(m_red, m_green, m_blue); glVertex2f(bottomLeft.GetX(), bottomLeft.GetY()); glVertex2f(bottomRight.GetX(), bottomRight.GetY()); glVertex2f(topLeft.GetX(), topLeft.GetY()); glVertex2f(topRight.GetX(), topRight.GetY()); glEnd(); }
void CMatrix4::SetColumn(std::int32_t column, const Vector4& v) { HASENPFOTE_ASSERT_MSG((column >= 0) && (column < order), "Column index out of bounds."); m[offset<order>(0, column)] = v.GetX(); m[offset<order>(1, column)] = v.GetY(); m[offset<order>(2, column)] = v.GetZ(); m[offset<order>(3, column)] = v.GetW(); }
void CgEffect::SetVector(const char* name, Vector4& v) { cgSetParameter4f(this->retrieveParameter(name), v.GetX(), v.GetY(), v.GetZ(), v.GetW()); }