i am far from it atm, but i am messing around with the meshbase and working on putting something together
i have a weapon trail made of mesh (meshbase of vtxs and quads) using the tutorial "swing trail effect"
at some point i want to fade out the trail, meaning the quads needs to blend out.
i tried a few things but i couldnt figured out how to make the vtx.color working
Code:
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Mesh mesh;
const int C_EdgesNumber = 80;
Memc<flt> texturecoordinate;
int Edge_Lastindex=0;
class TrailEdge
{
Vtx3DSimple vtx[2];
}
class Trail // Swing Trail Effect
{
Memc<TrailEdge> edges ; // container of edges
int edge_offset=0 ; // index of the most recently updated edge
flt edge_time =0 , // how long current edge is being updated
interval =0.08; // time duration for updating one edge
ImagePtr image;
void create(int edges)
{
T.edges.setNumZero(edges);
image=UID(2657528853, 1232062558, 109060020, 3126898957); // setup texture
Edge_Lastindex=0;
// prepare vertex Y texture coordinates (they will always remain the same)
REPA(T.edges)
{
T.edges[i].vtx[0].tex.y=0;
T.edges[i].vtx[1].tex.y=1;
}
}
void update(C Vec &new_pos_start, C Vec &new_pos_end)
{
MaterialPtr ptr_mat = UID(2119596147, 1089744579, 936902274, 2062842600) ;
MaterialPtr ptr_mat2 = UID(2490987775, 1326908686, 341860011, 1625056079) ;
if(edges.elms())
{
int old_edge=edge_offset; // remember old edge index
edge_offset=(edge_offset+1)%edges.elms(); // increase current edge index
edge_time+=Time.d(); // increase edge time counter
if(edge_time>=interval) // if edge has been updated for too long, then leave this edge, and start updating next edge
{
edge_time=0; // reset counter
// copy texture coordinates from last edge
edges[edge_offset].vtx[0].tex.x=edges[old_edge].vtx[0].tex.x;
edges[edge_offset].vtx[1].tex.x=edges[old_edge].vtx[1].tex.x;
}
// always update latest edge position and tex coords
{
// position
edges[edge_offset].vtx[0].pos=new_pos_start;
edges[edge_offset].vtx[1].pos=new_pos_end ;
// tex coords
flt tex_progress=Time.d()*0.5;
edges[edge_offset].vtx[0].tex.x+=tex_progress;
edges[edge_offset].vtx[1].tex.x+=tex_progress;
if(mesh.parts.elms()<C_EdgesNumber)// create a new part
{
mesh.parts.New();
Edge_Lastindex = mesh.parts.elms()-1;
mesh.parts.last().base.create(4, 0, 0, 1, VTX_TEX0); // create part with 4 vertexes, 1 quad, and texture coordinates (vertex positions and face vertex indexes are always created, and don't need to be specified manually)
texturecoordinate.New()=0.1;
mesh.parts.last().material(ptr_mat);
if(Random(0, 1))mesh.parts.last().material(ptr_mat);
else mesh.parts.last().material(ptr_mat2);
}
else if(Edge_Lastindex>=(C_EdgesNumber-1))
{
Edge_Lastindex = 0;
texturecoordinate[Edge_Lastindex]=0.1;
}
else
{
Edge_Lastindex++;
texturecoordinate[Edge_Lastindex]=0.1;
}
MeshPart &part=mesh.parts[Edge_Lastindex];
MeshBase &base=part.base; // access software version
base.vtx.pos (0).set(edges[old_edge].vtx[1].pos.xy, edges[old_edge].vtx[1].pos.z); // set #0 vertex position
base.vtx.pos (1).set(new_pos_end.xy, new_pos_end.z); // set #1 vertex position
base.vtx.pos (2).set(new_pos_start.xy, new_pos_start.z); // set #2 vertex position
base.vtx.pos (3).set(edges[old_edge].vtx[0].pos.xy, edges[old_edge].vtx[0].pos.z); // set #3 vertex position
base.vtx.tex0(0).set(-texturecoordinate[Edge_Lastindex], texturecoordinate[Edge_Lastindex] ); // set #0 vertex texture coordinates
base.vtx.tex0(1).set( texturecoordinate[Edge_Lastindex], texturecoordinate[Edge_Lastindex] ); // set #1 vertex texture coordinates
base.vtx.tex0(2).set( texturecoordinate[Edge_Lastindex],-texturecoordinate[Edge_Lastindex] ); // set #2 vertex texture coordinates
base.vtx.tex0(3).set(-texturecoordinate[Edge_Lastindex],-texturecoordinate[Edge_Lastindex] ); // set #3 vertex texture coordinates
base.quad.ind(0).set( 0, 1, 2, 3); // set quad vertex indexes (#0 #1 #2 #3 vertexes)
REPA(mesh.parts)
{
texturecoordinate[i]+=Time.rd()/4;
MeshPart &part=mesh.parts[i];
MeshBase &base2=part.base; // access software version
base2.vtx.tex0(0).set(-texturecoordinate[i], texturecoordinate[i] ); // set #0 vertex texture coordinates
base2.vtx.tex0(1).set( texturecoordinate[i], texturecoordinate[i] ); // set #1 vertex texture coordinates
base2.vtx.tex0(2).set( texturecoordinate[i],-texturecoordinate[i] ); // set #2 vertex texture coordinates
base2.vtx.tex0(3).set(-texturecoordinate[i],-texturecoordinate[i] ); // set #3 vertex texture coordinates
}
mesh.setNormals(); // set automatic vertex normals
mesh.setAutoTanBin(); // calculate tangents and binormals if needed
mesh.setRender (); // set rendering versions from software versions
mesh.setBox (); // recalculate bounding box from vertexes
}
// always update all edge colors
flt alpha=1, alpha_step=1.0/flt(edges.elms()-2); // start from most recent edge, and set its alpha to full
FREPA(edges)
{
int index=Mod(edge_offset-i, edges.elms());
Color color=ColorAlpha(Color(255, 120, 0, 128), alpha);
edges[index].vtx[0].color=color;
edges[index].vtx[1].color=color;
if(i==0)alpha-=alpha_step*(edge_time/interval); // first step is not full, because the edge is only partially long
else alpha-=alpha_step;
}
}
}
void draw() // this will be called only in RM_BLEND mode
{
SetMatrix(); // set identity matrix
// before drawing custom graphics in RM_BLEND using 'VI' we need to set alpha blending mode in order to avoid accidental glow effect
D.alpha(ALPHA_RENDER_BLEND);
// use Vertex Index Buffer for custom drawing
//VI.shader(..); setup custom shader if needed
image().noise(Random(0, 255), Random(0, 255), Random(0, 255), 250);
VI.image(image()); // set image
VI.wrap (); // set wrap texture addressing mode
REP(edges.elms()-1)
{
// get indexes of neighbour edges
int next=Mod(edge_offset-i , edges.elms()),
prev=Mod(edge_offset-i-1, edges.elms());
// draw quad face from 4 points
VI.face(edges[prev].vtx[1],
edges[prev].vtx[0],
edges[next].vtx[0],
edges[next].vtx[1]);
}
VI.end();
}
}
/******************************************************************************/
MeshPtr weapon;
Matrix weapon_matrix;
Trail trail;
/******************************************************************************/
void InitPre()
{
INIT();
D.viewRange(15);
}
/******************************************************************************/
Bool Init()
{
// camera
Cam.dist=3;
Cam.yaw=PI;
Cam.pitch=-0.4;
Cam.setSpherical().set();
// sun
Sun.image=UID(1275694243, 1199742097, 1108828586, 1055787228);
Sun.pos =!Vec(1, 1, 3);
Sun.light_color_l=1-D.ambientColorL();
// sky
Sky.atmospheric();
// weapon
weapon=ObjectPtr(UID(3865949516, 1110691029, 816879537, 746462228))->mesh();
// trail effect
trail.create(C_EdgesNumber);
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Update()
{
if(Kb.bp(KB_ESC))return false;
Gui.update();
// update weapon motion
weapon_matrix.setPosUp(Vec(0, 0, 0.5), Vec(0, 0, 1))
.rotateY (Time.time()*4)
.move (Vec(0, 0.3, 1.2));
// update trail effect
trail.update(weapon->ext.down()*weapon_matrix,
weapon->ext.up ()*weapon_matrix);
// camera
Cam.transformByMouse(0.01, 10, CAMH_ZOOM|CAMH_ROT);
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_PREPARE:
{
weapon->draw(weapon_matrix);
/*LinkShaderParamChanges(changes); mesh.draw(..);
UnlinkShaderParamChanges(changes); */
mesh.draw(MatrixIdentity);
}break;
case RM_OUTLINE:
{
mesh.drawOutline(BLACK, MatrixIdentity);
}
case RM_BLEND:
{
//trail.draw();
}break;
}
}
void Draw()
{
Renderer(Render);
D.text(0, D.h()-0.1, S+Time.fps()+"//mesh elms: "+mesh.parts.elms());
}
/******************************************************************************/