Jump to content

  • Log In with Google      Sign In   
  • Create Account

Sphere/Cylinder mapping with OpenGL


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 Tommato   Members   -  Reputation: 146

Like
0Likes
Like

Posted 29 March 2013 - 05:27 AM

Hi All
 
I need spherical/cylindrical map for arbitrary objects (not a reflection mapping). Actually I'm calculating UV manually. If a polygon crosses UV seam or pole, then I split it into several new polygons. It works but it's a big piece of code that makes app much slower. Are there better ways with OpenGL?
 
Thanks
Tom


Sponsor:

#2 blueshogun96   Crossbones+   -  Reputation: 1095

Like
0Likes
Like

Posted 29 March 2013 - 01:29 PM

Tbh, I don't know the exact algorithms used to do this, but I have managed to do this (at least the spherical) in OpenGL by copying some code from the DirectX 9 SDK (the older ones)  and changing the necessary features to work for OpenGL.  It's been years since I've done this so I can't remember exactly what I changed for the sphere, but it should be obvious enough IMO.

 

Here's the sphere: 

// Establish constants used in sphere generation
    DWORD dwNumSphereRings    = m_bHighTesselation ? 15 :  5;
    DWORD dwNumSphereSegments = m_bHighTesselation ? 30 : 10;
    FLOAT fDeltaRingAngle = ( D3DX_PI / dwNumSphereRings );
    FLOAT fDeltaSegAngle  = ( 2.0f * D3DX_PI / dwNumSphereSegments );

    D3DXVECTOR4 vT;
    FLOAT fScale;

    // Generate the group of rings for the sphere
    for( DWORD ring = 0; ring < (dwNumSphereRings/2); ring++ )
    {
        FLOAT r0 = sinf( (ring+0) * fDeltaRingAngle );
        FLOAT r1 = sinf( (ring+1) * fDeltaRingAngle );
        FLOAT y0 = cosf( (ring+0) * fDeltaRingAngle );
        FLOAT y1 = cosf( (ring+1) * fDeltaRingAngle );

        // Generate the group of segments for the current ring
        for( DWORD seg = 0; seg < (dwNumSphereSegments+1); seg++ )
        {
            FLOAT x0 =  r0 * sinf( seg * fDeltaSegAngle );
            FLOAT z0 =  r0 * cosf( seg * fDeltaSegAngle );
            FLOAT x1 =  r1 * sinf( seg * fDeltaSegAngle );
            FLOAT z1 =  r1 * cosf( seg * fDeltaSegAngle );

            // Add two vertices to the strip which makes up the sphere
            // (using the transformed normal to generate texture coords)
            (*vtx).p   = (*vtx).n   = D3DXVECTOR3(x0,y0,z0);
            D3DXVec3Transform( &vT, &(*vtx).n, &matWorldView );
            fScale = 1.37f / D3DXVec4Length( &vT );
            (*vtx).tu1 = 0.5f + fScale*vT.x;
            (*vtx).tv1 = 0.5f - fScale*vT.y;
            vtx++;

            (*vtx).p   = (*vtx).n   = D3DXVECTOR3(x1,y1,z1);
            D3DXVec3Transform( &vT, &(*vtx).n, &matWorldView );
            fScale = 1.37f / D3DXVec4Length( &vT );
            (*vtx).tu1 = 0.5f + fScale*vT.x;
            (*vtx).tv1 = 0.5f - fScale*vT.y;
            vtx++;
        }
    }

 

Then draw as a triangle strip.  You'll have to use your own matrix transformation and vector length functions to do the texture coordinates, but that shouldn't be hard.

 

The cylinder is much easier.  I don't know if you want an open or closed cylinder, I've never done the latter.

for( DWORD i=0; i<50; i++ )
    {
        FLOAT theta = (2*D3DX_PI*i)/(50-1);

        pVertices[2*i+0].position = D3DXVECTOR3( sinf(theta),-1.0f, cosf(theta) );
        pVertices[2*i+0].color    = 0xffffffff;
        pVertices[2*i+0].tu       = ((FLOAT)i)/(50-1);
        pVertices[2*i+0].tv       = 1.0f;

        pVertices[2*i+1].position = D3DXVECTOR3( sinf(theta), 1.0f, cosf(theta) );
        pVertices[2*i+1].color    = 0xff808080;
        pVertices[2*i+1].tu       = ((FLOAT)i)/(50-1);
        pVertices[2*i+1].tv       = 0.0f;
    }

 

Then draw as a triangle strip.  This example uses 100 vertices btw.

 

Not sure if this helped, but I tried. smile.png

 

Shogun.


Follow Shogun3D on the official website: http://shogun3d.net

 

blogger.png twitter.png tumblr_32.png facebook.png

 

"Yo mama so fat, she can't be frustum culled." - yoshi_lol


#3 Tommato   Members   -  Reputation: 146

Like
0Likes
Like

Posted 30 March 2013 - 01:26 AM

blueshougun96. thx for your reply. I've no problems with UV calculation itself, my question was about "should I do that" or, in other words. "can I avoid manual UV calcs?". An answer "no, you can't"  would be also informative for me, if so I'm doing things right

 

Thanks

Tom


Edited by Tommato, 30 March 2013 - 05:12 AM.


#4 blueshogun96   Crossbones+   -  Reputation: 1095

Like
0Likes
Like

Posted 01 April 2013 - 05:09 PM

Okay, my mistake.  

 

Generally speaking, it should be fine, that's what I'd do.  I don't know of any way to do it automatically, unless OpenGL has an equivalent of D3DTSS_TCI_x.  

 

Shogun


Follow Shogun3D on the official website: http://shogun3d.net

 

blogger.png twitter.png tumblr_32.png facebook.png

 

"Yo mama so fat, she can't be frustum culled." - yoshi_lol





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS