Форум программистов, компьютерный форум, киберфорум
Python: GUI, графика
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.60/15: Рейтинг темы: голосов - 15, средняя оценка - 4.60
3 / 3 / 0
Регистрация: 04.11.2018
Сообщений: 123
1

Непрерывное движение obj модели вверх-вниз

22.01.2021, 00:42. Просмотров 2984. Ответов 8

Здравствуйте уважаемые!

Столкнулся с проблемой, не могу заставить свою obj модель двигаться вниз вверх непрерывно на заданную высоту. Обычная анимация короче. То есть поднимается на 10, затем спускается на 10 и т.д.

Вылезают такие ошибки:
Traceback (most recent call last):
File "...", line 258, in <module>
main()
File "...", line 166, in main
meduza_matrix.for_translate('y', meduza_height)
AttributeError: 'matrix' object has no attribute 'for_translate'

Ошибка именно в этой строке: meduza_matrix.translate('y', meduza_height)
То есть я так понимаю что к meduza_matrix нельзя применить translate, но что тогда сделать чтобы можно было не понимаю :/


Пытаюсь сделать это движение через матрицу так:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
meduza_matrix = np.mat(np.eye(100))
    meduza_height = 0
    meduza_raise = true
 
    if meduza_raise:
        meduza_height += 1
        meduza_matrix.translate('y', meduza_height)
        if meduza_height == 10:
            meduza_raise == false
    else:
        meduza_height -= 1
        meduza_matrix.translate('y', meduza_height)
        if meduza_height == -10:
            meduza_raise == true
 
meduza_vao = glGenVertexArrays(1)
    glBindVertexArray(meduza_vao)
    meduza_vbo = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, meduza_vbo)
    glBufferData(GL_ARRAY_BUFFER, meduza.model.itemsize * len(meduza.model),
                 meduza_matrix * meduza.model, GL_STATIC_DRAW)
    # position
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, meduza.model.itemsize * 3, ctypes.c_void_p(0))
    glEnableVertexAttribArray(0)
    # textures
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, meduza.model.itemsize * 2, ctypes.c_void_p(meduza_texture_offset))
    glEnableVertexAttribArray(1)
    glBindVertexArray(0)
Может кто знает как мне можно сделать эту анимацию, а то я уже всю голову сломал
Подскажите пожалуйста, буду очень благодарен)
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.01.2021, 00:42
Ответы с готовыми решениями:

Движение точки вверх - вниз
.code start: mov ax, 0013h ; int 10h ; ;--------------тело проги tochka: MOV...

ActiveRecord треверсинг вверх и вниз по модели MySQL
Предположим, что есть модель: И есть результат запроса ActiveRecord который закеширован в...

Движение двух окружностей вверх / вниз
Нужно чтобы две окружности двигались верх вниз из одного угла в другой. Написал код. Они двигаются...

Движение картинки pictureBox вниз и вверх
Как сделать движение по экрану картинки вверх и вниз при запуске программы? Запустил я программу и...

8
846 / 563 / 156
Регистрация: 07.11.2019
Сообщений: 1,324
22.01.2021, 06:50 2
Так .for_translate или .translate вы вызываете?
0
3 / 3 / 0
Регистрация: 04.11.2018
Сообщений: 123
22.01.2021, 12:04  [ТС] 3
u235, а там без разницы, и то и то пробовал вызывать ошибка та же
AttributeError: 'matrix' object has no attribute 'translate'.

Добавлено через 2 минуты
u235, может есть какой-то другой способ такой анимации, если уж через матрицу не получается?
Смотрел через pygame, но не смог разобраться, как его конкретно к моей 3d obj-модели применить
0
846 / 563 / 156
Регистрация: 07.11.2019
Сообщений: 1,324
22.01.2021, 16:30 4
Космодемьян, запустите в режиме отладки и смотрите что у вас происходит и почему ошибка.
Так как вы привели неполный код и не приложили obj, то разбирайтесь самостоятельно. Удачи.
0
4176 / 2282 / 387
Регистрация: 05.10.2013
Сообщений: 6,385
Записей в блоге: 177
22.01.2021, 18:07 5
Лучший ответ Сообщение было отмечено Космодемьян как решение

Решение

Цитата Сообщение от Космодемьян Посмотреть сообщение
Может кто знает как мне можно сделать эту анимацию, а то я уже всю голову сломал
Подскажите пожалуйста, буду очень благодарен)
Я могу вам предложить свою посильную помощь в переписывании вашего примера на PyQt5 или на PySide2. В эти фреймворки встроена удобная лёгкая обёртка над матрицами и OpenGL.

Написал очень короткий пример на PyQt5 и PySide2, который просто выводит на экран матрицу после применения метода translate:

Python
1
2
3
4
5
6
    def initializeGL(self):
        gl.glClearColor(0.2, 0.2, 0.2, 1)
        gl.glEnable(gl.GL_DEPTH_TEST)
        self.matrix = QMatrix4x4()
        self.matrix.translate(QVector3D(2, 3, 5))
        print(self.matrix)
PyQt5

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import sys
 
from OpenGL import GL as gl
from PyQt5.QtWidgets import QApplication, QOpenGLWidget
from PyQt5.QtGui import QMatrix4x4, QVector3D
from PyQt5.QtCore import Qt
 
class Window(QOpenGLWidget):
 
    def __init__(self):
        super().__init__()
        self.setWindowTitle("PyQt5")
        self.resize(400, 400)
 
    def initializeGL(self):
        gl.glClearColor(0.2, 0.2, 0.2, 1)
        gl.glEnable(gl.GL_DEPTH_TEST)
        self.matrix = QMatrix4x4()
        self.matrix.translate(QVector3D(2, 3, 5))
        print(self.matrix)
 
    def paintGL(self):
        gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
 
def main():
    QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)
    app = QApplication(sys.argv)
    w = Window()
    w.show()
    sys.exit(app.exec_())
 
if __name__ == "__main__":
    main()


PySide2
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import sys
 
from OpenGL import GL as gl
from PySide2.QtWidgets import QApplication, QOpenGLWidget
from PySide2.QtGui import QMatrix4x4, QVector3D
from PySide2.QtCore import Qt
 
