• Advertisement
Sign in to follow this  

GLSL ftransform

This topic is 2677 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hi,

i got question regarding ftransform.

if for example i set my camera at (5, 5, 5), and i have a vertex at (3, 2, 3), if in the GLSL vertex shader code i call

v = ftransform();

what value does v returns? is it (2, 3, 2) or (-2, -3, -2) or else?

fyi my reshape function:


void onReshape(int w, int h) {
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective(60.0, (GLdouble) width/(GLdouble) height, 1.0, 100.0);
glGetDoublev(GL_PROJECTION_MATRIX, projectionMatrix);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glGetDoublev(GL_MODELVIEW_MATRIX, lookAtMatrix);
}



and my lookat code to set the camera position:


gluLookAt(cameraCartesianPos.GetX(),cameraCartesianPos.GetY(),cameraCartesianPos.GetZ(),
0, 0, 0,
getCosValue(cameraSphericalPos.GetZ()), 1, getSinValue(cameraSphericalPos.GetZ()));




thanks in advance!

Share this post


Link to post
Share on other sites
Advertisement
It will be neither of those values. Ftransform is equivalent to this:

v = ftransform();
v = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;

v will be a coordinate in projection (screen) space.

If you want to get the vertex's world or view space equivalent, than do the matrix multiplication yourself, ftransform is deprecated long ago anyway.

Share this post


Link to post
Share on other sites
hi,

sorry for being lazy-alike but i've been googling around and cant have the solution. if for example i send the camera position to the vertex shader (or in other word (5, 5, 5) is a known value), what should i do in the vertex shader to get the value (-2, -3, -2)? or perhaps how can i get the world space (2, 3, 2) of each vertex would be enough.

i've been trying to pick and multiply any values like gl_vertex etc but seeems cant find the desired value.


thanks in advance

Share this post


Link to post
Share on other sites
If you want the world space position, you need to upload the world space matrix. GLSL doesn't provide the world space matrix because it's concatenated with the view space.

The default OpenGL matrix stack is not going to be sufficient for a lot of vertex shader tricks. My suggestion is to stop using opengl matrix functions entirely, and use your own matrix class which you upload via uniform to the shaders. This is how it is supposed to be done in modern opengl, and it gives you a lot more flexibility to get the matrices you need.

The default matrices are only really sufficient for reproducing most of the fixed function pipeline, and as such all glMatrix* operations are deprecated now.

Once you do have the world space matrix, you can get the world position (3,2,3) by the operation : modelMatrix * gl_Vertex, or then get -2,-3,-2 by subtracting this from the camera world space position.

Share this post


Link to post
Share on other sites
hi karwosts,

thx for all the reply. however im really begineer in this kind of thing. can you elaborate more what you mean by saying world space matrix? how can i get that matrix from a given onReshape function that i mention above? and also what did i get from calling gl_vertex?

Share this post


Link to post
Share on other sites
Quote:
can you elaborate more what you mean by saying world space matrix?

I'll try to give a short explanation, but you'll likely need to spend some time researching matrices used in 3d mathematics, because there's more than I can go into in a short post.

Essentially when doing 3d graphics you'll typically hear of three different matrices. What these matrices do is convert a point from one space to another.

The Model Matrix:
This matrix converts your vertex from "model space" to "world space". Model space being defined as the position of the vertex in relation to the model. The center is always (0,0,0), and these vertices don't change when the entire model moves. When you multiply a model vertex by the model matrix you get the vertexes absolute position in world space. If you have a vertex that is at (0,1,0) in relation to the center of the model, and your model is at (10,10,10), then the model matrix converts your vertex to the world position of (10,11,10) (provided that there is no rotation).

The View Matrix:
This is what converts your vertex from "world space" to "camera space", where 0,0,0 is always where the "eye" is. When you're in camera space anything that is directly in front of the camera would have a vertex like (0,0,-X), as the camera looks out of the negative Z axis. In your case your camera matrix is constructed by your gluLookAt function.

The Projection Matrix:
This is the matrix that converts camera space to "projection space", or the x/y position that is on your screen. This is what you have typically stored in the GL_PROJECTION_MATRIX matrix.

Now as opengl has historically only had the fixed function pipeline, which doesn't require keeping separate copies of the model and view matrices, so it only stores the "modelview" matrix which is just the concatenation of the two matrices (modelview matrix = view matrix * model matrix). To do what you want in your shader this is not sufficient, so you have to provide separate matrices to the shader. This means you can't use the built in modelview matrix.

Quote:
how can i get that matrix from a given onReshape function that i mention above?


