PDA

View Full Version : basic vertex transformations



Morpheus011
11-01-2005, 05:33 PM
I am very new to glsl and am trying to get some basic applications written to get the general idea of how a glsl program works. Currently I am doing a simple shader where I stretch an object (a torus in this case) by applying a scale to its vertices. However I can't seem to get it working correctly and this problem has brought to my attention a few other questions I have pertaining to vertex and fragment shaders in general.

First of all this is the shader I am using to perform the vertex transforms (this is based on an example from the OpenGL SuperBible)--


// light position used for lighting calculations
uniform vec3 lightPos0;
uniform vec3 color;
uniform vec3 squashStretch;

void main()
{
// glPosition is a built in variable that stores the output vertex position.
// Here we multiply the object space vertex (gl_Vertex) by the model view
// projection matrix to transform the vertex to clip space.

vec4 stretchCoord = gl_Vertex;
stretchCoord.xyz *= squashStretch;

vec4 clipCoord = gl_ModelViewProjectionMatrix * stretchCoord;

// copy the clip space coordinates into our position
gl_Position = clipCoord;

vec3 stretchedNormal = gl_Normal;
stretchedNormal *= squashStretch;

// Let there be light!
vec3 N = normalize(gl_NormalMatrix * stretchedNormal);
vec3 V = gl_ModelViewMatrix * stretchCoord;
vec3 L = normalize(lightPos0 - V.xyz);
vec3 H = normalize(L + vec3(0.0, 0.0, 1.0));

// specular contribution
//const float spec = 128.0;

// calculate the diffuse lighting
float NdotL = dot(N, L);
vec4 diffuse = gl_Color * vec4(max(0.0, NdotL));

// calculate the specular component
float NdotH = max(0.0, dot(N, H) * 8.0 - 7.0);
gl_TexCoord[0] = vec4(NdotH, 0.0, 0.0, 1.0);

gl_FrontColor = diffuse;

// calculate normalized device coords
vec3 ndc = clipCoord.xyz / clipCoord.w;

// map from (-1, 1) to (0, 1) before outputting
vec3(gl_SecondaryColor) = (ndc * 0.5) + 0.5;
}For some reason the above code not only doesn't do what I want it to (essentially stretch the torus into a more oblong shape) but in fact nothing renders to the screen at all except for a black background. I have tried a few variations of this method and none seem to be working. This also leads to my next question which pertains to the variables listed ahead of the main() function signature. I know that the uniform qualifier means these variables remain constant but must be initialized outside of the shader, but I am not sure where they should be initialized. I am assuming that they must be init'd in my C code through OpenGL states and the like but I am not sure. I have gotten basic lighting (diffuse, specular) to work fine with the shader so I'm assuming I just need to somehow pass a value to the squashStretch param that is used for my lighting and vertex transform calculations. Thanks for any help you can give me and I apologize for the lengthy post (I hate reading long posts too).

Thanks again in advance

Zulfiqar Malik
11-01-2005, 09:58 PM
You can specify uniforms by first getting a pseudo-handle to the uniform within the shader using

GLuint loc = glGetUniformLocationARB(programHandle, uniformVariableName);

Then you can assign a value to that uniform using

glUniform[i]fARB(loc, <params>);

Where [i] can be 1, 2, 3 or 4 depending on whether you are setting a float, vec2, vec3 or vec4 uniform respectively.

For such a scaling problem, i would recommend using the modelview matrix from your opengl application simply because it blends in seamlessly with fixed function pipeline and its easier to provide fallback paths to fixed function pipeline, whereever required.
For a better understanding of GLSL (and of programmable pipeline for that matter), i would recommend reading the orange book.

Morpheus011
11-02-2005, 12:43 AM
that's very helpful thank you :)