blitz3d/blitz3d/sprite.cpp

140 lines
3.1 KiB
C++

#include "std.h"
#include "sprite.h"
extern float stats3d[];
static float null[]={0,0,0};
static float tex_coords0[2][2]={ {0,0},{0,0} };
static float tex_coords1[2][2]={ {1,0},{1,0} };
static float tex_coords2[2][2]={ {1,1},{1,1} };
static float tex_coords3[2][2]={ {0,1},{0,1} };
extern gxRuntime *gx_runtime;
extern gxGraphics *gx_graphics;
static gxMesh *mesh;
static int mesh_size;
static vector<int> mesh_indices;
static int allocIndex(){
if( !mesh_indices.size() ){
if( mesh_size ) gx_graphics->freeMesh( mesh );
for( int k=0;k<256;++k ){
mesh_indices.push_back( mesh_size++ );
}
mesh=gx_graphics->createMesh( mesh_size*4,mesh_size*2,0 );
}
int n=mesh_indices.back();
mesh_indices.pop_back();
return n;
}
static void freeIndex( int n ){
mesh_indices.push_back( n );
if( mesh_indices.size()!=mesh_size ) return;
gx_graphics->freeMesh( mesh );
mesh_indices.clear();
mesh_size=0;
}
Sprite::Sprite():
view_mode(VIEW_MODE_FREE),
xhandle(0),yhandle(0),
rot(0),xscale(1),yscale(1),captured(false){
setRenderSpace( RENDER_SPACE_WORLD );
mesh_index=allocIndex();
}
Sprite::Sprite( const Sprite &t ):
Model(t),
view_mode(t.view_mode),
xhandle(t.xhandle),yhandle(t.yhandle),
rot(t.rot),xscale(t.xscale),yscale(t.yscale),captured(false){
mesh_index=allocIndex();
}
Sprite::~Sprite(){
freeIndex( mesh_index );
}
void Sprite::setRotation( float angle ){
rot=angle;
}
void Sprite::setScale( float x,float y ){
xscale=x;yscale=y;
}
void Sprite::setHandle( float x,float y ){
xhandle=x;yhandle=y;
}
void Sprite::setViewmode( int mode ){
view_mode=mode;
}
void Sprite::capture(){
Model::capture();
r_rot=rot;
r_xscale=xscale;
r_yscale=yscale;
captured=true;
}
bool Sprite::beginRender( float tween ){
Model::beginRender( tween );
if( tween==1 || !captured ){
r_rot=rot;
r_xscale=xscale;
r_yscale=yscale;
}else{
r_rot=(rot-r_rot)*tween+r_rot;
r_xscale=(xscale-r_xscale)*tween+r_xscale;
r_yscale=(yscale-r_yscale)*tween+r_yscale;
}
return true;
}
bool Sprite::render( const RenderContext &rc ){
Transform t=getRenderTform();
if( view_mode==VIEW_MODE_FREE ){
t.m=rc.getCameraTform().m;
}else if( view_mode==VIEW_MODE_UPRIGHT ){
t.m.k=rc.getCameraTform().m.k;t.m.orthogonalize();
}else if( view_mode==VIEW_MODE_UPRIGHT2 ){
t.m=yawMatrix( matrixYaw( rc.getCameraTform().m ) ) * t.m;
}
t.m=t.m * rollMatrix( r_rot ) * scaleMatrix( r_xscale,r_yscale,1 );
static Vector verts[4];
verts[0]=t * Vector( -1-xhandle, 1-yhandle,0 );
verts[1]=t * Vector( 1-xhandle, 1-yhandle,0 );
verts[2]=t * Vector( 1-xhandle,-1-yhandle,0 );
verts[3]=t * Vector( -1-xhandle,-1-yhandle,0 );
if( !rc.getWorldFrustum().cull( verts,4 ) ) return false;
mesh->lock( false );
int fv=mesh_index*4,ft=mesh_index*2;
mesh->setVertex( fv+0,&verts[0].x,null,tex_coords0 );
mesh->setVertex( fv+1,&verts[1].x,null,tex_coords1 );
mesh->setVertex( fv+2,&verts[2].x,null,tex_coords2 );
mesh->setVertex( fv+3,&verts[3].x,null,tex_coords3 );
if( rc.isReflected() ){
mesh->setTriangle( ft+0,0,2,1 );
mesh->setTriangle( ft+1,0,3,2 );
}else{
mesh->setTriangle( ft+0,0,1,2 );
mesh->setTriangle( ft+1,0,2,3 );
}
mesh->unlock();
enqueue( mesh,fv,4,ft,2 );
return false;
}