class Window(QOpenGLWidget):
 
    def __init__(self):
        super().__init__()
        self.setWindowTitle("PySide2")
        self.resize(400, 400)
 
    def initializeGL(self):
        gl.glClearColor(0.2, 0.2, 0.2, 1)
        gl.glEnable(gl.GL_DEPTH_TEST)
        self.matrix = QMatrix4x4()
        self.matrix.translate(QVector3D(2, 3, 5))
        print(self.matrix)
 
    def paintGL(self):
        gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
 
def main():
    QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)
    app = QApplication(sys.argv)
    w = Window()
    w.show()
    sys.exit(app.exec_())
 
if __name__ == "__main__":
    main()


Пример, как нарисовать треугольник:
  • PyQt5: https://rextester.com/KWYGH93003
    main.py
    Python
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    
    import sys
    import numpy as np
    from OpenGL import GL as gl
    from PyQt5.QtWidgets import QOpenGLWidget, QApplication
    from PyQt5.QtGui import (QOpenGLBuffer, QOpenGLShaderProgram,
        QOpenGLShader)
    from PyQt5.QtCore import Qt
     
    class OpenGLWidget(QOpenGLWidget):
        def __init__(self):
            super().__init__()
            self.setWindowTitle("Triangle, PyQt5, OpenGL 3.3")
            self.resize(400, 400)
        def initializeGL(self):
            gl.glClearColor(0.5, 0.8, 0.7, 1.0)
            vertShaderSrc = """
                #version 330 core
                in vec3 aPosition;
                void main()
                {
                    gl_Position = vec4(aPosition, 1.0);
                }
            """
            fragShaderSrc = """
                #version 330 core
                void main()
                {
                    gl_FragColor = vec4(0.5, 0.2, 0.9, 1.0);
                }
            """
            program = QOpenGLShaderProgram(self)
            program.addShaderFromSourceCode(QOpenGLShader.Vertex, vertShaderSrc)
            program.addShaderFromSourceCode(QOpenGLShader.Fragment, fragShaderSrc)
            program.link()
            program.bind()
            vertPositions = np.array([
                -0.5, -0.5, 0.0,
                0.5, -0.5, 0.0,
                0.0, 0.5, 0.0], dtype=np.float32)
            self.vertPosBuffer = QOpenGLBuffer()
            self.vertPosBuffer.create()
            self.vertPosBuffer.bind()
            self.vertPosBuffer.allocate(vertPositions, len(vertPositions) * 4)
            program.bindAttributeLocation("aPosition", 0)
            program.setAttributeBuffer(0, gl.GL_FLOAT, 0, 3)
            program.enableAttributeArray(0)
     
        def paintGL(self):
            gl.glClear(gl.GL_COLOR_BUFFER_BIT)
            gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3)
     
    def main():
        QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)
        a = QApplication(sys.argv)
        w = OpenGLWidget()
        w.show()
        sys.exit(a.exec_())
     
    if __name__ == "__main__":
        main()
  • PySide2: https://rextester.com/RDHCF22516
    main.py
    Python
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    
    import sys
    import numpy as np
    from OpenGL import GL as gl
    from PySide2.QtWidgets import QOpenGLWidget, QApplication
    from PySide2.QtGui import (QOpenGLBuffer, QOpenGLShaderProgram,
        QOpenGLShader)
    from PySide2.QtCore import Qt
     
    class OpenGLWidget(QOpenGLWidget):
        def __init__(self):
            super().__init__()
            self.setWindowTitle("Triangle, PySide2, OpenGL 3.3")
            self.resize(400, 400)
        def initializeGL(self):
            gl.glClearColor(0.5, 0.8, 0.7, 1.0)
            vertShaderSrc = """
                #version 330 core
                in vec3 aPosition;
                void main()
                {
                    gl_Position = vec4(aPosition, 1.0);
                }
            """
            fragShaderSrc = """
                #version 330 core
                void main()
                {
                    gl_FragColor = vec4(0.5, 0.2, 0.9, 1.0);
                }
            """
            program = QOpenGLShaderProgram(self)
            program.addShaderFromSourceCode(QOpenGLShader.Vertex, vertShaderSrc)
            program.addShaderFromSourceCode(QOpenGLShader.Fragment, fragShaderSrc)
            program.link()
            program.bind()
            vertPositions = np.array([
                -0.5, -0.5, 0.0,
                0.5, -0.5, 0.0,
                0.0, 0.5, 0.0], dtype=np.float32)
            self.vertPosBuffer = QOpenGLBuffer()
            self.vertPosBuffer.create()
            self.vertPosBuffer.bind()
            self.vertPosBuffer.allocate(vertPositions, len(vertPositions) * 4)
            program.bindAttributeLocation("aPosition", 0)
            program.setAttributeBuffer(0, gl.GL_FLOAT, 0, 3)
            program.enableAttributeArray(0)
     
        def paintGL(self):
            gl.glClear(gl.GL_COLOR_BUFFER_BIT)
            gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3)
     
    def main():
        QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)
        a = QApplication(sys.argv)
        w = OpenGLWidget()
        w.show()
        sys.exit(a.exec_())
     
    if __name__ == "__main__":
        main()
2
4176 / 2282 / 387
Регистрация: 05.10.2013
Сообщений: 6,385
Записей в блоге: 177
23.01.2021, 15:15 6
Раз вам понравился мой ответ, то дарю вам пример кубика, откуда вы можете взять базу для 3D, в том числе шейдеры для базового освещения:

