Quellcode durchsuchen

feat: 封装图形学接口

nicetry12138 vor 1 Jahr
Ursprung
Commit
7e1e56510d

BIN
OpenGL/Image/034.png


+ 71 - 0
OpenGL/README.md

@@ -1374,3 +1374,74 @@ glIsEnabled(GL_TEXTURE_2D);
 4. 减少状态改变的开销
    - 在图形渲染过程中,频繁地改变状态是一项耗费性能的操作。通过维护一个持续的状态环境,可以最小化状态变化的次数,从而减少 `CPU` 和 `GPU` 之间的通信开销,提高整体性能
 
+```cpp
+GT::Point ptArray[] =
+{
+    {0.0f,0.0f,       GT::RGBA(255,0,0) , GT::floatV2(0,0)},
+    {300.0f,0.0f,    GT::RGBA(0,255,0) , GT::floatV2(1.0,0)},
+    {300.0f,300.0f,   GT::RGBA(0,0,255) , GT::floatV2(1.0,1.0)},
+
+    {300.0f,0.0f,       GT::RGBA(255,0,0) , GT::floatV2(1.0f,.0f)},
+    {300.0f,300.0f,    GT::RGBA(0,255,0) , GT::floatV2(.0f,.0f)},
+    {600.0f,500.0f,   GT::RGBA(0,0,255) , GT::floatV2(.0f,1.0f)},
+};
+
+//_canvas->drawTriangle(ptArray[3], ptArray[4], ptArray[5]);
+
+_canvas->gtVertexPointer(2, GT::GT_FLOAT, sizeof(GT::Point), (GT::byte*)ptArray);
+_canvas->gtColorPointer(1, GT::GT_FLOAT, sizeof(GT::Point), (GT::byte*)&ptArray[0].m_color);
+_canvas->gtTexCoordPointer(1, GT::GT_FLOAT, sizeof(GT::Point), (GT::byte*)&ptArray[0].m_uv);
+
+_canvas->enableTexture(true);
+_canvas->setTextureType(GT::Image::TX_REPEAT);
+_canvas->bindTexture(_bgImage);
+
+_canvas->gtDrawArray(GT::GT_TRIANGLE, 0, 6);
+```
+
+![](Image/034.png)
+
+参考上面的图片,结合前面新封装接口的代码,理解对 `ptArray` 操作的原理
+
+对于 `Point` 对象来说,它的大小是 `sizeof(Point)` 字节
+
+- 让 `ptArray + sizeof(Point)` 就指向了数组中下个 `Point` 对象
+- 让 `colorStart + sizeof(Point)` 就直接指向了数组中下一个 `Point` 对象的 `RGBA color` 数据
+- 让 `uvStart + sizeof(Point)` 就直接指向了数组中下一格 `Point` 对象的 `floatV2 uv` 数据 
+
+> 对于 `char* ptr` 来说, `ptr + 1` 就是指针向后位移一个 `char` 大小,也就是一个字节    
+> 对于 `int* ptr` 来说, `ptr + 1` 就是指针向后位移一个 `int` 大小的,可能是四个字节
+
+所以,程序中想要获取 `ptArray` 中所有的数据,可以直接
+
+```cpp
+for (int i = 0; i < inCount; i++)
+{
+	float* vertexDataFloat = (float*)vertexData;
+	pt0.m_x = vertexDataFloat[0];
+	pt0.m_y = vertexDataFloat[1];
+	vertexData += m_State.m_vertextData.m_stride;
+
+	vertexDataFloat = (float*)vertexData;
+	pt1.m_x = vertexDataFloat[0];
+	pt1.m_y = vertexDataFloat[1];
+	vertexData += m_State.m_vertextData.m_stride;
+
+	//取颜色坐标
+	RGBA* colorDataRGBA = (RGBA*)colorData;
+	pt0.m_color = colorDataRGBA[0];
+
+	colorData += m_State.m_colorData.m_stride;
+
+	colorDataRGBA = (RGBA*)colorData;
+	pt1.m_color = colorDataRGBA[0];
+	colorData += m_State.m_colorData.m_stride;
+
+	drawLine(pt0, pt1);
+}
+```
+
+就顶点信息来说,由于数据类型是 `float`,所以将源数据强制装换成 `vertexDataFloat = (float*)vertexData`,那么 `vertexDataFloat[0]` 对应的就是 `m_x`, `vertexDataFloat[1]` 对应的就是 `m_y`,那么下一个 `Point` 的 `m_x`、`m_y` 对应的起始坐标就是 `vertexData += m_State.m_vertextData.m_stride`,这里 `m_State.m_vertextData.m_stride` 就是 `sizeof(Point)
+
+至于颜色信息和 `UV` 信息同理,都是通过起始地址和地址偏移直接计算的
+

+ 77 - 7
OpenGL/src/WindowsProjectTest/WindowsProjectTest/Canvas.cpp

@@ -234,22 +234,91 @@ namespace GT {
 
 	void Canvas::gtDrawArray(DRAW_MODE inMode, int inFirstIndex, int inCount)
 	{
+		Point pt0, pt1, pt2;
+		byte* vertexData = m_State.m_vertextData.m_data + inFirstIndex * m_State.m_vertextData.m_stride;
+		byte* colorData = m_State.m_colorData.m_data + inFirstIndex * m_State.m_colorData.m_stride;
+		byte* texCoordData = m_State.m_texCoordData.m_data + inFirstIndex * m_State.m_texCoordData.m_stride;
 		switch (inMode)
 		{
 		case GT::GT_LINE: {
-			Point pt1, pt2;
-			byte* vertexData = m_State.m_vertextData.m_data;
-			byte* colorData = m_State.m_colorData.m_data;
-			byte* texCoordData = m_State.m_texCoordData.m_data;
-			for (int i = 0; i < inCount; i += 2) {
+			inCount = inCount / 2;
+			for (int i = 0; i < inCount; i++)
+			{
 				float* vertexDataFloat = (float*)vertexData;
+				pt0.m_x = vertexDataFloat[0];
+				pt0.m_y = vertexDataFloat[1];
+				vertexData += m_State.m_vertextData.m_stride;
+
+				vertexDataFloat = (float*)vertexData;
 				pt1.m_x = vertexDataFloat[0];
 				pt1.m_y = vertexDataFloat[1];
+				vertexData += m_State.m_vertextData.m_stride;
+
+				//取颜色坐标
+
+				RGBA* colorDataRGBA = (RGBA*)colorData;
+				pt0.m_color = colorDataRGBA[0];
+
+				colorData += m_State.m_colorData.m_stride;
+
+				colorDataRGBA = (RGBA*)colorData;
+				pt1.m_color = colorDataRGBA[0];
+				colorData += m_State.m_colorData.m_stride;
+
+				drawLine(pt0, pt1);
 			}
 			break;
 		}
 		case GT::GT_TRIANGLE: {
 
+			inCount = inCount / 3;
+			for (int i = 0; i < inCount; i++)
+			{
+				float* _vertexDataFloat = (float*)vertexData;
+				pt0.m_x = _vertexDataFloat[0];
+				pt0.m_y = _vertexDataFloat[1];
+				vertexData += m_State.m_vertextData.m_stride;
+
+				_vertexDataFloat = (float*)vertexData;
+				pt1.m_x = _vertexDataFloat[0];
+				pt1.m_y = _vertexDataFloat[1];
+				vertexData += m_State.m_vertextData.m_stride;
+
+				_vertexDataFloat = (float*)vertexData;
+				pt2.m_x = _vertexDataFloat[0];
+				pt2.m_y = _vertexDataFloat[1];
+				vertexData += m_State.m_vertextData.m_stride;
+
+
+				//取颜色坐标
+				RGBA* colorDataRGBA = (RGBA*)colorData;
+				pt0.m_color = colorDataRGBA[0];
+				colorData += m_State.m_colorData.m_stride;
+
+				colorDataRGBA = (RGBA*)colorData;
+				pt1.m_color = colorDataRGBA[0];
+				colorData += m_State.m_colorData.m_stride;
+
+				colorDataRGBA = (RGBA*)colorData;
+				pt2.m_color = colorDataRGBA[0];
+				colorData += m_State.m_colorData.m_stride;
+
+				//取uv坐标
+				floatV2* _uvData = (floatV2*)texCoordData;
+				pt0.m_uv = _uvData[0];
+				texCoordData += m_State.m_texCoordData.m_stride;
+
+				_uvData = (floatV2*)texCoordData;
+				pt1.m_uv = _uvData[0];
+				texCoordData += m_State.m_texCoordData.m_stride;
+
+				_uvData = (floatV2*)texCoordData;
+				pt2.m_uv = _uvData[0];
+				texCoordData += m_State.m_texCoordData.m_stride;
+
+				drawTriangle(pt0, pt1, pt2);
+			}
+
 			break;
 		}
 		default:
@@ -286,11 +355,12 @@ namespace GT {
 		}
 
 		for (; step <= totalStemp; posY += stepValue, ++step) {
-			int l1x = startX + 1 / k1 * stepValue * step;
+			// 如果 k1 或者 k2 为0 则 X 无变化,这里添加判断防止出现除0错误
+			int l1x = GT::UTool::dcmp(k1) == 0 ? startX : startX + 1 / k1 * stepValue * step;
 			float scale = step * 1.0f / totalStemp;
 			RGBA color1 = colorLerp(pt.m_color, pt1.m_color, scale);
 			floatV2 uv1 = uvLerp(pt.m_uv, pt1.m_uv, scale);
-			int l2x = startX + 1 / k2 * stepValue * step;
+			int l2x = GT::UTool::dcmp(k2) == 0 ? startX : startX + 1 / k2 * stepValue * step;
 			RGBA color2 = colorLerp(pt.m_color, pt2.m_color, scale);
 			floatV2 uv2 = uvLerp(pt.m_uv, pt2.m_uv, scale);
 

+ 34 - 9
OpenGL/src/WindowsProjectTest/WindowsProjectTest/WindowsProjectTest.cpp

@@ -62,15 +62,40 @@ void Render() {
     //_canvas->drawImage(200, 200, _image);
 
     // 测试贴图
-    _canvas->bindTexture(_bgImage);
-    _canvas->enableTexture(true);
-    _canvas->setTextureType(GT::Image::TX_CLAMP_TO_EDGE);
-
-	_canvas->drawTriangle(
-		GT::Point(0, wHeight / 2, GT::RGBA(), GT::floatV2(0, 0)),
-		GT::Point(wWidth, 0, GT::RGBA(), GT::floatV2(2, 0)),
-		GT::Point(wWidth / 2, wHeight, GT::RGBA(), GT::floatV2(1, 2))
-    );
+	//_canvas->bindTexture(_bgImage);
+	//_canvas->enableTexture(true);
+	//_canvas->setTextureType(GT::Image::TX_CLAMP_TO_EDGE);
+
+	//_canvas->drawTriangle(
+	//	GT::Point(0, wHeight / 2, GT::RGBA(), GT::floatV2(0, 0)),
+	//	GT::Point(wWidth, 0, GT::RGBA(), GT::floatV2(2, 0)),
+	//	GT::Point(wWidth / 2, wHeight, GT::RGBA(), GT::floatV2(1, 2))
+	//);
+
+    // 测试状态机
+
+    GT::Point ptArray[] =
+    {
+        {0.0f,0.0f,       GT::RGBA(255,0,0) , GT::floatV2(0,0)},
+        {300.0f,0.0f,    GT::RGBA(0,255,0) , GT::floatV2(1.0,0)},
+        {300.0f,300.0f,   GT::RGBA(0,0,255) , GT::floatV2(1.0,1.0)},
+
+        {300.0f,0.0f,       GT::RGBA(255,0,0) , GT::floatV2(1.0f,.0f)},
+        {300.0f,300.0f,    GT::RGBA(0,255,0) , GT::floatV2(.0f,.0f)},
+        {600.0f,500.0f,   GT::RGBA(0,0,255) , GT::floatV2(.0f,1.0f)},
+    };
+
+    //_canvas->drawTriangle(ptArray[3], ptArray[4], ptArray[5]);
+
+	_canvas->gtVertexPointer(2, GT::GT_FLOAT, sizeof(GT::Point), (GT::byte*)ptArray);
+	_canvas->gtColorPointer(1, GT::GT_FLOAT, sizeof(GT::Point), (GT::byte*)&ptArray[0].m_color);
+	_canvas->gtTexCoordPointer(1, GT::GT_FLOAT, sizeof(GT::Point), (GT::byte*)&ptArray[0].m_uv);
+
+	_canvas->enableTexture(true);
+    _canvas->setTextureType(GT::Image::TX_REPEAT);
+	_canvas->bindTexture(_bgImage);
+
+	_canvas->gtDrawArray(GT::GT_TRIANGLE, 0, 6);
 
 	// 将 hMem 的数据一次写入到 hDC 中
 	BitBlt(hDC, 0, 0, wWidth, wHeight, hMem, 0, 0, SRCCOPY);