GAMES101-作业2

GAMES101-作业2,第1张

GAMES101-作业2
static bool insideTriangle(double x, double y, const Vector3f* _v)
{   
    // TODO : Implement this function to check if the point (x, y) is inside the triangle represented by _v[0], _v[1], _v[2]
	Eigen::Vector2f p;
	p << x, y;

	Eigen::Vector2f AB = _v[1].head(2) - _v[0].head(2);
	Eigen::Vector2f BC = _v[2].head(2) - _v[1].head(2);
	Eigen::Vector2f CA = _v[0].head(2) - _v[2].head(2);

	Eigen::Vector2f AP = p - _v[0].head(2);
	Eigen::Vector2f BP = p - _v[1].head(2);
	Eigen::Vector2f CP = p - _v[2].head(2);

	return AB[0] * AP[1] - AB[1] * AP[0] > 0 
		&& BC[0] * BP[1] - BC[1] * BP[0] > 0
		&& CA[0] * CP[1] - CA[1] * CP[0] > 0;
}
void rst::rasterizer::rasterize_triangle(const Triangle& t) {
    auto v = t.toVector4();

	// TODO : Find out the bounding box of current triangle.
	float min_x = std::min(v[0][0], std::min(v[1][0], v[2][0]));
    float max_x = std::max(v[0][0], std::max(v[1][0], v[2][0]));
	float min_y = std::min(v[0][1], std::min(v[1][1], v[2][1]));
	float max_y = std::max(v[0][1], std::max(v[1][1], v[2][1]));

	min_x = (int)std::floor(min_x);
	max_x = (int)std::ceil(max_x);
	min_y = (int)std::floor(min_y);
	max_y = (int)std::ceil(max_y);

	bool MSAA = true;
	//MSAA 4X
	if (MSAA) {
		std::vector pos
		{
			{0.25,0.25},
			{0.75,0.25},
			{0.25,0.75},
			{0.75,0.75},
		};
        // iterate through the pixel and find if the current pixel is inside the triangle
		for (int x = min_x; x <= max_x; x++) {
			for (int y = min_y; y <= max_y; y++) {
				float minDepth = FLT_MAX;
				int count = 0;
				for (int i = 0; i < 4; i++) {
					if (insideTriangle((float)x + pos[i][0], (float)y + pos[i][1], t.v)) {
						// If so, use the fllowing code to get the interpolated z value.
						auto tup = computeBarycentric2D((float)x + pos[i][0], (float)y + pos[i][1], t.v);
						float alpha;
						float beta;
						float gamma;
						std::tie(alpha, beta, gamma) = tup;
						float w_reciprocal = 1.0 / (alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());
						float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();
						z_interpolated *= w_reciprocal;
						minDepth = std::min(minDepth, z_interpolated);
						count++;
					}
				}
                // TODO : set the current pixel (use the set_pixel function) to the color of the triangle (use getColor function) if it should be painted.
				if (count != 0) {
					if (depth_buf[get_index(x, y)] > minDepth) {
						Vector3f color = t.getColor() * count / 4.0;
						Vector3f point(3);
						point << (float)x, (float)y, minDepth;
						depth_buf[get_index(x, y)] = minDepth;
						set_pixel(point, color);
					}
				}
			}
		}
	}
	else {
        // iterate through the pixel and find if the current pixel is inside the triangle
		for (int x = min_x; x <= max_x; x++) {
			for (int y = min_y; y <= max_y; y++) {
				if (insideTriangle((float)x + 0.5, (float)y + 0.5, t.v)) {
                    // If so, use the fllowing code to get the interpolated z value.
					auto tup = computeBarycentric2D((float)x + 0.5, (float)y + 0.5, t.v);
					float alpha;
					float beta;
					float gamma;
					std::tie(alpha, beta, gamma) = tup;
					float w_reciprocal = 1.0 / (alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());
					float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();
					z_interpolated *= w_reciprocal;

                    // TODO : set the current pixel (use the set_pixel function) to the color of the triangle (use getColor function) if it should be painted.
					if (depth_buf[get_index(x, y)] > z_interpolated) {
						Vector3f color = t.getColor();
						Vector3f point(3);
						point << (float)x, (float)y, z_interpolated;
						depth_buf[get_index(x, y)] = z_interpolated;
						set_pixel(point, color);
					}
				}
			}
		}
	}
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/zaji/5714408.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存