Search code examples
matlabopengllightingtao-frameworkshading

Opengl lighting works top,bottom,front, back but not on the sides of the model


I have a model made up of five cubes, the whole model is textured, I added lighting and it sort of works for the top, bottom,font and back of the cubes but not the sides, there is also an issue with the shading because there is light where it should be shaded. I am using a Matlab .NET opengl wrapper based on Tao framework for this which is a unusual I admit.

I can provide the whole code if asked but for now,here is my lighting code

%% Lighting 

% Enable Light
Gl.glEnable(Gl.GL_LIGHTING);
% Vector for light position (directional light - try a positional one)

% Get Projection matrix in array of length 16
projmatrix = NET.createArray('System.Single', 16);
Gl.glGetFloatv(Gl.GL_PROJECTION_MATRIX,projmatrix);
% Reshape to 4x4 matrix
projmatrix=reshape(double(projmatrix),[4 4]);
% Use the inverse projection matrix to get the light fixed with the camera
LightPosCam=(projmatrix)\[0.3 0.5 -0.6 0]';

LightPos= NET.convertArray(LightPosCam, 'System.Single', 4);
Ambient =  NET.convertArray([0.000001 0.000001 0.000001 .1], 
'System.Single', 4); 
Diffuse=  NET.convertArray([0.7 0.7 0.7 1], 'System.Single', 4); 
Specular=  NET.convertArray([0.6 0.6 0.6 1], 'System.Single', 4); 

% Turn on Lighting
Gl.glEnable(Gl.GL_LIGHTING);
Gl.glEnable(Gl.GL_LIGHT0);

Gl.glLightfv(Gl.GL_LIGHT0,Gl.GL_POSITION,LightPos);
Gl.glLightfv(Gl.GL_LIGHT0,Gl.GL_AMBIENT,Ambient);
Gl.glLightfv(Gl.GL_LIGHT0,Gl.GL_DIFFUSE,Diffuse);
Gl.glLightfv(Gl.GL_LIGHT0,Gl.GL_SPECULAR,Specular);

% Constant attenuation (for distance, etc.)
% Only works for fixed light locations!  Otherwise disabled
Gl.glLightf(Gl.GL_LIGHT0, Gl.GL_CONSTANT_ATTENUATION, 1.0);
Gl.glLightf(Gl.GL_LIGHT0, Gl.GL_LINEAR_ATTENUATION, 0.0);
Gl.glLightf(Gl.GL_LIGHT0, Gl.GL_QUADRATIC_ATTENUATION, 0.0);
Gl.glLightModeli(Gl.GL_LIGHT_MODEL_LOCAL_VIEWER, Gl.GL_TRUE);

% Normalize vectors
Gl.glEnable(Gl.GL_NORMALIZE);

% Enable ColorMaterial
% Gl.glEnable (Gl.GL_COLOR_MATERIAL ) ;
% Set the Material Properties
floor_ambient = NET.convertArray([0, 0, 0, 0 ], 'System.Single', 4); 
floor_diffuse = NET.convertArray([0.8, 0.8, 0.8, 1.0 ], 'System.Single', 4); 

floor_specular= NET.convertArray([0.7,0.7,0.7, 1 ], 'System.Single', 4);
floor_emission= NET.convertArray([0.2,0.0,0.0, 1 ], 'System.Single', 4);
floor_shininess = 120;
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, floor_ambient);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, floor_diffuse);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, floor_specular);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SHININESS, floor_shininess);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_EMISSION, floor_emission);

% Gourang shanding
Gl.glShadeModel(Gl.GL_SMOOTH);

% Specular color enable

Gl.glLightModeli(Gl.GL_LIGHT_MODEL_COLOR_CONTROL,
Gl.GL_SEPARATE_SPECULAR_COLOR);
%  Gl.glTexEnvf(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, 
Gl.GL_MODULATE);
% Gl.glEnable(Gl.GL_BLEND); 

