简体   繁体   中英

Open GL Lighting Difficulties

Background

Currently I am esentially making a CAD viewer which will be used in a larger system. I have been reading a ton of information about learning Open GL and I am quite far along. I can import the file, display it, and navigate using keyboard controls. I am trying hard to understand and set up proper lighting now.

Problem

After some discussion bellow, I realize that I don't have a shader loaded which is why I am having my problems. In doing some research I have found some shader files, fragment.glsl and vertex.glsl which are written in C. Will this be a problem since I am writing my code in C#/ VB.net? I don't think so.

Now I am having a problem with compiling the shading, and linking the shaders to my code. I found a handy source for compiling:

http://pages.cpsc.ucalgary.ca/~brosz/wiki/pmwiki.php/CSharp/08022008

In this article, a function is created to compile a shader. The compiler requires a stream to which is then passed on to the compiler. I have this function I created to read the shader to a stream:

Public Function path_to_stream(ByVal path As String) As System.IO.Stream
    Dim bData As Byte()
    Dim br As System.IO.BinaryReader = New System.IO.BinaryReader(System.IO.File.OpenRead(path))
    bData = br.ReadBytes(br.BaseStream.Length)
    Dim ms As System.IO.MemoryStream = New System.IO.MemoryStream(bData, 0, bData.Length)
    ms.Write(bData, 0, bData.Length)
    Return ms
End Function

Towards the end of my draw function I try to load using the shader function:

vertexShader = path_to_stream(Application.StartupPath & "\default.frag")
    fragmentShader = path_to_stream(Application.StartupPath & "\default.vert")

    vs_object = Helpers.OpenGLUtilities.createAndCompileShader(vertexShader, Gl.GL_VERTEX_SHADER)
    fs_object = Helpers.OpenGLUtilities.createAndCompileShader(fragmentShader, Gl.GL_FRAGMENT_SHADER)

    program = Helpers.OpenGLUtilities.createAttachLinkShaderProgram(vs_object, fs_object)

I get an error message however that the shader could not be compiled. Any idea where I am going wrong?

Here is what my model looks like:

http://i.imgur.com/UvN4Tj8.png

Looks decent but not great..

http://i.imgur.com/G2TJt12.png

Looks terrible..

http://i.imgur.com/SXZ7C5S.png

Just as bad..

Update

Since it was asked below, this is my method for doing the actual drawing of my triangles. The listview it is getting the information from is basically the STL file, which contains the normal vector and then three points which make a triangle.

        Gl.glRotatef(rotX, 1.0F, 0.0F, 0.0F)
        ' Rotate on x
        Gl.glRotatef(rotY, 0.0F, 1.0F, 0.0F)
        ' Rotate on y
        Gl.glRotatef(rotZ, 0.0F, 0.0F, 1.0F)
        ' Rotate on z
        Gl.glTranslatef(X, Y, Z)

        'Gl.glPolygonMode(Gl.GL_FRONT_AND_BACK, Gl.GL_FILL)
        Gl.glBegin(Gl.GL_TRIANGLES)
        Gl.glColor3f(part_color.R, part_color.G, part_color.B)


        Dim i As Integer = 0

        Do Until i + 4 >= ListView1.Items.Count
            Gl.glNormal3f(ListView1.Items.Item(i).SubItems(0).Text, ListView1.Items.Item(i).SubItems(1).Text, ListView1.Items.Item(i).SubItems(2).Text)

            Gl.glVertex3f(ListView1.Items.Item(i + 1).SubItems(0).Text - avgx, ListView1.Items.Item(i + 1).SubItems(1).Text - avgy, ListView1.Items.Item(i + 1).SubItems(2).Text - avgz)
            Gl.glVertex3f(ListView1.Items.Item(i + 2).SubItems(0).Text - avgx, ListView1.Items.Item(i + 2).SubItems(1).Text - avgy, ListView1.Items.Item(i + 2).SubItems(2).Text - avgz)
            Gl.glVertex3f(ListView1.Items.Item(i + 3).SubItems(0).Text - avgx, ListView1.Items.Item(i + 3).SubItems(1).Text - avgy, ListView1.Items.Item(i + 3).SubItems(2).Text - avgz)
            i = i + 4
        Loop
        Gl.glEnd()

My main drawing sub:

