Performance of this demo improved by multitexturing extensions?

I’ve been particularly interested in this demo, written by Mark Kilgard in 1997:

http://www.opengl.org/developers/code/mjktips/caustics/

While it’s still a bit of a stretch for me to see exactly what is going on, it appears that it works by applying the animated texture maps in a second pass where it rerenders the entire scene but with the alternate map and in a monochrome and lightless mode to apply the texture effect. If my understanding here is incorrect, feel free to speak up about it…

This seems to be a pretty inefficient way to apply this effect to a potentially complex scene, and now that the multitexturing extensions are available, I’m wondering if this would be a particularly good example of where the new extensions would shine, but again, that presumes that my understanding of how both the original demo and the multitexturing extensions work, and at the moment my understanding of it all is insufficient to see what it would take to convert the demo…

I’m also rather confused by how even the original demo calculates the texture coordinates of the animated texture when it is applied to each object in the scene-- I would expect to find a loop somewhere that goes through every object in the scene and calculates the required texture coordinates in the second pass, but I don’t see anything that looks like that. In this case, the texture being applied is a projection onto an object, are there some tricks being used or some feature of OpenGL that I’m unaware of that is facilitating this?

(hmm… this forum doesn’t seem to have a “preview” feature, hope this is formatted OK…)

Kazoo

Look for glTexGen() in your favourite OpenGL reference (I use the spec PDF, which is available on the front page of this web site).

No offence intended but how about actually reading the article at URL you posted thoroughly before posting. Even the OpenGL code to do the texgen is at the bottom of the page.

Yes multitexture would be the obvious way to improve this old demo, it was written back before multitexture was widely available and while Mark worked at SGI, a company that to this day doesn’t support multitexture in their OpenGL implementations.

[This message has been edited by dorbie (edited 05-07-2003).]

Thanks for your responses…

Look for glTexGen() in your favourite OpenGL reference (I use the spec PDF, which is available on the front page of this web site).

I did-- as far as I was able to tell, NOWHERE in the spec (I checked opengl1.2.1.pdf and glspec14.pdf) does the string glTexGen appear, it’s not in the index, and in fact there are NO functions that begin with gl in the index at all. I found a few such functions in the GLU pdf, but not in the OpenGL pdfs. After your post, I looked a bit more and did find there’s a “TexGen” function which seems to be what you are referring to-- how am I supposed to know this? Is there a note somewhere that says “the C functions all have gl appended to the front of them, despite what they are called in the spec?” The spec is some 300 pages long, I must have overlooked it. So far, my use of OpenGl has ben through the Delphi GLScene library, so I haven’t done much exploration at this level, I’ve been trying to figure out how I can adapt the cited demo to GLScene, or call the OpenGL functions directly from Delphi, and it appears I’m in pretty deep here…

Assuming the function TexGen is what you are talking about, I see the specification is pretty terse-- it cites five coordinate generation types-- OBJECT_LINEAR, EYE_LINEAR, SPHERE_MAP, REFLECTION_MAP and NORMAL_MAP. The demo apparently uses OBJECT_LINEAR, which in the spec is defined with:

If TEXTURE GEN MODE indicates OBJECT LINEAR, then the generation function
for the coordinate indicated by coord is

g = p1xo + p2yo + p3zo + p4wo:

xo, yo, zo, and wo are the object coordinates of the vertex. p1; : : : ; p4 are specified
by calling TexGen with pname set to OBJECT PLANE in which case params points
to an array containing p1; : : : ; p4. There is a distinct group of plane equation coefficients
for each texture coordinate; coord indicates the coordinate to which the
specified coefficients pertain.

Anyone care to translate that into english? And the use of S and T in the demo seems unclear-- I took them to mean x and y in the 2D texture coordinate space. It’s a bit less that obvious that the net effect is the projection onto an object which I mentioned, and it’s also not clear how that might apply to projecting a texture onto an object from an arbitrary direction, which I would think would be of particular interest. I realize the math is important, but if I don’t know what the math here is trying to accomplish, I can’t tell if it has any bearing on what I’m trying to do-- so I can spend hours trying all of these texture operations to see what they all do to figure it out, OR I can ask in a forum where (hopefully) there are those who have already been down that path and can shed a little more directional light on the subject…

No offence intended but how about actually reading the article at URL you posted thoroughly before posting. Even the OpenGL code to do the texgen is at the bottom of the page.

None taken-- the problem is I read the article and understand that the code works, but the part of the code that actually calculated the texture coordinates was not at all obvious to me from the demo, and when looking up the functions glTexGeni, glTexGenfv in the specs, found no mention of them. And in fact, there are no versions of these particular calls WITHOUT the “gl” prefix either, as there is in the case of TexGen, so I still don’t know where to look for their documentation. The comments in the demo implied that there is some hidden voodoo going on in at least one of the gl… calls:

The texture generation will map the currently bound caustic texture object onto every object in the scene based on its object coordinates. See the underwater.c source code for more details.

But it wasn’t clear to me what it was referring to when it says “the texture generation”-- that’s somewhat generic, it doesn’t say “the glTexGeni function” so for all I know it was deep in the glEnable(GL_TEXTURE_GEN_S) call where the elusive voodoo is occurring.

And this comment:

As the briefest aside, I’d like to point out that many other 3D APIs (Direct3D in particular though) lack the texture coordinate generation capability (present in OpenGL since release 1.0) that makes possible the object-coordinate texturing of the caustic patterns onto arbitary geometry.

Was tantalizing enough to tell me that the logic of interest was indeed in there but not enough to tell me just where and neither was the spec…

