C++模拟OpenGL库——图形学状态机接口封装(一):用状态模式重构部分代码及接口定义
创始人
2024-02-03 12:44:40
0

目录

什么是状态机?

基于状态机模式进行重构

Canvas.h源码


什么是状态机?

回顾之前两部分内容,我们做了:

  • 绘制点
  • 绘制线(Brensenham)
  • 绘制三角形(拆分法)
  • 图片操作(stb_image.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源码

为了方便查看,这里贴出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个点};
}

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...