glScaled

Started by
21 comments, last by iSina 15 years, 9 months ago
Greetings, What I am doing isnt exactly a game but more of a molecular modelling program. I was planning only to include calculations and give output to known molecular visualization toolsi but however the form I have chosen to represent molecules are quite different from standard ones. So I will have to add my openGL extension. However among the load of other codes I have to write, I dont have time to extensively go over openGL books, so I am trying to string together pieces of codes I find around. The code is in perl, but it is almost the same as c or c++ except the $ sign which is a declaration of a variable like saying int Right now I have a question about glScaled: Suppose at some part of the program I want to plot N number of ellipsoids (where N is given) for (1..N){ # Here some code read changing variables for $x, $y, $z, $xdir, $ydir, $zdir values # glBegin (GL_QUADS); glLoadIdentity(); glScaled($x, $y, $z); my $newQuad = gluNewQuadric (); gluSphere($newQuad,1, 32, 16); glEnd ; glTranslatef($xdir, $ydir, $zdir); } What I want the program to do is to read some coordinate and radius information about a set of ellipsoids and plot them on screen one after the other. Each one has a specific scaling value. However when I use glScaled in that form, the scaling amount add up, so if at the first cycle it is glScaled(2,2,2) and in the second cycle it is glScaled (3,3,3) it acts as if glScaled(6,6,6). I know using glScaled isnt just as straight forward as this since it changes the scales of all the objects plotted after its call, but I havent been able to fix it. Thanks for the help...
Advertisement
You can either undo the scale after drawing the shape by scaling by 1/$x, etc...:
glLoadIdentity();// while loopingglScaled($x, $y, $z);//draw a shapeglScaled(1.0/$x, 1.0/$y, 1.0/$z);glTranslatef($xdir, $ydir, $zdir);


...or use the gl matrix stack:

glLoadIdentity();// while loopingglPushMatrix();glScaled($x, $y, $z);//draw a shapeglPopMatrix();glTranslatef($xdir, $ydir, $zdir);
You really need to get to know the mathematical effect of the different transformation commands-- that is, the ramifications of the fact that they cause an internal matrix to be postmultiplied by a different matrix, and what the effect of different orders of operations is. The OpenGL redbook has a great description of this stuff, but unfortunately only in the 3rd and later editions (opengl 1.3 and later, so it's not in the online version. You should also get to know the matrix stack (glPushMatrix and glPopMatrix), although this is somewhat a different thing.
You have two choices, either:
a) scale by the reciprocal value after drawing each object (which will reset the scale)
or, b) glPushMatrix() before scaling, and glPopMatrix() after drawing (which will save and restore the matrix before the scale)

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

I'd recommend option b) the matrix stack. Lots of multiplications (adding transformations and their inverse to cancel them out) will slowly introduce errors due to numerical instability/floating point precision issues.
If I was helpful, feel free to rate me up ;)If I wasn't and you feel to rate me down, please let me know why!
I was trying to rescale the scales back to its original value as you said, I will also try what you have recommended. I am quite aware of linear algebra as I had to really use construct amount of transformation operators (like those that would take an ellipsoid into unit circle and those that would rotate vectors around arbitrary axis). I am not however aware of the internal workings of openGL, and I dont think I will have enough time soon to see through it. However I will look through the book you mentioned. The graphics extension I am planning for now is very simple (I could write in matlab like in a day but I want it to be a part of my own program not a side script).

I will update this topic if I am stuck anywhere else, thanks alot for the help,
I am trying to use push and pop matrix way in this manner (I just put in 1.1 instead of varying scale amounts). So the size of the sphere should remain the same right? But its size increases and infact after the second sphere, it takes the form of an ellipsoid although the scaling is homogenous...(there is a picture after the code)

sub DrawGLScene {


glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();

glTranslatef(-1.5, 0.0, -6.0);


for (1..5){
glPushMatrix();
glScaled(1.1,1.1,1.1);

glBegin (GL_QUADS);
my $newQuad = gluNewQuadric ();
gluSphere($newQuad,1, 32, 16);
glEnd ;

glPopMatrix();
glTranslatef(3.0, 0.0, 0.0);

}


glutSwapBuffers;
}

http://img136.imageshack.us/img136/2268/spheredq6.jpg
It's also the order of the calls that matter. Your translation inside the loop influences the scaling. Put it inside the glPushMatrix/glPopMatrix pair and use glTranslatef(i * 3.0, 0.0, 0.0f) instead.
If I was helpful, feel free to rate me up ;)If I wasn't and you feel to rate me down, please let me know why!
When I put translation between push and pop, only a single sphere appears (they are not translated but all are put on top of each other) I suppose the translation goes wrong? And also what is the purpose of i* and f, they are not defined on perl like that I think because it gives an error..
Ah sorry, the f comes from my habit on using float literals which are declared as 0.0f (instead 0.0 which would be double).

The i was meant to be the counter variable of the loop, didn't pay attention to the fact that you don't declare it. What I meant is that you could increase the translation distance by 3 every time you loop, i.e. in C++
for(int i = 0; i < 5; i++){ ... glTranslatef(i * 3.0, 0.0, 0.0); //i.e. first iteration translate by 0, second by 3 etc. ...}
If I was helpful, feel free to rate me up ;)If I wasn't and you feel to rate me down, please let me know why!

This topic is closed to new replies.

Advertisement