Skip to main content
gamedev.net
🔒 Locked

Wierd Lighting Problem

Started by ScopeDynamo 0 replies 350+ views
Original Post
ScopeDynamo
ScopeDynamo
Can you see anything wrong with this OpenGL Light class(C#) or the normal generation function here? With a light mode of 1 (I.e setting the four par in the light position call to 1) I get good lighting on one side of the plane, but bad non existant lighting on the other. With a light mode of 0 I get no lighting at all except for highlights.) Even with no shininess or specular, turning the camera still affects the light sourec as well, it shimmers. Are there any great tutorials/methods for normal generation on the net? Or general gl lighting tutorials? (Not how to set it up, but how to use it effectively to achieve good lighting in practical siturations) Light Class.

namespace Vivid3D
{
    public class Light : Pivot
    {
        public int glLight, lightObj;
        public static int[] lstack = new int[8];
        public static int[] GL_Light = new int[8];
        public static void SetupLights()
        {
            GL_Light[0] = Gl.GL_LIGHT0;
            GL_Light[1] = Gl.GL_LIGHT1;
            GL_Light[2] = Gl.GL_LIGHT2;
            GL_Light[3] = Gl.GL_LIGHT3;
            GL_Light[4] = Gl.GL_LIGHT4;
            GL_Light[5] = Gl.GL_LIGHT5;
            GL_Light[6] = Gl.GL_LIGHT6;
            GL_Light[7] = Gl.GL_LIGHT7;
        }
        public static int RequestLight()
        {
            for (int j = 0; j < 8; j++)
            {
                if (lstack[j] == 0)
                {
                    lstack[j] = 1;
                    Gl.glEnable(GL_Light[j]);
                    return j;
                }
            }

            return -1;
        }
        public static void FreeLight(int light)
        {
            if (light < 0 || light > 7) return;
            lstack[light] = 0;
            Gl.glDisable(GL_Light[light]);
        }
        public Light()
        {
            glLight = Light.RequestLight();
            if (glLight != -1)
            {
                lightObj = Light.GL_Light[glLight];
            }
        }
        ~Light()
        {
            Light.FreeLight(glLight);
        }
        public void SetupGL()
        {
            float[] mat_spec = new float[4];
            float[] mat_shin = new float[4];
            float[] light_pos = new float[4];
            mat_spec[0] = 0;
            mat_spec[1] = 0;
            mat_spec[2] = 0;
            mat_spec[3] = 0;
            mat_shin[0] = 0;
            light_pos[0] = X;
            light_pos[1] = Y;
            light_pos[2] = Y;
            light_pos[3] = 1;
            Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR,mat_spec);
            Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SHININESS,mat_shin);
            Gl.glLightfv(lightObj,Gl.GL_POSITION,light_pos);
        }
    }
}


Normal Generator.

 public void UpdateNormals()
        {
            float[] Face_NX = new float[triCount];
            float[] Face_NY = new float[triCount];
            float[] Face_NZ = new float[triCount];
            int[] Vertex_ConnectedTris = new int[vertexCount];
            int[,] Vertex_TriList = new int[vertexCount,64];
            for (int i = 0; i < triCount; i++)
            {
                Face_NX = 0;
                Face_NY = 0;
                Face_NZ = 0;
            }
            for (int i = 0; i < vertexCount; i++)
            {
                Vertex_ConnectedTris = 0;
                for (int k = 0; k < 64; k++)
                {
                    Vertex_TriList[i, k] = 0;
                }
            }
            Console.WriteLine("About to update surface normals.");
            Console.WriteLine("Surface has " + CountTriangles().ToString() + " Triangles");
            for (int LOOP_Tris = 0; LOOP_Tris < CountTriangles(); LOOP_Tris++)
            {
                Console.WriteLine("Updating Normal:" + LOOP_Tris.ToString());
                int Vertex_0, Vertex_1, Vertex_2;
                Vertex_0 = TriangleVertex(LOOP_Tris, 0);
                Vertex_1 = TriangleVertex(LOOP_Tris, 1);
                Vertex_2 = TriangleVertex(LOOP_Tris, 2);
                int ConnectedTris = Vertex_ConnectedTris[Vertex_0];
                Vertex_TriList[Vertex_0, ConnectedTris] = LOOP_Tris;
                Vertex_ConnectedTris[Vertex_0] = ConnectedTris + 1;

                ConnectedTris = Vertex_ConnectedTris[Vertex_1];
                Vertex_TriList[Vertex_1, ConnectedTris] = LOOP_Tris;
                Vertex_ConnectedTris[Vertex_1] = ConnectedTris + 1;

                ConnectedTris = Vertex_ConnectedTris[Vertex_2];
                Vertex_TriList[Vertex_2, ConnectedTris] = LOOP_Tris;
                Vertex_ConnectedTris[Vertex_2] = ConnectedTris + 1;

                float Ax, Ay, Az, Bx, By, Bz, Cx, Cy, Cz;
                Ax = VertexX(Vertex_0);
                Ay = VertexY(Vertex_0);
                Az = VertexZ(Vertex_0);

                Bx = VertexX(Vertex_1);
                By = VertexY(Vertex_1);
                Bz = VertexZ(Vertex_1);

                Cx = VertexX(Vertex_2);
                Cy = VertexY(Vertex_2);
                Cz = VertexZ(Vertex_2);

                float Px, Py, Pz, Qx, Qy, Qz;
                Px = Ax - Bx;
                Py = Ay - By;
                Pz = Az - Bz;

                Qx = Bx - Cx;
                Qy = By - Cy;
                Qz = Bz - Cz;
                float Nx, Ny, Nz;
                Nx = Py * Qz - Pz * Qy;
                Ny = Pz * Qx - Px * Qz;
                Nz = Px * Qy - Py * Qx;
                Face_NX[LOOP_Tris] = Nx;
                Face_NY[LOOP_Tris] = Ny;
                Face_NZ[LOOP_Tris] = Nz;
            }
            Console.WriteLine("Updating surface vertice normals.");
            for (int Loop_Vertices = 0; Loop_Vertices < CountVertices(); Loop_Vertices++)
            {
                Console.WriteLine("Updating vertice " + Loop_Vertices.ToString());
                float Nx, Ny, Nz;
                Nx = Ny = Nz = 0;
                int Polys = Vertex_ConnectedTris[Loop_Vertices];
                for (int Loop_Polys = 0; Loop_Polys < Polys; Loop_Polys++)
                {
                    int ThisPoly = Vertex_TriList[Loop_Vertices,Loop_Polys];
                    Nx += Face_NX[ThisPoly];
                    Ny += Face_NY[ThisPoly];
                    Nz += Face_NZ[ThisPoly];
                }

                float N1 = (float)Math.Sqrt((double)Nx * (double)Nx + (double)Ny * (double)Ny + (Double)Nz * (double)Nz);

                Nx = Nx / N1;
                Ny = Ny / N1;
                Nz = Nz / N1;
                VertexNormal(Loop_Vertices, Nx, Ny, Nz);
                
            }


        }

ScopeDynamo
ScopeDynamo
The problem was me setting the Z Coord to the Y Value.
But there's another problem now, only the first light is actively effecting the display. If I arc it around the object, it works fine, but If I put a second light source in the scene, only the first affects it. I remove the first light source and suddenly the second light source works. Any ideas?

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.