A Texture Mapping Technique Using OpenGL

Environment: VC++6, Win32

Overview

Rendering an image on the surface of an object can be accomplished with just a few steps by using OpenGL. My last article on OpenGL demonstrated a simple method for drawing OpenGL output directly to a device independent bitmap (DIB), and for loading OpenGL commands into a call list to make rendering more efficient. This article builds on that framework and demonstrates how to overlay an image on the surface of an object. In this example, the object surfaces are spheres and the textures are images representing some of the planets in our solar system.

The following steps can be used to texture map objects:

  1. Load each texture into a 24-bit DIBSection object. (A regular DIB will do, but making it a DIB section doesn't hurt.)
  2. Tell the OpenGL library how your image is laid out by calling glTexImage2D. You can specify the image as RGB, or BGR, and so forth. Note: the width and height of the image can be different, but the dimensions have to each be powers of 2 plus any border width you specify in the call to glTexImage2D.
  3. As you build your model by specifying vertices, use the glTexCoord2d to specify the location within the texture image corresponding to each model vertex. Note: the image coordinates are scaled from 0 to 1; so, if your image is 100x100 pixels wide and you want to connect a vertex with the center pixel, you call glTexCoord2d(0.50,0.50).

Thats it! You're done.

In case you want to take texture mapping a little farther, there are two other things worth investigating:

The function glTexImage2D provides support for mip-mapping. Mip-mapping is basically when you use multiple images of the same thing at different resolutions. Let's say you want to map an image of the Earth onto a sphere. Using a smaller texture image will improve performance without ruining the model as long as the sphere is small. When the sphere is large (takes up a significant portion of the screen), you might want a higher-resolution image to avoid stretching artifacts: mip-mapping allows you to do that.

Another variation on texture mapping can be accomplished by using the glTexEnvf function. In the sample project, I used the following call: glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);. However, you may replace GL_DECAL with GL_BLEND or GL_MODULATE to get a different texturing effect.

The following code sample shows how to actually connect image coordinates with your model's vertices:

namespace GEO {
  const double PI = 3.14159265359;
  const double TWOPI = 6.28318530718;
  const double DE2RA = 0.01745329252;
  const double RA2DE = 57.2957795129;
  const double FLATTENING = 1.0/298.26;
  const double PIOVER2 = 1.570796326795;
}

if (m_have_texture)
{
  glTexImage2D(GL_TEXTURE_2D,0,3,m_texture_dib.Width(),
                                 m_texture_dib.Height(),
    0,GL_BGR_EXT,GL_UNSIGNED_BYTE,(GLvoid *)
                                 m_texture_dib.GetBits());

  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
                  GL_NEAREST);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
                  GL_NEAREST);
  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

  //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
  //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

  glEnable( GL_TEXTURE_2D );
}
else
{
  glDisable( GL_TEXTURE_2D );
}

glBegin( GL_TRIANGLES );

start_lat = -90;
start_lon = 0.0;
R = 1.0;

lat_incr = 180.0 / NumLatitudes;
lon_incr = 360.0 / NumLongitudes;

int row, col;

for (col = 0; col < NumLongitudes; col++){
  phi1 = (start_lon + col * lon_incr) * GEO::DE2RA;
  phi2 = (start_lon + (col + 1) * lon_incr) * GEO::DE2RA;
  for (row = 0; row < NumLatitudes; row++){
    theta1 = (start_lat + row * lat_incr) * GEO::DE2RA;
    theta2 = (start_lat + (row + 1) * lat_incr) * GEO::DE2RA;

    u[0] = R * cos(phi1) * cos(theta1);    //x
    u[1] = R * sin(theta1);                //y
    u[2] = R * sin(phi1) * cos(theta1);    //z

    v[0] = R * cos(phi1) * cos(theta2);    //x
    v[1] = R * sin(theta2);                //y
    v[2] = R * sin(phi1) * cos(theta2);    //z

    w[0] = R * cos(phi2) * cos(theta2);    //x
    w[1] = R * sin(theta2);                //y
    w[2] = R * sin(phi2) * cos(theta2);    //z

    NormalVector(u,v,w,n);
    glNormal3dv(n);
    glTexCoord2d((180.0 - phi1*GEO::RA2DE)/360.0,
                 (theta1 + GEO::PIOVER2)*GEO::RA2DE/180.0);
    glVertex3dv(u);
    glTexCoord2d((180.0 - phi1*GEO::RA2DE)/360.0,
                 (theta2 + GEO::PIOVER2)*GEO::RA2DE/180.0);
    glVertex3dv(v);
    glTexCoord2d((180.0 - phi2*GEO::RA2DE)/360.0,
                 (theta2 + GEO::PIOVER2)*GEO::RA2DE/180.0);
    glVertex3dv(w);

    v[0] = R * cos(phi2) * cos(theta1);    //x
    v[1] = R * sin(theta1);                //y
    v[2] = R * sin(phi2) * cos(theta1);    //z

    NormalVector(u,w,v,n);
    glNormal3dv(n);
    glTexCoord2d((180.0 - phi1*GEO::RA2DE)/360.0,
                 (theta1 + GEO::PIOVER2)*GEO::RA2DE/180.0);
    glVertex3dv(u);
    glTexCoord2d((180.0 - phi2*GEO::RA2DE)/360.0,
                 (theta2 + GEO::PIOVER2)*GEO::RA2DE/180.0);
    glVertex3dv(w);
    glTexCoord2d((180.0 - phi2*GEO::RA2DE)/360.0,
                 (theta1 + GEO::PIOVER2)*GEO::RA2DE/180.0);
    glVertex3dv(v);

    glDisable( GL_TEXTURE_2D );
  }
}

