Esempio n. 1
0
S32 LLFace::renderElements(const U16 *index_array) const
{
	S32 ret = 0;
	
	if (isState(GLOBAL))
	{	
		ret = pushVertices(index_array);
	}
	else
	{
		glPushMatrix();
		glMultMatrixf((float*)getRenderMatrix().mMatrix);
		ret = pushVertices(index_array);
		glPopMatrix();
	}
	
	return ret;
}
Esempio n. 2
0
void StretchableSprite2D::UpdateSourceBatches()
{
    /* The general idea is to subdivide the image in the following 9 patches

       *---*---*---*
     2 |   |   |   |
       *---*---*---*
     1 |   |   |   |
       *---*---*---*
     0 |   |   |   |
       *---*---*---*
         0   1   2

     X scaling works as follow: as long as the scale determines that the total
     width is larger than the sum of the widths of columns 0 and 2, only
     column 1 is scaled. Otherwise, column 1 is removed and columns 0 and 2 are
     scaled, maintaining their relative size. The same principle applies for
     Y scaling (but with lines rather than columns). */

    if (!sourceBatchesDirty_ || !sprite_ || (!useTextureRect_ && !sprite_->GetTextureRectangle(textureRect_, flipX_, flipY_)))
        return;

    Vector<Vertex2D>& vertices = sourceBatches_[0].vertices_;
    vertices.Clear();

    auto effectiveBorder = calcEffectiveBorder(border_, drawRect_.Size());

    float xs[4], ys[4], us[4], vs[4]; // prepare all coordinates
    const auto signedScale = node_->GetSignedWorldScale();

    prepareXYCoords(xs, drawRect_.min_.x_, drawRect_.max_.x_, effectiveBorder.min_.x_, effectiveBorder.max_.x_, signedScale.x_);
    prepareXYCoords(ys, drawRect_.min_.y_, drawRect_.max_.y_, effectiveBorder.min_.y_, effectiveBorder.max_.y_, signedScale.y_);

    prepareUVCoords(us, textureRect_.min_.x_, textureRect_.max_.x_, effectiveBorder.min_.x_, effectiveBorder.max_.x_,
        drawRect_.max_.x_ - drawRect_.min_.x_);
    prepareUVCoords(vs, textureRect_.min_.y_, textureRect_.max_.y_, -effectiveBorder.min_.y_,
        -effectiveBorder.max_.y_ /* texture y direction inverted*/, drawRect_.max_.y_ - drawRect_.min_.y_);

    Vertex2D vtx[4][4]; // prepare all vertices
    prepareVertices(vtx, xs, ys, us, vs, color_.ToUInt(), node_->GetWorldPosition(), node_->GetWorldRotation());

    pushVertices(vertices, vtx); // push the vertices that make up each patch

    sourceBatchesDirty_ = false;
}
Esempio n. 3
0
// tesselates the contours in preparation for a 3D output;
// returns true if all was fine, false otherwise
bool VRML_LAYER::Tesselate( VRML_LAYER* holes, bool aHolesOnly )
{
    if( !tess )
    {
        error = "Tesselate(): GLU tesselator was not initialized";
        return false;
    }

    pholes  = holes;
    Fault   = false;

    if( aHolesOnly )
        gluTessProperty( tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NEGATIVE );
    else
        gluTessProperty( tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE );


    if( contours.size() < 1 || vertices.size() < 3 )
    {
        error = "Tesselate(): not enough vertices";
        return false;
    }

    // finish the winding calculation on all vertices prior to setting 'fix'
    if( !fix )
    {
        for( unsigned int i = 0; i < contours.size(); ++i )
        {
            if( contours[i]->size() < 3 )
                continue;

            VERTEX_3D* vp0 = vertices[ contours[i]->back() ];
            VERTEX_3D* vp1 = vertices[ contours[i]->front() ];
            areas[i] += ( vp1->x - vp0->x ) * ( vp1->y + vp0->y );
        }
    }

    // prevent the addition of any further contours and contour vertices
    fix = true;

    // clear temporary internals which may have been used in a previous run
    clearTmp();

    // request an outline
    gluTessProperty( tess, GLU_TESS_BOUNDARY_ONLY, GL_TRUE );

    // adjust internal indices for extra points and holes
    if( holes )
        hidx = holes->GetSize();
    else
        hidx = 0;

    eidx = idx + hidx;

    if( aHolesOnly && ( checkNContours( true ) == 0 ) )
    {
        error = "tesselate(): no hole contours";
        return false;
    }
    else if( !aHolesOnly && ( checkNContours( false ) == 0 ) )
    {
        error = "tesselate(): no solid contours";
        return false;
    }

    // open the polygon
    gluTessBeginPolygon( tess, this );

    if( aHolesOnly )
    {
        pholes = NULL;  // do not accept foreign holes
        hidx = 0;
        eidx = idx;

        // add holes
        pushVertices( true );

        gluTessEndPolygon( tess );

        if( Fault )
            return false;

        return true;
    }

    // add solid outlines
    pushVertices( false );

    // close the polygon
    gluTessEndPolygon( tess );

    if( Fault )
        return false;

    // if there are no outlines we cannot proceed
    if( outline.empty() )
    {
        error = "tesselate(): no points in result";
        return false;
    }

    // at this point we have a solid outline; add it to the tesselator
    gluTessBeginPolygon( tess, this );

    if( !pushOutline( NULL ) )
        return false;

    // add the holes contained by this object
    pushVertices( true );

    // import external holes (if any)
    if( hidx && ( holes->Import( idx, tess ) < 0 ) )
    {
        std::ostringstream ostr;
        ostr << "Tesselate():FAILED: " << holes->GetError();
        error = ostr.str();
        return false;
    }

    if( Fault )
        return false;

    // erase the previous outline data and vertex order
    // but preserve the extra vertices
    while( !outline.empty() )
    {
        delete outline.back();
        outline.pop_back();
    }

    ordmap.clear();
    ord = 0;

    // go through the vertex lists and reset ephemeral parameters
    for( unsigned int i = 0; i < vertices.size(); ++i )
    {
        vertices[i]->o = -1;
    }

    for( unsigned int i = 0; i < extra_verts.size(); ++i )
    {
        extra_verts[i]->o = -1;
    }

    // close the polygon; this creates the outline points
    // and the point ordering list 'ordmap'
    solid.clear();
    gluTessEndPolygon( tess );

    // repeat the last operation but request a tesselated surface
    // rather than an outline; this creates the triangles list.
    gluTessProperty( tess, GLU_TESS_BOUNDARY_ONLY, GL_FALSE );

    gluTessBeginPolygon( tess, this );

    if( !pushOutline( holes ) )
        return false;

    gluTessEndPolygon( tess );

    if( Fault )
        return false;

    return true;
}
Esempio n. 4
0
// tesselates the contours in preparation for a 3D output;
// returns true if all was fine, false otherwise
bool VRML_LAYER::Tesselate( VRML_LAYER* holes )
{
    if( !tess )
    {
        error = "Tesselate(): GLU tesselator was not initialized";
        return false;
    }

    pholes  = holes;
    Fault   = false;

    if( contours.size() < 1 || vertices.size() < 3 )
    {
        error = "Tesselate(): not enough vertices";
        return false;
    }

    // finish the winding calculation on all vertices prior to setting 'fix'
    if( !fix )
    {
        for( unsigned int i = 0; i < contours.size(); ++i )
        {
            if( contours[i]->size() < 3 )
                continue;

            VERTEX_3D* vp0 = vertices[ contours[i]->back() ];
            VERTEX_3D* vp1 = vertices[ contours[i]->front() ];
            areas[i] += ( vp1->x - vp0->x ) * ( vp1->y + vp0->y );
        }
    }

    // prevent the addition of any further contours and contour vertices
    fix = true;

    // clear temporary internals which may have been used in a previous run
    clearTmp();

    // request an outline
    gluTessProperty( tess, GLU_TESS_BOUNDARY_ONLY, GL_TRUE );

    // adjust internal indices for extra points and holes
    if( holes )
        hidx = holes->GetSize();
    else
        hidx = 0;

    eidx = idx + hidx;

    // open the polygon
    gluTessBeginPolygon( tess, this );

    pushVertices( false );

    // close the polygon
    gluTessEndPolygon( tess );

    if( Fault )
        return false;

    // push the (solid) outline to the tesselator
    if( !pushOutline( holes ) )
        return false;

    // add the holes contained by this object
    pushVertices( true );

    // import external holes (if any)
    if( hidx && ( holes->Import( idx, tess ) < 0 ) )
    {
        std::ostringstream ostr;
        ostr << "Tesselate():FAILED: " << holes->GetError();
        error = ostr.str();
        return NULL;
    }

    if( Fault )
        return false;

    // erase the previous outline data and vertex order
    // but preserve the extra vertices
    for( int i = outline.size(); i > 0; --i )
    {
        delete outline.back();
        outline.pop_back();
    }

    for( unsigned int i = ordmap.size(); i > 0; --i )
        ordmap.pop_back();

    // go through the vertex lists and reset ephemeral parameters
    for( unsigned int i = 0; i < vertices.size(); ++i )
    {
        vertices[i]->o = -1;
    }

    for( unsigned int i = 0; i < extra_verts.size(); ++i )
    {
        extra_verts[i]->o = -1;
    }

    ord = 0;

    // close the polygon; we now have all the data necessary for the tesselation
    gluTessEndPolygon( tess );

    // request a tesselated surface
    gluTessProperty( tess, GLU_TESS_BOUNDARY_ONLY, GL_FALSE );

    if( !pushOutline( holes ) )
        return false;

    gluTessEndPolygon( tess );

    if( Fault )
        return false;

    return true;
}