哪些是现代的 glTranslate 和 glRotate 替代品?
Which are the modern glTranslate and glRotate alternatives?
重要编辑:我正在使用 OpenGL 的 PyOpenGL 绑定
我试图不使用 glRotate
and glTranslate
函数,但我还没有找到这两个函数的替代方法。此功能已弃用。我可以使用什么?
现代的方法是编写 Shader program, to use Vertex Array Objects and to use Uniform 个类型为 mat4
的变量。
与已弃用的固定函数管道相比,要编写的代码更多,但与通过 glBegin
/glEnd
序列绘制相比,其好处是灵活性高且性能好得多。
对于矩阵计算,可以使用 PyGLM library, which is the python version of the c++ OpenGL Mathematics (glm) 库。
例如围绕 z 轴的缩放、旋转矩阵 angle
和平移可以设置为:
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 operation glRoatate
相比,角度必须以弧度为单位设置。
请注意,除了使用 PyGLM,还可以使用流行的 NumPy library and numpy.matrix
,但 PyGLM 更接近于您从 Legacy OpenGL 和函数 glScale
、glTranslate
和 glRotate
.
当然也可以不使用任何库来设置 4x4 矩阵,也可以自己实现矩阵运算。
查看小示例程序,其中使用PyOpenGL and PyGLM (beside the modules math
and ctypes
):
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()
重要编辑:我正在使用 OpenGL 的 PyOpenGL 绑定
我试图不使用 glRotate
and glTranslate
函数,但我还没有找到这两个函数的替代方法。此功能已弃用。我可以使用什么?
现代的方法是编写 Shader program, to use Vertex Array Objects and to use Uniform 个类型为 mat4
的变量。
与已弃用的固定函数管道相比,要编写的代码更多,但与通过 glBegin
/glEnd
序列绘制相比,其好处是灵活性高且性能好得多。
对于矩阵计算,可以使用 PyGLM library, which is the python version of the c++ OpenGL Mathematics (glm) 库。
例如围绕 z 轴的缩放、旋转矩阵 angle
和平移可以设置为:
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 operation glRoatate
相比,角度必须以弧度为单位设置。
请注意,除了使用 PyGLM,还可以使用流行的 NumPy library and numpy.matrix
,但 PyGLM 更接近于您从 Legacy OpenGL 和函数 glScale
、glTranslate
和 glRotate
.
当然也可以不使用任何库来设置 4x4 矩阵,也可以自己实现矩阵运算。
查看小示例程序,其中使用PyOpenGL and PyGLM (beside the modules math
and ctypes
):
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()