And here is my code for only one of the cubes

     %% Draw Sats
        % Select our texture

        Gl.glEnable(Gl.GL_NORMALIZE)

        %     Bottom Face  
        Gl.glEnable(Gl.GL_TEXTURE_2D);
        Gl.glBindTexture(Gl.GL_TEXTURE_2D, data.TextureID8);  %%Metalic Texture
        Gl.glBegin(Gl.GL_QUADS);
            Gl.glNormal3f(0,0,-1);
            Gl.glTexCoord2f(0,0);
            Gl.glVertex3f(cornersx(1), cornersy(1), cornersz(1));  
            Gl.glNormal3f(0,0,-1);
            Gl.glTexCoord2f(1,0);
            Gl.glVertex3f(cornersx(2), cornersy(2), cornersz(2));   
            Gl.glNormal3f(0,0,-1);
            Gl.glTexCoord2f(1,1);
            Gl.glVertex3f(cornersx(4), cornersy(4), cornersz(4));   
            Gl.glNormal3f(0,0,-1);
            Gl.glTexCoord2f(0,1);
            Gl.glVertex3f(cornersx(3), cornersy(3), cornersz(3));   

        %     Top Face
           Gl.glEnd()

        Gl.glBindTexture(Gl.GL_TEXTURE_2D, data.TextureID3);  %%Glyph1 Texture
        Gl.glBegin(Gl.GL_QUADS);
            Gl.glNormal3f(0,0,1);
            Gl.glTexCoord2f(0,0);
            Gl.glVertex3f(cornersx(7), cornersy(7), cornersz(7));               

        Gl.glNormal3f(0,0,1);
        Gl.glTexCoord2f(1,0);
        Gl.glVertex3f(cornersx(8), cornersy(8), cornersz(8));               

        Gl.glNormal3f(0,0,1);
         Gl.glTexCoord2f(1,1);
         Gl.glVertex3f(cornersx(6), cornersy(6), cornersz(6));              

        Gl.glNormal3f(0,0,1);
        Gl.glTexCoord2f(0,1);
        Gl.glVertex3f(cornersx(5), cornersy(5), cornersz(5));
        Gl.glEnd()

        % Front Face
        Gl.glBindTexture(Gl.GL_TEXTURE_2D, data.TextureID);  
        Gl.glEnable(Gl.GL_TEXTURE_2D);  
        Gl.glBegin(Gl.GL_QUADS);
        Gl.glNormal3f(0,-1,0);
        Gl.glTexCoord2f(0,0);
        Gl.glVertex3f(cornersx(1), cornersy(1), cornersz(1));               

         Gl.glNormal3f(0,-1,0);
         Gl.glTexCoord2f(1,0);
         Gl.glVertex3f(cornersx(5), cornersy(5), cornersz(5));              

        Gl.glNormal3f(0,-1,0);
        Gl.glTexCoord2f(1,1);
        Gl.glVertex3f(cornersx(6), cornersy(6), cornersz(6));               

        Gl.glNormal3f(0,-1,0);
        Gl.glTexCoord2f(0,1);   
        Gl.glVertex3f(cornersx(2), cornersy(2), cornersz(2));

        %     Back Face

        Gl.glNormal3f(0,1,0);
        Gl.glTexCoord2f(0,0);
        Gl.glVertex3f(cornersx(3), cornersy(3), cornersz(3));               

        Gl.glNormal3f(0,1,0);
        Gl.glTexCoord2f(1,0);
        Gl.glVertex3f(cornersx(4), cornersy(4), cornersz(4));               

        Gl.glNormal3f(0,1,0);
        Gl.glTexCoord2f(1,1);
        Gl.glVertex3f(cornersx(8), cornersy(8), cornersz(8));               

        Gl.glNormal3f(0,1,0);
        Gl.glTexCoord2f(0,1);
        Gl.glVertex3f(cornersx(7), cornersy(7), cornersz(7));

        %     Right Face

         Gl.glNormal3f(-1,0,0);
         Gl.glTexCoord2f(0,0);
         Gl.glVertex3f(cornersx(4), cornersy(4), cornersz(4));              

         Gl.glNormal3f(-1,0,0);
         Gl.glTexCoord2f(1,0);
         Gl.glVertex3f(cornersx(2), cornersy(2), cornersz(2));              

         Gl.glNormal3f(-1,0,0);
         Gl.glTexCoord2f(1,1);
         Gl.glVertex3f(cornersx(6), cornersy(6), cornersz(6));              

        Gl.glNormal3f(-1,0,0);
        Gl.glTexCoord2f(0,1);
        Gl.glVertex3f(cornersx(8), cornersy(8), cornersz(8));

        %     Left Face

         Gl.glNormal3f(1,0,0);
         Gl.glTexCoord2f(0,0);
         Gl.glVertex3f(cornersx(3), cornersy(3), cornersz(3));              
         Gl.glNormal3f(1,0,0);
         Gl.glTexCoord2f(1,0);
         Gl.glVertex3f(cornersx(1), cornersy(1), cornersz(1));                  
         Gl.glNormal3f(1,0,0);
         Gl.glTexCoord2f(1,1);
         Gl.glVertex3f(cornersx(5), cornersy(5), cornersz(5));                  
         Gl.glNormal3f(1,0,0);
         Gl.glTexCoord2f(0,1);
         Gl.glVertex3f(cornersx(7), cornersy(7), cornersz(7));
        Gl.glEnd()

Finally a gif of my model and the issue in action.


Solution

  • There are two potential issues I can see:

    1. If you are only having trouble with the right and left faces, it may simply be that you accidentally flipped their surface normals. I would try this:

      Gl.glNormal3f(1,0,0);   % For all of the right face vertices
      Gl.glNormal3f(-1,0,0);  % For all of the left face vertices
      

      When the surface normals are pointed in the wrong direction (i.e. into your cube), that means the back face of the polygon is facing outward. When you call Gl.glMaterialfv, you specify Gl.GL_FRONT and not Gl.GL_FRONT_AND_BACK, which means back faces aren't being lit. I'm guessing this would be why you see no lighting applied to the sides.

    2. I don't know offhand if the order of your vertices matter, such that they should always be specified in either clockwise or counter-clockwise order around the face when viewed from the outside of the cube. Since I don't know what your cornersx, cornersy, or cornersz data looks like, I can't tell if you're defining them as clockwise or counter-clockwise. However, I can tell you that one of your faces is defined with a different clockwise order than the rest: the left face, with vertices ordered as 3 -> 1 -> 5 -> 7. I don't know enough about your lighting framework to say if this would be a problem, but for consistency you may want to define the vertices of the left face in the order 1 -> 3 -> 7 -> 5 instead.