目录
什么是状态机?
基于状态机模式进行重构
Canvas.h源码
回顾之前两部分内容,我们做了:
我们思考OpenGL是基于什么思想来做的,或者说什么样的设计模式?
答:状态机。那么什么是状态机?
状态机:
白话解释:你给我什么参数,我就做什么事。给我true我就去做,false就不去做。
为什么用状态机?
基于以上考虑和分析,我们对现有代码进行小小的重构:
canvas.h:
添加数据元类型,绘图模式,数据元素类:
enum DATA_TYPE {GT_FLOAT=0,GT_INT=1};enum DRAW_MODE {GT_LINE=0,GL_TRIANGLE=1};struct DataElement {int m_size;DATA_TYPE m_type;int m_stride;//每次取点的步长byte* m_data;//数据空间指针DataElement() {m_size = -1;m_type = GT_FLOAT;m_stride = 0;m_data = nullptr;}};
将之前Canvan类中的一些变量,抽象出来,到一个Statement类中:
随后添加部分状态机接口:
//===========状态机接口===============
void gtVertexPointer(int _size, DATA_TYPE _type, int _stride, byte* _data);
void gtColorPointer(int _size, DATA_TYPE _type, int _stride, byte* _data);
void gtTexCoordPointer(int _size, DATA_TYPE _type, int _stride, byte* _data);
void gtDrawArray(DRAW_MODE _mode,int _first,int _count);//从first的点,画count个点
void Canvas::gtVertexPointer(int _size, DATA_TYPE _type, int _stride, byte* _data){m_state.m_vertexData.m_size = _size;m_state.m_vertexData.m_type = _type;m_state.m_vertexData.m_stride = _stride;m_state.m_vertexData.m_data = _data;}void Canvas::gtColorPointer(int _size, DATA_TYPE _type, int _stride, byte* _data){m_state.m_colorData.m_size = _size;m_state.m_colorData.m_type = _type;m_state.m_colorData.m_stride = _stride;m_state.m_colorData.m_data = _data;}void Canvas::gtTexCoordPointer(int _size, DATA_TYPE _type, int _stride, byte* _data){m_state.m_texCoordData.m_size = _size;m_state.m_texCoordData.m_type = _type;m_state.m_texCoordData.m_stride = _stride;m_state.m_texCoordData.m_data = _data;}void Canvas::gtDrawArray(DRAW_MODE _mode, int _first, int _count){}
为了方便查看,这里贴出Canvas.h的整体源码,也是对之前的一个总结梳理:
#pragma once
#include "GTMATH.hpp"
#include
#include
#include "Image.h"namespace GT {//点类class Point {public:int m_x;int m_y;RGBA m_color;floatV2 m_uv;Point(int _x = 0, int _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;}~Point() {}};enum DATA_TYPE {GT_FLOAT=0,GT_INT=1};enum DRAW_MODE {GT_LINE=0,GL_TRIANGLE=1};struct DataElement {int m_size;DATA_TYPE m_type;int m_stride;//每次取点的步长byte* m_data;//数据空间指针DataElement() {m_size = -1;m_type = GT_FLOAT;m_stride = 0;m_data = nullptr;}};struct Statement {bool m_useBlend;//是否启用alpha混合模式bool m_enableTexture;//是否启用纹理贴图const Image* m_texture;//纹理贴图素材Image::TEXTURE_TYPE m_texType;//纹理过滤byte m_alphaLimit;//大于此像素值才可以进行绘制DataElement m_vertexData;DataElement m_colorData;DataElement m_texCoordData;Statement() {m_useBlend = false;m_enableTexture = false;m_texture = nullptr;m_texType = Image::TX_REPEAT;m_alphaLimit = 0;}};//画布类,封装一些之后的图形APIclass Canvas {private:int m_width;int m_height;RGBA* m_buffer;Statement m_state;public:Canvas(int _width, int _height, void* _buffer) {if (_width <= 0 || _height <= 0) {m_width = -1;m_height = -1;m_buffer = nullptr;}m_width = _width;m_height = _height;m_buffer = (RGBA*)_buffer;m_state.m_useBlend = false;m_state.m_enableTexture = false;}~Canvas(){}//=========画布清洗============void clear() {if (m_buffer != nullptr) {memset(m_buffer, 0, sizeof(RGBA) * m_width * m_height);}}//=========画点操作============void drawPoint(int x, int y, RGBA _color) {if (x < 0 || x >= m_width || y < 0 || y >= m_height) {return;}m_buffer[y * m_width + x] = _color;}//根据真正的背景值取pixelRGBA getColor(int x, int y) {if (x < 0 || x >= m_width || y < 0 || y >= m_height) {return RGBA(0, 0, 0, 0);}return m_buffer[y * m_width + x];}//=========画线算法Brensenhem===void drawLine(Point pt1,Point pt2);//=========线性插值Lerp=========inline RGBA colorLerp(RGBA _color1, RGBA _color2, float _scale) {RGBA _color;_color.m_r = _color.m_r + (float)(_color2.m_r - _color1.m_r) * _scale;_color.m_g = _color.m_g + (float)(_color2.m_g - _color1.m_g) * _scale;_color.m_b = _color.m_b + (float)(_color2.m_b - _color1.m_b) * _scale;_color.m_a = _color.m_a + (float)(_color2.m_a - _color1.m_a) * _scale;return _color;}//=========画三角形==============void drawTriange(Point p1, Point p2, Point p3);void drawTriangeFlat(Point pFlat1, Point pFlat2, Point pt);//=========判断三角形是否与屏幕相交======bool judgeInRect(Point p, GT_RECT _rect);bool judgeInTriangle(Point pt, std::vector _ptArray);//==========图片操作=============void drawImage(int _x, int _y, Image* _image);void setAlphaLimit(byte _limit) { m_state.m_alphaLimit = _limit; }void setBlend(bool _useBlend) { m_state.m_useBlend = _useBlend; }//===========纹理===============void enableTexture(bool _enable) { m_state.m_enableTexture = _enable; }void bindTexture(const Image* _image) { m_state.m_texture = _image; }void setTextureType(Image::TEXTURE_TYPE _type) { m_state.m_texType = _type; }inline floatV2 uvLerp(floatV2 _uv1, floatV2 _uv2, float _scale) {floatV2 _uv;_uv.x = _uv1.x + (_uv2.x - _uv1.x) * _scale;_uv.y = _uv1.y + (_uv2.y - _uv1.y) * _scale;return _uv;}//===========状态机接口===============void gtVertexPointer(int _size, DATA_TYPE _type, int _stride, byte* _data);void gtColorPointer(int _size, DATA_TYPE _type, int _stride, byte* _data);void gtTexCoordPointer(int _size, DATA_TYPE _type, int _stride, byte* _data);void gtDrawArray(DRAW_MODE _mode,int _first,int _count);//从first的点,画count个点};
}