python - 现代 glTranslate 和 glRotate 的替代品是什么?

标签 python python-3.x opengl pyopengl

重要编辑:我正在使用 PyOpenGL OpenGL的绑定(bind) 我试图不使用 glRotate glTranslate 函数,但我还没有找到这两个函数的替代品。该函数已被弃用。我可以使用什么?

最佳答案

现代的方法是写一个 Shader程序,使用Vertex Array Objects并使用Uniform mat4 类型的变量。
与已弃用的固定功能管道相比,需要编写更多代码,但与 glBegin/glEnd 绘制相比,好处是高度灵 active 和更好的性能。序列。

对于矩阵计算,可以使用 PyGLM库,这是 c++ 的 python 版本 OpenGL Mathematics (glm)图书馆。

例如缩放、绕 z 轴旋转矩阵角度和平移可以通过以下方式设置:

model = glm.mat4(1)
model = glm.translate(model, glm.vec3(0.2, 0.2, 0))
model = glm.rotate(model, angle, glm.vec3(0, 0, 1))
model = glm.scale(model, glm.vec3(0.5, 0.5, 1))

Legacy OpenGL 相比操作glRoatate ,角度必须以弧度为单位设置。
请注意,除了使用 PyGLM 之外,还可以使用流行的 NumPy图书馆和numpy.matrix ,但 PyGLM 更接近您从旧版 OpenGL 以及函数 glScaleglTranslateglRotate 中了解到的内容。
当然,也可以在不使用任何库的情况下设置 4x4 矩阵并自行实现矩阵运算。

请参阅小示例程序,它使用 PyOpenGLPyGLM (在模块 mathctypes 旁边):

import math 
import ctypes
import glm 
from OpenGL.GLUT import *
from OpenGL.GL import *
from OpenGL.GL.shaders import *

class MyWindow:

    __caption = 'OpenGL Window'
    __vp_size = [800, 600]
    __vp_valid = False
    __glut_wnd = None

    __glsl_vert = """
        #version 450 core

        layout (location = 0) in vec3 a_pos;
        layout (location = 1) in vec4 a_col;

        out vec4 v_color;

        layout (location = 0) uniform mat4 u_proj; 
        layout (location = 1) uniform mat4 u_view; 
        layout (location = 2) uniform mat4 u_model; 

        void main()
        {
            v_color     = a_col;
            gl_Position = u_proj * u_view * u_model * vec4(a_pos.xyz, 1.0);
        }
    """

    __glsl_frag = """
        #version 450 core

        out vec4 frag_color;
        in  vec4 v_color;

        void main()
        {
            frag_color = v_color;
        }
    """

    __program = None
    __vao = None
    __vbo = None

    def __init__(self, w, h):

        self.__vp_size = [w, h]

        glutInit()
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)
        glutInitWindowSize(self.__vp_size[0], self.__vp_size[1])
        __glut_wnd = glutCreateWindow(self.__caption)

        self.__program = compileProgram( 
            compileShader( self.__glsl_vert, GL_VERTEX_SHADER ),
            compileShader( self.__glsl_frag, GL_FRAGMENT_SHADER ),
        )

        attribures = [
        #    x       y    z    R  G  B  A
            -0.866, -0.5, 0,   1, 0, 0, 1, 
             0.866, -0.5, 0,   1, 1, 0, 1,
             0,      1.0, 0,   0, 0, 1, 1
        ]
        vertex_attributes = (GLfloat * len(attribures))(*attribures)
        itemsize = ctypes.sizeof(ctypes.c_float)

        self.__vbo = glGenBuffers(1)
        glBindBuffer(GL_ARRAY_BUFFER, self.__vbo)
        glBufferData(GL_ARRAY_BUFFER, vertex_attributes, GL_STATIC_DRAW)

        self.__vao = glGenVertexArrays(1)
        glBindVertexArray(self.__vao)
        glVertexAttribPointer(0, 3, GL_FLOAT, False, 7*itemsize, None)
        glEnableVertexAttribArray(0)
        glVertexAttribPointer(1, 4, GL_FLOAT, False, 7*itemsize, ctypes.c_void_p(3*itemsize))
        glEnableVertexAttribArray(1)

        glUseProgram(self.__program)

        glutReshapeFunc(self.__reshape)
        glutDisplayFunc(self.__mainloop)

    def run(self):
        self.__starttime = 0
        self.__starttime = self.elapsed_ms()
        glutMainLoop()

    def elapsed_ms(self):
      return glutGet(GLUT_ELAPSED_TIME) - self.__starttime

    def __reshape(self, w, h):
        self.__vp_valid = False

    def __mainloop(self):

        if not self.__vp_valid:
            self.__vp_size = [glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT)]
            self.__vp_valid = True
            glViewport(0, 0, self.__vp_size[0], self.__vp_size[1])

        proj  = glm.mat4(1)
        view  = glm.mat4(1)
        model = glm.mat4(1)

        aspect = self.__vp_size[0]/self.__vp_size[1]
        aspect_x = aspect if self.__vp_size[0] > self.__vp_size[1] else 1.0
        aspect_y = 1/aspect if self.__vp_size[0] < self.__vp_size[1] else 1.0 
        proj = glm.ortho(-aspect_x, aspect_x, -aspect_y, aspect_y, -1.0, 1.0)

        angle = self.elapsed_ms() * math.pi * 2 / 3000.0
        model = glm.translate(model, glm.vec3(0.2, 0.2, 0))
        model = glm.rotate(model, angle, glm.vec3(0, 0, 1))
        model = glm.scale(model, glm.vec3(0.5, 0.5, 1))

        glUniformMatrix4fv(0, 1, GL_FALSE, glm.value_ptr(proj) )
        glUniformMatrix4fv(1, 1, GL_FALSE, glm.value_ptr(view) )
        glUniformMatrix4fv(2, 1, GL_FALSE, glm.value_ptr(model) )

        glClearColor(0.2, 0.3, 0.3, 1.0)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        glDrawArrays(GL_TRIANGLES, 0, 3)

        glutSwapBuffers()
        glutPostRedisplay()


window = MyWindow(800, 600)
window.run()

关于python - 现代 glTranslate 和 glRotate 的替代品是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57187663/

相关文章:

c - OpenGL - 在窗口调整大小时保持纵横比

opengl - 什么时候应该使用 GL_SRGB8 而不是 GL_RGB8?

python - 从 python 脚本在 gnome-terminal 中打开选项卡

python - Flask-SocketIO redis 订阅

python-3.x - 值错误 : X has 1709 features per sample; expecting 2444

python-3.x - 找不到 win32com 模块

python - 带有代码完成功能的 python/django 的 Sublime Text 2 & 3 设置

python - 我如何在 MongoDB 中获取最近插入的文档及其所有字段?

python - 在 C++ 中的 PyObject 上调用 `+=`

macos - 加载顶点着色器时出错