荡漾 --写在开头
在两个文件组合起来要实现的功能就是使得一个画片图水波般荡漾
首先来看头文件中的东西
Chapter I: distort.h
Part Ⅰ:attributes
private: hgeDistortionMesh(); // 构造函数,话说放在 private 是为了屏蔽这个接口,使得初始化过程中必须有参数 static HGE *hge; // 引擎指针 hgeVertex *disp_array; // 顶点数组 int nRows, nCols; // 行数、列数 float cellw,cellh; // 每个小格子的 w、h float tx,ty,width,height; // 图片纹理的属性 hgeQuad quad; // 装图片的那个矩形
Part Ⅱ:interface 这里不用functions是因为这里的函数都是要给用户使用的
public: // 构造、析构函数 hgeDistortionMesh(int cols, int rows); hgeDistortionMesh(const hgeDistortionMesh &dm); ~hgeDistortionMesh(); // 等号重载 hgeDistortionMesh& operator= (const hgeDistortionMesh &dm); // 渲染与清理 void Render(float x, float y); void Clear(DWORD col=0xFFFFFFFF, float z=0.5f); // 属性的 Getter 和 Setter void SetTexture(HTEXTURE tex); void SetTextureRect(float x, float y, float w, float h); void SetBlendMode(int blend); void SetZ(int col, int row, float z); void SetColor(int col, int row, DWORD color); // 这个 Setter 是重点!!! void SetDisplacement(int col, int row, float dx, float dy, int ref); HTEXTURE GetTexture() const {return quad.tex;} void GetTextureRect(float *x, float *y, float *w, float *h) const { *x=tx; *y=ty; *w=width; *h=height; } int GetBlendMode() const { return quad.blend; } float GetZ(int col, int row) const; DWORD GetColor(int col, int row) const; void GetDisplacement(int col, int row, float *dx, float *dy, int ref) const; int GetRows() { return nRows; } int GetCols() { return nCols; }
Chapter I: distort.cpp
hgeDistortionMesh(int cols, int rows)
构造函数:
- 基本参数舒适化
- 最主要的是顶点数组的初始化
在这个初始化的过程中,没有特定的纹理,只是建立的一个顶点数组
hgeDistortionMesh::hgeDistortionMesh(int cols, int rows) { int i; hge=hgeCreate(HGE_VERSION); nRows=rows; nCols=cols; cellw=cellh=0; quad.tex=0; quad.blend=BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_ZWRITE; disp_array=new hgeVertex[rows*cols]; for(i=0;i<rows*cols;i++) { disp_array[i].x=0.0f; disp_array[i].y=0.0f; disp_array[i].tx=0.0f; disp_array[i].ty=0.0f; disp_array[i].z=0.5f; disp_array[i].col=0xFFFFFFFF; } }
hgeDistortionMesh(int cols, int rows)
hgeDistortionMesh(const hgeDistortionMesh &dm)
构造函数
- 用一个线程的来初始化当前的类
- 采用深拷贝,将顶点数组完全复制过来
hgeDistortionMesh::hgeDistortionMesh(const hgeDistortionMesh &dm) { hge=hgeCreate(HGE_VERSION); nRows=dm.nRows; nCols=dm.nCols; cellw=dm.cellw; cellh=dm.cellh; tx=dm.tx; ty=dm.ty; width=dm.width; height=dm.height; quad=dm.quad; disp_array=new hgeVertex[nRows*nCols]; memcpy(disp_array, dm.disp_array, sizeof(hgeVertex)*nRows*nCols); }
hgeDistortionMesh
hgeDistortionMesh& hgeDistortionMesh::operator= (const hgeDistortionMesh &dm)
赋值符重载
- 类似根据现有对象建立对象
- 需要特别注意的是将现有的顶点数组释放,拷贝新的对象的顶点数组
hgeDistortionMesh& hgeDistortionMesh::operator= (const hgeDistortionMesh &dm) { if(this!=&dm) { nRows=dm.nRows; nCols=dm.nCols; cellw=dm.cellw; cellh=dm.cellh; tx=dm.tx; ty=dm.ty; width=dm.width; height=dm.height; quad=dm.quad; delete[] disp_array; disp_array=new hgeVertex[nRows*nCols]; memcpy(disp_array, dm.disp_array, sizeof(hgeVertex)*nRows*nCols); } return *this; }
operator= (const hgeDistortionMesh &dm)
~hgeDistortionMesh()
析构函数
- 释放引擎指针;释放顶点数组
hgeDistortionMesh::~hgeDistortionMesh() { delete[] disp_array; hge->Release(); }
~hgeDistortionMesh()
Clear(DWORD col, float z)
- 对所有顶点设置深度z,颜色col
void hgeDistortionMesh::Clear(DWORD col, float z) { int i,j; for(j=0; j<nRows; j++) for(i=0; i<nCols; i++) { disp_array[j*nCols+i].x=i*cellw; disp_array[j*nCols+i].y=j*cellh; disp_array[j*nCols+i].col=col; disp_array[j*nCols+i].z=z; } }
Clear(DWORD col, float z)
Render(float x, float y)
- 渲染函数,将一个整体切割成rows*cols来渲染
void hgeDistortionMesh::Render(float x, float y) { int i,j,idx; for(j=0; j<nRows-1; j++) for(i=0; i<nCols-1; i++) { idx=j*nCols+i; quad.v[0].tx=disp_array[idx].tx; quad.v[0].ty=disp_array[idx].ty; quad.v[0].x=x+disp_array[idx].x; quad.v[0].y=y+disp_array[idx].y; quad.v[0].z=disp_array[idx].z; quad.v[0].col=disp_array[idx].col; quad.v[1].tx=disp_array[idx+1].tx; quad.v[1].ty=disp_array[idx+1].ty; quad.v[1].x=x+disp_array[idx+1].x; quad.v[1].y=y+disp_array[idx+1].y; quad.v[1].z=disp_array[idx+1].z; quad.v[1].col=disp_array[idx+1].col; quad.v[2].tx=disp_array[idx+nCols+1].tx; quad.v[2].ty=disp_array[idx+nCols+1].ty; quad.v[2].x=x+disp_array[idx+nCols+1].x; quad.v[2].y=y+disp_array[idx+nCols+1].y; quad.v[2].z=disp_array[idx+nCols+1].z; quad.v[2].col=disp_array[idx+nCols+1].col; quad.v[3].tx=disp_array[idx+nCols].tx; quad.v[3].ty=disp_array[idx+nCols].ty; quad.v[3].x=x+disp_array[idx+nCols].x; quad.v[3].y=y+disp_array[idx+nCols].y; quad.v[3].z=disp_array[idx+nCols].z; quad.v[3].col=disp_array[idx+nCols].col; hge->Gfx_RenderQuad(&quad); } }
Render(float x, float y)
SetTextureRect(float x, float y, float w, float h)
- 对顶点数组进行初始化
void hgeDistortionMesh::SetTextureRect(float x, float y, float w, float h) { int i,j; float tw,th; tx=x; ty=y; width=w; height=h; if (quad.tex) { tw=(float)hge->Texture_GetWidth(quad.tex); th=(float)hge->Texture_GetHeight(quad.tex); } else { tw = w; th = h; } cellw=w/(nCols-1); cellh=h/(nRows-1); for(j=0; j<nRows; j++) for(i=0; i<nCols; i++) { disp_array[j*nCols+i].tx=(x+i*cellw)/tw; disp_array[j*nCols+i].ty=(y+j*cellh)/th; disp_array[j*nCols+i].x=i*cellw; disp_array[j*nCols+i].y=j*cellh; } }
SetTextureRect(float x, float y, float w, float h)
SetDisplacement(int col, int row, float dx, float dy, int ref) 核心部分!
void hgeDistortionMesh::SetDisplacement(int col, int row, float dx, float dy, int ref) { if(row<nRows && col<nCols) { switch(ref) { case HGEDISP_NODE: dx+=col*cellw; dy+=row*cellh; break; case HGEDISP_CENTER: dx+=cellw*(nCols-1)/2;dy+=cellh*(nRows-1)/2; break; case HGEDISP_TOPLEFT: break; } disp_array[row*nCols+col].x=dx; disp_array[row*nCols+col].y=dy; } }
SetDisplacement(int col, int row, float dx, float dy, int ref)
剩下的都是一些getter和setter
void hgeDistortionMesh::SetTexture(HTEXTURE tex) { quad.tex=tex; }
SetTexture(HTEXTURE tex)
void hgeDistortionMesh::SetBlendMode(int blend) { quad.blend=blend; }
SetBlendMode(int blend)
void hgeDistortionMesh::SetZ(int col, int row, float z) { if(row<nRows && col<nCols) disp_array[row*nCols+col].z=z; }
SetZ(int col, int row, float z)
void hgeDistortionMesh::SetColor(int col, int row, DWORD color) { if(row<nRows && col<nCols) disp_array[row*nCols+col].col=color; }
SetColor(int col, int row, DWORD color)
float hgeDistortionMesh::GetZ(int col, int row) const { if(row<nRows && col<nCols) return disp_array[row*nCols+col].z; else return 0.0f; }
GetZ(int col, int row) const
DWORD hgeDistortionMesh::GetColor(int col, int row) const { if(row<nRows && col<nCols) return disp_array[row*nCols+col].col; else return 0; }
GetColor(int col, int row)
void hgeDistortionMesh::GetDisplacement(int col, int row, float *dx, float *dy, int ref) const { if(row<nRows && col<nCols) { switch(ref) { case HGEDISP_NODE: *dx=disp_array[row*nCols+col].x-col*cellw; *dy=disp_array[row*nCols+col].y-row*cellh; break; case HGEDISP_CENTER: *dx=disp_array[row*nCols+col].x-cellw*(nCols-1)/2; *dy=disp_array[row*nCols+col].x-cellh*(nRows-1)/2; break; case HGEDISP_TOPLEFT: *dx=disp_array[row*nCols+col].x; *dy=disp_array[row*nCols+col].y; break; } } }
GetDisplacement(int col, int row, float *dx, float *dy, int ref) const
SetDisplacement(int col, int row, float dx, float dy, int ref)