コード例 #1
0
ファイル: Prop2D.cpp プロジェクト: kengonakajima/moyai
void Prop2D::render(Camera *cam, DrawBatchList *bl ) {
    if( debug_id ) {
        assertmsg(deck || grid_used_num > 0 || children_num > 0 || prim_drawer , "no deck/grid/prim_drawer is set. deck:%p grid:%d child:%d prim:%p", deck, grid_used_num, children_num, prim_drawer );
    }
    
	float camx=0.0f;
	float camy=0.0f;
	if(cam){
		camx = cam->loc.x;
		camy = cam->loc.y;
	}

	if( children_num > 0 && render_children_first ){
		for(int i=0;i<children_num;i++){
			Prop2D *p = (Prop2D*) children[i];
            if( p->visible ) {
                if( !p->parent_group ) {
                    p->parent_group = parent_group;
                }
                p->render( cam, bl );
            }
		}
	}

	if( grid_used_num > 0 ){
		glEnable(GL_TEXTURE_2D);
		glColor4f(color.r,color.g,color.b,color.a);        
		for(int i=0;i<grid_used_num;i++){
			Grid *grid = grids[i];
			if(!grid)break;
			if(!grid->visible)continue;
            if(!grid->index_table)continue;

			Deck *draw_deck = deck;
			if( grid->deck ) draw_deck = grid->deck;
			if( grid->fragment_shader ){
#if !(TARGET_IPHONE_SIMULATOR ||TARGET_OS_IPHONE || defined(__linux__) )
				glUseProgram(grid->fragment_shader->program );
#endif                
				grid->fragment_shader->updateUniforms();
			}

            if(!grid->mesh) {
                //                print("new grid mesh! wh:%d,%d", grid->width, grid->height );
                grid->mesh = new Mesh();
                VertexFormat *vf = DrawBatch::getVertexFormat( VFTYPE_COORD_COLOR_UV );
                IndexBuffer *ib = new IndexBuffer();
                VertexBuffer *vb = new VertexBuffer();
                vb->setFormat(vf);
                /*
                  3+--+--+--+--+
                   |  |  |  |  |
                  2+--+--+--+--+
                   |  |  |  |  |
                  1+--+--+--+--+
                   |  |  |  |  |
                  0+--+--+--+--+
                   0  1  2  3  4
                 */
                int quad_num = grid->width * grid->height;
                int triangle_num = quad_num * 2;
                int vert_num = quad_num * 4; // Can't share vertices because each vert has different UVs 
                vb->reserve( vert_num);
                ib->reserve( triangle_num*3 );
                grid->mesh->setVertexBuffer(vb);
                grid->mesh->setIndexBuffer(ib);
                grid->mesh->setPrimType( GL_TRIANGLES );

                grid->uv_changed = true;
                grid->color_changed = true;
            }

            if( grid->uv_changed || grid->color_changed ) {
                if(grid->debug) {
                    print("debug:%d Grid changed: uv:%d col:%d", grid->debug, grid->uv_changed, grid->color_changed );
                }
                grid->uv_changed = false;
                grid->color_changed = false;
                
                VertexBuffer *vb = grid->mesh->vb;
                IndexBuffer *ib = grid->mesh->ib;
                vb->unbless();
                ib->unbless();

                int quad_cnt=0;
                for(int y=0;y<grid->height;y++) {
                    for(int x=0;x<grid->width;x++) {
                        int ind = x+y*grid->width;
                        if(grid->debug) {
                            if(grid->texofs_table) {
                                prt("%.2f,%.2f ", grid->texofs_table[ind].x, grid->texofs_table[ind].y );
                            } else if( grid->index_table ) {
                                prt("%3d ", grid->index_table[ind] );
                            }
                        }
                        if( grid->index_table[ind] == Grid::GRID_NOT_USED ) continue;
                        
                        
                        Vec2 left_bottom, right_top;
                        float u0,v0,u1,v1;
                        draw_deck->getUVFromIndex( grid->index_table[ind], &u0,&v0,&u1,&v1,0,0,grid->uv_margin);
                        if(grid->texofs_table) {
                            float u_per_cell = draw_deck->getUperCell();
                            float v_per_cell = draw_deck->getVperCell();
                            u0 += grid->texofs_table[ind].x * u_per_cell;
                            v0 += grid->texofs_table[ind].y * v_per_cell;
                            u1 += grid->texofs_table[ind].x * u_per_cell;
                            v1 += grid->texofs_table[ind].y * v_per_cell;
                        }

                        //
                        // Q (u0,v0) - R (u1,v0)      top-bottom upside down.
                        //      |           |
                        //      |           |                        
                        // P (u0,v1) - S (u1,v1)
                        //
                        if(grid->xflip_table && grid->xflip_table[ind]) {
                            swapf( &u0, &u1 );
                        }
                        if(grid->yflip_table && grid->yflip_table[ind]) {
                            swapf( &v0, &v1 );
                        }
                        Vec2 uv_p(u0,v1), uv_q(u0,v0), uv_r(u1,v0), uv_s(u1,v1);

                        
                        // left bottom
                        const float d = 1;
                        int vi = quad_cnt * 4;
                        vb->setCoord(vi,Vec3(d*x-enfat_epsilon,d*y-enfat_epsilon,0));
                        if(grid->rot_table && grid->rot_table[ind]) vb->setUV(vi,uv_s); else vb->setUV(vi,uv_p);
                        if(grid->color_table) vb->setColor(vi, grid->color_table[ind]); else vb->setColor(vi, Color(1,1,1,1));
                        // right bottom
                        vb->setCoord(vi+1,Vec3(d*(x+1)+enfat_epsilon,d*y-enfat_epsilon,0));
                        if(grid->rot_table && grid->rot_table[ind]) vb->setUV(vi+1,uv_r); else vb->setUV(vi+1,uv_s);                        
                        if(grid->color_table) vb->setColor(vi+1,grid->color_table[ind]); else vb->setColor(vi+1, Color(1,1,1,1));
                        // left top
                        vb->setCoord(vi+2,Vec3(d*x-enfat_epsilon,d*(y+1)+enfat_epsilon,0));
                        if(grid->rot_table && grid->rot_table[ind]) vb->setUV(vi+2,uv_p); else vb->setUV(vi+2,uv_q);
                        if(grid->color_table) vb->setColor(vi+2,grid->color_table[ind]); else vb->setColor(vi+2, Color(1,1,1,1));
                        // right top
                        vb->setCoord(vi+3,Vec3(d*(x+1)+enfat_epsilon,d*(y+1)+enfat_epsilon,0));
                        if(grid->rot_table && grid->rot_table[ind]) vb->setUV(vi+3,uv_q); else vb->setUV(vi+3,uv_r);
                        if(grid->color_table) vb->setColor(vi+3,grid->color_table[ind]); else vb->setColor(vi+3, Color(1,1,1,1));

                        // TODO: no need to update index every time it changes.
                       
                        int indi = quad_cnt * 6; // 2 triangles = 6 verts per quad
                        ib->setIndex(indi++, quad_cnt*4+0 );
                        ib->setIndex(indi++, quad_cnt*4+2 );
                        ib->setIndex(indi++, quad_cnt*4+1 );
                        ib->setIndex(indi++, quad_cnt*4+1 );
                        ib->setIndex(indi++, quad_cnt*4+2 );
                        ib->setIndex(indi++, quad_cnt*4+3 );

                        quad_cnt++; // next quad!
                    }
                    if(grid->debug) print("");
                }
                ib->setRenderLen(quad_cnt*6);
            } 

            
            // draw
            if(!draw_deck) {
                print("no tex? (grid)");
                continue;
            }
            if( grid->mesh == NULL || grid->mesh->hasIndexesToRender() == false ) {
                continue;
            }
            FragmentShader *fs = fragment_shader;
            if( grid->fragment_shader ) fs = grid->fragment_shader;
            //            print("appendMesh, tex:%d vn:%d rn:%d", draw_deck->tex->tex, grid->mesh->vb->array_len, grid->mesh->ib->render_len );
            Vec2 finloc(loc.x+grid->rel_loc.x, loc.y+grid->rel_loc.y);
            Vec2 finscl(scl.x*grid->rel_scl.x, scl.y*grid->rel_scl.y);
            if(!fs)fs=default_fs;
            bl->appendMesh( getViewport(), fs, getBlendType(), draw_deck->tex->tex, finloc - Vec2(camx,camy), finscl, rot, grid->mesh, copy_mesh_at_draw );
		}
	}

	if(deck && index >= 0 ){
        float u0,v0,u1,v1;
        deck->getUVFromIndex( index, &u0,&v0,&u1,&v1,0,0,uv_margin);
        if(xflip) {
            swapf(&u0,&u1);
        }
        if(yflip) {
            swapf(&v0,&v1);
        }
        // Q (u0,v0) - R (u1,v0)      top-bottom upside down.
        //      |           |
        //      |           |                        
        // P (u0,v1) - S (u1,v1)
        Vec2 uv_p(u0,v1), uv_q(u0,v0), uv_r(u1,v0), uv_s(u1,v1);
        if(uvrot) {
            Vec2 tmp = uv_p;
            uv_p = uv_s;
            uv_s = uv_r;
            uv_r = uv_q;
            uv_q = tmp;
        }
        if(!fragment_shader)fragment_shader=default_fs;
        bl->appendSprite1( getViewport(),
                           fragment_shader,
                           getBlendType(),
                           deck->tex->tex,
                           color,
                           loc - Vec2(camx,camy) + draw_offset,
                           scl,
                           rot,
                           uv_p,
                           uv_q,
                           uv_r,
                           uv_s
                           );
	}

	if( children_num > 0 && (render_children_first == false) ){
		for(int i=0;i<children_num;i++){
			Prop2D *p = (Prop2D*) children[i];
			if(p->visible) {
                if( !p->parent_group ) {
                    p->parent_group = parent_group;
                }
                p->render( cam, bl );
            }
		}
	}

	// primitives should go over image sprites
	if( prim_drawer ){
		prim_drawer->drawAll( bl, getViewport(), loc - Vec2(camx,camy),scl,rot);
	}
}