Archived

This topic is now archived and is closed to further replies.

Need help with the projection transformation

This topic is 5111 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I''m writing my own 3d software graphics engine and I''ve got a lot finished but I''m right now stuck on the perspective projection. If I have a triangle with vertices that look like this a.x = -10; a.y = -10; a.z = 0; b.x = 0; b.y = 10; b.z = 0; c.x = 10; c.y = -10; c.z = 0; and I try to project them onto a 2d plane it looks wierd. If I translate the triangle back to z = 1, then the triangle will be exactly 10 pixels high. Which isn''t right at z = 1 it should just about fill up the entire screen! Here is my code to set up the projection matrix
// 4x4 Projection Matrix

void dmath::MatrixProjection( dmath::Matrix4& m, const float fov, const float zNear, const float zFar )
{
	float Q = zFar / ( zFar - zNear );
	float W = 1 / tanf( fov / 2.0f );
	float H = 1 / tanf( fov / 2.0f );

	m.M11 = W; m.M12 = 0; m.M13 = 0;			m.M14 = 0;
	m.M21 = 0; m.M22 = H; m.M23 = 0;			m.M24 = 0;
	m.M31 = 0; m.M32 = 0; m.M33 = Q;			m.M34 = 1;
	m.M41 = 0; m.M42 = 0; m.M43 = -Q * zNear;	m.M44 = 0;
}
I pass it for FOV PI/2 and for zFar 10000 zNear 1 I multiply this matrix by all the vertices(after they are transformed to world coordinates) and then divide the x and y values by w. Here is the code that does it
		dmath::Vector4 worldTransPoint, untransPoint, transPoint;
 
		// Set the untransformed point to the vertex in the VBuffer

		untransPoint.x = m_untransVBuffer[activeVB][s].pos.x;
		untransPoint.y = m_untransVBuffer[activeVB][s].pos.y;
		untransPoint.z = m_untransVBuffer[activeVB][s].pos.z;
		untransPoint.w = 1;
 
		// Multiply the untransformed point by world matrix to get the transformedpoint

		dmath::VectorMatrixMultiply( worldTransPoint, untransPoint, m_matWorld );
 
		// Multply the world transformed point by projection matrix

		dmath::VectorMatrixMultiply( transPoint, worldTransPoint, m_matProj );
 
		// Set transformed point into the transformed vbuffer

		// and normalize the coordinates

		m_transVBuffer[activeVB][s] = m_untransVBuffer[activeVB][s];
		m_transVBuffer[activeVB][s].pos.x = transPoint.x / transPoint.w; // Normalize

		m_transVBuffer[activeVB][s].pos.y = transPoint.y / transPoint.w; // Normalize

		m_transVBuffer[activeVB][s].pos.z = transPoint.z;
 
		// Transform the coordinates to the viewport

		int halfWidth = (m_viewport.right - m_viewport.left) / 2;
		int halfHeight = (m_viewport.bottom - m_viewport.top ) / 2;
		m_transVBuffer[activeVB][s].pos.x += halfWidth;
		m_transVBuffer[activeVB][s].pos.y += halfHeight;
Thanks -ph33r

Share this post


Link to post
Share on other sites
Still working on this problem! I''ve tried a new projection matrix this time. I''m using


// 4x4 Projection Matrix

void dmath::MatrixProjection( dmath::Matrix4& m, const Viewport& view )
{
float l = view.left;
float r = view.right;
float t = view.top;
float b = view.bottom;
float zn = view.zNear;
float zf = view.zFar;

m.M11 = (2*zn)/(r-l); m.M12 = 0; m.M13 = 0; m.M14 = 0;
m.M21 = 0; m.M22 = (2*zn)/(b-t); m.M23 = 0; m.M24 = 0;
m.M31 = (r+l)/(r-l); m.M32 = (t+b)/(t-b); m.M33 = zf/(zf-zn); m.M34 = 1;
m.M41 = 0; m.M42 = 0; m.M43 = -((zf*zn)/(zf-zn)); m.M44 = 0;
}


Though it''s still not giving me any correct results, any help is appreciated

-ph33r

Share this post


Link to post
Share on other sites