Include PolyCubeMapped models in your application

It is very easy to include in your application a model textured with a PolyCubeMap.
Basically it is as easy as to include a standard texture mapped model.

Just follow three steps:

(No, the vertex shader does not need any change. The fixed functionality one is just fine.)

To let you test PolyCubeMap right away, we included a few downloadable examples of PolyCubeMapped models at the bottom of this page.

If anything is going wrong, you may check the troubleshooting section.

[back to main PolyCubeMap page]


Loading the fragment program.

You will need the fragment program below. It is a plain ascii file. In your program, read it from the disk into a string. Then, after initializing OpenGL, build a new fragment program (with glGenProgramsARB), bind it (glGenProgramsARB with GL_FRAGMENT_PROGRAM_ARB as parameter) and load the string into it, for example glProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(text), text).

 the PolyCubeMap fragment shader
  version:   5.0
language:   ARB fragment shader ver 1.0
input:   fragment interpolated 3D texture position
output:   fragment color taken from the PolyCubeMap texture
functionality:   1) projects fragment texture position onto polycube surface
 2) maps it on the 2D texture
 3) fetches corresponding texel
 see paper for details
resources used:   49 ALU istructions
 2 texture accesses (including the final one)
file:   polycubemap.fp


After loading it, you have got to let the program know about some parameters, that will reflect the 2D texture size that you will be using (in texels), and the size of texture ``squarelets'' (the squared 2D texture regions that store the surface of a quarter of a polycube face - again, see the paper for details).
We set these parameters implicitly, using them to compute appropriate formulas, and using the results to asign some Program Environment Parameters.
You don't have to worry about the details, here is a C doing everything.

void ParameterizeShader(int textSizeX, int textSizeY, int squareletSize) {
  double
    d0x =   1.0 / textSizeX ,
    d0y =   1.0 / textSizeY ,
    d1x = 255.0 * squareletSize / textSizeX ,
    d1y = 255.0 * squareletSize / textSizeY ,
    d2x =   1.0 * squareletSize / textSizeX ,
    d2y =   1.0 * squareletSize / textSizeY ;
  glProgramEnvParameter4dARB( GL_FRAGMENT_PROGRAM_ARB, 0, d0x,d0y,0,0 );
  glProgramEnvParameter4dARB( GL_FRAGMENT_PROGRAM_ARB, 1, d1x,d1y,0,0 );
  glProgramEnvParameter4dARB( GL_FRAGMENT_PROGRAM_ARB, 2, d2x,d2y,1,0 );
  glProgramEnvParameter4dARB( GL_FRAGMENT_PROGRAM_ARB, 3, d2x,d2y,1,1 );
};

And don't forget to enable the fragment program: glEnable(GL_FRAGMENT_PROGRAM_ARB);

Note that there are four alternative endings in the fragment program above. Select the one suiting your tastes, uncommenting it.
The first one (on by default) is a plain copy of the final texture value on the screen - useful for example when the texture maps encodes pre-shaded gray levels. The second one blends the texel color with the original fragment color (that may encode for example the shading). The last two are just for illustration purposes: the third blends in a color that codes the current cell configuration, and the fourth also highlights cell borders.

Of course there are much more things that you may want to do with the final texel value. Just to name one, in a normal-map polycube maps the texel would encode a normal value, that must be shaded accordingly, and so on. Implementing these is up to you...

[back to top]


Loading the PolyCubeMap image.

You load the PolyCubeMap image in the same way you load any other texture image. We provide here some example PolyCubeMap images and models. Get them at the bottom of this page.

Remember, a PolyCubeMap is stored in the texture memory as a flattened polycube 2D image, that stores the final texture values, plus a tiny lookup table that in practices stores the polycube layout. The latter can optionally be serialized and kept in a subpart of the former (instead of keeping it in a tiny separate texture). This is the case for the texture images provided here (and the fragment shader above knows about this). So all you have to do is to load the a single png image and store it in texture space as normal.

Don't forget to bind the texture and to activate it. Also, remember to set both the minification and magnification filters to a plain CLOSEST, leave that to the shader.

    

Displaying the mesh.

Again, you do that just as you normally would for a textured object. You can use anything: triangles, quads, triangle strips, fans, point clouds, display lists and so on.

Just be sure to send, along with each vertex, its 3D texture coordinates (actually, the possibility to set them uniquely per-vertex is one of the neat feature of PolyCubeMaps). For example, to send a single textured triangle of a mesh, just use:

  glBegin(GL_TRIANGLES);
  glTexCoord3dv( tc[i] );
  glVertex3dv( v[i] );
  glTexCoord3dv( tc[j] );
  glVertex3dv( v[j] );
  glTexCoord3dv( tc[k] );
  glVertex3dv( v[k] );
  glEnd();

where v and tc are the arrays containing the vertices position and the 3D texture coordinates respectively, and i,j,k are the three indices of the vertices composing the triangle. It's as simple as that.

Below, you will find some triangle meshes that can be used as a test. Each of them has one (or more) corresponding PolyCubeMaps images.

The format, an ascii ply file, should be quite self explanatory: after the header, you will find a plain series of vertices, followed by a series of faces. Each separate vertex or face is on a single line. A vertices is represented by it position (three real numbers), followed by its texture coordinates (other three real numbers). A face is plainly a number of sides (always "3" here, they are triangle meshes) followed by the three indexes of the vertices of that face.

[back to top]


Ready to Use PolyCubeMapped Models

Stanford Bunny

Meshes
Meshes (ply format, see above) with per vertex 3d texture coordinates.
The zip contains six zipped models representing the same bunny at different resolutions.

Texture
Png file 1024x512. Squarelet size: 16
Encodes pre-shaded color values.

Laurana Bust

Meshes
A mesh (ply format, see above) with per vertex 3d texture coordinates.
Seven zipped models representing the same model at different resolutions.

Texture
Png file 1024x1024. Squarelet size: 64
Encodes pre-shaded color values.

Armadillo

Mesh
A mesh (ply format, see above) with per vertex 3d texture coordinates.

Texture
Png file 1024x1024. Squarelet size: 32
Encodes pre-shaded color values.

Three Holes Torus

Meshes
A mesh (ply format, see above) with per vertex 3d texture coordinates.

Texture
Png file 1024x512. Squarelet size: 32
Encodes pre-shaded color values.

[back to top]


Troubleshooting

If you are experiencing any problems, you can check this list:

[back to top]