Кубик в 3D:
  • PyQt5: https://rextester.com/VIQC38551
    main.py

    Python
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    
    import sys
    import numpy as np
    from OpenGL import GL as gl
    from PyQt5.QtWidgets import QApplication, QOpenGLWidget
    from PyQt5.QtGui import (QOpenGLShaderProgram, QOpenGLShader,
        QOpenGLBuffer, QMatrix4x4, QVector3D)
    from PyQt5.QtCore import Qt
     
    class OpenGLWidget(QOpenGLWidget):
        def __init__(self):
            super().__init__()
            self.setWindowTitle("PyQt5, OpenGL")
            self.resize(268, 268)
        def initializeGL(self):
            gl.glClearColor(0.5, 0.8, 0.7, 1.0)
            gl.glEnable(gl.GL_DEPTH_TEST)
            vertShaderSrc = """
                    #version 330 core
                    in vec3 aPosition;
                    in vec4 aNormal;
                    uniform mat4 uMvpMatrix;
                    uniform mat4 uNormalMatrix;
                    out vec4 vColor;
                    void main()
                    {
                        gl_Position = uMvpMatrix * vec4(aPosition, 1.0);
                        vec3 lightDirection = normalize(vec3(0.0, 0.5, 0.7));
                        vec4 color = vec4(1.0, 0.4, 0.0, 1.0);
                        vec3 normal = normalize((uNormalMatrix * aNormal).xyz);
                        float nDotL = max(dot(normal, lightDirection), 0.0);
                        vColor = vec4(color.rgb * nDotL + vec3(0.1), color.a);
                    }
            """
            fragShaderSrc = """
                    #version 330 core
                    in vec4 vColor;
                    out vec4 fragColor;
                    void main()
                    {
                        fragColor = vColor;
                    }
            """
            self.program = QOpenGLShaderProgram()
            self.program.addShaderFromSourceCode(QOpenGLShader.Vertex, vertShaderSrc)
            self.program.addShaderFromSourceCode(QOpenGLShader.Fragment, fragShaderSrc)
            self.program.link()
            self.program.bind()
            self.amountOfVertices = self.initVertexBuffers()
            self.projMatrix = QMatrix4x4()
            self.viewMatrix = QMatrix4x4()
            self.viewMatrix.lookAt(
                QVector3D(20, 15, 30),
                QVector3D(0, 0, 0),
                QVector3D(0, 1, 0))
            self.modelMatrix = QMatrix4x4()
            self.modelMatrix.translate(QVector3D(0, 0, 0))
            self.modelMatrix.rotate(0, QVector3D(0, 1, 0))
            self.modelMatrix.scale(7, 7, 7)
            self.normalMatrix = QMatrix4x4()
        def paintGL(self):
            gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
            self.drawBox()
        def drawBox(self):
            mvpMatrix = self.projMatrix * self.viewMatrix * self.modelMatrix
            self.program.bind()
            self.program.setUniformValue("uMvpMatrix", mvpMatrix)
            self.normalMatrix = self.modelMatrix.inverted()
            self.normalMatrix = self.normalMatrix[0].transposed()
            self.program.setUniformValue("uNormalMatrix", self.normalMatrix)
            gl.glDrawElements(gl.GL_TRIANGLES, self.amountOfVertices, gl.GL_UNSIGNED_INT, None)
        def resizeGL(self, w, h):
            gl.glViewport(0, 0, w, h)
            self.projMatrix.setToIdentity()
            self.projMatrix.perspective(50, float(w)/float(h), 0.1, 100)
        def initVertexBuffers(self):
            # Create a cube
            #    v6----- v5
            #   /|      /|
            #  v1------v0|
            #  | |     | |
            #  | |v7---|-|v4
            #  |/      |/
            #  v2------v3
            vertPositions = np.array([
                # v0-v1-v2-v3 front
                1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0,
                # v0-v3-v4-v5 right
                1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0,
                # v0-v5-v6-v1 up
                1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0,
                # v1-v6-v7-v2 left
                -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0,
                # v7-v4-v3-v2 down
                -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0,
                # v4-v7-v6-v5 back
                1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0
            ], dtype=np.float32)
            self.vertPosBuffer = QOpenGLBuffer()
            self.vertPosBuffer.create()
            self.vertPosBuffer.bind()
            self.vertPosBuffer.allocate(vertPositions, len(vertPositions) * 4)
            self.program.bindAttributeLocation("aPosition", 0)
            self.program.setAttributeBuffer(0, gl.GL_FLOAT, 0, 3)
            self.program.enableAttributeArray(0)
            normals = np.array([
                # v0-v1-v2-v3 front
                0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0,
                # v0-v3-v4-v5 right
                1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
                # v0-v5-v6-v1 up
                0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0,
                # v1-v6-v7-v2 left
                -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
                # v7-v4-v3-v2 down
                0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0,
                # v4-v7-v6-v5 back
                0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0
            ], dtype=np.float32)
            self.normalBuffer = QOpenGLBuffer()
            self.normalBuffer.create()
            self.normalBuffer.bind()
            self.normalBuffer.allocate(normals, len(normals) * 4)
            self.program.bindAttributeLocation("aNormal", 1)
            self.program.setAttributeBuffer(1, gl.GL_FLOAT, 0, 3)
            self.program.enableAttributeArray(1)
            indices = np.array([
                0, 1, 2, 0, 2, 3,           # front
                4, 5, 6, 4, 6, 7,           # right
                8, 9, 10, 8, 10, 11,        # up
                12, 13, 14, 12, 14, 15,     # left
                16, 17, 18, 16, 18, 19,     # down
                20, 21, 22, 20, 22, 23      # back
            ])
            self.indexBuffer = QOpenGLBuffer(QOpenGLBuffer.IndexBuffer)
            self.indexBuffer.create()
            self.indexBuffer.bind()
            self.indexBuffer.allocate(indices, len(indices) * 4)
            return len(indices)
     
    def main():
        QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)
        a = QApplication(sys.argv)
        w = OpenGLWidget()
        w.show()
        sys.exit(a.exec_())
     
    if __name__ == "__main__":
        main()
  • PySide2: https://rextester.com/OWJ98916
    main.py

    Python
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    
    import sys
    import numpy as np
    from OpenGL import GL as gl
    from PySide2.QtWidgets import QApplication, QOpenGLWidget
    from PySide2.QtGui import (QOpenGLShaderProgram, QOpenGLShader,
        QOpenGLBuffer, QMatrix4x4, QVector3D)
    from PySide2.QtCore import Qt
     
    class OpenGLWidget(QOpenGLWidget):
        def __init__(self):
            super().__init__()
            self.setWindowTitle("PyQt5, OpenGL")
            self.resize(268, 268)
        def initializeGL(self):
            gl.glClearColor(0.5, 0.8, 0.7, 1.0)
            gl.glEnable(gl.GL_DEPTH_TEST)
            vertShaderSrc = """
                    #version 330 core
                    in vec3 aPosition;
                    in vec4 aNormal;
                    uniform mat4 uMvpMatrix;
                    uniform mat4 uNormalMatrix;
                    out vec4 vColor;
                    void main()
                    {
                        gl_Position = uMvpMatrix * vec4(aPosition, 1.0);
                        vec3 lightDirection = normalize(vec3(0.0, 0.5, 0.7));
                        vec4 color = vec4(1.0, 0.4, 0.0, 1.0);
                        vec3 normal = normalize((uNormalMatrix * aNormal).xyz);
                        float nDotL = max(dot(normal, lightDirection), 0.0);
                        vColor = vec4(color.rgb * nDotL + vec3(0.1), color.a);
                    }
            """
            fragShaderSrc = """
                    #version 330 core
                    in vec4 vColor;
                    out vec4 fragColor;
                    void main()
                    {
                        fragColor = vColor;
                    }
            """
            self.program = QOpenGLShaderProgram()
            self.program.addShaderFromSourceCode(QOpenGLShader.Vertex, vertShaderSrc)
            self.program.addShaderFromSourceCode(QOpenGLShader.Fragment, fragShaderSrc)
            self.program.link()
            self.program.bind()
            self.amountOfVertices = self.initVertexBuffers()
            self.projMatrix = QMatrix4x4()
            self.viewMatrix = QMatrix4x4()
            self.viewMatrix.lookAt(
                QVector3D(20, 15, 30),
                QVector3D(0, 0, 0),
                QVector3D(0, 1, 0))
            self.modelMatrix = QMatrix4x4()
            self.modelMatrix.translate(QVector3D(0, 0, 0))
            self.modelMatrix.rotate(0, QVector3D(0, 1, 0))
            self.modelMatrix.scale(7, 7, 7)
            self.normalMatrix = QMatrix4x4()
        def paintGL(self):
            gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
            self.drawBox()
        def drawBox(self):
            mvpMatrix = self.projMatrix * self.viewMatrix * self.modelMatrix
            self.program.bind()
            self.program.setUniformValue("uMvpMatrix", mvpMatrix)
            self.normalMatrix = self.modelMatrix.inverted()
            self.normalMatrix = self.normalMatrix[0].transposed()
            self.program.setUniformValue("uNormalMatrix", self.normalMatrix)
            gl.glDrawElements(gl.GL_TRIANGLES, self.amountOfVertices, gl.GL_UNSIGNED_INT, None)
        def resizeGL(self, w, h):
            gl.glViewport(0, 0, w, h)
            self.projMatrix.setToIdentity()
            self.projMatrix.perspective(50, float(w)/float(h), 0.1, 100)
        def initVertexBuffers(self):
            # Create a cube
            #    v6----- v5
            #   /|      /|
            #  v1------v0|
            #  | |     | |
            #  | |v7---|-|v4
            #  |/      |/
            #  v2------v3
            vertPositions = np.array([
                # v0-v1-v2-v3 front
                1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0,
                # v0-v3-v4-v5 right
                1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0,
                # v0-v5-v6-v1 up
                1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0,
                # v1-v6-v7-v2 left
                -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0,
                # v7-v4-v3-v2 down
                -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0,
                # v4-v7-v6-v5 back
                1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0
            ], dtype=np.float32)
            self.vertPosBuffer = QOpenGLBuffer()
            self.vertPosBuffer.create()
            self.vertPosBuffer.bind()
            self.vertPosBuffer.allocate(vertPositions, len(vertPositions) * 4)
            self.program.bindAttributeLocation("aPosition", 0)
            self.program.setAttributeBuffer(0, gl.GL_FLOAT, 0, 3)
            self.program.enableAttributeArray(0)
            normals = np.array([
                # v0-v1-v2-v3 front
                0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0,
                # v0-v3-v4-v5 right
                1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
                # v0-v5-v6-v1 up
                0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0,
                # v1-v6-v7-v2 left
                -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
                # v7-v4-v3-v2 down
                0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0,
                # v4-v7-v6-v5 back
                0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0
            ], dtype=np.float32)
            self.normalBuffer = QOpenGLBuffer()
            self.normalBuffer.create()
            self.normalBuffer.bind()
            self.normalBuffer.allocate(normals, len(normals) * 4)
            self.program.bindAttributeLocation("aNormal", 1)
            self.program.setAttributeBuffer(1, gl.GL_FLOAT, 0, 3)
            self.program.enableAttributeArray(1)
            indices = np.array([
                0, 1, 2, 0, 2, 3,           # front
                4, 5, 6, 4, 6, 7,           # right
                8, 9, 10, 8, 10, 11,        # up
                12, 13, 14, 12, 14, 15,     # left
                16, 17, 18, 16, 18, 19,     # down
                20, 21, 22, 20, 22, 23      # back
            ])
            self.indexBuffer = QOpenGLBuffer(QOpenGLBuffer.IndexBuffer)
            self.indexBuffer.create()
            self.indexBuffer.bind()
            self.indexBuffer.allocate(indices, len(indices) * 4)
            return len(indices)
     
    def main():
        QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)
        a = QApplication(sys.argv)
        w = OpenGLWidget()
        w.show()
        sys.exit(a.exec_())
     
    if __name__ == "__main__":
        main()

