0
votes

First of all, I'm sorry if the title is misleading but I'm not quite sure how to describe the issue, if it is an issue at all.

I'm vert new to OpenGL, and I have just started to scratch the surface of GLSL following this tutorial.

The main part of the rendering funcion looks like this

GLfloat ambientLight[] = {0.5f, 0.5f, 0.5f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);

//Add directed light
GLfloat lightColor1[] = {0.5f, 0.5f, 0.5f, 1.0f}; //Color (0.5, 0.2, 0.2)
//Coming from the direction (-1, 0.5, 0.5)
GLfloat lightPos1[] = { 40.0 * cos((float) elapsed_time / 500.0) , 40.0 * sin((float)      elapsed_time / 500.0), -20.0f, 0.0f};
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor1);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos1); 


glPushMatrix();
glTranslatef(0,0,-50);
glColor3f(1.0, 1.0, 1.0);
glRotatef( (float) elapsed_time / 100.0, 0.0,1.0,0.0 );
glUseProgram( shaderProg );

glutSolidTeapot( 10 );
glPopMatrix();

Where "shaderProg" is a shader program consisting of a vertex shader

varying vec3 normal;

void main(void)
{
  normal = gl_Normal;
  gl_Position = ftransform();
}  

And a fragment shader

uniform vec3 lightDir;
varying vec3 normal;

void main() {

  float intensity;
  vec4 color;
  intensity = dot(vec3(gl_LightSource[0].position), normalize(normal));


  if (intensity > 0.95)
    color = vec4(1.0,0.5,0.5,1.0);
  else if (intensity > 0.5)
    color = vec4(0.6,0.3,0.3,1.0);
  else if (intensity > 0.25)
    color = vec4(0.4,0.2,0.2,1.0);
  else
    color = vec4(0.2,0.1,0.1,1.0);

  gl_FragColor = color;
}

I have two issues.

First is that according to the tutorial the uniform lightDir should be usable, yet I only get results with vec3(gl_LightSource[0].position). Is there any difference between the two?

The other problem is that the setup rotates the light around the teapot differently when using the shader program. Without the shader the light orbits the teapot in the XY axis of the camera. Yet, if the shader is used, the light moves in the XZ axis of the camera. Have I made a mistake? Or have i forgot som translation in the shaders?

Thanks in advance : )

2
I would recommend not to use out-of-date fixed function pipeline functions like glLightXXX, but the uniforms instead (google "GLSL uniform").Denis Gladkiy

2 Answers

0
votes

First is that according to the tutorial the uniform lightDir should be usable, yet I only get results with vec3(gl_LightSource[0].position). Is there any difference between the two?

That tutorial uses lightDir as a uniform variable. You have to set that yourself. via some glUniform call. If it is the same or not will depend on what exactly you set as the light position here. The lightDir as it is used here is the vector from the surface point you want to shade to the light source. The tutorial uses a directional light, so the light direction is the same everywhere in the scene and does not really depend on the position of the vertex/fragment. You can do the same with the fixed-function lighting by setting the w component of the light poisition to 0. If you don't do that, the results will be very different.

A side note: The GLSL code in that tutorial is unforunately relying on lots of deprecated features. If you learn GLSL, I would really recommend that you learn modern GL core profile.

0
votes

lightDir is not a pre-defined uniform. The typical definition for a light direction vector is just a normalized vector to the light position in your shader, which you can easily calculate yourself by normalizing the position vector:

vec3 lightDir = normalize(gl_LightSource[0].position.xyz);

You could also pass it into the shader as a uniform you define yourself. For this approach, you would define the uniform in your fragment shader:

uniform vec3 lightDir;

and then get the uniform location with the glGetUniformLocation() call, and set a value with the glUniform3f() call. So once after linking the shader, you have this:

GLint lightDirLoc = glGetUniformLocation(shaderProg, "lightDir");

and then every time you want to change the light direction to (vx, vy, vz):

glUniform3f(lightDirLoc, vx, vy, vz);

For the second part of your question: The reason you get different behavior for the light position with the fixed pipeline compared to what you get with your own shader is that the fixed pipeline applies the current modelview matrix to the specified light position, which is not done in your shader.

As a number of others already suggested: If you learn OpenGL now, I strongly recommend that you skip the legacy features, which includes the fixed function light source parameters. In this case, you can simply use uniform variables you define yourself, as I already illustrated as an option for the lightDir variable above.