예제 #1
0
/**
 * @brief GlSphere::makeSurface North pole is (0,radius, 0), south pole is (0, -radius, 0)
 * We use true normals. On a sphere vertex and normal have the same direction.
 * @param pointContainer
 */
void GLSphere::makeSurface(QVector<GLPoint> *pointContainer, QVector<GLuint> *indexContainer)
{
    GLBody::makeSurface(pointContainer, indexContainer);
    QVector3D southPole = -v_Z; //unit vector, must be scaled by radius later
    QVector3D northPole = v_Z;
    QVector3D vertex;
    QVector3D normal;
    QVector3D texCoord;
    QMatrix4x4 longitudeMatrix;
    QMatrix4x4 latitudeMatrix;
    int iSouthPole = 0; //indices for the poles
    int iNorthPole = 0;

    //start with south pole
    m_firstPoint = m_points->size();
    m_firstIndex = m_indices->size();
    iSouthPole = m_firstPoint;
    m_points->append(GLPoint(southPole * m_radius,  //vertex
                           southPole,               //normal
                           QVector3D(0.5, 0.0, 0.0),//texCoord at 0 longitude
                           m_color));

    int firstRow = 1;
    int lastRow = m_stacks - 1;
    int slice;
    int duplicates = 1;
    for(slice = 0; slice < m_slices; slice ++)
    {
        longitudeMatrix.setToIdentity();//always start from scratch
        longitudeMatrix.rotate(slice * 360.0 / m_slices, -v_Z);
        if(slice == m_slices / 2) //we need to switch from end of texture to start of texture here
            duplicates = 2;
        else duplicates = 1;
        for(int duplicate = 0; duplicate < duplicates; duplicate++) // create an extra column of points
        for(int stack = firstRow; stack <= lastRow; stack ++)       // to switch from end of texture to start of texture
        {
           latitudeMatrix.setToIdentity(); //always start from scratch
           latitudeMatrix.rotate(stack * 180.0 / m_stacks, v_Y);
           vertex = (southPole * latitudeMatrix) * longitudeMatrix;
           normal = vertex;
           vertex *= m_radius;
           double texX = (double)slice / (double) m_slices + 0.5;
           if(texX > 1.01)
               texX -= 1.0;
           if(duplicate == 1)
               texX = 0.0;
           texCoord = QVector3D(texX, (double)stack / (double)m_stacks, 0.0);  //floats required!!
           m_points->append(GLPoint(vertex, normal, texCoord, m_color));
        }
    }
    //end with north pole
    iNorthPole = m_points->size();
    m_points->append(GLPoint(northPole * m_radius,  //vertex
                           northPole,               //normal
                           QVector3D(0.5, 1.0, 0.0),//texCoord at 0 longitude
                           m_color));
    m_nextPoint = m_points->size();

    for(int i = m_firstPoint; i < m_nextPoint; i++) //move to final position
        (*m_points)[i].move(m_center);


    int rows = m_stacks - 1;
    for(slice = 0; slice < m_slices; slice += 2)
    {
        //go upwards from south pole to north pole
        m_indices->append(iSouthPole);
        for(int stack = firstRow; stack <= lastRow; stack ++)
        {
           m_indices->append(iSouthPole + rows * slice + stack); //left meridian
           m_indices->append(iSouthPole + rows * slice + rows + stack ); //right meridian
        }
        m_indices->append(iNorthPole);

        //now go downwards back to southpole
        for(int stack = lastRow; stack >= firstRow; stack --)
        {
           m_indices->append(iSouthPole + rows * slice + rows + stack); //left meridian
           m_indices->append(iSouthPole + rows * slice + rows + rows + stack); //right meridian
        }
        //southpole will be added in next slice
    }

    //Close the sphere
    //go upwards from south pole to north pole
    m_indices->append(iSouthPole);
    for(int stack = firstRow; stack <= lastRow; stack ++)
    {
       m_indices->append(iSouthPole + rows * slice + stack); //left meridian = last meridian
       m_indices->append(iSouthPole + stack ); //right meridian = first meridian
    }
    m_indices->append(iNorthPole);

    m_indices->append(iSouthPole); //finally add south pole

    m_nextIndex = m_indices->size();

}
예제 #2
0
    void GLText::draw()
    {

        glEnable(GL_TEXTURE_2D);

        double pos=0;
        color.use();

        sf::Texture texture(font->getTexture(size));
        sf::Vector2u texsize=texture.getSize();
        sf::Texture::bind(&texture);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        int min_back=0;
        for (unsigned int i=0; i<message.size(); ++i)
        {
            sf::Glyph glyph=font->getGlyph(message[i],size,false);
            if (i==0)
                min_back=glyph.bounds.top;
            if (min_back>glyph.bounds.top)
                min_back=glyph.bounds.top;
        }

        GLPoint poz=position;
        poz.x-=origin.x;
        poz.y-=origin.y;
        poz.z-=origin.z;

        for (unsigned int i=0; i<message.size(); ++i)
        {
            sf::Glyph glyph=font->getGlyph(message[i],size,false);
            if (message[i]==' ')
                glyph.bounds.width=size/4;
            glBegin(GL_POLYGON);
            glTexCoord2d(glyph.textureRect.left/double(texsize.x),glyph.textureRect.top/double(texsize.y));

            GLPoint help(pos,glyph.bounds.top-min_back,0);
            rotate3d(help,rotation.x,rotation.y,rotation.z);
            help.x*=scale.x;
            help.y*=scale.y;
            help.z*=scale.z;
            help.x+=poz.x;
            help.y+=poz.y;
            help.z+=poz.z;
            help.use();

            glTexCoord2d((glyph.textureRect.left+glyph.textureRect.width)/double(texsize.x),glyph.textureRect.top/double(texsize.y));

            help=GLPoint(pos+glyph.bounds.width,glyph.bounds.top-min_back);
            rotate3d(help,rotation.x,rotation.y,rotation.z);
            help.x*=scale.x;
            help.y*=scale.y;
            help.z*=scale.z;
            help.x+=poz.x;
            help.y+=poz.y;
            help.z+=poz.z;
            help.use();

            glTexCoord2d((glyph.textureRect.left+glyph.textureRect.width)/double(texsize.x),(glyph.textureRect.top+glyph.textureRect.height)/double(texsize.y));

            help=GLPoint(pos+glyph.bounds.width,glyph.bounds.top-min_back+glyph.bounds.height);
            rotate3d(help,rotation.x,rotation.y,rotation.z);
            help.x*=scale.x;
            help.y*=scale.y;
            help.z*=scale.z;
            help.x+=poz.x;
            help.y+=poz.y;
            help.z+=poz.z;
            help.use();

            glTexCoord2d(glyph.textureRect.left/double(texsize.x),(glyph.textureRect.top+glyph.textureRect.height)/double(texsize.y));

            help=GLPoint(pos,glyph.bounds.top+glyph.bounds.height-min_back);
            rotate3d(help,rotation.x,rotation.y,rotation.z);
            help.x*=scale.x;
            help.y*=scale.y;
            help.z*=scale.z;
            help.x+=poz.x;
            help.y+=poz.y;
            help.z+=poz.z;
            help.use();

            glEnd();
            pos+=glyph.bounds.width;
        }
        sf::Texture::bind(NULL);
        glDisable(GL_TEXTURE_2D);
    }
예제 #3
0
 GLScene::ObjectData::ObjectData()
 {
     scale=GLPoint(1);
 }
예제 #4
0
 GLText::GLText()
 {
     font=NULL;
     size=1;
     scale=GLPoint(1);
 }