merge remote and local changes

This commit is contained in:
HP
2026-06-07 10:39:29 +08:00
119 changed files with 6484 additions and 105 deletions
-102
View File
@@ -1,102 +0,0 @@
#include "Rasterizer.h"
#include <Vector2.h>
#include "Color.h"
#include <cmath>
#include <cstdint>
namespace Rasterizer
{
using namespace Math;
using namespace RenderData;
void Rasterizer::DrawLineHorizontal(const Vector2Int v0, const Vector2Int v1, const Color color)
{
Vector2Int start = v0, end = v1;
if (v0.x > v1.x)
{
start = v1;
end = v0;
}
int32_t dx = end.x - start.x;
int32_t dy = end.y - start.y;
int32_t dir = dy < 0 ? -1 : 1;
dy *= dir;
if (dx == 0) return;
int32_t y = start.y;
int32_t p = 2 * dy - dx;
for (int32_t x = start.x; x <= end.x; x++)
{
frameBuffer->set_pixel(x, y, color.to_rgba());
// 当 p >= 0 时,取上方像素点
if (p >= 0)
{
y += dir;
p -= 2 * dx;
}
// 当 p < 0 时,取下方像素点
p += 2 * dy;
}
}
void Rasterizer::DrawLineVertical(const Vector2Int v0, const Vector2Int v1, const Color color)
{
Vector2Int start = v0, end = v1;
if (v0.y > v1.y)
{
start = v1;
end = v0;
}
int32_t dx = end.x - start.x;
int32_t dy = end.y - start.y;
int32_t dir = dx < 0 ? -1 : 1;
dx *= dir;
if (dy == 0) return;
int32_t x = start.x;
int32_t p = 2 * dx - dy;
for (int32_t y = start.y; y <= end.y; y++)
{
frameBuffer->set_pixel(x, y, color.to_rgba());
// 当 p >= 0 时,取上方像素点
if (p >= 0)
{
x += dir;
p -= 2 * dy;
}
// 当 p < 0 时,取下方像素点
p += 2 * dx;
}
}
/// <summary>
/// 在给定的起始点和结束点之间绘制一条线段,并使用指定的颜色填充
/// </summary>
/// <param name="v0">直线顶点 1</param>
/// <param name="v1">直线顶点 2</param>
/// <param name="color">绘制的颜色</param>
/// <remarks>
/// bresenham 画线算法
/// </remarks>
void Rasterizer::DrawLine(const Vector2Int v0, const Vector2Int v1, const Color color)
{
int32_t x0 = v0.x, y0 = v0.y;
int32_t x1 = v1.x, y1 = v1.y;
if (std::abs(x1 - x0) > std::abs(y1 - y0))
{
DrawLineHorizontal(v0, v1, color);
}
else
{
DrawLineVertical(v0, v1, color);
}
}
}
-24
View File
@@ -1,24 +0,0 @@
#pragma once
#include "Color.h"
#include "FrameBuffer.h"
#include "DepthBuffer.h"
#include <Vector2.h>
namespace Rasterizer
{
class Rasterizer
{
private:
Core::FrameBuffer* frameBuffer;
Core::DepthBuffer* depthBuffer;
void DrawLineHorizontal(const Math::Vector2Int v0, const Math::Vector2Int v1, const RenderData::Color color);
void DrawLineVertical(const Math::Vector2Int v0, const Math::Vector2Int v1, const RenderData::Color color);
public:
explicit Rasterizer(Core::FrameBuffer* frameBuffer) :frameBuffer(frameBuffer), depthBuffer(nullptr) {}
explicit Rasterizer(Core::FrameBuffer* frameBuffer, Core::DepthBuffer* depthBuffer) :frameBuffer(frameBuffer), depthBuffer(depthBuffer) {}
void DrawLine(const Math::Vector2Int v0, const Math::Vector2Int v1, const RenderData::Color color);
};
}
+45
View File
@@ -0,0 +1,45 @@
#include "SpriteRasterizer.h"
#include "../Core/FrameBuffer.h"
#include "../RenderData/Image.h"
#include "../RenderData/Sprite.h"
namespace Rasterizer
{
void SpriteRasterizer::DrawImage(const RenderData::Image& image, int32_t x, int32_t y)
{
DrawSprite(RenderData::Sprite(&image), x, y);
}
void SpriteRasterizer::DrawSprite(const RenderData::Sprite& sprite, int32_t x, int32_t y)
{
if (frameBuffer == nullptr || !sprite.is_valid())
{
return;
}
const int32_t minX = x < 0 ? -x : 0;
const int32_t minY = y < 0 ? -y : 0;
const int32_t maxX = x + sprite.width > frameBuffer->get_width() ? frameBuffer->get_width() - x : sprite.width;
const int32_t maxY = y + sprite.height > frameBuffer->get_height() ? frameBuffer->get_height() - y : sprite.height;
if (minX >= maxX || minY >= maxY)
{
return;
}
for (int32_t sy = minY; sy < maxY; ++sy)
{
for (int32_t sx = minX; sx < maxX; ++sx)
{
const uint32_t color = sprite.get_pixel_fast(sx, sy);
const uint8_t alpha = static_cast<uint8_t>(color & 0xFF);
if (alpha == 0)
{
continue;
}
frameBuffer->set_pixel(x + sx, y + sy, color);
}
}
}
}
+28
View File
@@ -0,0 +1,28 @@
#pragma once
#include <cstdint>
namespace Core
{
class FrameBuffer;
}
namespace RenderData
{
class Image;
struct Sprite;
}
namespace Rasterizer
{
class SpriteRasterizer
{
private:
Core::FrameBuffer* frameBuffer;
public:
explicit SpriteRasterizer(Core::FrameBuffer* frameBuffer) : frameBuffer(frameBuffer) {}
void DrawImage(const RenderData::Image& image, int32_t x, int32_t y);
void DrawSprite(const RenderData::Sprite& sprite, int32_t x, int32_t y);
};
}
-61
View File
@@ -1,61 +0,0 @@
#include "TriangleRasterizer.h"
#include <Triangle.h>
#include <Color.h>
#include "BoundingBox.h"
#include <Vector2.h>
#include <algorithm>
#include <cstdint>
namespace Rasterizer
{
void TriangleRasterizer::DrawTriangle2D(const RenderData::Triangle& triangle, const RenderData::Color color)
{
using namespace Math;
auto boundingBox = triangle.get_boundingBox();
int32_t minX = std::max(0, boundingBox.min.x);
int32_t maxX = std::min(frameBuffer->get_width() - 1, boundingBox.max.x);
int32_t minY = std::max(0, boundingBox.min.y);
int32_t maxY = std::min(frameBuffer->get_height() - 1, boundingBox.max.y);
for (int x = minX; x <= maxX; x++)
{
for (int y = minY; y <= maxY; y++)
{
Vector2 samplePoint(x + 0.5f, y + 0.5f);
float w0 = 0, w1 = 0, w2 = 0;
if (!triangle.get_barycentric(samplePoint, w0, w1, w2))
{
continue;
}
if ((w0 < 0) || (w1 < 0) || (w2 < 0))
{
continue;
}
const float depth =
w0 * triangle.v0.position.z +
w1 * triangle.v1.position.z +
w2 * triangle.v2.position.z;
if (depthBuffer)
{
// 深度越小离相机越近
if (depthBuffer->get_depth(x, y) < depth)
{
continue;
}
depthBuffer->set_depth(x, y, depth);
frameBuffer->set_pixel(x, y, color.to_rgba());
}
else
{
frameBuffer->set_pixel(x, y, color.to_rgba());
}
}
}
}
}
-22
View File
@@ -1,22 +0,0 @@
#pragma once
#include "Triangle.h"
#include "Color.h"
#include "FrameBuffer.h"
#include <DepthBuffer.h>
namespace Rasterizer
{
class TriangleRasterizer
{
private:
Core::FrameBuffer* frameBuffer;
Core::DepthBuffer* depthBuffer;
public:
explicit TriangleRasterizer(Core::FrameBuffer* frameBuffer) :frameBuffer(frameBuffer), depthBuffer(nullptr) {};
explicit TriangleRasterizer(Core::FrameBuffer* frameBuffer, Core::DepthBuffer* depthBuffer) :frameBuffer(frameBuffer), depthBuffer(depthBuffer) {};
void DrawTriangle2D(const RenderData::Triangle& triangle, const RenderData::Color color);
};
}