View more

View more

View more

Image of the Day Submit

IOTD | Top Screenshots

The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

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.

3 replies to this topic

#1Tommato  Members

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

#2blueshogun96  Members

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.

Shogun.

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

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

"One objection to a “critique of C#” would be that you can’t talk about C# without talking about the whole “.Net experience”. However, one can approach the topic of Hitler without a complete discussion of Nationalist Socialism, so I feel justified." - Steve White.

#3Tommato  Members

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.

#4blueshogun96  Members

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

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

"One objection to a “critique of C#” would be that you can’t talk about C# without talking about the whole “.Net experience”. However, one can approach the topic of Hitler without a complete discussion of Nationalist Socialism, so I feel justified." - Steve White.

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.