I’m coming at this from the GLScene API where most of the OpenGL calls are buried, having found an example of this effect which I’d REALLY like to translate into what I’m doing, and having little or no idea what is in OpenGL, what is in GLU, and what is in GLUT in the demo and trying to translate it into something that is even less documented than any of these (GLScene) which works at a completely different level. So I’m diving in the deep end before I’ve really learned to swim…

May thanks though, it seems to be getting a little less muddled the more I bang my head against it…

kazoo

Originally posted by kazoo:
NOWHERE in the spec (I checked opengl1.2.1.pdf and glspec14.pdf) does the string glTexGen appear, it’s not in the index, and in fact there are NO functions that begin with gl in the index at all.

Mayb you should take some reading lessons =)

[b]If TEXTURE GEN MODE indicates OBJECT LINEAR, then the generation function
for the coordinate indicated by coord is

g = p1xo + p2yo + p3zo + p4wo:

xo, yo, zo, and wo are the object coordinates of the vertex. p1; : : : ; p4 are specified
by calling TexGen with pname set to OBJECT PLANE in which case params points
to an array containing p1; : : : ; p4. There is a distinct group of plane equation coefficients
for each texture coordinate; coord indicates the coordinate to which the
specified coefficients pertain.

Anyone care to translate that into english? [/b]

p1,p2,p3,p4 defines a vector basis (or a 4x4 matrix if you want). So you take the object space coordinates (x;y;z;1) and transform them using your matrix (do here translations, rotations scalings, whatever maths you want), which gives you the texture coordinates you’re looking for as a result.

[b]And the use of S and T in the demo seems unclear-- I took them to mean x and y in the 2D texture coordinate space. It’s a bit less that obvious that the net effect is the projection onto an object which I mentioned, and it’s also not clear how that might apply to projecting a texture onto an object from an arbitrary direction, which I would think would be of particular interest.{/B]

Remember the previous matrix you can set? You can put a projection matrix into it, which will give you homogenous coordinates, that after projection (that is, divided by w) will give you the U and V coordinates.

[This message has been edited by tfpsly (edited 05-07-2003).]

As I’m in a good day, I’ll add an example. I use the following old code for shadow mapping:

static float Mat_clipShadCoord[16] =
{
0.5, 0, 0, 0,
0, 0.5, 0, 0,
0, 0, 0.5, 0,
0.5, 0.5, 0.5, 1.0
};

glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );

glEnable( GL_TEXTURE_GEN_S );
glEnable( GL_TEXTURE_GEN_T );
// glEnable( GL_TEXTURE_GEN_R ); // Useless
glEnable( GL_TEXTURE_GEN_Q );

Matrice m2( Mat_clipShadCoord );
Matrice m3( m1 );
Matrice m4;
m4.mulMat( m3, m2 );
m1 = m4.get_datas();

p[0] = m1[0];
p[1] = m1[4];
p[2] = m1[8];
p[3] = m1[12];
glTexGenfv( GL_S, GL_EYE_PLANE, p );
p[0] = m1[1];
p[1] = m1[5];
p[2] = m1[9];
p[3] = m1[13];
glTexGenfv( GL_T, GL_EYE_PLANE, p );
// p[0] = m1[2]; // Useless
// p[1] = m1[6]; // Useless
// p[2] = m1[10]; // Useless
// p[3] = m1[14]; // Useless
// glTexGenfv( GL_R, GL_EYE_PLANE, p ); // Useless
p[0] = m1[3];
p[1] = m1[7];
p[2] = m1[11];
p[3] = m1[15];
glTexGenfv( GL_Q, GL_EYE_PLANE, p );

/*

  • ( s t r q ) = Mat_clipShadCoord Pl Ml M-1 M T R S ( x y z w ) = Mat_clipShadCoord Pl Ml T R S ( x y z w )
  • Pl = light projection matrix
  • Ml = light modelview
  • M = world modelview
  • T,R,S : translation, rotation, scaling of object
  • giving you a object space coordinates → light view projected coordinates matrix
    */

Then
glBindTexture( GL_TEXTURE_2D, light->shadowmap );
And render everything that should receive the shadowmap

Originally posted by dorbie:
SGI, a company that to this day doesn’t support multitexture in their OpenGL implementations.

For real? But IRISGL supports it, right? If not, what other APIs are used on SGI hardware?

Originally posted by kazoo:
I did-- as far as I was able to tell, NOWHERE in the spec (I checked opengl1.2.1.pdf and glspec14.pdf) does the string glTexGen appear, it’s not in the index, and in fact there are NO functions that begin with gl in the index at all.

The specs typically omit (but not always) the gl prefix for function names and the GL_ prefix for token names. Just so you know. It can be confusing. This includes the documentation for extensions within the extension registry.

IRISGL is dead, forget about it, the last system to really support IrisGL natively was Reality Engine class graphics, so you’re talking a LONG time ago, before Infinite Reality. IGLOO was used on later systems for IrisGL (IrisGL On Opengl) and was basically a wrapper on OpenGL that apps never really saw but it’s how things worked, and even that has been deprecated AFAIK. Only OpenGL should be used on SGI hardware now. Other 3D APIs (Shader, Inventor, Optimizer Performer) tend to add higher level functionality on top of OpenGL, they still use OpenGL for their low level graphics. Neither IRISGL nor OpenGL on SGI has ever supported multitexture on an SGI hardware design. They had plans to support features like this and even spec’d out appropriate extensions for OpenGL but the hardware never got built.

The only systems SGI has ever shipped with multitexture are those with PC class hardware sourced from the big PC graphics card designers.