Мне больше всего понравилась книга, где отлично описывается введение в шейдеры: WebGL. Программирование трехмерной графики | Мацуда Коичи, Ли Роджер. Код в ней на JavaScript, но WebGL - это по сути тоже самое, что и OpenGL, поэтому код переписывать несложно. Главное, что в книге очень доступно изложена теория работы шейдеров и многих других полезных вещей. Примеры из книги в первом сообщении темы: Небольшие примеры на WebGL
1
4176 / 2282 / 387
Регистрация: 05.10.2013
Сообщений: 6,385
Записей в блоге: 177
24.01.2021, 12:29 7
Я использую формат dae, потому что его легче парсить, так как dae - это XML, а в PyQt5 и PySide2 встроен парсинг XML, и второе - dae позволяет сохранять анимации созданные в Blender.

В этом видео обзорно показан формат dae:
OpenGL Skeletal Animation Tutorial #4: Collada (.dae) Format


Скину пример загрузки объекта из формата dae (Collada) на PyQt5 и PySide2. Может кому-нибудь пригодится.

Название: ad5bdb90-07b6-4c31-a302-26f3940a8a61.png
Просмотров: 65

Размер: 4.2 Кб

Скачать исходники:

Посмотреть исходники:
  • PyQt5: https://rextester.com/LPUC58350
    main.py

    Python
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    
    import sys
    import numpy as np
    from OpenGL import GL as gl
    from PyQt5.QtWidgets import QApplication, QOpenGLWidget
    from PyQt5.QtGui import QOpenGLShaderProgram, QOpenGLShader, QOpenGLBuffer
    from PyQt5.QtGui import QOpenGLTexture, QImage
    from PyQt5.QtGui import QMatrix4x4, QVector3D
    from PyQt5.QtXml import QDomDocument, QDomElement
    from PyQt5.QtCore import Qt, QFile, QIODevice
     
    class VertexBuffers:
        vertex_pos_buffer = None
        normal_buffer = None
        tex_coord_buffer = None
        amount_of_vertices = None
     
    class Locations:
        mvp_matrix_location = None
        model_matrix_location = None
        normal_matrix_location = None
     
    class Object3D:
        position = QVector3D(0, 0, 0)
        rotation = QVector3D(0, 0, 0)
        scale = QVector3D(1, 1, 1)
        mvp_matrix = QMatrix4x4()
        model_matrix = QMatrix4x4()
        normal_matrix = QMatrix4x4()
     
        def __init__(self, vert_buffers, locations, texture):
            self.vert_pos_buffer = vert_buffers.vert_pos_buffer
            self.normal_buffer = vert_buffers.normal_buffer
            self.tex_coord_buffer = vert_buffers.tex_coord_buffer
            self.amount_of_vertices = vert_buffers.amount_of_vertices
            
            self.mvp_matrix_location = locations.mvp_matrix_location
            self.model_matrix_location = locations.model_matrix_location
            self.normal_matrix_location = locations.normal_matrix_location
            
            self.texture = texture
     
        def draw(self, program, proj_view_matrix):
            program.bind()
     
            self.vert_pos_buffer.bind()
            program.setAttributeBuffer(0, gl.GL_FLOAT, 0, 3)
            program.enableAttributeArray(0)
     
            self.normal_buffer.bind()
            program.setAttributeBuffer(1, gl.GL_FLOAT, 0, 3)
            program.enableAttributeArray(1)
     
            self.tex_coord_buffer.bind()
            program.setAttributeBuffer(2, gl.GL_FLOAT, 0, 2)
            program.enableAttributeArray(2)
            
            self.model_matrix.setToIdentity()
            self.model_matrix.translate(self.position)
            self.model_matrix.rotate(self.rotation.x(), QVector3D(1, 0, 0))
            self.model_matrix.rotate(self.rotation.y(), QVector3D(0, 1, 0))
            self.model_matrix.rotate(self.rotation.z(), QVector3D(0, 0, 1))
            self.model_matrix.scale(self.scale)
            self.mvp_matrix = proj_view_matrix * self.model_matrix;
            
            self.normal_matrix = self.model_matrix.inverted()
            self.normal_matrix = self.normal_matrix[0].transposed()
            
            program.bind()
            program.setUniformValue(self.mvp_matrix_location, self.mvp_matrix)
            program.setUniformValue(self.model_matrix_location, self.model_matrix)
            program.setUniformValue(self.normal_matrix_location, self.normal_matrix)
            
            self.texture.bind()
     
            gl.glDrawArrays(gl.GL_TRIANGLES, 0, self.amount_of_vertices)
     
    class Window(QOpenGLWidget):
     
        def __init__(self):
            super().__init__()
            self.setWindowTitle("Dae, Collada")
            self.resize(268, 268)
     
        def initializeGL(self):
            gl.glClearColor(0.2, 0.2, 0.2, 1)
            gl.glEnable(gl.GL_DEPTH_TEST)
            vertShaderSrc = """
                #version 330 core
     
                in vec4 aPosition;
                in vec4 aNormal;
                in vec2 aTexCoord;
     
                uniform mat4 uMvpMatrix;
                uniform mat4 uModelMatrix;
                uniform mat4 uNormalMatrix;
     
                out vec3 vPosition;
                out vec3 vNormal;
                out vec2 vTexCoord;
     
                void main()
                {
                    gl_Position = uMvpMatrix * aPosition;
                    vPosition = vec3(uModelMatrix * aPosition);
                    vNormal = normalize(vec3(uNormalMatrix * aNormal));
                    vTexCoord = aTexCoord;
                }
            """
            fragShaderSrc = """
                #version 330 core
     
                const vec3 lightColor = vec3(0.8, 0.8, 0.8);
                const vec3 lightPosition = vec3(5.0, 7.0, 2.0);
                const vec3 ambientLight = vec3(0.3, 0.3, 0.3);
     
                uniform sampler2D uSampler;
     
                in vec3 vPosition;
                in vec3 vNormal;
                in vec2 vTexCoord;
     
                void main()
                {
                    vec4 color = texture2D(uSampler, vTexCoord);
                    vec3 normal = normalize(vNormal);
                    vec3 lightDirection = normalize(lightPosition - vPosition);
                    float nDotL = max(dot(lightDirection, normal), 0.0);
                    vec3 diffuse = lightColor * color.rgb * nDotL;
                    vec3 ambient = ambientLight * color.rgb;
                    gl_FragColor = vec4(diffuse + ambient, color.a);
                }
            """
            self.program = QOpenGLShaderProgram()
            self.program.addShaderFromSourceCode(QOpenGLShader.Vertex, vertShaderSrc)
            self.program.addShaderFromSourceCode(QOpenGLShader.Fragment, fragShaderSrc)
            self.program.link()
            self.program.bind()
            self.program.bindAttributeLocation("aPosition", 0)
            self.program.bindAttributeLocation("aNormal", 1)
            self.program.bindAttributeLocation("aTexCoord", 2)
            locations = Locations()
            self.program.bind()
            locations.mvp_matrix_location = self.program.uniformLocation("uMvpMatrix");
            locations.model_matrix_location = self.program.uniformLocation("uModelMatrix")
            locations.normal_matrix_location = self.program.uniformLocation("uNormalMatrix")
            self.vert_buffers = self.initVertexBuffers("assets/cube.dae")
            self.proj_view_matrix = QMatrix4x4()
            self.proj_matrix = QMatrix4x4()
            self.view_matrix = QMatrix4x4()
            self.view_matrix.lookAt(
                QVector3D(2, 3, 5),
                QVector3D(0, 0, 0),
                QVector3D(0, 1, 0))
            
            self.texture = QOpenGLTexture(QOpenGLTexture.Target2D)
            self.texture.create()
            self.texture.setData(QImage("assets/cube.png"))
            self.texture.setMinMagFilters(QOpenGLTexture.Linear, QOpenGLTexture.Linear)
            self.texture.setWrapMode(QOpenGLTexture.ClampToEdge)
            self.plane = Object3D(self.vert_buffers, locations, self.texture)
            
        def paintGL(self):
            gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
            self.proj_view_matrix = self.proj_matrix * self.view_matrix
            self.plane.draw(self.program, self.proj_view_matrix)
     
        def resizeGL(self, w, h):
            gl.glViewport(0, 0, w, h)
            self.proj_matrix.setToIdentity()
            self.proj_matrix.perspective(50, float(w) / float(h), 0.1, 100)
            
        def initVertexBuffers(self, path):
            xml_doc = QDomDocument()
            file = QFile(path)
            if not file.open(QIODevice.ReadOnly):
                print("Failed to open the file: " + path)
            xml_doc.setContent(file)
            file.close()
            
            vert_pos_array = []
            normal_array = []
            tex_coord_array = []
            index_array = []
            
            root = xml_doc.documentElement()
            dae_elem = root.firstChildElement()
            while not dae_elem.isNull():
                if dae_elem.tagName() == "library_geometries":
                    geom_elem = dae_elem.firstChildElement()
                    if geom_elem.tagName() == "geometry":
                        mesh_elem = geom_elem.firstChildElement()
                        if mesh_elem.tagName() == "mesh":
                            mesh_child_elem = mesh_elem.firstChildElement()
                            while not mesh_child_elem.isNull():
                                float_array_elem = mesh_child_elem.firstChildElement()
                                str_array = float_array_elem.firstChild().toText().data().split(" ")
                                if mesh_child_elem.attribute("id").endswith("-mesh-positions"):
                                    vert_pos_array = list(map(float, str_array))
                                if mesh_child_elem.attribute("id").endswith("-mesh-normals"):
                                    normal_array = list(map(float, str_array))
                                if mesh_child_elem.attribute("id").endswith("-mesh-map-0"):
                                    tex_coord_array = list(map(float, str_array))
                                if mesh_child_elem.tagName() == "triangles" or mesh_child_elem.tagName() == "polylist":
                                    p_child_elem = mesh_child_elem.firstChildElement()
                                    while not p_child_elem.isNull():
                                        if p_child_elem.tagName() == "p":
                                            str_indices = p_child_elem.firstChild().toText().data().split(" ")
                                            index_array = list(map(int, str_indices))
                                        p_child_elem = p_child_elem.nextSiblingElement()
                                mesh_child_elem = mesh_child_elem.nextSiblingElement()
                dae_elem = dae_elem.nextSiblingElement()
            # print(vert_pos_array)
            # print(normal_array)
            # print(tex_coord_array)
            # print(index_array)
            
            num_of_attributes = 3
            vert_positions = []
            normals = []
            tex_coords = []
            for i in range(0, len(index_array), num_of_attributes):
                vert_pos_index = index_array[i + 0]
                vert_positions.append(vert_pos_array[vert_pos_index * 3 + 0])
                vert_positions.append(vert_pos_array[vert_pos_index * 3 + 1])
                vert_positions.append(vert_pos_array[vert_pos_index * 3 + 2])
                
                normal_index = index_array[i + 1]
                normals.append(normal_array[normal_index * 3 + 0])
                normals.append(normal_array[normal_index * 3 + 1])
                normals.append(normal_array[normal_index * 3 + 2])
                
                tex_coord_index = index_array[i + 2]
                tex_coords.append(tex_coord_array[tex_coord_index * 2 + 0])
                tex_coords.append(tex_coord_array[tex_coord_index * 2 + 1])
            # print(vert_positions)
            # print(normals)
            # print(tex_coords)
            
            output = {}
     
            vert_positions = np.array(vert_positions, dtype=np.float32)
            vert_pos_buffer = QOpenGLBuffer()
            vert_pos_buffer.create()
            vert_pos_buffer.bind()
            vert_pos_buffer.allocate(vert_positions, len(vert_positions) * 4)
            
            normals = np.array(normals, dtype=np.float32)
            normal_buffer = QOpenGLBuffer()
            normal_buffer.create()
            normal_buffer.bind()
            normal_buffer.allocate(normals, len(normals) * 4)
            
            tex_coords = np.array(tex_coords, dtype=np.float32)
            tex_coord_buffer = QOpenGLBuffer()
            tex_coord_buffer.create()
            tex_coord_buffer.bind()
            tex_coord_buffer.allocate(tex_coords, len(tex_coords) * 4)
     
            vert_buffers = VertexBuffers()
            vert_buffers.vert_pos_buffer = vert_pos_buffer
            vert_buffers.normal_buffer = normal_buffer
            vert_buffers.tex_coord_buffer = tex_coord_buffer
            vert_buffers.amount_of_vertices = int(len(index_array) / 3);
            
            return vert_buffers
     
    def main():
        QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)
        app = QApplication(sys.argv)
        w = Window()
        w.show()
        sys.exit(app.exec_())
     
    if __name__ == "__main__":
        main()
  • PySide2: https://rextester.com/APZF83828
    main.py

    Python
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    
    import sys
    import numpy as np
    from OpenGL import GL as gl
    from PySide2.QtWidgets import QApplication, QOpenGLWidget
    from PySide2.QtGui import QOpenGLShaderProgram, QOpenGLShader, QOpenGLBuffer
    from PySide2.QtGui import QOpenGLTexture, QImage
    from PySide2.QtGui import QMatrix4x4, QVector3D
    from PySide2.QtXml import QDomDocument, QDomElement
    from PySide2.QtCore import Qt, QFile, QIODevice
     
    class VertexBuffers:
        vertex_pos_buffer = None
        normal_buffer = None
        tex_coord_buffer = None
        amount_of_vertices = None
     
    class Locations:
        mvp_matrix_location = None
        model_matrix_location = None
        normal_matrix_location = None
     
    class Object3D:
        position = QVector3D(0, 0, 0)
        rotation = QVector3D(0, 0, 0)
        scale = QVector3D(1, 1, 1)
        mvp_matrix = QMatrix4x4()
        model_matrix = QMatrix4x4()
        normal_matrix = QMatrix4x4()
     
        def __init__(self, vert_buffers, locations, texture):
            self.vert_pos_buffer = vert_buffers.vert_pos_buffer
            self.normal_buffer = vert_buffers.normal_buffer
            self.tex_coord_buffer = vert_buffers.tex_coord_buffer
            self.amount_of_vertices = vert_buffers.amount_of_vertices
            
            self.mvp_matrix_location = locations.mvp_matrix_location
            self.model_matrix_location = locations.model_matrix_location
            self.normal_matrix_location = locations.normal_matrix_location
            
            self.texture = texture
     
        def draw(self, program, proj_view_matrix):
            program.bind()
     
            self.vert_pos_buffer.bind()
            program.setAttributeBuffer(0, gl.GL_FLOAT, 0, 3)
            program.enableAttributeArray(0)
     
            self.normal_buffer.bind()
            program.setAttributeBuffer(1, gl.GL_FLOAT, 0, 3)
            program.enableAttributeArray(1)
     
            self.tex_coord_buffer.bind()
            program.setAttributeBuffer(2, gl.GL_FLOAT, 0, 2)
            program.enableAttributeArray(2)
            
            self.model_matrix.setToIdentity()
            self.model_matrix.translate(self.position)
            self.model_matrix.rotate(self.rotation.x(), QVector3D(1, 0, 0))
            self.model_matrix.rotate(self.rotation.y(), QVector3D(0, 1, 0))
            self.model_matrix.rotate(self.rotation.z(), QVector3D(0, 0, 1))
            self.model_matrix.scale(self.scale)
            self.mvp_matrix = proj_view_matrix * self.model_matrix;
            
            self.normal_matrix = self.model_matrix.inverted()
            self.normal_matrix = self.normal_matrix[0].transposed()
            
            program.bind()
            program.setUniformValue(self.mvp_matrix_location, self.mvp_matrix)
            program.setUniformValue(self.model_matrix_location, self.model_matrix)
            program.setUniformValue(self.normal_matrix_location, self.normal_matrix)
            
            self.texture.bind()
     
            gl.glDrawArrays(gl.GL_TRIANGLES, 0, self.amount_of_vertices)
     
    class Window(QOpenGLWidget):
     
        def __init__(self):
            super().__init__()
            self.setWindowTitle("Dae, Collada")
            self.resize(268, 268)
     
        def initializeGL(self):
            gl.glClearColor(0.2, 0.2, 0.2, 1)
            gl.glEnable(gl.GL_DEPTH_TEST)
            vertShaderSrc = """
                #version 330 core
     
                in vec4 aPosition;
                in vec4 aNormal;
                in vec2 aTexCoord;
     
                uniform mat4 uMvpMatrix;
                uniform mat4 uModelMatrix;
                uniform mat4 uNormalMatrix;
     
                out vec3 vPosition;
                out vec3 vNormal;
                out vec2 vTexCoord;
     
                void main()
                {
                    gl_Position = uMvpMatrix * aPosition;
                    vPosition = vec3(uModelMatrix * aPosition);
                    vNormal = normalize(vec3(uNormalMatrix * aNormal));
                    vTexCoord = aTexCoord;
                }
            """
            fragShaderSrc = """
                #version 330 core
     
                const vec3 lightColor = vec3(0.8, 0.8, 0.8);
                const vec3 lightPosition = vec3(5.0, 7.0, 2.0);
                const vec3 ambientLight = vec3(0.3, 0.3, 0.3);
     
                uniform sampler2D uSampler;
     
                in vec3 vPosition;
                in vec3 vNormal;
                in vec2 vTexCoord;
     
                void main()
                {
                    vec4 color = texture2D(uSampler, vTexCoord);
                    vec3 normal = normalize(vNormal);
                    vec3 lightDirection = normalize(lightPosition - vPosition);
                    float nDotL = max(dot(lightDirection, normal), 0.0);
                    vec3 diffuse = lightColor * color.rgb * nDotL;
                    vec3 ambient = ambientLight * color.rgb;
                    gl_FragColor = vec4(diffuse + ambient, color.a);
                }
            """
            self.program = QOpenGLShaderProgram()
            self.program.addShaderFromSourceCode(QOpenGLShader.Vertex, vertShaderSrc)
            self.program.addShaderFromSourceCode(QOpenGLShader.Fragment, fragShaderSrc)
            self.program.link()
            self.program.bind()
            self.program.bindAttributeLocation("aPosition", 0)
            self.program.bindAttributeLocation("aNormal", 1)
            self.program.bindAttributeLocation("aTexCoord", 2)
            locations = Locations()
            self.program.bind()
            locations.mvp_matrix_location = self.program.uniformLocation("uMvpMatrix");
            locations.model_matrix_location = self.program.uniformLocation("uModelMatrix")
            locations.normal_matrix_location = self.program.uniformLocation("uNormalMatrix")
            self.vert_buffers = self.initVertexBuffers("assets/cube.dae")
            self.proj_view_matrix = QMatrix4x4()
            self.proj_matrix = QMatrix4x4()
            self.view_matrix = QMatrix4x4()
            self.view_matrix.lookAt(
                QVector3D(2, 3, 5),
                QVector3D(0, 0, 0),
                QVector3D(0, 1, 0))
            
            self.texture = QOpenGLTexture(QOpenGLTexture.Target2D)
            self.texture.create()
            self.texture.setData(QImage("assets/cube.png"))
            self.texture.setMinMagFilters(QOpenGLTexture.Linear, QOpenGLTexture.Linear)
            self.texture.setWrapMode(QOpenGLTexture.ClampToEdge)
            self.plane = Object3D(self.vert_buffers, locations, self.texture)
            
        def paintGL(self):
            gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
            self.proj_view_matrix = self.proj_matrix * self.view_matrix
            self.plane.draw(self.program, self.proj_view_matrix)
     
        def resizeGL(self, w, h):
            gl.glViewport(0, 0, w, h)
            self.proj_matrix.setToIdentity()
            self.proj_matrix.perspective(50, float(w) / float(h), 0.1, 100)
            
        def initVertexBuffers(self, path):
            xml_doc = QDomDocument()
            file = QFile(path)
            if not file.open(QIODevice.ReadOnly):
                print("Failed to open the file: " + path)
            xml_doc.setContent(file)
            file.close()
            
            vert_pos_array = []
            normal_array = []
            tex_coord_array = []
            index_array = []
            
            root = xml_doc.documentElement()
            dae_elem = root.firstChildElement()
            while not dae_elem.isNull():
                if dae_elem.tagName() == "library_geometries":
                    geom_elem = dae_elem.firstChildElement()
                    if geom_elem.tagName() == "geometry":
                        mesh_elem = geom_elem.firstChildElement()
                        if mesh_elem.tagName() == "mesh":
                            mesh_child_elem = mesh_elem.firstChildElement()
                            while not mesh_child_elem.isNull():
                                float_array_elem = mesh_child_elem.firstChildElement()
                                str_array = float_array_elem.firstChild().toText().data().split(" ")
                                if mesh_child_elem.attribute("id").endswith("-mesh-positions"):
                                    vert_pos_array = list(map(float, str_array))
                                if mesh_child_elem.attribute("id").endswith("-mesh-normals"):
                                    normal_array = list(map(float, str_array))
                                if mesh_child_elem.attribute("id").endswith("-mesh-map-0"):
                                    tex_coord_array = list(map(float, str_array))
                                if mesh_child_elem.tagName() == "triangles" or mesh_child_elem.tagName() == "polylist":
                                    p_child_elem = mesh_child_elem.firstChildElement()
                                    while not p_child_elem.isNull():
                                        if p_child_elem.tagName() == "p":
                                            str_indices = p_child_elem.firstChild().toText().data().split(" ")
                                            index_array = list(map(int, str_indices))
                                        p_child_elem = p_child_elem.nextSiblingElement()
                                mesh_child_elem = mesh_child_elem.nextSiblingElement()
                dae_elem = dae_elem.nextSiblingElement()
            # print(vert_pos_array)
            # print(normal_array)
            # print(tex_coord_array)
            # print(index_array)
            
            num_of_attributes = 3
            vert_positions = []
            normals = []
            tex_coords = []
            for i in range(0, len(index_array), num_of_attributes):
                vert_pos_index = index_array[i + 0]
                vert_positions.append(vert_pos_array[vert_pos_index * 3 + 0])
                vert_positions.append(vert_pos_array[vert_pos_index * 3 + 1])
                vert_positions.append(vert_pos_array[vert_pos_index * 3 + 2])
                
                normal_index = index_array[i + 1]
                normals.append(normal_array[normal_index * 3 + 0])
                normals.append(normal_array[normal_index * 3 + 1])
                normals.append(normal_array[normal_index * 3 + 2])
                
                tex_coord_index = index_array[i + 2]
                tex_coords.append(tex_coord_array[tex_coord_index * 2 + 0])
                tex_coords.append(tex_coord_array[tex_coord_index * 2 + 1])
            # print(vert_positions)
            # print(normals)
            # print(tex_coords)
            
            output = {}
     
            vert_positions = np.array(vert_positions, dtype=np.float32)
            vert_pos_buffer = QOpenGLBuffer()
            vert_pos_buffer.create()
            vert_pos_buffer.bind()
            vert_pos_buffer.allocate(vert_positions, len(vert_positions) * 4)
            
            normals = np.array(normals, dtype=np.float32)
            normal_buffer = QOpenGLBuffer()
            normal_buffer.create()
            normal_buffer.bind()
            normal_buffer.allocate(normals, len(normals) * 4)
            
            tex_coords = np.array(tex_coords, dtype=np.float32)
            tex_coord_buffer = QOpenGLBuffer()
            tex_coord_buffer.create()
            tex_coord_buffer.bind()
            tex_coord_buffer.allocate(tex_coords, len(tex_coords) * 4)
     
            vert_buffers = VertexBuffers()
            vert_buffers.vert_pos_buffer = vert_pos_buffer
            vert_buffers.normal_buffer = normal_buffer
            vert_buffers.tex_coord_buffer = tex_coord_buffer
            vert_buffers.amount_of_vertices = int(len(index_array) / 3);
            
            return vert_buffers
     
    def main():
        QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)
        app = QApplication(sys.argv)
        w = Window()
        w.show()
        sys.exit(app.exec_())
     
    if __name__ == "__main__":
        main()
