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()
There are two potential issues I can see:
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.
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.