Private Sub display()


    Gl.glClear(Gl.GL_COLOR_BUFFER_BIT)
    ' Clear the Color Buffer 
    Gl.glPushMatrix()
    ' It is important to push
    ' the Matrix before calling
    ' glRotatef and glTranslatef
    Gl.glRotatef(rotX, 1.0F, 0.0F, 0.0F)
    ' Rotate on x
    Gl.glRotatef(rotY, 0.0F, 1.0F, 0.0F)
    ' Rotate on y
    Gl.glRotatef(rotZ, 0.0F, 0.0F, 1.0F)
    ' Rotate on z
    Gl.glTranslatef(X, Y, Z)
    ' Translates the screen
    ' left or right, up or down
    ' or zoom in zoom out
    ' Draw the positive side of the lines x,y,z
    Gl.glBegin(Gl.GL_LINES)
    'Gl.glColor3f(0.0F, 1.0F, 0.0F)
    Gl.glColor4f(0.0F, 1.0F, 0.0F, 1.0F)

    ' Green for x axis
    Gl.glVertex3f(0.0F, 0.0F, 0.0F)
    Gl.glVertex3f(10.0F, 0.0F, 0.0F)
    Gl.glColor3f(1.0F, 0.0F, 0.0F)
    ' Red for y axis
    Gl.glVertex3f(0.0F, 0.0F, 0.0F)
    Gl.glVertex3f(0.0F, 10.0F, 0.0F)
    Gl.glColor3f(0.0F, 0.0F, 1.0F)
    ' Blue for z axis
    Gl.glVertex3f(0.0F, 0.0F, 0.0F)
    Gl.glVertex3f(0.0F, 0.0F, 10.0F)
    Gl.glEnd()

    ' Dotted lines for the negative sides of x,y,z
    Gl.glEnable(Gl.GL_LINE_STIPPLE)
    ' Enable line stipple to
    ' use a dotted pattern for
    ' the lines
    Gl.glLineStipple(1, &H101)
    ' Dotted stipple pattern for
    ' the lines
    Gl.glBegin(Gl.GL_LINES)
    Gl.glColor3f(0.0F, 1.0F, 0.0F)
    ' Green for x axis
    Gl.glVertex3f(-10.0F, 0.0F, 0.0F)
    Gl.glVertex3f(0.0F, 0.0F, 0.0F)
    Gl.glColor3f(1.0F, 0.0F, 0.0F)
    ' Red for y axis
    Gl.glVertex3f(0.0F, 0.0F, 0.0F)
    Gl.glVertex3f(0.0F, -10.0F, 0.0F)
    Gl.glColor3f(0.0F, 0.0F, 1.0F)
    ' Blue for z axis
    Gl.glVertex3f(0.0F, 0.0F, 0.0F)
    Gl.glVertex3f(0.0F, 0.0F, -10.0F)
    Gl.glEnd()

    Gl.glDisable(Gl.GL_LINE_STIPPLE)
    ' Disable the line stipple
    Gl.glPopMatrix()
    ' Don't forget to pop the Matrix

    Gl.glEnable(Gl.GL_LIGHTING)

    Light1Position = {0.0F, 0.0F, 100.0F, 0.0F}

    ' Enable Default Light
    Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_AMBIENT, Light1Ambient)
    Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_DIFFUSE, Light1Diffuse)
    Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_POSITION, Light1Position)
    Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_SPECULAR, Light1Specular)

    ' Enable Lighting
    Gl.glEnable(Gl.GL_LIGHT1)




    draw_extras()


    Gl.glEnable(Gl.GL_COLOR_MATERIAL)
    Gl.glColorMaterial(Gl.GL_FRONT, Gl.GL_AMBIENT_AND_DIFFUSE)
    Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, MaterialSpecular)
    Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SHININESS, SurfaceShininess)

    Gl.glEnable(Gl.GL_COLOR_MATERIAL)

    Glut.glutSwapBuffers()
End Sub

My draw_extra sub:

Public Sub draw_extras()
    Dim texture As UInteger() = New UInteger(0) {}


    If allowdraw = True Then

        find_center_of_part()


        Gl.glPushMatrix()


        Gl.glRotatef(rotX, 1.0F, 0.0F, 0.0F)
        ' Rotate on x
        Gl.glRotatef(rotY, 0.0F, 1.0F, 0.0F)
        ' Rotate on y
        Gl.glRotatef(rotZ, 0.0F, 0.0F, 1.0F)
        ' Rotate on z
        Gl.glTranslatef(X, Y, Z)

        Gl.glBegin(Gl.GL_TRIANGLES)
        Gl.glColor3f(part_color.R, part_color.G, part_color.B)


        Dim i As Integer = 0

        Do Until i + 4 >= ListView1.Items.Count
            Gl.glNormal3f(ListView1.Items.Item(i).SubItems(0).Text, ListView1.Items.Item(i).SubItems(1).Text, ListView1.Items.Item(i).SubItems(2).Text)

            Gl.glVertex3f(ListView1.Items.Item(i + 1).SubItems(0).Text - avgx, ListView1.Items.Item(i + 1).SubItems(1).Text - avgy, ListView1.Items.Item(i + 1).SubItems(2).Text - avgz)
            Gl.glVertex3f(ListView1.Items.Item(i + 2).SubItems(0).Text - avgx, ListView1.Items.Item(i + 2).SubItems(1).Text - avgy, ListView1.Items.Item(i + 2).SubItems(2).Text - avgz)
            Gl.glVertex3f(ListView1.Items.Item(i + 3).SubItems(0).Text - avgx, ListView1.Items.Item(i + 3).SubItems(1).Text - avgy, ListView1.Items.Item(i + 3).SubItems(2).Text - avgz)
            i = i + 4
        Loop
        Gl.glEnd()




        ' Disable the line stipple
        Gl.glPopMatrix()

    End If

End Sub

Here is what the STL file looks like:

在此处输入图片说明

It starts with the normal vector, then is followed by three points for the triangle, then another normal vector, and so forth. That is all my loop is doing.

Next Update

I tried changing the code for the light to be:

 Gl.glEnable(Gl.GL_LIGHTING)

    Light1Position = {X, Y, Z, 0.0F}

    ' Enable Default Light
    Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_AMBIENT, Light1Ambient)
    Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_DIFFUSE, Light1Diffuse)
    Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_POSITION, Light1Position)
    Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_SPECULAR, Light1Specular)


    ' Enable Lighting
    Gl.glEnable(Gl.GL_LIGHT1)

The X, Y, Z variables should match the camera since earlier in the code it translates the camera:

Gl.glTranslatef(X, Y, Z)

No light to be found:

在此处输入图片说明

Any guidance at all would be greatly appreaiciated. I tagged this as both C# and VB .NET since either answers would work for me.

You could also write your own shader to render your actual object, which will calculate diffuse lighting, maybe even specular if you want. From there, you could also do texture mapping, shadows, normals, etc.

There is an excellent tutorial by OpenGL on the shader code here , and you can find a tutorial on using GLSL with C# on the internet.

I disagree with the answers here, if your goal is to have simple lighting and you are just starting to learn OGL, you should not have to write your own shaders. OpenGL has built in functionality to handle this for you, as I'm sure you've seen in many tutorials. Although this functionality is no longer supported, which prompts many people to condemn it despite its obvious benefits, it will make your learning process much easier.

Since it's been mentioned that you have enabled lighting, I'd like to know how you currently draw your model. If you use immediate mode (calling glVertex for every vertex), do you also call glNormal to supply normals? Without normals OpenGL has no information about how to calculate the lighting for your model. If you do not use immediate mode, please explain exactly what you do. Submitting your code would be a big help, as I have no idea what you are currently doing, and OpenGL has a million ways for you to make a mistake.

As an addition: The shader code in the tutorial you linked appears to be overly complicated for a beginner, you should not use that.

I'd like to put this in a comment instead of an answer, but my reputation is currently insufficient.

Please ask any questions in the comments of my answer, so a step-by-step resolution of your problem can be achieved.

I can see nowhere when you turned on lightning. It's okay that you turned on 2 lights with glEnable(GL_LIGHTn) but the whole stuff is not enabled. There's an article if you're confused. I'm saying that because your models look like aren't shaded at all, they all have the same colour and that colour not depends on how the surface directs to the light source, doesn't depend on the normal if you set it I should say. I think two light is far enough for that purpose, for demo projects I usually have my lightning with one diffuse light, I don't even set the ambient or the specular part. Like this way:

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_DIFFUSE, { 0.8f, 0.8f, 0.8f, 1.0f } );

It's pretty simple but you have all you probably want, basic shading, and not just one big colour splotch in your screen forming your shape's border.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM