Open GL Lighting Трудности

Фон

В настоящее время я по сути делаю просмотрщик САПР, который будет использоваться в более крупной системе. Я читал тонну информации об изучении Open GL, и я довольно далеко продвинулся. Я могу импортировать файл, отображать его и перемещаться с помощью клавиш управления. Я стараюсь понять и настроить правильное освещение сейчас.

проблема

После некоторого обсуждения ниже, я понимаю, что у меня нет загруженного шейдера, поэтому у меня проблемы. Проводя некоторые исследования, я нашел несколько шейдерных файлов, фрагмента.glsl и vertex.glsl, которые написаны на C. Будет ли это проблемой, так как я пишу свой код на C#/ VB.net? Я так не думаю.

Теперь у меня проблема с компиляцией шейдинга и связыванием шейдеров с моим кодом. Я нашел удобный источник для компиляции:

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

В этой статье создается функция для компиляции шейдера. Компилятору требуется поток, в который затем передается компилятору. У меня есть эта функция, которую я создал, чтобы читать шейдер в поток:

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

В конце своей функции рисования я пытаюсь загрузить, используя функцию шейдера:

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)

Однако я получаю сообщение об ошибке, что шейдер не может быть скомпилирован. Любая идея, где я иду не так?

Вот как выглядит моя модель:

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

Выглядит достойно, но не отлично..

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

Выглядит ужасно..

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

Так же плохо..

Обновить

Так как это было задано ниже, это мой метод для рисования моих треугольников. Представление списка, из которого он получает информацию, в основном представляет собой файл STL, который содержит вектор нормали, а затем три точки, образующие треугольник.

        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()

Мой основной чертежный саб:

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

Моя ветка draw_extra:

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

Вот как выглядит файл STL:

введите описание изображения здесь

Он начинается с вектора нормали, затем следуют три точки для треугольника, затем еще один вектор нормали и так далее. Это все, что делает мой цикл.

Следующее обновление

Я попытался изменить код для света, чтобы быть:

 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)

Переменные X, Y, Z должны соответствовать камере, так как ранее в коде она переводит камеру:

Gl.glTranslatef(X, Y, Z)

Нет света, чтобы найти:

введите описание изображения здесь

Любое руководство будет очень оценено. Я отметил это как C# и VB .NET, так как оба ответа будут работать для меня.

3 ответа

Вы также можете написать свой собственный шейдер для визуализации вашего реального объекта, который будет рассчитывать рассеянное освещение, возможно, даже зеркальное, если хотите. Оттуда вы также можете делать наложение текстур, тени, нормали и т. Д.

OpenGL предлагает отличное руководство по коду шейдера, и вы можете найти руководство по использованию GLSL с C# в Интернете.

Я не согласен с ответами здесь: если ваша цель - иметь простое освещение и вы только начинаете изучать OGL, вам не нужно писать свои собственные шейдеры. OpenGL имеет встроенную функциональность, чтобы справиться с этим для вас, как я уверен, вы видели во многих руководствах. Хотя эта функция больше не поддерживается, что побуждает многих людей осуждать ее, несмотря на ее очевидные преимущества, она значительно облегчит ваш учебный процесс.

Поскольку уже упоминалось, что вы включили освещение, я хотел бы знать, как вы в данный момент рисуете свою модель. Если вы используете немедленный режим (вызывая glVertex для каждой вершины), вызываете ли вы также glNormal для предоставления нормалей? Без нормалей OpenGL не имеет информации о том, как рассчитать освещение для вашей модели. Если вы не используете немедленный режим, пожалуйста, объясните, что именно вы делаете. Отправка вашего кода была бы большой помощью, так как я понятия не имею, чем вы сейчас занимаетесь, и у OpenGL есть миллион способов сделать ошибку.

Как дополнение: код шейдера в учебнике, который вы связали, кажется слишком сложным для начинающего, вы не должны его использовать.

Я хотел бы поместить это в комментарии вместо ответа, но моя репутация в настоящее время недостаточна.

Пожалуйста, задавайте любые вопросы в комментариях к моему ответу, чтобы можно было найти пошаговое решение вашей проблемы.

Я нигде не вижу, когда ты включил молнию. Это нормально, что вы включили 2 лампы с glEnable(GL_LIGHTn) но весь материал не включен. Там есть статья, если вы запутались. Я говорю, что, поскольку ваши модели выглядят совсем не затененными, все они имеют одинаковый цвет, и этот цвет не зависит от того, как поверхность направлена ​​на источник света, не зависит от нормального, если вы установите его. должен сказать. Я думаю, что двух источников света достаточно для этой цели, для демонстрационных проектов у меня обычно есть молния с одним рассеянным светом, я даже не устанавливаю рассеивающую или зеркальную часть. Вот так:

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

Это довольно просто, но у вас есть все, что вы, вероятно, хотите, базовое затенение, а не только одно большое цветовое пятно на экране, формирующее границу вашей фигуры.

Другие вопросы по тегам