2
Вложения
Тип файла: rar load_texture_object_from_dae_pyqt5.rar (145.8 Кб, 0 просмотров)
Тип файла: rar load_texture_object_from_dae_pyside2.rar (145.8 Кб, 0 просмотров)
4176 / 2282 / 387
Регистрация: 05.10.2013
Сообщений: 6,385
Записей в блоге: 177
25.01.2021, 14:39 8
Лучший ответ Сообщение было отмечено u235 как решение

Решение

Анимация движения вверх-вниз 3D-модели загруженной из Blender из формата .dae (COLLADA)

Название: move_dae_obj_up_and_down.gif
Просмотров: 57

Размер: 191.5 Кб
2
Вложения
Тип файла: zip move_dae_obj_up_and_down_pyqt5.zip (146.6 Кб, 6 просмотров)
Тип файла: zip move_dae_obj_up_and_down_pyside2.zip (146.7 Кб, 6 просмотров)
3 / 3 / 0
Регистрация: 04.11.2018
Сообщений: 123
30.01.2021, 19:09  [ТС] 9
8Observer8, Спасибо огроменное, вы мне очень помогли)))
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.01.2021, 19:09

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Движение лифта вверх и вниз, изображённого в PictureBox
Помогите построить движение лифта вверх и вниз, с графикой просто не дружу. Нужно плавное движение...

Движение вверх, вниз, вправо и влево, но не по диагонали
как реализовать движение фигуры только в таком направление, т.е. вверх, вниз, вправо и влево, но не...

Движение курсора только вверх или вниз по DataGridView
Всем привет.Подскажите как реализовать, чтобы курсор в DataGridView двигался только вверх или вниз,...

Сделать движение самолета, управляемого стрелками вверх и вниз
2. Сделать движение самолета, управляемого стрелками вверх и вниз.

Влияние сопротивления воздуха на движение камня вверх и вниз
Вычислить скорость, с какой камень упадет на землю, если он падал с высоты 50м из состояния покоя....

Движение шарика при нажатии клавиши вверх вниз влево вправо
Приветствую вас.:)Надо сделать что бы шарик двигался при нажатии клавиши вверх вниз влево вправо....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.