glEnd();

Sample Project

I only have textures for the Earth, Mars, Jupiter, and Saturn, so I just picked a color for the other planets. If time permitted, it would be nice to see a ring around Saturn.

Enjoy.

Downloads

Download demo project - 405 Kb



About the Author

Andy McGovern

Andy McGovern - Software Developer/Engineer. Special interests: astronomy, image processing, orbital mechanics, mathematics. Currently work at the Johns Hopkins University Applied Physics Laboratory on the science operations team for the CRISM instrument on the Mars Reconnaissance Orbiter.

Comments

  • Right Here Is A Practice That's Also Assisting gucci-gurus Growing

    Posted by BobHotgloff on 05/03/2013 02:15pm

    A quick review instructs you all the details of nike together with the thing that you want to accomplish straight away. [url=http://www.mizunogoruhujp.com/]ミズノ グローブ[/url] The Actual Key To Success For nike [url=http://www.mizunogoruhujp.com/ミズノ-ゴルフクラブ-c-1.html]ミズノ アイアン[/url] Compact write-up helps you with the most important details on nike and consequently what you must do right now. [url=http://www.mizunogoruhujp.com/ゴルフグローブ-c-33.html]グローブ ミズノ[/url] The things that all others engages in when considering nike and the thing you are looking to try and do completely different. [url=http://www.mizunogoruhujp.com/ゴルフバッグ-c-7.html]ミズノゴルフ[/url] Independent site lets out 5 all new things over nike that noone is speaking of. [url=http://www.mizunogoruhu.com/]ミズノゴルフ[/url] A certain double sprain on nike [url=http://www.mizunogoruhu.com/ミズノmizuno-クラブ-c-4.html]ミズノ グラブ[/url] Appliances and developing throughout Vegas - nike has left without any kind regards [url=http://www.mizunogoruhu.com/ミズノmizuno-アイアン-c-3.html]ミズノ アイアン[/url] Economical guidelines for nike which can be used starting off as we speak. [url=http://www.mizunogoruhu.com/ミズノmizuno-バッグ-c-5.html]ミズノ[/url] Shorter post discloses the proven facts about nike and the way it could effect users.

    Reply
  • More concessions with herveleger, more mutate touched in the head!

    Posted by jonemkig on 04/26/2013 09:30am

    sheilastewardbe in fervency withreviewboldcater to in

    Reply
  • Compressed textures

    Posted by Legacy on 04/03/2003 12:00am

    Originally posted by: U'dragon

    What would be really nice is an example of using compressed textures with OpenGL under Windows.

    Can't seem to find anything related to that in the MSDN.

    Reply
  • why don't you insert a rendered image with this article ?!

    Posted by Legacy on 04/02/2003 12:00am

    Originally posted by: Zhefu Zhang

    why don't you insert a rendered image with this article ?!

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • With JRebel, developers get to see their code changes immediately, fine-tune their code with incremental changes, debug, explore and deploy their code with ease (both locally and remotely), and ultimately spend more time coding instead of waiting for the dreaded application redeploy to finish. Every time a developer tests a code change it takes minutes to build and deploy the application. JRebel keeps the app server running at all times, so testing is instantaneous and interactive.

  • The impact of a data loss event can be significant. Real-time data is essential to remaining competitive. Many companies can no longer afford to rely on a truck arriving each day to take backup tapes offsite. For most companies, a cloud backup and recovery solution will eliminate, or significantly reduce, IT resources related to the mundane task of backup and allow your resources to be redeployed to more strategic projects. The cloud - can now be comfortable for you – with 100% recovery from anywhere all …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds