Просмотр исходного кода

feat: 添加直线颜色插值计算

nicetry12138 1 год назад
Родитель
Сommit
fee689c7f9

+ 48 - 0
OpenGL/README.md

@@ -468,7 +468,55 @@ void func(int x0, int y0, int x1, int y1) {
 
 对于 **区域7、8** 也就是 `slope < 0` 的区域来说,**对 x 轴做镜像变换**即可,让 $y = -y$ 就能变换到**区域1、2**,等像素坐标计算完毕之后再变换回来
 
+### 直线上的颜色
 
+封装 `Point` 类,用于存储点的信息,包括 `x、y` 坐标和 `RGBA` 颜色信息
+
+```cpp
+struct Point
+{
+public:
+    int m_x;
+    int m_y;
+    RGBA m_color;
+    Point(int _x = 0, int _y = 0, RGBA _color = RGBA(0, 0, 0, 0))
+    {
+        m_x = _x;
+        m_y = _y;
+        m_color = _color;
+    }
+    ~Point()
+    {
+
+    }
+};
+```
+
+简单的直线的颜色计算,只需要根据两端点的颜色信息进行线性插值即可
+
+```cpp
+inline RGBA colorLerp(const RGBA& _color1, const RGBA& _color2, float _scale) {
+    RGBA result;
+
+    result.m_r = _color1.m_r + (float)(_color2.m_r - _color1.m_r) * _scale;
+    result.m_g = _color1.m_g + (float)(_color2.m_g - _color1.m_g) * _scale;
+    result.m_b = _color1.m_b + (float)(_color2.m_b - _color1.m_b) * _scale;
+    result.m_a = _color1.m_a + (float)(_color2.m_a - _color1.m_a) * _scale;
+
+    return result;
+}
+```
+
+然后在绘制直线的时候,只需要根据计算点的进入即可知道点的颜色插值
+
+```cpp
+for (int index = 0; index < sumStep; ++ index) {
+    auto pointColor = colorLerp(pt1.m_color, pt2.m_color, (float)index / sumStep);
+    drawPoint(Point(xNow, yNow, pointColor));
+
+    // 后续 brensenham 算法计算
+}
+```
 
 ## 图形处理及纹理系统
 

+ 21 - 8
OpenGL/src/WindowsProjectTest/WindowsProjectTest/Canvas.cpp

@@ -5,25 +5,25 @@
 #include <string>
 
 namespace GT {
-	void Canvas::drawLine(intV2 pt1, intV2 pt2, RGBA _Color) {
-		int disY = abs(pt2.y - pt1.y);
-		int disX = abs(pt2.x - pt1.x);
+	void Canvas::drawLine(const Point& pt1, const Point& pt2) {
+		int disY = abs(pt2.m_y - pt1.m_y);
+		int disX = abs(pt2.m_x - pt1.m_x);
 
-		int xNow = pt1.x;
-		int yNow = pt1.y;
+		int xNow = pt1.m_x;
+		int yNow = pt1.m_y;
 
 		int stepX = 0;
 		int stepY = 0;
 
 		// Åжϲ½¾¶·½Ïò 
-		if (pt1.x < pt2.x) {
+		if (pt1.m_x < pt2.m_x) {
 			stepX = 1;
 		}
 		else {
 			stepX = -1;
 		}
 
-		if (pt1.y < pt2.y) {
+		if (pt1.m_y < pt2.m_y) {
 			stepY = 1;
 		}
 		else {
@@ -47,7 +47,9 @@ namespace GT {
 		for (int index = 0; index < sumStep; ++ index) {
 			//std::wstring str = L"index = " + std::to_wstring(index) + L" xNow = " + std::to_wstring(xNow) + L", yNow = " + std::to_wstring(yNow) + L"\n";
 			//OutputDebugString(str.c_str());
-			drawPoint(xNow, yNow, _Color);
+
+			auto pointColor = colorLerp(pt1.m_color, pt2.m_color, (float)index / sumStep);
+			drawPoint(Point(xNow, yNow, pointColor));
 			if (p >= 0) {
 				if (useXStep) {
 					yNow += stepY;
@@ -72,4 +74,15 @@ namespace GT {
 			}
 		}
 	}
+	inline RGBA Canvas::colorLerp(const RGBA& _color1, const RGBA& _color2, float _scale)
+	{
+		RGBA result;
+
+		result.m_r = _color1.m_r + (float)(_color2.m_r - _color1.m_r) * _scale;
+		result.m_g = _color1.m_g + (float)(_color2.m_g - _color1.m_g) * _scale;
+		result.m_b = _color1.m_b + (float)(_color2.m_b - _color1.m_b) * _scale;
+		result.m_a = _color1.m_a + (float)(_color2.m_a - _color1.m_a) * _scale;
+
+		return result;
+	}
 }

+ 8 - 4
OpenGL/src/WindowsProjectTest/WindowsProjectTest/Canvas.h

@@ -28,17 +28,21 @@ namespace GT {
 		}
 
 		// 画线
-		void drawLine(intV2 pt1, intV2 pt2, RGBA _Color);
+		void drawLine(const Point &pt1, const Point &pt2);
 
 		// 画点操作
-		void drawPoint(int x, int y, RGBA _collor) {
-			if (x < 0 || x >= m_Width || y < 0 || y >= m_Height) {
+		void drawPoint(const Point &_pt) {
+			if (_pt.m_x < 0 || _pt.m_x >= m_Width || _pt.m_y < 0 || _pt.m_y >= m_Height) {
 				return;
 			}
 
-			m_Buffer[y * m_Width + x] = _collor;
+			int _index = _pt.m_y * m_Width + _pt.m_x;
+			m_Buffer[_index] = _pt.m_color;
 		}
 
+		// 颜色线性插值
+		inline RGBA colorLerp(const RGBA& _color1, const RGBA& _color2, float _scale);
+
 		// 清理操作
 		void clear() {
 			if (m_Buffer != nullptr) {

+ 19 - 2
OpenGL/src/WindowsProjectTest/WindowsProjectTest/GTMATH.hpp

@@ -3,8 +3,7 @@
 
 namespace GT
 {
-
-#define	PI									3.14159265358979323
+#define	PI									3.14159265358979323f
 #define	DEG2RAD(theta)						(0.01745329251994329 * (theta))
 #define MIN(a,b)							((a)<(b)?(a):(b))
 #define MAX(a,b)							((a)>(b)?(a):(b))
@@ -78,4 +77,22 @@ namespace GT
 			m_a = _a;
 		}
 	};
+
+	struct Point
+	{
+	public:
+		int m_x;
+		int m_y;
+		RGBA m_color;
+		Point(int _x = 0, int _y = 0, RGBA _color = RGBA(0, 0, 0, 0))
+		{
+			m_x = _x;
+			m_y = _y;
+			m_color = _color;
+		}
+		~Point()
+		{
+
+		}
+	};
 }

+ 3 - 1
OpenGL/src/WindowsProjectTest/WindowsProjectTest/WindowsProjectTest.cpp

@@ -38,12 +38,14 @@ void Render() {
 	//}
 
     // 测试直线 极坐标绘制一圈线
+    GT::RGBA Color1 = GT::RGBA(255, 0, 0, 0);
+    GT::RGBA Color2 = GT::RGBA(0, 255, 0, 0);
     for (int i = 0; i < 360; i += 10) {
         float angle = i * PI / 180 ;
         int x = cos(angle) * 300 + wWidth / 2;
         int y = sin(angle) * 300 + wHeight / 2;
         //GT::UTool::DebugPrint(L"angle = %d\n", angle);
-        _canvas->drawLine(GT::intV2(wWidth / 2, wHeight / 2), GT::intV2(x, y), GT::RGBA(255, 0, 0, 0));
+        _canvas->drawLine(GT::Point(wWidth / 2, wHeight / 2, Color1), GT::Point(x, y, Color2));
     }
 
 	// 将 hMem 的数据一次写入到 hDC 中