You'll need a matrix class that can perform these operations. You essentially leave opengl totally out of this now. So your onReshape would look something like this:

void onReshape(int w, int h) {
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
Matrix4D myProjectionMatrix;
myProjectionMatrix.setPerspective(60.0,width/height, 1.0, 100.0);

//do this for each shader
glUniformMatrix4fv(projMatrixUniformLoc,1,&myProjectionMatrix);

}



And your drawing code might look like this. Notice no glTranslate, no glRotate, nothing like that anymore.


void DrawMyStuff() {

Matrix4D cameraMatrix;
Matrix4D modelMatrix;

cameraMatrix.lookAt(cameraCartesianPos.GetX(),cameraCartesianPos.GetY(),cameraCartesianPos.GetZ(),
0, 0, 0,
getCosValue(cameraSphericalPos.GetZ()), 1, getSinValue(cameraSphericalPos.GetZ()));

modelMatrix.Translate(5,5,5);
modelMatrix.Rotate(45,0,0,1);

glUniformMatrix4fv(viewMatrixUniformLoc,1,&cameraMatrix);
glUniformMatrix4fv(modelMatrixUniformLoc,1,&modelMatrix);

//now draw the model via glDrawArrays,glDrawElements, etc

}



And finally your shader will be something like this (forgive my syntax if it's incorrect I'm a little rusty):


uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;

out oVertex;
main() {
oVertex = projectionMatrix * viewMatrix * modelMatrix * gl_Vertex;
}




Quote:
and also what did i get from calling gl_vertex?

This is a special variable which has the model space position of the vertex. Every time the vertex shader runs, gl_Vertex has the position of the vertex it is processing. Technically this is deprecated too, but I think you've got enough to chew on for one day :)


I know this is a lot and probably daunting, but just try to take things one step at a time. OpenGL has changed a lot since the fixed pipeline, so the methodology is quite different now from what you've probably learned.

Share this post


Link to post
Share on other sites
hi,

thx for the info. so i dig on the net and i found out that i can use gl_ModelViewProjectionMatrix to get the whole matrix without sending it from main program. but still im no luck in converting it to spherical coordinate.

this is my whole vertex shader code:


#version 130

in vec4 MCvertex;

uniform float cameraPosX;
uniform float cameraPosY;
uniform float cameraPosZ;

uniform mat4 MVMatrix;
uniform mat4 MVPMatrix;

varying float sphIndexY;
varying float sphIndexZ;

void main()
{
vec3 spherical;
gl_TexCoord[0] = gl_MultiTexCoord0;

vec3 cameraDir = vec3(normalize(-(gl_ModelViewProjectionMatrix * gl_Vertex)));

spherical.x = sqrt((cameraDir.x*cameraDir.x) + (cameraDir.y*cameraDir.y) + (cameraDir.z*cameraDir.z));

spherical.y = atan(cameraDir.z, cameraDir.x);
spherical.z = acos(cameraDir.y/spherical.x);
}





there are some other part to handle the minus value, but lets ignore that for a while. so my intention is to find the spherical coordinate from the vertex to the camera based on world space coordinate. for a given camera position at (xc, yc, zc) (gluLookAt) and a vertex at (xv, yv, zv), im trying to find the spherical angle by using this simple spherical conversion:

r=sqrt{x^2+y^2+z^2}
theta=arccos(z/r}
phi = atan2(y,x)

which since r is 1, there is no need to divide the z when calculating the theta. since my up value is y instead of z, i use this formula instead:

r = sqrt(x^2 + y^2 + z^2);
theta = atan(z, x);
phi = acos(y);

and (x, y, z) = (xc, yc, zc) - (xv, yv, zv)

now i checked my conversion in a simple c++ program


for (int i =0 ; i <= 180; i=i+9) {
for (int k = 0; k <= 360; k=k+18) {
camX = sin(i*PI/180)*cos(k*PI/360);
camY = cos(i*PI/180);
camZ = sin(i*PI/180)*sin(k*PI/360);

std::cout << camX << " " << camY << " " << camZ << " -> ";

phi = atan2(camZ, camX) * 180 / (PI*9.0);
theta = acos(camY) * 180 / (PI*9.0);
if (phi < 0) {
phi = 20+phi;
}
std::cout << (int)phi << " " << (int)theta << std::endl;
}
std::cout << std::endl;
}




it works so my formula seems to be ok. my guess the problem is trying to retrieve the camera/vertex coordinate. i even modify the vertex shader so it get the camera position from the c++ and try to substract it with world position vertex. but i also had trouble trying to do that.

any idea where i missed the point?


thanks in advance

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement