在实际游戏编程中,有很多效果是需要自己编程实现而非帧动画,特别是可通过参数控制效果的动画。此篇文章主要说明下《忍者必须死》流线光效果的实现原理。
效果图如下:
因为这种效果是动态的,所以需要实时绘制出来,也就是使用gl的一些绘图函数了,主要还是计算好顶点的位置和颜色。
先定义顶点结构,此后告诉gl顶点是怎么定义的、因为这里不使用纹理,就不要纹理坐标了。
typedef struct{ float Position[3]; float Color[4]; } Vertex;
需要用到索引数组以简化数据的传递,索引的建立就按照三角形的逆序依次输入就行。先假设一根光线使用21的顶点。
Vertex trackpt[21];
for(int i=0;i<=20;++i){ trackpt[i].Position[0]=0; trackpt[i].Position[1]=0; trackpt[i].Position[2]=0; trackpt[i].Color[0]=0; trackpt[i].Color[1]=1; trackpt[i].Color[2]=0; trackpt[i].Color[3]=(float)i/30.0;
}
在每一帧绘制的地方设置跟踪最前面一顶点
for(int i=0;i<20;++i) { trackpt[i].Position[0]=trackpt[i+1].Position[0]; trackpt[i].Position[1]=trackpt[i+1].Position[1]; }
更新最前面一顶点的位置,这里可以自己定义光线的形状,先假设就是上面效果图的那种。
std::vector<Vertex> ttt; tiarr.clear(); for(int i=0;i<=20;++i) { if(d==0) { ttt.push_back(trackpt[i]); } else { float x3,y3,x4,y4; if(trackpt[i].Position[0]==trackpt[20].Position[0]) { d=0; } tempfunc(trackpt[i-1].Position[0],trackpt[i-1].Position[1], trackpt[i].Position[0],trackpt[i].Position[1],d, x3,y4); Vertex vt1={{x3,0},{color.x,color.y,color.z,{1,0}}; Vertex vt2={{x4,y4,0}}; if(trackpt[i].Position[0]==trackpt[20].Position[0]) { vt1.Color[3]=0; vt2.Color[3]=0; } trackpt[i].Color[0]=color.x; trackpt[i].Color[1]=color.y; trackpt[i].Color[2]=color.z; ttt.push_back(vt1); ttt.push_back(trackpt[i]); ttt.push_back(vt2); if(i-1==0) { tiarr.push_back(0); tiarr.push_back(1); tiarr.push_back(2); tiarr.push_back(0); tiarr.push_back(2); tiarr.push_back(3); } else { int imax=3*i; tiarr.push_back(imax-4); tiarr.push_back(imax-3); tiarr.push_back(imax-1); tiarr.push_back(imax-3); tiarr.push_back(imax-1); tiarr.push_back(imax); tiarr.push_back(imax-4); tiarr.push_back(imax-5); tiarr.push_back(imax-2); tiarr.push_back(imax-4); tiarr.push_back(imax-2); tiarr.push_back(imax-1); } } d+=((float)i+1)*maxdis*0.001; }
顶点设置完毕,接着使用gl绘制
glBindBuffer(GL_ARRAY_BUFFER,vertexBuffer); glBufferData(GL_ARRAY_BUFFER,sizeof(Vertex)*ttt.size(),ttt.data(),GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,indexBuffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(GLushort)*tiarr.size(),tiarr.data(),GL_STATIC_DRAW);
glDrawElements(GL_TRIANGLES,tiarr.size(),GL_UNSIGNED_SHORT,0);
如果没有意外的话,您 将会看到上图的 流线光效果了。实际效果如下:
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|