目录
上次我们定义了一系列状态机接口,并遗留了:
void Canvas::gtDrawArray(DRAW_MODE _mode, int _first, int _count)
没有去实现,这次对他进行一个实现,一个利用状态机接口画线的功能。
这里直接上代码,并且连带着之前的关键类,方便理解:
- class Point {
- public:
- float m_x;
- float m_y;
- RGBA m_color;
- floatV2 m_uv;
-
- Point(float _x = 0, float _y = 0, RGBA _color = RGBA(0, 0, 0, 0), floatV2 _uv = floatV2(0.0, 0.0)) {
- m_x = _x, m_y = _y, m_color = _color, m_uv = _uv;
- }
-
- //===========================Render==================================================
- void Render() {
- _canvas->clear();
-
- GT::Point ptArray[] = {
- {0.0,200.0, GT::RGBA(255,0,0),GT::floatV2(0,0)},
- {800.0,200.0, GT::RGBA(0,255,0),GT::floatV2(1.0,0)},
- {100.0,600.0, GT::RGBA(0,0,255),GT::floatV2(1.0,1.0)},
- {800.0,300.0, GT::RGBA(0,0,255),GT::floatV2(1.0,1.0)},
- {200.0,150.0, GT::RGBA(0,0,255),GT::floatV2(1.0,1.0)}
- };
-
- _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->gtDrawArray(GT::GT_LINE, 0, 5);
-
- //在这里画到设备上,hMem相当于缓冲区
- BitBlt(hDC, 0, 0, wWidth, wHeight, hMem, 0, 0, SRCCOPY);
- }
- void Canvas::gtDrawArray(DRAW_MODE _mode, int _first, int _count)
- {
- GT::Point pt0, pt1;
- byte* _vertexData = m_state.m_vertexData.m_data;
- byte* _colorData = m_state.m_colorData.m_data;
- switch (_mode) {
- case GT_LINE:
- _count /= 2;
- for (int i = 0; i < _count; i ++) {
- //取坐标,按步长
- float* _vertexDataFloat = (float*)_vertexData;
- pt0.m_x = _vertexDataFloat[0];
- pt0.m_y = _vertexDataFloat[1];
- _vertexData += m_state.m_vertexData.m_stride;
-
- _vertexDataFloat = (float*)_vertexData;
- pt1.m_x = _vertexDataFloat[0];
- pt1.m_y = _vertexDataFloat[1];
- _vertexData += m_state.m_vertexData.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 GL_TRIANGLE:
- break;
- default:
- break;
- }
- }
简单解析一下:
首先我们从上往下看,我们有了一个Point类,里面包含了坐标xy,颜色RGBA信息m_color,以及uv坐标。
我们在Render函数里设定里五个点,分别是:
- GT::Point ptArray[] = {
- {0.0,200.0, GT::RGBA(255,0,0),GT::floatV2(0,0)},
- {800.0,200.0, GT::RGBA(0,255,0),GT::floatV2(1.0,0)},
- {100.0,600.0, GT::RGBA(0,0,255),GT::floatV2(1.0,1.0)},
- {800.0,300.0, GT::RGBA(0,0,255),GT::floatV2(1.0,1.0)},
- {200.0,150.0, GT::RGBA(0,0,255),GT::floatV2(1.0,1.0)}
- };
那么接下来的事就是如何利用这些信息来描绘这些点,并且调用drawLine来绘制直线了。
首先用gtVertexPointer获得点的信息:
_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);
也是同理,不多赘述。值得注意的是我们要从Point中的m_color部分开始取颜色的数据。
接下来就是如何遍历这个Point数组,来取数据,并且把取来的数据进行一个装配,配置好点pt1和pt2的坐标信息以及颜色信息,然后进行画线的过程。
- void Canvas::gtDrawArray(DRAW_MODE _mode, int _first, int _count)
- {
- GT::Point pt0, pt1;
- byte* _vertexData = m_state.m_vertexData.m_data;
- byte* _colorData = m_state.m_colorData.m_data;
- switch (_mode) {
- case GT_LINE:
- _count /= 2;
- for (int i = 0; i < _count; i ++) {
- //取坐标,按步长
- float* _vertexDataFloat = (float*)_vertexData;
- pt0.m_x = _vertexDataFloat[0];
- pt0.m_y = _vertexDataFloat[1];
- _vertexData += m_state.m_vertexData.m_stride;
-
- _vertexDataFloat = (float*)_vertexData;
- pt1.m_x = _vertexDataFloat[0];
- pt1.m_y = _vertexDataFloat[1];
- _vertexData += m_state.m_vertexData.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 GL_TRIANGLE:
- break;
- default:
- break;
- }
- }
测试一下:

五个点,只能画出两条线。在Canvas::gtDrawArray有一个_count /= 2;,作用就是这个。
(其实颜色不对,估计是和windows下的RGBA 值没有对应上,,有时间再看看改改吧。原理上是对的,暂时就可以了)
原理和画线是一样的,只不过每次绘制需要多加一个点,并且可以加入纹理的信息:
- //===========================Render==================================================
- void Render() {
- _canvas->clear();
-
- GT::Point ptArray[] = {
- {0.0,200.0, GT::RGBA(255,0,0),GT::floatV2(0,0)},
- {400.0,200.0, GT::RGBA(0,255,0),GT::floatV2(1.0,0)},
- {500.0,400.0, GT::RGBA(0,0,255),GT::floatV2(1.0,1.0)},
- {600.0,300.0, GT::RGBA(0,0,255),GT::floatV2(1.0,1.0)},
- {200.0,150.0, GT::RGBA(0,0,255),GT::floatV2(1.0,1.0)},
- {150.0,150.0, GT::RGBA(0,0,255),GT::floatV2(1.0,1.0)},
- {220.0,100.0, GT::RGBA(0,0,255),GT::floatV2(1.0,1.0)}
- };
-
- _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->gtDrawArray(GT::GL_TRIANGLE, 0, 7);
-
- //在这里画到设备上,hMem相当于缓冲区
- BitBlt(hDC, 0, 0, wWidth, wHeight, hMem, 0, 0, SRCCOPY);
- }
- void Canvas::gtDrawArray(DRAW_MODE _mode, int _first, int _count)
- {
- //三个点
- GT::Point pt0, pt1, pt2;
- byte* _vertexData = m_state.m_vertexData.m_data;
- byte* _colorData = m_state.m_colorData.m_data;
- byte* _texCoordData = m_state.m_texCoordData.m_data;
-
- switch (_mode) {
- case GT_LINE:
- ......
- break;
- case GL_TRIANGLE:
- _count /= 3;
- for (int i = 0; i < _count; i++) {
- //取坐标,按步长
- //pt0
- float* _vertexDataFloat = (float*)_vertexData;
- pt0.m_x = _vertexDataFloat[0];
- pt0.m_y = _vertexDataFloat[1];
- _vertexData += m_state.m_vertexData.m_stride;
- //pt1
- _vertexDataFloat = (float*)_vertexData;
- pt1.m_x = _vertexDataFloat[0];
- pt1.m_y = _vertexDataFloat[1];
- _vertexData += m_state.m_vertexData.m_stride;
- //pt2
- _vertexDataFloat = (float*)_vertexData;
- pt2.m_x = _vertexDataFloat[0];
- pt2.m_y = _vertexDataFloat[1];
- _vertexData += m_state.m_vertexData.m_stride;
-
- //取颜色坐标
- //pt1
- RGBA* _colorDataRGBA = (RGBA*)_colorData;
- pt0.m_color = _colorDataRGBA[0];
- _colorData += m_state.m_colorData.m_stride;
- //pt2
- _colorDataRGBA = (RGBA*)_colorData;
- pt1.m_color = _colorDataRGBA[0];
- _colorData += m_state.m_colorData.m_stride;
- //pt3
- _colorDataRGBA = (RGBA*)_colorData;
- pt2.m_color = _colorDataRGBA[0];
- _colorData += m_state.m_colorData.m_stride;
-
- //画三角形
- drawTriange(pt0, pt1, pt2);
- }
- break;
- default:
- break;
- }
- }
结果如下,(颜色不对,先忽略下。。):

我们之前绘制的点,都是默认从头到尾的,比如:
_canvas->gtDrawArray(GT::GL_TRIANGLE, 0, 7);
有7个点,从0到7这样取。那如果要是想从2到5这样取呢?回到函数定义上:
void gtDrawArray(DRAW_MODE _mode,int _first,int _count);//从first的点,画count个点
只需修改一下即可:
- void Canvas::gtDrawArray(DRAW_MODE _mode, int _first, int _count)
- {
- //三个点
- GT::Point pt0, pt1, pt2;
- byte* _vertexData = m_state.m_vertexData.m_data + _first * m_state.m_vertexData.m_stride;
- byte* _colorData = m_state.m_colorData.m_data + _first * m_state.m_colorData.m_stride;
- byte* _texCoordData = m_state.m_texCoordData.m_data + _first * m_state.m_texCoordData.m_stride;
- _count -= _first;
- .....................
测试:
_canvas->gtDrawArray(GT::GL_TRIANGLE, 2, 7);

取了5个点,只能画一个三角形。
.
void Canvas::gtDrawArray(DRAW_MODE _mode, int _first, int _count) 中:
- case GL_TRIANGLE:
- _count /= 3;
- for (int i = 0; i < _count; i++) {
- ......
-
- //取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;
测试:
- //===========================Render==================================================
- void Render() {
- _canvas->clear();
-
- GT::Point ptArray[] = {
- {0.0,0.0, GT::RGBA(255,0,0),GT::floatV2(0,0)},
- {500.0,0.0, GT::RGBA(0,255,0),GT::floatV2(1.0,0)},
- {500.0,300.0, GT::RGBA(0,0,255),GT::floatV2(1.0,1.0)},
- {0.0,300.0, GT::RGBA(0,0,255),GT::floatV2(0.0,1.0)},
- {0.0,0.0, GT::RGBA(0,0,255),GT::floatV2(0,0)},
- {500.0,300.0, GT::RGBA(0,0,255),GT::floatV2(1.0,1.0)}
- };
-
- _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->gtDrawArray(GT::GL_TRIANGLE, 0, 6);
-
- _canvas->enableTexture(true);
- _canvas->bindTexture(_bkImage);
-
- //在这里画到设备上,hMem相当于缓冲区
- BitBlt(hDC, 0, 0, wWidth, wHeight, hMem, 0, 0, SRCCOPY);
- }
